aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpzread <netfirewall@gmail.com>2013-06-26 01:49:13 +0800
committerpzread <netfirewall@gmail.com>2013-06-26 01:49:13 +0800
commit17c8c94e097018ccaf15f8a9296b03b5195cc3f7 (patch)
treef3c32a7a7a272f0ab0c2236928c4b78e36846d56
parente0043639746fdbbf4958c67a3ef55c63c2fe51a5 (diff)
downloadtaiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.tar
taiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.tar.gz
taiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.tar.bz2
taiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.tar.lz
taiwan-online-judge-17c8c94e097018ccaf15f8a9296b03b5195cc3f7.tar.xz
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.less1
-rw-r--r--src/css/square.less53
-rw-r--r--src/css/style.less6
-rw-r--r--src/html/index.html28
-rw-r--r--src/html/square.html9
-rw-r--r--src/js/com.js4
-rw-r--r--src/js/index.js12
-rw-r--r--src/js/mail.js87
-rw-r--r--src/js/notice.js29
-rw-r--r--src/js/square.js275
-rw-r--r--src/js/user.js13
-rw-r--r--src/py/asyncmcd.py143
-rwxr-xr-xsrc/py/backend_server.py29
-rwxr-xr-xsrc/py/center_server.py10
-rw-r--r--src/py/mail.py33
-rw-r--r--src/py/mod.py50
-rw-r--r--src/py/notice.py16
-rw-r--r--src/py/square.py323
-rwxr-xr-xsrc/py/user.py18
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