diff options
author | pzread <netfirewall@gmail.com> | 2013-06-22 18:55:10 +0800 |
---|---|---|
committer | pzread <netfirewall@gmail.com> | 2013-06-22 18:55:10 +0800 |
commit | e0043639746fdbbf4958c67a3ef55c63c2fe51a5 (patch) | |
tree | bf553445c16ad67b56fd26403057428c4e6dd4af | |
parent | a66de70527978a4510c6e230fcc56ce890bf20a2 (diff) | |
download | taiwan-online-judge-e0043639746fdbbf4958c67a3ef55c63c2fe51a5.tar.gz taiwan-online-judge-e0043639746fdbbf4958c67a3ef55c63c2fe51a5.tar.zst taiwan-online-judge-e0043639746fdbbf4958c67a3ef55c63c2fe51a5.zip |
Add notice. Done profile page
-rw-r--r-- | src/css/color.less | 1 | ||||
-rw-r--r-- | src/css/index.less | 34 | ||||
-rw-r--r-- | src/css/mail.less | 25 | ||||
-rw-r--r-- | src/css/style.less | 20 | ||||
-rw-r--r-- | src/css/user_edit.less | 5 | ||||
-rw-r--r-- | src/css/user_main.less | 15 | ||||
-rw-r--r-- | src/html/index.html | 9 | ||||
-rw-r--r-- | src/html/user_edit.html | 31 | ||||
-rw-r--r-- | src/html/user_main.html | 11 | ||||
-rw-r--r-- | src/js/com.js | 46 | ||||
-rw-r--r-- | src/js/imc.js | 2 | ||||
-rw-r--r-- | src/js/index.js | 29 | ||||
-rw-r--r-- | src/js/mail.js | 18 | ||||
-rw-r--r-- | src/js/notice.js | 66 | ||||
-rw-r--r-- | src/js/user.js | 299 | ||||
-rwxr-xr-x | src/py/backend_server.py | 36 | ||||
-rwxr-xr-x | src/py/center_server.py | 79 | ||||
-rwxr-xr-x | src/py/imc/proxy.py | 9 | ||||
-rw-r--r-- | src/py/mail.py | 15 | ||||
-rw-r--r-- | src/py/notice.py | 236 | ||||
-rw-r--r-- | src/py/square.py | 311 | ||||
-rwxr-xr-x | src/py/user.py | 72 |
22 files changed, 1234 insertions, 135 deletions
diff --git a/src/css/color.less b/src/css/color.less index 5752589..c1887c6 100644 --- a/src/css/color.less +++ b/src/css/color.less @@ -1,4 +1,5 @@ @white:#FFFFFF; +@lightgray:#FCFAF2; @gray:#BDC0BA; @darkgray:#373C38; @black:#000000; diff --git a/src/css/index.less b/src/css/index.less index d85bcce..81d9546 100644 --- a/src/css/index.less +++ b/src/css/index.less @@ -2,12 +2,24 @@ @import 'mixin.less'; body{ + overflow-x:hidden; overflow-y:scroll; } #index_header{ + height:0px; z-index:1; - position:relative; + position:fixed; + top:0px; + left:0px; + opacity:0; + transition:opacity @fast; + + &.active{ + height:40px; + opacity:1; + display:block; + } } .index_tag{ height:32px; @@ -48,6 +60,7 @@ body{ div.notice{ width:70px; text-align:center; + background-color:@darkgray } div.notice_hl{ background-color:@orange; @@ -106,10 +119,14 @@ body{ div.notice{ overflow-y:auto; - li > a{ - height:64px; + ul.nav > li > a{ + min-height:64px; padding-left:@SmallPad; font-size:@NormalFontSize; + + p{ + word-wrap:break-word; + } } } } @@ -120,9 +137,12 @@ body{ right:@MediumPad; } #index_page{ + margin-top:40px; padding-top:@MediumPad; - - div.page{ - - } +} +#index_footer{ + margin-top:@MediumPad; + padding:@MediumPad @MediumPad 0px @MediumPad; + background-color:@lightgray; + text-align:right; } diff --git a/src/css/mail.less b/src/css/mail.less index dbfe3f2..e0bd6e7 100644 --- a/src/css/mail.less +++ b/src/css/mail.less @@ -1,3 +1,6 @@ +@import "mixin.less"; +@import "color.less"; + #index_page{ div.newmail{ div.content{ @@ -9,7 +12,29 @@ width:100%; } } + div.oper{ + text-align:center; + } table.maillist{ + position:relative; + left:-39px; + + th.check{ + width:16px; + text-align:center; + + span.check{ + margin-bottom:-2px; + } + } + td.check{ + width:16px; + text-align:center; + + span.check{ + margin-top:4px; + } + } tr.item{ cursor:pointer; } diff --git a/src/css/style.less b/src/css/style.less index 97e519e..c36c429 100644 --- a/src/css/style.less +++ b/src/css/style.less @@ -6,6 +6,26 @@ div.medium_modal{ width:970px; margin-left:-485px; } +span.check{ + width:14px; + height:14px; + border:@gray 1px solid; + position:relative; + display:inline-block; + + &:hover{ + background-color:fade(@black,10%); + } + + i{ + position:absolute; + top:-2px; + left:0px; + } +} +span.check_bold{ + border:@darkgray 2px solid; +} .time{ font-size:@SmallFontSize; } diff --git a/src/css/user_edit.less b/src/css/user_edit.less new file mode 100644 index 0000000..6a454f7 --- /dev/null +++ b/src/css/user_edit.less @@ -0,0 +1,5 @@ +#index_page{ + img.avatar,img.cover{ + width:270px; + } +} diff --git a/src/css/user_main.less b/src/css/user_main.less index 33518fe..a136854 100644 --- a/src/css/user_main.less +++ b/src/css/user_main.less @@ -1,3 +1,16 @@ -#index_page{ +@import "mixin.less"; +@import "color.less"; +#index_page{ + div.cover{ + width:100%; + height:900px; + overflow-y:hidden; + position:absolute; + top:0px; left:0px; z-index:0; + background-size:cover; + } + div.profile{ + color:darken(@gray,20%); + } } diff --git a/src/html/index.html b/src/html/index.html index 16b3880..b8795ea 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -23,6 +23,7 @@ <script src="/toj/js/com.js" type="text/javascript"></script> <script src="/toj/js/index.js" type="text/javascript"></script> <script src="/toj/js/user.js" type="text/javascript"></script> +<script src="/toj/js/notice.js" type="text/javascript"></script> <script src="/toj/js/home.js" type="text/javascript"></script> <script src="/toj/js/mail.js" type="text/javascript"></script> @@ -36,6 +37,7 @@ $(document).ready(function(){ com.conn_callback.add(function(){ user.ready(); + notice.ready(); index.ready(); home.ready(); mail.ready(); @@ -91,7 +93,7 @@ $(document).ready(function(){ </div> <div id="index_paneltag" class="active"> - <div class="notice notice_hl">[5]</div> + <div class="notice"></div> </div> <div id="index_panel" exheight=true> <div class="tagblock"></div> @@ -122,6 +124,9 @@ $(document).ready(function(){ </div> <div id="index_alert" style="z-index:2000;"></div> -<div id="index_page" class="container"></div> +<div id="index_page" class="container" exminheight=true extop=56px exbottom=62px></div> +<div id="index_footer"> + <p class="muted">εpsilon team</p> +</div> </body> </html> diff --git a/src/html/user_edit.html b/src/html/user_edit.html new file mode 100644 index 0000000..da8706d --- /dev/null +++ b/src/html/user_edit.html @@ -0,0 +1,31 @@ +<link href="/toj/css/user_edit.css" rel="stylesheet"> + +<div class="row"> + <div class="offset3 span3"> + <h3>個人資料</h3> + <label>暱稱</label> + <input name="nickname" type="text"> + <label>信箱</label> + <input name="email" type="text"> + <label>個人頭像網址</label> + <input name="avatar" type="text"><br> + <img class="img-polaroid avatar"></img><br><br> + <label>個人封面網址</label> + <input name="cover" type="text"><br> + <img class="img-polaroid cover"></img><br><br> + <label>關於我</label> + <input name="aboutme" type="text"><br> + <button class="btn btn-primary submit">確定</button> + <button class="btn cancel">取消</button> + + <h3>更改密碼</h3> + <label>舊密碼</label> + <input name="oldpassword" type="password"> + <label>新密碼</label> + <input name="password" type="password"> + <label>重複密碼</label> + <input name="repeat" type="password"><br> + <button class="btn btn-primary submit">確定</button> + <button class="btn cancel">取消</button> + </div> +</div> diff --git a/src/html/user_main.html b/src/html/user_main.html index ae8b25d..ad0755d 100644 --- a/src/html/user_main.html +++ b/src/html/user_main.html @@ -1,12 +1,11 @@ <link href="/toj/css/user_main.css" rel="stylesheet"> -<div style="width:100%; max-height:900px; overflow-y:hidden; position:absolute; top:0px; left:0px; z-index:0;"> - <img src="http://i.imgur.com/Btrg9wz.jpg"></img> -</div> -<div class="row" style="height:768px; margin-top:560px; position:relative; z-index:0;"> + +<div class="cover"></div> +<div class="row" style="height:768px; margin-top:640px; position:relative; z-index:0;"> <div class="offset4 span2"> - <img class="img-polaroid avatar" src="http://i.imgur.com/R9lfWcm.jpg"></img> + <img class="img-polaroid avatar"></img> </div> - <div class="span7" style="color:white;"> + <div class="span3 profile"> <h3 class="name"></h3> <h3>關於我</h3> <p class="aboutme"></p> diff --git a/src/js/com.js b/src/js/com.js index 4105dd6..3e50173 100644 --- a/src/js/com.js +++ b/src/js/com.js @@ -201,7 +201,9 @@ var com = new function(){ that.url_chg(); }; that.url_push_back = function(block_regexp){ - if(that.url_back == null || that.url_back.search(block_regexp) != -1){ + console.log(that.url_back); + + if(that.url_back == null || (block_regexp != undefined && that.url_back.search(block_regexp) != -1)){ that.url_push('/toj/home/'); }else{ that.url_push(that.url_back); @@ -466,28 +468,37 @@ var com = new function(){ }; that.exheight = function(){ var i; - var es = $('[exheight="true"]'); var j_e; var winheight = $(window).innerHeight(); var exratio; var extop; + var exbottom; - for(i = 0;i < es.length;i++){ - j_e = $(es[i]); + function ex(es,attr){ + for(i = 0;i < es.length;i++){ + j_e = $(es[i]); - if((exratio = j_e.attr('exratio')) != undefined){ - exratio = parseInt(exratio.match('(.*)%')[1]) / 100; - j_e.height(winheight * exratio); - }else{ - if((extop = j_e.attr('extop')) == undefined){ - extop = j_e.css('top'); - } + if((exratio = j_e.attr('exratio')) != undefined){ + exratio = parseInt(exratio.match('(.*)%')[1]) / 100; + j_e.height(winheight * exratio); + }else{ + if((extop = j_e.attr('extop')) == undefined){ + extop = j_e.css('top'); + } + if((exbottom = j_e.attr('exbottom')) == undefined){ + exbottom = '0px'; + } - extop = extop.match('(.*)px')[1]; - j_e.height(winheight - extop); + extop = extop.match('(.*)px')[1]; + exbottom = exbottom.match('(.*)px')[1]; + j_e.css(attr,(winheight - extop - exbottom)); + } } } + ex($('[exheight="true"]'),'height'); + ex($('[exminheight="true"]'),'min-height'); + $('.modal-body').css('max-height',(winheight * 0.5) + 'px'); }; that.get_cookie = function(){ @@ -673,12 +684,13 @@ var com = new function(){ imc.Auth.change_current_iden(idendesc) - if((cookie = com.get_cookie()) != null){ - com.call_backend('core/user/','cookie_login',function(result){ - if(com.is_callerr(result)){ + if((cookie = that.get_cookie()) != null){ + that.call_backend('core/user/','cookie_login',function(result){ + if(that.is_callerr(result)){ //TODO GE }else{ imc.Auth.change_current_iden(result.data.idendesc); + user.uid = imc.Auth.get_current_iden().uid; } that.conn_callback.fire(); @@ -696,7 +708,7 @@ var com = new function(){ var i; var params = new Array() - params = [com.backend_link + path,func_name,1000,callback] + params = [that.backend_link + path,func_name,1000,callback] for(i = 3;i < arguments.length;i++){ params.push(arguments[i]); } diff --git a/src/js/imc.js b/src/js/imc.js index 8970ccf..aea4a03 100644 --- a/src/js/imc.js +++ b/src/js/imc.js @@ -87,6 +87,8 @@ var imc = new function(){ } }; + console.log(func_name); + part = dst.split('/'); dst_link = part.slice(0,3).join('/') + '/' dst_path = part.slice(3,-1); diff --git a/src/js/index.js b/src/js/index.js index 9f1ba44..3ea93fc 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -10,11 +10,19 @@ var index = new function(){ var j_header; var j_alertbox; + function active_header(){ + j_header.addClass('active'); + } + function inactive_header(){ + if(j_win.scrollTop() > 8 && !j_header.hasClass('force')){ + j_header.removeClass('active'); + } + } function active_menutag(){ j_menutag.addClass('active'); }; function inactive_menutag(){ - if(j_win.scrollTop() > 8 && !j_menu.hasClass('active')){ + if(j_win.scrollTop() > 8 && !j_menutag.hasClass('force') && !j_menu.hasClass('active')){ j_menutag.removeClass('active'); } }; @@ -22,7 +30,7 @@ var index = new function(){ j_paneltag.addClass('active'); }; function inactive_paneltag(){ - if(j_win.scrollTop() > 8 && !j_panel.hasClass('active')){ + if(j_win.scrollTop() > 8 && !j_paneltag.hasClass('force') && !j_panel.hasClass('active')){ j_paneltag.removeClass('active'); } }; @@ -51,15 +59,21 @@ var index = new function(){ j_panel = $('#index_panel'); j_header = $('#index_header'); j_alertbox = $('#index_alert'); - - j_win.on('scroll',function(e){ + + function _change(){ if(j_win.scrollTop() <= 8){ + active_header(); active_menutag(); active_paneltag(); }else{ + inactive_header(); inactive_menutag(); inactive_paneltag(); } + } + + j_win.on('scroll',function(e){ + _change(); }); j_win.on('mouseover',function(e){ var j_e; @@ -92,6 +106,11 @@ var index = new function(){ active_panel(); } }); + j_panel.find('div.notice').on('click',function(e){ + if(j_panel.hasClass('active')){ + inactive_panel(); + } + }); user.login_callback.add(function(){ var j_li; @@ -102,6 +121,8 @@ var index = new function(){ j_menu.find('div.menu li.mail').show(); }); + + _change(); }; that.set_title = function(title){ j_header.find('p.title').text(title); diff --git a/src/js/mail.js b/src/js/mail.js index 780aa90..0abe12a 100644 --- a/src/js/mail.js +++ b/src/js/mail.js @@ -51,6 +51,10 @@ var mail = new function(){ return j_item; }; function update_maillist(){ + if(maillist_type == null){ + return; + } + j_index_page.find('span.checkall').check(false); com.call_backend('core/mail/','list_mail',function(result){ @@ -90,6 +94,11 @@ var mail = new function(){ var backup_node = new vus.node('backup'); j_index_page = $('#index_page'); + + imc.Proxy.instance.register_call('core/mail/','update_mail',function(callback){ + update_maillist(); + callback('Success'); + }); mail_node.url_chg = function(direct,url_upart,url_dpart,param){ if(direct == 'in'){ @@ -152,8 +161,6 @@ var mail = new function(){ j_newmail.on('hide',function(e){ j_newmail.find('input').val(''); newmail_content.setValue(''); - - update_maillist(); }); j_newmail.find('button.submit').on('click',function(e){ var to_username = j_newmail.find('input.to_username').val(); @@ -212,6 +219,7 @@ var mail = new function(){ j_readmail.find('h3.title').text(''); j_readmail.find('span.from_username').text(''); readmail_content.setValue(''); + readmail_mailid = null; update_maillist(); }); @@ -270,6 +278,9 @@ var mail = new function(){ },maillist_type); update_maillist(); + }else if(direct == 'out'){ + maillist_type = null; + maillist_off = null; } return 'cont'; @@ -306,6 +317,9 @@ var mail = new function(){ },maillist_type); update_maillist(); + }else if(direct == 'out'){ + maillist_type = null; + maillist_off = null; } return 'cont'; diff --git a/src/js/notice.js b/src/js/notice.js new file mode 100644 index 0000000..9bd92eb --- /dev/null +++ b/src/js/notice.js @@ -0,0 +1,66 @@ +var notice = new function(){ + var that = this; + var j_noticetag; + var j_noticelist; + + that.ready = function(){ + function _set_unseen_count(count){ + if(count == 0){ + j_noticetag.removeClass('notice_hl'); + }else{ + j_noticetag.addClass('notice_hl'); + } + j_noticetag.text('[' + count + ']'); + } + + j_noticetag = $('#index_paneltag > div.notice'); + j_noticelist = $('#index_panel > div.notice > ul.nav'); + + j_noticetag.on('click',function(e){ + j_noticelist.empty(); + + com.call_backend('core/notice/','list_notice',function(result){ + var i; + var data = result.data; + var notice; + var j_item; + + if(com.is_callerr(result)){ + index.add_alert('','警告','通知發生錯誤'); + }else{ + console.log(data); + + for(i = 0;i < data.length;i++){ + notice = data[i]; + + j_item = $('<li><a><h5></h5><p></p></a></li>'); + j_item.find('h5').text(notice.title); + j_item.find('p').text(notice.content); + + if(notice.noticemodid == null){ + j_item.find('a').attr('href','/toj' + notice.metadata); + } + + j_noticelist.append(j_item); + } + } + }); + }); + + imc.Proxy.instance.register_call('core/notice/','update_notice',function(callback,unseen_count){ + _set_unseen_count(unseen_count); + callback('Success'); + }); + + com.call_backend('core/notice/','get_unseen_count',function(result){ + var data = result.data; + + if(com.is_callerr(result)){ + index.add_alert('','警告','通知發生錯誤'); + }else{ + _set_unseen_count(data.unseen_count); + } + }); + }; + +}; diff --git a/src/js/user.js b/src/js/user.js index 259768d..f6d32b9 100644 --- a/src/js/user.js +++ b/src/js/user.js @@ -7,15 +7,19 @@ var user = new function(){ that.nickname = null; that.email = null; that.avatar = null; + that.cover = null; that.login_callback = $.Callbacks(); that.ready = function(){ var uid; var user_node_uid = null; + var j_tabnav_main; + var j_tabnav_edit; var user_node = new vus.node('user'); var main_node = new vus.node('main'); + var edit_node = new vus.node('edit'); var login_node = new vus.node('login'); var register_node = new vus.node('register'); var logout_node = new vus.node('logout'); @@ -29,7 +33,9 @@ var user = new function(){ document.cookie = 'hash=' + hash + ';path=/;expires=' + expire.toUTCString(); imc.Auth.change_current_iden(idendesc); - _set_user_data(uid); + _set_user_data(uid).done(function(){ + that.login_callback.fire(); + }); }; function _logout(){ document.cookie = 'uid=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT'; @@ -49,71 +55,293 @@ var user = new function(){ return defer.promise(); }; function _set_user_data(uid){ + var defer = $.Deferred(); + _get_user_info(uid).done(function(data){ + var j_a; + that.uid = data.uid; that.username = data.username; that.nickname = data.nickname; that.email = data.email; that.avatar = data.avatar; + that.cover = data.cover; - that.login_callback.fire(); + j_a = $('#index_header li.nickname > a'); + j_a.text(that.nickname); + j_a.attr('href','/toj/user:' + that.uid + '/main/'); + defer.resolve(); }).fail(function(data){ - //TODO GE + defer.reject(); }); + + return defer.promise(); } j_index_page = $('#index_page'); if((uid = imc.Auth.get_current_iden().uid) != undefined){ - _set_user_data(uid); + _set_user_data(uid).done(function(){ + that.login_callback.fire(); + }); } user_node.url_chg = function(direct,url_upart,url_dpart,param){ - if(direct == 'in'){ - user_node_uid = parseInt(param[0]); + var param_uid; + + if(direct == 'in' || direct == 'same'){ + if((param_uid = parseInt(param[0])) == user_node_uid){ + return 'cont'; + } + user_node_uid = param_uid; + + index.set_menu('使用者'); + index.set_title(''); + + index.clear_tabnav(); + + j_tabnav_main = index.add_tabnav('個人','/toj/user:' + user_node_uid + '/main/'); + + if(user_node_uid == that.uid){ + j_tabnav_edit = index.add_tabnav('編輯資料','/toj/user:' + user_node_uid + '/edit/'); + user_node.child_set(edit_node); + } + }else if(direct == 'out'){ + user_node_uid = null; + user_node.child_del(edit_node); } }; com.vus_root.child_set(user_node); - function _tmp(y){ - var now = 0; - var ay = 80; + main_node.url_chg = function(direct,url_upart,url_dpart,param){ + var j_win = $(window); + var j_header = $('#index_header'); + var j_menutag = $('#index_menutag'); + var j_paneltag = $('#index_paneltag'); - function __ani(){ - if(y <= now){ - $(window).scrollTop(y); - return; + function _tmp(y){ + var now = 0; + var ay = 100; + + /*function __ani(){ + if(y <= now){ + $(window).scrollTop(y); + return; + } + $(window).scrollTop(now); + + now = now + ay; + ay = Math.max(5,ay * 0.86); + setTimeout(__ani,10); } - $(window).scrollTop(now); - now = now + ay; - ay = Math.max(5,ay * 0.86); - setTimeout(__ani,10); + __ani();*/ + j_win.scrollTop(y); } - __ani(); - } + function _active(){ + j_header.addClass('force'); + j_header.addClass('active'); + j_menutag.addClass('force'); + j_menutag.addClass('active'); + j_paneltag.addClass('force'); + j_paneltag.addClass('active'); + } + function _inactive(){ + j_header.removeClass('force'); + j_menutag.removeClass('force'); + j_paneltag.removeClass('force'); + } - main_node.url_chg = function(direct,url_upart,url_dpart,param){ - if(direct == 'in'){ - index.set_menu('使用者'); - index.set_title(''); - index.clear_tabnav(); + if(direct == 'in' || direct == 'same'){ + j_tabnav_main.active(); + + j_index_page.css('visibility','hidden'); $.when( _get_user_info(user_node_uid), com.loadpage('/toj/html/user_main.html') ).done(function(data){ + var reen = false; + var url; + + if((url = data.avatar) == ''){ + url = 'http://i.imgur.com/ykkQD.png'; + } + j_index_page.find('img.avatar').attr('src',url); + if((url = data.cover) == ''){ + url = 'http://i.imgur.com/7COsFS4.jpg'; + } + j_index_page.find('div.cover').css('background-image','url(\'' + url + '\')'); j_index_page.find('h3.name').text(data.nickname + '(' + data.username + ')'); j_index_page.find('p.aboutme').text(data.aboutme); - _tmp(560); + j_win.on('scroll.user_main',function(e){ + if(reen == true){ + return; + } + reen = true; + + if(j_win.scrollTop() > 500){ + _inactive(); + j_win.scroll(); + }else{ + _active(); + } + + reen = false; + }); + + _active(); + _tmp(500); + j_index_page.show(); + j_index_page.css('visibility','visible'); }); + }else if(direct == 'out'){ + console.log(direct); + j_win.off('scroll.user_main'); + _inactive(); } + + return 'cont'; }; user_node.child_set(main_node); + edit_node.url_chg = function(direct,url_upart,url_dpart,param){ + if(direct == 'in' || direct == 'same'){ + j_tabnav_edit.active(); + + $.when( + _get_user_info(user_node_uid), + com.loadpage('/toj/html/user_edit.html') + ).done(function(data){ + var j_nickname = j_index_page.find('[name="nickname"]'); + var j_email = j_index_page.find('[name="email"]'); + var j_avatar = j_index_page.find('[name="avatar"]'); + var j_cover = j_index_page.find('[name="cover"]'); + var j_aboutme = j_index_page.find('[name="aboutme"]'); + var j_oldpassword = j_index_page.find('[name="oldpassword"]'); + var j_password = j_index_page.find('[name="password"]'); + var j_repeat = j_index_page.find('[name="repeat"]'); + var j_img_avatar = j_index_page.find('img.avatar'); + var j_img_cover = j_index_page.find('img.cover'); + + j_avatar.on('change',function(e){ + var url = $(this).val(); + + if(url == ''){ + url = 'http://i.imgur.com/ykkQD.png'; + } + j_img_avatar.attr('src',url); + }); + j_cover.on('change',function(e){ + var url = $(this).val(); + + if(url == ''){ + url = 'http://i.imgur.com/7COsFS4.jpg'; + } + j_img_cover.attr('src',url); + }); + + j_nickname.val(data.nickname); + j_email.val(data.email); + j_avatar.val(data.avatar); + j_avatar.change(); + j_cover.val(data.cover); + j_cover.change(); + j_aboutme.val(data.aboutme); + + j_index_page.find('button.submit').on('click',function(e){ + var oldpassword; + var password; + var repeat; + var set_defer = $.Deferred(); + var change_defer = $.Deferred(); + + oldpassword = j_oldpassword.val(); + password = j_password.val(); + repeat = j_repeat.val(); + + if(password != repeat){ + index.add_alert('alert-error','失敗','重複密碼不同',true); + return; + } + + com.call_backend('core/user/','set_user_info',function(result){ + var errmsg; + + if(com.is_callerr(result)){ + if(result.data == 'Eusername_too_short'){ + errmsg = '使用者名稱過短'; + }else if(data == 'Eusername_too_long'){ + errmsg = '使用者名稱過長'; + }else if(data == 'Eavatar_too_short'){ + errmsg = '個人頭像網址過短'; + }else if(data == 'Eavatar_too_long'){ + errmsg = '個人頭像網址過長'; + }else if(data == 'Enickname_too_short'){ + errmsg = '暱稱過短'; + }else if(data == 'Enickname_too_long'){ + errmsg = '暱稱過長'; + }else if(data == 'Eemail_too_short'){ + errmsg = '信箱過短'; + }else if(data == 'Eemail_too_long'){ + errmsg = '信箱過長'; + }else{ + errmsg = '資料更新時發生錯誤'; + } + + index.add_alert('alert-error','失敗',errmsg,true); + set_defer.reject(); + }else{ + _set_user_data(that.uid); + set_defer.resolve(); + } + },that.uid,j_nickname.val(),j_email.val(),j_avatar.val(),j_aboutme.val(),j_cover.val()); + + if(oldpassword == ''){ + change_defer.resolve(); + }else{ + com.call_backend('core/user/','change_user_password',function(result){ + var errmsg; + + console.log(result); + if(com.is_callerr(result)){ + if(result.data == 'Epassword_too_short'){ + errmsg = '密碼過短'; + }else if(data == 'Epsaaword_too_long'){ + errmsg = '密碼過長'; + }else if(data == 'Ewrong_old_password'){ + errmsg = '舊密碼錯誤'; + }else{ + errmsg = '密碼更改時發生錯誤'; + } + + index.add_alert('alert-error','失敗',errmsg,true); + change_defer.reject(); + }else{ + change_defer.resolve(); + } + },that.uid,oldpassword,password); + } + + $.when(set_defer,change_defer).done(function(){ + index.add_alert('alert-success','成功','資料已更新',true); + com.url_push('/toj/user:' + that.uid + '/main/'); + }); + }); + j_index_page.find('button.cancel').on('click',function(e){ + com.url_push_back('/toj/user.*/edit/'); + }); + }); + }else if(direct == 'out'){ + + } + + return 'cont'; + }; + login_node.url_chg = function(direct,url_upart,url_dpart,param){ if(direct == 'in'){ index.set_menu('登入'); @@ -139,12 +367,12 @@ var user = new function(){ com.call_backend('core/user/','login',function(result){ data = result.data; - if(result.stat == true && typeof(data) != 'string'){ - _login(data.uid,data.hash,data.idendesc); - com.url_push('/toj/home/'); - }else{ + if(com.is_callerr(result)){ j_alert.text('登入失敗'); j_alert.show(); + }else{ + _login(data.uid,data.hash,data.idendesc); + com.url_push_back('/toj/(login/|register)/'); } },username,password); }); @@ -186,8 +414,10 @@ var user = new function(){ com.call_backend('core/user/','login',function(result){ data = result.data; _login(data.uid,data.hash,data.idendesc); + com.url_push_back('/toj/(login/|register)/'); },username,password); }else{ + console.log(data); if(data == 'Eusername_too_short'){ j_alert.text('使用者名稱過短'); }else if(data == 'Eusername_too_long'){ @@ -206,11 +436,13 @@ var user = new function(){ j_alert.text('信箱過長'); }else if(data == 'Eusername_exists'){ j_alert.text('使用者名稱已存在'); + }else{ + j_alert.text('註冊時發生錯誤'); } j_alert.show(); } - },username,password,nickname,email,'',''); + },username,password,nickname,email,'','',''); }); }); } @@ -227,12 +459,7 @@ var user = new function(){ that.login_callback.add(function(){ var j_index_header = $('#index_header'); - var j_a; - - j_a = j_index_header.find('li.nickname > a'); - j_a.text(that.nickname); - j_a.attr('href','/toj/user:' + that.uid + '/main/'); - + j_index_header.find('li.login').hide(); j_index_header.find('li.register').hide(); j_index_header.find('li.nickname').show(); diff --git a/src/py/backend_server.py b/src/py/backend_server.py index 197d820..b9bb07b 100755 --- a/src/py/backend_server.py +++ b/src/py/backend_server.py @@ -14,12 +14,14 @@ import tornado.websocket from imc import auth import imc.async -from imc.proxy import Proxy,Connection,imc_call,imc_call_async,imc_register_call +from imc.proxy import Proxy,Connection import netio from netio import SocketStream,SocketConnection,WebSocketConnection from tojauth import TOJAuth -import mod +from notice import Notice +from user import UserMg +from mail import Mail class BackendWorker(tornado.tcpserver.TCPServer): def __init__(self,center_addr,ws_port): @@ -113,8 +115,15 @@ class BackendWorker(tornado.tcpserver.TCPServer): Proxy.instance.register_call('test/','test_dst',self._test_dst) #Proxy.instance.register_filter('test/',self._test_filter) - mod.load('core_user','user',self._idendesc,self._get_link) - mod.load('core_mail','mail',self._idendesc,self._get_link) + try: + Notice(self._idendesc,self._get_link) + UserMg(self._idendesc,self._get_link) + Mail(self._idendesc,self._get_link) + except Exception as e: + print(e) + + #mod.load('core_user','user',self._idendesc,self._get_link) + #mod.load('core_mail','mail',self._idendesc,self._get_link) #if self._link == '/backend/2/': # self._test_call(None) @@ -178,6 +187,9 @@ class BackendWorker(tornado.tcpserver.TCPServer): with TOJAuth.change_current_iden(self._idendesc): stat,ret = Proxy.instance.call(self.center_conn.link,'lookup_link',65536,link) + print(link) + print(ret) + if stat == False or ret == None: return None @@ -236,10 +248,15 @@ class BackendWorker(tornado.tcpserver.TCPServer): except KeyError: pass - def _get_link(self,linkclass): + def _get_link(self,linkclass,uid = None): if linkclass == 'center': return self.center_conn.link + elif linkclass == 'client' and uid != None: + stat,ret = Proxy.instance.call(self.center_conn.link + 'core/','get_uid_clientlink',10000,uid) + print(ret) + return ret + @imc.async.caller def _test_get_client_list(self,talk,talk2): stat,ret = Proxy.instance.call(TOJAuth.get_current_iden()['link'] + 'test/route/','80s',1000,'attation','mega') @@ -262,18 +279,13 @@ class BackendWorker(tornado.tcpserver.TCPServer): continue fileres = Proxy.instance.sendfile(dst,'Fedora-18-x86_64-DVD.iso') - ret = imc_call_async(dst + 'test/','test_dst',lambda result: print('ok'),fileres.filekey) + ret = Proxy.instance.call_async(dst + 'test/','test_dst',lambda result: print('ok'),fileres.filekey) print(fileres.wait()) print(time.perf_counter() - st) print(self._link) - #imc_call_async(dst,'test_dst',lambda result : print(result),'test',113) - - #ret = imc_call('/center/1/','create_iden','client','1234',1221,TOJAuth.ROLETYPE_USER,{'uid':31}) - #print(ret) - return pend = [] @@ -284,7 +296,7 @@ class BackendWorker(tornado.tcpserver.TCPServer): fileres = Proxy.instance.sendfile('/backend/' + str((i % 16) + 2) + '/','Fedora-18-x86_64-DVD.iso') dst = '/backend/' + str((i % 16) + 2) + '/' - ret = imc_call(self._idendesc,dst,'test_dst',fileres.filekey) + ret = Proxy.instance.call(self._idendesc,dst,'test_dst',fileres.filekey) pend.append(fileres) diff --git a/src/py/center_server.py b/src/py/center_server.py index 1f67c9d..bed117d 100755 --- a/src/py/center_server.py +++ b/src/py/center_server.py @@ -11,7 +11,7 @@ import tornado.httpserver import tornado.web import imc.async -from imc.proxy import Proxy,Connection,imc_call,imc_call_async,imc_register_call +from imc.proxy import Proxy,Connection import netio from netio import SocketStream,SocketConnection @@ -62,6 +62,7 @@ class CenterServer(tornado.tcpserver.TCPServer): self._client_linkmap = {} self._client_backendmap = {} self._backend_workerlist = [] + self._uid_clientmap = {} pubkey = open('pubkey.pem','r').read() privkey = open('privkey.pem','r').read() @@ -72,12 +73,13 @@ class CenterServer(tornado.tcpserver.TCPServer): self._idendesc = TOJAuth.instance.create_iden(self._link,1,TOJAuth.ROLETYPE_TOJ) Proxy(self._link,TOJAuth.instance,self._idendesc) - imc_register_call('','lookup_link',self._lookup_link) - imc_register_call('','create_iden',self._create_iden) - imc_register_call('','add_client',self._add_client) - imc_register_call('','del_client',self._del_client) + Proxy.instance.register_call('','lookup_link',self._lookup_link) + Proxy.instance.register_call('','create_iden',self._create_iden) + Proxy.instance.register_call('','add_client',self._add_client) + Proxy.instance.register_call('','del_client',self._del_client) + Proxy.instance.register_call('core/','get_uid_clientlink',self._get_uid_clientlink) - imc_register_call('test/','get_client_list',self._test_get_client_list) + Proxy.instance.register_call('test/','get_client_list',self._test_get_client_list) def handle_stream(self,stream,addr): def _recv_worker_info(data): @@ -150,18 +152,30 @@ class CenterServer(tornado.tcpserver.TCPServer): #else: # worker = self._worker_linkidmap[str(a - 1)] - linkclass = TOJAuth.get_current_iden()['link'].split('/',2)[1] - if linkclass != 'client': - worker = self._worker_linkmap[link] - - sock_ip,sock_port = worker.sock_addr - return { - 'worker_link':worker.link, - 'sock_ip':sock_ip, - 'sock_port':sock_port - } + if TOJAuth.get_current_iden()['link'].split('/')[1] != 'client': + linkclass,linkid = link.split('/')[1:3] + + if linkclass == 'client': + backend_link = self._client_linkmap[link]['backend_link'] + worker = self._worker_linkmap[backend_link] + + sock_ip,sock_port = worker.sock_addr + return { + 'worker_link':worker.link, + 'sock_ip':sock_ip, + 'sock_port':sock_port + } + + else: + worker = self._worker_linkmap[link] + + sock_ip,sock_port = worker.sock_addr + return { + 'worker_link':worker.link, + 'sock_ip':sock_ip, + 'sock_port':sock_port + } - else: return None except KeyError: @@ -170,13 +184,27 @@ class CenterServer(tornado.tcpserver.TCPServer): @imc.async.caller @TOJAuth.check_access(1,TOJAuth.ACCESS_EXECUTE) def _create_iden(self,link,idenid,roletype,payload): + linkclass = link.split('/')[1] + if linkclass == 'client' and roletype == TOJAuth.ROLETYPE_USER: + uid = payload['uid'] + client = self._client_linkmap[link] + client['uid'] = uid + + if uid not in self._uid_clientmap: + self._uid_clientmap[uid] = {link:client} + + else: + self._uid_clientmap[uid][link] = client + return TOJAuth.instance.create_iden(link,idenid,roletype,payload) @imc.async.caller @TOJAuth.check_access(1,TOJAuth.ACCESS_EXECUTE) def _add_client(self,client_link,backend_link): self._client_linkmap[client_link] = { - 'backend_link':backend_link + 'client_link':client_link, + 'backend_link':backend_link, + 'uid':None } self._client_backendmap[backend_link].add(client_link) @@ -188,13 +216,28 @@ class CenterServer(tornado.tcpserver.TCPServer): @imc.async.caller @TOJAuth.check_access(1,TOJAuth.ACCESS_EXECUTE) def _del_client(self,client_link,backend_link): + uid = self._client_linkmap[client_link]['uid'] + + if uid != None: + clients = self._uid_clientmap[uid] + del clients[client_link] + + if len(clients) == 0: + del self._uid_clientmap[uid] + del self._client_linkmap[client_link] self._client_backendmap[backend_link].remove(client_link) Proxy.instance.unlink_conn(client_link) + @imc.async.caller + def _get_uid_clientlink(self,uid): + if uid in self._uid_clientmap: + clients = self._uid_clientmap[uid] + return list(clients.keys()) + return [] @imc.async.caller def _test_get_client_list(self,talk,talk2): diff --git a/src/py/imc/proxy.py b/src/py/imc/proxy.py index 8f750c0..da4bfd4 100755 --- a/src/py/imc/proxy.py +++ b/src/py/imc/proxy.py @@ -621,12 +621,3 @@ class Proxy: def _abort_sendfile(self,filekey): if filekey in self._info_filekeymap: self._ioloop.add_callback(self._ret_sendfile,filekey,'Eabort') - -def imc_call(dst,func_name,*args): - return Proxy.instance.call(dst,func_name,65536,*args) - -def imc_call_async(dst,func_name,callback,*args): - Proxy.instance.call_async(dst,func_name,65536,callback,*args) - -def imc_register_call(path,func_name,func): - Proxy.instance.register_call(path,func_name,func) diff --git a/src/py/mail.py b/src/py/mail.py index d3e2fd6..aa01dd6 100644 --- a/src/py/mail.py +++ b/src/py/mail.py @@ -1,6 +1,7 @@ from tojauth import TOJAuth from asyncdb import AsyncDB from user import UserMg +from notice import Notice from imc.proxy import Proxy import imc.proxy import config @@ -70,7 +71,12 @@ class Mail: self._add_mail( uid, to_uid, self.MAIL_TYPE_SENT_BACKUP, False, title, content ) - + username = UserMg.instance.get_user_info_by_uid(uid)['username'] + Notice.instance.send_notice( + to_uid, 'Mail From ' + username, title, None, '/mail/inbox/' + ) + self.notify_client(uid) + self.notify_client(to_uid) @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) def _add_mail(self, uid, from_uid, mail_type, unread, title, content): @@ -254,6 +260,13 @@ class Mail: count = data[0] return count + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def notify_client(self, uid): + for link in self.get_link('client', uid = uid): + Proxy.instance.call_async( + link + 'core/mail/', 'update_mail', 10000, None + ) def load(mod_idendesc, get_link_fn): Mail(mod_idendesc, get_link_fn) diff --git a/src/py/notice.py b/src/py/notice.py new file mode 100644 index 0000000..3a0a988 --- /dev/null +++ b/src/py/notice.py @@ -0,0 +1,236 @@ +from tojauth import TOJAuth +from asyncdb import AsyncDB + +from imc.proxy import Proxy +import imc.proxy +import config + +class Notice: + _accessid = 5 + + NOTICE_LIST_NUM = 10 + + def __init__(self, mod_idendesc, get_link_fn): + Notice.instance = self + Notice.db = AsyncDB(config.CORE_DBNAME, config.CORE_DBUSER, + config.CORE_DBPASSWORD) + Notice._idendesc = mod_idendesc + self.get_link = get_link_fn + + Proxy.instance.register_call( + 'core/notice/', 'list_notice', self.list_notice) + Proxy.instance.register_call( + 'core/notice/', 'read_notice', self.read_notice) + Proxy.instance.register_call( + 'core/notice/', 'del_notice', self.del_notice) + Proxy.instance.register_call( + 'core/notice/', 'get_unseen_count', self.get_unseen_count) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def send_notice(self, uid, title, content, noticemod_path, metadata): + cur = self.db.cursor() + + noticemodid = None + + if noticemod_path != None: + sqlstr = ('SELECT "noticemodid" FROM "NOTICEMOD" WHERE "path" ' + '= %s;') + sqlarr = (noticemod_path, ) + cur.execute(sqlstr, sqlarr) + + for data in cur: + noticemodid = data[0] + + if noticemodid == None: + sqlstr = ('INSERT INTO "NOTICEMOD" ("path") VALUES (%s) ' + 'RETURNING "noticemodid";') + sqlarr = (noticemod_path, ) + cur.execute(sqlstr, sqlarr) + for data in cur: + noticemodid = data[0] + + sqlstr = ('INSERT INTO "NOTICE" ("uid", "title", "content", ' + '"noticemodid", "metadata") VALUES (%s, %s, %s, %s, %s) ' + 'RETURNING "noticeid";') + sqlarr = (uid, title, content, noticemodid, metadata) + cur.execute(sqlstr, sqlarr) + + noticeid = None + for data in cur: + noticeid = data[0] + + unseen_count = self._get_unseen_count(uid) + self.set_unseen_count(uid, unseen_count + 1) + + return noticeid + + @imc.async.caller + def del_notice(self, noticeid): + if( + type(noticeid) != int + ): + return 'Eparameter' + + notice = self.get_notice(noticeid) + if notice == None: + return 'Enoticeid' + + with TOJAuth.change_current_iden(self._idendesc): + self._del_notice(noticeid) + self.notify_client(notice['uid']) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def _del_notice(self, noticeid): + cur = self.db.cursor() + sqlstr = ('DELETE FROM "NOTICE" WHERE "noticeid" = %s;') + sqlarr = (noticeid, ) + cur.execute(sqlstr, sqlarr) + + @imc.async.caller + def list_notice(self, start_index = 0, list_num = NOTICE_LIST_NUM): + if( + type(start_index) != int or + type(list_num) != int + ): + return 'Eparameter' + + uid = UserMg.get_current_uid() + if uid == None: + return 'Euid' + + with TOJAuth.change_current_iden(self._idendesc): + ret = self._list_notice(uid, start_index, list_num) + + return ret + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def _list_notice(self, uid, start_index, list_num): + cur = self.db.cursor() + sqlstr = ('SELECT "noticeid", "title", "content", "time", ' + '"noticemodid", "metadata", "unread" FROM "NOTICE" WHERE ' + '"uid" = %s ORDER BY "noticeid" DESC LIMIT %s OFFSET %s;') + sqlarr = (uid, list_num, start_index) + cur.execute(sqlstr, sqlarr) + + ret = [] + for data in cur: + obj = {} + obj['noticeid'] = data[0] + obj['title'] = data[1] + obj['content'] = data[2] + obj['time'] = data[3] + obj['noticemodid'] = data[4] + obj['metadata'] = data[5] + obj['unread'] = data[6] + ret.append(obj) + + self.set_unseen_count(uid, 0) + + return ret + + @imc.async.caller + def read_notice(self, noticeid): + if( + type(noticeid) != int + ): + return 'Eparameter' + + notice = self.get_notice(noticeid) + if notice == None: + return 'Enoticeid' + + with TOJAuth.change_current_iden(self._idendesc): + self.set_notice_unread(noticeid, False) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def set_notice_unread(self, noticeid, unread): + cur = self.db.cursor() + sqlstr = ('UPDATE "NOTICE" SET "unread" = %s WHERE "noticeid" = %s;') + sqlarr = (unread, noticeid) + cur.execute(sqlstr, sqlarr) + + @imc.async.caller + def get_unseen_count(self): + uid = UserMg.get_current_uid() + if uid == None: + return 'Euid' + + with TOJAuth.change_current_iden(self._idendesc): + unseen_count = self._get_unseen_count(uid) + + return {'unseen_count': unseen_count} + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def _get_unseen_count(self, uid): + cur = self.db.cursor() + sqlstr = ('SELECT "unseen_count" FROM "NOTICE_UNSEEN" WHERE ' + '"uid" = %s;') + sqlarr = (uid, ) + cur.execute(sqlstr, sqlarr) + + unseen_count = None + for data in cur: + unseen_count = data[0] + + return unseen_count + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def set_unseen_count(self, uid, unseen_count): + old_unseen_count = self._get_unseen_count(uid) + + cur = self.db.cursor() + sqlstr = ('UPDATE "NOTICE_UNSEEN" SET "unseen_count" = %s WHERE ' + '"uid" = %s;') + sqlarr = (unseen_count, uid) + cur.execute(sqlstr, sqlarr) + + if old_unseen_count != unseen_count: + self.notify_client(uid) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def create_unseen_count(self, uid): + cur = self.db.cursor() + sqlstr = ('INSERT INTO "NOTICE_UNSEEN" ("uid", "unseen_count") ' + 'VALUES (%s, %s);') + sqlarr = (uid, 0) + cur.execute(sqlstr, sqlarr) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def notify_client(self, uid): + unseen_count = self._get_unseen_count(uid) + + for link in self.get_link('client', uid = uid): + Proxy.instance.call_async( + link + 'core/notice/', 'update_notice', 10000, None, unseen_count + ) + + def get_notice(self, noticeid): + cur = self.db.cursor() + sqlstr = ('SELECT "noticeid", "uid", "title", "content", "time", ' + '"noticemodid", "metadata", "unread" FROM "NOTICE" WHERE ' + '"noticeid" = %s;') + sqlarr = (noticeid, ) + cur.execute(sqlstr, sqlarr) + + ret = None + for data in cur: + ret = {} + ret['noticeid'] = data[0] + ret['uid'] = data[1] + ret['title'] = data[2] + ret['content'] = data[3] + ret['time'] = data[4] + ret['noticemodid'] = data[5] + ret['metadata'] = data[6] + ret['unread'] = data[7] + + if ret == None: + return None + + uid = UserMg.get_current_uid() + if uid != ret['uid']: + TOJAuth.check_access_func(self._accessid, TOJAuth.ACCESS_EXECUTE) + + return ret + +from user import UserMg diff --git a/src/py/square.py b/src/py/square.py new file mode 100644 index 0000000..68f1be4 --- /dev/null +++ b/src/py/square.py @@ -0,0 +1,311 @@ +from tojauth import TOJAuth +from asyncdb import AsyncDB +from user import UserMg +import imc.proxy +import config + +class SquareMg: + _accessid = 4 + + TITLE_LEN_MIN = 1 + TITLE_LEN_MAX = 100 + + SQUARE_CATE_NUM_MAX = 50 + + def __init__(self, mod_idendesc, get_link_fn): + SquareMg.instance = self + SquareMg.db = AsyncDB(config.CORE_DBNAME, config.CORE_DBUSER, + config.CORE_DBPASSWORD) + SquareMg._idendesc = mod_idendesc + self.get_link = get_link_fn + + @imc.async.caller + def create_square(self, title, hidden, sqmodid, category = []): + if( + type(title) != str or + type(hidden) != bool or + type(sqmodid) != int or + type(category) != list + ): + return 'Eparameter' + + for cateid in category: + if( + type(cateid) != int + ): + return 'Eparameter' + + if len(title) < self.TITLE_LEN_MIN: + return 'Etitle_too_short' + elif len(title) > self.TITLE_LEN_MAX: + return 'Etitle_too_long' + + if len(category) > self.SQUARE_CATE_NUM_MAX: + return 'Etoo_many_category' + + category = list(set(category)) + + for cateid in category: + if not self.does_cateid_exist(cateid): + return 'Eno_such_cateid' + + sqid = self._create_square(title, hidden, sqmodid) + self._set_square_category(sqid, category) + return {'sqid': sqid} + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_CREATE) + def _create_square(self, title, hidden, sqmodid): + cur = self.db.cursor() + sqlstr = ('INSERT INTO "SQUARE" ("title", "hidden", "sqmodid", ' + '"accessid") VALUES (%s, %s, %s, %s) RETURNING "sqid";') + sqlarr = (title, hidden, sqmodid, 0) + cur.execute(sqlstr, sqlarr) + + sqid = None + for data in cur: + sqid = data[0] + + if sqid != None: + user_idenid = TOJAuth.get_current_iden()['idenid'] + with TOJAuth.change_current_iden(self._idendesc): + accessid = TOJAuth.instance.create_access(user_idenid) + + sqlstr = ('UPDATE "SQUARE" SET "accessid" = %s WHERE "sqid" = %s;') + sqlarr = (accessid, sqid) + cur.execute(sqlstr, sqlarr) + + with TOJAuth.change_current_iden(self._idendesc): + TOJAuth.instance.set_access_list( + accessid, TOJAuth.ROLEID_SQUARE_ADMIN_GROUP, + TOJAuth.ACCESS_ALL + ) + + # sqmod.create_square_data(sqid) + + return sqid; + + @imc.async.caller + def delete_square(self, sqid): + if( + type(sqid) != int + ): + return 'Eparameter' + + if not self.does_sqid_exist(sqid): + return 'Eno_such_sqid' + + self._delete_square(self, sqid) + + def _delete_square(self, sqid): + accessid = self.get_accessid_by_sqid(sqid) + TOJAuth.check_access_func(accessid, TOJAuth.ACCESS_DELETE) + + # sqmod.delete_square_data(sqid) + + with TOJAuth.change_current_iden(self._idendesc): + TOJAuth.instance.del_access(accessid) + + cur = self.db.cursor() + sqlstr = ('DELETE FROM "SQUARE" WHERE "sqid" = %s;') + sqlarr = (sqid, ) + cur.execute() + + @imc.async.caller + def list_square(self, cateid = None): + if( + cateid != None and type(cateid) != int + ): + return 'Eparameter' + + ret = None + if cateid == None: + ret = self._list_square_all() + else: + if not self.does_cateid_exist(cateid): + return 'Eno_such_cateid' + ret = self._list_square_category(cateid) + + return ret + + def _list_square_category(self, cateid): + cur = self.db.cursor() + sqlstr = ('SELECT "sqid", "title", "start_time", "end_time", "hidden",' + ' "sqmodid" FROM "SQUARE" WHERE %s = ANY ("cateid");') + sqlarr = (cateid, ) + cur.execute(sqlstr, sqlarr) + + ret = [] + for data in cur: + obj = {} + obj['sqid'] = data[0] + obj['title'] = data[1] + obj['start_time'] = data[2] + obj['end_time'] = data[3] + obj['hidden'] = data[4] + obj['sqmodid'] = data[5] + ret.append(obj) + + return ret + + def _list_square_all(self): + cur = self.db.cursor() + sqlstr = ('SELECT "sqid", "title", "start_time", "end_time", "hidden",' + ' "sqmodid" FROM "SQUARE";') + cur.execute(sqlstr) + + ret = [] + for data in cur: + obj = {} + obj['sqid'] = data[0] + obj['title'] = data[1] + obj['start_time'] = data[2] + obj['end_time'] = data[3] + obj['hidden'] = data[4] + obj['sqmodid'] = data[5] + ret.append(obj) + + return ret + + @imc.async.caller + def create_group(): + pass + + @imc.async.caller + def del_group(): + pass + + @imc.async.caller + def list_group(): + pass + + @imc.async.caller + def group_create_square(): + pass + + @imc.async.caller + def group_remove_square(): + pass + + @imc.async.caller + def group_list_square(): + pass + + @imc.async.caller + def create_category(self, catename): + if( + type(catename) != str + ): + return 'Eparameter' + + cateid = self._create_category(catename) + return cateid + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_CREATE) + def _create_category(self, catename): + cur = self.db.cursor() + sqlstr = ('INSERT INTO "CATEGORY" ("catename") VALUES (%s) RETURNING ' + '"cateid";') + sqlarr = (catename, ) + cur.execute(sqlstr, sqlarr) + + cateid = None + for data in cur: + cateid = data[0] + + return cateid + + @imc.async.caller + def set_square_category(self, sqid, category): + if( + type(sqid) != int or + type(category) != list + ): + return 'Eparameter' + + for cateid in category: + if( + type(cateid) != int + ): + return 'Eparameter' + + if len(category) > self.SQUARE_CATE_NUM_MAX: + return 'Etoo_many_category' + + category = list(set(category)) + + if not self.does_sqid_exist(sqid): + return 'Eno_such_sqid' + + for cateid in category: + if not self.does_cateid_exist(cateid): + return 'Eno_such_cateid' + + self._set_square_category(sqid, category) + + def _set_square_category(self, sqid, category): + sq_accessid = self.get_accessid_by_sqid(sqid) + TOJAuth.check_access_func(sq_accessid, TOJAuth.ACCESS_WRITE) + + cur = self.db.cursor() + sqlstr = ('UPDATE "SQUARE" SET "cateid" = %s WHERE "sqid" = %s;') + sqlarr = (category, sqid) + cur.execute(sqlstr, sqlarr) + + def get_square_info_by_sqid(self, sqid): + cur = self.db.cursor() + sqlstr = ('SELECT "sqid", "title", "start_time", "end_time", ' + '"hidden", "sqmodid", "cateid" FROM "SQUARE" WHERE ' + '"sqid" = %s;') + sqlarr = (sqid, ) + cur.execute(sqlstr, sqlarr) + + ret = None + for data in cur: + ret = {} + ret['sqid'] = data[0] + ret['title'] = data[1] + ret['start_time'] = data[2] + ret['end_time'] = data[3] + ret['hidden'] = data[4] + ret['sqmodid'] = data[5] + ret['cateid'] = data[6] + + return ret + + def does_sqid_exist(self, sqid): + ret = self.get_square_info_by_sqid(sqid) + return ret != None + + def get_accessid_by_sqid(self, sqid): + cur = self.db.cursor() + sqlstr = ('SELECT "accessid" FROM "SQUARE" WHERE "sqid" = %s;') + sqlarr = (sqid, ) + cur.execute(sqlstr, sqlarr) + + accessid = None + for data in cur: + accessid = data[0] + + return accessid + + def get_catename_by_cateid(self, cateid): + cur = self.db.cursor() + sqlstr = ('SELECT "catename" FROM "CATEGORY" WHERE "cateid" = %s;') + sqlarr = (cateid, ) + cur.execute(sqlstr, sqlarr) + + catename = None + for data in cur: + catename = data[0] + + return catename + + def does_cateid_exist(self, cateid): + catename = self.get_catename_by_cateid(cateid) + return catename != None + +class Square: + pass + +class Group: + pass diff --git a/src/py/user.py b/src/py/user.py index 3c58c03..33c2c6c 100755 --- a/src/py/user.py +++ b/src/py/user.py @@ -22,6 +22,8 @@ class UserMg: AVATAR_LEN_MAX = 200 ABOUTME_LEN_MIN = 0 ABOUTME_LEN_MAX = 1000 + COVER_LEN_MIN = 0 + COVER_LEN_MAX = 200 def __init__(self, mod_idendesc, get_link_fn): UserMg.instance = self @@ -40,16 +42,21 @@ class UserMg: 'core/user/', 'get_user_info', self.get_user_info) Proxy.instance.register_call( 'core/user/', 'set_user_info', self.set_user_info) + Proxy.instance.register_call( + 'core/user/', 'change_user_password', self.change_user_password) @imc.async.caller - def register(self, username, password, nickname, email, avatar, aboutme): + def register( + self, username, password, nickname, email, avatar, aboutme, cover + ): if( type(username) != str or type(password) != str or type(nickname) != str or type(email) != str or type(avatar) != str or - type(aboutme) != str + type(aboutme) != str or + type(cover) != str ): return 'Eparameter' @@ -77,32 +84,44 @@ class UserMg: return 'Eaboutme_too_short' elif len(aboutme) > self.ABOUTME_LEN_MAX: return 'Eaboutme_too_long' + elif len(cover) < self.COVER_LEN_MIN: + return 'Ecover_too_short' + elif len(cover) > self.COVER_LEN_MAX: + return 'Ecover_too_long' passhash = self._password_hash(password) with TOJAuth.change_current_iden(self._idendesc): try: uid = self._create_user( - username, passhash, nickname, email, avatar, aboutme) + username, passhash, nickname, email, avatar, aboutme, cover + ) except psycopg2.IntegrityError: return 'Eusername_exists' return {'uid' : uid} @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) - def _create_user(self, username, passhash, nickname, email, avatar, - aboutme): + def _create_user( + self, username, passhash, nickname, email, avatar, aboutme, cover + ): roleid = TOJAuth.instance.create_role(username, TOJAuth.ROLETYPE_USER) cur = self.db.cursor() sqlstr = ('INSERT INTO "USER" ("username", "passhash", "nickname", ' - '"email", "avatar", "aboutme", "idenid") ' - 'VALUES (%s, %s, %s, %s, %s, %s, %s) RETURNING "uid";') - sqlarr = (username, passhash, nickname, email, avatar, aboutme, roleid) + '"email", "avatar", "aboutme", "cover", "idenid") ' + 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s) RETURNING "uid";') + sqlarr = ( + username, passhash, nickname, email, avatar, aboutme, cover, roleid + ) cur.execute(sqlstr, sqlarr) for data in cur: uid = data[0] + + with TOJAuth.change_current_iden(self._idendesc): + Notice.instance.create_unseen_count(uid) + return uid @imc.async.caller @@ -130,13 +149,14 @@ class UserMg: idenid = data[0] if idenid == None: - return 'Elogin_faild' + return 'Elogin_failed' + client_link = TOJAuth.get_current_iden()['link'] with TOJAuth.change_current_iden(self._idendesc): stat,data = Proxy.instance.call(self.get_link('center'), 'create_iden', 10000, - TOJAuth.get_current_iden()['link'], + client_link, idenid, TOJAuth.ROLETYPE_USER, {'uid' : uid}) @@ -178,11 +198,12 @@ class UserMg: if real_uphash != uphash: return 'Elogin_failed' + client_link = TOJAuth.get_current_iden()['link'] with TOJAuth.change_current_iden(self._idendesc): stat,data = Proxy.instance.call(self.get_link('center'), 'create_iden', 10000, - TOJAuth.get_current_iden()['link'], + client_link, idenid, TOJAuth.ROLETYPE_USER, {'uid' : uid}) @@ -212,13 +233,14 @@ class UserMg: return ret @imc.async.caller - def set_user_info(self, uid, nickname, email, avatar, aboutme): + def set_user_info(self, uid, nickname, email, avatar, aboutme, cover): if( type(uid) != int or type(nickname) != str or type(email) != str or type(avatar) != str or - type(aboutme) != str + type(aboutme) != str or + type(cover) != str ): return 'Eparameter' @@ -238,6 +260,10 @@ class UserMg: return 'Eaboutme_too_short' elif len(aboutme) > self.ABOUTME_LEN_MAX: return 'Eaboutme_too_long' + elif len(cover) < self.COVER_LEN_MIN: + return 'Ecover_too_short' + elif len(cover) > self.COVER_LEN_MAX: + return 'Ecover_too_long' idenid = self.get_idenid_by_uid(uid) if idenid == None: @@ -249,8 +275,9 @@ class UserMg: cur = self.db.cursor() sqlstr = ('UPDATE "USER" SET "nickname" = %s, "email" = %s, ' - '"avatar" = %s, "aboutme" = %s WHERE "uid" = %s;') - sqlarr = (nickname, email, avatar, aboutme, uid) + '"avatar" = %s, "aboutme" = %s, "cover" = %s WHERE ' + '"uid" = %s;') + sqlarr = (nickname, email, avatar, aboutme, cover, uid) cur.execute(sqlstr, sqlarr) @imc.async.caller @@ -310,7 +337,8 @@ class UserMg: def get_user_info_by_uid(self, uid): cur = self.db.cursor() - sqlstr = ('SELECT * FROM "USER" WHERE "uid" = %s;') + sqlstr = ('SELECT "uid", "username", "nickname", "email", "avatar", ' + '"aboutme", "cover" FROM "USER" WHERE "uid" = %s;') sqlarr = (uid, ) cur.execute(sqlstr, sqlarr) @@ -319,10 +347,11 @@ class UserMg: ret = {} ret['uid'] = data[0] ret['username'] = data[1] - ret['nickname'] = data[3] - ret['email'] = data[4] - ret['avatar'] = data[5] - ret['aboutme'] = data[6] + ret['nickname'] = data[2] + ret['email'] = data[3] + ret['avatar'] = data[4] + ret['aboutme'] = data[5] + ret['cover'] = data[6] return ret @@ -374,3 +403,6 @@ def load(mod_idendesc, get_link_fn): def unload(): pass + +from notice import Notice + |