summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRomainLibert <rli@odoo.com>2018-06-12 11:30:02 +0000
committerRomainLibert <rli@odoo.com>2018-12-17 11:46:48 +0000
commita03faab03fdf8a164c2f1298cc138b3fa83b0bea (patch)
treeb62bc7a1dedb4756ee19103199084adf2c9d3734
parent496920a8f5691b7654b83453f9dd855af8a3c504 (diff)
[IMP] event, website_event: Make ics file generation available in event
Ics file generation should be possible even when only event is installed as it is a basic feature of events. Moreover we need to be able to generate such files in order to replace the old outlook api used in the event templates, api which is not supported anymore. We decided to use ics files because it is supported by most calendar schedulers hence working with outlook. Linked to task #1853063 closes odoo/odoo#28477
-rw-r--r--addons/event/__init__.py1
-rw-r--r--addons/event/__manifest__.py2
-rw-r--r--addons/event/controllers/__init__.py4
-rw-r--r--addons/event/controllers/main.py23
-rw-r--r--addons/event/data/email_template_data.xml3
-rw-r--r--addons/event/models/event.py32
-rw-r--r--addons/portal/__init__.py15
-rw-r--r--addons/website_event/controllers/main.py14
-rw-r--r--addons/website_event/models/event.py36
9 files changed, 80 insertions, 50 deletions
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/<model("event.event", "[('state', 'in', ('confirm', 'done'))]"):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 @@
<td style="padding:25px 0px;">
<strong>Add this event to your calendar</strong>
<a href="https://www.google.com/calendar/render?action=TEMPLATE&amp;text=${object.event_id.name}&amp;dates=${date_begin}/${date_end}&amp;location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16" alt=""/> Google</a>
- <a href="https://bay02.calendar.live.com/calendar/calendar.aspx?rru=addevent&amp;summary=${object.event_id.name}&amp;dtstart=${date_begin}&amp;dtend=${date_end}&amp;location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16" alt=""/> Outlook</a>
+ <a href="/event/${slug(object.event_id)}/ics" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16" alt=""/> iCal/Outlook</a>
<a href="https://calendar.yahoo.com/?v=60&amp;view=d&amp;type=20&amp;title=${object.event_id.name}&amp;in_loc=${location}&amp;st=${format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%S')}&amp;et=${format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%S')}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new">
<img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16" alt=""/> Yahoo</a>
</td>
@@ -374,6 +374,7 @@
<td style="padding:25px 0px;">
<strong>Add this event to your calendar</strong>
<a href="https://www.google.com/calendar/render?action=TEMPLATE&amp;text=${object.event_id.name}&amp;dates=${date_begin}/${date_end}&amp;location=${location}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16" alt=""/> Google</a>
+ <a href="/event/${slug(object.event_id)}/ics" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;"><img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16" alt=""/> iCal/Outlook</a>
<a href="https://calendar.yahoo.com/?v=60&amp;view=d&amp;type=20&amp;title=${object.event_id.name}&amp;in_loc=${location}&amp;st=${format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%S')}&amp;et=${format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%S')}" style="padding:3px 5px;border:1px solid #875A7B;color:#875A7B;text-decoration:none;border-radius:3px;" target="new">
<img src="/web_editor/font_to_img/61525/rgb(135,90,123)/16" style="vertical-align:middle;" height="16" alt=""/> Yahoo</a>
</td>
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/<model("event.event", "[('website_id', 'in', (False, current_website_id))]"):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):