def post_notification(self): base_url = self.env['ir.config_parameter'].get_param('web.base.url') for post in self: if post.state == 'active' and post.parent_id: body = _( '<p>A new answer for <i>%s</i> has been posted. <a href="%s/forum/%s/question/%s">Click here to access the post.</a></p>' % (post.parent_id.name, base_url, slug(post.parent_id.forum_id), slug(post.parent_id)) ) post.parent_id.message_post(subject=_('Re: %s') % post.parent_id.name, body=body, subtype='website_forum.mt_answer_new') elif post.state == 'active' and not post.parent_id: body = _( '<p>A new question <i>%s</i> has been asked on %s. <a href="%s/forum/%s/question/%s">Click here to access the question.</a></p>' % (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post)) ) post.message_post(subject=post.name, body=body, subtype='website_forum.mt_question_new') elif post.state == 'pending' and not post.parent_id: # TDE FIXME: in master, you should probably use a subtype; # however here we remove subtype but set partner_ids partners = post.sudo().message_partner_ids.filtered(lambda partner: partner.user_ids and partner.user_ids.karma >= post.forum_id.karma_moderate) note_subtype = self.sudo().env.ref('mail.mt_note') body = _( '<p>A new question <i>%s</i> has been asked on %s and require your validation. <a href="%s/forum/%s/question/%s">Click here to access the question.</a></p>' % (post.name, post.forum_id.name, base_url, slug(post.forum_id), slug(post)) ) post.message_post(subject=post.name, body=body, subtype_id=note_subtype.id, partner_ids=partners.ids) return True
def save_edited_profile(self, forum, user, **kwargs): values = { 'name': kwargs.get('name'), 'website': kwargs.get('website'), 'email': kwargs.get('email'), 'city': kwargs.get('city'), 'country_id': int(kwargs.get('country')) if kwargs.get('country') else False, 'website_description': kwargs.get('description'), } if request.uid == user.id: # the controller allows to edit only its own privacy settings; use partner management for other cases values['website_published'] = kwargs.get('website_published') == 'True' user.write(values) return werkzeug.utils.redirect("/forum/%s/user/%d" % (slug(forum), user.id))
def post_create(self, forum, post_parent=None, post_type=None, **post): if post_type == 'question' and not post.get('post_name', '').strip(): return request.website.render('website.http_error', {'status_code': _('Bad Request'), 'status_message': _('Title should not be empty.')}) post_tag_ids = forum._tag_to_write_vals(post.get('post_tags', '')) new_question = request.env['forum.post'].create({ 'forum_id': forum.id, 'name': post.get('post_name', ''), 'content': post.get('content', False), 'content_link': post.get('content_link', False), 'parent_id': post_parent and post_parent.id or False, 'tag_ids': post_tag_ids, 'post_type': post_parent and post_parent.post_type or post_type, # tde check in selection field }) return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), post_parent and slug(post_parent) or new_question.id))
def thread_headers(self, group, page=1, mode='thread', date_begin=None, date_end=None, **post): cr, uid, context = request.cr, request.uid, request.context thread_obj = request.registry.get('mail.message') domain = [('model', '=', 'mail.channel'), ('res_id', '=', group.id)] if mode == 'thread': domain += [('parent_id', '=', False)] if date_begin and date_end: domain += [('date', '>=', date_begin), ('date', '<=', date_end)] thread_count = thread_obj.search_count(cr, uid, domain, context=context) pager = request.website.pager( url='/groups/%s' % slug(group), total=thread_count, page=page, step=self._thread_per_page, url_args={ 'mode': mode, 'date_begin': date_begin or '', 'date_end': date_end or '' }, ) thread_ids = thread_obj.search(cr, uid, domain, limit=self._thread_per_page, offset=pager['offset']) messages = thread_obj.browse(cr, uid, thread_ids, context) values = { 'messages': messages, 'group': group, 'pager': pager, 'mode': mode, 'archives': self._get_archives(group.id), 'date_begin': date_begin, 'date_end': date_end, 'replies_per_page': self._replies_per_page, } return request.website.render('website_mail_channel.group_messages', values)
def message_get_email_values(self, cr, uid, id, notif_mail=None, context=None): res = super(MailGroup, self).message_get_email_values(cr, uid, id, notif_mail=notif_mail, context=context) group = self.browse(cr, uid, id, context=context) base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url') headers = {} if res.get('headers'): try: headers = eval(res['headers']) except Exception: pass headers.update({ 'List-Archive': '<%s/groups/%s>' % (base_url, slug(group)), 'List-Subscribe': '<%s/groups>' % (base_url), 'List-Unsubscribe': '<%s/groups?unsubscribe>' % (base_url,), }) res['headers'] = repr(headers) return res
def _add_event(self, event_name=None, context={}, **kwargs): if not event_name: event_name = _("New Event") Event = request.registry.get('event.event') date_begin = datetime.today() + timedelta(days=(14)) vals = { 'name': event_name, 'date_begin': date_begin.strftime('%Y-%m-%d'), 'date_end': (date_begin + timedelta(days=(1))).strftime('%Y-%m-%d'), 'seats_available': 1000, } event_id = Event.create(request.cr, request.uid, vals, context=context) event = Event.browse(request.cr, request.uid, event_id, context=context) return request.redirect("/event/%s/register?enable_editor=1" % slug(event))
def send_get_mail_body(self, cr, uid, ids, partner=None, context=None): """ Short-circuit parent method for mail groups, replace the default footer with one appropriate for mailing-lists.""" # TDE: temporary addition (mail was parameter) due to semi-new-API mail = self.browse(cr, uid, ids[0], context=context) if mail.model == 'mail.channel' and mail.res_id: # no super() call on purpose, no private links that could be quoted! channel = self.pool['mail.channel'].browse(cr, uid, mail.res_id, context=context) base_url = self.pool['ir.config_parameter'].get_param( cr, uid, 'web.base.url') vals = { 'maillist': _('Mailing-List'), 'post_to': _('Post to'), 'unsub': _('Unsubscribe'), 'mailto': 'mailto:%s@%s' % (channel.alias_name, channel.alias_domain), 'group_url': '%s/groups/%s' % (base_url, slug(channel)), 'unsub_url': '%s/groups?unsubscribe' % (base_url, ), } footer = """_______________________________________________ %(maillist)s: %(group_url)s %(post_to)s: %(mailto)s %(unsub)s: %(unsub_url)s """ % vals body = tools.append_content_to_html(mail.body, footer, container_tag='div') return body else: return super(MailMail, self).send_get_mail_body(cr, uid, ids, partner=partner, context=context)
def users(self, forum, page=1, **searches): User = request.env['res.users'] step = 30 tag_count = User.sudo().search_count([('karma', '>', 1), ('website_published', '=', True)]) pager = request.website.pager(url="/forum/%s/users" % slug(forum), total=tag_count, page=page, step=step, scope=30) user_obj = User.sudo().search([('karma', '>', 1), ('website_published', '=', True)], limit=step, offset=pager['offset'], order='karma DESC') # put the users in block of 3 to display them as a table users = [[] for i in range(len(user_obj) / 3 + 1)] for index, user in enumerate(user_obj): users[index / 3].append(user) searches['users'] = 'True' values = self._prepare_forum_values(forum=forum, searches=searches) values .update({ 'users': users, 'main_object': forum, 'notifications': self._get_notifications(), 'pager': pager, }) return request.website.render("website_forum.users", values)
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
def test_08_survey_urls(self): def validate_url(url): """ Reference: https://github.com/django/django/blob/master/django/core/validators.py """ url_regex = re.compile( r'^https?://' # http:// or https:// r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' # domain... r'localhost|' # localhost... r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' # ...or ipv4 r'\[?[A-F0-9]*:[A-F0-9:]+\]?)' # ...or ipv6 r'(?::\d+)?' # optional port r'(?:/?|[/?]\S+)$', re.IGNORECASE) return True if url_regex.match(url) else False base_url = self.env['ir.config_parameter'].get_param('web.base.url') urltypes = {'public': 'start', 'print': 'print', 'result': 'results'} for urltype, urltxt in urltypes.iteritems(): survey_url = getattr(self.survey1, urltype + '_url') survey_url_relative = getattr( self.survey1.with_context({'relative_url': True}), urltype + '_url') self.assertTrue(validate_url(survey_url)) url = "survey/%s/%s" % (urltxt, slug(self.survey1)) full_url = urljoin(base_url, url) self.assertEqual(full_url, survey_url) self.assertEqual('/' + url, survey_url_relative) if urltype == 'public': url_html = '<a href="%s">Click here to start survey</a>' self.assertEqual(url_html % full_url, getattr(self.survey1, urltype + '_url_html'), msg="Public URL is incorrect") self.assertEqual( url_html % ('/' + url), getattr(self.survey1.with_context({'relative_url': True}), urltype + '_url_html'), msg="Public URL is incorrect.")
def to_url(self, value): return slug(value)
def jobs_add(self, **kwargs): job = request.env['hr.job'].create({ 'name': _('New Job Offer'), }) return request.redirect("/jobs/detail/%s?enable_editor=1" % slug(job))
def _website_url(self, name, arg): res = super(event, self)._website_url(name, arg) res.update({(e.id, '/event/%s' % slug(e)) for e in self}) return res
def question_reopen(self, forum, question, **kwarg): question.reopen() return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
def post_delete(self, forum, post, **kwargs): question = post.parent_id post.unlink() if question: werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question))) return werkzeug.utils.redirect("/forum/%s" % slug(forum))
def question_undelete(self, forum, question, **kwarg): question.active = True return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
def blog_post(self, blog, blog_post, tag_id=None, page=1, enable_editor=None, **post): """ Prepare all values to display the blog. :return dict values: values for the templates, containing - 'blog_post': browse of the current post - 'blog': browse of the current blog - 'blogs': list of browse records of blogs - 'tag': current tag, if tag_id in parameters - 'tags': all tags, for tag-based navigation - 'pager': a pager on the comments - 'nav_list': a dict [year][month] for archives navigation - 'next_post': next blog post, to direct the user towards the next interesting post """ cr, uid, context = request.cr, request.uid, request.context tag_obj = request.registry['blog.tag'] blog_post_obj = request.registry['blog.post'] date_begin, date_end = post.get('date_begin'), post.get('date_end') pager_url = "/blogpost/%s" % blog_post.id pager = request.website.pager(url=pager_url, total=len(blog_post.website_message_ids), page=page, step=self._post_comment_per_page, scope=7) pager_begin = (page - 1) * self._post_comment_per_page pager_end = page * self._post_comment_per_page comments = blog_post.website_message_ids[pager_begin:pager_end] tag = None if tag_id: tag = request.registry['blog.tag'].browse(request.cr, request.uid, int(tag_id), context=request.context) blog_url = QueryURL('', ['blog', 'tag'], blog=blog_post.blog_id, tag=tag, date_begin=date_begin, date_end=date_end) if not blog_post.blog_id.id == blog.id: return request.redirect("/blog/%s/post/%s" % (slug(blog_post.blog_id), slug(blog_post))) tags = tag_obj.browse(cr, uid, tag_obj.search(cr, uid, [], context=context), context=context) # Find next Post all_post_ids = blog_post_obj.search(cr, uid, [('blog_id', '=', blog.id)], context=context) # should always return at least the current post current_blog_post_index = all_post_ids.index(blog_post.id) next_post_id = all_post_ids[0 if current_blog_post_index == len(all_post_ids) - 1 \ else current_blog_post_index + 1] next_post = next_post_id and blog_post_obj.browse( cr, uid, next_post_id, context=context) or False values = { 'tags': tags, 'tag': tag, 'blog': blog, 'blog_post': blog_post, 'blog_post_cover_properties': json.loads(blog_post.cover_properties), 'main_object': blog_post, 'nav_list': self.nav_list(blog), 'enable_editor': enable_editor, 'next_post': next_post, 'next_post_cover_properties': json.loads(next_post.cover_properties) if next_post else {}, 'date': date_begin, 'blog_url': blog_url, 'pager': pager, 'comments': comments, } response = request.website.render("website_blog.blog_post_complete", values) request.session[request.session_id] = request.session.get( request.session_id, []) if not (blog_post.id in request.session[request.session_id]): request.session[request.session_id].append(blog_post.id) # Increase counter blog_post_obj.write(cr, SUPERUSER_ID, [blog_post.id], { 'visits': blog_post.visits + 1, }, context=context) return response
def open_partner(self, forum, partner_id=0, **post): if partner_id: partner = request.env['res.partner'].sudo().search([('id', '=', partner_id)]) if partner and partner.user_ids: return werkzeug.utils.redirect("/forum/%s/user/%d" % (slug(forum), partner.user_ids[0].id)) return werkzeug.utils.redirect("/forum/%s" % slug(forum))
def _website_url(self, cr, uid, ids, field_name, arg, context=None): res = super(res_partner_grade, self)._website_url(cr, uid, ids, field_name, arg, context=context) for grade in self.browse(cr, uid, ids, context=context): res[grade.id] = "/partners/grade/%s" % (slug(grade)) return res
def open_user(self, forum, user_id=0, **post): User = request.env['res.users'] Post = request.env['forum.post'] Vote = request.env['forum.post.vote'] Activity = request.env['mail.message'] Followers = request.env['mail.followers'] Data = request.env["ir.model.data"] user = User.sudo().search([('id', '=', user_id)]) current_user = request.env.user.sudo() # Users with high karma can see users with karma <= 0 for # moderation purposes, IFF they have posted something (see below) if (not user or (user.karma < 1 and current_user.karma < forum.karma_unlink_all)): return werkzeug.utils.redirect("/forum/%s" % slug(forum)) values = self._prepare_forum_values(forum=forum, **post) # questions and answers by user user_question_ids = Post.search([ ('parent_id', '=', False), ('forum_id', '=', forum.id), ('create_uid', '=', user.id)], order='create_date desc') count_user_questions = len(user_question_ids) if (user_id != request.session.uid and not (user.website_published or (count_user_questions and current_user.karma > forum.karma_unlink_all))): return request.website.render("website_forum.private_profile", values) # limit length of visible posts by default for performance reasons, except for the high # karma users (not many of them, and they need it to properly moderate the forum) post_display_limit = None if current_user.karma < forum.karma_unlink_all: post_display_limit = 20 user_questions = user_question_ids[:post_display_limit] user_answer_ids = Post.search([ ('parent_id', '!=', False), ('forum_id', '=', forum.id), ('create_uid', '=', user.id)], order='create_date desc') count_user_answers = len(user_answer_ids) user_answers = user_answer_ids[:post_display_limit] # showing questions which user following post_ids = [follower.res_id for follower in Followers.sudo().search([('res_model', '=', 'forum.post'), ('partner_id', '=', user.partner_id.id)])] followed = Post.search([('id', 'in', post_ids), ('forum_id', '=', forum.id), ('parent_id', '=', False)]) # showing Favourite questions of user. favourite = Post.search([('favourite_ids', '=', user.id), ('forum_id', '=', forum.id), ('parent_id', '=', False)]) # votes which given on users questions and answers. data = Vote.read_group([('forum_id', '=', forum.id), ('recipient_id', '=', user.id)], ["vote"], groupby=["vote"]) up_votes, down_votes = 0, 0 for rec in data: if rec['vote'] == '1': up_votes = rec['vote_count'] elif rec['vote'] == '-1': down_votes = rec['vote_count'] # Votes which given by users on others questions and answers. vote_ids = Vote.search([('user_id', '=', user.id)]) # activity by user. model, comment = Data.get_object_reference('mail', 'mt_comment') activities = Activity.search([('res_id', 'in', (user_question_ids + user_answer_ids).ids), ('model', '=', 'forum.post'), ('subtype_id', '!=', comment)], order='date DESC', limit=100) posts = {} for act in activities: posts[act.res_id] = True posts_ids = Post.search([('id', 'in', posts.keys())]) posts = dict(map(lambda x: (x.id, (x.parent_id or x, x.parent_id and x or False)), posts_ids)) # TDE CLEANME MASTER: couldn't it be rewritten using a 'menu' key instead of one key for each menu ? if user == request.env.user: post['my_profile'] = True else: post['users'] = True values.update({ 'uid': request.env.user.id, 'user': user, 'main_object': user, 'searches': post, 'questions': user_questions, 'count_questions': count_user_questions, 'answers': user_answers, 'count_answers': count_user_answers, 'followed': followed, 'favourite': favourite, 'up_votes': up_votes, 'down_votes': down_votes, 'activities': activities, 'posts': posts, 'vote_post': vote_ids, }) return request.website.render("website_forum.user_detail_full", values)
def partners(self, country=None, grade=None, page=0, **post): country_all = post.pop('country_all', False) partner_obj = request.registry['res.partner'] country_obj = request.registry['res.country'] search = post.get('search', '') base_partner_domain = [('is_company', '=', True), ('grade_id', '!=', False), ('website_published', '=', True)] if not request.registry['res.users'].has_group( request.cr, request.uid, 'base.group_website_publisher'): base_partner_domain += [('grade_id.website_published', '=', True)] if search: base_partner_domain += [ '|', ('name', 'ilike', search), ('website_description', 'ilike', search) ] # group by grade grade_domain = list(base_partner_domain) if not country and not country_all: country_code = request.session['geoip'].get('country_code') if country_code: country_ids = country_obj.search(request.cr, request.uid, [('code', '=', country_code)], context=request.context) if country_ids: country = country_obj.browse(request.cr, request.uid, country_ids[0], context=request.context) if country: grade_domain += [('country_id', '=', country.id)] grades = partner_obj.read_group(request.cr, SUPERUSER_ID, grade_domain, ["id", "grade_id"], groupby="grade_id", orderby="grade_id DESC", context=request.context) grades_partners = partner_obj.search(request.cr, SUPERUSER_ID, grade_domain, context=request.context, count=True) # flag active grade for grade_dict in grades: grade_dict[ 'active'] = grade and grade_dict['grade_id'][0] == grade.id grades.insert( 0, { 'grade_id_count': grades_partners, 'grade_id': (0, _("All Categories")), 'active': bool(grade is None), }) # group by country country_domain = list(base_partner_domain) if grade: country_domain += [('grade_id', '=', grade.id)] countries = partner_obj.read_group(request.cr, SUPERUSER_ID, country_domain, ["id", "country_id"], groupby="country_id", orderby="country_id", context=request.context) countries_partners = partner_obj.search(request.cr, SUPERUSER_ID, country_domain, context=request.context, count=True) # flag active country for country_dict in countries: country_dict['active'] = country and country_dict[ 'country_id'] and country_dict['country_id'][0] == country.id countries.insert( 0, { 'country_id_count': countries_partners, 'country_id': (0, _("All Countries")), 'active': bool(country is None), }) # current search if grade: base_partner_domain += [('grade_id', '=', grade.id)] if country: base_partner_domain += [('country_id', '=', country.id)] # format pager if grade and not country: url = '/partners/grade/' + slug(grade) elif country and not grade: url = '/partners/country/' + slug(country) elif country and grade: url = '/partners/grade/' + slug(grade) + '/country/' + slug( country) else: url = '/partners' url_args = {} if search: url_args['search'] = search if country_all: url_args['country_all'] = True partner_count = partner_obj.search_count(request.cr, SUPERUSER_ID, base_partner_domain, context=request.context) pager = request.website.pager(url=url, total=partner_count, page=page, step=self._references_per_page, scope=7, url_args=url_args) # search partners matching current search parameters partner_ids = partner_obj.search( request.cr, SUPERUSER_ID, base_partner_domain, order="grade_id DESC", context=request.context ) # todo in trunk: order="grade_id DESC, implemented_count DESC", offset=pager['offset'], limit=self._references_per_page partners = partner_obj.browse(request.cr, SUPERUSER_ID, partner_ids, request.context) # remove me in trunk partners = sorted( partners, key=lambda x: (x.grade_id.sequence if x.grade_id else 0, len([i for i in x.implemented_partner_ids if i.website_published])), reverse=True) partners = partners[pager['offset']:pager['offset'] + self._references_per_page] google_map_partner_ids = ','.join(map(str, [p.id for p in partners])) values = { 'countries': countries, 'current_country': country, 'grades': grades, 'current_grade': grade, 'partners': partners, 'google_map_partner_ids': google_map_partner_ids, 'pager': pager, 'searches': post, 'search_path': "%s" % werkzeug.url_encode(post), } return request.website.render("website_crm_partner_assign.index", values)
def question_close(self, forum, question, **post): question.close(reason_id=int(post.get('reason_id', False))) return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
def _website_url(self, name, arg): res = super(Channel, self)._website_url(name, arg) base_url = self.env['ir.config_parameter'].get_param('web.base.url') res.update({(channel.id, '%s/slides/%s' % (base_url, slug(channel))) for channel in self}) return res
def convert_answer_to_comment(self, forum, post, **kwarg): question = post.parent_id new_msg_id = post.convert_answer_to_comment()[0] if not new_msg_id: return werkzeug.utils.redirect("/forum/%s" % slug(forum)) return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
def convert_comment_to_answer(self, forum, post, comment, **kwarg): post = request.env['forum.post'].convert_comment_to_answer(comment.id) if not post: return werkzeug.utils.redirect("/forum/%s" % slug(forum)) question = post.parent_id if post.parent_id else post return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
def _website_url(self, cr, uid, ids, field_name, arg, context=None): res = super(BlogPost, self)._website_url(cr, uid, ids, field_name, arg, context=context) for blog_post in self.browse(cr, uid, ids, context=context): res[blog_post.id] = "/blog/%s/post/%s" % (slug(blog_post.blog_id), slug(blog_post)) return res
def question_edit_answer(self, forum, question, **kwargs): for record in question.child_ids: if record.create_uid.id == request.uid: answer = record break return werkzeug.utils.redirect("/forum/%s/post/%s/edit" % (slug(forum), slug(answer)))