OLD | NEW |
1 # Copyright: 2012 MoinMoin:CheerXiao | 1 # Copyright: 2012 MoinMoin:CheerXiao |
2 # Copyright: 2009 MoinMoin:ThomasWaldmann | 2 # Copyright: 2009 MoinMoin:ThomasWaldmann |
3 # Copyright: 2009-2011 MoinMoin:ReimarBauer | 3 # Copyright: 2009-2011 MoinMoin:ReimarBauer |
4 # Copyright: 2009 MoinMoin:ChristopherDenter | 4 # Copyright: 2009 MoinMoin:ChristopherDenter |
5 # Copyright: 2008,2009 MoinMoin:BastianBlank | 5 # Copyright: 2008,2009 MoinMoin:BastianBlank |
6 # Copyright: 2010 MoinMoin:ValentinJaniaut | 6 # Copyright: 2010 MoinMoin:ValentinJaniaut |
7 # Copyright: 2010 MoinMoin:DiogenesAugusto | 7 # Copyright: 2010 MoinMoin:DiogenesAugusto |
8 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details. | 8 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details. |
9 | 9 |
10 """ | 10 """ |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 from MoinMoin import log | 35 from MoinMoin import log |
36 logging = log.getLogger(__name__) | 36 logging = log.getLogger(__name__) |
37 | 37 |
38 from MoinMoin.security.textcha import TextCha, TextChaizedForm | 38 from MoinMoin.security.textcha import TextCha, TextChaizedForm |
39 from MoinMoin.signalling import item_modified | 39 from MoinMoin.signalling import item_modified |
40 from MoinMoin.storage.middleware.protecting import AccessDenied | 40 from MoinMoin.storage.middleware.protecting import AccessDenied |
41 from MoinMoin.i18n import L_ | 41 from MoinMoin.i18n import L_ |
42 from MoinMoin.themes import render_template | 42 from MoinMoin.themes import render_template |
43 from MoinMoin.util.mime import Type | 43 from MoinMoin.util.mime import Type |
44 from MoinMoin.util.interwiki import url_for_item | 44 from MoinMoin.util.interwiki import url_for_item, split_fqname, get_fqname |
45 from MoinMoin.util.registry import RegistryBase | 45 from MoinMoin.util.registry import RegistryBase |
46 from MoinMoin.util.clock import timed | 46 from MoinMoin.util.clock import timed |
47 from MoinMoin.forms import RequiredText, OptionalText, JSON, Tags | 47 from MoinMoin.forms import RequiredText, OptionalText, JSON, Tags |
48 from MoinMoin.constants.keys import ( | 48 from MoinMoin.constants.keys import ( |
49 NAME, NAME_OLD, NAME_EXACT, WIKINAME, MTIME, ITEMTYPE, | 49 NAME, NAME_OLD, NAME_EXACT, WIKINAME, MTIME, ITEMTYPE, |
50 CONTENTTYPE, SIZE, ACTION, ADDRESS, HOSTNAME, USERID, COMMENT, | 50 CONTENTTYPE, SIZE, ACTION, ADDRESS, HOSTNAME, USERID, COMMENT, |
51 HASH_ALGORITHM, ITEMID, REVID, DATAID, CURRENT, PARENTID | 51 HASH_ALGORITHM, ITEMID, REVID, DATAID, CURRENT, PARENTID, NAMESPACE, |
| 52 UFIELDS_TYPELIST |
52 ) | 53 ) |
53 from MoinMoin.constants.contenttypes import CHARSET, CONTENTTYPE_NONEXISTENT | 54 from MoinMoin.constants.contenttypes import CHARSET, CONTENTTYPE_NONEXISTENT |
54 from MoinMoin.constants.itemtypes import ( | 55 from MoinMoin.constants.itemtypes import ( |
55 ITEMTYPE_NONEXISTENT, ITEMTYPE_USERPROFILE, ITEMTYPE_DEFAULT, | 56 ITEMTYPE_NONEXISTENT, ITEMTYPE_USERPROFILE, ITEMTYPE_DEFAULT, |
56 ) | 57 ) |
57 | 58 |
58 from .content import content_registry, Content, NonExistentContent, Draw | 59 from .content import content_registry, Content, NonExistentContent, Draw |
59 | 60 |
60 | 61 |
61 COLS = 80 | 62 COLS = 80 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 """ if we have no stored Revision, we use this dummy """ | 103 """ if we have no stored Revision, we use this dummy """ |
103 def __init__(self, item, itemtype=None, contenttype=None): | 104 def __init__(self, item, itemtype=None, contenttype=None): |
104 self.item = item | 105 self.item = item |
105 self.meta = { | 106 self.meta = { |
106 ITEMTYPE: itemtype or ITEMTYPE_NONEXISTENT, | 107 ITEMTYPE: itemtype or ITEMTYPE_NONEXISTENT, |
107 CONTENTTYPE: contenttype or CONTENTTYPE_NONEXISTENT | 108 CONTENTTYPE: contenttype or CONTENTTYPE_NONEXISTENT |
108 } | 109 } |
109 self.data = StringIO('') | 110 self.data = StringIO('') |
110 self.revid = None | 111 self.revid = None |
111 if self.item: | 112 if self.item: |
112 self.meta[NAME] = [self.item.name] | 113 self.meta[NAMESPACE] = item.fqname.namespace |
| 114 if item.fqname.field in UFIELDS_TYPELIST: |
| 115 self.meta[item.fqname.field] = [item.fqname.value] |
| 116 else: |
| 117 self.meta[item.fqname.field] = item.fqname.value |
113 | 118 |
114 | 119 |
115 class DummyItem(object): | 120 class DummyItem(object): |
116 """ if we have no stored Item, we use this dummy """ | 121 """ if we have no stored Item, we use this dummy """ |
117 def __init__(self, name): | 122 def __init__(self, fqname): |
118 self.name = name | 123 self.fqname = fqname |
119 | 124 |
120 def list_revisions(self): | 125 def list_revisions(self): |
121 return [] # same as an empty Item | 126 return [] # same as an empty Item |
122 | 127 |
123 def destroy_all_revisions(self): | 128 def destroy_all_revisions(self): |
124 return True | 129 return True |
125 | 130 |
126 | 131 |
127 def get_storage_revision(name, itemtype=None, contenttype=None, rev_id=CURRENT,
item=None): | 132 def get_storage_revision(fqname, itemtype=None, contenttype=None, rev_id=CURRENT
, item=None): |
128 """ | 133 """ |
129 Get a storage Revision. | 134 Get a storage Revision. |
130 | 135 |
131 If :item is supplied it is used as the storage Item; otherwise the storage | 136 If :item is supplied it is used as the storage Item; otherwise the storage |
132 Item is looked up with :name. If it is not found (either because the item | 137 Item is looked up with :name. If it is not found (either because the item |
133 doesn't exist or the user does not have the required permissions) a | 138 doesn't exist or the user does not have the required permissions) a |
134 DummyItem is created, and a DummyRev is created with appropriate metadata | 139 DummyItem is created, and a DummyRev is created with appropriate metadata |
135 properties and the "item" property pointing to the DummyItem. The DummyRev | 140 properties and the "item" property pointing to the DummyItem. The DummyRev |
136 is then returned. | 141 is then returned. |
137 | 142 |
138 If the previous step didn't end up with a DummyRev, the revision | 143 If the previous step didn't end up with a DummyRev, the revision |
139 designated by :rev_id is then looked up. If it is not found, current | 144 designated by :rev_id is then looked up. If it is not found, current |
140 revision is looked up and returned instead. If current revision is not | 145 revision is looked up and returned instead. If current revision is not |
141 found (i.e. the item has no revision), a DummyRev is created. (TODO: in | 146 found (i.e. the item has no revision), a DummyRev is created. (TODO: in |
142 the last two cases, emit warnings or throw exceptions.) | 147 the last two cases, emit warnings or throw exceptions.) |
143 | 148 |
144 :itemtype and :contenttype are used when creating a DummyRev, where | 149 :itemtype and :contenttype are used when creating a DummyRev, where |
145 metadata is not available from the storage. | 150 metadata is not available from the storage. |
146 """ | 151 """ |
| 152 query = {fqname.field: fqname.value, NAMESPACE: fqname.namespace} |
| 153 rev_id = fqname.value if fqname.field == REVID else rev_id |
147 if 1: # try: | 154 if 1: # try: |
148 if item is None: | 155 if item is None: |
149 item = flaskg.storage[name] | 156 item = flaskg.storage.get_item(**query) |
150 else: | 157 else: |
151 name = item.name | 158 if item.fqname: |
| 159 fqname = item.fqname |
152 if not item: # except NoSuchItemError: | 160 if not item: # except NoSuchItemError: |
153 logging.debug("No such item: {0!r}".format(name)) | 161 logging.debug("No such item: {0!r}".format(fqname)) |
154 item = DummyItem(name) | 162 item = DummyItem(fqname) |
155 rev = DummyRev(item, itemtype, contenttype) | 163 rev = DummyRev(item, itemtype, contenttype) |
156 logging.debug("Item {0!r}, created dummy revision with contenttype {1!r}
".format(name, contenttype)) | 164 logging.debug("Item {0!r}, created dummy revision with contenttype {1!r}
".format(fqname, contenttype)) |
157 else: | 165 else: |
158 logging.debug("Got item: {0!r}".format(name)) | 166 logging.debug("Got item: {0!r}".format(fqname)) |
159 try: | 167 try: |
160 rev = item.get_revision(rev_id) | 168 rev = item.get_revision(rev_id) |
161 except KeyError: # NoSuchRevisionError: | 169 except KeyError: # NoSuchRevisionError: |
162 try: | 170 try: |
163 rev = item.get_revision(CURRENT) # fall back to current revisio
n | 171 rev = item.get_revision(CURRENT) # fall back to current revisio
n |
164 # XXX add some message about invalid revision | 172 # XXX add some message about invalid revision |
165 except KeyError: # NoSuchRevisionError: | 173 except KeyError: # NoSuchRevisionError: |
166 logging.debug("Item {0!r} has no revisions.".format(name)) | 174 logging.debug("Item {0!r} has no revisions.".format(fqname)) |
167 rev = DummyRev(item, itemtype, contenttype) | 175 rev = DummyRev(item, itemtype, contenttype) |
168 logging.debug("Item {0!r}, created dummy revision with contentty
pe {1!r}".format(name, contenttype)) | 176 logging.debug("Item {0!r}, created dummy revision with contentty
pe {1!r}".format(fqname, contenttype)) |
169 logging.debug("Got item {0!r}, revision: {1!r}".format(name, rev_id)) | 177 logging.debug("Got item {0!r}, revision: {1!r}".format(fqname, rev_id)) |
170 return rev | 178 return rev |
171 | 179 |
172 | 180 |
173 class BaseChangeForm(TextChaizedForm): | 181 class BaseChangeForm(TextChaizedForm): |
174 comment = OptionalText.using(label=L_('Comment')).with_properties(placeholde
r=L_("Comment about your change")) | 182 comment = OptionalText.using(label=L_('Comment')).with_properties(placeholde
r=L_("Comment about your change")) |
175 submit_label = L_('OK') | 183 submit_label = L_('OK') |
176 | 184 |
177 | 185 |
178 class BaseMetaForm(Form): | 186 class BaseMetaForm(Form): |
179 itemtype = RequiredText.using(label=L_("Item type")).with_properties(placeho
lder=L_("Item type")) | 187 itemtype = RequiredText.using(label=L_("Item type")).with_properties(placeho
lder=L_("Item type")) |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 only when handling +convert (when deciding the contenttype of target | 276 only when handling +convert (when deciding the contenttype of target |
269 item), +modify (when creating a new item whose contenttype is not yet | 277 item), +modify (when creating a new item whose contenttype is not yet |
270 decided), +diff and +diffraw (to coerce the Content to a common | 278 decided), +diff and +diffraw (to coerce the Content to a common |
271 super-contenttype of both revisions). | 279 super-contenttype of both revisions). |
272 | 280 |
273 After that the Content instance, an instance of Item subclass is | 281 After that the Content instance, an instance of Item subclass is |
274 created according to the item's itemtype metadata entry, and the | 282 created according to the item's itemtype metadata entry, and the |
275 previously created Content instance is assigned to its content | 283 previously created Content instance is assigned to its content |
276 property. | 284 property. |
277 """ | 285 """ |
278 rev = get_storage_revision(name, itemtype, contenttype, rev_id, item) | 286 fqname = split_fqname(name) |
| 287 rev = get_storage_revision(fqname, itemtype, contenttype, rev_id, item) |
279 contenttype = rev.meta.get(CONTENTTYPE) or contenttype | 288 contenttype = rev.meta.get(CONTENTTYPE) or contenttype |
280 logging.debug("Item {0!r}, got contenttype {1!r} from revision meta".for
mat(name, contenttype)) | 289 logging.debug("Item {0!r}, got contenttype {1!r} from revision meta".for
mat(name, contenttype)) |
281 #logging.debug("Item %r, rev meta dict: %r" % (name, dict(rev.meta))) | 290 #logging.debug("Item %r, rev meta dict: %r" % (name, dict(rev.meta))) |
282 | 291 |
283 # XXX Cannot pass item=item to Content.__init__ via | 292 # XXX Cannot pass item=item to Content.__init__ via |
284 # content_registry.get yet, have to patch it later. | 293 # content_registry.get yet, have to patch it later. |
285 content = Content.create(contenttype) | 294 content = Content.create(contenttype) |
286 | 295 |
287 itemtype = rev.meta.get(ITEMTYPE) or itemtype or ITEMTYPE_DEFAULT | 296 itemtype = rev.meta.get(ITEMTYPE) or itemtype or ITEMTYPE_DEFAULT |
288 logging.debug("Item {0!r}, got itemtype {1!r} from revision meta".format
(name, itemtype)) | 297 logging.debug("Item {0!r}, got itemtype {1!r} from revision meta".format
(name, itemtype)) |
289 | 298 |
290 item = item_registry.get(itemtype, name, rev=rev, content=content) | 299 item = item_registry.get(itemtype, fqname, rev=rev, content=content) |
291 logging.debug("Item class {0!r} handles {1!r}".format(item.__class__, it
emtype)) | 300 logging.debug("Item class {0!r} handles {1!r}".format(item.__class__, it
emtype)) |
292 | 301 |
293 content.item = item | 302 content.item = item |
294 | |
295 return item | 303 return item |
296 | 304 |
297 def __init__(self, name, rev=None, content=None): | 305 def __init__(self, fqname, rev=None, content=None): |
298 self.name = name | 306 self.fqname = fqname |
299 self.rev = rev | 307 self.rev = rev |
300 self.content = content | 308 self.content = content |
301 | 309 |
302 def get_meta(self): | 310 def get_meta(self): |
303 return self.rev.meta | 311 return self.rev.meta |
304 meta = property(fget=get_meta) | 312 meta = property(fget=get_meta) |
305 | 313 |
| 314 @property |
| 315 def name(self): |
| 316 """ |
| 317 returns the item name |
| 318 """ |
| 319 if self.fqname.field == NAME_EXACT: |
| 320 return self.fqname.value |
| 321 else: |
| 322 return self.meta.get(NAME)[0] |
| 323 |
306 # XXX Backward compatibility, remove soon | 324 # XXX Backward compatibility, remove soon |
307 @property | 325 @property |
308 def contenttype(self): | 326 def contenttype(self): |
309 return self.content.contenttype if self.content else None | 327 return self.content.contenttype if self.content else None |
310 | 328 |
311 def _render_meta(self): | 329 def _render_meta(self): |
312 return "<pre>{0}</pre>".format(escape(self.meta_dict_to_text(self.meta,
use_filter=False))) | 330 return "<pre>{0}</pre>".format(escape(self.meta_dict_to_text(self.meta,
use_filter=False))) |
313 | 331 |
314 def meta_filter(self, meta): | 332 def meta_filter(self, meta): |
315 """ kill metadata entries that we set automatically when saving """ | 333 """ kill metadata entries that we set automatically when saving """ |
316 kill_keys = [ # shall not get copied from old rev to new rev | 334 kill_keys = [ # shall not get copied from old rev to new rev |
317 NAME_OLD, | 335 NAME_OLD, |
318 # are automatically implanted when saving | 336 # are automatically implanted when saving |
319 ITEMID, REVID, DATAID, | 337 REVID, DATAID, |
320 HASH_ALGORITHM, | 338 HASH_ALGORITHM, |
321 SIZE, | 339 SIZE, |
322 COMMENT, | 340 COMMENT, |
323 MTIME, | 341 MTIME, |
324 ACTION, | 342 ACTION, |
325 ADDRESS, HOSTNAME, USERID, | 343 ADDRESS, HOSTNAME, USERID, |
326 ] | 344 ] |
327 for key in kill_keys: | 345 for key in kill_keys: |
328 meta.pop(key, None) | 346 meta.pop(key, None) |
329 return meta | 347 return meta |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 Handle +modify requests, both GET and POST. | 469 Handle +modify requests, both GET and POST. |
452 | 470 |
453 This method should be overridden in subclasses, providing polymorphic | 471 This method should be overridden in subclasses, providing polymorphic |
454 behavior for the +modify view. | 472 behavior for the +modify view. |
455 """ | 473 """ |
456 raise NotImplementedError | 474 raise NotImplementedError |
457 | 475 |
458 def _save(self, meta, data=None, name=None, action=u'SAVE', contenttype_gues
sed=None, comment=None, | 476 def _save(self, meta, data=None, name=None, action=u'SAVE', contenttype_gues
sed=None, comment=None, |
459 overwrite=False, delete=False): | 477 overwrite=False, delete=False): |
460 backend = flaskg.storage | 478 backend = flaskg.storage |
461 storage_item = backend[self.name] | 479 query = {self.fqname.field: self.fqname.value, NAMESPACE: self.fqname.na
mespace} |
| 480 storage_item = backend.get_item(**query) |
462 try: | 481 try: |
463 currentrev = storage_item.get_revision(CURRENT) | 482 currentrev = storage_item.get_revision(CURRENT) |
464 rev_id = currentrev.revid | 483 rev_id = currentrev.revid |
465 contenttype_current = currentrev.meta.get(CONTENTTYPE) | 484 contenttype_current = currentrev.meta.get(CONTENTTYPE) |
466 except KeyError: # XXX was: NoSuchRevisionError: | 485 except KeyError: # XXX was: NoSuchRevisionError: |
467 currentrev = None | 486 currentrev = None |
468 rev_id = None | 487 rev_id = None |
469 contenttype_current = None | 488 contenttype_current = None |
470 | 489 |
471 meta = dict(meta) # we may get a read-only dict-like, copy it | 490 meta = dict(meta) # we may get a read-only dict-like, copy it |
472 | |
473 # we store the previous (if different) and current item name into revisi
on metadata | 491 # we store the previous (if different) and current item name into revisi
on metadata |
474 # this is useful for rename history and backends that use item uids inte
rnally | 492 # this is useful for rename history and backends that use item uids inte
rnally |
475 if name is None: | 493 if self.fqname.field == NAME_EXACT: |
476 name = self.name | 494 if name is None: |
477 oldname = meta.get(NAME) | 495 name = self.fqname.value |
478 if oldname: | 496 oldname = meta.get(NAME) |
479 if not isinstance(oldname, list): | 497 if oldname: |
480 oldname = [oldname] | 498 if not isinstance(oldname, list): |
481 if delete or name not in oldname: # this is a delete or rename | 499 oldname = [oldname] |
482 meta[NAME_OLD] = oldname[:] | 500 if delete or name not in oldname: # this is a delete or rename |
483 try: | 501 meta[NAME_OLD] = oldname[:] |
484 oldname.remove(self.name) | 502 try: |
485 except ValueError: | 503 oldname.remove(self.name) |
486 pass | 504 except ValueError: |
487 if not delete: | 505 pass |
488 oldname.append(name) | 506 if not delete: |
489 meta[NAME] = oldname | 507 oldname.append(name) |
490 else: | 508 meta[NAME] = oldname |
491 meta[NAME] = [name] | 509 else: |
| 510 meta[NAME] = [name] |
492 | 511 |
493 if comment is not None: | 512 if comment is not None: |
494 meta[COMMENT] = unicode(comment) | 513 meta[COMMENT] = unicode(comment) |
495 | 514 |
496 if not overwrite and REVID in meta: | 515 if not overwrite and REVID in meta: |
497 # we usually want to create a new revision, thus we must remove the
existing REVID | 516 # we usually want to create a new revision, thus we must remove the
existing REVID |
498 del meta[REVID] | 517 del meta[REVID] |
499 | 518 |
500 if data is None: | 519 if data is None: |
501 if currentrev is not None: | 520 if currentrev is not None: |
502 # we don't have (new) data, just copy the old one. | 521 # we don't have (new) data, just copy the old one. |
503 # a valid usecase of this is to just edit metadata. | 522 # a valid usecase of this is to just edit metadata. |
504 data = currentrev.data | 523 data = currentrev.data |
505 else: | 524 else: |
506 data = '' | 525 data = '' |
507 | 526 |
508 if isinstance(data, unicode): | 527 if isinstance(data, unicode): |
509 data = data.encode(CHARSET) # XXX wrong! if contenttype gives a cod
ing, we MUST use THAT. | 528 data = data.encode(CHARSET) # XXX wrong! if contenttype gives a cod
ing, we MUST use THAT. |
510 | 529 |
511 if isinstance(data, str): | 530 if isinstance(data, str): |
512 data = StringIO(data) | 531 data = StringIO(data) |
513 | |
514 newrev = storage_item.store_revision(meta, data, overwrite=overwrite, | 532 newrev = storage_item.store_revision(meta, data, overwrite=overwrite, |
515 action=unicode(action), | 533 action=unicode(action), |
516 contenttype_current=contenttype_cur
rent, | 534 contenttype_current=contenttype_cur
rent, |
517 contenttype_guessed=contenttype_gue
ssed, | 535 contenttype_guessed=contenttype_gue
ssed, |
518 return_rev=True, | 536 return_rev=True, |
519 ) | 537 ) |
520 item_modified.send(app._get_current_object(), item_name=name) | 538 item_modified.send(app._get_current_object(), item_name=name) |
521 return newrev.revid, newrev.meta[SIZE] | 539 return newrev.revid, newrev.meta[SIZE] |
522 | 540 |
523 @property | 541 @property |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 relname = fullname[prefixlen:] | 587 relname = fullname[prefixlen:] |
570 if '/' in relname: | 588 if '/' in relname: |
571 # Find the *direct* subitem that is the ancestor of curr
ent | 589 # Find the *direct* subitem that is the ancestor of curr
ent |
572 # (indirect) subitem. e.g. suppose when the index root i
s | 590 # (indirect) subitem. e.g. suppose when the index root i
s |
573 # 'foo', and current item (`rev`) is 'foo/bar/lorem/ipsu
m', | 591 # 'foo', and current item (`rev`) is 'foo/bar/lorem/ipsu
m', |
574 # 'foo/bar' will be found. | 592 # 'foo/bar' will be found. |
575 direct_relname = relname.partition('/')[0] | 593 direct_relname = relname.partition('/')[0] |
576 if direct_relname not in added_dir_relnames: | 594 if direct_relname not in added_dir_relnames: |
577 added_dir_relnames.add(direct_relname) | 595 added_dir_relnames.add(direct_relname) |
578 direct_fullname = prefix + direct_relname | 596 direct_fullname = prefix + direct_relname |
579 direct_rev = get_storage_revision(direct_fullname) | 597 fqname = split_fqname(direct_fullname) |
| 598 direct_rev = get_storage_revision(fqname) |
580 dirs.append(IndexEntry(direct_relname, direct_fullna
me, direct_rev.meta)) | 599 dirs.append(IndexEntry(direct_relname, direct_fullna
me, direct_rev.meta)) |
581 else: | 600 else: |
582 files.append(IndexEntry(relname, fullname, rev.meta)) | 601 files.append(IndexEntry(relname, fullname, rev.meta)) |
583 | 602 |
584 return dirs, files | 603 return dirs, files |
585 | 604 |
586 def build_index_query(self, startswith=None, selected_groups=None): | 605 def build_index_query(self, startswith=None, selected_groups=None): |
587 prefix = self.subitems_prefix | 606 prefix = self.subitems_prefix |
588 if startswith: | 607 if startswith: |
589 query = Prefix(NAME_EXACT, prefix + startswith) | Prefix(NAME_EXACT,
prefix + startswith.swapcase()) | 608 query = Prefix(NAME_EXACT, prefix + startswith) | Prefix(NAME_EXACT,
prefix + startswith.swapcase()) |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 itemtype = ITEMTYPE_DEFAULT | 681 itemtype = ITEMTYPE_DEFAULT |
663 display_name = L_('Default') | 682 display_name = L_('Default') |
664 description = L_('Wiki item') | 683 description = L_('Wiki item') |
665 order = -10 | 684 order = -10 |
666 | 685 |
667 def _do_modify_show_templates(self): | 686 def _do_modify_show_templates(self): |
668 # call this if the item is still empty | 687 # call this if the item is still empty |
669 rev_ids = [] | 688 rev_ids = [] |
670 item_templates = self.content.get_templates(self.contenttype) | 689 item_templates = self.content.get_templates(self.contenttype) |
671 return render_template('modify_select_template.html', | 690 return render_template('modify_select_template.html', |
672 item_name=self.name, | 691 item_name=self.fqname.fullname, |
673 itemtype=self.itemtype, | 692 itemtype=self.itemtype, |
674 rev=self.rev, | 693 rev=self.rev, |
675 contenttype=self.contenttype, | 694 contenttype=self.contenttype, |
676 templates=item_templates, | 695 templates=item_templates, |
677 first_rev_id=rev_ids and rev_ids[0], | 696 first_rev_id=rev_ids and rev_ids[0], |
678 last_rev_id=rev_ids and rev_ids[-1], | 697 last_rev_id=rev_ids and rev_ids[-1], |
679 meta_rendered='', | 698 meta_rendered='', |
680 data_rendered='', | 699 data_rendered='', |
681 ) | 700 ) |
682 | 701 |
683 def do_show(self, revid): | 702 def do_show(self, revid): |
684 show_revision = revid != CURRENT | 703 show_revision = revid != CURRENT |
685 show_navigation = False # TODO | 704 show_navigation = False # TODO |
686 first_rev = last_rev = None # TODO | 705 first_rev = last_rev = None # TODO |
687 return render_template(self.show_template, | 706 return render_template(self.show_template, |
688 item=self, item_name=self.name, | 707 item=self, item_name=self.fqname.fullname, |
689 rev=self.rev, | 708 rev=self.rev, |
690 contenttype=self.contenttype, | 709 contenttype=self.contenttype, |
691 first_rev_id=first_rev, | 710 first_rev_id=first_rev, |
692 last_rev_id=last_rev, | 711 last_rev_id=last_rev, |
693 data_rendered=Markup(self.content._render_data())
, | 712 data_rendered=Markup(self.content._render_data())
, |
694 show_revision=show_revision, | 713 show_revision=show_revision, |
695 show_navigation=show_navigation, | 714 show_navigation=show_navigation, |
696 ) | 715 ) |
697 | 716 |
698 def do_modify(self): | 717 def do_modify(self): |
699 method = request.method | 718 method = request.method |
700 if method in ['GET', 'HEAD']: | 719 if method in ['GET', 'HEAD']: |
701 if isinstance(self.content, NonExistentContent): | 720 if isinstance(self.content, NonExistentContent): |
702 return render_template('modify_select_contenttype.html', | 721 return render_template('modify_select_contenttype.html', |
703 item_name=self.name, | 722 item_name=self.fqname.fullname, |
704 itemtype=self.itemtype, | 723 itemtype=self.itemtype, |
705 group_names=content_registry.group_names, | 724 group_names=content_registry.group_names, |
706 groups=content_registry.groups, | 725 groups=content_registry.groups, |
707 ) | 726 ) |
708 item = self | 727 item = self |
709 if isinstance(self.rev, DummyRev): | 728 if isinstance(self.rev, DummyRev): |
710 template_name = request.values.get('template') | 729 template_name = request.values.get('template') |
711 if template_name is None: | 730 if template_name is None: |
712 return self._do_modify_show_templates() | 731 return self._do_modify_show_templates() |
713 elif template_name: | 732 elif template_name: |
(...skipping 13 matching lines...) Expand all Loading... |
727 form = self.ModifyForm.from_request(request) | 746 form = self.ModifyForm.from_request(request) |
728 state = dict(name=self.name, itemid=self.meta.get(ITEMID)) | 747 state = dict(name=self.name, itemid=self.meta.get(ITEMID)) |
729 if form.validate(state): | 748 if form.validate(state): |
730 meta, data, contenttype_guessed, comment = form._dump(self) | 749 meta, data, contenttype_guessed, comment = form._dump(self) |
731 contenttype_qs = request.values.get('contenttype') | 750 contenttype_qs = request.values.get('contenttype') |
732 try: | 751 try: |
733 self.modify(meta, data, comment, contenttype_guessed, conten
ttype_qs) | 752 self.modify(meta, data, comment, contenttype_guessed, conten
ttype_qs) |
734 except AccessDenied: | 753 except AccessDenied: |
735 abort(403) | 754 abort(403) |
736 else: | 755 else: |
737 return redirect(url_for_item(self.name)) | 756 return redirect(url_for_item(**self.fqname.split)) |
738 return render_template(self.modify_template, | 757 return render_template(self.modify_template, |
739 item_name=self.name, | 758 item_name=self.fqname.fullname, |
740 rows_meta=str(ROWS_META), cols=str(COLS), | 759 rows_meta=str(ROWS_META), cols=str(COLS), |
741 form=form, | 760 form=form, |
742 search_form=None, | 761 search_form=None, |
743 ) | 762 ) |
744 | 763 |
745 show_template = 'show.html' | 764 show_template = 'show.html' |
746 modify_template = 'modify.html' | 765 modify_template = 'modify.html' |
747 | 766 |
748 | 767 |
749 @register | 768 @register |
(...skipping 18 matching lines...) Expand all Loading... |
768 | 787 |
769 def _convert(self, doc): | 788 def _convert(self, doc): |
770 abort(404) | 789 abort(404) |
771 | 790 |
772 def do_show(self, revid): | 791 def do_show(self, revid): |
773 # First, check if the current user has the required privileges | 792 # First, check if the current user has the required privileges |
774 if flaskg.user.may.create(self.name): | 793 if flaskg.user.may.create(self.name): |
775 content = self._select_itemtype() | 794 content = self._select_itemtype() |
776 else: | 795 else: |
777 content = render_template('show_nonexistent.html', | 796 content = render_template('show_nonexistent.html', |
778 item_name=self.name, | 797 item_name=self.fqname.fullname, |
779 ) | 798 ) |
780 return Response(content, 404) | 799 return Response(content, 404) |
781 | 800 |
782 def do_modify(self): | 801 def do_modify(self): |
783 # First, check if the current user has the required privileges | 802 # First, check if the current user has the required privileges |
784 if not flaskg.user.may.create(self.name): | 803 if not flaskg.user.may.create(self.name): |
785 abort(403) | 804 abort(403) |
786 return self._select_itemtype() | 805 return self._select_itemtype() |
787 | 806 |
788 def _select_itemtype(self): | 807 def _select_itemtype(self): |
789 return render_template('modify_select_itemtype.html', | 808 return render_template('modify_select_itemtype.html', |
790 item_name=self.name, | 809 item_name=self.fqname.fullname, |
791 itemtypes=item_registry.shown_entries, | 810 itemtypes=item_registry.shown_entries, |
792 ) | 811 ) |
793 | 812 |
794 def rename(self, name, comment=u''): | 813 def rename(self, name, comment=u''): |
795 # pointless for non-existing items | 814 # pointless for non-existing items |
796 pass | 815 pass |
797 | 816 |
798 def delete(self, comment=u''): | 817 def delete(self, comment=u''): |
799 # pointless for non-existing items | 818 # pointless for non-existing items |
800 pass | 819 pass |
801 | 820 |
802 def revert(self, comment=u''): | 821 def revert(self, comment=u''): |
803 # pointless for non-existing items | 822 # pointless for non-existing items |
804 pass | 823 pass |
805 | 824 |
806 def destroy(self, comment=u'', destroy_item=False): | 825 def destroy(self, comment=u'', destroy_item=False): |
807 # pointless for non-existing items | 826 # pointless for non-existing items |
808 pass | 827 pass |
809 | 828 |
810 | 829 |
811 from ..util.pysupport import load_package_modules | 830 from ..util.pysupport import load_package_modules |
812 load_package_modules(__name__, __path__) | 831 load_package_modules(__name__, __path__) |
OLD | NEW |