diff --git a/addons/website_mail_channel/__init__.py b/addons/website_mail_channel/__init__.py deleted file mode 100644 index bb0aae7ee63..00000000000 --- a/addons/website_mail_channel/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import controllers -from . import models diff --git a/addons/website_mail_channel/__manifest__.py b/addons/website_mail_channel/__manifest__.py deleted file mode 100644 index 76f45a70f08..00000000000 --- a/addons/website_mail_channel/__manifest__.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. -{ - 'name': 'Website Mail Channels', - 'category': 'Website/Website', - 'summary': 'Allow visitors to join public mail channels', - 'description': """ -Visitors can join public mail channels managed in the Discuss app in order to get regular updates or reach out with your community. - """, - 'depends': ['website_mail'], - 'data': [ - 'data/mail_template_data.xml', - 'views/snippets/s_channel.xml', - 'views/snippets/snippets.xml', - 'views/website_mail_channel_templates.xml', - ], - 'assets': { - 'web.assets_frontend': [ - 'website_mail_channel/static/src/css/website_mail_channel.css', - 'website_mail_channel/static/src/js/website_mail_channel.js', - ], - 'website.assets_wysiwyg': [ - 'website_mail_channel/static/src/snippets/s_channel/options.js', - ], - } -} diff --git a/addons/website_mail_channel/controllers/__init__.py b/addons/website_mail_channel/controllers/__init__.py deleted file mode 100644 index 7fc0cd7cb93..00000000000 --- a/addons/website_mail_channel/controllers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import main diff --git a/addons/website_mail_channel/controllers/main.py b/addons/website_mail_channel/controllers/main.py deleted file mode 100644 index 0237ef4dc1d..00000000000 --- a/addons/website_mail_channel/controllers/main.py +++ /dev/null @@ -1,279 +0,0 @@ -# -*- 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/''', - '''/groups//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//', message.date)], order="date", limit=1) or None - - # handle access to attachments for public / portal - if request.env.user.has_group('base.group_user'): - attachments = message.attachment_ids - else: - # portal / external people cannot access attachments -> grant access - # as message is ok, generate access tokens - attachments = message.sudo().attachment_ids - attachments.generate_access_token() - - values = { - 'message': message, - 'attachments': attachments, - '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///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///", 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///", 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}) diff --git a/addons/website_mail_channel/data/mail_template_data.xml b/addons/website_mail_channel/data/mail_template_data.xml deleted file mode 100644 index 88fc73cb9f6..00000000000 --- a/addons/website_mail_channel/data/mail_template_data.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - Channel: Mailing list subscription - - Confirm subscription to ${object.name} - -
- Hello,

- You have requested to be subscribed to the mailing list ${object.name}. -

- To confirm, please visit the following link: ${ctx['token_url']} -

- If this was a mistake or you did not requested this action, please ignore this message. - % if user.signature -
- ${user.signature | safe} - % endif -
- -
- - - Channel: Mailing list unsubscription - - Confirm unsubscription to ${object.name} - -
- Hello,

- You have requested to be unsubscribed to the mailing list ${object.name}. -

- To confirm, please visit the following link: ${ctx['token_url']}. -

