Exemple #1
0
    def question(self, forum, question, **post):

        # Hide posts from abusers (negative karma), except for moderators
        if not question.can_view:
            raise werkzeug.exceptions.NotFound()

        # Hide pending posts from non-moderators and non-creator
        user = request.env.user
        if question.state == 'pending' and user.karma < forum.karma_post and question.create_uid != user:
            raise werkzeug.exceptions.NotFound()

        # increment view counter
        question.sudo().set_viewed()
        if question.parent_id:
            redirect_url = "/forum/%s/question/%s" % (slug(forum), slug(question.parent_id))
            return werkzeug.utils.redirect(redirect_url, 301)
        filters = 'question'
        values = self._prepare_forum_values(forum=forum, searches=post)
        values.update({
            'main_object': question,
            'question': question,
            'can_bump': (question.forum_id.allow_bump and not question.child_ids and (datetime.today() - datetime.strptime(question.write_date, tools.DEFAULT_SERVER_DATETIME_FORMAT)).days > 9),
            'header': {'question_data': True},
            'filters': filters,
            'reversed': reversed,
        })
        return request.website.render("website_forum.post_description_full", values)
Exemple #2
0
    def questions(self, forum, tag=None, page=1, filters='all', sorting=None, search='', post_type=None, **post):
        Post = request.env['forum.post']

        domain = [('forum_id', '=', forum.id), ('parent_id', '=', False), ('state', '=', 'active')]
        if search:
            domain += ['|', ('name', 'ilike', search), ('content', 'ilike', search)]
        if tag:
            domain += [('tag_ids', 'in', tag.id)]
        if filters == 'unanswered':
            domain += [('child_ids', '=', False)]
        elif filters == 'followed':
            domain += [('message_partner_ids', '=', request.env.user.partner_id.id)]
        if post_type:
            domain += [('post_type', '=', post_type)]

        if sorting:
            # check that sorting is valid
            # retro-compatibily for V8 and google links
            try:
                Post._generate_order_by(sorting, None)
            except ValueError:
                sorting = False

        if not sorting:
            sorting = forum.default_order

        question_count = Post.search_count(domain)

        if tag:
            url = "/forum/%s/tag/%s/questions" % (slug(forum), slug(tag))
        else:
            url = "/forum/%s" % slug(forum)

        url_args = {
            'sorting': sorting
        }
        if search:
            url_args['search'] = search
        if filters:
            url_args['filters'] = filters
        pager = request.website.pager(url=url, total=question_count, page=page,
                                      step=self._post_per_page, scope=self._post_per_page,
                                      url_args=url_args)

        question_ids = Post.search(domain, limit=self._post_per_page, offset=pager['offset'], order=sorting)

        values = self._prepare_forum_values(forum=forum, searches=post)
        values.update({
            'main_object': tag or forum,
            'question_ids': question_ids,
            'question_count': question_count,
            'pager': pager,
            'tag': tag,
            'filters': filters,
            'sorting': sorting,
            'search': search,
            'post_type': post_type,
        })
        return request.website.render("website_forum.forum_index", values)
Exemple #3
0
 def post_mark_as_offensive(self, forum, post, **kwargs):
     post.mark_as_offensive(reason_id=int(kwargs.get('reason_id', False)))
     url = ''
     if post.parent_id:
         url = "/forum/%s/question/%s/#answer-%s" % (slug(forum), post.parent_id.id, post.id)
     else:
         url = "/forum/%s/question/%s" % (slug(forum), slug(post))
     return werkzeug.utils.redirect(url)
Exemple #4
0
 def _website_url(self, field_name, arg):
     res = super(event_track, self)._website_url(field_name, arg)
     res.update({
         (track.id,
          '/event/%s/track/%s' % (slug(track.event_id), slug(track)))
         for track in self
     })
     return res
Exemple #5
0
 def post_accept(self, forum, post):
     url = "/forum/%s/validation_queue" % (slug(forum))
     if post.state == 'flagged':
         url = "/forum/%s/flagged_queue" % (slug(forum))
     elif post.state == 'offensive':
         url = "/forum/%s/offensive_posts" % (slug(forum))
     post.validate()
     return werkzeug.utils.redirect(url)
