# -*- coding: utf-8 -*- import datetime import urllib import werkzeug from openerp import tools from openerp.addons.web import http from openerp.addons.web.http import request from openerp.addons.website.models.website import slug from openerp.exceptions import UserError from openerp.osv.orm import browse_record from openerp.tools.translate import _ from openerp import SUPERUSER_ID from openerp.tools import html2plaintext class QueryURL(object): def __init__(self, path='', path_args=None, **args): self.path = path self.args = args self.path_args = set(path_args or []) def __call__(self, path=None, path_args=None, **kw): path = path or self.path for k, v in self.args.items(): kw.setdefault(k, v) path_args = set(path_args or []).union(self.path_args) paths, fragments = [], [] for key, value in kw.items(): if value and key in path_args: if isinstance(value, browse_record): paths.append((key, slug(value))) else: paths.append((key, value)) elif value: if isinstance(value, list) or isinstance(value, set): fragments.append(werkzeug.url_encode([(key, item) for item in value])) else: fragments.append(werkzeug.url_encode([(key, value)])) for key, value in paths: path += '/' + key + '/%s' % value if fragments: path += '?' + '&'.join(fragments) return path class WebsiteBlog(http.Controller): _blog_post_per_page = 20 _post_comment_per_page = 10 def nav_list(self, blog=None): blog_post_obj = request.registry['blog.post'] domain = blog and [('blog_id', '=', blog.id)] or [] groups = blog_post_obj.read_group( request.cr, request.uid, domain, ['name', 'create_date'], groupby="create_date", orderby="create_date desc", context=request.context) for group in groups: begin_date = datetime.datetime.strptime(group['__domain'][0][2], tools.DEFAULT_SERVER_DATETIME_FORMAT).date() end_date = datetime.datetime.strptime(group['__domain'][1][2], tools.DEFAULT_SERVER_DATETIME_FORMAT).date() group['date_begin'] = '%s' % datetime.date.strftime(begin_date, tools.DEFAULT_SERVER_DATE_FORMAT) group['date_end'] = '%s' % datetime.date.strftime(end_date, tools.DEFAULT_SERVER_DATE_FORMAT) return groups @http.route([ '/blog', '/blog/page/', ], type='http', auth="public", website=True) def blogs(self, page=1, **post): cr, uid, context = request.cr, request.uid, request.context blog_obj = request.registry['blog.post'] total = blog_obj.search(cr, uid, [], count=True, context=context) pager = request.website.pager( url='/blog', total=total, page=page, step=self._blog_post_per_page, ) post_ids = blog_obj.search(cr, uid, [], offset=(page-1)*self._blog_post_per_page, limit=self._blog_post_per_page, context=context) posts = blog_obj.browse(cr, uid, post_ids, context=context) blog_url = QueryURL('', ['blog', 'tag']) return request.website.render("website_blog.latest_blogs", { 'posts': posts, 'pager': pager, 'blog_url': blog_url, }) @http.route([ '/blog/', '/blog//page/', '/blog//tag/', '/blog//tag//page/', ], type='http', auth="public", website=True) def blog(self, blog=None, tag=None, page=1, **opt): """ Prepare all values to display the blog. :return dict values: values for the templates, containing - 'blog': current blog - 'blogs': all blogs for navigation - 'pager': pager of posts - 'active_tag_ids' : list of active tag ids, - 'tags_list' : function to built the comma-separated tag list ids (for the url), - 'tags': all tags, for navigation - 'nav_list': a dict [year][month] for archives navigation - 'date': date_begin optional parameter, used in archives navigation - 'blog_url': help object to create URLs """ date_begin, date_end = opt.get('date_begin'), opt.get('date_end') cr, uid, context = request.cr, request.uid, request.context blog_post_obj = request.registry['blog.post'] blog_obj = request.registry['blog.blog'] blog_ids = blog_obj.search(cr, uid, [], order="create_date asc", context=context) blogs = blog_obj.browse(cr, uid, blog_ids, context=context) # build the domain for blog post to display domain = [] active_tag_ids = tag and map(int, tag.split(',')) or [] if active_tag_ids: domain += [('tag_ids', 'in', active_tag_ids)] if blog: domain += [('blog_id', '=', blog.id)] if date_begin and date_end: domain += [("create_date", ">=", date_begin), ("create_date", "<=", date_end)] blog_url = QueryURL('', ['blog', 'tag'], blog=blog, tag=tag, date_begin=date_begin, date_end=date_end) blog_post_ids = blog_post_obj.search(cr, uid, domain, order="create_date desc", context=context) blog_posts = blog_post_obj.browse(cr, uid, blog_post_ids, context=context) pager = request.website.pager( url=blog_url(), total=len(blog_posts), page=page, step=self._blog_post_per_page, ) pager_begin = (page - 1) * self._blog_post_per_page pager_end = page * self._blog_post_per_page blog_posts = blog_posts[pager_begin:pager_end] all_tags = blog.all_tags()[blog.id] # function to create the string list of tag ids, and toggle a given one. # used in the 'Tags Cloud' template. def tags_list(tag_ids, current_tag): tag_ids = list(tag_ids) # required to avoid using the same list if current_tag in tag_ids: tag_ids.remove(current_tag) else: tag_ids.append(current_tag) return ','.join(map(str, tag_ids)) values = { 'blog': blog, 'blogs': blogs, 'tags': all_tags, 'active_tag_ids': active_tag_ids, 'tags_list' : tags_list, 'blog_posts': blog_posts, 'pager': pager, 'nav_list': self.nav_list(blog), 'blog_url': blog_url, 'date': date_begin, } response = request.website.render("website_blog.blog_post_short", values) return response @http.route([ '''/blog//post//post/new', type='http', auth="public", website=True) def blog_post_create(self, blog_id, **post): cr, uid, context = request.cr, request.uid, request.context new_blog_post_id = request.registry['blog.post'].create(cr, uid, { 'blog_id': blog_id, 'name': _("Blog Post Title"), 'subtitle': _("Subtitle"), 'content': '', 'website_published': False, }, context=context) new_blog_post = request.registry['blog.post'].browse(cr, uid, new_blog_post_id, context=context) return werkzeug.utils.redirect("/blog/%s/post/%s?enable_editor=1" % (slug(new_blog_post.blog_id), slug(new_blog_post))) @http.route('/blog/post_duplicate', type='http', auth="public", website=True) def blog_post_copy(self, blog_post_id, **post): """ Duplicate a blog. :param blog_post_id: id of the blog post currently browsed. :return redirect to the new blog created """ cr, uid, context = request.cr, request.uid, request.context create_context = dict(context, mail_create_nosubscribe=True) nid = request.registry['blog.post'].copy(cr, uid, int(blog_post_id), {}, context=create_context) new_blog_post = request.registry['blog.post'].browse(cr, uid, nid, context=context) post = request.registry['blog.post'].browse(cr, uid, nid, context) return werkzeug.utils.redirect("/blog/%s/post/%s?enable_editor=1" % (slug(post.blog_id), slug(new_blog_post))) @http.route('/blog/post_get_discussion/', type='json', auth="public", website=True) def discussion(self, post_id=0, path=None, count=False, **post): cr, uid, context = request.cr, request.uid, request.context mail_obj = request.registry.get('mail.message') domain = [('res_id', '=', int(post_id)), ('model', '=', 'blog.post'), ('path', '=', path)] #check current user belongs to website publisher group publish = request.registry['res.users'].has_group(cr, uid, 'base.group_website_publisher') if not publish: domain.append(('website_published', '=', True)) ids = mail_obj.search(cr, SUPERUSER_ID, domain, count=count) if count: return ids return self._get_discussion_detail(ids, publish, **post) @http.route('/blog/post_get_discussions/', type='json', auth="public", website=True) def discussions(self, post_id=0, paths=None, count=False, **post): ret = [] for path in paths: result = self.discussion(post_id=post_id, path=path, count=count, **post) ret.append({"path": path, "val": result}) return ret @http.route('/blog/post_change_background', type='json', auth="public", website=True) def change_bg(self, post_id=0, image=None, **post): if not post_id: return False return request.registry['blog.post'].write(request.cr, request.uid, [int(post_id)], {'background_image': image}, request.context) @http.route('/blog/get_user/', type='json', auth="public", website=True) def get_user(self, **post): return [False if request.session.uid else True]