diff --git a/addons/event/__init__.py b/addons/event/__init__.py index f17ad3dbaec..5e8764bb37f 100644 --- a/addons/event/__init__.py +++ b/addons/event/__init__.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from . import controllers from . import models from . import wizard from . import report diff --git a/addons/event/__manifest__.py b/addons/event/__manifest__.py index e9f22c0f53d..a726ca2558b 100644 --- a/addons/event/__manifest__.py +++ b/addons/event/__manifest__.py @@ -17,7 +17,7 @@ Key Features * Manage your Events and Registrations * Use emails to automatically confirm and send acknowledgments for any event registration """, - 'depends': ['base_setup', 'mail'], + 'depends': ['base_setup', 'mail', 'portal'], 'data': [ 'security/event_security.xml', 'security/ir.model.access.csv', diff --git a/addons/event/controllers/__init__.py b/addons/event/controllers/__init__.py new file mode 100644 index 00000000000..5d4b25db9c0 --- /dev/null +++ b/addons/event/controllers/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import main diff --git a/addons/event/controllers/main.py b/addons/event/controllers/main.py new file mode 100644 index 00000000000..481fc5f27ba --- /dev/null +++ b/addons/event/controllers/main.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from werkzeug.exceptions import NotFound + +from odoo.http import Controller, request, route, content_disposition + + +class EventController(Controller): + + @route(['''/event//ics'''], type='http', auth="public") + def event_ics_file(self, event): + if not event or not event.registration_ids: + return request.not_found() + files = event._get_ics_file() + if not event.id in files: + return NotFound() + content = files[event.id] + return request.make_response(content, [ + ('Content-Type', 'application/octet-stream'), + ('Content-Length', len(content)), + ('Content-Disposition', content_disposition('%s.ics' % event.name)) + ]) diff --git a/addons/event/data/email_template_data.xml b/addons/event/data/email_template_data.xml index 023cb9d44bc..d78d4c27de4 100644 --- a/addons/event/data/email_template_data.xml +++ b/addons/event/data/email_template_data.xml @@ -177,7 +177,7 @@ Add this event to your calendar Google - Outlook + iCal/Outlook Yahoo @@ -374,6 +374,7 @@ Add this event to your calendar Google + iCal/Outlook Yahoo diff --git a/addons/event/models/event.py b/addons/event/models/event.py index 20e3d765d04..0b6c6a6897a 100644 --- a/addons/event/models/event.py +++ b/addons/event/models/event.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- +import logging import pytz from odoo import _, api, fields, models @@ -9,6 +10,14 @@ from odoo.tools.translate import html_translate from dateutil.relativedelta import relativedelta +_logger = logging.getLogger(__name__) + +try: + import vobject +except ImportError: + _logger.warning("`vobject` Python module not found, iCal file generation disabled. Consider installing this module if you want to generate iCal files") + vobject = None + class EventType(models.Model): _name = 'event.type' @@ -331,6 +340,29 @@ class EventEvent(models.Model): def _is_event_registrable(self): return True + @api.multi + def _get_ics_file(self): + """ Returns iCalendar file for the event invitation. + :returns a dict of .ics file content for each event + """ + result = {} + if not vobject: + return result + + for event in self: + cal = vobject.iCalendar() + cal_event = cal.add('vevent') + + cal_event.add('created').value = fields.Datetime.now().replace(tzinfo=pytz.timezone('UTC')) + cal_event.add('dtstart').value = fields.Datetime.from_string(event.date_begin).replace(tzinfo=pytz.timezone('UTC')) + cal_event.add('dtend').value = fields.Datetime.from_string(event.date_end).replace(tzinfo=pytz.timezone('UTC')) + cal_event.add('summary').value = event.name + if event.address_id: + cal_event.add('location').value = event.sudo().address_id.contact_address + + result[event.id] = cal.serialize().encode('utf-8') + return result + class EventRegistration(models.Model): _name = 'event.registration' diff --git a/addons/portal/__init__.py b/addons/portal/__init__.py index 88710707227..d1a0c30eafd 100644 --- a/addons/portal/__init__.py +++ b/addons/portal/__init__.py @@ -1,6 +1,21 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +# Updating mako environement in order to be able to use slug +try: + from odoo.addons.mail.models.mail_template import mako_template_env, mako_safe_template_env + from odoo.addons.http_routing.models.ir_http import slug + + mako_template_env.globals.update({ + 'slug': slug, + }) + + mako_safe_template_env.globals.update({ + 'slug': slug, + }) +except ImportError: + pass + from . import controllers from . import models from . import wizard diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index acff56f9321..1174f91d40e 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -10,7 +10,7 @@ from dateutil.relativedelta import relativedelta from odoo import fields, http, _ from odoo.addons.http_routing.models.ir_http import slug -from odoo.http import content_disposition, request +from odoo.http import request class WebsiteEventController(http.Controller): @@ -283,15 +283,3 @@ class WebsiteEventController(http.Controller): 'google_url': urls.get('google_url'), 'iCal_url': urls.get('iCal_url') }) - - @http.route(['''/event//ics'''], type='http', auth="public", website=True) - def make_event_ics_file(self, event, **kwargs): - if not event or not event.registration_ids: - return request.not_found() - files = event._get_ics_file() - content = files[event.id] - return request.make_response(content, [ - ('Content-Type', 'application/octet-stream'), - ('Content-Length', len(content)), - ('Content-Disposition', content_disposition('%s.ics' % event.name)) - ]) diff --git a/addons/website_event/models/event.py b/addons/website_event/models/event.py index 3b02869cf2e..86f172b96ca 100644 --- a/addons/website_event/models/event.py +++ b/addons/website_event/models/event.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- -import logging import pytz import werkzeug @@ -8,14 +7,6 @@ from odoo import api, fields, models, _ from odoo.addons.http_routing.models.ir_http import slug from odoo.exceptions import UserError -_logger = logging.getLogger(__name__) - -try: - import vobject -except ImportError: - _logger.warning("`vobject` Python module not found, iCal file generation disabled. Consider installing this module if you want to generate iCal files") - vobject = None - GOOGLE_CALENDAR_URL = 'https://www.google.com/calendar/render?' @@ -133,31 +124,6 @@ class Event(models.Model): 'url': '/report/html/%s/%s?enable_editor' % ('event.event_event_report_template_badge', self.id), } - @api.multi - def _get_ics_file(self): - """ Returns iCalendar file for the event invitation. - :returns a dict of .ics file content for each event - """ - result = {} - if not vobject: - return result - - for event in self: - cal = vobject.iCalendar() - cal_event = cal.add('vevent') - - if not event.date_begin or not event.date_end: - raise UserError(_("No date has been specified for the event, no file will be generated.")) - cal_event.add('created').value = fields.Datetime.now().replace(tzinfo=pytz.timezone('UTC')) - cal_event.add('dtstart').value = fields.Datetime.from_string(event.date_begin).replace(tzinfo=pytz.timezone('UTC')) - cal_event.add('dtend').value = fields.Datetime.from_string(event.date_end).replace(tzinfo=pytz.timezone('UTC')) - cal_event.add('summary').value = event.name - if event.address_id: - cal_event.add('location').value = event.sudo().address_id.contact_address - - result[event.id] = cal.serialize().encode('utf-8') - return result - def _get_event_resource_urls(self, attendees): url_date_start = self.date_begin.strftime('%Y%m%dT%H%M%SZ') url_date_stop = self.date_end.strftime('%Y%m%dT%H%M%SZ') @@ -171,7 +137,7 @@ class Event(models.Model): params.update(location=self.sudo().address_id.contact_address.replace('\n', ' ')) encoded_params = werkzeug.url_encode(params) google_url = GOOGLE_CALENDAR_URL + encoded_params - iCal_url = '/event/%s/ics?%s' % (slug(self), encoded_params) + iCal_url = '/event/%d/ics?%s' % (self.id, encoded_params) return {'google_url': google_url, 'iCal_url': iCal_url} def _default_website_meta(self):