def confirm_unsubscribe(self, channel, partner_id, token, **kw): subscriber = request.env['mail.channel.partner'].search([('channel_id', '=', channel.id), ('partner_id', '=', partner_id)]) if not subscriber: partner = request.env['res.partner'].browse(partner_id).sudo().exists() # FIXME: remove try/except in master try: response = request.render( 'website_mail_channel.not_subscribed', {'partner_id': partner}) # make sure the rendering (and thus error if template is # missing) happens inside the try block response.flatten() return response except ValueError: return _("The address %s is already unsubscribed or was never subscribed to any mailing list") % ( partner.email ) subscriber_token = channel._generate_action_token(partner_id, action='unsubscribe') if token != subscriber_token: return request.render('website_mail_channel.invalid_token_subscription') # remove partner channel.sudo().write({'channel_partner_ids': [(3, partner_id)]}) return request.render("website_mail_channel.confirmation_subscription", {'subscribing': False})
def view_user_profile(self, user_id, **post): user = self._check_user_profile_access(user_id) if not user: return request.render("website_profile.private_profile") values = self._prepare_user_values(**post) params = self._prepare_user_profile_parameters(**post) values.update(self._prepare_user_profile_values(user, **params)) return request.render("website_profile.user_profile_main", values)
def confirm_subscribe(self, channel, partner_id, token, **kw): subscriber = request.env['mail.channel.partner'].search([('channel_id', '=', channel.id), ('partner_id', '=', partner_id)]) if subscriber: # already registered, maybe clicked twice return request.render('website_mail_channel.invalid_token_subscription') subscriber_token = channel._generate_action_token(partner_id, action='subscribe') if token != subscriber_token: return request.render('website_mail_channel.invalid_token_subscription') # add partner channel.sudo().write({'channel_partner_ids': [(4, partner_id)]}) return request.render("website_mail_channel.confirmation_subscription", {'subscribing': True})
def thread_headers(self, group, page=1, mode='thread', date_begin=None, date_end=None, **post): if group.channel_type != 'channel': raise werkzeug.exceptions.NotFound() Message = request.env['mail.message'] domain = [('model', '=', 'mail.channel'), ('res_id', '=', group.id), ('message_type', '!=', 'notification')] if mode == 'thread': domain += [('parent_id', '=', False)] if date_begin and date_end: domain += [('date', '>=', date_begin), ('date', '<=', date_end)] pager = request.website.pager( url='/groups/%s' % slug(group), total=Message.search_count(domain), page=page, step=self._thread_per_page, url_args={'mode': mode, 'date_begin': date_begin or '', 'date_end': date_end or ''}, ) messages = Message.search(domain, limit=self._thread_per_page, offset=pager['offset']) 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.render('website_mail_channel.group_messages', values)
def forum(self, **kwargs): domain = request.website.website_domain() forums = request.env['forum.forum'].search(domain) if len(forums) == 1: return werkzeug.utils.redirect('/forum/%s' % slug(forums[0]), code=302) return request.render("website_forum.forum_all", {'forums': forums})
def web_auth_reset_password(self, *args, **kw): qcontext = self.get_auth_signup_qcontext() if not qcontext.get('token') and not qcontext.get( 'reset_password_enabled'): raise werkzeug.exceptions.NotFound() if 'error' not in qcontext and request.httprequest.method == 'POST': try: if qcontext.get('token'): self.do_signup(qcontext) return self.web_login(*args, **kw) else: login = qcontext.get('login') assert login, _("No login provided.") _logger.info( "Password reset attempt for <%s> by user <%s> from %s", login, request.env.user.login, request.httprequest.remote_addr) request.env['res.users'].sudo().reset_password(login) qcontext['message'] = _( "An email has been sent with credentials to reset your password" ) except UserError as e: qcontext['error'] = e.name or e.value except SignupError: qcontext['error'] = _("Could not reset your password") _logger.exception('error when resetting password') except Exception as e: qcontext['error'] = str(e) response = request.render('auth_signup.reset_password', qcontext) response.headers['X-Frame-Options'] = 'DENY' return response
def event_agenda(self, event, tag=None, **post): if not event.can_access_from_current_website(): raise NotFound() event = event.with_context(tz=event.date_tz or 'UTC') local_tz = pytz.timezone(event.date_tz or 'UTC') days_tracks = collections.defaultdict(lambda: []) for track in event.track_ids.sorted(lambda track: (bool(track.date), track.date, bool(track.location_id))): if not track.date: continue date = fields.Datetime.from_string(track.date).replace(tzinfo=pytz.utc).astimezone(local_tz) days_tracks[str(date)[:10]].append(track) days = {} tracks_by_days = {} for day, tracks in days_tracks.items(): tracks_by_days[day] = tracks days[day] = self._prepare_calendar(event, tracks) return request.render("website_event_track.agenda", { 'event': event, 'days': days, 'tracks_by_days': tracks_by_days, 'tag': tag })
def event_track_view(self, event, track, **post): if not event.can_access_from_current_website(): raise NotFound() track = track.sudo().with_context(tz=event.date_tz or 'UTC') values = {'track': track, 'event': track.event_id, 'main_object': track} return request.render("website_event_track.track_view", values)
def event_track_proposal_post(self, event, **post): if not event.can_access_from_current_website(): raise NotFound() tags = [] for tag in event.allowed_track_tag_ids: if post.get('tag_' + str(tag.id)): tags.append(tag.id) track = request.env['event.track'].sudo().create({ 'name': post['track_name'], 'partner_name': post['partner_name'], 'partner_email': post['email_from'], 'partner_phone': post['phone'], 'partner_biography': escape(post['biography']), 'event_id': event.id, 'tag_ids': [(6, 0, tags)], 'user_id': False, 'description': escape(post['description']) }) if request.env.user != request.website.user_id: track.sudo().message_subscribe(partner_ids=request.env.user.partner_id.ids) else: partner = request.env['res.partner'].sudo().search([('email', '=', post['email_from'])]) if partner: track.sudo().message_subscribe(partner_ids=partner.ids) return request.render("website_event_track.event_track_proposal_success", {'track': track, 'event': event})
def portal_my_invoice_detail(self, invoice_id, access_token=None, report_type=None, download=False, **kw): try: invoice_sudo = self._document_check_access('account.move', invoice_id, access_token) except (AccessError, MissingError): return request.redirect('/my') if report_type in ('html', 'pdf', 'text'): return self._show_report(model=invoice_sudo, report_type=report_type, report_ref='account.account_invoices', download=download) values = self._invoice_get_page_view_values(invoice_sudo, access_token, **kw) acquirers = values.get('acquirers') if acquirers: country_id = values.get('partner_id') and values.get( 'partner_id')[0].country_id.id values['acq_extra_fees'] = acquirers.get_acquirer_extra_fees( invoice_sudo.amount_residual, invoice_sudo.currency_id, country_id) return request.render("account.portal_invoice_page", values)
def statistics_shorten_url(self, code, **post): code = request.env['link.tracker.code'].search([('code', '=', code)], limit=1) if code: return request.render("website_links.graphs", code.link_id.read()[0]) else: return werkzeug.utils.redirect('', 301)
def survey_report(self, survey, answer_token=None, **post): '''Display survey Results & Statistics for given survey.''' result_template = 'survey.result' current_filters = [] filter_display_data = [] filter_finish = False answers = survey.user_input_ids.filtered( lambda answer: answer.state != 'new' and not answer.test_entry) if 'finished' in post: post.pop('finished') filter_finish = True if post or filter_finish: filter_data = self._get_filter_data(post) current_filters = survey.filter_input_ids(filter_data, filter_finish) filter_display_data = survey.get_filter_display_data(filter_data) return request.render( result_template, { 'survey': survey, 'answers': answers, 'survey_dict': self._prepare_result_dict( survey, current_filters), 'page_range': self.page_range, 'current_filters': current_filters, 'filter_display_data': filter_display_data, 'filter_finish': filter_finish })
def google_map(self, *arg, **post): clean_ids = [] for partner_id in post.get('partner_ids', "").split(","): try: clean_ids.append(int(partner_id)) except ValueError: pass partners = request.env['res.partner'].sudo().search([("id", "in", clean_ids), ('website_published', '=', True), ('is_company', '=', True)]) partner_data = { "counter": len(partners), "partners": [] } for partner in partners.with_context(show_address=True): # TODO in master, do not use `escape` but `t-esc` in the qweb template. partner_data["partners"].append({ 'id': partner.id, 'name': escape(partner.name), 'address': escape('\n'.join(partner.name_get()[0][1].split('\n')[1:])), 'latitude': escape(str(partner.partner_latitude)), 'longitude': escape(str(partner.partner_longitude)), }) if 'customers' in post.get('partner_url', ''): partner_url = '/customers/' else: partner_url = '/partners/' google_maps_api_key = request.website.google_maps_api_key values = { 'partner_url': partner_url, 'partner_data': json.dumps(partner_data), 'google_maps_api_key': google_maps_api_key, } return request.render("website_google_map.google_map", values)
def post_create(self, forum, post_parent=None, **post): if post.get('content', '') == '<p><br></p>': return request.render( 'http_routing.http_error', { 'status_code': _('Bad Request'), 'status_message': post_parent and _('Reply should not be empty.') or _('Question should not be empty.') }) post_tag_ids = forum._tag_to_write_vals(post.get('post_tags', '')) if request.env.user.forum_waiting_posts_count: return werkzeug.utils.redirect("/forum/%s/ask" % slug(forum)) new_question = request.env['forum.post'].create({ 'forum_id': forum.id, 'name': post.get('post_name') or (post_parent and 'Re: %s' % (post_parent.name or '')) or '', 'content': post.get('content', False), 'parent_id': post_parent and post_parent.id or False, 'tag_ids': post_tag_ids }) return werkzeug.utils.redirect( "/forum/%s/question/%s" % (slug(forum), post_parent and slug(post_parent) or new_question.id))
def tags(self, forum, tag_char=None, **post): # build the list of tag first char, with their value as tag_char param Ex : [('All', 'all'), ('C', 'c'), ('G', 'g'), ('Z', z)] first_char_tag = forum.get_tags_first_char() first_char_list = [(t, t.lower()) for t in first_char_tag if t.isalnum()] first_char_list.insert(0, (_('All'), 'all')) active_char_tag = tag_char and tag_char.lower() or 'all' # generate domain for searched tags domain = [('forum_id', '=', forum.id), ('posts_count', '>', 0)] order_by = 'name' if active_char_tag and active_char_tag != 'all': domain.append( ('name', '=ilike', tools.escape_psql(active_char_tag) + '%')) order_by = 'posts_count DESC' tags = request.env['forum.tag'].search(domain, limit=None, order=order_by) # prepare values and render template values = self._prepare_user_values(forum=forum, searches={'tags': True}, **post) values.update({ 'tags': tags, 'pager_tag_chars': first_char_list, 'active_char_tag': active_char_tag, }) return request.render("website_forum.tag", values)
def sale_quotation_builder_template_view(self, template_id, **post): template_id = unslug(template_id)[-1] template = request.env['sale.order.template'].browse(template_id).with_context( allowed_company_ids=request.env.user.company_ids.ids, ) values = {'template': template} return request.render('sale_quotation_builder.so_template', values)
def channel_list(self, **kw): # display the list of the channel channels = request.env['im_livechat.channel'].search([ ('website_published', '=', True) ]) values = {'channels': channels} return request.render('website_livechat.channel_list_page', values)
def jobs_detail(self, job, **kwargs): if not job.can_access_from_current_website(): raise NotFound() return request.render("website_hr_recruitment.detail", { 'job': job, 'main_object': job, })
def portal_my_purchase_order(self, order_id=None, access_token=None, **kw): try: order_sudo = self._document_check_access('purchase.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') values = self._purchase_order_get_page_view_values(order_sudo, access_token, **kw) return request.render("purchase.portal_my_purchase_order", values)
def blacklist_page(self, mailing_id, trace_code, **post): check_res = self._check_trace(mailing_id, trace_code) if not check_res.get('trace'): return werkzeug.utils.redirect('/web') return request.render('mass_mailing_sms.blacklist_main', { 'mailing_id': mailing_id, 'trace_code': trace_code, })
def blacklist_number(self, mailing_id, trace_code, **post): check_res = self._check_trace(mailing_id, trace_code) if not check_res.get('trace'): return werkzeug.utils.redirect('/web') country_code = request.session.get( 'geoip', False) and request.session.geoip.get( 'country_code', False) if request.session.get('geoip') else None # parse and validate number sms_number = post.get('sms_number', '').strip(' ') sanitize_res = phone_validation.phone_sanitize_numbers( [sms_number], country_code, None)[sms_number] tocheck_number = sanitize_res['sanitized'] or sms_number trace = check_res['trace'].filtered( lambda r: r.sms_number == tocheck_number)[:1] mailing_list_ids = trace.mass_mailing_id.contact_list_ids # compute opt-out / blacklist information lists_optout = request.env['mailing.list'].sudo() lists_optin = request.env['mailing.list'].sudo() unsubscribe_error = False if tocheck_number and trace: if mailing_list_ids: subscriptions = request.env[ 'mailing.contact.subscription'].sudo().search([ ('list_id', 'in', mailing_list_ids.ids), ('contact_id.phone_sanitized', '=', tocheck_number), ]) subscriptions.write({'opt_out': True}) lists_optout = subscriptions.mapped('list_id') else: blacklist_rec = request.env['phone.blacklist'].sudo().add( tocheck_number) blacklist_rec._message_log(body=_( 'Blacklist through SMS Marketing unsubscribe (mailing ID: %s - model: %s)' ) % (trace.mass_mailing_id.id, trace.mass_mailing_id.mailing_model_id.display_name)) lists_optin = request.env['mailing.contact.subscription'].sudo( ).search([ ('contact_id.phone_sanitized', '=', tocheck_number), ('list_id', 'not in', mailing_list_ids.ids), ('opt_out', '=', False), ]).mapped('list_id') elif tocheck_number: unsubscribe_error = _('Number %s not found' % tocheck_number) else: unsubscribe_error = sanitize_res['msg'] return request.render( 'mass_mailing_sms.blacklist_number', { 'mailing_id': mailing_id, 'trace_code': trace_code, 'sms_number': sms_number, 'lists_optin': lists_optin, 'lists_optout': lists_optout, 'unsubscribe_error': unsubscribe_error, })
def partners_detail(self, partner_id, **post): _, partner_id = unslug(partner_id) if partner_id: partner = request.env['res.partner'].sudo().browse(partner_id) if partner.exists() and partner.website_published: values = {} values['main_object'] = values['partner'] = partner return request.render("website_customer.details", values) return self.customers(**post)
def survey_start(self, survey_token, answer_token=None, email=False, **post): """ Start a survey by providing * a token linked to a survey; * a token linked to an answer or generate a new token if access is allowed; """ access_data = self._get_access_data(survey_token, answer_token, ensure_token=False) if access_data['validity_code'] is not True: return self._redirect_with_error(access_data, access_data['validity_code']) survey_sudo, answer_sudo = access_data['survey_sudo'], access_data[ 'answer_sudo'] if not answer_sudo: try: answer_sudo = survey_sudo._create_answer(user=request.env.user, email=email) except UserError: answer_sudo = False if not answer_sudo: try: survey_sudo.with_user( request.env.user).check_access_rights('read') survey_sudo.with_user( request.env.user).check_access_rule('read') except: return werkzeug.utils.redirect("/") else: return request.render("survey.403", {'survey': survey_sudo}) # Select the right page if answer_sudo.state == 'new': # Intro page data = {'survey': survey_sudo, 'answer': answer_sudo, 'page': 0} return request.render('survey.survey_init', data) else: return request.redirect( '/survey/fill/%s/%s' % (survey_sudo.access_token, answer_sudo.token))
def _redirect_with_error(self, access_data, error_key): survey_sudo = access_data['survey_sudo'] answer_sudo = access_data['answer_sudo'] if error_key == 'survey_void' and access_data['can_answer']: return request.render("survey.survey_void", { 'survey': survey_sudo, 'answer': answer_sudo }) elif error_key == 'survey_closed' and access_data['can_answer']: return request.render("survey.survey_expired", {'survey': survey_sudo}) elif error_key == 'survey_auth' and answer_sudo.token: if answer_sudo.partner_id and (answer_sudo.partner_id.user_ids or survey_sudo.users_can_signup): if answer_sudo.partner_id.user_ids: answer_sudo.partner_id.signup_cancel() else: answer_sudo.partner_id.signup_prepare( expiration=fields.Datetime.now() + relativedelta(days=1)) redirect_url = answer_sudo.partner_id._get_signup_url_for_action( url='/survey/start/%s?answer_token=%s' % (survey_sudo.access_token, answer_sudo.token))[answer_sudo.partner_id.id] else: redirect_url = '/web/login?redirect=%s' % ( '/survey/start/%s?answer_token=%s' % (survey_sudo.access_token, answer_sudo.token)) return request.render("survey.auth_required", { 'survey': survey_sudo, 'redirect_url': redirect_url }) elif error_key == 'answer_deadline' and answer_sudo.token: return request.render("survey.survey_expired", {'survey': survey_sudo}) elif error_key == 'answer_done' and answer_sudo.token: return request.render( "survey.sfinished", self._prepare_survey_finished_values(survey_sudo, answer_sudo, token=answer_sudo.token)) return werkzeug.utils.redirect("/")
def view_all_users_page(self, page=1, **searches): User = request.env['res.users'] dom = [('karma', '>', 1), ('website_published', '=', True)] # Searches search_term = searches.get('search') if search_term: dom = expression.AND([[ '|', ('name', 'ilike', search_term), ('company_id.name', 'ilike', search_term) ], dom]) user_count = User.sudo().search_count(dom) if user_count: page_count = math.ceil(user_count / self._users_per_page) pager = request.website.pager( url="/profile/users", total=user_count, page=page, step=self._users_per_page, scope=page_count if page_count < self._pager_max_pages else self._pager_max_pages) users = User.sudo().search(dom, limit=self._users_per_page, offset=pager['offset'], order='karma DESC') user_values = self._prepare_all_users_values(users) # Get karma position for users (only website_published) position_domain = [('karma', '>', 1), ('website_published', '=', True)] position_map = self._get_users_karma_position( position_domain, users.ids) for user in user_values: user['position'] = position_map.get(user['id'], 0) values = { 'top3_users': user_values[:3] if not search_term and page == 1 else None, 'users': user_values[3:] if not search_term and page == 1 else user_values, 'pager': pager } else: values = { 'top3_users': [], 'users': [], 'search': search_term, 'pager': dict(page_count=0) } return request.render("website_profile.users_page_main", values)
def loader(self, channel_id, **kwargs): username = kwargs.get("username", _("Visitor")) channel = request.env['im_livechat.channel'].sudo().browse(channel_id) info = channel.get_livechat_info(username=username) return request.render('im_livechat.loader', { 'info': info, 'web_session_required': True }, headers=[('Content-Type', 'application/javascript')])
def partners_detail(self, partner_id, **post): _, partner_id = unslug(partner_id) if partner_id: partner = request.env['res.partner'].sudo().browse(partner_id) if partner.exists( ) and partner.website_published: # TODO should be done with access rules values = {} values['main_object'] = values['partner'] = partner return request.render("website_membership.partner", values) return self.members(**post)
def payment_status_page(self, **kwargs): # When the customer is redirect to this website page, # we retrieve the payment transaction list from his session tx_ids_list = self.get_payment_transaction_ids() payment_transaction_ids = request.env['payment.transaction'].sudo( ).browse(tx_ids_list).exists() render_ctx = { 'payment_tx_ids': payment_transaction_ids.ids, } return request.render("payment.payment_process_page", render_ctx)
def question_ask_for_close(self, forum, question, **post): reasons = request.env['forum.post.reason'].search([('reason_type', '=', 'basic')]) values = self._prepare_user_values(**post) values.update({ 'question': question, 'forum': forum, 'reasons': reasons, }) return request.render("website_forum.close_post", values)
def forum_post(self, forum, **post): user = request.env.user 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_user_values(forum=forum, searches={}, header={'ask_hide': True}, new_question=True) return request.render("website_forum.new_question", values)