Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

finish mail.html

  • Loading branch information...
commit b3f0fe08a183edcce44e19224793785acbb2cd9c 1 parent edd5626
@LTaoist LTaoist authored
View
43 model/Model.py
@@ -302,25 +302,29 @@ def init_user_favourite(self, userid):
self.ch.delete(key)
self.ch.sunionstore(key, self.keyf % self.default_userid)
- def add(self, userid, boardname):
+ def add(self, userid, bid):
u''' Add an board into user's favourtie.'''
key = self.keyf % userid
- self.ch.sadd(key, boardname)
+ self.ch.sadd(key, bid)
- def remove(self, userid, boardname):
+ def remove(self, userid, bid):
key = self.keyf % userid
- self.ch.srem(key, boardname)
+ self.ch.srem(key, bid)
def get_all(self, userid):
u'''Return a set holds all board's name in user's favourite.'''
key = self.keyf % userid
return self.ch.smembers(key)
- def add_default(self, boardname):
- self.add(self.default_userid, boardname)
+ def is_fav(self, userid, bid):
+ key = self.keyf % userid
+ return self.ch.sismember(key, bid)
+
+ def add_default(self, bid):
+ self.add(self.default_userid, bid)
- def remove_default(self, boardname):
- self.remove(self.default_userid, boardname)
+ def remove_default(self, bid):
+ self.remove(self.default_userid, bid)
class Post(Model):
@@ -620,6 +624,12 @@ class UserInfo(Model):
def get_user(self,name):
return self.table_get_by_key(self.__, 'userid', name)
+ def get_avatar(self, userid):
+ res = self.db.get("SELECT iconidx FROM %s "
+ "WHERE userid=%%s" % self.__,
+ userid)
+ return res and res['iconidx']
+
def add_user(self,**kwargs):
return self.table_insert(self.__, kwargs)
@@ -816,7 +826,7 @@ def get_mail(self, userid, start, limit):
start, limit)
def get_mail_simple(self, userid, start, limit):
- return self.db.query("SELECT title,mid FROM `%s` "
+ return self.db.query("SELECT title,mid,sendtime,readmark FROM `%s` "
"WHERE touserid=%%s "
"ORDER BY mid "
"LIMIT %%s,%%s" % (self._index_table), userid,
@@ -829,6 +839,14 @@ def get_mid_rank(self, touserid, mid):
'ORDER BY mid' % self._index_table,
mid, touserid)['sum']
+ def get_first_unread(self, touserid):
+ return self.db.get('SELECT count(*) '
+ 'FROM `%s` '
+ 'WHERE mid < ( '
+ ' SELECT mid FROM `%s` WHERE touserid=%%s '
+ ' AND readmark=0 ORDER BY mid LIMIT 1 )' % (\
+ self._index_table, self._index_table), touserid)['count(*)']
+
def rank2mid(self, touserid, rank):
res = self.db.get("SELECT mid "
"WHERE touser=%%s ORDER BY mid "
@@ -894,6 +912,12 @@ def update_mail(self, mid, **kwargs):
return self.table_update_by_key(self._index_table, 'mid', mid, kwargs)
def set_read(self, uid, mid):
+ # old version that need to be clean
+ sql = "UPDATE `%s` SET readmark = readmark | 1 WHERE mid = %%s" %\
+ self._index_table
+ self.db.execute(sql, mid)
+
+ def set_mail_read(self, mid):
sql = "UPDATE `%s` SET readmark = readmark | 1 WHERE mid = %%s" %\
self._index_table
self.db.execute(sql, mid)
@@ -1077,7 +1101,6 @@ def clear_unread(self, userid, boardname, last):
key = self.keyf%(userid,boardname)
self.ch.delete(key)
self.ch.zadd(key, last, last)
- print ('clear', last)
def get_first_read(self, userid, boardname):
d = self.ch.zrange(self.__(userid, boardname), 0, 0)
View
8 telnet/mail.py
@@ -141,9 +141,7 @@ class ReadMailFrame(BaseMailListFrame):
]
def get_mid_rank(self, mid):
- return self.MODE_RANKER[self.mode](self.session.user['uid'],
- self.userid,
- mid)
+ return self.MODE_RANKER[self.mode](self.userid, mid)
def initialize(self, mode=0):
manager.status.set_status(self.seid,
@@ -278,10 +276,12 @@ def initialize(self, touserid=None):
self.writeln(u'取消写信!')
self.pause()
self.goto_back()
- if not manager.userinfo.get_user(touserid):
+ touser = manager.userinfo.get_user(touserid)
+ if not touser :
self.writeln(u'无法找到该收信人!')
self.pause()
self.goto_back()
+ touserid = touser.userid
self.touserid = touserid
sign_num = manager.usersign.get_sign_num(self.userid)
self.attrs = self.read_attrs(touserid, sign_num)
View
31 web/board.py
@@ -6,28 +6,25 @@
class BoardHandler(BaseHandler):
+ page_size = 30
+
def get(self, boardname, rank=None):
board = manager.board.get_board(boardname)
if not board:
raise tornado.web.HTTPError(404)
boardname = board.boardname
- maxrank = max(0, manager.post.get_post_total(board['bid']) - 3)
- if rank is not None:
+ maxrank = max(0, manager.post.get_post_total(board['bid']))
+ if rank is None:
+ rank = maxrank // self.page_size * self.page_size
+ else :
rank = int(rank)
- posts = manager.post.get_posts(board['bid'], rank, 30)
- elif self.get_current_user() :
- userid = self.get_current_user()
- lastread = manager.readmark.get_first_read(userid, boardname) or 0
- lastread = manager.post.prev_three_post(board.bid, lastread) or 0
- posts = manager.post.get_posts_after_pid(
- board.bid, lastread, 30)
- rank = manager.post.get_rank_num(board.bid, lastread)
- else:
- rank = maxrank
- posts = manager.post.get_posts(board['bid'], rank, 30)
+ posts = manager.post.get_posts(board['bid'], rank, self.page_size)
if self.get_current_user() :
userid = self.get_current_user()
manager.readmark.wrapper_post_with_readmark(posts, boardname, userid)
+ isfav = manager.favourite.is_fav(userid, board.bid)
+ else:
+ isfav = None
vistors = (
("LTaoist", "2012-03-04"),
("gcc", "2012-01-09"),
@@ -36,7 +33,8 @@ def get(self, boardname, rank=None):
board['bm'] = board['bm'] and board['bm'].split(':')
board['httpbg'] = "http://ww3.sinaimg.cn/large/6b888227jw1dwesulldlyj.jpg"
self.srender('board.html', board=board, rank=rank, maxrank=maxrank,
- posts=posts, vistors=vistors)
+ posts=posts, vistors=vistors, isfav=isfav,
+ page_size=self.page_size)
class AjaxBookBoardHandler(BaseHandler):
@@ -55,9 +53,8 @@ def get(self, boardname):
"content": u"没有该版块."
})
return
- boardname = board.boardname
- manager.favourite.add(userid, boardname)
+ manager.favourite.add(userid, board.bid)
return self.write({
"success": True,
- "msg": u"预定成功!",
+ "content": u"预定成功!",
})
View
4 web/comm_ajax.py
@@ -105,9 +105,9 @@ def get(self, mid):
uid = mgr.userinfo.name2id(self.userid)
mail = mgr.mail.one_mail(mid)
- if mail:
+ if mail and (mail.touserid == self.userid):
result['success'] = True
- mgr.mail.set_read(uid, mid)
+ mgr.mail.set_mail_read(mid)
for k,v in mail.items():
try:
v = str(v)
View
7 web/lib.py
@@ -35,7 +35,7 @@ def url_for_avatar(userid):
Return the avatar url for userid.
NOT IMPLEMENTED YET.
'''
- return "/static/img/avatar/%s" % userid
+ return manager.userinfo.get_avatar(userid) or "/static/img/avatar_default.jpg"
func = SDict([
("url_for_avatar", url_for_avatar),
@@ -106,6 +106,11 @@ def timeformat(time):
'''
return time.strftime("%d-%m")
+def shorttime(time):
+ '''
+ Better and short outlook for time.
+ '''
+ return time.strftime('%d-%m')
def fun_gen_quote(userid, content):
'''
View
106 web/mail.py
@@ -1,33 +1,61 @@
-from lib import BaseHandler, manager
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+from lib import BaseHandler, manager, url_for_avatar, timeformat, fun_gen_quote
import tornado.web
class MailHandler(BaseHandler):
- page_size = 10
+ def get(self):
+ self.srender('mail.html')
+
+class AjaxMailListHandler(BaseHandler):
- def get(self, start = 0):
+ page_size = 20
+
+ def get(self, start = None):
userid = self.get_current_user()
if not userid :
- self.login_page()
+ self.write({
+ "success": False,
+ "content": "未认证用户!",
+ })
+ return
- start = int(start) or 0
total = manager.mail.get_mail_total(userid)
+ if start is None:
+ start = manager.mail.get_first_unread(userid)
+ if start == 0 :
+ start = total
+ start = start // 20 * 20
+ else:
+ start = int(start)
- if start == 0:
+ if start > total:
+ self.write({
+ "success": False,
+ "content": "没有新的数据!",
+ })
+ return
+
+ if (start < 0) :
start = total - self.page_size
if start < 0 :
start = 0
maillist = manager.mail.get_mail_simple(userid, start, self.page_size)
+ for li in maillist :
+ li['sendtime'] = timeformat(li['sendtime'])
self.write({
- "success":True,
- "content":maillist,
+ "success": True,
+ "content": maillist,
+ "start": start,
})
class AjaxAddMailHandler(BaseHandler):
def get(self):
- self.srender("add_mail")
+ self.render('addmail.html')
def post(self):
userid = self.get_current_user()
@@ -41,13 +69,18 @@ def post(self):
"content":u"错误的收件人。",
})
return
- title=self.get_argument("title", None),
+ title = self.get_argument("title", None)
if not title :
self.write({
"success":False,
"content":u"必须有标题!",
})
return
+ signnum = self.get_argument('signnum', None)
+ if signnum is None or signnum < manager.usersign.get_sign_num(userid):
+ signature = ''
+ else:
+ signature = manager.usersign.get_sign(userid, signnum)
manager.action.send_mail(
fromuserid=userid, touserid=touserid,
content=self.get_argument("text"), title=title,
@@ -74,16 +107,16 @@ def get(self, mid):
return
title = mail.title if mail.title.startswith('Re: ') \
else 'Re: %s' % mail.title
- content = fun_gen_quote(mail.owner, mail.content)
- self.write({
- "title": title,
- "content" : content,
- })
+ content = fun_gen_quote(mail.fromuserid, mail.content)
+ self.render('replymail.html', title=title, content=content, mid=mid)
def post(self, mid):
userid = self.get_current_user()
if not userid :
- self.login_page()
+ self.write({
+ "success": False,
+ "content": "未认证用户!",
+ })
return
mail = manager.mail.one_mail(mid)
if not mail or mail.touserid != userid :
@@ -92,13 +125,46 @@ def post(self, mid):
"content":"没有该邮件!",
})
return
- manager.action.reply_mail(userid,
- self.get_argument('replymid'),
+ signnum = self.get_argument('signnum', None)
+ if signnum is None or signnum < manager.usersign.get_sign_num(userid):
+ signature = ''
+ else:
+ signature = manager.usersign.get_sign(userid, signnum)
+ manager.action.reply_mail(userid, mail,
content=self.get_argument('content'),
title=self.get_argument('title'),
- fromaddr=self.request.remote_ip)
+ fromaddr=self.request.remote_ip,
+ signature=signature)
self.write({
"success":True,
"content":"回复邮件成功!",
})
-
+
+class AjaxGetMailHandler(BaseHandler):
+
+ def get(self, mid):
+ userid = self.get_current_user()
+ if not userid :
+ self.write({
+ "success":False,
+ "content":"没有登录",
+ })
+ return
+ mail = manager.mail.one_mail(mid)
+ if mail and (mail.touserid == userid):
+ manager.mail.set_mail_read(mid)
+ self.write({
+ "success":True,
+ "UserAvatar": url_for_avatar(mail.fromuserid),
+ "Title": mail.title,
+ "Userid": mail.fromuserid,
+ "Content": mail.content,
+ "Sendtime": timeformat(mail.sendtime),
+ "Signature": mail.signature,
+ "Mid": mail.mid,
+ })
+ return
+ self.write({
+ "success":False,
+ "content":"没有该邮件!",
+ })
View
6 web/post.py
@@ -62,7 +62,7 @@ def post(self, replyid):
tid=post.tid, replyable=(self.get_argument('replyable')=='on'),
signature=signature)
manager.readmark.set_read(userid, boardname, pid)
- self.redirect('/post/%s' % pid)
+ self.redirect('/board/%s/' % boardname)
#################### HERE
class NewPostHandler(BaseHandler):
@@ -75,7 +75,7 @@ def post(self, boardname):
if not userid:
raise tornado.web.HTTPError(404)
bid = manager.board.name2id(boardname)
- boardname = manager.board.name2id(bid)
+ boardname = manager.board.id2name(bid)
signnum = self.get_argument('signnum', None)
if signnum is None or signnum < manager.usersign.get_sign_num(userid):
signature = ''
@@ -89,4 +89,4 @@ def post(self, boardname):
signature=signature)
manager.post.update_post(pid, tid=pid)
manager.readmark.set_read(userid, boardname, pid)
- self.redirect('/post/%s' % pid)
+ self.redirect('/board/%s/' % boardname)
View
9 web/server.py
@@ -32,9 +32,13 @@ def __init__(self, handlers, **settings):
(r'/post/add/(\w{1,40})', import_handler('post', 'NewPostHandler')),
(r'/notify', import_handler('user', 'NoticeHandler')),
- (r'/a/get_maillist/(\d{1,4})', import_handler('mail', 'MailHandler')),
+ (r'/mail', import_handler('mail', 'MailHandler')),
+
+ (r'/a/get_maillist/(\d{1,4})?', import_handler('mail','AjaxMailListHandler')),
+ (r'/a/get_mail/(\d{1,4})', import_handler('mail', 'AjaxGetMailHandler')),
(r'/a/add_mail', import_handler('mail', 'AjaxAddMailHandler')),
- (r'/a/reply_mail', import_handler('mail', 'AjaxReplyMailHandler')),
+ (r'/a/reply_mail/(\d{1,4})', import_handler('mail', 'AjaxReplyMailHandler')),
+ (r"/a/book_board/(\w{2,16})", import_handler("board", "AjaxBookBoardHandler")),
(r"/a/checkmail/?", import_handler("comm_ajax","CommAjaxCheckMailHandler")),
(r"/a/mail/(\d{1,10})/?", import_handler("comm_ajax","CommAjaxGetMailHandler")),
@@ -42,7 +46,6 @@ def __init__(self, handlers, **settings):
(r"/a/(\w{2,16})/(\d{1,10})/?", import_handler("comm_ajax","CommAjaxGetPostHandler")),
(r"/a/(\w{2,16})/quote/(\d{1,10})/?", import_handler("comm_ajax","CommAjaxGetQuoteHandler")),
(r"/a/(\w{2,16})/post/?", import_handler("comm_ajax", "CommAjaxNewPostHandler")),
- (r"/a/book_board/(\w{2,16})", import_handler("board", "AjaxBookBoardHandler")),
# mobile
View
51 web/static/css/argo.css
@@ -282,4 +282,55 @@ div.center{
.read,
.read a{
color:grey;
+}
+
+#maillist-holder{
+ border:1px solid #eee;
+ background:#eee;
+}
+
+#maillist-holder li{
+ padding:.33em 1em;
+ border:1px solid transparent;
+ border-bottom:1px solid #ccc;
+ cursor: pointer;
+}
+
+#maillist-holder>li span{
+ color:grey;
+ margin:0;
+ float:right;
+}
+
+#maillist-holder li:hover{
+ border:1px solid #5a7;
+ border-bottom:1px solid #5a7;
+}
+
+.selected{
+ border-left:3px solid #395 !important;
+}
+
+.read0{
+ font-weight:bold;
+}
+
+.userbox img{
+ width: 48px;
+ height: 48px;
+}
+
+.form-crow .control-label{
+ width: 4em !important;
+}
+
+.form-crow .controls{
+ margin-left: 5em !important;
+}
+
+.global-alert{
+ position:fixed;
+ top: 20%;
+ left:20%;
+ min-width: 300px;
}
View
BIN  web/static/images/avatar_default.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  web/static/images/wait.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
27 web/static/js/argo.js
@@ -180,3 +180,30 @@
// });
// }
+
+$(document).ready(function(){
+ if($('#board-head-bookbtn')){
+ $('#board-head-bookbtn').popover({
+ "animation": true,
+ "html": true,
+ "placement": "top",
+ "trigger": 'click',
+ "delay": { show: 500, hide: 1500 },
+ "content": function(){
+ boardname = $('#board-head-bookbtn').attr('data-boardname');
+ $.ajax({
+ type: "GET",
+ url: "/a/book_board/" + boardname,
+ dataType: "json",
+ success : function(data){
+ $('#wait').html('<p class="' + (data['success']?'success':'failed') + '">' + data['content'] + '</p>');
+ setTimeout(function(){
+ $('#wait').remove();
+ $('#board-head-bookbtn').popover('hide');
+ }, 2500);
+ }});
+ return '<div id="wait"><img src="/static/img/wait.gif"/></div>';
+ },
+ })
+ }
+})
View
10 web/static/js/jquery-tmpl.js
@@ -0,0 +1,10 @@
+/*
+ * jQuery Templates Plugin 1.0.0pre
+ * http://github.com/jquery/jquery-tmpl
+ * Requires jQuery 1.4.2
+ *
+ * Copyright 2011, Software Freedom Conservancy, Inc.
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ */
+(function(a){var r=a.fn.domManip,d="_tmplitem",q=/^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,b={},f={},e,p={key:0,data:{}},i=0,c=0,l=[];function g(g,d,h,e){var c={data:e||(e===0||e===false)?e:d?d.data:{},_wrap:d?d._wrap:null,tmpl:null,parent:d||null,nodes:[],calls:u,nest:w,wrap:x,html:v,update:t};g&&a.extend(c,g,{nodes:[],parent:d});if(h){c.tmpl=h;c._ctnt=c._ctnt||c.tmpl(a,c);c.key=++i;(l.length?f:b)[i]=c}return c}a.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(f,d){a.fn[f]=function(n){var g=[],i=a(n),k,h,m,l,j=this.length===1&&this[0].parentNode;e=b||{};if(j&&j.nodeType===11&&j.childNodes.length===1&&i.length===1){i[d](this[0]);g=this}else{for(h=0,m=i.length;h<m;h++){c=h;k=(h>0?this.clone(true):this).get();a(i[h])[d](k);g=g.concat(k)}c=0;g=this.pushStack(g,f,i.selector)}l=e;e=null;a.tmpl.complete(l);return g}});a.fn.extend({tmpl:function(d,c,b){return a.tmpl(this[0],d,c,b)},tmplItem:function(){return a.tmplItem(this[0])},template:function(b){return a.template(b,this[0])},domManip:function(d,m,k){if(d[0]&&a.isArray(d[0])){var g=a.makeArray(arguments),h=d[0],j=h.length,i=0,f;while(i<j&&!(f=a.data(h[i++],"tmplItem")));if(f&&c)g[2]=function(b){a.tmpl.afterManip(this,b,k)};r.apply(this,g)}else r.apply(this,arguments);c=0;!e&&a.tmpl.complete(b);return this}});a.extend({tmpl:function(d,h,e,c){var i,k=!c;if(k){c=p;d=a.template[d]||a.template(null,d);f={}}else if(!d){d=c.tmpl;b[c.key]=c;c.nodes=[];c.wrapped&&n(c,c.wrapped);return a(j(c,null,c.tmpl(a,c)))}if(!d)return[];if(typeof h==="function")h=h.call(c||{});e&&e.wrapped&&n(e,e.wrapped);i=a.isArray(h)?a.map(h,function(a){return a?g(e,c,d,a):null}):[g(e,c,d,h)];return k?a(j(c,null,i)):i},tmplItem:function(b){var c;if(b instanceof a)b=b[0];while(b&&b.nodeType===1&&!(c=a.data(b,"tmplItem"))&&(b=b.parentNode));return c||p},template:function(c,b){if(b){if(typeof b==="string")b=o(b);else if(b instanceof a)b=b[0]||{};if(b.nodeType)b=a.data(b,"tmpl")||a.data(b,"tmpl",o(b.innerHTML));return typeof c==="string"?(a.template[c]=b):b}return c?typeof c!=="string"?a.template(null,c):a.template[c]||a.template(null,q.test(c)?c:a(c)):null},encode:function(a){return(""+a).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;")}});a.extend(a.tmpl,{tag:{tmpl:{_default:{$2:"null"},open:"if($notnull_1){__=__.concat($item.nest($1,$2));}"},wrap:{_default:{$2:"null"},open:"$item.calls(__,$1,$2);__=[];",close:"call=$item.calls();__=call._.concat($item.wrap(call,__));"},each:{_default:{$2:"$index, $value"},open:"if($notnull_1){$.each($1a,function($2){with(this){",close:"}});}"},"if":{open:"if(($notnull_1) && $1a){",close:"}"},"else":{_default:{$1:"true"},open:"}else if(($notnull_1) && $1a){"},html:{open:"if($notnull_1){__.push($1a);}"},"=":{_default:{$1:"$data"},open:"if($notnull_1){__.push($.encode($1a));}"},"!":{open:""}},complete:function(){b={}},afterManip:function(f,b,d){var e=b.nodeType===11?a.makeArray(b.childNodes):b.nodeType===1?[b]:[];d.call(f,b);m(e);c++}});function j(e,g,f){var b,c=f?a.map(f,function(a){return typeof a==="string"?e.key?a.replace(/(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g,"$1 "+d+'="'+e.key+'" $2'):a:j(a,e,a._ctnt)}):e;if(g)return c;c=c.join("");c.replace(/^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/,function(f,c,e,d){b=a(e).get();m(b);if(c)b=k(c).concat(b);if(d)b=b.concat(k(d))});return b?b:k(c)}function k(c){var b=document.createElement("div");b.innerHTML=c;return a.makeArray(b.childNodes)}function o(b){return new Function("jQuery","$item","var $=jQuery,call,__=[],$data=$item.data;with($data){__.push('"+a.trim(b).replace(/([\\'])/g,"\\$1").replace(/[\r\t\n]/g," ").replace(/\$\{([^\}]*)\}/g,"{{= $1}}").replace(/\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,function(m,l,k,g,b,c,d){var j=a.tmpl.tag[k],i,e,f;if(!j)throw"Unknown template tag: "+k;i=j._default||[];if(c&&!/\w$/.test(b)){b+=c;c=""}if(b){b=h(b);d=d?","+h(d)+")":c?")":"";e=c?b.indexOf(".")>-1?b+h(c):"("+b+").call($item"+d:b;f=c?e:"(typeof("+b+")==='function'?("+b+").call($item):("+b+"))"}else f=e=i.$1||"null";g=h(g);return"');"+j[l?"close":"open"].split("$notnull_1").join(b?"typeof("+b+")!=='undefined' && ("+b+")!=null":"true").split("$1a").join(f).split("$1").join(e).split("$2").join(g||i.$2||"")+"__.push('"})+"');}return __;")}function n(c,b){c._wrap=j(c,true,a.isArray(b)?b:[q.test(b)?b:a(b).html()]).join("")}function h(a){return a?a.replace(/\\'/g,"'").replace(/\\\\/g,"\\"):null}function s(b){var a=document.createElement("div");a.appendChild(b.cloneNode(true));return a.innerHTML}function m(o){var n="_"+c,k,j,l={},e,p,h;for(e=0,p=o.length;e<p;e++){if((k=o[e]).nodeType!==1)continue;j=k.getElementsByTagName("*");for(h=j.length-1;h>=0;h--)m(j[h]);m(k)}function m(j){var p,h=j,k,e,m;if(m=j.getAttribute(d)){while(h.parentNode&&(h=h.parentNode).nodeType===1&&!(p=h.getAttribute(d)));if(p!==m){h=h.parentNode?h.nodeType===11?0:h.getAttribute(d)||0:0;if(!(e=b[m])){e=f[m];e=g(e,b[h]||f[h]);e.key=++i;b[i]=e}c&&o(m)}j.removeAttribute(d)}else if(c&&(e=a.data(j,"tmplItem"))){o(e.key);b[e.key]=e;h=a.data(j.parentNode,"tmplItem");h=h?h.key:0}if(e){k=e;while(k&&k.key!=h){k.nodes.push(j);k=k.parent}delete e._ctnt;delete e._wrap;a.data(j,"tmplItem",e)}function o(a){a=a+n;e=l[a]=l[a]||g(e,b[e.parent.key+n]||e.parent)}}}function u(a,d,c,b){if(!a)return l.pop();l.push({_:a,tmpl:d,item:this,data:c,options:b})}function w(d,c,b){return a.tmpl(a.template(d),c,b,this)}function x(b,d){var c=b.options||{};c.wrapped=d;return a.tmpl(a.template(b.tmpl),b.data,c,b.item)}function v(d,c){var b=this._wrap;return a.map(a(a.isArray(b)?b.join(""):b).filter(d||"*"),function(a){return c?a.innerText||a.textContent:a.outerHTML||s(a)})}function t(){var b=this.nodes;a.tmpl(null,null,null,this).insertBefore(b[0]);a(b).remove()}})(jQuery);
View
51 web/template/addmail.html
@@ -0,0 +1,51 @@
+<div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="myModalLabel">发送站内信</h3>
+</div>
+<div class="modal-body">
+ <form class="form-horizontal form-crow">
+ <div class="control-group">
+ <label class="control-label" for="input-title">标题</label>
+ <div class="controls">
+ <input type="text" placeholder="标题" id="input-title"/>
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="control-label" for="touserid">收件人</label>
+ <div class="controls">
+ <input type="text" placeholder="收件人" id="touserid"/>
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="control-label" for="inputContent">正文</label>
+ <div class="controls">
+ <textarea class="input-xlarge" rows="6" name="content" id="inputContent"></textarea>
+ </div>
+ </div>
+ </form>
+</div>
+<div class="modal-footer">
+ <button id="sender" class="btn btn-primary">发送</button>
+</div>
+<script>
+ $('#sender').click(function(){
+ $.ajax({
+ type: "POST",
+ dataType: "json",
+ url: "/a/add_mail",
+ data: {
+ "title": $("#input-title").val(),
+ "touserid" : $("#touserid").val(),
+ "text": $("#inputContent").val(),
+ },
+ success : function(data){
+ if(data.success){
+ $("#add-mail").modal("hide");
+ }
+ else{
+ show_alert(data.content);
+ }
+ }
+ });
+ });
+</script>
View
6 web/template/base.html
@@ -9,6 +9,7 @@
<script src="/static/js/lib/jquery.js"></script>
<script src="/static/js/lib/bootstrap.js"></script>
<script src="/static/js/argo.js"></script>
+ {% block scripthead %}{% end %}
</head>
<body>
{% include "nav.html" %}
@@ -20,7 +21,8 @@
{% end %}
</div>
<div class="span10">
- {% block pagehead %}{% end %}
+ {% block pagehead %}{% end %}
+ {% block content %}
<div class="row">
<div class="span8">
{% block main %}{% end %}
@@ -29,6 +31,7 @@
{% block rightsidebar %}{% end %}
</div>
</div>
+ {% end %}
</div>
</div>
</div>
@@ -37,5 +40,6 @@
<p>&copy Life is originally a tragedy.</p>
</div>
</footer>
+ {% block script %}{% end %}
</body>
</html>
View
18 web/template/board.html
@@ -20,9 +20,17 @@
{% module PostTable(posts) %}
<div class="pagination pagination-centered">
<ul>
- <li><a href="/board/{{ board['boardname'] }}/{{ (rank-30) if rank > 30 else 0 }}">上一页</a></li>
- <li class="active"><a>第 {{ rank//30 }} 页</a></li>
- <li><a href="/board/{{ board['boardname'] }}/{{ (rank+30) if (rank+30 <=maxrank) else maxrank }}">下一页</a></li>
+ {% if rank != 0 %}
+ <li><a href="/board/{{ board.boardname }}/{{ rank - page_size }}">上一页</a></li>
+ {% else %}
+ <li class="disabled"><a>上一页</a></li>
+ {% end %}
+ <li class="active"><a>第 {{ rank//page_size + 1 }} 页</a></li>
+ {% if (rank + page_size) <= maxrank %}
+ <li><a href="/board/{{ board.boardname }}/{{ rank + page_size }}">下一页</a></li>
+ {% else %}
+ <li class="disabled"><a>下一页</a></li>
+ {% end %}
</ul>
</div>
</div>
@@ -36,7 +44,9 @@
<p>{{ board['about'] }}</p>
</div>
<img class="img-rounded" src="{{ board['httpbg'] }}"/>
- <a id="board-head-bookbtn" href="/board/{{ board.boardname }}/book" class="btn btn-mini pull-right btn-info">收藏该版</a>
+ {% if isfav is False %}
+ <a id="board-head-bookbtn" data-boardname="{{ board['boardname'] }}" class="btn btn-mini pull-right btn-info">收藏该版</a>
+ {% end %}
</div>
{% end %}
View
201 web/template/mail.html
@@ -1,27 +1,184 @@
{% extends "base.html" %}
-{% block main %}
-<div class="cell">
- <div class="btn-toolbar">
- <a href="/mail/add" class="btn btn-small btn-success">写信</a>
+{% block content %}
+
+<div class="row">
+ <div class="span7">
+ <div id="mail-wrapper">
+ </div>
+ </div>
+ <div class="span3">
+ <div class="cell">
+ <div class="btn-toolbar">
+ <a href="#add-mail" data-toggle="modal" id="send-new-mail" class="btn btn-small btn-success">写信</a>
+ <button class="btn btn-mini prev-list">上一页</button>
+ <button class="btn btn-mini next-list">下一页</button>
+ <input type="text" class="pull-right input-mini" id="input-start"/>
+ </div>
+ <ul class="unstyled" id="maillist-holder">
+ </ul>
</div>
- <table class="mailtable table table-hover table-condensed" width="100%">
- <thead>
- <tr>
- <th width="auto">标题</th>
- <th width="20%">发信人</th>
- <th width="20%">最后更新</th>
- </tr>
- </thead>
- <tbody>
- {% for li in mails %}
- <tr{% if li.readmark %} class="read"{% end %}>
- <td><a href="/mail/{{ li.tid }}">{{ li.title }}</a></td>
- <td><a href="/user/{{ li.fromuserid }}">{{ li.fromuserid }}</td>
- <td>{{ li.lastupdate }}</td>
- </tr>
- {% end %}
- </tbody>
- </table>
+ </div>
+</div>
+
+<div class="modal" style="display: none" id="add-mail" aria-hidden="true">
</div>
+
+{% end %}
+
+{% block scripthead %}
+<script src="/static/js/jquery-tmpl.js"></script>
{% end %}
+
+{% block script %}
+<script id="mail-template" type="text/x-jquery-tmpl">
+ <div class="post-wrapper">
+ <div class="post-head">
+ <img src="${UserAvatar}"/>
+ <div class="post-info">
+ <h2 id="post-title">${Title}</h2>
+ <div>
+ <span>发信人:
+ <a href="/user/${Userid}">${Userid}</a>
+ </span> |
+ <span> <i class="icon-time"></i>${Sendtime}</span> </div>
+ </div>
+ </div>
+ <div id="post-content" class="post-content">
+ ${Content}
+ </div>
+ <div class="post-sign">
+ ${Signature}
+ </div>
+ <div class="post-meta">
+ <a class="reply-mail" data-mid="${Mid}" href="#">回复</a>
+ </div>
+ </div>
+</script>
+
+<script id="maillist-template" type="text/x-jquery-tmpl">
+ <li class="read${readmark}" data-mid="${mid}">
+ <div>${index}. ${title} <span>${sendtime}</span></div>
+ </li>
+</script>
+
+<script>
+var load_post;
+var load_maillist;
+var set_maillist;
+var update_maillist;
+
+$(document).ready(function(){
+
+ function render_post(data){
+ $("#mail-wrapper").empty();
+ $("#mail-template").tmpl(data).appendTo("#mail-wrapper");
+ $('.post-content').html($('.post-content').html().replace(/\n/g, '<br/>'));
+ $('.reply-mail').click(function(){
+ var mid = $(".reply-mail").attr("data-mid");
+ $(".modal").empty()
+ $(".modal").load("/a/reply_mail/" + mid);
+ $(".modal").modal('show');
+ })
+ }
+
+ function render_maillist(data, start){
+ $("#maillist-holder").empty()
+ for(var i=0; i<data.length; ++i){
+ data[i].index = start+i;
+ }
+ $("#maillist-template").tmpl(data).appendTo("#maillist-holder");
+ $('#maillist-holder>li').click(function(e){
+ var $target = $(this)
+ $.ajax({
+ type: "GET",
+ dataType: "json",
+ url: "/a/get_mail/" + $target.attr('data-mid'),
+ success : function( data ){
+ if( data.success ){
+ if($(".selected")){
+ $(".selected").removeClass("selected");
+ }
+ $target.addClass("selected").removeClass("read0");
+ $("#mail-wrapper").fadeOut(200, function(){
+ render_post(data);
+ $("#mail-wrapper").fadeIn(500);
+ })
+ }
+ else{
+ show_alert(data.content);
+ }
+ }
+ });
+ });
+ }
+
+ set_maillist = function( start ){
+ $.ajax({
+ type: "GET",
+ dataType: "json",
+ url: "/a/get_maillist/" + start,
+ success : function( data ){
+ if( data.success ){
+ $('#input-start').val(data.start);
+ $("#maillist-holder").fadeOut(200, function(){
+ render_maillist(data.content, data.start+1)
+ $("#maillist-holder").fadeIn(500);
+ });
+ }
+ else{
+ show_alert(data.content);
+ }
+ },
+ })
+ }
+
+ update_maillist = function (){
+ $.ajax({
+ type: "GET",
+ dataType: "json",
+ url: "/a/get_maillist/",
+ success : function( data ){
+ $('#input-start').val(data.start);
+ if( data.success ){
+ render_maillist(data.content, data.start+1)
+ $('#maillist-holder>li:first-child').click();
+ }
+ else{
+ show_alert(data.content);
+ }
+ },
+ });
+ }
+
+ $('.prev-list').click(function(){
+ set_maillist(Math.max($('#input-start').val() - 20, 0));
+ });
+
+ $('.next-list').click(function(){
+ set_maillist(Number($('#input-start').val()) + 20);
+ });
+
+ $('#send-new-mail').click(function(){
+ $(".modal").empty()
+ $(".modal").load("/a/add_mail");
+ });
+
+ update_maillist();
+
+ function show_alert(message){
+ $(".modal").empty();
+ if(typeof message == "string"){
+ message = '<div class="modal-body">' + message + '</div>';
+ }
+ $(".modal").html(message);
+ $(".modal").modal("show");
+ setTimeout(function(){
+ $(".modal").modal("hide");
+ }, 2000);
+ }
+
+})
+</script>
+{% end %}
+
View
7 web/template/post.html
@@ -22,12 +22,7 @@
{{ post.signature }}
</div>
<div class="post-meta">
- <a href="#">转寄</a>
- <a href="#">转贴</a>
- <a href="#">删除</a>
- <a href="#">修改</a>
<a href="/post/add/{{ post.pid }}">回复</a>
- <a href="#">同主题阅读</a>
</div>
</div>
{% module PostNav(firstpid, prevpid, nextpid, lastpid, post.pid) %}
@@ -55,7 +50,7 @@
{% end %}
</ul>
{% else %}
- <p>没有回复,<br/>要<a href="#">发表回复</a>吗? </p>
+ <p>没有回复,<br/>要<a href="/post/add/{{ post.pid }}">发表回复</a>吗? </p>
{% end %}
</div>
{% end %}
View
44 web/template/replymail.html
@@ -0,0 +1,44 @@
+<div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
+ <h3 id="myModalLabel">回复站内信</h3>
+</div>
+<div class="modal-body">
+ <form class="form-horizontal form-crow">
+ <div class="control-group">
+ <label class="control-label" for="input-title">标题</label>
+ <div class="controls">
+ <input type="text" placeholder="标题" id="input-title" value="{{ title }}"/>
+ </div>
+ </div>
+ <div class="control-group">
+ <label class="control-label" for="inputContent">正文</label>
+ <div class="controls">
+ <textarea class="input-xlarge" rows="6" name="content" id="inputContent">{{ content }}</textarea>
+ </div>
+ </div>
+ </form>
+</div>
+<div class="modal-footer">
+ <button id="sender" data-mid={{ mid }} class="btn btn-primary">发送</button>
+</div>
+<script>
+ $('#sender').click(function(){
+ $.ajax({
+ type: "POST",
+ dataType: "json",
+ url:"/a/reply_mail/{{ mid }}",
+ data: {
+ title: $("#input-title").val(),
+ content: $("#inputContent").val(),
+ },
+ success: function(data){
+ if(data.success){
+ $("#add-mail").modal("hide");
+ }
+ else{
+ show_alert(data.content);
+ }
+ },
+ });
+ })
+</script>
Please sign in to comment.
Something went wrong with that request. Please try again.