├── config ├── __init__.py ├── .gitignore ├── config.py.default └── urls.py ├── models ├── __init__.py ├── notify_type_model.py ├── money_type_model.py ├── money_option_model.py ├── post_thanks_model.py ├── comment_thanks_model.py ├── user_meta_model.py ├── comment_model.py ├── site_model.py ├── cat_model.py ├── money_model.py ├── notify_model.py ├── node_model.py ├── model.py ├── post_model.py └── user_model.py ├── controllers ├── __init__.py ├── index.py ├── notifications.py ├── node.py ├── comment.py ├── post.py ├── admin.py └── user.py ├── libraries ├── __init__.py ├── error.py ├── crumb.py ├── db.py ├── pagination.py ├── widget.py └── helper.py ├── run ├── static ├── .gitignore ├── img │ ├── rss.png │ ├── top.png │ ├── app48.png │ ├── arrow.png │ ├── gold.png │ ├── qbar.png │ ├── reply.png │ ├── bg_item.png │ ├── bronze.png │ ├── favicon.ico │ ├── github.png │ ├── linode.png │ ├── location.png │ ├── logo@2x.png │ ├── mobileme.png │ ├── promoted.png │ ├── shadow.png │ ├── silver.png │ ├── twitter.png │ ├── write48.png │ ├── bg_blended.png │ ├── dot_orange.png │ └── logo_20110809.png ├── icons │ ├── big │ │ └── default.jpg │ ├── tiny │ │ └── default.jpg │ └── normal │ │ └── default.jpg ├── avatar │ ├── big │ │ ├── default.jpg │ │ └── default_f.jpg │ ├── tiny │ │ ├── default.jpg │ │ └── default_f.jpg │ └── normal │ │ ├── default.jpg │ │ └── default_f.jpg ├── css │ ├── desktop.css │ └── main.css └── js │ └── main.js ├── tpl ├── not_found.html ├── user_nf.html ├── login.html ├── no_money.html ├── post_nf.html ├── signup.html ├── admin │ ├── site.html │ ├── create_cat.html │ ├── create_node.html │ ├── node_nf.html │ ├── cat_nf.html │ ├── node_view.html │ ├── set_node_icon.html │ ├── cat_view.html │ ├── index.html │ └── layout.html ├── password.html ├── widget │ ├── ga.html │ ├── site_statics.html │ ├── hot_posts_tody.html │ └── user_panel.html ├── create_post.html ├── about.html ├── node_nf.html ├── avatar.html ├── user_comments.html ├── settings.html ├── user_posts.html ├── recent.html ├── following_posts.html ├── node_favs.html ├── post_favs.html ├── notify.html ├── index.html ├── node_posts.html ├── layout.html ├── profile.html ├── post_view.html └── money_record.html ├── .gitignore ├── README.md ├── code.py ├── index.py.default └── post_bar_init.sql /config/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /models/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /controllers/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /libraries/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/.gitignore: -------------------------------------------------------------------------------- 1 | config.py -------------------------------------------------------------------------------- /run: -------------------------------------------------------------------------------- 1 | python code.py 8888 2 | -------------------------------------------------------------------------------- /static/.gitignore: -------------------------------------------------------------------------------- 1 | avatar 2 | icons -------------------------------------------------------------------------------- /static/img/rss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/rss.png -------------------------------------------------------------------------------- /static/img/top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/top.png -------------------------------------------------------------------------------- /static/img/app48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/app48.png -------------------------------------------------------------------------------- /static/img/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/arrow.png -------------------------------------------------------------------------------- /static/img/gold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/gold.png -------------------------------------------------------------------------------- /static/img/qbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/qbar.png -------------------------------------------------------------------------------- /static/img/reply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/reply.png -------------------------------------------------------------------------------- /static/img/bg_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/bg_item.png -------------------------------------------------------------------------------- /static/img/bronze.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/bronze.png -------------------------------------------------------------------------------- /static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/favicon.ico -------------------------------------------------------------------------------- /static/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/github.png -------------------------------------------------------------------------------- /static/img/linode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/linode.png -------------------------------------------------------------------------------- /static/img/location.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/location.png -------------------------------------------------------------------------------- /static/img/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/logo@2x.png -------------------------------------------------------------------------------- /static/img/mobileme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/mobileme.png -------------------------------------------------------------------------------- /static/img/promoted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/promoted.png -------------------------------------------------------------------------------- /static/img/shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/shadow.png -------------------------------------------------------------------------------- /static/img/silver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/silver.png -------------------------------------------------------------------------------- /static/img/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/twitter.png -------------------------------------------------------------------------------- /static/img/write48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/write48.png -------------------------------------------------------------------------------- /static/img/bg_blended.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/bg_blended.png -------------------------------------------------------------------------------- /static/img/dot_orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/dot_orange.png -------------------------------------------------------------------------------- /static/icons/big/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/icons/big/default.jpg -------------------------------------------------------------------------------- /static/img/logo_20110809.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/img/logo_20110809.png -------------------------------------------------------------------------------- /static/avatar/big/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/avatar/big/default.jpg -------------------------------------------------------------------------------- /static/avatar/tiny/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/avatar/tiny/default.jpg -------------------------------------------------------------------------------- /static/icons/tiny/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/icons/tiny/default.jpg -------------------------------------------------------------------------------- /static/avatar/big/default_f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/avatar/big/default_f.jpg -------------------------------------------------------------------------------- /static/avatar/normal/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/avatar/normal/default.jpg -------------------------------------------------------------------------------- /static/avatar/tiny/default_f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/avatar/tiny/default_f.jpg -------------------------------------------------------------------------------- /static/icons/normal/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/icons/normal/default.jpg -------------------------------------------------------------------------------- /static/avatar/normal/default_f.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HugoPresents/post_bar/HEAD/static/avatar/normal/default_f.jpg -------------------------------------------------------------------------------- /tpl/not_found.html: -------------------------------------------------------------------------------- 1 | $def with (title, text) 2 | $var title: $title 3 | $var widgets=['user_panel_widget'] 4 |
-------------------------------------------------------------------------------- /static/css/desktop.css: -------------------------------------------------------------------------------- 1 | h1 { 2 | font-size: 24px; 3 | font-weight: 500; 4 | line-height: 150%; 5 | margin: 0px 0px 10px 0px; 6 | padding: 0px; 7 | } -------------------------------------------------------------------------------- /static/css/main.css: -------------------------------------------------------------------------------- 1 | form label{ 2 | display: block; 3 | padding: 10px 0 10px 0; 4 | font-size: 15px; 5 | text-align: left; 6 | font-weight: bold; 7 | } -------------------------------------------------------------------------------- /libraries/error.py: -------------------------------------------------------------------------------- 1 | # -- coding: utf8 -- 2 | 3 | # 自定义错误类 4 | 5 | # 自定义值已经存在错误 6 | class ValueExistsError(Exception): 7 | def __init__(self, message): 8 | Exception.__init__(self) 9 | self.message = message -------------------------------------------------------------------------------- /models/notify_type_model.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | __metaclass__ = type 3 | 4 | from models.model import * 5 | class notify_type_model(model): 6 | 7 | def __init__(self): 8 | super(notify_type_model, self).__init__('notify_type') -------------------------------------------------------------------------------- /models/money_type_model.py: -------------------------------------------------------------------------------- 1 | # -- coding: utf8 -- 2 | __metaclass__ = type 3 | from models.model import * 4 | 5 | class money_type_model(model): 6 | 7 | def __init__(self): 8 | super(money_type_model, self).__init__('money_type') -------------------------------------------------------------------------------- /models/money_option_model.py: -------------------------------------------------------------------------------- 1 | # -- coding: utf8 -- 2 | __metaclass__ = type 3 | from models.model import * 4 | 5 | class money_option_model(model): 6 | 7 | def __init__(self): 8 | super(money_option_model, self).__init__('money_option') -------------------------------------------------------------------------------- /models/post_thanks_model.py: -------------------------------------------------------------------------------- 1 | # -- coding: utf8 -- 2 | __metaclass__ = type 3 | import web 4 | from models.model import * 5 | from config.config import * 6 | 7 | class post_thanks_model(model): 8 | 9 | def __init__(self): 10 | super(post_thanks_model, self).__init__('post_thanks') -------------------------------------------------------------------------------- /models/comment_thanks_model.py: -------------------------------------------------------------------------------- 1 | # -- coding: utf8 -- 2 | __metaclass__ = type 3 | import web 4 | from models.model import * 5 | from config.config import * 6 | 7 | class comment_thanks_model(model): 8 | 9 | def __init__(self): 10 | super(comment_thanks_model, self).__init__('comment_thanks') -------------------------------------------------------------------------------- /tpl/user_nf.html: -------------------------------------------------------------------------------- 1 | $def with (title, crumb) 2 | $var title: $title 3 | $var widgets=None 4 |我部署这个网站只想跟大家交流 Python 编程,我没有什么额外目的,希望你也如此,感谢伟大的 V2EX,谢谢。
17 |这是个抄袭 V2EX 的 demo 站,真相在此
15 | 16 || 注册会员总数 | 10 |$site_count['user'] | 11 |
| 主题总数 | 14 |$site_count['post'] | 15 |
| 回复总数 | 18 |$site_count['comment'] | 19 |
|
10 | |
12 | 13 | | 14 | 15 | $:post['post'].title 16 | 17 | | 18 |
33 | <VirtualHost *:80> 34 | ServerAdmin admin@localhost 35 | DocumentRoot /var/www/post_bar 36 | ServerName post_bar.localhost 37 | ErrorLog "logs/post_bar.log" 38 | CustomLog "logs/post_bar.log" combined 39 | WSGIScriptAlias / /var/www/post_bar/index.py 40 | Alias /static /var/www/post_bar/static 41 | AddType text/html .py 42 | </VirtualHost> 43 |44 | 9. 有疑问请 rabbitzhang52#gmail.com 45 | 46 | 10. 有人问到开源协议,我对那个确实没什么研究,本身就是抄袭了V2EX的设计,我只想跟大家交流一下python 的开发经验。你可以用这个做任何事只要不侵犯丝毫V2EX的权益。 47 | -------------------------------------------------------------------------------- /models/money_model.py: -------------------------------------------------------------------------------- 1 | # coding: utf8 2 | __metaclass__ = type 3 | from models.model import * 4 | from models.money_option_model import * 5 | 6 | class money_model(model): 7 | def __init__(self): 8 | super(money_model, self).__init__('money') 9 | # 将财富配置表数据取出 10 | self.ruler = {} 11 | options = money_option_model().get_all() 12 | for option in options: 13 | # 转成浮点进行下面的保留小数运算 14 | self.ruler[option.key] = float(option.value) 15 | 16 | def cal_post(self, content): 17 | if not isinstance(content, unicode): 18 | content = unicode(content) 19 | length = len_ = float(len(content)) 20 | cost = self.ruler['post_cost'] 21 | len_ -= self.ruler['post_length'] 22 | if len_ > 0: 23 | cost += self.ruler['post_cost_add'] * (len_ / 100) 24 | return length, cost 25 | 26 | def cal_comment(self, content): 27 | if not isinstance(content, unicode): 28 | content = unicode(content) 29 | length = len_ = float(len(content)) 30 | cost = self.ruler['comment_cost'] 31 | len_ -= self.ruler['comment_length'] 32 | if len_ > 0: 33 | cost += self.ruler['post_cost_add'] * (len_ / 100) 34 | return length, cost 35 | 36 | def cal_thanks(self): 37 | return self.ruler['thanks_cost'] -------------------------------------------------------------------------------- /code.py: -------------------------------------------------------------------------------- 1 | # -- coding: utf8 -- 2 | import sys 3 | if sys.getdefaultencoding() != 'utf-8': 4 | reload(sys) 5 | sys.setdefaultencoding('utf-8') 6 | import web 7 | from config.config import * 8 | from config.urls import * 9 | from libraries import helper 10 | from libraries import widget 11 | from models.site_model import * 12 | from models.user_model import * 13 | from models.notify_model import * 14 | 15 | #web.template.Template.globals['render'] = render 16 | #web.template.Template.globals['admin_render'] = admin_render 17 | #web.template.Template.globals['site_title'] = site_title 18 | web.template.Template.globals['helper'] = helper 19 | web.template.Template.globals['widget'] = widget 20 | web.template.Template.globals['site_options'] = site_model().get_options() 21 | 22 | app = web.application(urls, globals()) 23 | 24 | if web.config.get('_session') is None: 25 | session = web.session.Session(app, web.session.DiskStore('sessions'), initializer={'user_id': None}) 26 | web.config._session = session 27 | else: 28 | session = web.config._session 29 | 30 | #user_model.auth_cookie() 31 | app.add_processor(user_model().auth_cookie) 32 | app.add_processor(notify_model().check) 33 | 34 | # 如果这里不 不将 session 赋值给模板全局变量, 模板中将不能得到此变量 35 | web.template.Template.globals['session'] = session 36 | #web.template.Template.globals['site_url'] = 'http://127.0.0.1:8080' 37 | if __name__ == "__main__": 38 | app.run() -------------------------------------------------------------------------------- /tpl/admin/node_view.html: -------------------------------------------------------------------------------- 1 | $def with (title, crumb, node, form) 2 | $var title:$title 3 | $var widgets=None 4 |
| 当前图标 | 23 |
24 | |
28 |
| 31 | | 32 | |
| ' + prev + ' | ' 25 | string += '' + page + ' | ' 26 | string += '' + next + ' | ' 27 | string += '
|
25 | |
27 | 28 | $node.display_name 29 | 30 | $node.description 31 | | 32 |
$helper.stamp2during(comment_cur.time) 回复了 $post_user.name 创建的主题 › $:post.title |
27 |
![]() |
30 |
| 当前头像 | 24 |
25 | |
29 |
| 32 | | 33 | |
| $:post.title
21 |
22 |
23 | $node.display_name • $user.name • $helper.stamp2during(post.last_update)
24 | $if comment_user is not None:
25 | • 最后回复来自 $comment_user.name
26 |
27 | |
28 | $if post.comments > 0:
29 | 30 | $post.comments 31 | | 32 |
|
18 | |
21 | 22 | | 23 |$:post.title
24 |
25 |
26 | $post.node_display_name • $post.post_user_name • $helper.stamp2during(post.last_update)
27 | $if post.comment_user_name:
28 | • 最后回复来自 $post.comment_user_name
29 |
30 | |
31 | $if post.comments > 0:
32 | 33 | $post.comments 34 | | 35 |
'+data+' 条未读提醒');
8 | document.title += ' ('+data+')';
9 | }
10 | }
11 | );
12 | }
13 |
14 | function click_reply(name) {
15 | textarea = $('#content');
16 | var content = textarea.val();
17 | if(content.length > 0) {
18 | content += '\n@'+name+' ';
19 | } else {
20 | content += '@'+name+' ';
21 | }
22 | textarea.val(content);
23 | moveEnd(textarea[0]);
24 | //textarea.focus();
25 | }
26 |
27 | function thankReply(comment_id) {
28 | $.post(
29 | '/comment/thanks', {
30 | comment_id:comment_id
31 | }, function(data) {
32 | if(data.success == 1) {
33 | $("#thank_area_"+comment_id).addClass('thanked').html('感谢已发送')
34 | } else {
35 | alert(data.msg)
36 | }
37 | eval(data.script)
38 | }, 'json'
39 | )
40 | }
41 |
42 | function thankTopic(post_id) {
43 | $.post(
44 | '/post/thanks', {
45 | post_id:post_id
46 | }, function(data) {
47 | if(data.success == 1) {
48 | $("#topic_thank").html('感谢已发送')
49 | } else {
50 | alert(data.msg)
51 | }
52 | eval(data.script)
53 | }, 'json'
54 | )
55 | }
56 |
57 | function moveEnd(obj){
58 | obj.focus();
59 | var len = obj.value.length;
60 | if (document.selection) {
61 | var sel = obj.createTextRange();
62 | sel.moveStart('character',len);
63 | sel.collapse();
64 | sel.select();
65 | } else if (typeof obj.selectionStart == 'number' && typeof obj.selectionEnd == 'number') {
66 | obj.selectionStart = obj.selectionEnd = len;
67 | }
68 | }
--------------------------------------------------------------------------------
/models/node_model.py:
--------------------------------------------------------------------------------
1 | # -- coding: utf8 --
2 | __metaclass__ = type
3 | from models.model import *
4 | from config.config import *
5 |
6 | class node_model(model):
7 |
8 | def __init__(self):
9 | super(node_model, self).__init__('node')
10 | self.create_form = web.form.Form(
11 | web.form.Textbox('name', notnull, size=45, description="节点名,用于url,english please", class_='sl'),
12 | web.form.Textbox('display_name', notnull, size=45, description="显示名", class_='sl'),
13 | web.form.Textarea('description', notnull, class_='mle tall', description='分类描述'),
14 | web.form.Button('创建', class_='super normal button')
15 | )
16 | self.modify_form = web.form.Form(
17 | web.form.Textbox('name', size=45, description="node name", class_='sl', disabled="disabled"),
18 | web.form.Textbox('display_name', notnull, size=45, description="display name", class_='sl'),
19 | web.form.Textarea('description', notnull, class_='mle tall', description='分类描述'),
20 | web.form.Button('修改', class_='super normal button')
21 | )
22 |
23 | def set_icon(self, filename, node_id):
24 | import Image
25 | import os
26 | path = 'static/icons/'
27 | im = Image.open(path+'tmp/'+filename)
28 | size = im.size
29 | if size[0] > size[1]:
30 | crop_size = size[1]
31 | left = (size[0]-size[1])/2
32 | right = size[1] + left
33 | upper = 0
34 | lower = size[1]
35 | else:
36 | crop_size = size[0]
37 | left = 0
38 | right = size[0]
39 | upper = (size[1]-size[0])/2
40 | lower = size[0] + upper
41 | box = (left, upper, right, lower)
42 | region = im.crop(box)
43 | region.save(path+'tmp/'+filename)
44 | im = Image.open(path+'tmp/'+filename)
45 | im.thumbnail((73, 73), Image.ANTIALIAS)
46 | im.save(path+'big/'+filename)
47 | im.thumbnail((48, 48), Image.ANTIALIAS)
48 | im.save(path+'normal/'+filename)
49 | im.thumbnail((24, 24), Image.ANTIALIAS)
50 | im.save(path+'tiny/'+filename)
51 | del im, region
52 | os.remove(path+'tmp/'+filename)
53 | self.update({'id':node_id}, {'icon':filename})
--------------------------------------------------------------------------------
/tpl/following_posts.html:
--------------------------------------------------------------------------------
1 | $def with (title, posts, total, crumb, pagination)
2 | $var title:$title
3 | $var widgets=['user_panel_widget']
4 | |
24 | |
27 | 28 | | 29 |$post.title
30 |
31 |
32 | $node.display_name • $user.name • $helper.stamp2during(post.time)
33 | $if comment_user is not None:
34 | • 最后回复来自 $comment_user.name
35 |
36 | |
37 | $if post.comments > 0:
38 | 39 | $post.comments 40 | | 41 |
|
22 |
23 | |
26 | 27 | | 28 |$:post.title
29 |
30 |
31 |
32 | $node.display_name •
33 | $user.name • $helper.stamp2during(post.last_update)
34 | $if comment_user is not None:
35 | • 最后回复来自 $comment_user.name
36 |
37 | |
38 | $if post.comments > 0:
39 | 40 | $post.comments 41 | | 42 |
|
22 | |
25 | 26 | | 27 |$:post.title
28 |
29 |
30 | $node.display_name • $user.name • $helper.stamp2during(post.last_update)
31 | $if comment_user is not None:
32 | • 最后回复来自 $comment_user.name
33 |
34 | |
35 | $if post.comments > 0:
36 | 37 | $post.comments 38 | | 39 |
![]() |
15 | 站点设置
16 |
17 |
18 | 站点名,描述
19 | |
20 |
| 44 | $cat_cur['node_total'] 45 | | 46 |
47 | $cat.display_name
48 |
49 |
50 | $cat.description
51 | |
52 |
|
25 | |
27 |
28 | $if type == 'post_at':
29 | $user.name 在发表 $post.title 时提到了你 $helper.stamp2during(post.time) 删除
30 |
31 |
32 | $:post.content
33 |
34 | $elif type == 'comment':
35 | $user.name 在 $post.title 里回复了你 $helper.stamp2during(comment.time) 删除
36 |
37 |
38 | $:comment.content
39 |
40 | $elif type == 'comment_at':
41 | $user.name 在回复 $post.title 时提到了你 $helper.stamp2during(comment.time) 删除
42 |
43 |
44 | $:comment.content
45 |
46 | |
47 |
|
17 | |
20 | 21 | | 22 |$:post.title
23 |
24 |
25 | $post.node_display_name • $post.post_user_name • $helper.stamp2during(post.last_update)
26 | $if post.comment_user_name:
27 | • 最后回复来自 $post.comment_user_name
28 |
29 | |
30 | $if post.comments > 0:
31 | 32 | $post.comments 33 | | 34 |
| 54 | $cat.display_name 55 | | 56 |57 | $for node in nodes: 58 | $node.display_name 59 | | 60 |
|
37 | |
38 | 39 | | 40 |$:post.title
41 |
42 |
43 | $post.post_user_name • $helper.stamp2during(post.last_update)
44 | $if post.comment_user_name:
45 | • 最后回复来自 $post.comment_user_name
46 |
47 | |
48 | $if post.comments > 0:
49 | 50 | $post.comments 51 | | 52 |
|
8 |
9 | |
12 | 13 | | 14 |$session.name
15 |
16 |
17 | $session.signature
18 | |
19 |
|
27 |
28 | $session.node_favs
29 |
30 |
31 | 节点收藏
32 |
33 | |
34 |
35 |
36 | $session.post_favs
37 |
38 |
39 | 主题收藏
40 |
41 | |
42 |
43 |
44 | $session.user_favs
45 |
46 |
47 | 特别关注
48 |
49 | |
50 |
$session.notifications 条未读提醒
62 | $else:
63 | 0 条未读提醒
64 |
65 |
66 |
'
91 | if money >= 100:
92 | silver = money // 100
93 | money = money % 100
94 | if gold:
95 | string += ' '
96 | string += str(silver) + ' '
97 | string += '
'
98 | bronze = money
99 | if silver:
100 | string += ' '
101 | if bronze <= 0 and (gold or silver):
102 | pass
103 | else:
104 | string += str(bronze) + ' '
105 | string += '
'
106 | return string
107 |
108 | #转成html实体
109 | def str2entity(str):
110 | import htmlentitydefs
111 | str = unicode(str)
112 | to = u''
113 | for i in str:
114 | if ord(i) in htmlentitydefs.codepoint2name:
115 | name = htmlentitydefs.codepoint2name.get(ord(i))
116 | to += "&" + name + ";"
117 | else:
118 | to += i
119 | return to
120 |
121 | def html2db(str):
122 | #str = str.encode()
123 | str = str.replace("'", "\\'").replace('"', '\\"').replace('$', '\\$').replace('<', '<').replace('>', '>')
124 | return str
125 |
126 | def unique_list(list_):
127 | u_list = []
128 | for item in list_:
129 | if item not in u_list:
130 | u_list.append(item)
131 | return u_list
132 |
133 | def list_diff(list_1, list_2):
134 | list_ = []
135 | for item in list_1:
136 | if item not in list_2:
137 | list_.append(item)
138 | return list_
139 |
140 | def strip_tags(html):
141 | from HTMLParser import HTMLParser
142 | html=html.strip()
143 | html=html.strip("\n")
144 | result=[]
145 | parse=HTMLParser()
146 | parse.handle_data=result.append
147 | parse.feed(html)
148 | parse.close()
149 | return "".join(result)
--------------------------------------------------------------------------------
/controllers/comment.py:
--------------------------------------------------------------------------------
1 | # -- coding: utf8 --
2 | import web
3 | session = web.config._session
4 | import time
5 | from config.config import render
6 | from models.comment_model import *
7 | from models.comment_thanks_model import *
8 | from models.post_model import *
9 | from models.money_model import *
10 | from models.money_type_model import *
11 | from models.user_model import *
12 | from models.notify_model import *
13 | from models.notify_type_model import *
14 | from libraries.helper import *
15 |
16 | class create:
17 |
18 | def __init__(self):
19 | self.form = comment_model().form
20 |
21 | def GET(self, post_id):
22 | raise web.SeeOther('/post/' + post_id)
23 |
24 | def POST(self, post_id):
25 | if session.user_id is None:
26 | raise web.SeeOther('/login')
27 | post = post_model().get_one({'id':post_id})
28 | if post is not None:
29 | if not self.form.validates():
30 | raise web.SeeOther('/post/' + post_id)
31 | else:
32 | user_model().update_session(session.user_id)
33 | length, cost = money_model().cal_comment(self.form.d.content)
34 | if session.money < cost:
35 | self.crumb.append('财富不够')
36 | return render.no_money('财富不够', '你的财富值不够,不能创建改主题 :(', self.crumb.output())
37 | content = html2db(self.form.d.content)
38 | content, receiver_list = notify_model().convert_content(content)
39 | create_time = time.time()
40 | comment_id = comment_model().insert({'user_id' : session.user_id, 'post_id' : post_id, 'content' : content, 'time' : create_time})
41 | money_type_id = money_type_model().get_one({'name':'comment'})['id']
42 | money_model().insert({'user_id':session.user_id, 'money_type_id':money_type_id, 'amount':-cost, 'length':length, 'balance':user_model().update_money(session.user_id, -cost), 'foreign_id':comment_id})
43 | if session.user_id != post.user_id:
44 | money_model().insert({'user_id':post.user_id, 'money_type_id':money_type_id, 'amount':cost, 'length':length, 'foreign_id':comment_id, 'balance':user_model().update_money(post.user_id, cost)})
45 | # notify
46 | notify_model().insert({'user_id':session.user_id, 'receiver':post.user_id, 'type_id':notify_type_model().get_one({'name':'comment'}).id, 'foreign_id':comment_id})
47 | # notify
48 | receiver_list = list_diff(receiver_list, [session.name, user_model().get_one({'id':post.user_id}).name])
49 | notify_model().insert_notify(session.user_id, receiver_list, 'comment_at', comment_id)
50 | user_model().update_session(session.user_id)
51 | post_model().update({'id':post_id}, {'last_update':create_time})
52 | post_model().count_comment(post_id)
53 | raise web.SeeOther('/post/' + post_id)
54 | else:
55 | raise web.SeeOther('/post/' + post_id)
56 |
57 | class thanks:
58 | def POST(self):
59 | import json
60 | json_dict = {'success':0, 'msg':'', 'script':''}
61 | comment_id = web.input(comment_id=None)['comment_id']
62 | comment = comment_model().get_one({'id':comment_id})
63 | if comment_id and comment:
64 | if session.user_id is None:
65 | post = post_model().get_one({'id':comment.post_id})
66 | json_dict['msg'] = '你要先登录的亲'
67 | json_dict['script'] = 'location.href=\'/login?next=/post/'+str(post.id)+'#reply-'+str(comment_id)+'\''
68 | elif comment.user_id != session.user_id:
69 | comment_thanks_id = comment_thanks_model().unique_insert({'user_id':session.user_id, 'comment_id':comment_id})
70 | if comment_thanks_id:
71 | comment_thanks_model().update({'id':comment_thanks_id}, {'time':int(time.time())})
72 | cost = money_model().cal_thanks()
73 | money_type_id = money_type_model().get_one({'name':'comment_thanks'})['id']
74 | money_model().insert({'user_id':session.user_id, 'money_type_id':money_type_id, 'amount':-cost, 'balance':user_model().update_money(session.user_id, -cost), 'foreign_id':comment_thanks_id})
75 | money_model().insert({'user_id':comment.user_id, 'money_type_id':money_type_id, 'amount':cost, 'foreign_id':comment_thanks_id, 'balance':user_model().update_money(comment.user_id, cost)})
76 | comment_model().count_thanks(comment_id)
77 | user_model().update_session(session.user_id)
78 | json_dict['success'] = 1
79 | else:
80 | json_dict['msg'] = '你已经感谢过了不是吗?'
81 | else:
82 | json_dict['msg'] = '你不能感谢你自己不是吗?'
83 | else:
84 | json_dict['message'] = '评论不存在'
85 | return json.dumps(json_dict)
--------------------------------------------------------------------------------
/tpl/profile.html:
--------------------------------------------------------------------------------
1 | $def with (title, user, posts, comments, following)
2 | $var title: $title
3 | $var widgets = None
4 | | 13 | | 14 |
15 |
16 | $if user.id != session.user_id:
17 | $if following:
18 |
19 | $else:
20 |
21 |
22 | $user.name23 | $user.signature 24 |
25 |
26 | $site_options['title'] 第 $user.id 号会员,加入于 $helper.stamp2time(user.regist_time)
27 |
28 |
29 |
30 | $:helper.display_money(user.money)
31 |
32 | |
33 |
| $:post.title
59 |
60 |
61 | $node.display_name • $user.name • $helper.stamp2during(post.time)
62 | $if comment_user is not None:
63 | • 最后回复来自 $comment_user.name
64 |
65 | |
66 | 67 | $if post.comments > 0: 68 | $post.comments 69 | | 70 |
$helper.stamp2during(comment_cur.time) 回复了 $post_user.name 创建的主题 › $:post.title |
96 |
![]() |
99 |
| 62 | | 63 |
64 |
65 | $if session.user_id:
66 | $if comment_cur['thanks']:
67 |
76 | 感谢已发送
68 | $else:
69 |
70 | 感谢回复者
71 |
72 |
73 |
74 | $comment_num
75 |
77 |
78 | $comment_user.name
79 | $helper.stamp2during(comment.time)
80 | $if comment.thanks > 0:
81 | ♥ $comment.thanks
82 |
83 |
84 |
85 | $:comment.content
86 |
87 | |
88 |
|
16 | 当前账户余额
17 |
18 |
19 |
20 |
21 |
22 | $:helper.display_money(session.money)
23 | |
24 |
| 时间 | 33 |类型 | 34 |数额 | 35 |余额 | 36 |描述 | 37 |
| $helper.stamp2time(comment_thanks.time) | 51 |收到谢意 | 52 |$record.amount | 53 |$record.balance | 54 |$sender.name 感谢你发布的评论 › $:post.title | 55 |
| $helper.stamp2time(comment_thanks.time) | 59 |发送谢意 | 60 |$record.amount | 61 |$record.balance | 62 |感谢 $comment_user.name 的回复 › $:post.title | 63 |
| $helper.stamp2time(post_thanks.time) | 68 |收到谢意 | 69 |$record.amount | 70 |$record.balance | 71 |$sender.name 感谢你发布的主题 › $:post.title | 72 |
| $helper.stamp2time(post_thanks.time) | 76 |发送谢意 | 77 |$record.amount | 78 |$record.balance | 79 |感谢 $post_user.name 的主题 › $:post.title | 80 |
| $helper.stamp2time(comment.time) | 85 |主题回复收益 | 86 |$record.amount | 87 |$record.balance | 88 |收到 $comment_user.name 的回复 › $:post.title | 89 |
| $helper.stamp2time(comment.time) | 93 |创建回复 | 94 |$record.amount | 95 |$record.balance | 96 |创建了长度为 $record.length 个字符的回复 › $:post.title | 97 |
| $helper.stamp2time(post.time) | 101 |创建主题 | 102 |$record.amount | 103 |$record.balance | 104 |创建了长度为 $record.length 个字符的主题 › $:post.title | 105 |