summaryrefslogtreecommitdiff
path: root/addons/website_mail_channel/controllers/main.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/website_mail_channel/controllers/main.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/website_mail_channel/controllers/main.py')
-rw-r--r--addons/website_mail_channel/controllers/main.py268
1 files changed, 268 insertions, 0 deletions
diff --git a/addons/website_mail_channel/controllers/main.py b/addons/website_mail_channel/controllers/main.py
new file mode 100644
index 00000000..bed34aa2
--- /dev/null
+++ b/addons/website_mail_channel/controllers/main.py
@@ -0,0 +1,268 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import werkzeug
+
+from datetime import datetime
+from dateutil import relativedelta
+
+from odoo import http, fields, tools, _
+from odoo.http import request
+from odoo.addons.http_routing.models.ir_http import slug
+
+
+class MailGroup(http.Controller):
+ _thread_per_page = 20
+ _replies_per_page = 10
+
+ def _get_archives(self, group_id):
+ MailMessage = request.env['mail.message']
+ # use sudo to avoid side-effects due to custom ACLs
+ groups = MailMessage.sudo()._read_group_raw(
+ [('model', '=', 'mail.channel'), ('res_id', '=', group_id), ('message_type', '!=', 'notification')],
+ ['subject', 'date'],
+ groupby=["date"], orderby="date desc")
+ for group in groups:
+ (r, label) = group['date']
+ start, end = r.split('/')
+ group['date'] = label
+ group['date_begin'] = self._to_date(start)
+ group['date_end'] = self._to_date(end)
+ return groups
+
+ def _to_date(self, dt):
+ """ date is (of course) a datetime so start and end are datetime
+ strings, but we just want date strings
+ """
+ return (datetime
+ .strptime(dt, tools.DEFAULT_SERVER_DATETIME_FORMAT)
+ .date() # may be unnecessary?
+ .strftime(tools.DEFAULT_SERVER_DATE_FORMAT))
+
+ @http.route("/groups", type='http', auth="public", website=True, sitemap=True)
+ def view(self, **post):
+ groups = request.env['mail.channel'].search([('alias_id.alias_name', '!=', False)])
+
+ # compute statistics
+ month_date = datetime.today() - relativedelta.relativedelta(months=1)
+ # use sudo to avoid side-effects due to custom ACLs
+ messages = request.env['mail.message'].sudo().read_group([
+ ('model', '=', 'mail.channel'),
+ ('date', '>=', fields.Datetime.to_string(month_date)),
+ ('message_type', '!=', 'notification'),
+ ('res_id', 'in', groups.ids),
+ ], ['res_id'], ['res_id'])
+ message_data = dict((message['res_id'], message['res_id_count']) for message in messages)
+
+ group_data = dict(
+ (group.id, {'monthly_message_nbr': message_data.get(group.id, 0),
+ 'members_count': len(group.channel_partner_ids)})
+ for group in groups.sudo())
+ return request.render('website_mail_channel.mail_channels', {'groups': groups, 'group_data': group_data})
+
+ @http.route(["/groups/is_member"], type='json', auth="public", website=True)
+ def is_member(self, channel_id=0, **kw):
+ """ Determine if the current user is member of the given channel_id
+ :param channel_id : the channel_id to check
+ """
+ current_user = request.env.user
+ session_partner_id = request.session.get('partner_id')
+ public_user = request.website.user_id
+ partner = None
+ # find the current partner
+ if current_user != public_user:
+ partner = current_user.partner_id
+ elif session_partner_id:
+ partner = request.env['res.partner'].sudo().browse(session_partner_id)
+
+ values = {
+ 'is_user': current_user != public_user,
+ 'email': partner.email if partner else "",
+ 'is_member': False,
+ 'alias_name': False,
+ }
+ # check if the current partner is member or not
+ channel = request.env['mail.channel'].browse(int(channel_id))
+ if channel.exists() and partner is not None:
+ values['is_member'] = bool(partner in channel.sudo().channel_partner_ids)
+ return values
+
+ @http.route(["/groups/subscription"], type='json', auth="public", website=True)
+ def subscription(self, channel_id=0, subscription="on", email='', **kw):
+ """ Subscribe to a mailing list : this will create a partner with its email address (if public user not
+ registered yet) and add it as channel member
+ :param channel_id : the channel id to join/quit
+ :param subscription : 'on' to unsubscribe the user, 'off' to subscribe
+ """
+ unsubscribe = subscription == 'on'
+ channel = request.env['mail.channel'].browse(int(channel_id))
+ if not channel.exists():
+ return False
+
+ partner_ids = []
+
+ # search partner_id
+ if request.env.user != request.website.user_id:
+ # connected users are directly (un)subscribed
+ partner_ids = request.env.user.partner_id.ids
+
+ # add or remove channel members
+ if unsubscribe:
+ channel.check_access_rule('read')
+ channel.sudo().write({'channel_partner_ids': [(3, partner_id) for partner_id in partner_ids]})
+ return "off"
+ else: # add partner to the channel
+ request.session['partner_id'] = partner_ids[0]
+ channel.check_access_rule('read')
+ channel.sudo().write({'channel_partner_ids': [(4, partner_id) for partner_id in partner_ids]})
+ return "on"
+
+ else:
+ # public users will recieve confirmation email
+ partner_ids = [p.id for p in request.env['mail.thread'].sudo()._mail_find_partner_from_emails([email], records=channel.sudo()) if p]
+ if not partner_ids or not partner_ids[0]:
+ name = email.split('@')[0]
+ partner_ids = [request.env['res.partner'].sudo().create({'name': name, 'email': email}).id]
+
+ channel.sudo()._send_confirmation_email(partner_ids, unsubscribe)
+ return "email"
+
+ @http.route([
+ '''/groups/<model('mail.channel', "[('channel_type', '=', 'channel')]"):group>''',
+ '''/groups/<model('mail.channel'):group>/page/<int:page>'''
+ ], type='http', auth="public", website=True, sitemap=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)
+
+ @http.route([
+ '''/groups/<model('mail.channel', "[('channel_type', '=', 'channel')]"):group>/<model('mail.message', "[('model','=','mail.channel'), ('res_id','=',group.id)]"):message>''',
+ ], type='http', auth="public", website=True, sitemap=True)
+ def thread_discussion(self, group, message, mode='thread', date_begin=None, date_end=None, **post):
+ if group.channel_type != 'channel':
+ raise werkzeug.exceptions.NotFound()
+
+ Message = request.env['mail.message']
+ if mode == 'thread':
+ base_domain = [('model', '=', 'mail.channel'), ('res_id', '=', group.id), ('parent_id', '=', message.parent_id and message.parent_id.id or False)]
+ else:
+ base_domain = [('model', '=', 'mail.channel'), ('res_id', '=', group.id)]
+ next_message = Message.search(base_domain + [('date', '<', message.date)], order="date DESC", limit=1) or None
+ prev_message = Message.search(base_domain + [('date', '>', message.date)], order="date", limit=1) or None
+ values = {
+ 'message': message,
+ 'group': group,
+ 'mode': mode,
+ 'archives': self._get_archives(group.id),
+ 'date_begin': date_begin,
+ 'date_end': date_end,
+ 'replies_per_page': self._replies_per_page,
+ 'next_message': next_message,
+ 'prev_message': prev_message,
+ }
+ return request.render('website_mail_channel.group_message', values)
+
+ @http.route(
+ '''/groups/<model('mail.channel', "[('channel_type', '=', 'channel')]"):group>/<model('mail.message', "[('model','=','mail.channel'), ('res_id','=',group.id)]"):message>/get_replies''',
+ type='json', auth="public", methods=['POST'], website=True)
+ def render_messages(self, group, message, **post):
+ if group.channel_type != 'channel':
+ return False
+
+ last_displayed_id = post.get('last_displayed_id')
+ if not last_displayed_id:
+ return False
+
+ replies_domain = [('id', '<', int(last_displayed_id)), ('parent_id', '=', message.id)]
+ messages = request.env['mail.message'].search(replies_domain, limit=self._replies_per_page)
+ message_count = request.env['mail.message'].search_count(replies_domain)
+ values = {
+ 'group': group,
+ 'thread_header': message,
+ 'messages': messages,
+ 'msg_more_count': message_count - self._replies_per_page,
+ 'replies_per_page': self._replies_per_page,
+ }
+ return request.env.ref('website_mail_channel.messages_short')._render(values, engine='ir.qweb')
+
+ @http.route("/groups/<int:group_id>/get_alias_info", type='json', auth='public', website=True)
+ def get_alias_info(self, group_id, **post):
+ group = request.env['mail.channel'].search([('id', '=', group_id)])
+ if not group: # doesn't exist or doesn't have the right to access it
+ return {}
+
+ return {
+ 'alias_name': group.alias_id and group.alias_id.alias_name and group.alias_id.alias_domain and '%s@%s' % (group.alias_id.alias_name, group.alias_id.alias_domain) or False
+ }
+
+ @http.route("/groups/subscribe/<model('mail.channel'):channel>/<int:partner_id>/<string:token>", type='http', auth='public', website=True)
+ 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})
+
+ @http.route("/groups/unsubscribe/<model('mail.channel'):channel>/<int:partner_id>/<string:token>", type='http', auth='public', website=True)
+ 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})