Exemple #6
0
 def post_comment(self, forum, post, **kwargs):
     question = post.parent_id if post.parent_id else post
     if kwargs.get('comment') and post.forum_id.id == forum.id:
         # TDE FIXME: check that post_id is the question or one of its answers
         post.with_context(mail_create_nosubscribe=True).message_post(
             body=kwargs.get('comment'),
             message_type='comment',
             subtype='mt_comment')
     return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
Exemple #7
0
 def forum_create(self, forum_name="New Forum", add_menu=False):
     forum_id = request.env['forum.forum'].create({'name': forum_name})
     if add_menu:
         request.env['website.menu'].create({
             'name': forum_name,
             'url': "/forum/%s" % slug(forum_id),
             'parent_id': request.website.menu_id.id,
             'website_id': request.website.id,
         })
     return request.redirect("/forum/%s" % slug(forum_id))
Exemple #8
0
 def _get_new_menu_pages(self):
     result = super(event_event, self)._get_new_menu_pages()[0]  # TDE CHECK api.one -> returns a list with one item ?
     if self.show_tracks:
         result.append((_('Talks'), '/event/%s/track' % slug(self)))
         result.append((_('Agenda'), '/event/%s/agenda' % slug(self)))
     if self.blog_id:
         result.append((_('News'), '/blogpost'+slug(self.blog_ig)))
     if self.show_track_proposal:
         result.append((_('Talk Proposals'), '/event/%s/track_proposal' % slug(self)))
     return result
Exemple #9
0
 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
Exemple #10
0
 def _get_new_menu_pages(self):
     result = super(event_event, self)._get_new_menu_pages()[
         0]  # TDE CHECK api.one -> returns a list with one item ?
     if self.show_tracks:
         result.append((_('Talks'), '/event/%s/track' % slug(self)))
         result.append((_('Agenda'), '/event/%s/agenda' % slug(self)))
     if self.blog_id:
         result.append((_('News'), '/blogpost' + slug(self.blog_ig)))
     if self.show_track_proposal:
         result.append(
             (_('Talk Proposals'), '/event/%s/track_proposal' % slug(self)))
     return result
Exemple #11
0
 def post_save(self, forum, post, **kwargs):
     if 'post_name' in kwargs and not kwargs.get('post_name').strip():
         return request.website.render('website.http_error', {'status_code': _('Bad Request'), 'status_message': _('Title should not be empty.')})
     post_tags = forum._tag_to_write_vals(kwargs.get('post_tags', ''))
     vals = {
         'tag_ids': post_tags,
         'name': kwargs.get('post_name'),
         'content': kwargs.get('content'),
         'content_link': kwargs.get('content_link'),
     }
     post.write(vals)
     question = post.parent_id if post.parent_id else post
     return werkzeug.utils.redirect("/forum/%s/question/%s" % (slug(forum), slug(question)))
Exemple #12
0
 def _get_new_menu_pages(self):
     todo = [
         (_('Introduction'), 'website_event.template_intro'),
         (_('Location'), 'website_event.template_location')
     ]
     result = []
     for name, path in todo:
         complete_name = name + ' ' + self.name
         newpath = self.env['website'].new_page(complete_name, path, ispage=False)
         url = "/event/" + slug(self) + "/page/" + newpath
         result.append((name, url))
     result.append((_('Register'), '/event/%s/register' % slug(self)))
     return result
Exemple #13
0
 def _check_for_publication(self, cr, uid, ids, vals, context=None):
     if vals.get('website_published'):
         base_url = self.pool['ir.config_parameter'].get_param(cr, uid, 'web.base.url')
         for post in self.browse(cr, uid, ids, context=context):
             post.blog_id.message_post(
                 body='<p>%(post_publication)s <a href="%(base_url)s/blog/%(blog_slug)s/post/%(post_slug)s">%(post_link)s</a></p>' % {
                     'post_publication': _('A new post %s has been published on the %s blog.') % (post.name, post.blog_id.name),
                     'post_link': _('Click here to access the post.'),
                     'base_url': base_url,
                     'blog_slug': slug(post.blog_id),
                     'post_slug': slug(post),
                 },
                 subtype='website_blog.mt_blog_blog_published')
         return True
     return False
Exemple #14
0
    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.")
