[IMP] /blog controler and simplification of dates navigation
[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     def nav_list(self):
37         blog_post_obj = request.registry['blog.post']
38         nav = {}
39         for group in blog_post_obj.read_group(request.cr, request.uid, [], ['name', 'create_date'], 
40                 groupby="create_date", orderby="create_date asc", context=request.context):
41             # FIXME: vietnamese month names contain spaces. Set sail for fail.
42             year = group['create_date'].split(" ")[1]
43             if not year in nav:
44                 nav[year] = {'name': year, 'create_date_count': 0, 'months': []}
45             nav[year]['create_date_count'] += group['create_date_count']
46             nav[year]['months'].append(group)
47         return nav
48
49     @website.route([
50         '/blog',
51         '/blog/page/<int:page>/',
52     ], type='http', auth="public", multilang=True)
53     def blogs(self, page=1):
54         BYPAGE = 60
55         cr, uid, context = request.cr, request.uid, request.context
56         blog_obj = request.registry['blog.post']
57         total = blog_obj.search(cr, uid, [], count=True, context=context)
58         pager = request.website.pager(
59             url='/blog/',
60             total=total,
61             page=page,
62             step=BYPAGE,
63         )
64         bids = blog_obj.search(cr, uid, [], offset=(page-1)*BYPAGE, limit=BYPAGE, context=context)
65         blogs = blog_obj.browse(cr, uid, bids, context=context)
66         return request.website.render("website_blog.blogs", {
67             'blogs': blogs,
68             'pager': pager
69         })
70
71     @website.route([
72         '/blog/cat/<model("blog.category"):category>/',
73         '/blog/cat/<model("blog.category"):category>/page/<int:page>/',
74         '/blog/tag/<model("blog.tag"):tag>/',
75         '/blog/tag/<model("blog.tag"):tag>/page/<int:page>/',
76     ], type='http', auth="public", multilang=True)
77     def blog(self, category=None, tag=None, page=1):
78         """ Prepare all values to display the blog.
79
80         :param category: category currently browsed.
81         :param tag: tag that is currently used to filter blog posts
82         :param integer page: current page of the pager. Can be the category or
83                             post pager.
84
85         :return dict values: values for the templates, containing
86
87          - 'blog_posts': list of browse records that are the posts to display
88                          in a given category, if not blog_post_id
89          - 'category': browse of the current category, if category_id
90          - 'categories': list of browse records of categories
91          - 'pager': the pager to display posts pager in a category
92          - 'tag': current tag, if tag_id
93          - 'nav_list': a dict [year][month] for archives navigation
94         """
95         cr, uid, context = request.cr, request.uid, request.context
96         blog_post_obj = request.registry['blog.post']
97
98         blog_posts = None
99
100         category_obj = request.registry['blog.category']
101         category_ids = category_obj.search(cr, uid, [], context=context)
102         categories = category_obj.browse(cr, uid, category_ids, context=context)
103
104         if category:
105             pager_url = "/blog/cat/%s/" % category.id
106             blog_posts = category.blog_post_ids
107         elif tag:
108             pager_url = '/blog/tag/%s/' % tag.id
109             blog_posts = tag.blog_post_ids
110         else:
111             pager_url = '/blog/'
112             blog_post_ids = blog_post_obj.search(cr, uid, [], context=context)
113             blog_posts = blog_post_obj.browse(cr, uid, blog_post_ids, context=context)
114
115         pager = request.website.pager(
116             url=pager_url,
117             total=len(blog_posts),
118             page=page,
119             step=self._category_post_per_page,
120             scope=7
121         )
122         pager_begin = (page - 1) * self._category_post_per_page
123         pager_end = page * self._category_post_per_page
124         blog_posts = blog_posts[pager_begin:pager_end]
125
126         values = {
127             'category': category,
128             'categories': categories,
129             'tag': tag,
130             'blog_posts': blog_posts,
131             'pager': pager,
132             'nav_list': self.nav_list(),
133         }
134
135         if tag:
136             values['main_object'] = tag
137         elif category:
138             values['main_object'] = category
139
140         return request.website.render("website_blog.blog_post_short", values)
141
142     @website.route([
143         '/blog/<model("blog.post"):blog_post>/',
144         '/blog/<model("blog.post"):blog_post>/page/<int:page>/'
145     ], type='http', auth="public", multilang=True)
146     def blog_post(self, blog_post=None, page=1, enable_editor=None):
147         """ Prepare all values to display the blog.
148
149         :param blog_post: blog post currently browsed. If not set, the user is
150                           browsing the category and a post pager is calculated.
151                           If set the user is reading the blog post and a
152                           comments pager is calculated.
153         :param integer page: current page of the pager. Can be the category or
154                             post pager.
155         :param dict post: kwargs, may contain
156
157          - 'enable_editor': editor control
158
159         :return dict values: values for the templates, containing
160
161          - 'blog_post': browse of the current post, if blog_post_id
162          - 'category': browse of the current category, if category_id
163          - 'pager': the pager to display comments pager in a blog post
164          - 'nav_list': a dict [year][month] for archives navigation
165         """
166         pager = request.website.pager(
167             url="/blog/%s/" % blog_post.id,
168             total=len(blog_post.website_message_ids),
169             page=page,
170             step=self._post_comment_per_page,
171             scope=7
172         )
173         pager_begin = (page - 1) * self._post_comment_per_page
174         pager_end = page * self._post_comment_per_page
175         blog_post.website_message_ids = blog_post.website_message_ids[pager_begin:pager_end]
176
177         cr, uid, context = request.cr, request.uid, request.context
178         category_obj = request.registry['blog.category']
179         category_ids = category_obj.search(cr, uid, [], context=context)
180         categories = category_obj.browse(cr, uid, category_ids, context=context)
181
182         values = {
183             'category': blog_post.category_id,
184             'categories': categories,
185             'blog_post': blog_post,
186             'pager': pager,
187             'nav_list': self.nav_list(),
188             'enable_editor': enable_editor,
189         }
190         return request.website.render("website_blog.blog_post_complete", values)
191
192     # TODO: Refactor (used in website_blog.js for archive links)
193     # => the archive links should be generated server side
194     @website.route(['/blog/nav'], type='http', auth="public", multilang=True)
195     def nav(self, **post):
196         cr, uid, context = request.cr, request.uid, request.context
197         blog_post_ids = request.registry['blog.post'].search(
198             cr, uid, safe_eval(post.get('domain')),
199             order="create_date asc",
200             limit=None,
201             context=context
202         )
203         blog_post_data = [
204             {
205                 'id': blog_post.id,
206                 'website_published': blog_post.website_published,
207                 'fragment': request.website.render("website_blog.blog_archive_link", {
208                     'blog_post': blog_post
209                 }),
210             }
211             for blog_post in request.registry['blog.post'].browse(cr, uid, blog_post_ids, context=context)
212         ]
213         return simplejson.dumps(blog_post_data)
214
215     @website.route(['/blog/<int:blog_post_id>/comment'], type='http', auth="public")
216     def blog_post_comment(self, blog_post_id=None, **post):
217         cr, uid, context = request.cr, request.uid, request.context
218         if post.get('comment'):
219             request.registry['blog.post'].message_post(
220                 cr, uid, blog_post_id,
221                 body=post.get('comment'),
222                 type='comment',
223                 subtype='mt_comment',
224                 context=dict(context, mail_create_nosubcribe=True))
225         return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
226
227     @website.route(['/blog/<int:category_id>/new'], type='http', auth="public", multilang=True)
228     def blog_post_create(self, category_id=None, **post):
229         cr, uid, context = request.cr, request.uid, request.context
230         create_context = dict(context, mail_create_nosubscribe=True)
231         new_blog_post_id = request.registry['blog.post'].create(
232             request.cr, request.uid, {
233                 'category_id': category_id,
234                 'name': _("Blog title"),
235                 'content': '',
236                 'website_published': False,
237             }, context=create_context)
238         return werkzeug.utils.redirect("/blog/%s/?enable_editor=1" % (new_blog_post_id))
239
240     @website.route(['/blog/<int:blog_post_id>/duplicate'], type='http', auth="public")
241     def blog_post_copy(self, blog_post_id=None, **post):
242         cr, uid, context = request.cr, request.uid, request.context
243         create_context = dict(context, mail_create_nosubscribe=True)
244         new_blog_post_id = request.registry['blog.post'].copy(cr, uid, blog_post_id, {}, context=create_context)
245         return werkzeug.utils.redirect("/blog/%s/?enable_editor=1" % (new_blog_post_id))