Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(86)

Delta Between Two Patch Sets: MoinMoin/items/__init__.py

Issue 10761044: Add initial implementation of Comment itemtype.
Left Patch Set: Created 11 years, 9 months ago
Right Patch Set: Updates ModifyForm and templates. Created 11 years, 8 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
LEFTRIGHT
1 # Copyright: 2012-2013 MoinMoin:PavelSviderski
1 # Copyright: 2012 MoinMoin:CheerXiao 2 # Copyright: 2012 MoinMoin:CheerXiao
2 # Copyright: 2009 MoinMoin:ThomasWaldmann 3 # Copyright: 2009 MoinMoin:ThomasWaldmann
3 # Copyright: 2009-2011 MoinMoin:ReimarBauer 4 # Copyright: 2009-2011 MoinMoin:ReimarBauer
4 # Copyright: 2009 MoinMoin:ChristopherDenter 5 # Copyright: 2009 MoinMoin:ChristopherDenter
5 # Copyright: 2008,2009 MoinMoin:BastianBlank 6 # Copyright: 2008,2009 MoinMoin:BastianBlank
6 # Copyright: 2010 MoinMoin:ValentinJaniaut 7 # Copyright: 2010 MoinMoin:ValentinJaniaut
7 # Copyright: 2010 MoinMoin:DiogenesAugusto 8 # Copyright: 2010 MoinMoin:DiogenesAugusto
8 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details. 9 # License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
9 10
10 """ 11 """
11 MoinMoin - high-level (frontend) items 12 MoinMoin - high-level (frontend) items
12 13
13 While MoinMoin.storage cares for backend storage of items, 14 While MoinMoin.storage cares for backend storage of items,
14 this module cares for more high-level, frontend items, 15 this module cares for more high-level, frontend items,
15 e.g. showing, editing, etc. of wiki items. 16 e.g. showing, editing, etc. of wiki items.
16 17
17 Each class in this module corresponds to an itemtype. 18 Each class in this module corresponds to an itemtype.
18 """ 19 """
19 20
20 import json 21 import json
21 from StringIO import StringIO 22 from StringIO import StringIO
22 from collections import namedtuple 23 from collections import namedtuple
23 from operator import attrgetter 24 from operator import attrgetter
24 25
25 from flask import current_app as app 26 from flask import current_app as app
26 from flask import g as flaskg 27 from flask import g as flaskg
27 from flask import request, Response, redirect, abort, escape 28 from flask import request, Response, redirect, abort, escape
28 29
29 from flatland import Form 30 from flatland import Form, Unset
30 31
31 from jinja2 import Markup 32 from jinja2 import Markup
32 33
33 from whoosh.query import Term, Prefix, And, Or, Not 34 from whoosh.query import Term, Prefix, And, Or, Not
34 35
35 from MoinMoin import log 36 from MoinMoin import log
36 logging = log.getLogger(__name__) 37 logging = log.getLogger(__name__)
37 38
38 from MoinMoin.security.textcha import TextCha, TextChaizedForm 39 from MoinMoin.security.textcha import TextCha, TextChaizedForm
39 from MoinMoin.signalling import item_modified 40 from MoinMoin.signalling import item_modified
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 389
389 def destroy(self, comment=u'', destroy_item=False): 390 def destroy(self, comment=u'', destroy_item=False):
390 # called from destroy UI/POST 391 # called from destroy UI/POST
391 if destroy_item: 392 if destroy_item:
392 # destroy complete item with all revisions, metadata, etc. 393 # destroy complete item with all revisions, metadata, etc.
393 self.rev.item.destroy_all_revisions() 394 self.rev.item.destroy_all_revisions()
394 else: 395 else:
395 # just destroy this revision 396 # just destroy this revision
396 self.rev.item.destroy_revision(self.rev.revid) 397 self.rev.item.destroy_revision(self.rev.revid)
397 398
398 def modify(self, meta, data, comment=u'', contenttype_guessed=None, contentt ype_qs=None): 399 def modify(self, meta, data, comment=u'', contenttype_guessed=None, **update _meta):
399 if contenttype_qs: 400 meta = dict(meta) # we may get a read-only dict-like, copy it
400 # we use querystring param to FORCE content type 401 # get rid of None values
401 meta[CONTENTTYPE] = contenttype_qs 402 update_meta = {key:value for key, value in update_meta.items() if value is not None}
Thomas.J.Waldmann 2013/07/29 22:48:59 key: value pep8
402 403 meta.update(update_meta)
403 return self._save(meta, data, contenttype_guessed=contenttype_guessed, c omment=comment) 404 return self._save(meta, data, contenttype_guessed=contenttype_guessed, c omment=comment)
404 405
405 class _ModifyForm(BaseModifyForm): 406 class _ModifyForm(BaseModifyForm):
406 """ 407 """
407 ModifyForm (the form used on +modify view), sans the content part. 408 ModifyForm (the form used on +modify view), sans the content part.
408 Combined dynamically with the ModifyForm of the Content subclass in 409 Combined dynamically with the ModifyForm of the Content subclass in
409 Contentful.ModifyForm. 410 Contentful.ModifyForm.
410 411
411 Subclasses of Contentful should generally override this instead of 412 Subclasses of Contentful should generally override this instead of
412 ModifyForm. 413 ModifyForm.
(...skipping 22 matching lines...) Expand all
435 """ 436 """
436 Dump useful data out of :self. :item contains the old item and 437 Dump useful data out of :self. :item contains the old item and
437 should not be the primary data source; but it can be useful in case 438 should not be the primary data source; but it can be useful in case
438 the data in :self is not sufficient. 439 the data in :self is not sufficient.
439 440
440 :returns: a tuple (meta, data, contenttype_guessed, comment), 441 :returns: a tuple (meta, data, contenttype_guessed, comment),
441 suitable as arguments of the same names to pass to 442 suitable as arguments of the same names to pass to
442 item.modify 443 item.modify
443 """ 444 """
444 meta = self['meta_form'].value.copy() 445 meta = self['meta_form'].value.copy()
445 meta.update(item.meta_text_to_dict(self['extra_meta_text'].value)) 446 if self['extra_meta_text'].raw is not Unset: # it's an optional fie ld
447 meta.update(item.meta_text_to_dict(self['extra_meta_text'].value ))
446 data, contenttype_guessed = self['content_form']._dump(item.content) 448 data, contenttype_guessed = self['content_form']._dump(item.content)
447 comment = self['comment'].value 449 comment = self['comment'].value
448 return meta, data, contenttype_guessed, comment 450 return meta, data, contenttype_guessed, comment
449 451
450 def do_modify(self): 452 def do_modify(self):
451 """ 453 """
452 Handle +modify requests, both GET and POST. 454 Handle +modify requests, both GET and POST.
453 455
454 This method should be overridden in subclasses, providing polymorphic 456 This method should be overridden in subclasses, providing polymorphic
455 behavior for the +modify view. 457 behavior for the +modify view.
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 itemtype=self.itemtype, 676 itemtype=self.itemtype,
675 rev=self.rev, 677 rev=self.rev,
676 contenttype=self.contenttype, 678 contenttype=self.contenttype,
677 templates=item_templates, 679 templates=item_templates,
678 first_rev_id=rev_ids and rev_ids[0], 680 first_rev_id=rev_ids and rev_ids[0],
679 last_rev_id=rev_ids and rev_ids[-1], 681 last_rev_id=rev_ids and rev_ids[-1],
680 meta_rendered='', 682 meta_rendered='',
681 data_rendered='', 683 data_rendered='',
682 ) 684 )
683 685
684 def get_comment_items(self): 686 def get_comment_item_ids(self):
685 terms = [Term(WIKINAME, app.cfg.interwikiname), 687 terms = [Term(WIKINAME, app.cfg.interwikiname),
686 # Only comment items 688 # Only comment items
687 Term(ITEMTYPE, ITEMTYPE_COMMENT), 689 Term(ITEMTYPE, ITEMTYPE_COMMENT),
688 # Only comments for this item 690 # Only comments for this item
689 Term(COMMENT_FOR, self.meta[ITEMID]), 691 Term(COMMENT_FOR, self.meta[ITEMID]),
690 ] 692 ]
691 query = And(terms) 693 query = And(terms)
692 revs = flaskg.storage.search(query, sortedby=PTIME, limit=None) 694 revs = flaskg.storage.search(query, sortedby=PTIME, limit=None)
693 comment_items = [Item.create(rev.name) for rev in revs] 695 comment_item_ids = [rev.item.itemid for rev in revs]
Thomas.J.Waldmann 2013/06/28 22:45:30 as a general hint: be careful with creating potent
694 return comment_items 696 return comment_item_ids
695 697
696 def do_show(self, revid): 698 def do_show(self, revid):
697 show_revision = revid != CURRENT 699 show_revision = revid != CURRENT
698 show_navigation = False # TODO 700 show_navigation = False # TODO
699 first_rev = last_rev = None # TODO 701 first_rev = last_rev = None # TODO
700 comments=self.get_comment_items() 702 # TODO: comments should be a list of ITEMIDs, but currently we use a lis t
703 # of ITEMNAMEs because we are not able to create an Item object by ITEMI D yet.
704 # TODO: filter out protected comments
705 comments = [flaskg.storage.document(itemid=itemid).name
706 for itemid in self.get_comment_item_ids()]
701 return render_template(self.show_template, 707 return render_template(self.show_template,
702 item=self, item_name=self.name, 708 item=self, item_name=self.name,
703 rev=self.rev, 709 rev=self.rev,
704 contenttype=self.contenttype, 710 contenttype=self.contenttype,
705 first_rev_id=first_rev, 711 first_rev_id=first_rev,
706 last_rev_id=last_rev, 712 last_rev_id=last_rev,
707 data_rendered=Markup(self.content._render_data()) , 713 data_rendered=Markup(self.content._render_data()) ,
708 show_revision=show_revision, 714 show_revision=show_revision,
709 show_navigation=show_navigation, 715 show_navigation=show_navigation,
710 comments=comments, 716 comments=comments,
Thomas.J.Waldmann 2013/06/28 22:45:30 maybe this could be more dynamic later, so that co
711 ) 717 )
712 718
713 def do_modify(self): 719 def do_modify(self):
714 method = request.method 720 method = request.method
715 if method in ['GET', 'HEAD']: 721 if method in ['GET', 'HEAD']:
716 if isinstance(self.content, NonExistentContent): 722 if isinstance(self.content, NonExistentContent):
717 return render_template('modify_select_contenttype.html', 723 return render_template('modify_select_contenttype.html',
718 item_name=self.name, 724 item_name=self.name,
719 itemtype=self.itemtype, 725 itemtype=self.itemtype,
720 group_names=content_registry.group_names, 726 group_names=content_registry.group_names,
(...skipping 17 matching lines...) Expand all
738 else: 744 else:
739 # *Draw Applets POSTs more than once, redirecting would 745 # *Draw Applets POSTs more than once, redirecting would
740 # break them 746 # break them
741 return "OK" 747 return "OK"
742 form = self.ModifyForm.from_request(request) 748 form = self.ModifyForm.from_request(request)
743 state = dict(name=self.name, itemid=self.meta.get(ITEMID)) 749 state = dict(name=self.name, itemid=self.meta.get(ITEMID))
744 if form.validate(state): 750 if form.validate(state):
745 meta, data, contenttype_guessed, comment = form._dump(self) 751 meta, data, contenttype_guessed, comment = form._dump(self)
746 contenttype_qs = request.values.get('contenttype') 752 contenttype_qs = request.values.get('contenttype')
747 try: 753 try:
748 self.modify(meta, data, comment, contenttype_guessed, conten ttype_qs) 754 self.modify(meta, data, comment, contenttype_guessed, **{CON TENTTYPE: contenttype_qs})
749 except AccessDenied: 755 except AccessDenied:
750 abort(403) 756 abort(403)
751 else: 757 else:
752 return redirect(url_for_item(self.name)) 758 return redirect(url_for_item(self.name))
753 return render_template(self.modify_template, 759 return render_template(self.modify_template,
754 item_name=self.name, 760 item_name=self.name,
755 rows_meta=str(ROWS_META), cols=str(COLS), 761 rows_meta=str(ROWS_META), cols=str(COLS),
756 form=form, 762 form=form,
757 search_form=None, 763 search_form=None,
758 ) 764 )
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 # pointless for non-existing items 824 # pointless for non-existing items
819 pass 825 pass
820 826
821 def destroy(self, comment=u'', destroy_item=False): 827 def destroy(self, comment=u'', destroy_item=False):
822 # pointless for non-existing items 828 # pointless for non-existing items
823 pass 829 pass
824 830
825 831
826 from ..util.pysupport import load_package_modules 832 from ..util.pysupport import load_package_modules
827 load_package_modules(__name__, __path__) 833 load_package_modules(__name__, __path__)
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b