OLD | NEW |
1 # Copyright: 2012 MoinMoin:CheerXiao | 1 # Copyright: 2012 MoinMoin:CheerXiao |
2 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details. | 2 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details. |
3 | 3 |
4 """ | 4 """ |
5 MoinMoin - Ticket itemtype | 5 MoinMoin - Ticket itemtype |
6 """ | 6 """ |
7 | 7 |
8 | 8 |
9 from __future__ import absolute_import, division | 9 from __future__ import absolute_import, division |
10 | 10 |
11 import time | 11 import time |
12 | 12 |
13 from flask import request, abort, redirect, url_for | 13 from flask import request, abort, redirect, url_for |
14 from flask import g as flaskg | 14 from flask import g as flaskg |
| 15 from flask import current_app as app |
15 | 16 |
16 from jinja2 import Markup | 17 from jinja2 import Markup |
17 | 18 |
18 from whoosh.query import Term | 19 from whoosh.query import Term, Prefix |
19 | 20 |
20 from MoinMoin.i18n import L_ | 21 from MoinMoin.i18n import L_ |
21 from MoinMoin.themes import render_template | 22 from MoinMoin.themes import render_template |
22 from MoinMoin.forms import (Form, OptionalText, OptionalMultilineText, SmallNatu
ral, Tags, | 23 from MoinMoin.forms import (Form, OptionalText, OptionalMultilineText, SmallNatu
ral, Tags, |
23 Reference, BackReference, SelectSubmit) | 24 Reference, BackReference, SelectSubmit) |
24 from MoinMoin.storage.middleware.protecting import AccessDenied | 25 from MoinMoin.storage.middleware.protecting import AccessDenied |
25 from MoinMoin.constants.keys import ITEMTYPE, CONTENTTYPE, ITEMID, CURRENT, SUPE
RSEDED_BY, DEPENDS_ON, SUBSCRIBED_ITEMS | 26 from MoinMoin.constants.keys import ITEMTYPE, CONTENTTYPE, ITEMID, CURRENT, SUPE
RSEDED_BY, DEPENDS_ON, SUBSCRIBED_ITEMS, WIKINAME, NAME, NAME_EXACT |
26 from MoinMoin.constants.contenttypes import CONTENTTYPE_USER | 27 from MoinMoin.constants.contenttypes import CONTENTTYPE_USER |
27 from MoinMoin.items import Item, Contentful, register, BaseModifyForm | 28 from MoinMoin.items import Item, Contentful, register, BaseModifyForm, Default,
IndexEntry |
28 from MoinMoin.items.content import NonExistentContent | 29 from MoinMoin.items.content import NonExistentContent |
| 30 from MoinMoin.display_field import DisplayField |
| 31 from MoinMoin.constants.display_widgets import DISPLAY_PLAIN, DISPLAY_TAGS, DISP
LAY_REFERENCE |
29 | 32 |
30 | 33 |
31 ITEMTYPE_TICKET = u'ticket' | 34 ITEMTYPE_TICKET = u'ticket' |
32 | 35 |
33 USER_QUERY = Term(CONTENTTYPE, CONTENTTYPE_USER) | 36 USER_QUERY = Term(CONTENTTYPE, CONTENTTYPE_USER) |
34 TICKET_QUERY = Term(ITEMTYPE, ITEMTYPE_TICKET) | 37 TICKET_QUERY = Term(ITEMTYPE, ITEMTYPE_TICKET) |
35 | 38 |
36 Rating = SmallNatural.using(optional=True).with_properties(lower=1, upper=5) | 39 Rating = SmallNatural.using(optional=True).with_properties(lower=1, upper=5) |
37 OptionalTicketReference = Reference.to(TICKET_QUERY).using(optional=True) | 40 OptionalTicketReference = Reference.to(TICKET_QUERY).using(optional=True) |
38 OptionalUserReference = Reference.to(USER_QUERY).using(optional=True).with_prope
rties(empty_label='(Nobody)') | 41 OptionalUserReference = Reference.to(USER_QUERY).using(optional=True).with_prope
rties(empty_label='(Nobody)') |
39 | 42 |
40 | 43 |
41 class TicketMetaForm(Form): | 44 class TicketMetaForm(Form): |
42 summary = OptionalText.using(label=L_("Summary")).with_properties(placeholde
r=L_("One-line summary of the item")) | 45 summary = OptionalText.using(label=L_("Summary")).with_properties(placeholde
r=L_("One-line summary of the item")) |
43 effort = Rating.using(label=L_("Effort")) | 46 effort = Rating.using(label=L_("Effort")) |
44 difficulty = Rating.using(label=L_("Difficulty")) | 47 difficulty = Rating.using(label=L_("Difficulty")) |
45 severity = Rating.using(label=L_("Severity")) | 48 severity = Rating.using(label=L_("Severity")) |
46 priority = Rating.using(label=L_("Priority")) | 49 priority = Rating.using(label=L_("Priority")) |
47 tags = Tags.using(optional=True) | 50 tags = Tags.using(optional=True) |
48 assigned_to = OptionalUserReference.using(label=L_("Assigned To")) | 51 assigned_to = OptionalUserReference.using(label=L_("Assigned To")) |
49 superseded_by = OptionalTicketReference.using(label=L_("Superseded By")) | 52 superseded_by = OptionalTicketReference.using(label=L_("Superseded By")) |
50 depends_on = OptionalTicketReference.using(label=L_("Depends On")) | 53 depends_on = OptionalTicketReference.using(label=L_("Depends On")) |
51 | 54 |
52 | 55 |
| 56 display_fields = [ |
| 57 DisplayField('summary', label=L_('Summary'), widget=DISPLAY_PLAIN), |
| 58 DisplayField('effort', label=L_('Effort'), widget=DISPLAY_PLAIN), |
| 59 DisplayField('difficulty', label=L_('Difficulty'), widget=DISPLAY_PLAIN), |
| 60 DisplayField('severity', label=L_('Severity'), widget=DISPLAY_PLAIN), |
| 61 DisplayField('priority', label=L_('Priority'), widget=DISPLAY_PLAIN), |
| 62 DisplayField('tags', label=L_('Tags'), widget=DISPLAY_TAGS), |
| 63 DisplayField('assigned_to', label=L_('Assigned To'), widget=DISPLAY_REFERENC
E), |
| 64 DisplayField('superseded_by', label=L_('Superseded By'), widget=DISPLAY_REFE
RENCE), |
| 65 DisplayField('depends_on', label=L_('Depends On'), widget=DISPLAY_REFERENCE)
, |
| 66 ] |
| 67 |
| 68 |
53 class TicketBackRefForm(Form): | 69 class TicketBackRefForm(Form): |
54 supersedes = BackReference.using(label=L_("Supersedes")) | 70 supersedes = BackReference.using(label=L_("Supersedes")) |
55 required_by = BackReference.using(label=L_("Required By")) | 71 required_by = BackReference.using(label=L_("Required By")) |
56 subscribers = BackReference.using(label=L_("Subscribers")) | 72 subscribers = BackReference.using(label=L_("Subscribers")) |
57 | 73 |
58 def _load(self, item): | 74 def _load(self, item): |
59 id_ = item.meta[ITEMID] | 75 id_ = item.meta[ITEMID] |
60 self['supersedes'].set(Term(SUPERSEDED_BY, id_)) | 76 self['supersedes'].set(Term(SUPERSEDED_BY, id_)) |
61 self['required_by'].set(Term(DEPENDS_ON, id_)) | 77 self['required_by'].set(Term(DEPENDS_ON, id_)) |
62 self['subscribers'].set(Term(SUBSCRIBED_ITEMS, id_)) | 78 self['subscribers'].set(Term(SUBSCRIBED_ITEMS, id_)) |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 # XXX When creating new item, suppress the "foo doesn't exist. Create it
?" dummy content | 186 # XXX When creating new item, suppress the "foo doesn't exist. Create it
?" dummy content |
171 data_rendered = None if is_new else Markup(self.content._render_data()) | 187 data_rendered = None if is_new else Markup(self.content._render_data()) |
172 | 188 |
173 return render_template(self.submit_template if is_new else self.modify_t
emplate, | 189 return render_template(self.submit_template if is_new else self.modify_t
emplate, |
174 is_new=is_new, | 190 is_new=is_new, |
175 closed=closed, | 191 closed=closed, |
176 item_name=self.name, | 192 item_name=self.name, |
177 data_rendered=data_rendered, | 193 data_rendered=data_rendered, |
178 form=form, | 194 form=form, |
179 ) | 195 ) |
| 196 |
| 197 |
| 198 ITEMTYPE_TICKET_INDEX = u'ticketindex' |
| 199 |
| 200 |
| 201 @register |
| 202 class TicketIndex(Default): |
| 203 itemtype = ITEMTYPE_TICKET_INDEX |
| 204 display_name = L_('Ticket Index') |
| 205 description = L_('An index for all tickets under it') |
| 206 show_template = 'ticket/index.html' |
| 207 |
| 208 def do_show(self, revid): |
| 209 prefix = self.subitems_prefix |
| 210 prefixlen = len(prefix) |
| 211 query = (Term(WIKINAME, app.cfg.interwikiname) & |
| 212 Term(ITEMTYPE, ITEMTYPE_TICKET) & |
| 213 Prefix(NAME_EXACT, prefix)) |
| 214 revs = flaskg.storage.search(query, limit=None) |
| 215 tickets = [] |
| 216 for rev in revs: |
| 217 fullname = rev.meta[NAME][0] |
| 218 relname = fullname[prefixlen:] |
| 219 tickets.append(IndexEntry(relname, fullname, rev.meta)) |
| 220 return render_template(self.show_template, |
| 221 item_name=self.name, |
| 222 data_rendered=Markup(self.content._render_data())
, |
| 223 fields=display_fields, |
| 224 tickets=tickets |
| 225 ) |
OLD | NEW |