Ticket #1198: trac-timeline-author-1198.patch
| File trac-timeline-author-1198.patch, 16.1 KB (added by davidf@…, 6 months ago) |
|---|
-
trac/attachment.py
451 451 time = datetime.fromtimestamp(ts, utc) 452 452 yield ('created', realm, id, filename, time, description, author) 453 453 454 def get_timeline_events(self, req, resource_realm, start, stop ):454 def get_timeline_events(self, req, resource_realm, start, stop, filters): 455 455 """Return an event generator suitable for ITimelineEventProvider. 456 This is called from the parent resource, it doesn't directly implement 457 ITimelineEventProvider. 456 458 457 459 Events are changes to attachments on resources of the given 458 460 `resource_realm.realm`. 459 461 """ 462 if filters.get('author', ''): 463 filter_author = lambda author: author == filters['author'] 464 else: 465 filter_author = lambda author: True 460 466 for change, realm, id, filename, time, descr, author in \ 461 467 self.get_history(start, stop, resource_realm.realm): 462 468 attachment = resource_realm(id=id).child('attachment', filename) 463 469 if 'ATTACHMENT_VIEW' in req.perm(attachment): 470 if not filter_author(author): 471 continue 464 472 yield ('attachment', time, author, (attachment, descr), self) 465 473 466 474 def render_timeline_event(self, context, field, event): -
trac/ticket/web_ui.py
199 199 200 200 def get_timeline_filters(self, req): 201 201 if 'TICKET_VIEW' in req.perm: 202 yield ('ticket', _('Ticket changes')) 202 yield ('ticket', ITimelineEventProvider.CHECKBOX, _('Ticket changes'), True) 203 yield ('author', ITimelineEventProvider.STRING, _('Author'), '') 203 204 if self.timeline_details: 204 yield ('ticket_details', _('Ticket details'), False)205 yield ('ticket_details', ITimelineEventProvider.CHECKBOX, _('Ticket details'), False) 205 206 206 207 def get_timeline_events(self, req, start, stop, filters): 207 208 ts_start = to_timestamp(start) … … 213 214 'edit': ('editedticket', 'updated')} 214 215 215 216 ticket_realm = Resource('ticket') 217 if filters.get('author', ''): 218 filter_author = lambda author: author == filters['author'] 219 else: 220 filter_author = lambda author: True 216 221 217 222 def produce_event((id, ts, author, type, summary, description), 218 223 status, fields, comment, cid): … … 221 226 return None 222 227 resolution = fields.get('resolution') 223 228 info = '' 229 if not filter_author(author): 230 return None 224 231 if status == 'edit': 225 232 if 'ticket_details' in filters: 226 233 if len(fields) > 0: … … 290 297 # Attachments 291 298 if 'ticket_details' in filters: 292 299 for event in AttachmentModule(self.env).get_timeline_events( 293 req, ticket_realm, start, stop ):300 req, ticket_realm, start, stop, filters): 294 301 yield event 295 302 296 303 def render_timeline_event(self, context, field, event): -
trac/ticket/roadmap.py
501 501 502 502 def get_timeline_filters(self, req): 503 503 if 'MILESTONE_VIEW' in req.perm: 504 yield ('milestone', _('Milestones'))504 yield ('milestone', ITimelineEventProvider.CHECKBOX, _('Milestones'), True) 505 505 506 506 def get_timeline_events(self, req, start, stop, filters): 507 507 if 'milestone' in filters: … … 520 520 521 521 # Attachments 522 522 for event in AttachmentModule(self.env).get_timeline_events( 523 req, milestone_realm, start, stop ):523 req, milestone_realm, start, stop, filters): 524 524 yield event 525 525 526 526 def render_timeline_event(self, context, field, event): -
trac/versioncontrol/web_ui/changeset.py
764 764 765 765 def get_timeline_filters(self, req): 766 766 if 'CHANGESET_VIEW' in req.perm: 767 yield ('changeset', _('Repository checkins')) 767 yield ('changeset', ITimelineEventProvider.CHECKBOX, _('Repository checkins'), True) 768 yield ('author', ITimelineEventProvider.STRING, _('Author'), '') 768 769 769 770 def get_timeline_events(self, req, start, stop, filters): 771 if filters.get('author', ''): 772 filter_author = lambda author: author == filters['author'] 773 else: 774 filter_author = lambda author: True 770 775 if 'changeset' in filters: 771 776 show_files = self.timeline_show_files 772 777 show_location = show_files == 'location' … … 792 797 permitted_changesets.append(chgset) 793 798 if permitted_changesets: 794 799 chgset = permitted_changesets[-1] 800 if not filter_author(chgset.author): 801 continue 795 802 yield ('changeset', chgset.date, chgset.author, 796 803 (permitted_changesets, chgset.message or '', 797 804 show_location, show_files)) -
trac/admin/console.py
107 107 except TracError, e: 108 108 print>>sys.stderr, 'Command failed: %s' % e 109 109 rv = 2 110 raise 110 111 if not self.interactive: 111 112 return rv 112 113 -
trac/wiki/web_ui.py
549 549 550 550 def get_timeline_filters(self, req): 551 551 if 'WIKI_VIEW' in req.perm: 552 yield ('wiki', _('Wiki changes')) 552 yield ('wiki', ITimelineEventProvider.CHECKBOX, _('Wiki changes'), True) 553 yield ('author', ITimelineEventProvider.STRING, _('Author'), '') 553 554 554 555 def get_timeline_events(self, req, start, stop, filters): 555 556 db = self.env.get_db_cnx() 557 if filters.get('author', ''): 558 filter_author = lambda author: author == filters['author'] 559 else: 560 filter_author = lambda author: True 556 561 if 'wiki' in filters: 557 562 wiki_realm = Resource('wiki') 558 563 cursor = db.cursor() … … 563 568 wiki_page = wiki_realm(id=name, version=version) 564 569 if 'WIKI_VIEW' not in req.perm(wiki_page): 565 570 continue 571 if not filter_author(author): 572 continue 566 573 yield ('wiki', datetime.fromtimestamp(ts, utc), author, 567 574 (wiki_page, comment)) 568 575 569 576 # Attachments 570 577 for event in AttachmentModule(self.env).get_timeline_events( 571 req, wiki_realm, start, stop ):578 req, wiki_realm, start, stop, filters): 572 579 yield event 573 580 574 581 def render_timeline_event(self, context, field, event): -
trac/timeline/api.py
30 30 timeline. 31 31 """ 32 32 33 CHECKBOX = 'checkbox' 34 STRING = 'string' 35 33 36 def get_timeline_filters(req): 34 37 """Return a list of filters that this event provider supports. 35 38 36 Each filter must be a (name, label) tuple, where `name` is the internal 37 name, and `label` is a human-readable name for display. 38 39 Optionally, the tuple can contain a third element, `checked`. 40 If `checked` is omitted or True, the filter is active by default, 41 otherwise it will be inactive. 39 Each filter must be a (name, type, label, default) tuple, where 40 `name` is the internal name, 41 `label` is a human-readable name for display, 42 `type` is either CHECKBOX or STRING 43 `default` is the default option for this filter 42 44 """ 43 45 44 46 def get_timeline_events(req, start, stop, filters): 45 47 """Return a list of events in the time range given by the `start` and 46 48 `stop` parameters. 47 49 48 The `filters` parameters is a list of the enabled filters, each item 49 being the name of the tuples returned by `get_timeline_filters`. 50 The `filters` parameters is a dictionary of the enabled filters, each 51 key being the name of the tuples returned by `get_timeline_filters`, 52 and each value being either `True` for a `CHECKBOX` filter or the string 53 passed to a `STRING` filter. `False` `CHECKBOX` filters are not included. 50 54 51 55 Since 0.11, the events are `(kind, date, author, data)` tuples, 52 56 where `kind` is a string used for categorizing the event, `date` -
trac/timeline/web_ui.py
128 128 129 129 available_filters = [] 130 130 for event_provider in self.event_providers: 131 available_filters += event_provider.get_timeline_filters(req) 131 for timeline_filter in event_provider.get_timeline_filters(req): 132 # support for previous timeline filter format (Deprecated) 133 if len(timeline_filter) == 2: 134 timeline_filter = (timeline_filter[0], ITimelineEventProvider.CHECKBOX, 135 timeline_filter[1], True) 136 elif len(timeline_filter) == 3: 137 timeline_filter = (timeline_filter[0], ITimelineEventProvider.CHECKBOX, 138 timeline_filter[1], timeline_filter[2]) 139 available_filters.append(timeline_filter) 132 140 133 filters = []141 filters = {} 134 142 # check the request or session for enabled filters, or use default 135 for test in (lambda f: f[0] in req.args, 136 lambda f: req.session.get('timeline.filter.%s' % f[0], 137 '') == '1', 138 lambda f: len(f) == 2 or f[2]): 139 if filters: 140 break 141 filters = [f[0] for f in available_filters if test(f)] 143 for f in available_filters: 144 filter_name = f[0] 145 if filter_name in filters: 146 continue 147 if f[1] == ITimelineEventProvider.CHECKBOX: 148 if filter_name in req.args: 149 filters[filter_name] = True 150 elif req.session.get('timeline.filter.%s' % filter_name, '') == '1': 151 filters[filter_name] = True 152 elif f[3]: 153 filters[filter_name] = True 154 elif f[1] == ITimelineEventProvider.STRING: 155 if filter_name in req.args: 156 filters[filter_name] = req.args[filter_name] 157 elif req.session.get('timeline.filter.%s' % filter_name, None) is not None: 158 filters[filter_name] = req.session.get('timeline.filter.%s' % filter_name) 159 else: 160 filters[filter_name] = f[3] 142 161 143 162 # save the results of submitting the timeline form to the session 144 163 if 'update' in req.args: 145 164 for filter in available_filters: 146 165 key = 'timeline.filter.%s' % filter[0] 147 166 if filter[0] in req.args: 148 req.session[key] = '1' 167 if filter[1] == ITimelineEventProvider.CHECKBOX: 168 req.session[key] = '1' 169 elif filter[1] == ITimelineEventProvider.STRING: 170 req.session[key] = req.args[filter[0]] 149 171 elif key in req.session: 150 172 del req.session[key] 151 173 … … 190 212 add_link(req, 'alternate', rss_href, _('RSS Feed'), 191 213 'application/rss+xml', 'rss') 192 214 215 filter_options_check = {} 193 216 for filter_ in available_filters: 194 data['filters'].append({'name': filter_[0], 'label': filter_[1], 195 'enabled': filter_[0] in filters}) 196 217 if filter_[0] in filter_options_check: 218 continue 219 if filter_[1] == ITimelineEventProvider.CHECKBOX: 220 filter_options_check[filter_[0]] = True 221 data['filters'].append({'name': filter_[0], 'filter_type': filter_[1], 222 'label': filter_[2], 223 'enabled': filters.get(filter_[0], False)}) 224 elif filter_[1] == ITimelineEventProvider.STRING: 225 filter_options_check[filter_[0]] = True 226 data['filters'].append({'name': filter_[0], 'filter_type': filter_[1], 227 'label': filter_[2], 'enabled': True, 228 'value': filters.get(filter_[0], filter_[3])}) 197 229 # Navigation to the previous/next period of 'daysback' days 198 230 previous_start = format_date(fromdate - timedelta(days=daysback+1), 199 231 format='%Y-%m-%d', tzinfo=req.tz) … … 305 337 self.log.exception('Timeline event provider %s failed', ep_name) 306 338 307 339 guilty_filters = [f[0] for f in ep.get_timeline_filters(req)] 308 guilty_ kinds = [f[1] for f in ep.get_timeline_filters(req)]340 guilty_labels = [f[2] for f in ep.get_timeline_filters(req)] 309 341 other_filters = [f for f in current_filters if not f in guilty_filters] 310 342 if not other_filters: 311 343 other_filters = [f for f in all_filters if not f in guilty_filters] … … 313 345 'daysback')] 314 346 href = req.href.timeline(args+[(f, 'on') for f in other_filters]) 315 347 raise TracError(tag( 316 tag.p(', '.join(guilty_ kinds),348 tag.p(', '.join(guilty_labels), 317 349 ' event provider (', tag.tt(ep_name), ') failed:', tag.br(), 318 350 exc_name, ': ', to_unicode(exc), class_='message'), 319 351 tag.p('You may want to see the other kind of events from the ', -
trac/timeline/templates/timeline.html
21 21 and <label><input type="text" size="3" name="daysback" value="$daysback" /> days back</label>. 22 22 </div> 23 23 <fieldset> 24 <label py:for="filter in filters" >24 <label py:for="filter in filters" py:if="filter.filter_type == 'checkbox'"> 25 25 <input type="checkbox" name="${filter.name}" 26 26 checked="${filter.enabled or None}"/> ${filter.label} 27 27 </label> 28 <label py:for="filter in filters" py:if="filter.filter_type == 'string'"> 29 ${filter.label} 30 <input type="text" name="${filter.name}" value="${filter.value}"/> 31 </label> 28 32 </fieldset> 29 33 <div class="buttons"> 30 34 <input type="submit" name="update" value="Update" /> -
contrib/workflow/graph-workflows
1 #!/bin/bash 2 for f in *.ini ../../trac/ticket/workflows/*.ini 3 do 4 echo $f 5 dot=`basename "$f" .ini`.dot 6 python workflow_parser.py $f | grep -v rotate > $dot 7 dot $dot -Tpng -O 8 done 9
