[FIX] blog controller to suck less and be more compatible with routes introspection
[odoo/odoo.git] / addons / website_blog / controllers / main.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 from openerp.addons.web import http
23 from openerp.addons.web.http import request
24 from openerp.addons.website.models import website
25 from openerp.tools.translate import _
26 from openerp.tools.safe_eval import safe_eval
27
28 import simplejson
29 import werkzeug
30
31
32 class WebsiteBlog(http.Controller):
33     _category_post_per_page = 6
34     _post_comment_per_page = 6
35
36     @website.route([
37         '/blog/',
38         '/blog/page/<int:page>/',
39         '/blog/<model("blog.post"):blog_post>/',
40         '/blog/<model("blog.post"):blog_post>/page/<int:page>/',
41         '/blog/cat/<model("blog.category"):category>/',
42         '/blog/cat/<model("blog.category"):category>/page/<int:page>/',
43         '/blog/tag/<model("blog.tag"):tag>/',
44         '/blog/tag/<model("blog.tag"):tag>/page/<int:page>/',
45     ], type='http', auth="public", multilang=True)
46     def blog(self, category=None, blog_post=None, tag=None, page=1, enable_editor=None):
47         """ Prepare all values to display the blog.
48
49         :param category: category currently browsed.
50         :param tag: tag that is currently used to filter blog posts
51         :param blog_post: blog post currently browsed. If not set, the user is
52                           browsing the category and a post pager is calculated.
53                           If set the user is reading the blog post and a
54                           comments pager is calculated.
55         :param integer page: current page of the pager. Can be the category or
56                             post pager.
57         :param dict post: kwargs, may contain
58
59          - 'enable_editor': editor control
60
61         :return dict values: values for the templates, containing
62
63          - 'blog_post': browse of the current post, if blog_post_id
64          - 'blog_posts': list of browse records that are the posts to display
65                          in a given category, if not blog_post_id
66          - 'category': browse of the current category, if category_id
67          - 'categories': list of browse records of categories
68          - 'pager': the pager to display, posts pager in a category or comments
69                     pager in a blog post
70          - 'tag': current tag, if tag_id
71          - 'nav_list': a dict [year][month] for archives navigation
72         """
73         cr, uid, context = request.cr, request.uid, request.context
74         blog_post_obj = request.registry['blog.post']
75         category_obj = request.registry['blog.category']
76
77         blog_posts = None
78         nav = {}
79
80         category_ids = category_obj.search(cr, uid, [], context=context)
81         categories = category_obj.browse(cr, uid, category_ids, context=context)
82
83         if blog_post:
84             category = blog_post.category_id
85             pager = request.website.pager(
86                 url="/blog/%s/" % blog_post.id,
87                 total=len(blog_post.website_message_ids),
88                 page=page,
89                 step=self._post_comment_per_page,
90                 scope=7
91             )
92             pager_begin = (page - 1) * self._post_comment_per_page
93             pager_end = page * self._post_comment_per_page
94             blog_post.website_message_ids = blog_post.website_message_ids[pager_begin:pager_end]
95         else:
96             if category:
97                 pager_url = "/blog/cat/%s/" % category.id
98                 blog_posts = category.blog_post_ids
99             elif tag:
100                 pager_url = '/blog/tag/%s/' % tag.id
101                 blog_posts = tag.blog_post_ids
102             else:
103                 pager_url = '/blog/'
104                 blog_post_ids = blog_post_obj.search(cr, uid, [], context=context)
105                 blog_posts = blog_post_obj.browse(cr, uid, blog_post_ids, context=context)
106
107             pager = request.website.pager(
108                 url=pager_url,
109                 total=len(blog_posts),
110                 page=page,
111                 step=self._category_post_per_page,
112                 scope=7
113             )
114             pager_begin = (page - 1) * self._category_post_per_page
115             pager_end = page * self._category_post_per_page
116             blog_posts = blog_posts[pager_begin:pager_end]
117
118         for group in blog_post_obj.read_group(cr, uid, [], ['name', 'create_date'], groupby="create_date", orderby="create_date asc", context=context):
119             year = group['create_date'].split(" ")[1]
120             if not year in nav:
121                 nav[year] = {'name': year, 'create_date_count': 0, 'months': []}
122             nav[year]['create_date_count'] += group['create_date_count']
123             nav[year]['months'].append(group)
124
125         values = {
126             'category': category,
127             'categories': categories,
128             'tag': tag,
129             'blog_post': blog_post,
130             'blog_posts': blog_posts,
131             'pager': pager,
132             'nav_list': nav,
133             'enable_editor': enable_editor,
134         }
135
136         if blog_post:
137             values['main_object'] = blog_post
138         elif tag:
139             values['main_object'] = tag
140         elif category:
141             values['main_object'] = category
142
143         return request.website.render("website_blog.index", values)
144
145     # TODO: Refactor (used in website_blog.js for archive links)
146     # => the archive links should be generated server side
147     @website.route(['/blog/nav'], type='http', auth="public", multilang=True)
148     def nav(self, **post):
149         cr, uid, context = request.cr, request.uid, request.context
150         blog_post_ids = request.registry['blog.post'].search(
151             cr, uid, safe_eval(post.get('domain')),
152             order="create_date asc",
153             limit=None,
154             context=context
155         )
156         blog_post_data = [
157             {
158                 'id': blog_post.id,
159                 'website_published': blog_post.website_published,
160                 'fragment': request.website.render("website_blog.blog_archive_link", {
161                     'blog_post': blog_post
162                 }),
163             }
164             for blog_post in request.registry['blog.post'].browse(cr, uid, blog_post_ids, context=context)
165         ]
166         return simplejson.dumps(blog_post_data)
167
168     @website.route(['/blog/<int:blog_post_id>/comment'], type='http', auth="public")
169     def blog_post_comment(self, blog_post_id=None, **post):
170         cr, uid, context = request.cr, request.uid, request.context
171         request.registry['blog.post'].message_post(
172             cr, uid, blog_post_id,
173             body=post.get('comment'),
174             type='comment',
175             subtype='mt_comment',
176             context=dict(context, mail_create_nosubcribe=True))
177         return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
178
179     @website.route(['/blog/<int:category_id>/new'], type='http', auth="public")
180     def blog_post_create(self, category_id=None, **post):
181         cr, uid, context = request.cr, request.uid, request.context
182         create_context = dict(context, mail_create_nosubscribe=True)
183         new_blog_post_id = request.registry['blog.post'].create(
184             request.cr, request.uid, {
185                 'category_id': category_id,
186                 'name': _("Blog title"),
187                 'content': '',
188                 'website_published': False,
189             }, context=create_context)
190         return werkzeug.utils.redirect("/blog/%s/?enable_editor=1" % (new_blog_post_id))
191
192     @website.route(['/blog/<int:blog_post_id>/duplicate'], type='http', auth="public")
193     def blog_post_copy(self, blog_post_id=None, **post):
194         cr, uid, context = request.cr, request.uid, request.context
195         create_context = dict(context, mail_create_nosubscribe=True)
196         new_blog_post_id = request.registry['blog.post'].copy(cr, uid, blog_post_id, {}, context=create_context)
197         return werkzeug.utils.redirect("/blog/%s/?enable_editor=1" % (new_blog_post_id))