Exemple #15
0
 def _website_url(self, name, arg):
     res = super(Slide, self)._website_url(name, arg)
     base_url = self.env['ir.config_parameter'].get_param('web.base.url')
     #link_tracker is not in dependencies, so use it to shorten url only if installed.
     if self.env.registry.get('link.tracker'):
         LinkTracker = self.env['link.tracker']
         res.update({(slide.id, LinkTracker.sudo().create({
             'url':
             '%s/slides/slide/%s' % (base_url, slug(slide))
         }).short_url)
                     for slide in self})
     else:
         res.update({(slide.id,
                      '%s/slides/slide/%s' % (base_url, slug(slide)))
                     for slide in self})
     return res
Exemple #16
0
 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,
             '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)))
Exemple #17
0
 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
Exemple #18
0
    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)
Exemple #19
0
 def forum_post(self, forum, post_type=None, **post):
     user = request.env.user
     if post_type not in ['question', 'link', 'discussion']:  # fixme: make dynamic
         return werkzeug.utils.redirect('/forum/%s' % slug(forum))
     if not user.email or not tools.single_email_re.match(user.email):
         return werkzeug.utils.redirect("/forum/%s/user/%s/edit?email_required=1" % (slug(forum), request.session.uid))
     values = self._prepare_forum_values(forum=forum, searches={}, header={'ask_hide': True})
     return request.website.render("website_forum.new_%s" % post_type, values)
Exemple #20
0
 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,
         '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)))
Exemple #21
0
    def add_product(self, name=None, category=0, **post):
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
        if not name:
            name = _("New Product")
        product_obj = request.registry.get('product.product')
        product_id = product_obj.create(cr, uid, { 'name': name, 'public_categ_ids': category }, context=context)
        product = product_obj.browse(cr, uid, product_id, context=context)

        return request.redirect("/shop/product/%s?enable_editor=1" % slug(product.product_tmpl_id))
Exemple #22
0
 def _website_url(self, name, arg):
     res = super(Slide, self)._website_url(name, arg)
     base_url = self.env['ir.config_parameter'].get_param('web.base.url')
     #link_tracker is not in dependencies, so use it to shorten url only if installed.
     if self.env.registry.get('link.tracker'):
         LinkTracker = self.env['link.tracker']
         res.update({(slide.id, LinkTracker.sudo().create({'url': '%s/slides/slide/%s' % (base_url, slug(slide))}).short_url) for slide in self})
     else:
         res.update({(slide.id, '%s/slides/slide/%s' % (base_url, slug(slide))) for slide in self})
     return res
Exemple #23
0
 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
Exemple #24
0
 def _website_url(self, cr, uid, ids, field_name, arg, context=None):
     res = super(WebsiteResPartner, self)._website_url(cr,
                                                       uid,
                                                       ids,
                                                       field_name,
                                                       arg,
                                                       context=context)
     for partner in self.browse(cr, uid, ids, context=context):
         res[partner.id] = "/partners/%s" % slug(partner)
     return res
Exemple #25
0
    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)))
Exemple #26
0
 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
Exemple #27
0
 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))
Exemple #28
0
    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)))
Exemple #29
0
 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))
Exemple #30
0
 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))
Exemple #31
0
    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)
Exemple #32
0
 def _check_for_publication(self, cr, uid, ids, vals, context=None):
     if vals.get('website_published'):
         base_url = self.pool['ir.config_parameter'].get_param(
             cr, uid, 'web.base.url')
         for post in self.browse(cr, uid, ids, context=context):
             post.blog_id.message_post(
                 body=
                 '<p>%(post_publication)s <a href="%(base_url)s/blog/%(blog_slug)s/post/%(post_slug)s">%(post_link)s</a></p>'
                 % {
                     'post_publication':
                     _('A new post %s has been published on the %s blog.') %
                     (post.name, post.blog_id.name),
                     'post_link':
                     _('Click here to access the post.'),
                     'base_url':
                     base_url,
                     'blog_slug':
                     slug(post.blog_id),
                     'post_slug':
                     slug(post),
                 },
                 subtype='website_blog.mt_blog_blog_published')
         return True
     return False
Exemple #33
0
 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
Exemple #34
0
    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)
Exemple #35
0
 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
Exemple #36
0
 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
Exemple #37
0
    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.")
Exemple #38
0
 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
Exemple #39
0
 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
Exemple #40
0
 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
Exemple #41
0
    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)
Exemple #42
0
 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
Exemple #43
0
 def _website_url(self, cr, uid, ids, field_name, arg, context=None):
     res = super(WebsiteResPartner, self)._website_url(cr, uid, ids, field_name, arg, context=context)
     for partner in self.browse(cr, uid, ids, context=context):
         res[partner.id] = "/partners/%s" % slug(partner)
     return res
