diff options
author | pzread <netfirewall@gmail.com> | 2013-06-26 01:49:13 +0800 |
---|---|---|
committer | pzread <netfirewall@gmail.com> | 2013-06-26 01:49:13 +0800 |
commit | 17c8c94e097018ccaf15f8a9296b03b5195cc3f7 (patch) | |
tree | f3c32a7a7a272f0ab0c2236928c4b78e36846d56 | |
parent | e0043639746fdbbf4958c67a3ef55c63c2fe51a5 (diff) | |
download | taiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.tar.gz taiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.tar.zst taiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.zip |
Add square page. Add AsyncMCD. Add sqmod manage
-rw-r--r-- | src/css/index.less | 1 | ||||
-rw-r--r-- | src/css/square.less | 53 | ||||
-rw-r--r-- | src/css/style.less | 6 | ||||
-rw-r--r-- | src/html/index.html | 28 | ||||
-rw-r--r-- | src/html/square.html | 9 | ||||
-rw-r--r-- | src/js/com.js | 4 | ||||
-rw-r--r-- | src/js/index.js | 12 | ||||
-rw-r--r-- | src/js/mail.js | 87 | ||||
-rw-r--r-- | src/js/notice.js | 29 | ||||
-rw-r--r-- | src/js/square.js | 275 | ||||
-rw-r--r-- | src/js/user.js | 13 | ||||
-rw-r--r-- | src/py/asyncmcd.py | 143 | ||||
-rwxr-xr-x | src/py/backend_server.py | 29 | ||||
-rwxr-xr-x | src/py/center_server.py | 10 | ||||
-rw-r--r-- | src/py/mail.py | 33 | ||||
-rw-r--r-- | src/py/mod.py | 50 | ||||
-rw-r--r-- | src/py/notice.py | 16 | ||||
-rw-r--r-- | src/py/square.py | 323 | ||||
-rwxr-xr-x | src/py/user.py | 18 |
19 files changed, 898 insertions, 241 deletions
diff --git a/src/css/index.less b/src/css/index.less index 81d9546..83885ba 100644 --- a/src/css/index.less +++ b/src/css/index.less @@ -143,6 +143,5 @@ body{ #index_footer{ margin-top:@MediumPad; padding:@MediumPad @MediumPad 0px @MediumPad; - background-color:@lightgray; text-align:right; } diff --git a/src/css/square.less b/src/css/square.less new file mode 100644 index 0000000..022f9e4 --- /dev/null +++ b/src/css/square.less @@ -0,0 +1,53 @@ +@import 'color.less'; +@import 'mixin.less'; + +#index_page{ + div.catelist{ + position:fixed; + } + div.indexlist{ + div.catebox{ + margin-bottom:@MediumPad; + + & > h4{ + display:none; + } + } + div.boxlist{ + margin-bottom:@MediumPad; + display:none; + + div.box{ + height:108px; + margin-bottom:12px; + box-shadow:0px 0px 6px 0px fade(@black,30%); + position:relative; + + img.logo{ + height:108px; + margin-right:@SmallPad; + float:left; + } + div.time{ + line-height:12px; + } + p.intro{ + margin-top:@SmallPad; + font-size:@SmallFontSize; + } + div.oper{ + position:absolute; + top:6px; + right:6px; + } + + &:hover{ + box-shadow:0px 0px 6px 1px fade(@black,30%); + } + &:nth-child(2n - 1){ + margin-left:0px; + } + } + } + } +} diff --git a/src/css/style.less b/src/css/style.less index c36c429..c754f57 100644 --- a/src/css/style.less +++ b/src/css/style.less @@ -2,6 +2,11 @@ @import "color.less"; @import "index.less"; +@font-face{ + font-family:monospace; + src:url('/DejaVuSansMono.woff'); +} + div.medium_modal{ width:970px; margin-left:-485px; @@ -28,6 +33,7 @@ span.check_bold{ } .time{ font-size:@SmallFontSize; + font-family:monospace; } .uneditable-input{ cursor:default; diff --git a/src/html/index.html b/src/html/index.html index b8795ea..28632de 100644 --- a/src/html/index.html +++ b/src/html/index.html @@ -25,6 +25,7 @@ <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/square.js" type="text/javascript"></script> <script src="/toj/js/mail.js" type="text/javascript"></script> <script type="text/javascript"> @@ -40,6 +41,7 @@ $(document).ready(function(){ notice.ready(); index.ready(); home.ready(); + square.ready(); mail.ready(); j_win.on('resize',com.exheight); @@ -85,6 +87,7 @@ $(document).ready(function(){ <ul class="nav nav-list"> <li><a href="/toj/home/">首頁</a></li> <li class="profile" style="display:none;"><a href="">個人</a></li> + <li class="square" style="display:none;"><a href="/toj/square/user/">方塊</a></li> <li class="mail" style="display:none;"><a href="/toj/mail/inbox/">信箱</a></li> <li><a href="#">狀態</a></li> <li><a href="#">關於</a></li> @@ -93,33 +96,12 @@ $(document).ready(function(){ </div> <div id="index_paneltag" class="active"> - <div class="notice"></div> + <div class="notice" style="display:none;"></div> </div> <div id="index_panel" exheight=true> <div class="tagblock"></div> <div class="notice" exheight=true extop=41px> - <ul class="nav nav-list"> - <li><a href="#"> - <h5>Mail From Alice</h5> - Hey, don't challenge me! - </a></li> - <li><a href="#"> - <h5>Challenge Success</h5> - You get +50 points - </a></li> - <li><a href="#"> - <h5>Submit 573</h5> - Result:WA Score:37 - </a></li> - <li><a href="#"> - <h5>Submit 570</h5> - Result:WA Score:23 - </a></li> - <li><a href="#"> - <h5>Submit 565</h5> - Result:AC Score:100 - </a></li> - </ul> + <ul class="nav nav-list"></ul> </div> </div> diff --git a/src/html/square.html b/src/html/square.html new file mode 100644 index 0000000..483ba0a --- /dev/null +++ b/src/html/square.html @@ -0,0 +1,9 @@ +<link href="/toj/css/square.css" rel="stylesheet"> + +<div class="row"> + <div class="span3 catelist"> + <h3>分類</h3> + <ul class="nav nav-tabs nav-stacked catelist"></ul> + </div> + <div class="span10 offset3 indexlist"></div> +</div> diff --git a/src/js/com.js b/src/js/com.js index 3e50173..64d76a2 100644 --- a/src/js/com.js +++ b/src/js/com.js @@ -684,10 +684,10 @@ var com = new function(){ imc.Auth.change_current_iden(idendesc) - if((cookie = that.get_cookie()) != null){ + if((cookie = that.get_cookie()).uid != undefined){ that.call_backend('core/user/','cookie_login',function(result){ if(that.is_callerr(result)){ - //TODO GE + index.add_alert('','登入發生錯誤'); }else{ imc.Auth.change_current_iden(result.data.idendesc); user.uid = imc.Auth.get_current_iden().uid; diff --git a/src/js/index.js b/src/js/index.js index 3ea93fc..33e22b4 100644 --- a/src/js/index.js +++ b/src/js/index.js @@ -114,10 +114,18 @@ var index = new function(){ user.login_callback.add(function(){ var j_li; + + j_header.find('li.login').hide(); + j_header.find('li.register').hide(); + j_header.find('li.nickname').show(); + j_header.find('li.logout').show(); + - j_li = j_menu.find('div.menu li.profile') + j_li = j_menu.find('div.menu li.profile'); j_li.find('a').attr('href','/toj/user:' + user.uid + '/main/'); j_li.show(); + + j_menu.find('div.menu li.square').show(); j_menu.find('div.menu li.mail').show(); }); @@ -161,7 +169,7 @@ var index = new function(){ if(autofade != false){ setTimeout(function(){ j_alert.alert('close'); - },10000); + },5000); } j_alertbox.prepend(j_alert); diff --git a/src/js/mail.js b/src/js/mail.js index 0abe12a..a3a357a 100644 --- a/src/js/mail.js +++ b/src/js/mail.js @@ -4,8 +4,8 @@ var mail = new function(){ var j_maillist; var j_newmail; var j_readmail; - var j_tabnav_inbox; - var j_tabnav_backup; + var inbox_tabnav; + var backup_tabnav; var readmail_mailid = null; var maillist_type = null; @@ -57,28 +57,52 @@ var mail = new function(){ j_index_page.find('span.checkall').check(false); + com.call_backend('core/mail/','get_mail_count',function(result){ + var i; + var j_div = j_index_page.find('div.pagination'); + var offs; + var as; + var pfix; + + if(com.is_callerr(result)){ + index.add_alert('','警告','信箱發生錯誤'); + }else{ + if(maillist_type == 1){ + pfix = '/toj/mail/inbox:'; + }else if(maillist_type == 2){ + pfix = '/toj/mail/backup:'; + } + + offs = com.create_pagination(j_div,0,result.data.tot_count,maillist_off,20); + as = j_div.find('a'); + for(i = 0;i < as.length;i++){ + $(as[i]).attr('href',pfix + offs[i] + '/'); + } + } + },maillist_type); + com.call_backend('core/mail/','list_mail',function(result){ var data; - var mail; + var mailo; var items; var j_item; var i; if(com.is_callerr(result)){ - //TODO GE + index.add_alert('','警告','信箱發生錯誤'); }else{ data = result.data; items = j_maillist.find('tr.item'); for(i = 0;i < Math.min(items.length,data.length);i++){ - mail = data[i]; + mailo = data[i]; - mailitem_set($(items[i]),mail.mailid,mail.from_username,mail.title,com.get_timestring(mail.send_time),mail.unread); + mailitem_set($(items[i]),mailo.mailid,mailo.from_username,mailo.title,com.get_timestring(mailo.send_time),mailo.unread); } for(;i < data.length;i++){ - mail = data[i]; + mailo = data[i]; - j_item = mailitem_create(mail.mailid,mail.from_username,mail.title,com.get_timestring(mail.send_time),mail.unread); + j_item = mailitem_create(mailo.mailid,mailo.from_username,mailo.title,com.get_timestring(mailo.send_time),mailo.unread); j_maillist.append(j_item); } for(;i < items.length;i++){ @@ -104,7 +128,6 @@ var mail = new function(){ if(direct == 'in'){ index.set_menu('信箱'); index.set_title(''); - index.clear_tabnav(); mail_node.child_delayset('inbox'); @@ -120,8 +143,8 @@ var mail = new function(){ newmail_content = com.create_codebox(j_newmail.find('div.content'),'text/html'); readmail_content = com.create_codebox(j_readmail.find('div.content'),'text/html',true); - j_tabnav_inbox = index.add_tabnav('收件匣','/toj/mail/inbox/'); - j_tabnav_backup = index.add_tabnav('寄件備份','/toj/mail/backup/'); + inbox_tabnav = index.add_tabnav('收件匣','/toj/mail/inbox/'); + backup_tabnav = index.add_tabnav('寄件備份','/toj/mail/backup/'); j_index_page.find('button.newmail').on('click',function(e){ j_newmail.modal('show'); @@ -183,7 +206,7 @@ var mail = new function(){ }else if(data == 'Eto_username'){ errmsg = '收件人不存在'; }else{ - errmsg = '信件寄出時發生錯誤'; + errmsg = '信件寄出發生錯誤'; } index.add_alert('alert-error','失敗',errmsg,true); @@ -202,7 +225,7 @@ var mail = new function(){ var data; if(com.is_callerr(result)){ - //TODO GE + index.add_alert('','警告','讀取郵件發生錯誤'); }else{ data = result.data; @@ -256,27 +279,10 @@ var mail = new function(){ maillist_off = parseInt(param); } - j_tabnav_inbox.active(); + inbox_tabnav.active(); j_index_page.find('table.maillist th.username').text('寄件人'); j_readmail.find('span.username_label').text('寄件人'); - com.call_backend('core/mail/','get_mail_count',function(result){ - var i; - var j_div = j_index_page.find('div.pagination'); - var offs; - var as; - - if(com.is_callerr(result)){ - //TODO GE - }else{ - offs = com.create_pagination(j_div,0,result.data.tot_count,maillist_off,20); - as = j_div.find('a'); - for(i = 0;i < as.length;i++){ - $(as[i]).attr('href','/toj/mail/inbox:' + offs[i] + '/'); - } - } - },maillist_type); - update_maillist(); }else if(direct == 'out'){ maillist_type = null; @@ -295,27 +301,10 @@ var mail = new function(){ maillist_off = parseInt(param); } - j_tabnav_backup.active(); + backup_tabnav.active(); j_index_page.find('table.maillist th.username').text('收件人'); j_readmail.find('span.username_label').text('收件人'); - com.call_backend('core/mail/','get_mail_count',function(result){ - var i; - var j_div = j_index_page.find('div.pagination'); - var offs; - var as; - - if(com.is_callerr(result)){ - //TODO GE - }else{ - offs = com.create_pagination(j_div,0,result.data.tot_count,maillist_off,20); - as = j_div.find('a'); - for(i = 0;i < as.length;i++){ - $(as[i]).attr('href','/toj/mail/backup:' + offs[i] + '/'); - } - } - },maillist_type); - update_maillist(); }else if(direct == 'out'){ maillist_type = null; diff --git a/src/js/notice.js b/src/js/notice.js index 9bd92eb..3b7dff1 100644 --- a/src/js/notice.js +++ b/src/js/notice.js @@ -28,8 +28,6 @@ var notice = new function(){ if(com.is_callerr(result)){ index.add_alert('','警告','通知發生錯誤'); }else{ - console.log(data); - for(i = 0;i < data.length;i++){ notice = data[i]; @@ -47,20 +45,23 @@ var notice = new function(){ }); }); - imc.Proxy.instance.register_call('core/notice/','update_notice',function(callback,unseen_count){ - _set_unseen_count(unseen_count); - callback('Success'); - }); + user.login_callback.add(function(){ + 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; + 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); - } + if(com.is_callerr(result)){ + index.add_alert('','警告','通知發生錯誤'); + }else{ + _set_unseen_count(data.unseen_count); + } + }); + + j_noticetag.show(); }); }; - }; diff --git a/src/js/square.js b/src/js/square.js new file mode 100644 index 0000000..a8431f9 --- /dev/null +++ b/src/js/square.js @@ -0,0 +1,275 @@ +var square = new function(){ + var that = this; + var j_index_page; + var j_catelist; + var j_indexlist; + + that.ready = function(){ + var square_node = new vus.node('square'); + var user_node = new vus.node('user'); + var index_node = new vus.node('index'); + var user_tabnav; + var index_tabnav; + + function box_set(j_box,id,logo,title,start_time,end_time,intro,active){ + var j_oper; + + j_box.attr('boxid',id); + + j_box.find('img.logo').attr('src',logo); + j_box.find('h5.title').text(title); + j_box.find('p.intro').text(intro); + + if(start_time != null || end_time != null){ + if(start_time != null){ + j_box.find('div.start').text('┌─' + start_time); + } + if(end_time != null){ + j_box.find('div.end').text('└→' + end_time); + } + } + + j_oper = j_box.find('div.oper'); + j_oper.empty(); + if(active == null){ + j_oper.append('<button class="btn btn-primary join" data-loading-text="處理中">加入</button><button class="btn">開啓</button>'); + j_oper.find('button.join').on('click',function(e){ + $(this).button('loading'); + + com.call_backend('core/square/','join_square',function(result){ + var data = result.data; + + if(com.is_callerr(result)){ + if(data == 'Ereject'){ + index.add_alert('alert-error','拒絕','加入請求被拒絕'); + }else if(data == 'Eno_such_sqid'){ + index.add_alert('alert-error','錯誤','方塊不存在'); + }else{ + index.add_alert('alert-error','錯誤','操作方塊發生錯誤'); + } + }else{ + box_update(id,logo,title,start_time,end_time,intro,data.active); + } + },id); + }); + }else{ + if(active== true){ + j_oper.append('<button class="btn btn-success quit" data-loading-text="處理中">退出</button><button class="btn">開啓</button>'); + }else{ + j_oper.append('<button class="btn btn-warning quit" data-loading-text="處理中">取消申請</button><button class="btn">開啓</button>'); + } + + j_oper.find('button.quit').on('click',function(e){ + $(this).button('loading'); + + com.call_backend('core/square/','quit_square',function(result){ + var data = result.data; + + if(com.is_callerr(result)){ + if(data == 'Eno_such_sqid'){ + index.add_alert('alert-error','錯誤','方塊不存在'); + }else{ + index.add_alert('alert-error','錯誤','操作方塊發生錯誤'); + } + }else{ + box_update(id,logo,title,start_time,end_time,intro,null); + } + },id); + }); + } + } + function box_update(id,logo,title,start_time,end_time,intro,active){ + var i; + var boxs; + + boxs = j_indexlist.find('[boxid="' + id + '"]'); + for(i = 0;i < boxs.length;i++){ + box_set($(boxs[i]),id,logo,title,start_time,end_time,intro,active); + } + } + function box_create(id,logo,title,start_time,end_time,intro,active){ + var j_box = $('<div class="span5 box"><img class="logo"></img><h5 class="title"></h5><div class="time start"></div><div class="time end"></div><p class="intro"></p><div class="btn-group oper"></div></div>'); + + box_set(j_box,id,logo,title,start_time,end_time,intro,active); + + return j_box; + } + function catebox_set(j_box,cateid,catename){ + j_box.attr('cateid',cateid); + j_box.find('h3.catename').text(catename); + } + function catebox_create(cateid,catename){ + var j_box = $('<div class="catebox"><h3 class="catename"></h3><h4 class="run">進行中</h4><div class="clearfix boxlist run"></div><h4 class="pend">等待中</h4><div class="clearfix boxlist pend"></div><h4 class="past">已結束</h4><div class="clearfix boxlist past"></div>'); + + catebox_set(j_box,cateid,catename); + + return j_box; + } + + function catelist_update(){ + var defer = $.Deferred(); + + com.call_backend('core/square/','list_category',function(result){ + var data = result.data; + + if(com.is_callerr(result)){ + index.add_alert('','警告','方塊目錄發生錯誤'); + defer.reject(); + }else{ + defer.resolve(data); + } + }); + + return defer.promise(); + } + function indexlist_update(catelist,joined){ + var i; + var j_catebox; + var cateo; + + j_catelist.empty(); + j_indexlist.empty(); + for(i = 0;i < catelist.length;i++){ + cateo = catelist[i]; + + com.call_backend('core/square/','list_square',function(cateo){return function(result){ + var i; + var data = result.data; + var sqo; + var logo; + var start_time; + var end_time; + var j_cate; + var j_box; + var j_run; + var j_pend; + var j_past; + var j_a; + + if(com.is_callerr(result)){ + index.add_alert('','警告','方塊目錄發生錯誤'); + }else{ + if(data.length == 0){ + return; + } + + j_cate = $('<li><a href=""></a></li>'); + j_a = j_cate.find('a'); + j_a.text(cateo.catename); + j_a.on('click',function(e){ + $(window).scrollTop(j_indexlist.find('[cateid="' + cateo.cateid + '"]').offset().top - 66); + return false; + }); + j_catelist.append(j_cate); + + j_catebox = catebox_create(cateo.cateid,cateo.catename); + j_indexlist.append(j_catebox); + + j_run = j_catebox.find('div.run'); + j_pend = j_catebox.find('div.pend'); + j_past = j_catebox.find('div.past'); + + for(i = 0;i < data.length;i++){ + sqo = data[i]; + if(joined == true && sqo.active == null){ + continue; + } + + if((logo = sqo.logo) == ''){ + logo = 'http://www.gravatar.com/avatar/' + sqo.sqid + '?f=y&d=identicon&s=96'; + } + if(sqo.start_time == null){ + start_time = null; + }else{ + start_time = com.get_timestring(sqo.start_time); + } + if(sqo.end_time == null){ + end_time = null; + }else{ + end_time = com.get_timestring(sqo.end_time); + } + + j_box = box_create(sqo.sqid,logo,sqo.title,start_time,end_time,sqo.intro,sqo.active); + + if(sqo.status == 1){ + j_pend.append(j_box); + }else if(sqo.status == 2){ + j_run.append(j_box); + }else if(sqo.status == 3){ + j_past.append(j_box); + } + } + + if(j_pend.children().length > 0){ + j_catebox.find('h4.pend').show(); + j_pend.show(); + } + if(j_run.children().length > 0){ + j_catebox.find('h4.run').show(); + j_run.show(); + } + if(j_past.children().length > 0){ + j_catebox.find('h4.past').show(); + j_past.show(); + } + } + }}(cateo),cateo.cateid); + } + } + function update(joined){ + catelist_update().done(function(catelist){ + indexlist_update(catelist,joined); + }); + } + + j_index_page = $('#index_page'); + + square_node.url_chg = function(direct,url_upart,url_dpart,param){ + if(direct == 'in'){ + index.set_menu('方塊'); + index.set_title(''); + index.clear_tabnav(); + + square_node.child_delayset('user'); + square_node.child_delayset('index'); + + com.loadpage('/toj/html/square.html').done(function(){ + j_catelist = j_index_page.find('ul.catelist'); + j_indexlist = j_index_page.find('div.indexlist'); + + user_tabnav = index.add_tabnav('已加入','/toj/square/user/'); + index_tabnav = index.add_tabnav('目錄','/toj/square/index/'); + + square_node.child_set(user_node); + square_node.child_set(index_node); + }); + }else if(direct == 'out'){ + square_node.child_del(user_node); + square_node.child_del(index_node); + } + + return 'cont'; + }; + com.vus_root.child_set(square_node); + + user_node.url_chg = function(direct,url_upart,url_dpart,param){ + if(direct == 'in'){ + user_tabnav.active(); + + update(true); + } + + return 'cont'; + } + + index_node.url_chg = function(direct,url_upart,url_dpart,param){ + if(direct == 'in'){ + index_tabnav.active(); + + update(false); + } + + return 'cont'; + } + }; +}; diff --git a/src/js/user.js b/src/js/user.js index f6d32b9..9e78d83 100644 --- a/src/js/user.js +++ b/src/js/user.js @@ -167,7 +167,7 @@ var user = new function(){ var url; if((url = data.avatar) == ''){ - url = 'http://i.imgur.com/ykkQD.png'; + url = 'http://www.gravatar.com/avatar/' + user_node_uid + '?f=y&d=identicon&s=256'; } j_index_page.find('img.avatar').attr('src',url); if((url = data.cover) == ''){ @@ -231,7 +231,7 @@ var user = new function(){ var url = $(this).val(); if(url == ''){ - url = 'http://i.imgur.com/ykkQD.png'; + url = 'http://www.gravatar.com/avatar/' + that.uid + '?f=y&d=identicon&s=256'; } j_img_avatar.attr('src',url); }); @@ -456,13 +456,4 @@ var user = new function(){ }; com.vus_root.child_set(logout_node); }; - - that.login_callback.add(function(){ - var j_index_header = $('#index_header'); - - j_index_header.find('li.login').hide(); - j_index_header.find('li.register').hide(); - j_index_header.find('li.nickname').show(); - j_index_header.find('li.logout').show(); - }); }; diff --git a/src/py/asyncmcd.py b/src/py/asyncmcd.py new file mode 100644 index 0000000..0a4c0e6 --- /dev/null +++ b/src/py/asyncmcd.py @@ -0,0 +1,143 @@ +import socket +import struct +import json + +import tornado.ioloop +import tornado.stack_context +import tornado.iostream + +import imc.async + +class AsyncMCD: + def __init__(self): + def _conn(): + print('conn') + + self.TYPE_INT = 0 + self.TYPE_BYTES = 1 + self.TYPE_STR = 2 + self.TYPE_JSON = 3 + + self._ioloop = tornado.ioloop.IOLoop.instance() + self._opaque_count = 0 + self._opaque_map = {} + + self._stream = tornado.iostream.IOStream(socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)) + self._stream.connect(('10.8.0.6',11211),_conn) + + self._recv_loop() + + def get(self,key): + def _recv(opcode,status,opaque,cas,extra,key,value): + del self._opaque_map[opaque] + + if status != 0: + imc.async.ret(retid,None) + + else: + flag, = struct.unpack('!I',extra) + if flag == self.TYPE_INT: + ret, = struct.unpack('!Q',value) + + elif flag == self.TYPE_BYTES: + ret = value + + elif flag == self.TYPE_STR: + ret = value.decode('utf-8') + + elif flag == self.TYPE_JSON: + ret = json.loads(value.decode('utf-8')) + + imc.async.ret(retid,ret) + + if not isinstance(key,str): + raise TypeError + + key = bytes(key,'utf-8') + keylen = len(key) + + opaque = self._get_opaque(_recv) + header = self._request_header(0x00,keylen,0,0,keylen,opaque,0) + data = bytes(bytearray().join([header,key])) + + self._stream.write(data) + + retid = imc.async.get_retid() + return imc.async.switch_top() + + def set(self,key,value,expiration = 0): + def _recv(opcode,status,opaque,cas,extra,key,value): + del self._opaque_map[opaque] + imc.async.ret(retid,status) + + if not isinstance(key,str): + raise TypeError + + key = bytes(key,'utf-8') + keylen = len(key) + + if isinstance(value,int): + value_type = self.TYPE_INT + value = struct.pack('!Q',value) + + elif isinstance(value,bytes): + value_type = self.TYPE_BYTES + + elif isinstance(value,str): + value_type = self.TYPE_STR + value = bytes(value,'utf-8') + + else: + value_type = 2 + value = bytes(json.dumps(value),'utf-8') + + valuelen = len(value) + + extra = struct.pack('!II',value_type,expiration) + extralen = len(extra) + + opaque = self._get_opaque(_recv) + header = self._request_header(0x01,keylen,extralen,0,extralen + keylen + valuelen,opaque,0) + data = bytes(bytearray().join([header,extra,key,value])) + + self._stream.write(data) + + retid = imc.async.get_retid() + return imc.async.switch_top() + + def _get_opaque(self,data): + self._opaque_count += 1 + self._opaque_map[self._opaque_count] = data + + return self._opaque_count + + def _request_header(self,opcode,keylen,extralen,vid,totallen,opaque,cas): + return struct.pack('!BBHBBHIIQ',0x80,opcode,keylen,extralen,0x0,vid,totallen,opaque,cas) + + def _recv_loop(self): + def __recv(data): + def ___recvdata(data): + extra = data[0:extralen] + key = data[extralen:extralen + keylen] + value = data[extralen + keylen:totallen] + + self._opaque_map[opaque](opcode,status,opaque,cas,extra,key,value) + self._stream.read_bytes(24,__recv) + + header = struct.unpack('!BBHBBHIIQ',data) + opcode = header[1] + keylen = header[2] + extralen = header[3] + status = header[5] + totallen = header[6] + opaque = header[7] + cas = header[8] + + if totallen == 0: + self._opaque_map[opaque](opcode,status,opaque,cas,bytes(),bytes(),bytes()) + self._stream.read_bytes(24,__recv) + + else: + self._stream.read_bytes(totallen,___recvdata) + + self._stream.read_bytes(24,__recv) diff --git a/src/py/backend_server.py b/src/py/backend_server.py index b9bb07b..71c3b1e 100755 --- a/src/py/backend_server.py +++ b/src/py/backend_server.py @@ -12,16 +12,13 @@ import tornado.tcpserver import tornado.httpserver import tornado.websocket -from imc import auth import imc.async from imc.proxy import Proxy,Connection +import mod import netio from netio import SocketStream,SocketConnection,WebSocketConnection from tojauth import TOJAuth -from notice import Notice -from user import UserMg -from mail import Mail class BackendWorker(tornado.tcpserver.TCPServer): def __init__(self,center_addr,ws_port): @@ -68,7 +65,7 @@ class BackendWorker(tornado.tcpserver.TCPServer): @imc.async.caller def _call(): with TOJAuth.change_current_iden(self._idendesc): - Proxy.instance.call(self.center_conn.link,'add_client',10000,link,self._link) + Proxy.instance.call(self.center_conn.link + 'core/','add_client',10000,link,self._link) self._client_linkmap[link] = {} @@ -84,7 +81,7 @@ class BackendWorker(tornado.tcpserver.TCPServer): @imc.async.caller def _call(): with TOJAuth.change_current_iden(self._idendesc): - Proxy.instance.call(self.center_conn.link,'del_client',10000,link,self._link) + Proxy.instance.call(self.center_conn.link + 'core/','del_client',10000,link,self._link) del self._client_linkmap[link] @@ -111,20 +108,19 @@ class BackendWorker(tornado.tcpserver.TCPServer): self.center_conn.add_close_callback(__retry) Proxy.instance.add_conn(self.center_conn) - Proxy.instance.register_call('test/','get_client_list',self._test_get_client_list) - Proxy.instance.register_call('test/','test_dst',self._test_dst) + #Proxy.instance.register_call('test/','get_client_list',self._test_get_client_list) + #Proxy.instance.register_call('test/','test_dst',self._test_dst) #Proxy.instance.register_filter('test/',self._test_filter) try: - Notice(self._idendesc,self._get_link) - UserMg(self._idendesc,self._get_link) - Mail(self._idendesc,self._get_link) + mod.load('Notice','notice',self._idendesc,self._get_link) + mod.load('UserMg','user',self._idendesc,self._get_link) + mod.load('SquareMg','square',self._idendesc,self._get_link) + mod.load('Mail','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) @@ -185,10 +181,7 @@ class BackendWorker(tornado.tcpserver.TCPServer): return None with TOJAuth.change_current_iden(self._idendesc): - stat,ret = Proxy.instance.call(self.center_conn.link,'lookup_link',65536,link) - - print(link) - print(ret) + stat,ret = Proxy.instance.call(self.center_conn.link + 'core/','lookup_link',65536,link) if stat == False or ret == None: return None diff --git a/src/py/center_server.py b/src/py/center_server.py index bed117d..b4273ef 100755 --- a/src/py/center_server.py +++ b/src/py/center_server.py @@ -73,13 +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) - 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/','lookup_link',self._lookup_link) + Proxy.instance.register_call('core/','create_iden',self._create_iden) + Proxy.instance.register_call('core/','add_client',self._add_client) + Proxy.instance.register_call('core/','del_client',self._del_client) Proxy.instance.register_call('core/','get_uid_clientlink',self._get_uid_clientlink) - Proxy.instance.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): diff --git a/src/py/mail.py b/src/py/mail.py index aa01dd6..7bfa53c 100644 --- a/src/py/mail.py +++ b/src/py/mail.py @@ -1,7 +1,6 @@ from tojauth import TOJAuth from asyncdb import AsyncDB -from user import UserMg -from notice import Notice +import mod from imc.proxy import Proxy import imc.proxy import config @@ -21,7 +20,6 @@ class Mail: LIST_ITEM_PER_PAGE = 20 def __init__(self, mod_idendesc, get_link_fn): - Mail.instance = self Mail.db = AsyncDB(config.CORE_DBNAME, config.CORE_DBUSER, config.CORE_DBPASSWORD) Mail._idendesc = mod_idendesc @@ -56,11 +54,11 @@ class Mail: elif len(content) > self.CONTENT_LEN_MAX: return 'Econtent_too_long' - to_uid = UserMg.instance.get_uid_by_username(to_username) + to_uid = mod.UserMg.get_uid_by_username(to_username) if to_uid == None: return 'Eto_username' - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid == None: return 'Euid' @@ -71,8 +69,8 @@ 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( + username = mod.UserMg.get_user_info_by_uid(uid)['username'] + mod.Notice.send_notice( to_uid, 'Mail From ' + username, title, None, '/mail/inbox/' ) self.notify_client(uid) @@ -100,7 +98,7 @@ class Mail: ): return 'Eparameter' - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid == None: return 'Eno_uid' @@ -137,9 +135,9 @@ class Mail: ret['send_time'] = data[7] ret['to_username'] = ( - UserMg.instance.get_user_info_by_uid(data[1])['username']) + mod.UserMg.get_user_info_by_uid(data[1])['username']) ret['from_username'] = ( - UserMg.instance.get_user_info_by_uid(data[2])['username']) + mod.UserMg.get_user_info_by_uid(data[2])['username']) return ret @@ -159,7 +157,7 @@ class Mail: ): return 'Eparameter' - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid == None: return 'Eno_uid' @@ -189,7 +187,7 @@ class Mail: item['send_time'] = data[4] item['from_username'] = ( - UserMg.instance.get_user_info_by_uid(data[1])['username']) + mod.UserMg.get_user_info_by_uid(data[1])['username']) ret.append(item) @@ -202,7 +200,7 @@ class Mail: ): return 'Eparameter' - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid == None: return 'Eno_uid' @@ -227,7 +225,7 @@ class Mail: @imc.async.caller def get_mail_count(self, mail_type = None): - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid == None: return 'Eno_uid' @@ -268,8 +266,5 @@ class Mail: link + 'core/mail/', 'update_mail', 10000, None ) -def load(mod_idendesc, get_link_fn): - Mail(mod_idendesc, get_link_fn) - -def unload(): - pass + def unload(): + pass diff --git a/src/py/mod.py b/src/py/mod.py index c41b839..e67a9e6 100644 --- a/src/py/mod.py +++ b/src/py/mod.py @@ -1,33 +1,35 @@ import sys +import re; +import importlib from importlib import import_module +from importlib.abc import MetaPathFinder +import importlib.machinery -mod_info = {} +mod = sys.modules[__name__] +mod_list = {} -def load(mod_name, mod_path, *args): - if( - mod_name in mod_info or - mod_path in sys.modules - ): - raise NameError +class SqmodFinder(MetaPathFinder): + def find_module(fullname,path): + if not fullname.startswith('sqmod/'): + return None - instance = import_module(mod_path, "") - instance.load(*args) - mod_info[mod_name] = [instance, args, mod_path] - return instance + return importlib.machinery.SourceFileLoader(fullname,fullname + '.py') -def reload(mod_name): - instance, args, mod_path = mod_info[mod_name] - instance = import_module(mod_path, "") - instance.load(*args) - mod_info[mod_name][0] = instance - return instance +def load(name,path,*args): + instance = import_module(path,'') + mod_list[name] = instance + setattr(mod,name,getattr(instance,name)(*args)) +def unload(name): + getattr(mod,name).unload() + delattr(mod,name) + del mod_list[name] -def unload(mod_name): - instance, args, mod_path = mod_info[mod_name] - instance.unload() - del sys.modules[mod_path] - del mod_info[mod_name] +def load_sqmod(sqmodname): + print(sqmodname) -def list_mod(): - print(list(mod_info.keys())) + instance = import_module(''.join(['sqmod/',sqmodname,'/py/',sqmodname])) + + return getattr(instance,sqmodname) + +sys.meta_path.append(SqmodFinder) diff --git a/src/py/notice.py b/src/py/notice.py index 3a0a988..de2e2d8 100644 --- a/src/py/notice.py +++ b/src/py/notice.py @@ -1,6 +1,6 @@ from tojauth import TOJAuth from asyncdb import AsyncDB - +import mod from imc.proxy import Proxy import imc.proxy import config @@ -11,7 +11,6 @@ class Notice: 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 @@ -94,7 +93,7 @@ class Notice: ): return 'Eparameter' - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid == None: return 'Euid' @@ -151,7 +150,7 @@ class Notice: @imc.async.caller def get_unseen_count(self): - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid == None: return 'Euid' @@ -201,7 +200,8 @@ class Notice: for link in self.get_link('client', uid = uid): Proxy.instance.call_async( - link + 'core/notice/', 'update_notice', 10000, None, unseen_count + link + 'core/notice/', 'update_notice', 10000, None, + unseen_count ) def get_notice(self, noticeid): @@ -227,10 +227,12 @@ class Notice: if ret == None: return None - uid = UserMg.get_current_uid() + uid = mod.UserMg.get_current_uid() if uid != ret['uid']: TOJAuth.check_access_func(self._accessid, TOJAuth.ACCESS_EXECUTE) return ret -from user import UserMg + def unload(): + pass + diff --git a/src/py/square.py b/src/py/square.py index 68f1be4..ebdf9fb 100644 --- a/src/py/square.py +++ b/src/py/square.py @@ -1,7 +1,10 @@ +import datetime + from tojauth import TOJAuth from asyncdb import AsyncDB -from user import UserMg -import imc.proxy +import mod +import imc.async +from imc.proxy import Proxy import config class SquareMg: @@ -9,23 +12,64 @@ class SquareMg: TITLE_LEN_MIN = 1 TITLE_LEN_MAX = 100 + INTRO_LEN_MIN = 0 + INTRO_LEN_MAX = 1000 + LOGO_LEN_MIN = 0 + LOGO_LEN_MAX = 200 SQUARE_CATE_NUM_MAX = 50 + JOIN_REJECT = 1 + JOIN_ACCEPT = 2 + JOIN_PENDING = 3 + + STATUS_WAITING = 1 + STATUS_RUNNING = 2 + STATUS_ENDED = 3 + 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 + self._sqmod_list = {} + + Proxy.instance.register_call( + 'core/square/', 'list_category', self.list_category) + Proxy.instance.register_call( + 'core/square/', 'list_square', self.list_square) + Proxy.instance.register_call( + 'core/square/', 'join_square', self.join_square) + Proxy.instance.register_call( + 'core/square/', 'quit_square', self.quit_square) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def load_square(self, sqid): + if sqid in self._sqmod_list: + return self._sqmod_list[sqid] + + sqinfo = self.get_square_info_by_sqid(sqid) + sqmodname = self.get_sqmodname_by_sqmodid(sqinfo['sqmodid']) + sqmod = mod.load_sqmod(sqmodname) + self._sqmod_list[sqid] = sqmod(self._idendesc, self.get_link, sqid) + + return self._sqmod_list[sqid] + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_EXECUTE) + def unload_square(self, sqid): + if sqid in self._sqmod_list: + self._sqmod_list[sqid].unload(True) + del self._sqmod_list[sqid] @imc.async.caller - def create_square(self, title, hidden, sqmodid, category = []): + def create_square(self, title, hidden, sqmodid, intro, logo, category = []): if( type(title) != str or type(hidden) != bool or type(sqmodid) != int or - type(category) != list + type(category) != list or + type(intro) != str or + type(logo) != str ): return 'Eparameter' @@ -39,6 +83,14 @@ class SquareMg: return 'Etitle_too_short' elif len(title) > self.TITLE_LEN_MAX: return 'Etitle_too_long' + elif len(intro) < self.INTRO_LEN_MIN: + return 'Eintro_too_short' + elif len(intro) > self.INTRO_LEN_MAX: + return 'Eintro_too_long' + elif len(logo) < self.INTRO_LEN_MIN: + return 'Elogo_too_short' + elif len(logo) > self.INTRO_LEN_MAX: + return 'Elogo_too_long' if len(category) > self.SQUARE_CATE_NUM_MAX: return 'Etoo_many_category' @@ -49,38 +101,47 @@ class SquareMg: if not self.does_cateid_exist(cateid): return 'Eno_such_cateid' - sqid = self._create_square(title, hidden, sqmodid) + if not self.does_sqmodid_exist(sqmodid): + return 'Eno_such_sqmodid' + + sqid = self._create_square(title, hidden, sqmodid, intro, logo) self._set_square_category(sqid, category) return {'sqid': sqid} @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_CREATE) - def _create_square(self, title, hidden, sqmodid): + def _create_square(self, title, hidden, sqmodid, intro, logo): cur = self.db.cursor() sqlstr = ('INSERT INTO "SQUARE" ("title", "hidden", "sqmodid", ' - '"accessid") VALUES (%s, %s, %s, %s) RETURNING "sqid";') - sqlarr = (title, hidden, sqmodid, 0) + '"intro", "logo", "accessid") VALUES (%s, %s, %s, %s, ' + '%s, %s) RETURNING "sqid";') + sqlarr = (title, hidden, sqmodid, intro, logo, 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) + if sqid == None: + return None - sqlstr = ('UPDATE "SQUARE" SET "accessid" = %s WHERE "sqid" = %s;') - sqlarr = (accessid, sqid) - cur.execute(sqlstr, sqlarr) + user_idenid = TOJAuth.get_current_iden()['idenid'] + with TOJAuth.change_current_iden(self._idendesc): + accessid = TOJAuth.instance.create_access(user_idenid) - with TOJAuth.change_current_iden(self._idendesc): - TOJAuth.instance.set_access_list( - accessid, TOJAuth.ROLEID_SQUARE_ADMIN_GROUP, - TOJAuth.ACCESS_ALL - ) + 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 + ) + + sqmodname = self.get_sqmodname_by_sqmodid(sqmodid) + sqmod = mod.load_sqmod(sqmodname) - # sqmod.create_square_data(sqid) + sqmod.create_square_data(sqid) return sqid; @@ -100,7 +161,14 @@ class SquareMg: accessid = self.get_accessid_by_sqid(sqid) TOJAuth.check_access_func(accessid, TOJAuth.ACCESS_DELETE) - # sqmod.delete_square_data(sqid) + sqinfo = self.get_square_info_by_sqid(sqid) + sqmodname = self.get_sqmodname_by_sqmodid(sqinfo['sqmodid']) + sqmod = mod.load_sqmod(sqmodname) + + with TOJAuth.change_current_iden(self._idendesc): + self.unload_square(sqid) + + sqmod.delete_square_data(sqid) with TOJAuth.change_current_iden(self._idendesc): TOJAuth.instance.del_access(accessid) @@ -110,6 +178,10 @@ class SquareMg: sqlarr = (sqid, ) cur.execute() + sqlstr = ('DELETE FROM "SQUARE_USER" WHERE "sqid" = %s;') + sqlarr = (sqid, ) + cur.execute() + @imc.async.caller def list_square(self, cateid = None): if( @@ -118,40 +190,36 @@ class SquareMg: 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) + if cateid != None and not self.does_cateid_exist(cateid): + return 'Eno_such_cateid' - return ret + uid = mod.UserMg.get_current_uid() - 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) + ret = self._list_square_category(cateid, uid) return ret - def _list_square_all(self): + def _list_square_category(self, cateid, uid): cur = self.db.cursor() - sqlstr = ('SELECT "sqid", "title", "start_time", "end_time", "hidden",' - ' "sqmodid" FROM "SQUARE";') - cur.execute(sqlstr) + sqlsel = ('SELECT "SQUARE"."sqid", "title", "start_time", "end_time", ' + '"hidden", "sqmodid", "intro", "logo"') + sqlfrom = (' FROM "SQUARE"') + sqlwhere = (' WHERE true') + sqlarr = [] + + if uid != None: + sqlsel = sqlsel + (', "active"') + sqlfrom = sqlfrom + (' LEFT JOIN "SQUARE_USER" ON "SQUARE"."sqid"' + ' = "SQUARE_USER"."sqid" AND "SQUARE_USER".' + '"uid" = %s') + sqlarr.append(uid) + + if cateid != None: + sqlwhere = sqlwhere + (' AND %s = ANY ("cateid")') + sqlarr.append(cateid) + + sqlstr = sqlsel + sqlfrom + sqlwhere + ';' + cur.execute(sqlstr, sqlarr) ret = [] for data in cur: @@ -162,6 +230,24 @@ class SquareMg: obj['end_time'] = data[3] obj['hidden'] = data[4] obj['sqmodid'] = data[5] + obj['intro'] = data[6] + obj['logo'] = data[7] + if uid != None: + obj['active'] = data[8] + + nowtime = datetime.datetime.now(datetime.timezone.utc) + + if obj['start_time'] == None: + obj['status'] = self.STATUS_RUNNING + elif nowtime < obj['start_time']: + obj['status'] = self.STATUS_WAITING + elif obj['end_time'] == None: + obj['status'] = self.STATUS_RUNNING + elif nowtime > obj['end_time']: + obj['status'] = self.STATUS_ENDED + else: + obj['status'] = self.STATUS_RUNNING + ret.append(obj) return ret @@ -246,16 +332,117 @@ class SquareMg: sq_accessid = self.get_accessid_by_sqid(sqid) TOJAuth.check_access_func(sq_accessid, TOJAuth.ACCESS_WRITE) + if category == {}: + category = {0} + cur = self.db.cursor() sqlstr = ('UPDATE "SQUARE" SET "cateid" = %s WHERE "sqid" = %s;') sqlarr = (category, sqid) cur.execute(sqlstr, sqlarr) + @imc.async.caller + def list_category(self): + cur = self.db.cursor() + sqlstr = ('SELECT "cateid", "catename" FROM "CATEGORY" ORDER BY ' + '"cateid" ASC;') + cur.execute(sqlstr) + + cate_list = [] + for data in cur: + cate = {} + cate['cateid'] = data[0] + cate['catename'] = data[1] + + if cate['cateid'] == 0: + zerocate = cate + else: + cate_list.append(cate) + + cate_list.append(zerocate) + + return cate_list + + @imc.async.caller + def join_square(self, sqid): + if( + type(sqid) != int + ): + return 'Eparameter' + + uid = mod.UserMg.get_current_uid() + if uid == None: + return 'Euid' + + sq = self.get_square_info_by_sqid(sqid) + if sq == None: + return 'Eno_such_sqid' + + with TOJAuth.change_current_iden(self._idendesc): + sqobj = self.load_square(sqid) + + result = sqobj.join_square(uid) + + if result == self.JOIN_REJECT: + return 'Ereject' + elif result == self.JOIN_PENDING: + with TOJAuth.change_current_iden(self._idendesc): + self._set_user_square_relation(uid, sqid, False) + return {'active': False} + elif result == self.JOIN_ACCEPT: + with TOJAuth.change_current_iden(self._idendesc): + self._set_user_square_relation(uid, sqid, True) + return {'active': True} + else: + return 'Ejoin_sq_error' + + @imc.async.caller + def quit_square(self, sqid): + if( + type(sqid) != int + ): + return 'Eparameter' + + uid = mod.UserMg.get_current_uid() + if uid == None: + return 'Euid' + + sq = self.get_square_info_by_sqid(sqid) + if sq == None: + return 'Eno_such_sqid' + + with TOJAuth.change_current_iden(self._idendesc): + sqobj = self.load_square(sqid) + + sqobj.quit_square(uid) + + with TOJAuth.change_current_iden(self._idendesc): + self._del_user_square_relation(uid, sqid) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_WRITE) + def _set_user_square_relation(self, uid, sqid, active): + cur = self.db.cursor() + name = 'SQUARE_USER' + cond = { + 'sqid': sqid, + 'uid': uid + } + value = { + 'active': active + } + cur.upsert(name, cond, value) + + @TOJAuth.check_access(_accessid, TOJAuth.ACCESS_WRITE) + def _del_user_square_relation(self, uid, sqid): + cur = self.db.cursor() + sqlstr = ('DELETE FROM "SQUARE_USER" WHERE "uid" = %s AND "sqid" = %s;') + sqlarr = (uid, 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;') + '"hidden", "sqmodid", "intro", "logo", "cateid" FROM ' + '"SQUARE" WHERE "sqid" = %s;') sqlarr = (sqid, ) cur.execute(sqlstr, sqlarr) @@ -268,7 +455,12 @@ class SquareMg: ret['end_time'] = data[3] ret['hidden'] = data[4] ret['sqmodid'] = data[5] - ret['cateid'] = data[6] + ret['intro'] = data[6] + ret['logo'] = data[7] + ret['cateid'] = data[8] + + if 0 in ret['cateid']: + ret['cateid'] = [] return ret @@ -304,8 +496,29 @@ class SquareMg: catename = self.get_catename_by_cateid(cateid) return catename != None + def get_sqmodname_by_sqmodid(self, sqmodid): + cur = self.db.cursor() + sqlstr = ('SELECT "sqmodname" FROM "SQMOD" WHERE "sqmodid" = %s;') + sqlarr = (sqmodid, ) + cur.execute(sqlstr, sqlarr) + + sqmodname = None + for data in cur: + sqmodname = data[0] + + return sqmodname + + def does_sqmodid_exist(self, sqmodid): + sqmodname = self.get_sqmodname_by_sqmodid(sqmodid) + return sqmodname != None + + def unload(): + pass + class Square: - pass + def unload(self): + pass class Group: pass + diff --git a/src/py/user.py b/src/py/user.py index 33c2c6c..43605e0 100755 --- a/src/py/user.py +++ b/src/py/user.py @@ -7,6 +7,8 @@ import imc.async from imc.proxy import Proxy import config +import mod + class UserMg: _accessid = 2 @@ -26,7 +28,6 @@ class UserMg: COVER_LEN_MAX = 200 def __init__(self, mod_idendesc, get_link_fn): - UserMg.instance = self UserMg.db = AsyncDB(config.CORE_DBNAME, config.CORE_DBUSER, config.CORE_DBPASSWORD) UserMg._idendesc = mod_idendesc @@ -120,7 +121,7 @@ class UserMg: uid = data[0] with TOJAuth.change_current_iden(self._idendesc): - Notice.instance.create_unseen_count(uid) + mod.Notice.create_unseen_count(uid) return uid @@ -153,7 +154,7 @@ class UserMg: client_link = TOJAuth.get_current_iden()['link'] with TOJAuth.change_current_iden(self._idendesc): - stat,data = Proxy.instance.call(self.get_link('center'), + stat,data = Proxy.instance.call(self.get_link('center') + 'core/', 'create_iden', 10000, client_link, @@ -200,7 +201,7 @@ class UserMg: client_link = TOJAuth.get_current_iden()['link'] with TOJAuth.change_current_iden(self._idendesc): - stat,data = Proxy.instance.call(self.get_link('center'), + stat,data = Proxy.instance.call(self.get_link('center') + 'core/', 'create_iden', 10000, client_link, @@ -398,11 +399,6 @@ class UserMg: return None return uid -def load(mod_idendesc, get_link_fn): - UserMg(mod_idendesc, get_link_fn) - -def unload(): - pass - -from notice import Notice + def unload(): + pass |