- If this was a mistake or you did not requested this action, please ignore this message. - % if user.signature: -
- ${user.signature | safe} - % endif -
- -
-
- -
diff --git a/addons/website_mail_channel/models/__init__.py b/addons/website_mail_channel/models/__init__.py deleted file mode 100644 index f5c2bbb5e3c..00000000000 --- a/addons/website_mail_channel/models/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. -from . import mail_channel -from . import mail_mail -from . import website diff --git a/addons/website_mail_channel/models/mail_channel.py b/addons/website_mail_channel/models/mail_channel.py deleted file mode 100644 index 3cae5bd50c8..00000000000 --- a/addons/website_mail_channel/models/mail_channel.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from werkzeug import urls - -from odoo import models, tools -from odoo.addons.http_routing.models.ir_http import slug - - -class MailGroup(models.Model): - _inherit = 'mail.channel' - - def _notify_email_header_dict(self): - headers = super(MailGroup, self)._notify_email_header_dict() - base_url = self.get_base_url() - headers['List-Archive'] = '<%s/groups/%s>' % (base_url, slug(self)) - headers['List-Subscribe'] = '<%s/groups>' % (base_url) - headers['List-Unsubscribe'] = '<%s/groups?unsubscribe>' % (base_url,) - return headers - - def _send_confirmation_email(self, partner_ids, unsubscribe=False): - website = self.env['website'].get_current_website() - base_url = website.get_base_url() - - route = "/groups/%(action)s/%(channel)s/%(partner)s/%(token)s" - if unsubscribe: - template = self.env.ref('website_mail_channel.mail_template_list_unsubscribe') - action = 'unsubscribe' - else: - template = self.env.ref('website_mail_channel.mail_template_list_subscribe') - action = 'subscribe' - - for partner_id in partner_ids: - # generate a new token per subscriber - token = self._generate_action_token(partner_id, action=action) - - token_url = urls.url_join(base_url, route % { - 'action': action, - 'channel': self.id, - 'partner': partner_id, - 'token': token, - }) - template.with_context(token_url=token_url).send_mail( - self.id, - force_send=True, - email_values={ - 'recipient_ids': [(4, partner_id)], - 'email_from': website.company_id.email_formatted, - 'author_id': self.create_uid.partner_id.id, - 'message_type': 'user_notification', - }, - notif_layout='mail.mail_notification_light', - ) - - return True - - def _generate_action_token(self, partner_id, action='unsubscribe'): - self.ensure_one() - data = '$'.join([ - str(self.id), - str(partner_id), - action]) - return tools.hmac(self.env(su=True), 'website_mail_channel-email-subscription', data) diff --git a/addons/website_mail_channel/models/mail_mail.py b/addons/website_mail_channel/models/mail_mail.py deleted file mode 100644 index b8a157a133a..00000000000 --- a/addons/website_mail_channel/models/mail_mail.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import api, models, tools, _ -from odoo.addons.http_routing.models.ir_http import slug - - -class MailMail(models.Model): - _inherit = 'mail.mail' - - def _send_prepare_body(self): - """ Short-circuit parent method for mail groups, replace the default - footer with one appropriate for mailing-lists.""" - if self.model == 'mail.channel' and self.res_id: - # no super() call on purpose, no private links that could be quoted! - channel = self.env['mail.channel'].browse(self.res_id) - base_url = channel.get_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(self.body, footer, container_tag='div') - return body - else: - return super(MailMail, self)._send_prepare_body() diff --git a/addons/website_mail_channel/models/website.py b/addons/website_mail_channel/models/website.py deleted file mode 100644 index 854e99bdbe8..00000000000 --- a/addons/website_mail_channel/models/website.py +++ /dev/null @@ -1,14 +0,0 @@ -# -*- coding: utf-8 -*- -# Part of Odoo. See LICENSE file for full copyright and licensing details. - -from odoo import models, _ -from odoo.addons.http_routing.models.ir_http import url_for - - -class Website(models.Model): - _inherit = "website" - - def get_suggested_controllers(self): - suggested_controllers = super(Website, self).get_suggested_controllers() - suggested_controllers.append((_('Mailing Lists'), url_for('/groups'), 'website_mail_channel')) - return suggested_controllers diff --git a/addons/website_mail_channel/static/description/icon.png b/addons/website_mail_channel/static/description/icon.png deleted file mode 100644 index 2c737fbe1d4..00000000000 Binary files a/addons/website_mail_channel/static/description/icon.png and /dev/null differ diff --git a/addons/website_mail_channel/static/description/icon.svg b/addons/website_mail_channel/static/description/icon.svg deleted file mode 100644 index 779be8054e2..00000000000 --- a/addons/website_mail_channel/static/description/icon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/addons/website_mail_channel/static/src/css/website_mail_channel.css b/addons/website_mail_channel/static/src/css/website_mail_channel.css deleted file mode 100644 index 2365860f8fb..00000000000 --- a/addons/website_mail_channel/static/src/css/website_mail_channel.css +++ /dev/null @@ -1,7 +0,0 @@ -.o_mg_link_show { - display: none; -} - -.o_mg_link_content { - display: none; -} diff --git a/addons/website_mail_channel/static/src/js/website_mail_channel.js b/addons/website_mail_channel/static/src/js/website_mail_channel.js deleted file mode 100644 index 30928d781dc..00000000000 --- a/addons/website_mail_channel/static/src/js/website_mail_channel.js +++ /dev/null @@ -1,71 +0,0 @@ -odoo.define('website_mail_channel', function (require) { -'use strict'; - -var publicWidget = require('web.public.widget'); - -publicWidget.registry.websiteMailChannel = publicWidget.Widget.extend({ - selector: '#wrapwrap', - events: { - 'click .o_mg_link_hide': '_onHideLinkClick', - 'click .o_mg_link_show': '_onShowLinkClick', - 'click button.o_mg_read_more': '_onReadMoreClick', - }, - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * @private - * @param {Event} ev - */ - _onHideLinkClick: function (ev) { - ev.preventDefault(); - ev.stopPropagation(); - var $link = $(ev.currentTarget); - var $container = $link.parents('div').first(); - $container.find('.o_mg_link_hide').first().hide(); - $container.find('.o_mg_link_show').first().show(); - $container.find('.o_mg_link_content').first().show(); - }, - /** - * @private - * @param {Event} ev - */ - _onShowLinkClick: function (ev) { - ev.preventDefault(); - ev.stopPropagation(); - var $link = $(ev.currentTarget); - var $container = $link.parents('div').first(); - $container.find('.o_mg_link_hide').first().show(); - $container.find('.o_mg_link_show').first().hide(); - $container.find('.o_mg_link_content').first().hide(); - }, - /** - * @private - * @param {Event} ev - */ - _onReadMoreClick: function (ev) { - var $link = $(ev.target); - this._rpc({ - route: $link.data('href'), - params: { - last_displayed_id: $link.data('msg-id'), - }, - }).then(function (data) { - if (!data) { - return; - } - var $threadContainer = $link.parents('.o_mg_replies').first().find('ul.list-unstyled'); - if ($threadContainer) { - var $lastMsg = $threadContainer.find('li.media').last(); - $(data).find('li.media').insertAfter($lastMsg); - $(data).find('.o_mg_read_more').parent().appendTo($threadContainer); - } - var $showMore = $link.parent(); - $showMore.remove(); - return; - }); - }, -}); -}); diff --git a/addons/website_mail_channel/static/src/snippets/s_channel/000.js b/addons/website_mail_channel/static/src/snippets/s_channel/000.js deleted file mode 100644 index afcd22c638e..00000000000 --- a/addons/website_mail_channel/static/src/snippets/s_channel/000.js +++ /dev/null @@ -1,148 +0,0 @@ -odoo.define('website_mail_channel.s_channel', function (require) { -'use strict'; - -var publicWidget = require('web.public.widget'); - -publicWidget.registry.Channel = publicWidget.Widget.extend({ - selector: '.s_channel', - disabledInEditableMode: false, - read_events: { - 'click .js_follow_btn, .js_unfollow_btn': '_onFollowUnFollowBtnClick', - 'click .js_follow_btn': '_onFollowBtnClick', - }, - - /** - * @override - */ - start: function () { - var self = this; - this.is_user = false; - var unsubscribePage = window.location.search.slice(1).split('&').indexOf("unsubscribe") >= 0; - - var always = function (data) { - self.is_user = data.is_user; - self.email = data.email; - self.$target.find('.js_mg_link').attr('href', '/groups/' + self.$target.data('id')); - if (unsubscribePage && self.is_user) { - self.$target.find(".js_mg_follow_form").remove(); - } - self._toggleSubscription(data.is_member ? 'on' : 'off', data.email); - self.$target.removeClass('d-none'); - }; - - this._rpc({ - route: '/groups/is_member', - params: { - model: this.$target.data('object'), - channel_id: this.$target.data('id'), - get_alias_info: true, - }, - }).then(always).guardedCatch(always); - - // not if editable mode to allow designer to edit alert field - if (!this.editableMode) { - this.$('> .alert').addClass('d-none'); - this.$('> .input-group-append.d-none').removeClass('d-none'); - } - return this._super.apply(this, arguments); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @private - */ - _getAliasInfo: function () { - var self = this; - if (! this.$target.data('id')) { - return Promise.resolve(); - } - return this._rpc({route: '/groups/' + this.$target.data('id') + '/get_alias_info'}).then(function (data) { - if (data.alias_name) { - self.$target.find('.js_mg_email').attr('href', 'mailto:' + data.alias_name); - self.$target.find('.js_mg_email').removeClass('d-none'); - } else { - self.$target.find('.js_mg_email').addClass('d-none'); - } - }); - }, - /** - * @private - */ - _toggleSubscription: function (follow, email) { - // .js_mg_follow_form contains subscribe form - // .js_mg_details contains send/archives/unsubscribe links - // .js_mg_confirmation contains message warning has been sent - var aliasDone = this._getAliasInfo(); - if (follow === "on") { - // user is connected and can unsubscribe - this.$target.find(".js_mg_follow_form").addClass('d-none'); - this.$target.find(".js_mg_details").removeClass('d-none'); - this.$target.find(".js_mg_confirmation").addClass('d-none'); - } else if (follow === "off") { - // user is connected and can subscribe - this.$target.find(".js_mg_follow_form").removeClass('d-none'); - this.$target.find(".js_mg_details").addClass('d-none'); - this.$target.find(".js_mg_confirmation").addClass('d-none'); - } else if (follow === "email") { - // a confirmation email has been sent - this.$target.find(".js_mg_follow_form").addClass('d-none'); - this.$target.find(".js_mg_details").addClass('d-none'); - this.$target.find(".js_mg_confirmation").removeClass('d-none'); - } else { - console.error("Unknown subscription action", follow); - } - this.$target.find('input.js_follow_email') - .val(email ? email : "") - .attr("disabled", follow === "on" || (email.length && this.is_user) ? "disabled" : false); - this.$target.attr("data-follow", follow); - return Promise.resolve(aliasDone); - }, - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * @private - */ - _onFollowBtnClick: function (ev) { - if ($(ev.currentTarget).closest('.js_mg_follow_form').length) { - this.$('.js_follow_email').val($(ev.currentTarget).closest('.js_mg_follow_form').find('.js_follow_email').val()); - } - }, - /** - * @private - */ - _onFollowUnFollowBtnClick: function (ev) { - ev.preventDefault(); - var self = this; - var $email = this.$target.find(".js_follow_email"); - - if ($email.length && !$email.val().match(/.+@.+/)) { - this.$target.addClass('o_has_error').find('.form-control, .custom-select').addClass('is-invalid'); - return false; - } - this.$target.removeClass('o_has_error').find('.form-control, .custom-select').removeClass('is-invalid'); - - var subscriptionAction = this.$target.attr("data-follow") || "off"; - if (window.location.search.slice(1).split('&').indexOf("unsubscribe") >= 0) { - // force unsubscribe mode via URI /groups?unsubscribe - subscriptionAction = 'on'; - } - this._rpc({ - route: '/groups/subscription', - params: { - 'channel_id': +this.$target.data('id'), - 'object': this.$target.data('object'), - 'subscription': subscriptionAction, - 'email': $email.length ? $email.val() : false, - }, - }).then(function (follow) { - self._toggleSubscription(follow, self.email); - }); - }, -}); -}); diff --git a/addons/website_mail_channel/static/src/snippets/s_channel/options.js b/addons/website_mail_channel/static/src/snippets/s_channel/options.js deleted file mode 100644 index 858ba8715cd..00000000000 --- a/addons/website_mail_channel/static/src/snippets/s_channel/options.js +++ /dev/null @@ -1,102 +0,0 @@ -odoo.define('website_mail_channel.s_channel_options', function (require) { -'use strict'; - -var core = require('web.core'); -var options = require('web_editor.snippets.options'); -var wUtils = require('website.utils'); - -var _t = core._t; - -options.registry.Channel = options.Class.extend({ - /** - * @override - */ - async start() { - await this._super(...arguments); - this.publicChannels = await this._getPublicChannels(); - }, - /** - * @override - */ - cleanForSave: function () { - this.$target.addClass('d-none'); - }, - /** - * If we have already created channels => select the first one - * else => modal prompt (create a new channel) - * - * @override - */ - onBuilt() { - if (this.publicChannels.length) { - this.$target[0].dataset.id = this.publicChannels[0][0]; - } else { - const widget = this._requestUserValueWidgets('create_mail_channel_opt')[0]; - widget.$el.click(); - } - }, - - //-------------------------------------------------------------------------- - // Options - //-------------------------------------------------------------------------- - - /** - * Creates a new mail.channel through a modal prompt. - * - * @see this.selectClass for parameters - */ - createChannel: function (previewMode, widgetValue, params) { - var self = this; - return wUtils.prompt({ - id: "editor_new_mail_channel_subscribe", - window_title: _t("New Mail Channel"), - input: _t("Name"), - }).then(function (result) { - var name = result.val; - if (!name) { - return; - } - return self._rpc({ - model: 'mail.channel', - method: 'create', - args: [{ - name: name, - public: 'public', - }], - }).then(function (id) { - self.$target.attr("data-id", id); - return self._rerenderXML(); - }); - }); - }, - - //-------------------------------------------------------------------------- - // Private - //-------------------------------------------------------------------------- - - /** - * @override - */ - async _renderCustomXML(uiFragment) { - const channels = await this._getPublicChannels(); - const menuEl = uiFragment.querySelector('.select_discussion_list'); - for (const channel of channels) { - const el = document.createElement('we-button'); - el.dataset.selectDataAttribute = channel[0]; - el.textContent = channel[1]; - menuEl.appendChild(el); - } - }, - /** - * @private - * @return {Promise} - */ - _getPublicChannels() { - return this._rpc({ - model: 'mail.channel', - method: 'name_search', - args: ['', [['public', '=', 'public']]], - }); - }, -}); -}); diff --git a/addons/website_mail_channel/tests/__init__.py b/addons/website_mail_channel/tests/__init__.py deleted file mode 100644 index 2e3364d701d..00000000000 --- a/addons/website_mail_channel/tests/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -# -*- coding: utf-8 -*- -from . import test_unsubscribe diff --git a/addons/website_mail_channel/tests/test_unsubscribe.py b/addons/website_mail_channel/tests/test_unsubscribe.py deleted file mode 100644 index 8da7bb5b08b..00000000000 --- a/addons/website_mail_channel/tests/test_unsubscribe.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- - -from odoo.tests import common, tagged -from odoo.tools.misc import mute_logger, ustr - - -@tagged('-at_install', 'post_install') -class TestConfirmUnsubscribe(common.HttpCase): - def setUp(self): - super(TestConfirmUnsubscribe, self).setUp() - self.partner = self.env['res.partner'].create({ - 'name': 'Bob', - 'email': 'bob@bob.bob' - }) - self.mailing_list = self.env['mail.channel'].create({ - 'name': 'Test Mailing List', - 'public': 'public', - }) - self.token = self.mailing_list._generate_action_token(self.partner.id, action='unsubscribe') - - def test_not_subscribed(self): - """Test warning works""" - self._unsubscribe_check("The address %s is already unsubscribed" % self.partner.email) - - @mute_logger('odoo.addons.website.models.ir_ui_view') - def test_not_subscribed_no_template(self): - """ Test warning works on db without template (code update w/o module update) """ - self.env.ref('website_mail_channel.not_subscribed').unlink() - self.assertEqual( - self.env['ir.model.data'].search_count([ - ('module', '=', 'website_mail_channel'), - ('name', '=', 'not_subscribed'), - ]), 0, 'XID for template should have been deleted') - - self._unsubscribe_check("The address %s is already unsubscribed or was never subscribed to any mailing list" % self.partner.email) - - def test_wrong_token(self): - self.mailing_list.sudo().write({ - 'channel_partner_ids': [(4, self.partner.id, False)] - }) - self.token = 'XXX' - - self._unsubscribe_check("Invalid or expired confirmation link.") - - def test_successful_unsubscribe(self): - self.mailing_list.sudo().write({ - 'channel_partner_ids': [(4, self.partner.id, False)] - }) - - self._unsubscribe_check("You have been correctly unsubscribed") - - def _unsubscribe_check(self, text): - url = "/groups/unsubscribe/{}/{}/{}".format( - self.mailing_list.id, self.partner.id, - self.token - ) - r = self.url_open(url) - body = ustr(r.content) - # normalize space to make matching simpler - self.assertIn(text, u' '.join(body.split())) diff --git a/addons/website_mail_channel/views/snippets/s_channel.xml b/addons/website_mail_channel/views/snippets/s_channel.xml deleted file mode 100644 index 13d6d8723ec..00000000000 --- a/addons/website_mail_channel/views/snippets/s_channel.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - Channel 000 JS - web.assets_frontend - website_mail_channel/static/src/snippets/s_channel/000.js - - - diff --git a/addons/website_mail_channel/views/snippets/snippets.xml b/addons/website_mail_channel/views/snippets/snippets.xml deleted file mode 100644 index 6ea512167b1..00000000000 --- a/addons/website_mail_channel/views/snippets/snippets.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - diff --git a/addons/website_mail_channel/views/website_mail_channel_templates.xml b/addons/website_mail_channel/views/website_mail_channel_templates.xml deleted file mode 100644 index 6d6d103356c..00000000000 --- a/addons/website_mail_channel/views/website_mail_channel_templates.xml +++ /dev/null @@ -1,345 +0,0 @@ - - - - - - - - - - - - - - - - - - -