Changeset 2617
- Timestamp:
- 09/06/07 14:30:48 (10 months ago)
- Files:
-
- discussionplugin/0.11/tracdiscussion/api.py (modified) (30 diffs)
- discussionplugin/0.11/tracdiscussion/core.py (modified) (1 diff)
- discussionplugin/0.11/tracdiscussion/htdocs/css/discussion.css (modified) (2 diffs)
- discussionplugin/0.11/tracdiscussion/templates/forum-list.html (modified) (2 diffs)
- discussionplugin/0.11/tracdiscussion/templates/topic-list.html (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
discussionplugin/0.11/tracdiscussion/api.py
r2534 r2617 4 4 5 5 from trac.core import * 6 from trac.perm import PermissionError 6 7 from trac.web.chrome import add_stylesheet, add_script 7 8 from trac.wiki.formatter import format_to_html, format_to_oneliner 8 from trac.perm import PermissionError9 9 from trac.util.datefmt import to_timestamp, to_datetime, utc, \ 10 10 format_datetime, pretty_timedelta … … 14 14 from tracdiscussion.notification import * 15 15 16 class DiscussionApi(object): 17 18 def __init__(self): 16 class DiscussionApi(Component): 17 18 # Main request processing function. 19 20 def process_discussion(self, context): 21 # Clear data for next request. 19 22 self.data = {} 20 23 21 # Main request processing function22 23 def process_discussion(self, context): 24 # Get database access. 25 context.cursor = context.db.cursor() 26 24 27 # Get request items and modes. 25 28 group, forum, topic, message = self._get_items(context) … … 30 33 or context.req.perm.has_permission('DISCUSSION_ADMIN') 31 34 32 # Add CSS styles 33 add_stylesheet(context.req, 'common/css/wiki.css') 34 add_stylesheet(context.req, 'discussion/css/discussion.css') 35 add_stylesheet(context.req, 'discussion/css/admin.css') 36 37 add_script(context.req, 'common/js/trac.js') 38 add_script(context.req, 'common/js/search.js') 39 add_script(context.req, 'common/js/wikitoolbar.js') 40 41 # Perform mode actions 35 # Get session data. 36 context.visited_forums = eval(context.req.session.get('visited-forums') 37 or '{}') 38 context.visited_topics = eval(context.req.session.get('visited-topics') 39 or '{}') 40 41 # Perform mode actions. 42 42 self._do_action(context, modes, group, forum, topic, message, 43 43 is_moderator) 44 45 # Update session data. 46 context.req.session['visited-topics'] = unicode(context.visited_topics) 47 context.req.session['visited-forums'] = unicode(context.visited_forums) 44 48 45 49 # Fill up template data struture. … … 75 79 message['time'] = format_datetime(message['time']) 76 80 77 # Return template and data. 81 # Add CSS styles and scripts. 82 add_stylesheet(context.req, 'common/css/wiki.css') 83 add_stylesheet(context.req, 'discussion/css/discussion.css') 84 add_stylesheet(context.req, 'discussion/css/admin.css') 85 86 add_script(context.req, 'common/js/trac.js') 87 add_script(context.req, 'common/js/search.js') 88 add_script(context.req, 'common/js/wikitoolbar.js') 89 90 # Commit database changes and return template and data. 91 context.db.commit() 78 92 context.env.log.debug(self.data) 79 93 return modes[-1] + '.html', {'discussion' : self.data} … … 82 96 group, forum, topic, message = None, None, None, None 83 97 84 # Populate active group 98 # Populate active group. 85 99 if context.req.args.has_key('group'): 86 100 group_id = int(context.req.args.get('group') or 0) 87 101 group = self.get_group(context, group_id) 88 102 89 # Populate active forum 103 # Populate active forum. 90 104 if context.req.args.has_key('forum'): 91 105 forum_id = int(context.req.args.get('forum') or 0) 92 106 forum = self.get_forum(context, forum_id) 93 107 94 # Populate active topic 108 # Populate active topic. 95 109 if context.req.args.has_key('topic'): 96 110 topic_id = int(context.req.args.get('topic') or 0) 97 111 topic = self.get_topic(context, topic_id) 98 112 99 # Populate active topic 113 # Populate active topic. 100 114 if context.req.args.has_key('message'): 101 115 message_id = int(context.req.args.get('message') or 0) … … 105 119 106 120 def _get_modes(self, context, group, forum, topic, message): 107 # Get action 121 # Get action. 108 122 action = context.req.args.get('discussion_action') 109 123 preview = context.req.args.has_key('preview'); 110 124 submit = context.req.args.has_key('submit'); 111 125 112 # Determine mode 126 # Determine mode. 113 127 if message: 114 128 if context.realm == 'discussion-admin': … … 281 295 context.req.perm.assert_permission('DISCUSSION_ADMIN') 282 296 283 # Get form values 297 # Get form values. 284 298 order = context.req.args.get('order') or 'id' 285 299 desc = context.req.args.get('desc') … … 350 364 context.req.perm.assert_permission('DISCUSSION_VIEW') 351 365 352 # Get form values 366 # Get form values. 353 367 order = context.req.args.get('order') or 'id' 354 368 desc = context.req.args.get('desc') … … 364 378 context.req.perm.assert_permission('DISCUSSION_ADMIN') 365 379 366 # Get ordering arguments values 380 # Get ordering arguments values. 367 381 order = context.req.args.get('order') or 'id' 368 382 desc = context.req.args.get('desc') … … 439 453 context.req.perm.assert_permission('DISCUSSION_ADMIN') 440 454 441 # Delete forum 455 # Delete forum. 442 456 self.delete_forum(context, forum['id']) 443 457 … … 465 479 elif mode == 'topic-list': 466 480 context.req.perm.assert_permission('DISCUSSION_VIEW') 481 482 # Update this forum visit time. 483 context.visited_forums[forum['id']] = to_timestamp(datetime.now(utc)) 467 484 468 485 # Get form values … … 565 582 raise PermissionError('Forum moderate') 566 583 567 # Display Move Topic form 584 # Display Move Topic form. 568 585 self.data['forums'] = self.get_forums(context) 569 586 … … 573 590 raise PermissionError('Forum moderate') 574 591 575 # Get form values 592 # Get form values. 576 593 new_forum = int(context.req.args.get('new_forum') or 0) 577 594 … … 686 703 context.req.perm.assert_permission('DISCUSSION_VIEW') 687 704 688 # Get form values 705 # Get form values. 689 706 display = context.req.args.get('display') 690 707 691 # Set message list display mode to session 708 # Set message list display mode to session. 692 709 context.req.session['message-list-display'] = display 693 694 695 710 696 711 def _prepare_message_list(self, context, topic): … … 701 716 702 717 # Get time when topic was visited from session. 703 visited = eval(context.req.session.get('visited-topics') or '{}') 704 visit_time = visited.has_key(topic['id']) and \ 705 int(visited[topic['id']]) or 0 706 707 # Update this topic visit time and save to session. 708 visited[topic['id']] = to_timestamp(datetime.now(utc)) 709 context.req.session['visited-topics'] = unicode(visited) 718 visit_time = context.visited_topics.has_key(topic['id']) and \ 719 int(context.visited_topics[topic['id']] or 0) 720 721 # Update this topic visit time. 722 context.visited_topics[topic['id']] = to_timestamp(datetime.now(utc)) 710 723 711 724 # Mark new topic. … … 713 726 topic['new'] = True 714 727 715 # Prepare display of topic 728 # Prepare display of topic. 716 729 if new_author: 717 730 self.data['author'] = format_to_oneliner(context, new_author) … … 721 734 self.data['body'] = format_to_html(context, new_body) 722 735 723 # Prepare display of messages 736 # Prepare display of messages. 724 737 display = context.req.session.get('message-list-display') 725 738 self.data['display'] = display … … 734 747 visit_time) 735 748 736 # Get one item functions 749 # Get one item functions. 737 750 738 751 def get_message(self, context, id): … … 827 840 return {'id' : 0, 'name': 'None', 'description': 'No Group'} 828 841 829 # Set item functions 830 831 def set_group(self, context, forum, group): 832 if not group: 833 group = '0' 834 sql = "UPDATE forum SET forum_group = %s WHERE id = %s" 835 context.env.log.debug(sql % (group, forum)) 836 context.cursor.execute(sql, (group, forum)) 837 838 def set_forum(self, context, topic, forum): 839 sql = "UPDATE topic SET forum = %s WHERE id = %s" 840 context.env.log.debug(sql % (forum, topic)) 841 context.cursor.execute(sql, (forum, topic)) 842 sql = "UPDATE message SET forum = %s WHERE topic = %s" 843 context.env.log.debug(sql % (forum, topic)) 844 context.cursor.execute(sql, (forum, topic)) 845 846 # Edit all functons 847 848 def edit_group(self, context, group, name, description): 849 sql = "UPDATE forum_group SET name = %s, description = %s WHERE id = %s" 850 context.env.log.debug(sql % (name, description, group)) 851 context.cursor.execute(sql, (name, description, group)) 852 853 def edit_forum(self, context, forum, name, subject, description, moderators, 854 group): 855 moderators = ' '.join(moderators) 856 if not group: 857 group = '0' 858 sql = "UPDATE forum SET name = %s, subject = %s, description = %s," \ 859 " moderators = %s, forum_group = %s WHERE id = %s" 860 context.env.log.debug(sql % (name, subject, description, moderators, 861 group, forum)) 862 context.cursor.execute(sql, (name, subject, description, moderators, 863 group, forum)) 864 865 def edit_topic(self, context, topic, forum, subject, body): 866 sql = "UPDATE topic SET forum = %s, subject = %s, body = %s WHERE id" \ 867 " = %s" 868 context.env.log.debug(sql % (forum, subject, body, topic)) 869 context.cursor.execute(sql, (forum, subject, body, topic)) 870 871 def edit_message(self, context, message, forum, topic, replyto, body): 872 sql = "UPDATE message SET forum = %s, topic = %s, replyto = %s, body" \ 873 " = %s WHERE id = %s" 874 context.env.log.debug(sql % (forum, topic, replyto, body, message)) 875 context.cursor.execute(sql, (forum, topic, replyto, body, message)) 876 877 # Get list functions 842 # Get list functions. 878 843 879 844 def get_groups(self, context, order_by = 'id', desc = False): 880 # Get count of forums without group 845 # Get count of forums without group. 881 846 sql = "SELECT COUNT(f.id) FROM forum f WHERE f.forum_group = 0" 882 847 context.env.log.debug(sql) … … 888 853 'forums' : no_group_forums}] 889 854 890 # Get forum groups 855 # Get forum groups. 891 856 if order_by != 'forum': 892 857 order_by = 'g.' + order_by … … 907 872 908 873 def get_forums(self, context, order_by = 'subject', desc = False): 874 875 def _get_new_topic_count(context, forum_id): 876 time = context.visited_forums.has_key(forum_id) and \ 877 int(context.visited_forums[forum_id] or 0) 878 sql = "SELECT COUNT(id) FROM topic t WHERE t.forum = %s AND t.time > %s" 879 880 context.env.log.debug(sql % (forum_id, time)) 881 context.cursor.execute(sql, (forum_id, time)) 882 for row in context.cursor: 883 return int(row[0]) 884 return 0 885 886 def _get_new_replies_count(context, forum_id): 887 time = context.visited_forums.has_key(forum_id) and \ 888 int(context.visited_topics[forum_id] or 0) 889 sql = "SELECT COUNT(id) FROM message m WHERE m.forum = %s AND m.time > %s" 890 891 context.env.log.debug(sql % (forum_id, time)) 892 context.cursor.execute(sql, (forum_id, time)) 893 for row in context.cursor: 894 return int(row[0]) 895 return 0 896 909 897 if not order_by in ('topics', 'replies', 'lasttopic', 'lastreply'): 910 898 order_by = 'f.' + order_by … … 923 911 context.env.log.debug(sql) 924 912 context.cursor.execute(sql) 913 914 # Convert certain forum attributes. 925 915 forums = [] 926 916 for row in context.cursor: … … 937 927 row['time'] = format_datetime(row['time']) 938 928 forums.append(row) 929 930 # Compute count of new replies and topics. 931 for forum in forums: 932 forum['new_topics'] = _get_new_topic_count(context, forum['id']) 933 forum['new_replies'] = _get_new_replies_count(context, forum['id']) 934 939 935 return forums 940 936 941 937 def get_topics(self, context, forum_id, order_by = 'time', desc = False): 938 939 def _get_new_replies_count(context, topic_id): 940 time = context.visited_topics.has_key(topic_id) and \ 941 int(context.visited_topics[topic_id] or 0) 942 sql = "SELECT COUNT(id) FROM message m WHERE m.topic = %s AND m.time > %s" 943 944 context.env.log.debug(sql % (topic_id, time)) 945 context.cursor.execute(sql, (topic_id, time)) 946 for row in context.cursor: 947 return int(row[0]) 948 return 0 949 942 950 if not order_by in ('replies', 'lastreply',): 943 951 order_by = 't.' + order_by … … 951 959 context.env.log.debug(sql % (unicode(forum_id),)) 952 960 context.cursor.execute(sql, (unicode(forum_id),)) 961 962 # Convert certain topic attributes. 953 963 topics = [] 954 964 for row in context.cursor: … … 962 972 row['time'] = format_datetime(row['time']) 963 973 topics.append(row) 974 975 # Compute count of new replies. 976 for topic in topics: 977 topic['new_replies'] = _get_new_replies_count(context, topic['id']) 978 964 979 return topics 965 980 … … 982 997 messagemap[row['id']] = row 983 998 984 # Add top-level messages to the main list, in order of time 999 # Add top-level messages to the main list, in order of time. 985 1000 if row['replyto'] == -1: 986 1001 messages.append(row) 987 1002 988 # Second pass, add replies 1003 # Second pass, add replies. 989 1004 for message in messagemap.values(): 990 1005 if message['replyto'] != -1: … … 1020 1035 return users 1021 1036 1022 # Add items functions 1037 # Add items functions. 1023 1038 1024 1039 def add_group(self, context, name, description): … … 1049 1064 context.cursor.execute(sql, (forum, topic, replyto, time, author, body)) 1050 1065 1051 # Delete items functions 1066 # Delete items functions. 1052 1067 1053 1068 def delete_group(self, context, group): … … 1079 1094 1080 1095 def delete_message(self, context, message): 1081 # Get message replies 1096 # Get message replies. 1082 1097 sql = "SELECT m.id FROM message m WHERE m.replyto = %s" 1083 1098 context.env.log.debug(sql % (unicode(message),)) … … 1089 1104 replies.append(row[0]) 1090 1105 1091 # Delete all replies 1106 # Delete all replies. 1092 1107 for reply in replies: 1093 1108 self.delete_message(context, reply) 1094 1109 1095 # Delete message itself 1110 # Delete message itself. 1096 1111 sql = "DELETE FROM message WHERE id = %s" 1097 1112 context.env.log.debug(sql % (unicode(message),)) 1098 1113 context.cursor.execute(sql, (unicode(message),)) 1114 1115 # Set item functions. 1116 1117 def set_group(self, context, forum, group): 1118 if not group: 1119 group = '0' 1120 sql = "UPDATE forum SET forum_group = %s WHERE id = %s" 1121 context.env.log.debug(sql % (group, forum)) 1122 context.cursor.execute(sql, (group, forum)) 1123 1124 def set_forum(self, context, topic, forum): 1125 sql = "UPDATE topic SET forum = %s WHERE id = %s" 1126 context.env.log.debug(sql % (forum, topic)) 1127 context.cursor.execute(sql, (forum, topic)) 1128 sql = "UPDATE message SET forum = %s WHERE topic = %s" 1129 context.env.log.debug(sql % (forum, topic)) 1130 context.cursor.execute(sql, (forum, topic)) 1131 1132 # Edit functions. 1133 1134 def edit_group(self, context, group, name, description): 1135 sql = "UPDATE forum_group SET name = %s, description = %s WHERE id = %s" 1136 context.env.log.debug(sql % (name, description, group)) 1137 context.cursor.execute(sql, (name, description, group)) 1138 1139 def edit_forum(self, context, forum, name, subject, description, moderators, 1140 group): 1141 moderators = ' '.join(moderators) 1142 if not group: 1143 group = '0' 1144 sql = "UPDATE forum SET name = %s, subject = %s, description = %s," \ 1145 " moderators = %s, forum_group = %s WHERE id = %s" 1146 context.env.log.debug(sql % (name, subject, description, moderators, 1147 group, forum)) 1148 context.cursor.execute(sql, (name, subject, description, moderators, 1149 group, forum)) 1150 1151 def edit_topic(self, context, topic, forum, subject, body): 1152 sql = "UPDATE topic SET forum = %s, subject = %s, body = %s WHERE id" \ 1153 " = %s" 1154 context.env.log.debug(sql % (forum, subject, body, topic)) 1155 context.cursor.execute(sql, (forum, subject, body, topic)) 1156 1157 def edit_message(self, context, message, forum, topic, replyto, body): 1158 sql = "UPDATE message SET forum = %s, topic = %s, replyto = %s, body" \ 1159 " = %s WHERE id = %s" 1160 context.env.log.debug(sql % (forum, topic, replyto, body, message)) 1161 context.cursor.execute(sql, (forum, topic, replyto, body, message)) discussionplugin/0.11/tracdiscussion/core.py
r2534 r2617 73 73 # Create request context. 74 74 context = Context(self.env, req)('discussion-core') 75 context.cursor = context.db.cursor()76 75 77 # Process request. 78 api = DiscussionApi() 79 content = api.process_discussion(context) 80 context.db.commit() 81 82 # Return request result content. 83 return (content[0], content[1], None) 76 # Process request and return content. 77 api = self.env[DiscussionApi] 78 return api.process_discussion(context) + (None,) discussionplugin/0.11/tracdiscussion/htdocs/css/discussion.css
r2353 r2617 24 24 .forum-list td.id, .forum-list td.moderators, .forum-list td.lasttopic, 25 25 .forum-list td.lastreply, .forum-list td.time, .forum-list td.topics, 26 .forum-list td. replies26 .forum-list td.new_topics, .forum-list td.replies, .forum-list td.new_replies 27 27 { 28 28 text-align: center; … … 53 53 /* Topic list */ 54 54 .topic-list td.id, .topic-list td.author, .topic-list td.lastreply, 55 .topic-list td.time, .topic-list td.replies 55 .topic-list td.time, .topic-list td.replies, .topic-list td.new_replies 56 56 { 57 57 text-align: center; discussionplugin/0.11/tracdiscussion/templates/forum-list.html
r2365 r2617 24 24 ${sortable_th(discussion.order, discussion.desc, 'time', 'Founded', href.discussion())} 25 25 ${sortable_th(discussion.order, discussion.desc, 'topics', 'Topics', href.discussion())} 26 <th>New Topics</th> 26 27 ${sortable_th(discussion.order, discussion.desc, 'replies', 'Replies', href.discussion())} 28 <th>New Replies</th> 27 29 </tr> 28 30 </thead> … … 84 86 </div> 85 87 </td> 88 <td class="new_topics"> 89 <div class="new_topics"> 90 <a href="${href.discussion(forum.id)}"> 91 <span>${forum.new_topics or '0'}</span> 92 </a> 93 </div> 94 </td> 86 95 <td class="replies"> 87 96 <div class="replies"> 88 97 <a href="${href.discussion(forum.id)}"> 89 98 <span>${forum.replies or '0'}</span> 99 </a> 100 </div> 101 </td> 102 <td class="new_replies"> 103 <div class="new_replies"> 104 <a href="${href.discussion(forum.id)}"> 105 <span>${forum.new_replies or '0'}</span> 90 106 </a> 91 107 </div> discussionplugin/0.11/tracdiscussion/templates/topic-list.html
r2365 r2617 27 27 ${sortable_th(discussion.order, discussion.desc, 'time', 'Founded', href.discussion(discussion.forum.id))} 28 28 ${sortable_th(discussion.order, discussion.desc, 'replies', 'Replies', href.discussion(discussion.forum.id))} 29 <th class="new_replies">New Replies</th> 29 30 </tr> 30 31 </thead> … … 73 74 </div> 74 75 </td> 76 <td class="new_replies"> 77 <div class="new_replies"> 78 <a href="${href.discussion(discussion.forum.id, topic.id)}"> 79 <span>${topic.new_replies or '0'}</span> 80 </a> 81 </div> 82 </td> 75 83 </tr> 76 84 </tbody>