Exemple #44
0
 def _website_url(self, field_name, arg):
     res = super(event_track, self)._website_url(field_name, arg)
     res.update({(track.id, '/event/%s/track/%s' % (slug(track.event_id), slug(track))) for track in self})
     return res
Exemple #45
0
    def shop(self, page=0, category=None, search='', ppg=False, **post):
        cr, uid, context, pool = request.cr, request.uid, request.context, request.registry

        if ppg:
            try:
                ppg = int(ppg)
            except ValueError:
                ppg = PPG
            post["ppg"] = ppg
        else:
            ppg = PPG

        attrib_list = request.httprequest.args.getlist('attrib')
        attrib_values = [map(int, v.split("-")) for v in attrib_list if v]
        attributes_ids = set([v[0] for v in attrib_values])
        attrib_set = set([v[1] for v in attrib_values])

        domain = self._get_search_domain(search, category, attrib_values)

        keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list)

        if not context.get('pricelist'):
            pricelist = self.get_pricelist()
            context['pricelist'] = int(pricelist)
        else:
            pricelist = pool.get('product.pricelist').browse(cr, uid, context['pricelist'], context)
        url = "/shop"
        if search:
            post["search"] = search
        if category:
            category = pool['product.public.category'].browse(cr, uid, int(category), context=context)
            url = "/shop/category/%s" % slug(category)
        if attrib_list:
            post['attrib'] = attrib_list

        style_obj = pool['product.style']
        style_ids = style_obj.search(cr, uid, [], context=context)
        styles = style_obj.browse(cr, uid, style_ids, context=context)

        category_obj = pool['product.public.category']
        category_ids = category_obj.search(cr, uid, [('parent_id', '=', False)], context=context)
        categs = category_obj.browse(cr, uid, category_ids, context=context)

        product_obj = pool.get('product.template')

        parent_category_ids = []
        if category:
            parent_category_ids = [category.id]
            current_category = category
            while current_category.parent_id:
                parent_category_ids.append(current_category.parent_id.id)
                current_category = current_category.parent_id

        product_count = product_obj.search_count(cr, uid, domain, context=context)
        pager = request.website.pager(url=url, total=product_count, page=page, step=ppg, scope=7, url_args=post)
        product_ids = product_obj.search(cr, uid, domain, limit=ppg, offset=pager['offset'], order='website_published desc, website_sequence desc', context=context)
        products = product_obj.browse(cr, uid, product_ids, context=context)

        attributes_obj = request.registry['product.attribute']
        if product_ids:
            attributes_ids = attributes_obj.search(cr, uid, [('attribute_line_ids.product_tmpl_id', 'in', product_ids)], context=context)
        attributes = attributes_obj.browse(cr, uid, attributes_ids, context=context)

        from_currency = pool['res.users'].browse(cr, uid, uid, context=context).company_id.currency_id
        to_currency = pricelist.currency_id
        compute_currency = lambda price: pool['res.currency']._compute(cr, uid, from_currency, to_currency, price, context=context)

        values = {
            'search': search,
            'category': category,
            'attrib_values': attrib_values,
            'attrib_set': attrib_set,
            'pager': pager,
            'pricelist': pricelist,
            'products': products,
            'bins': table_compute().process(products, ppg),
            'rows': PPR,
            'styles': styles,
            'categories': categs,
            'attributes': attributes,
            'compute_currency': compute_currency,
            'keep': keep,
            'parent_category_ids': parent_category_ids,
            'style_in_product': lambda style, product: style.id in [s.id for s in product.website_style_ids],
            'attrib_encode': lambda attribs: werkzeug.url_encode([('attrib',i) for i in attribs]),
        }
        if category:
            values['main_object'] = category
        return request.website.render("website_sale.products", values)
Exemple #46
0
 def registration_new(self, event, **post):
     tickets = self._process_tickets_details(post)
     if not tickets:
         return request.redirect("/event/%s" % slug(event))
     return request.website._render("website_event.registration_attendee_details", {'tickets': tickets, 'event': event})
Exemple #47
0
 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
Exemple #48
0
    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)
Exemple #49
0
 def to_url(self, value):
     return slug(value)
Exemple #50
0
 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
Exemple #51
0
    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
Exemple #52
0
 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))