1.1 --- a/MoinMoin/forms.py Wed Aug 15 23:35:06 2012 +0200
1.2 +++ b/MoinMoin/forms.py Thu Aug 16 10:25:22 2012 +0200
1.3 @@ -136,7 +136,7 @@
1.4 dt = utctimestamp(dt)
1.5 return dt
1.6
1.7 -DateTime = (DateTimeUNIX.with_properties(widget=WIDGET_DATETIME, placeholder=_("YYYY-MM-DD HH:MM:SS (example: 2999-12-31 23:59:59)"))
1.8 +DateTime = (DateTimeUNIX.with_properties(widget=WIDGET_DATETIME, placeholder=_("YYYY-MM-DD HH:MM:SS (example: 2013-12-31 23:59:59)"))
1.9 .validated_by(Converted(incorrect=L_("Please use the following format: YYYY-MM-DD HH:MM:SS"))))
1.10
1.11 File = FileStorage.with_properties(widget=WIDGET_FILE)
2.1 --- a/MoinMoin/items/__init__.py Wed Aug 15 23:35:06 2012 +0200
2.2 +++ b/MoinMoin/items/__init__.py Thu Aug 16 10:25:22 2012 +0200
2.3 @@ -23,16 +23,15 @@
2.4 from StringIO import StringIO
2.5 from collections import namedtuple
2.6 from functools import partial
2.7 -from datetime import datetime
2.8
2.9 from flatland import Form
2.10 from flatland.validation import Validator
2.11
2.12 from jinja2 import Markup
2.13
2.14 -from whoosh.query import Term, And, Prefix, DateRange
2.15 +from whoosh.query import Term, And, Prefix
2.16
2.17 -from MoinMoin.forms import RequiredText, OptionalText, JSON, Tags, DateTime, Submit
2.18 +from MoinMoin.forms import RequiredText, OptionalText, JSON, Tags, Submit
2.19
2.20 from MoinMoin.security.textcha import TextCha, TextChaizedForm
2.21 from MoinMoin.signalling import item_modified
2.22 @@ -55,7 +54,7 @@
2.23 from MoinMoin.storage.error import NoSuchItemError, NoSuchRevisionError, StorageError
2.24 from MoinMoin.util.registry import RegistryBase
2.25 from MoinMoin.constants.keys import (
2.26 - NAME, NAME_OLD, NAME_EXACT, WIKINAME, MTIME, PTIME, SYSITEM_VERSION, ITEMTYPE,
2.27 + NAME, NAME_OLD, NAME_EXACT, WIKINAME, MTIME, SYSITEM_VERSION, ITEMTYPE,
2.28 CONTENTTYPE, SIZE, TAGS, ACTION, ADDRESS, HOSTNAME, USERID, COMMENT,
2.29 HASH_ALGORITHM, ITEMID, REVID, DATAID, CURRENT, PARENTID
2.30 )
2.31 @@ -685,76 +684,5 @@
2.32 )
2.33
2.34
2.35 -# TODO: move into a separate items/blog.py module
2.36 -class BlogMetaForm(BaseMetaForm):
2.37 - supertags = (Tags.using(label=L_('Supertags (Categories)'))
2.38 - .with_properties(placeholder=L_("Ordered comma separated list of tags")))
2.39 -
2.40 -class BlogEntryMetaForm(BaseMetaForm):
2.41 - summary = (OptionalText.using(label=L_("Title"))
2.42 - .with_properties(placeholder=L_("One-line title of the blog entry")))
2.43 - ptime = DateTime.using(label=L_('Publication time (UTC)'), optional=True)
2.44 -
2.45 -@register
2.46 -class Blog(Default):
2.47 - itemtype = u'blog'
2.48 -
2.49 - class _ModifyForm(Default._ModifyForm):
2.50 - meta_form = BlogMetaForm
2.51 - meta_template = 'modify_blog_meta.html'
2.52 -
2.53 - def do_show(self, revid):
2.54 - """
2.55 - Show a blog item and a list of its blog entries below it.
2.56 -
2.57 - If tag GET-parameter is defined, the list of blog entries consists only
2.58 - of those entries that contain the tag value in their lists of tags.
2.59 - """
2.60 - # for now it is just one tag=value, later it could be tag=value1&tag=value2&...
2.61 - tag = request.values.get('tag')
2.62 - prefix = self.name + u'/'
2.63 - current_timestamp = int(time.time())
2.64 - terms = [Term(WIKINAME, app.cfg.interwikiname),
2.65 - # Only sub items of this item
2.66 - Prefix(NAME_EXACT, prefix),
2.67 - # Filter out those items that do not have a PTIME meta or PTIME is in the future.
2.68 - DateRange(PTIME, start=None, end=datetime.utcfromtimestamp(current_timestamp)),
2.69 - ]
2.70 - if tag:
2.71 - terms.append(Term(TAGS, tag))
2.72 - query = And(terms)
2.73 - revs = flaskg.storage.search(query, sortedby=[PTIME], reverse=True, limit=None)
2.74 - blog_entry_items = [Item.create(rev.meta[NAME], rev_id=rev.revid) for rev in revs]
2.75 - return render_template('blog.html',
2.76 - item_name=self.name,
2.77 - blog_item=self,
2.78 - blog_entry_items=blog_entry_items,
2.79 - tag=tag,
2.80 - )
2.81 -
2.82 -@register
2.83 -class BlogEntry(Default):
2.84 - itemtype = u'blogentry'
2.85 -
2.86 - class _ModifyForm(Default._ModifyForm):
2.87 - meta_form = BlogEntryMetaForm
2.88 - meta_template = 'modify_blog_entry_meta.html'
2.89 -
2.90 - def do_show(self, revid):
2.91 - blog_item_name = self.name.rsplit('/', 1)[0]
2.92 - try:
2.93 - blog_item = Item.create(blog_item_name)
2.94 - except AccessDenied:
2.95 - abort(403)
2.96 - if not isinstance(blog_item, Blog):
2.97 - # The parent item of this blog entry item is not a Blog item.
2.98 - abort(403)
2.99 - return render_template('blog_entry.html',
2.100 - item_name=self.name,
2.101 - blog_item=blog_item,
2.102 - blog_entry_item=self,
2.103 - )
2.104 -
2.105 -
2.106 from ..util.pysupport import load_package_modules
2.107 load_package_modules(__name__, __path__)
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/MoinMoin/items/blog.py Thu Aug 16 10:25:22 2012 +0200
3.3 @@ -0,0 +1,105 @@
3.4 +# Copyright: 2012 MoinMoin:PavelSviderski
3.5 +# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
3.6 +
3.7 +"""
3.8 +MoinMoin - Blog itemtype
3.9 +"""
3.10 +
3.11 +
3.12 +import time
3.13 +from datetime import datetime
3.14 +
3.15 +from flask import request, abort
3.16 +from flask import g as flaskg
3.17 +from flask import current_app as app
3.18 +
3.19 +from whoosh.query import Term, And, Prefix, DateRange
3.20 +
3.21 +from MoinMoin.i18n import L_
3.22 +from MoinMoin.themes import render_template
3.23 +from MoinMoin.forms import OptionalText, Tags, DateTime
3.24 +from MoinMoin.storage.middleware.protecting import AccessDenied
3.25 +from MoinMoin.constants.keys import NAME, NAME_EXACT, WIKINAME, PTIME, TAGS
3.26 +from MoinMoin.items import Item, Default, register, BaseMetaForm
3.27 +
3.28 +
3.29 +ITEMTYPE_BLOG = u'blog'
3.30 +ITEMTYPE_BLOG_ENTRY = u'blogentry'
3.31 +
3.32 +
3.33 +class BlogMetaForm(BaseMetaForm):
3.34 + supertags = (Tags.using(label=L_('Supertags (Categories)'))
3.35 + .with_properties(placeholder=L_("Ordered comma separated list of tags")))
3.36 +
3.37 +class BlogEntryMetaForm(BaseMetaForm):
3.38 + summary = (OptionalText.using(label=L_("Title"))
3.39 + .with_properties(placeholder=L_("One-line title of the blog entry")))
3.40 + ptime = DateTime.using(label=L_('Publication time (UTC)'), optional=True)
3.41 +
3.42 +@register
3.43 +class Blog(Default):
3.44 + itemtype = ITEMTYPE_BLOG
3.45 +
3.46 + class _ModifyForm(Default._ModifyForm):
3.47 + meta_form = BlogMetaForm
3.48 + meta_template = 'modify_blog_meta.html'
3.49 +
3.50 + def do_show(self, revid):
3.51 + """
3.52 + Show a blog item and a list of its blog entries below it.
3.53 +
3.54 + If tag GET-parameter is defined, the list of blog entries consists only
3.55 + of those entries that contain the tag value in their lists of tags.
3.56 + """
3.57 + # for now it is just one tag=value, later it could be tag=value1&tag=value2&...
3.58 + tag = request.values.get('tag')
3.59 + prefix = self.name + u'/'
3.60 + current_timestamp = int(time.time())
3.61 + terms = [Term(WIKINAME, app.cfg.interwikiname),
3.62 + # Only sub items of this item
3.63 + Prefix(NAME_EXACT, prefix),
3.64 + # Filter out those items that do not have a PTIME meta or PTIME is in the future.
3.65 + DateRange(PTIME, start=None, end=datetime.utcfromtimestamp(current_timestamp)),
3.66 + ]
3.67 + if tag:
3.68 + terms.append(Term(TAGS, tag))
3.69 + query = And(terms)
3.70 + revs = flaskg.storage.search(query, sortedby=[PTIME], reverse=True, limit=None)
3.71 + blog_entry_items = [Item.create(rev.meta[NAME], rev_id=rev.revid) for rev in revs]
3.72 + return render_template('blog.html',
3.73 + item_name=self.name,
3.74 + blog_item=self,
3.75 + blog_entry_items=blog_entry_items,
3.76 + tag=tag,
3.77 + )
3.78 +
3.79 +@register
3.80 +class BlogEntry(Default):
3.81 + itemtype = ITEMTYPE_BLOG_ENTRY
3.82 +
3.83 + class _ModifyForm(Default._ModifyForm):
3.84 + meta_form = BlogEntryMetaForm
3.85 + meta_template = 'modify_blog_entry_meta.html'
3.86 +
3.87 + @classmethod
3.88 + def from_item(cls, item):
3.89 + form = super(BlogEntry._ModifyForm, cls).from_item(item)
3.90 + # preload PTIME with the current datetime
3.91 + if not form['meta_form']['ptime']:
3.92 + form['meta_form']['ptime'].set(datetime.utcnow())
3.93 + return form
3.94 +
3.95 + def do_show(self, revid):
3.96 + blog_item_name = self.name.rsplit('/', 1)[0]
3.97 + try:
3.98 + blog_item = Item.create(blog_item_name)
3.99 + except AccessDenied:
3.100 + abort(403)
3.101 + if not isinstance(blog_item, Blog):
3.102 + # The parent item of this blog entry item is not a Blog item.
3.103 + abort(403)
3.104 + return render_template('blog_entry.html',
3.105 + item_name=self.name,
3.106 + blog_item=blog_item,
3.107 + blog_entry_item=self,
3.108 + )
4.1 --- a/MoinMoin/templates/blog_layout.html Wed Aug 15 23:35:06 2012 +0200
4.2 +++ b/MoinMoin/templates/blog_layout.html Thu Aug 16 10:25:22 2012 +0200
4.3 @@ -1,6 +1,7 @@
4.4 {% extends theme("layout.html") %}
4.5 {% import "forms.html" as forms %}
4.6 {% import "utils.html" as utils %}
4.7 +{% import "itemviews.html" as itemviews with context %}
4.8
4.9 {% macro show_blog_entry(entry_item) %}
4.10 {% if entry_item.meta['summary'] %}
4.11 @@ -74,6 +75,10 @@
4.12 {% endmacro %}
4.13 {% endif %}
4.14
4.15 +{% block header_itemviews %}
4.16 + {{ itemviews }}
4.17 +{% endblock %}
4.18 +
4.19 {% block content %}
4.20 {% block content_data %}
4.21 <div id="moin-content-data">
4.22 @@ -93,3 +98,7 @@
4.23 </div>
4.24 {% endblock %}
4.25 {% endblock %}
4.26 +
4.27 +{% block footer_itemviews %}
4.28 + {{ itemviews }}
4.29 +{% endblock %}