def get_forums(self, req, cursor, order_by = 'ORDER BY subject ASC'): columns = ('id', 'name', 'author', 'time', 'moderators', 'group', 'subject', 'description', 'topics', 'replies', 'lastreply', 'lasttopic') sql = "SELECT id, name, author, time, moderators, forum_group," \ " subject, description, (SELECT COUNT(id) FROM topic t WHERE" \ " t.forum = forum.id) AS topics, (SELECT COUNT(id) FROM message m" \ " WHERE m.forum = forum.id) AS replies, (SELECT MAX(time) FROM" \ " message m WHERE m.forum = forum.id) AS lasttopic, (SELECT" \ " MAX(time) FROM topic t WHERE t.forum = forum.id) AS lastreply" \ " FROM forum " + order_by self.log.debug(sql) cursor.execute(sql) forums = [] for row in cursor: row = dict(zip(columns, row)) row['moderators'] = wiki_to_oneliner(row['moderators'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) if row['lastreply']: row['lastreply'] = pretty_timedelta(row['lastreply']) else: row['lastreply'] = 'No replies' if row['lasttopic']: row['lasttopic'] = pretty_timedelta(row['lasttopic']) else: row['lasttopic'] = 'No topics' row['time'] = format_datetime(row['time']) forums.append(row) return forums
def get_groups(self, req, cursor, order_by='id', desc=False): # Get count of forums without group sql = "SELECT COUNT(f.id) FROM forum f WHERE f.forum_group = 0" self.log.debug(sql) cursor.execute(sql) no_group_forums = 0 for row in cursor: no_group_forums = row[0] groups = [{ 'id': 0, 'name': 'None', 'description': 'No Group', 'forums': no_group_forums }] # Get forum groups if order_by != 'forum': order_by = 'g.' + order_by columns = ('id', 'name', 'description', 'forums') sql = "SELECT g.id, g.name, g.description, f.forums FROM " \ " forum_group g LEFT JOIN (SELECT COUNT(id) AS forums, " \ " forum_group FROM forum GROUP BY forum_group) f ON g.id = " \ " f.forum_group ORDER BY " + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) for row in cursor: row = dict(zip(columns, row)) row['name'] = wiki_to_oneliner(row['name'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) groups.append(row) return groups
def get_forums(self, req, cursor, order_by='ORDER BY subject ASC'): columns = ('id', 'name', 'author', 'time', 'moderators', 'group', 'subject', 'description', 'topics', 'replies', 'lastreply', 'lasttopic') sql = "SELECT id, name, author, time, moderators, forum_group," \ " subject, description, (SELECT COUNT(id) FROM topic t WHERE" \ " t.forum = forum.id) AS topics, (SELECT COUNT(id) FROM message m" \ " WHERE m.forum = forum.id) AS replies, (SELECT MAX(time) FROM" \ " message m WHERE m.forum = forum.id) AS lasttopic, (SELECT" \ " MAX(time) FROM topic t WHERE t.forum = forum.id) AS lastreply" \ " FROM forum " + order_by self.log.debug(sql) cursor.execute(sql) forums = [] for row in cursor: row = dict(zip(columns, row)) row['moderators'] = wiki_to_oneliner(row['moderators'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) if row['lastreply']: row['lastreply'] = pretty_timedelta(row['lastreply']) else: row['lastreply'] = 'No replies' if row['lasttopic']: row['lasttopic'] = pretty_timedelta(row['lasttopic']) else: row['lasttopic'] = 'No topics' row['time'] = format_datetime(row['time']) forums.append(row) return forums
def get_groups(self, req, cursor, order_by = 'id', desc = False): # Get count of forums without group sql = "SELECT COUNT(f.id) FROM forum f WHERE f.forum_group = 0" self.log.debug(sql) cursor.execute(sql) no_group_forums = 0 for row in cursor: no_group_forums = row[0] groups = [{'id' : 0, 'name' : 'None', 'description' : 'No Group', 'forums' : no_group_forums}] # Get forum groups if order_by != 'forum': order_by = 'g.' + order_by columns = ('id', 'name', 'description', 'forums') sql = "SELECT g.id, g.name, g.description, f.forums FROM " \ " forum_group g LEFT JOIN (SELECT COUNT(id) AS forums, " \ " forum_group FROM forum GROUP BY forum_group) f ON g.id = " \ " f.forum_group ORDER BY " + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) for row in cursor: row = dict(zip(columns, row)) row['name'] = wiki_to_oneliner(row['name'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) groups.append(row) return groups
def get_groups(self, req, cursor, order_by='ORDER BY id ASC'): # Get count of forums without group sql = "SELECT COUNT(id) FROM forum WHERE forum_group = 0" self.log.debug(sql) cursor.execute(sql) no_group_forums = 0 for row in cursor: no_group_forums = row[0] groups = [{ 'id': 0, 'name': 'None', 'description': 'No Group', 'forums': no_group_forums }] # Get forum groups columns = ('id', 'name', 'description', 'forums') sql = "SELECT id, name, description, (SELECT COUNT(id) FROM forum f" \ " WHERE f.forum_group = forum_group.id) FROM forum_group " + order_by self.log.debug(sql) cursor.execute(sql) for row in cursor: row = dict(zip(columns, row)) row['name'] = wiki_to_oneliner(row['name'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) groups.append(row) return groups
def get_timeline_events(self, req, start, stop, filters): if 'changeset' in filters: format = req.args.get('format') wiki_format = self.wiki_format_messages show_files = self.timeline_show_files db = self.env.get_db_cnx() repos = self.env.get_repository(req.authname) for chgset in repos.get_changesets(start, stop): message = chgset.message or '--' if wiki_format: shortlog = wiki_to_oneliner(message, self.env, db, shorten=True) else: shortlog = shorten_line(message) if format == 'rss': title = Markup('Changeset [%s]: %s', chgset.rev, shortlog) href = req.abs_href.changeset(chgset.rev) if wiki_format: message = wiki_to_html(message, self.env, req, db, absurls=True) else: message = html.PRE(message) else: title = Markup('Changeset <em>[%s]</em> by %s', chgset.rev, chgset.author) href = req.href.changeset(chgset.rev) if wiki_format: if self.timeline_long_messages: message = wiki_to_html(message, self.env, req, db, absurls=True) else: message = wiki_to_oneliner(message, self.env, db, shorten=True) else: message = shortlog if show_files and req.perm.has_permission('BROWSER_VIEW'): files = [] for chg in chgset.get_changes(): if show_files > 0 and len(files) >= show_files: files.append(html.LI(Markup('…'))) break files.append(html.LI(html.DIV(class_=chg[2]), chg[0] or '/')) message = html.UL(files, class_="changes") + message yield 'changeset', href, title, chgset.date, chgset.author,\ message
def get_timeline_events(self, req, start, stop, filters): if 'changeset' in filters: format = req.args.get('format') wiki_format = self.wiki_format_messages show_files = self.timeline_show_files db = self.env.get_db_cnx() repos = self.env.get_repository(req.authname) for chgset in repos.get_changesets(start, stop): message = chgset.message or '--' if wiki_format: shortlog = wiki_to_oneliner(message, self.env, db, shorten=True) else: shortlog = shorten_line(message) if format == 'rss': title = Markup(u'변경사항 [%s]: %s', chgset.rev, shortlog) href = req.abs_href.changeset(chgset.rev) if wiki_format: message = wiki_to_html(message, self.env, req, db, absurls=True) else: message = html.PRE(message) else: title = Markup(u'변경사항 <em>[%s]</em> : %s에 의해 수정됨', chgset.rev, chgset.author) href = req.href.changeset(chgset.rev) if wiki_format: if self.timeline_long_messages: message = wiki_to_html(message, self.env, req, db, absurls=True) else: message = wiki_to_oneliner(message, self.env, db, shorten=True) else: message = shortlog if show_files and req.perm.has_permission('BROWSER_VIEW'): files = [] for chg in chgset.get_changes(): if show_files > 0 and len(files) >= show_files: files.append(html.LI(Markup('…'))) break files.append(html.LI(html.DIV(class_=chg[2]), chg[0] or '/')) message = html.UL(files, class_="changes") + message yield 'changeset', href, title, chgset.date, chgset.author,\ message
def get_timeline_events(self, req, start, stop, filters): if 'codereview' in filters: crp = CodeReviewPool(self.env) for t, author, text, cr_id, status, version, message in \ crp.get_codereviews_by_time(to_timestamp(start), to_timestamp(stop)): if status == str_status["NoNeedToReview"]: continue elif status == str_status["CompletelyReview"]: title = Markup( 'CodeReview : [ <em title="%s" >%s</em> ] completed by %s' % (message, cr_id, author)) elif version == 1: title = Markup( 'CodeReview : [ <em title="%s" >%s</em> ] created by %s' % (message, cr_id, author)) else: title = Markup( 'CodeReview : [ <em title="%s" >%s</em> ] edited by %s' % (message, cr_id, author)) href = "%s/%s" % (self.env.href.CodeReview(), cr_id) text = wiki_to_oneliner(text, self.env, self.env.get_db_cnx(), shorten=True, req=req) yield 'codereview', href, title, t, author, text
def get_changes(env, repos, revs, full=None, req=None, format=None): db = env.get_db_cnx() changes = {} for rev in revs: changeset = repos.get_changeset(rev) message = changeset.message or '--' files = None if format == 'changelog': files = [change[0] for change in changeset.get_changes()] elif message: if not full: message = wiki_to_oneliner(message, env, db, shorten=True) else: message = wiki_to_html(message, env, req, db, absurls=(format == 'rss'), escape_newlines=True) if not message: message = '--' changes[rev] = { 'date_seconds': changeset.date, 'date': format_datetime(changeset.date), 'age': pretty_timedelta(changeset.date), 'author': changeset.author or 'anonymous', 'message': message, 'shortlog': shorten_line(message), 'files': files } return changes
def attachment_to_hdf(env, req, db, attachment): """ This function have been removed from 0.11, this is copied from 0.10, then modified to work with 0.11 """ if not db: db = env.get_db_cnx() hdf = { 'filename': attachment.filename, 'description': wiki_to_oneliner(attachment.description, env, db, req=req), 'author': attachment.author, 'ipnr': attachment.ipnr, 'size': pretty_size(attachment.size), 'time': format_datetime(attachment.date), 'age': pretty_timedelta(attachment.date), 'href': AttachmentModule(env).get_resource_url(attachment.resource, req.href) } return hdf
def get_timeline_events(self, req, start, stop, filters): self.log.debug("start: %s, stop: %s, filters: %s" % (start, stop, filters)) if 'downloads' in filters: # Create database context db = self.env.get_db_cnx() cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] format = req.args.get('format') self.log.debug("format: %s" % (format)) # Get message events for download in api.get_new_downloads(req, cursor, start, stop): kind = 'newticket' title = Markup("New download <em>%s</em> created by %s" % (download['file'], download['author'])) time = download['time'] author = download['author'] if format == 'rss': href = req.abs_href.downloads(download['id']) message = wiki_to_html(download['description'], self.env, req) else: href = req.href.downloads(download['id']) message = wiki_to_oneliner(download['description'], self.env) yield kind, href, title, time, author, message
def get_downloads(self, req, cursor, order_by = 'id', desc = False): columns = ('id', 'file', 'description', 'size', 'time', 'count', 'author', 'tags', 'component', 'version', 'architecture', 'platform', 'type') sql = "SELECT id, file, description, size, time, count, author, tags," \ " component, version, architecture, platform, type FROM download " \ "ORDER BY " + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) downloads = [] for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) row['size'] = pretty_size(row['size']) row['time'] = pretty_timedelta(row['time']) row['count'] = row['count'] or 0 downloads.append(row) # Replace field ids with apropriate objects. for download in downloads: download['architecture'] = self.get_architecture(cursor, download['architecture']) download['platform'] = self.get_platform(cursor, download['platform']) download['type'] = self.get_type(cursor, download['type']) return downloads
def get_timeline_events(self, req, start, stop, filters): if 'milestone' in filters: format = req.args.get('format') db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute( "SELECT completed,name,description FROM milestone " "WHERE completed>=%s AND completed<=%s", ( start, stop, )) for completed, name, description in cursor: title = Markup('Milestone <em>%s</em> completed', name) if format == 'rss': href = req.abs_href.milestone(name) message = wiki_to_html(description, self.env, req, db, absurls=True) else: href = req.href.milestone(name) message = wiki_to_oneliner(description, self.env, db, shorten=True) yield 'milestone', href, title, completed, None, message or '--'
def get_messages(self, req, cursor, topic, time, order_by='ORDER BY time ASC'): columns = ('id', 'replyto', 'time', 'author', 'body') sql = "SELECT id, replyto, time, author, body FROM message WHERE" \ " topic = %s " + order_by self.log.debug(sql % (topic, )) cursor.execute(sql, (topic, )) messagemap = {} messages = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req) if int(row['time']) > time: row['new'] = True row['time'] = format_datetime(row['time']) messagemap[row['id']] = row # Add top-level messages to the main list, in order of time if row['replyto'] == -1: messages.append(row) # Second pass, add replies for message in messagemap.values(): if message['replyto'] != -1: parent = messagemap[message['replyto']] if 'replies' in parent: parent['replies'].append(message) else: parent['replies'] = [message] return messages
def get_messages(self, req, cursor, topic, time, order_by = 'ORDER BY time ASC'): columns = ('id', 'replyto', 'time', 'author', 'body') sql = "SELECT id, replyto, time, author, body FROM message WHERE" \ " topic = %s " + order_by self.log.debug(sql % (topic,)) cursor.execute(sql, (topic,)) messagemap = {} messages = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req) if int(row['time']) > time: row['new'] = True row['time'] = format_datetime(row['time']) messagemap[row['id']] = row # Add top-level messages to the main list, in order of time if row['replyto'] == -1: messages.append(row) # Second pass, add replies for message in messagemap.values(): if message['replyto'] != -1: parent = messagemap[message['replyto']] if 'replies' in parent: parent['replies'].append(message) else: parent['replies'] = [message] return messages;
def render_listtags(self, req, *tags, **kwargs): """ List tags. For backwards compatibility, can accept a list of tags. This will simply call ListTagged. Optional keyword arguments are tagspace=wiki, tagspaces=(wiki, ticket, ...) and shownames=true. """ if tags: # Backwards compatibility return self.render_listtagged(req, *tags, **kwargs) page = self._current_page(req) engine = TagEngine(self.env) showpages = kwargs.get('showpages', None) or kwargs.get('shownames', 'false') if 'tagspace' in kwargs: tagspaces = [kwargs['tagspace']] else: tagspaces = kwargs.get('tagspaces', []) or \ list(TagEngine(self.env).tagspaces) out = StringIO() out.write('<ul class="listtags">\n') tag_details = {} for tag, names in sorted(engine.get_tags(tagspaces=tagspaces, detailed=True).iteritems()): href, title = engine.get_tag_link(tag) htitle = wiki_to_oneliner(title, self.env) out.write('<li><a href="%s" title="%s">%s</a> %s <span class="tagcount">(%i)</span>' % (href, title, tag, htitle, len(names))) if showpages == 'true': out.write('\n') out.write(self.render_listtagged(req, tag, tagspaces=tagspaces)) out.write('</li>\n') out.write('</ul>\n') return out.getvalue()
def get_downloads(self, req, cursor, order_by='id', desc=False): columns = ('id', 'file', 'description', 'size', 'time', 'count', 'author', 'tags', 'component', 'version', 'architecture', 'platform', 'type') sql = "SELECT id, file, description, size, time, count, author, tags," \ " component, version, architecture, platform, type FROM download " \ "ORDER BY " + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) downloads = [] for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) row['size'] = pretty_size(row['size']) row['time'] = pretty_timedelta(row['time']) row['count'] = row['count'] or 0 downloads.append(row) # Replace field ids with apropriate objects. for download in downloads: download['architecture'] = self.get_architecture( cursor, download['architecture']) download['platform'] = self.get_platform(cursor, download['platform']) download['type'] = self.get_type(cursor, download['type']) return downloads
def get_messages(self, req, cursor, topic_id, time, order_by = 'time', desc = False): order_by = 'm.' + order_by columns = ('id', 'replyto', 'time', 'author', 'body') sql = "SELECT m.id, m.replyto, m.time, m.author, m.body FROM message m WHERE" \ " m.topic = %s ORDER BY " + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql % (topic_id,)) cursor.execute(sql, (topic_id,)) messagemap = {} messages = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req, None, False, True) if int(row['time']) > time: row['new'] = True row['time'] = format_datetime(row['time']) messagemap[row['id']] = row # Add top-level messages to the main list, in order of time if row['replyto'] == -1: messages.append(row) # Second pass, add replies for message in messagemap.values(): if message['replyto'] != -1: parent = messagemap[message['replyto']] if 'replies' in parent: parent['replies'].append(message) else: parent['replies'] = [message] return messages;
def get_timeline_events(self, req, start, stop, filters): self.log.debug("start: %s, stop: %s, filters: %s" % (start, stop, filters)) if "downloads" in filters: # Create database context db = self.env.get_db_cnx() cursor = db.cursor() # Get API component. api = self.env[DownloadsApi] format = req.args.get("format") self.log.debug("format: %s" % (format)) # Get message events for download in api.get_new_downloads(req, cursor, start, stop): kind = "newticket" title = Markup("New download <em>%s</em> created by %s" % (download["file"], download["author"])) time = download["time"] author = download["author"] if format == "rss": href = req.abs_href.downloads(download["id"]) message = wiki_to_html(download["description"], self.env, req) else: href = req.href.downloads(download["id"]) message = wiki_to_oneliner(download["description"], self.env) yield kind, href, title, time, author, message
def get_topics(self, req, cursor, forum_id, order_by = 'time', desc = False): if not order_by in ('replies', 'lastreply',): order_by = 't.' + order_by columns = ('id', 'forum', 'time', 'subject', 'body', 'author', 'replies', 'lastreply') sql = "SELECT t.id, t.forum, t.time, t.subject, t.body, t.author," \ " m.replies, m.lastreply FROM topic t LEFT JOIN (SELECT COUNT(id)" \ " AS replies, MAX(time) AS lastreply, topic FROM message GROUP BY" \ " topic) m ON t.id = m.topic WHERE t.forum = %s ORDER BY " \ + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql % (forum_id,)) cursor.execute(sql, (forum_id,)) topics = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req) if row['lastreply']: row['lastreply'] = pretty_timedelta(float(row['lastreply'])) else: row['lastreply'] = 'No replies' if not row['replies']: row['replies'] = 0 row['time'] = format_datetime(row['time']) topics.append(row) return topics
def get_topics(self, req, cursor, forum_id, order_by='time', desc=False): if not order_by in ( 'replies', 'lastreply', ): order_by = 't.' + order_by columns = ('id', 'forum', 'time', 'subject', 'body', 'author', 'replies', 'lastreply') sql = "SELECT t.id, t.forum, t.time, t.subject, t.body, t.author," \ " m.replies, m.lastreply FROM topic t LEFT JOIN (SELECT COUNT(id)" \ " AS replies, MAX(time) AS lastreply, topic FROM message GROUP BY" \ " topic) m ON t.id = m.topic WHERE t.forum = %s ORDER BY " \ + order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql % (forum_id, )) cursor.execute(sql, (forum_id, )) topics = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req) if row['lastreply']: row['lastreply'] = pretty_timedelta(float(row['lastreply'])) else: row['lastreply'] = 'No replies' if not row['replies']: row['replies'] = 0 row['time'] = format_datetime(row['time']) topics.append(row) return topics
def get_timeline_events(self, req, start, stop, filters): format = req.args.get('format') status_map = { 'new': ('newticket', u'créé'), 'reopened': ('newticket', u'réouvert'), 'closed': ('closedticket', u'fermé'), 'edit': ('editedticket', u'mis à jour') } href = format == 'rss' and req.abs_href or req.href def produce( (id, t, author, type, summary), status, fields, comment, cid): if status == 'edit': if 'ticket_details' in filters: info = u'' if len(fields) > 0: info = u', '.join([u'<i>%s</i>' % f for f in \ fields.keys()]) + u' modifié<br />' else: return None elif 'ticket' in filters: if status == 'closed' and fields.has_key('resolution'): info = fields['resolution'] if info and comment: info = '%s: ' % info else: info = '' else: return None kind, verb = status_map[status] if format == 'rss': title = u'Ticket #%s (%s %s): %s' % \ (id, translate(self.env, type).lower(), verb, summary) else: title = Markup( u'Ticket <em title="%s">#%s</em> (%s) %s par %s', summary, id, translate(self.env, type), verb, author) ticket_href = href.ticket(id) if cid: ticket_href += '#comment:' + cid if status == 'new': message = unicode(summary) else: message = Markup(info) if comment: if format == 'rss': message += wiki_to_html(comment, self.env, req, db, absurls=True) else: message += wiki_to_oneliner(comment, self.env, db, shorten=True) return kind, ticket_href, title, t, author, message
def _prepare_message_list(self, req, cursor, topic): # Get form values. new_author = req.args.get('author') new_subject = req.args.get('subject') new_body = req.args.get('body') # Get time when topic was visited from session. visited = eval(req.session.get('visited-topics') or '{}') if visited.has_key(topic['id']): visit_time = int(visited[topic['id']]) else: visit_time = 0 # Update this topic visit time and save to session. visited[topic['id']] = int(time.time()) req.session['visited-topics'] = to_unicode(visited) # Mark new topic. if int(topic['time']) > visit_time: topic['new'] = True # Prepare display of topic if new_author: req.hdf['discussion.author'] = wiki_to_oneliner(new_author, self.env) if new_subject: req.hdf['discussion.subject'] = wiki_to_oneliner(new_subject, self.env) if new_body: req.hdf['discussion.body'] = wiki_to_html(new_body, self.env, req) # Prepare display of messages display = req.session.get('message-list-display') or \ self.default_display req.hdf['discussion.display'] = display if display == 'flat-asc': req.hdf['discussion.messages'] = self.get_flat_messages(req, cursor, topic['id'], visit_time) elif display == 'flat-desc' or display == 'flat': req.hdf['discussion.messages'] = self.get_flat_messages(req, cursor, topic['id'], visit_time, 'ORDER BY time DESC') elif display == 'tree' or display == '': req.hdf['discussion.messages'] = self.get_messages(req, cursor, topic['id'], visit_time) else: raise TracError('Unsupported display mode: %s' % (display))
def _prepare_message_list(self, req, cursor, topic): # Get form values. new_author = req.args.get('author') new_subject = req.args.get('subject') new_body = req.args.get('body') # Get time when topic was visited from session. visited = eval(req.session.get('visited-topics') or '{}') if visited.has_key(topic['id']): visit_time = int(visited[topic['id']]) else: visit_time = 0 # Update this topic visit time and save to session. visited[topic['id']] = int(time.time()) req.session['visited-topics'] = to_unicode(visited) # Mark new topic. if int(topic['time']) > visit_time: topic['new'] = True # Prepare display of topic if new_author: req.hdf['discussion.author'] = wiki_to_oneliner( new_author, self.env) if new_subject: req.hdf['discussion.subject'] = wiki_to_oneliner( new_subject, self.env) if new_body: req.hdf['discussion.body'] = wiki_to_html(new_body, self.env, req) # Prepare display of messages display = req.session.get('message-list-display') or \ self.default_display req.hdf['discussion.display'] = display if display == 'flat-asc': req.hdf['discussion.messages'] = self.get_flat_messages( req, cursor, topic['id'], visit_time) elif display == 'flat-desc' or display == 'flat': req.hdf['discussion.messages'] = self.get_flat_messages( req, cursor, topic['id'], visit_time, 'ORDER BY time DESC') elif display == 'tree' or display == '': req.hdf['discussion.messages'] = self.get_messages( req, cursor, topic['id'], visit_time) else: raise TracError('Unsupported display mode: %s' % (display))
def render_discussion(self, req): # Get request mode group, forum, topic, message = self._get_items(req) modes = self._get_modes(req, group, forum, topic, message) self.log.debug('modes: %s' % modes) # Determine moderator rights. if forum: is_moderator = (req.authname in forum['moderators']) or \ req.perm.has_permission('DISCUSSION_ADMIN') else: is_moderator = req.perm.has_permission('DISCUSSION_ADMIN') # Perform mode actions self._do_action(req, modes, group, forum, topic, message, is_moderator) # Add CSS styles add_stylesheet(req, 'common/css/wiki.css') add_stylesheet(req, 'discussion/css/discussion.css') add_stylesheet(req, 'discussion/css/admin.css') add_link(req, 'alternate', '/timeline?discussion=on&max=50&daysback=90&format=rss', 'POPFile forums', 'application/rss+xml') # Fill up HDF structure and return template req.hdf['discussion.authname'] = req.authname req.hdf['discussion.is_moderator'] = is_moderator title = 'POPFile Forums' if group: group['name'] = wiki_to_oneliner(group['name'], self.env) group['description'] = wiki_to_oneliner(group['description'], self.env) req.hdf['discussion.group'] = group if forum: forum['name'] = wiki_to_oneliner(forum['name'], self.env) forum['description'] = wiki_to_oneliner(forum['description'], self.env) forum['subject'] = wiki_to_oneliner(forum['subject'], self.env) forum['time'] = format_datetime(forum['time']) req.hdf['discussion.forum'] = forum title = 'POPFile ' + forum['name'] + ' Forum' if topic: topic['subject'] = wiki_to_oneliner(topic['subject'], self.env) topic['author'] = wiki_to_oneliner(topic['author'], self.env) topic['body'] = wiki_to_html(topic['body'], self.env, req, None, False, True) topic['time'] = format_datetime(topic['time']) req.hdf['discussion.topic'] = topic if message: message['author'] = wiki_to_oneliner(message['author'], self.env) message['body'] = wiki_to_html(message['body'], self.env, req, None, False, True) message['time'] = format_datetime(message['time']) req.hdf['discussion.message'] = message req.hdf['discussion.mode'] = modes[-1] req.hdf['discussion.time'] = format_datetime(time.time()) req.hdf['title'] = title return modes[-1] + '.cs', None
def render_listtagged(self, req, *tags, **kwargs): """ List tagged objects. Optionally accepts a list of tags to match against. The special tag '''. (dot)''' inserts the current Wiki page name. `[[ListTagged(<tag>, ...)]]` ||'''Argument'''||'''Description'''|| ||`tagspace=<tagspace>`||Specify the tagspace the macro should operate on.|| ||`tagspaces=(<tagspace>,...)`||Specify a set of tagspaces the macro should operate on.|| ||`operation=intersection|union`||The set operation to perform on the discovered objects.|| ||`showheadings=true|false`||List objects under the tagspace they occur in.|| """ if 'tagspace' in kwargs: tagspaces = [kwargs.get('tagspace', None)] else: tagspaces = kwargs.get('tagspaces', '') or \ list(TagEngine(self.env).tagspaces) showheadings = kwargs.get('showheadings', 'false') operation = kwargs.get('operation', 'intersection') if operation not in ('union', 'intersection'): raise TracError("Invalid tag set operation '%s'" % operation) engine = TagEngine(self.env) page_name = req.hdf.get('wiki.page_name') if page_name: tags = [tag == '.' and page_name or tag for tag in tags] taginfo = {} out = StringIO() out.write('<ul class="listtagged">') # Cull empty names tagged_names = [(tagspace, names) for tagspace, names in engine.get_tagged_names(tags=tags, tagspaces=tagspaces, operation=operation, detailed=True).iteritems() if names] for tagspace, tagspace_names in sorted(tagged_names): if showheadings == 'true': out.write('<lh>%s tags</lh>' % tagspace) for name, tags in sorted(tagspace_names.iteritems()): if tagspace == 'wiki' and unicode(name).startswith('tags/'): continue tags = sorted(tags) taginfo = self._tag_details(taginfo, tags) href, link, title = engine.name_details(tagspace, name) htitle = wiki_to_oneliner(title, self.env) name_tags = ['<a href="%s" title="%s">%s</a>' % (taginfo[tag][0], taginfo[tag][1], tag) for tag in tags] if not name_tags: name_tags = '' else: name_tags = ' (' + ', '.join(sorted(name_tags)) + ')' out.write('<li>%s %s%s</li>\n' % (link, htitle, name_tags)) out.write('</ul>') return out.getvalue()
def get_screenshots(self, cursor, component, version): columns = ('id', 'name', 'description', 'time', 'author', 'tags', 'large_file', 'medium_file', 'small_file') sql = "SELECT s.id, s.name, s.description, s.time, s.author, s.tags," \ " s.large_file, s.medium_file, s.small_file FROM screenshot s," \ " screenshot_component c, screenshot_version v WHERE c.component" \ " = %s AND v.version = %s AND s.id = c.screenshot AND s.id =" \ " v.screenshot;" self.log.debug(sql % (component, version)) cursor.execute(sql, (component, version)) screenshots = [] for row in cursor: row = dict(zip(columns, row)) row['name'] = wiki_to_oneliner(row['name'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) row['author'] = wiki_to_oneliner(row['author'], self.env) screenshots.append(row) return screenshots
def render_listtagged(self, req, *tags, **kwargs): """ List tagged objects. Takes a list of tags to match against. The special tag '.' inserts the current Wiki page name. Optional keyword arguments are tagspace=wiki, tagspaces=(wiki, title, ...) and showheadings=true. By default displays the intersection of objects matching each tag. By passing operation=union this can be modified to display the union of objects matching each tag. """ if 'tagspace' in kwargs: tagspaces = [kwargs.get('tagspace', None)] else: tagspaces = kwargs.get('tagspaces', '') or \ list(TagEngine(self.env).tagspaces) showheadings = kwargs.get('showheadings', 'false') operation = kwargs.get('operation', 'intersection') if operation not in ('union', 'intersection'): raise TracError("Invalid tag set operation '%s'" % operation) engine = TagEngine(self.env) page_name = req.hdf.get('wiki.page_name') if page_name: tags = [tag == '.' and page_name or tag for tag in tags] taginfo = {} out = StringIO() out.write('<ul class="listtagged">') for tagspace, tagspace_names in sorted( engine.get_tagged_names(tags=tags, tagspaces=tagspaces, operation=operation, detailed=True).iteritems()): if showheadings == 'true': out.write('<lh>%s tags</lh>' % tagspace) for name, tags in sorted(tagspace_names.iteritems()): if tagspace == 'wiki' and unicode(name).startswith('tags/'): continue tags = sorted(tags) taginfo = self._tag_details(taginfo, tags) href, link, title = engine.name_details(tagspace, name) htitle = wiki_to_oneliner(title, self.env) name_tags = [ '<a href="%s" title="%s">%s</a>' % (taginfo[tag][0], taginfo[tag][1], tag) for tag in tags ] if not name_tags: name_tags = '' else: name_tags = ' (' + ', '.join(sorted(name_tags)) + ')' out.write('<li>%s %s%s</li>\n' % (link, htitle, name_tags)) out.write('</ul>') return out.getvalue()
def get_task_markup(self, req, ticket, task): if not task: return '' ticket_text = 'ticket #' + str(task['ticket']) if task['ticket'] == ticket: ticket_text = 'this ticket' timedelta = pretty_timedelta(task['starttime'], None); return '<li>%s</li>' % wiki_to_oneliner('You have been working on %s for %s' % (ticket_text, timedelta), self.env, req=req)
def get_timeline_events(self, req, start, stop, filters): format = req.args.get('format') status_map = { 'new': ('newticket', u'créé'), 'reopened': ('newticket', u'réouvert'), 'closed': ('closedticket', u'fermé'), 'edit': ('editedticket', u'mis à jour') } href = format == 'rss' and req.abs_href or req.href def produce((id, t, author, type, summary), status, fields, comment, cid): if status == 'edit': if 'ticket_details' in filters: info = u'' if len(fields) > 0: info = u', '.join([u'<i>%s</i>' % f for f in \ fields.keys()]) + u' modifié<br />' else: return None elif 'ticket' in filters: if status == 'closed' and fields.has_key('resolution'): info = fields['resolution'] if info and comment: info = '%s: ' % info else: info = '' else: return None kind, verb = status_map[status] if format == 'rss': title = u'Ticket #%s (%s %s): %s' % \ (id, translate(self.env, type).lower(), verb, summary) else: title = Markup( u'Ticket <em title="%s">#%s</em> (%s) %s par %s', summary, id, translate(self.env, type), verb, author) ticket_href = href.ticket(id) if cid: ticket_href += '#comment:' + cid if status == 'new': message = unicode(summary) else: message = Markup(info) if comment: if format == 'rss': message += wiki_to_html( comment, self.env, req, db, absurls=True) else: message += wiki_to_oneliner( comment, self.env, db, shorten=True) return kind, ticket_href, title, t, author, message
def render_discussion(self, req, cursor): # Get request mode group, forum, topic, message = self._get_items(req, cursor) modes = self._get_modes(req, group, forum, topic, message) self.log.debug('modes: %s' % modes) # Determine moderator rights. if forum: is_moderator = (req.authname in forum['moderators']) or \ req.perm.has_permission('DISCUSSION_ADMIN') else: is_moderator = req.perm.has_permission('DISCUSSION_ADMIN') # Perform mode actions self._do_action(req, cursor, modes, group, forum, topic, message, is_moderator) # Add CSS styles add_stylesheet(req, 'common/css/wiki.css') add_stylesheet(req, 'discussion/css/discussion.css') add_stylesheet(req, 'discussion/css/admin.css') # Fill up HDF structure and return template req.hdf['discussion.authname'] = req.authname req.hdf['discussion.is_moderator'] = is_moderator if group: group['name'] = wiki_to_oneliner(group['name'], self.env) group['description'] = wiki_to_oneliner(group['description'], self.env) req.hdf['discussion.group'] = group if forum: forum['name'] = wiki_to_oneliner(forum['name'], self.env) forum['description'] = wiki_to_oneliner(forum['description'], self.env) forum['subject'] = wiki_to_oneliner(forum['subject'], self.env) forum['time'] = format_datetime(forum['time']) req.hdf['discussion.forum'] = forum if topic: topic['subject'] = wiki_to_oneliner(topic['subject'], self.env) topic['author'] = wiki_to_oneliner(topic['author'], self.env) topic['body'] = wiki_to_html(topic['body'], self.env, req) topic['time'] = format_datetime(topic['time']) req.hdf['discussion.topic'] = topic if message: message['author'] = wiki_to_oneliner(message['author'], self.env) message['body'] = wiki_to_html(message['body'], self.env, req) message['time'] = format_datetime(message['time']) req.hdf['discussion.message'] = message req.hdf['discussion.mode'] = modes[-1] req.hdf['discussion.time'] = format_datetime(time.time()) return modes[-1] + '.cs', None
def get_forums(self, req, cursor, order_by = 'subject', desc = False): if not order_by in ('topics', 'replies', 'lasttopic', 'lastreply'): order_by = 'f.' + order_by columns = ('id', 'name', 'author', 'time', 'moderators', 'group', 'subject', 'description', 'topics', 'replies', 'lasttopic', 'lastreply') sql = "SELECT f.id, f.name, f.author, f.time, f.moderators, " \ "f.forum_group, f.subject, f.description, ta.topics, ta.replies, " \ "ta.lasttopic, ta.lastreply FROM forum f LEFT JOIN (SELECT " \ "COUNT(t.id) AS topics, MAX(t.time) AS lasttopic, SUM(ma.replies) " \ "AS replies, MAX(ma.lastreply) AS lastreply, t.forum AS forum FROM " \ " topic t LEFT JOIN (SELECT COUNT(m.id) AS replies, MAX(m.time) AS " \ "lastreply, m.topic AS topic FROM message m GROUP BY m.topic) ma ON " \ "t.id = ma.topic GROUP BY forum) ta ON f.id = ta.forum ORDER BY " + \ order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) forums = [] for row in cursor: row = dict(zip(columns, row)) row['moderators'] = wiki_to_oneliner(row['moderators'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) if row['lastreply']: row['lastreply'] = pretty_timedelta(float(row['lastreply'])) else: row['lastreply'] = 'No replies' if row['lasttopic']: self.log.debug('lasttopic: %s' % row['lasttopic']) row['lasttopic'] = pretty_timedelta(float(row['lasttopic'])) else: row['lasttopic'] = 'No topics' if not row['topics']: row['topics'] = 0 if not row['replies']: row['replies'] = 0 else: # SUM on PosgreSQL returns float number. row['replies'] = int(row['replies']) row['time'] = format_datetime(row['time']) forums.append(row) return forums
def get_forums(self, req, cursor, asc=0, order_by='subject'): if not order_by in ('topics', 'replies', 'lasttopic', 'lastreply'): order_by = 'f.' + order_by columns = ('id', 'name', 'author', 'time', 'moderators', 'group', 'subject', 'description', 'topics', 'replies', 'lasttopic', 'lastreply') sql = "SELECT f.id, f.name, f.author, f.time, f.moderators, " \ "f.forum_group, f.subject, f.description, ta.topics, ta.replies, " \ "ta.lasttopic, ta.lastreply FROM forum f LEFT JOIN (SELECT " \ "COUNT(t.id) AS topics, MAX(t.time) AS lasttopic, SUM(ma.replies) " \ "AS replies, MAX(ma.lastreply) AS lastreply, t.forum AS forum FROM " \ " topic t LEFT JOIN (SELECT COUNT(m.id) AS replies, MAX(m.time) AS " \ "lastreply, m.topic AS topic FROM message m GROUP BY m.topic) ma ON " \ "t.id = ma.topic GROUP BY forum) ta ON f.id = ta.forum ORDER BY " + \ order_by + (" DESC", " ASC")[int(asc)] self.log.debug(sql) cursor.execute(sql) forums = [] for row in cursor: row = dict(zip(columns, row)) row['moderators'] = wiki_to_oneliner(row['moderators'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) if row['lastreply']: row['lastreply'] = pretty_timedelta(float(row['lastreply'])) else: row['lastreply'] = 'No replies' if row['lasttopic']: self.log.debug('lasttopic: %s' % row['lasttopic']) row['lasttopic'] = pretty_timedelta(float(row['lasttopic'])) else: row['lasttopic'] = 'No topics' if not row['topics']: row['topics'] = 0 if not row['replies']: row['replies'] = 0 else: # SUM on PosgreSQL returns float number. row['replies'] = int(row['replies']) row['time'] = format_datetime(row['time']) forums.append(row) return forums
def get_types(self, req, cursor, order_by='id', desc=False): columns = ('id', 'name', 'description') sql = "SELECT id, name, description FROM download_type ORDER BY " + \ order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) types = [] for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) types.append(row) return types
def _get_messages(self, req, cursor): cursor.execute("SELECT id, author, time, title, body FROM guestbook" " ORDER BY time") columns = ['id', 'author', 'time', 'title', 'body'] messages = [] for message in cursor: message = dict(zip(columns, message)) message['time'] = format_datetime(message['time']) message['title'] = wiki_to_oneliner(message['title'], self.env) message['body'] = wiki_to_html(message['body'], self.env, req) messages.append(message) return messages
def get_timeline_events(self, req, start, stop, filters): if 'ticket_details' in filters: db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute( "SELECT tc.time,tc.ticket,t.type,tc.field, " " tc.oldvalue,tc.newvalue,tc.author,t.summary " "FROM ticket_change tc" " INNER JOIN ticket t ON t.id = tc.ticket " "AND tc.time>=%s AND tc.time<=%s ORDER BY tc.time" % (start, stop)) previous_update = None updates = [] ticket_change = False for time, id, type, field, oldvalue, newvalue, author, summary in cursor: if not previous_update or (time, id, author) != previous_update[:3]: if previous_update and not ticket_change: updates.append( (previous_update, field_changes, comment)) ticket_change = False field_changes = [] comment = '' previous_update = (time, id, author, type, summary) if field == 'comment': comment = newvalue elif field == 'status' and newvalue in ['reopened', 'closed']: ticket_change = True else: field_changes.append(field) if previous_update and not ticket_change: updates.append((previous_update, field_changes, comment)) absurls = req.args.get('format') == 'rss' # Kludge for (t, id, author, type, summary), field_changes, comment in updates: if absurls: href = self.env.abs_href.ticket(id) else: href = self.env.href.ticket(id) title = util.Markup( 'Ticket <em title="%s">#%s</em> (%s) ' 'updated by %s', summary, id, type, author) message = util.Markup() if len(field_changes) > 0: message = util.Markup(', '.join(field_changes) + \ ' changed.<br />') message += wiki_to_oneliner(comment, self.env, db, shorten=True, absurls=absurls) yield 'editedticket', href, title, t, author, message
def get_types(self, req, cursor, order_by = 'id', desc = False): columns = ('id', 'name', 'description') sql = "SELECT id, name, description FROM download_type ORDER BY " + \ order_by + (" ASC", " DESC")[bool(desc)] self.log.debug(sql) cursor.execute(sql) types = [] for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) types.append(row) return types
def render_listtagged(self, req, *tags, **kwargs): """ List tagged objects. Takes a list of tags to match against. The special tag '.' inserts the current Wiki page name. Optional keyword arguments are tagspace=wiki, tagspaces=(wiki, title, ...) and showheadings=true. By default displays the intersection of objects matching each tag. By passing operation=union this can be modified to display the union of objects matching each tag. """ if 'tagspace' in kwargs: tagspaces = [kwargs.get('tagspace', None)] else: tagspaces = kwargs.get('tagspaces', '') or \ list(TagEngine(self.env).tagspaces) showheadings = kwargs.get('showheadings', 'false') operation = kwargs.get('operation', 'intersection') if operation not in ('union', 'intersection'): raise TracError("Invalid tag set operation '%s'" % operation) engine = TagEngine(self.env) page_name = req.hdf.get('wiki.page_name') if page_name: tags = [tag == '.' and page_name or tag for tag in tags] taginfo = {} out = StringIO() out.write('<ul class="listtagged">') for tagspace, tagspace_names in sorted(engine.get_tagged_names(tags=tags, tagspaces=tagspaces, operation=operation, detailed=True).iteritems()): if showheadings == 'true': out.write('<lh>%s tags</lh>' % tagspace) for name, tags in sorted(tagspace_names.iteritems()): if tagspace == 'wiki' and unicode(name).startswith('tags/'): continue tags = sorted(tags) taginfo = self._tag_details(taginfo, tags) href, link, title = engine.name_details(tagspace, name) htitle = wiki_to_oneliner(title, self.env) name_tags = ['<a href="%s" title="%s">%s</a>' % (taginfo[tag][0], taginfo[tag][1], tag) for tag in tags] if not name_tags: name_tags = '' else: name_tags = ' (' + ', '.join(sorted(name_tags)) + ')' out.write('<li>%s %s%s</li>\n' % (link, htitle, name_tags)) out.write('</ul>') return out.getvalue()
def get_timeline_events(self, req, start, stop, filters): if 'changeset' in filters: format = req.args.get('format') show_files = int( self.config.get('timeline', 'changeset_show_files')) db = self.env.get_db_cnx() repos = self.env.get_repository() authzperm = SubversionAuthorizer(self.env, req.authname) rev = repos.youngest_rev while rev: if not authzperm.has_permission_for_changeset(rev): rev = repos.previous_rev(rev) continue chgset = repos.get_changeset(rev) if chgset.date < start: return if chgset.date < stop: message = chgset.message or '--' if format == 'rss': title = util.Markup('Changeset <em>[%s]</em>: %s', chgset.rev, util.shorten_line(message)) href = self.env.abs_href.changeset(chgset.rev) message = wiki_to_html(message, self.env, req, db, absurls=True) else: title = util.Markup('Changeset <em>[%s]</em> by %s', chgset.rev, chgset.author) href = self.env.href.changeset(chgset.rev) message = wiki_to_oneliner(message, self.env, db, shorten=True) if show_files: files = [] for chg in chgset.get_changes(): if show_files > 0 and len(files) >= show_files: files.append('...') break files.append('<span class="%s">%s</span>' % (chg[2], util.escape(chg[0]))) message = '<span class="changes">' + ', '.join(files) +\ '</span>: ' + message yield 'changeset', href, title, chgset.date, chgset.author,\ util.Markup(message) rev = repos.previous_rev(rev)
def get_components(self, req, cursor): columns = ('name', 'description') sql = "SELECT name, description FROM component" self.log.debug(sql) cursor.execute(sql) components = [] id = 0 for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) id = id + 1 row['id'] = id components.append(row) return components
def attachment_to_hdf(env, db, req, attachment): from trac.wiki import wiki_to_oneliner if not db: db = env.get_db_cnx() hdf = { 'filename': attachment.filename, 'description': wiki_to_oneliner(attachment.description, env, db), 'author': util.escape(attachment.author), 'ipnr': attachment.ipnr, 'size': util.pretty_size(attachment.size), 'time': time.strftime('%c', time.localtime(attachment.time)), 'href': attachment.href() } return hdf
def get_groups(self, req, cursor, order_by = 'ORDER BY id ASC'): # Get count of forums without group sql = "SELECT COUNT(id) FROM forum WHERE forum_group = 0" self.log.debug(sql) cursor.execute(sql) no_group_forums = 0 for row in cursor: no_group_forums = row[0] groups = [{'id' : 0, 'name' : 'None', 'description' : 'No Group', 'forums' : no_group_forums}] # Get forum groups columns = ('id', 'name', 'description', 'forums') sql = "SELECT id, name, description, (SELECT COUNT(id) FROM forum f" \ " WHERE f.forum_group = forum_group.id) FROM forum_group " + order_by self.log.debug(sql) cursor.execute(sql) for row in cursor: row = dict(zip(columns, row)) row['name'] = wiki_to_oneliner(row['name'], self.env) row['description'] = wiki_to_oneliner(row['description'], self.env) groups.append(row) return groups
def get_changes(env, repos, revs, full=None, req=None, format=None): db = env.get_db_cnx() changes = {} for rev in revs: try: changeset = repos.get_changeset(rev) except NoSuchChangeset: changes[rev] = {} continue wiki_format = env.config['changeset'].getbool('wiki_format_messages') message = changeset.message or '--' absurls = (format == 'rss') if wiki_format: shortlog = wiki_to_oneliner(message, env, db, shorten=True, absurls=absurls) else: shortlog = Markup.escape(shorten_line(message)) if full: if wiki_format: message = wiki_to_html(message, env, req, db, absurls=absurls, escape_newlines=True) else: message = html.PRE(message) else: message = shortlog if format == 'rss': if isinstance(shortlog, Markup): shortlog = shortlog.plaintext(keeplinebreaks=False) message = unicode(message) changes[rev] = { 'date_seconds': changeset.date, 'date': format_datetime(changeset.date), 'age': pretty_timedelta(changeset.date), 'author': changeset.author or 'anonymous', 'message': message, 'shortlog': shortlog, } return changes
def get_components(self, cursor): columns = ('name', 'description') sql = "SELECT name, description FROM component" self.log.debug(sql) cursor.execute(sql) components = [] id = 0 for row in cursor: row = dict(zip(columns, row)) row['description'] = wiki_to_oneliner(row['description'], self.env) id = id + 1 row['id'] = id components.append(row) return components
def get_timeline_events(self, req, start, stop, filters): if 'codereview' in filters: crp = CodeReviewPool(self.env) for t, author, text, cr_id, status, version, message in crp.get_codereviews_by_time(start, stop): if status == str_status["NoNeedToReview"]: continue elif status == str_status["CompletelyReview"]: title = Markup('CodeReview : [ <em title="%s" >%s</em> ] completed by %s', message, cr_id, author) elif version == 1: title = Markup('CodeReview : [ <em title="%s" >%s</em> ] created by %s', message, cr_id, author) else: title = Markup('CodeReview : [ <em title="%s" >%s</em> ] edited by %s', message, cr_id, author) href = "%s/%s" % (self.env.href.CodeReview(), cr_id) text = wiki_to_oneliner(text, self.env, self.env.get_db_cnx(), shorten=True) yield 'codereview', href, title, t, author, text
def get_flat_messages(self, req, cursor, topic, time, order_by = 'ORDER BY time ASC'): columns = ('id', 'replyto', 'time', 'author', 'body') sql = "SELECT id, replyto, time, author, body FROM message WHERE" \ " topic = %s " + order_by self.log.debug(sql % (topic,)) cursor.execute(sql, (topic,)) messages = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req) if int(row['time']) > time: row['new'] = True row['time'] = format_datetime(row['time']) messages.append(row) return messages
def get_flat_messages(self, req, cursor, topic_id, time, order_by = 'ORDER BY time ASC'): columns = ('id', 'replyto', 'time', 'author', 'body') sql = "SELECT m.id, m.replyto, m.time, m.author, m.body FROM message m" \ " WHERE m.topic = %s " + order_by self.log.debug(sql % (topic_id,)) cursor.execute(sql, (topic_id,)) messages = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req, None, False, True) if int(row['time']) > time: row['new'] = True row['time'] = format_datetime(row['time']) messages.append(row) return messages
def render_listtags(self, req, *tags, **kwargs): """ List all tags. ||'''Argument'''||'''Description'''|| ||`tagspace=<tagspace>`||Specify the tagspace the macro should operate on.|| ||`tagspaces=(<tagspace>,...)`||Specify a set of tagspaces the macro should operate on.|| ||`shownames=true|false`||Whether to show the objects that tags appear on ''(long)''.|| """ if tags: # Backwards compatibility return self.render_listtagged(req, *tags, **kwargs) page = self._current_page(req) engine = TagEngine(self.env) showpages = kwargs.get('showpages', None) or kwargs.get( 'shownames', 'false') if 'tagspace' in kwargs: tagspaces = [kwargs['tagspace']] else: tagspaces = kwargs.get('tagspaces', []) or \ list(TagEngine(self.env).tagspaces) out = StringIO() out.write('<ul class="listtags">\n') tag_details = {} for tag, names in sorted( engine.get_tags(tagspaces=tagspaces, detailed=True).iteritems()): href, title = engine.get_tag_link(tag) htitle = wiki_to_oneliner(title, self.env, req=req) out.write( '<li><a href="%s" title="%s">%s</a> %s <span class="tagcount">(%i)</span>' % (href, title, tag, htitle, len(names))) if showpages == 'true': out.write('\n') out.write(self.render_listtagged(req, tag, tagspaces=tagspaces)) out.write('</li>\n') out.write('</ul>\n') return out.getvalue()
def get_timeline_events(self, req, start, stop, filters): if 'ticket_details' in filters: db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT tc.time,tc.ticket,t.type,tc.field, " " tc.oldvalue,tc.newvalue,tc.author,t.summary " "FROM ticket_change tc" " INNER JOIN ticket t ON t.id = tc.ticket " "AND tc.time>=%s AND tc.time<=%s ORDER BY tc.time" % (start, stop)) previous_update = None updates = [] ticket_change = False for time,id,type,field,oldvalue,newvalue,author,summary in cursor: if not previous_update or (time,id,author) != previous_update[:3]: if previous_update and not ticket_change: updates.append((previous_update,field_changes,comment)) ticket_change = False field_changes = [] comment = '' previous_update = (time,id,author,type,summary) if field == 'comment': comment = newvalue elif field == 'status' and newvalue in ['reopened', 'closed']: ticket_change = True else: field_changes.append(field) if previous_update and not ticket_change: updates.append((previous_update,field_changes,comment)) absurls = req.args.get('format') == 'rss' # Kludge for (t,id,author,type,summary),field_changes,comment in updates: if absurls: href = self.env.abs_href.ticket(id) else: href = self.env.href.ticket(id) title = util.Markup('Ticket <em title="%s">#%s</em> (%s) ' 'updated by %s', summary, id, type, author) message = util.Markup() if len(field_changes) > 0: message = util.Markup(', '.join(field_changes) + \ ' changed.<br />') message += wiki_to_oneliner(comment, self.env, db, shorten=True, absurls=absurls) yield 'editedticket', href, title, t, author, message
def get_timeline_events(self, req, start, stop, filters): if 'changeset' in filters: format = req.args.get('format') show_files = int(self.config.get('timeline', 'changeset_show_files')) db = self.env.get_db_cnx() repos = self.env.get_repository() authzperm = SubversionAuthorizer(self.env, req.authname) rev = repos.youngest_rev while rev: if not authzperm.has_permission_for_changeset(rev): rev = repos.previous_rev(rev) continue chgset = repos.get_changeset(rev) if chgset.date < start: return if chgset.date < stop: message = chgset.message or '--' if format == 'rss': title = util.Markup('Changeset <em>[%s]</em>: %s', chgset.rev, util.shorten_line(message)) href = self.env.abs_href.changeset(chgset.rev) message = wiki_to_html(message, self.env, req, db, absurls=True) else: title = util.Markup('Changeset <em>[%s]</em> by %s', chgset.rev, chgset.author) href = self.env.href.changeset(chgset.rev) message = wiki_to_oneliner(message, self.env, db, shorten=True) if show_files: files = [] for chg in chgset.get_changes(): if show_files > 0 and len(files) >= show_files: files.append('...') break files.append('<span class="%s">%s</span>' % (chg[2], util.escape(chg[0]))) message = '<span class="changes">' + ', '.join(files) +\ '</span>: ' + message yield 'changeset', href, title, chgset.date, chgset.author,\ util.Markup(message) rev = repos.previous_rev(rev)
def get_timeline_events(self, req, start, stop, filters): if 'milestone' in filters: format = req.args.get('format') db = self.env.get_db_cnx() cursor = db.cursor() cursor.execute("SELECT completed,name,description FROM milestone " "WHERE completed>=%s AND completed<=%s", (start, stop,)) for completed, name, description in cursor: title = Markup(u'Jalon <em>%s</em> completé', name) if format == 'rss': href = req.abs_href.milestone(name) message = wiki_to_html(description, self.env, req, db, absurls=True) else: href = req.href.milestone(name) message = wiki_to_oneliner(description, self.env, db, shorten=True) yield 'milestone', href, title, completed, None, message or '--'
def process_request(self, req, chrome, projects): folders = [] for project in projects: env = project["env"] if not req.authname: req.authname = "anonymous" try: repos = env.get_repository(req.authname) except TracError: continue try: change = repos.get_changeset(repos.get_youngest_rev()) folders.append({'name': project["name"], 'href': project["href"]+"/browser", 'rev': repos.get_youngest_rev(), 'age': util.pretty_timedelta(change.date), 'author': change.author, 'message': wiki_to_oneliner(change.message, env, env.get_db_cnx(), shorten=True, absurls=True, req=req)}) except Exception, e: pass
def _format_description(self, template, screenshot): description = template.replace('$id', to_unicode(screenshot['id'])) description = description.replace('$name', screenshot['name']) description = description.replace('$file', to_unicode(screenshot['file'])) description = description.replace('$time', format_datetime(screenshot['time'])) description = description.replace('$author', screenshot['author']) description = description.replace('$description', screenshot['description']) description = description.replace('$width', to_unicode(screenshot['width'])) description = description.replace('$height', to_unicode(screenshot['height'])) description = description.replace('$tags', to_unicode(screenshot['tags'])) description = description.replace('$components', ', '.join(screenshot['components'])) description = description.replace('$versions', ', '.join(screenshot['versions'])) return wiki_to_oneliner(description, self.env)
def get_topics(self, req, cursor, forum, order_by = 'ORDER BY time ASC'): columns = ('id', 'forum', 'time', 'subject', 'body', 'author', 'replies', 'lastreply') sql = "SELECT id, forum, time, subject, body, author, (SELECT" \ " COUNT(id) FROM message m WHERE m.topic = topic.id) AS replies," \ " (SELECT MAX(time) FROM message m WHERE m.topic = topic.id) AS" \ " lastreply FROM topic WHERE forum = %s " + order_by self.log.debug(sql % (forum,)) cursor.execute(sql, (forum,)) topics = [] for row in cursor: row = dict(zip(columns, row)) row['author'] = wiki_to_oneliner(row['author'], self.env) row['body'] = wiki_to_html(row['body'], self.env, req) if row['lastreply']: row['lastreply'] = pretty_timedelta(row['lastreply']) else: row['lastreply'] = 'No replies' row['time'] = format_datetime(row['time']) topics.append(row) return topics
def _format_description(self, template, screenshot): description = template.replace('$id', to_unicode(screenshot['id'])) description = description.replace('$name', screenshot['name']) description = description.replace('$file', to_unicode(screenshot['file'])) description = description.replace('$time', format_datetime( screenshot['time'])) description = description.replace('$author', screenshot['author']) description = description.replace('$description', screenshot['description']) description = description.replace('$width', to_unicode( screenshot['width'])) description = description.replace('$height', to_unicode( screenshot['height'])) description = description.replace('$tags', to_unicode( screenshot['tags'])) description = description.replace('$components', ', '.join(screenshot['components'])) description = description.replace('$versions', ', '.join(screenshot['versions'])) return wiki_to_oneliner(description, self.env)