caldav_sync: fix a bug where deleting an event fails to remove it from iCloud calendars.
This commit is contained in:
parent
8d9fc7db46
commit
4e4068446c
6 changed files with 42 additions and 42 deletions
|
|
@ -8,15 +8,10 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "CalDAV Synchronization",
|
"name": "CalDAV Synchronization",
|
||||||
"version": "17.0.0.5.5",
|
"version": "17.0.0.5.6",
|
||||||
"license": "LGPL-3",
|
"license": "LGPL-3",
|
||||||
"category": "Productivity",
|
"category": "Productivity",
|
||||||
"summary": "Synchronize Odoo Calendar Events with CalDAV Servers",
|
"summary": "Synchronize Odoo Calendar Events with CalDAV Servers",
|
||||||
"description": """
|
|
||||||
This module allows Odoo to synchronize calendar events with CalDAV servers.
|
|
||||||
Users can synchronize their Odoo calendar with external applications like
|
|
||||||
Apple Calendar or Thunderbird using CalDAV protocol.
|
|
||||||
""",
|
|
||||||
"author": "Bemade Inc.",
|
"author": "Bemade Inc.",
|
||||||
"website": "https://www.bemade.org",
|
"website": "https://www.bemade.org",
|
||||||
"depends": ["base", "calendar"],
|
"depends": ["base", "calendar"],
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
<odoo>
|
<odoo noupdate="1">
|
||||||
<data noupdate="1">
|
<record id="ir_cron_caldav_sync" model="ir.cron">
|
||||||
<record id="ir_cron_caldav_sync" model="ir.cron">
|
<field name="name">CalDAV Sync</field>
|
||||||
<field name="name">CalDAV Sync</field>
|
<field name="model_id" ref="model_calendar_event" />
|
||||||
<field name="model_id" ref="model_calendar_event"/>
|
<field name="state">code</field>
|
||||||
<field name="state">code</field>
|
<field name="code">model.poll_caldav_server()</field>
|
||||||
<field name="code">model.poll_caldav_server()</field>
|
<field name="interval_number">1</field>
|
||||||
<field name="interval_number">1</field>
|
<field name="interval_type">minutes</field>
|
||||||
<field name="interval_type">minutes</field>
|
<field name="numbercall">-1</field>
|
||||||
<field name="numbercall">-1</field>
|
<field name="doall" eval="False" />
|
||||||
<field name="doall" eval="False"/>
|
<field name="active" eval="True" />
|
||||||
<field name="active" eval="True"/>
|
</record>
|
||||||
</record>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,12 @@ from odoo import models, api, fields
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
import caldav
|
import caldav
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime
|
||||||
from icalendar import Calendar, Event, vCalAddress, vText
|
from icalendar import Calendar, Event, vCalAddress, vText
|
||||||
from bs4 import BeautifulSoup
|
from bs4 import BeautifulSoup
|
||||||
import re
|
import re
|
||||||
from pytz import timezone, utc
|
from pytz import timezone, utc
|
||||||
|
from caldav.elements.cdav import CompFilter
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -132,8 +133,7 @@ class CalendarEvent(models.Model):
|
||||||
if event.caldav_uid:
|
if event.caldav_uid:
|
||||||
try:
|
try:
|
||||||
_logger.debug(f"Removing CalDAV event {event.caldav_uid}")
|
_logger.debug(f"Removing CalDAV event {event.caldav_uid}")
|
||||||
caldav_event = calendar.object_by_uid(event.caldav_uid)
|
event._get_icalendar().delete()
|
||||||
caldav_event.delete()
|
|
||||||
except caldav.error.NotFoundError:
|
except caldav.error.NotFoundError:
|
||||||
_logger.warning(
|
_logger.warning(
|
||||||
f"CalDAV event {event.caldav_uid} not found on server."
|
f"CalDAV event {event.caldav_uid} not found on server."
|
||||||
|
|
@ -217,9 +217,9 @@ class CalendarEvent(models.Model):
|
||||||
msg = f"""Failed to connect to the calendar, but successfully connected to the
|
msg = f"""Failed to connect to the calendar, but successfully connected to the
|
||||||
server at {client.url}.
|
server at {client.url}.
|
||||||
You may need to select another calendar URL from those below.
|
You may need to select another calendar URL from those below.
|
||||||
|
|
||||||
Available calendars:
|
Available calendars:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
for calendar in principal.calendars():
|
for calendar in principal.calendars():
|
||||||
msg += f"{calendar.name}: {calendar.url}\n"
|
msg += f"{calendar.name}: {calendar.url}\n"
|
||||||
|
|
@ -382,7 +382,7 @@ class CalendarEvent(models.Model):
|
||||||
values.update(recurrency_vals)
|
values.update(recurrency_vals)
|
||||||
if not existing_instance:
|
if not existing_instance:
|
||||||
_logger.info(f"Creating with vals: {values}")
|
_logger.info(f"Creating with vals: {values}")
|
||||||
self.with_context({"caldav_no_sync": True}).create(values)
|
self.with_context(caldav_no_sync=True).create(values)
|
||||||
else:
|
else:
|
||||||
_logger.info(f"Updating with vals: {values}")
|
_logger.info(f"Updating with vals: {values}")
|
||||||
changed_vals = {}
|
changed_vals = {}
|
||||||
|
|
@ -414,9 +414,7 @@ class CalendarEvent(models.Model):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
existing_instance.with_context(
|
existing_instance.with_context(
|
||||||
{
|
caldav_no_sync=True,
|
||||||
"caldav_no_sync": True,
|
|
||||||
}
|
|
||||||
).write(changed_vals)
|
).write(changed_vals)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
||||||
3
caldav_sync/requirements.txt
Normal file
3
caldav_sync/requirements.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
caldav==1.3.9
|
||||||
|
icalendar==5.0.13
|
||||||
|
bs4==0.0.2
|
||||||
|
|
@ -42,7 +42,13 @@
|
||||||
<ol>
|
<ol>
|
||||||
<li>Install the module in Odoo.</li>
|
<li>Install the module in Odoo.</li>
|
||||||
<li>Go to the User settings in Odoo.</li>
|
<li>Go to the User settings in Odoo.</li>
|
||||||
<li>Enter the CalDAV calendar URL, username, and password on the user settings.</li>
|
<li>
|
||||||
|
Enter the CalDAV calendar URL, username, and password on the user settings.
|
||||||
|
In some cases, the calendar URL to use is not evident. For Apple iCloud
|
||||||
|
calendars, for example, we recommend starting with the base server url
|
||||||
|
at https://caldav.icloud.com/ and then selecting a specific calendar url
|
||||||
|
from the error given in the server logs.
|
||||||
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p><strong>Note: </strong>Some calendar service providers such as
|
<p><strong>Note: </strong>Some calendar service providers such as
|
||||||
Apple iCloud require app-specific passwords to be set so that
|
Apple iCloud require app-specific passwords to be set so that
|
||||||
|
|
|
||||||
|
|
@ -1,32 +1,32 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
<record id="view_users_form" model="ir.ui.view">
|
<record id="view_users_form_inherit" model="ir.ui.view">
|
||||||
<field name="name">res.users.form</field>
|
<field name="name">res.users.form.inherit</field>
|
||||||
<field name="model">res.users</field>
|
<field name="model">res.users</field>
|
||||||
<field name="inherit_id" ref="base.view_users_form"/>
|
<field name="inherit_id" ref="base.view_users_form" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//notebook" position="inside">
|
<xpath expr="//notebook" position="inside">
|
||||||
<page string="Calendar">
|
<page string="Calendar">
|
||||||
<group string="CalDAV">
|
<group string="CalDAV">
|
||||||
<field name="caldav_calendar_url"/>
|
<field name="caldav_calendar_url" />
|
||||||
<field name="caldav_username"/>
|
<field name="caldav_username" />
|
||||||
<field name="caldav_password" password="True"/>
|
<field name="caldav_password" password="True" />
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="view_users_form" model="ir.ui.view">
|
<record id="view_users_form_simple_modif_inherit" model="ir.ui.view">
|
||||||
<field name="name">res.users.form</field>
|
<field name="name">res.users.form.simple.modif.inherit</field>
|
||||||
<field name="model">res.users</field>
|
<field name="model">res.users</field>
|
||||||
<field name="inherit_id" ref="base.view_users_form_simple_modif"/>
|
<field name="inherit_id" ref="base.view_users_form_simple_modif" />
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//notebook" position="inside">
|
<xpath expr="//notebook" position="inside">
|
||||||
<page string="Calendar">
|
<page string="Calendar">
|
||||||
<group string="CalDAV">
|
<group string="CalDAV">
|
||||||
<field name="caldav_calendar_url"/>
|
<field name="caldav_calendar_url" />
|
||||||
<field name="caldav_username"/>
|
<field name="caldav_username" />
|
||||||
<field name="caldav_password" password="True"/>
|
<field name="caldav_password" password="True" />
|
||||||
</group>
|
</group>
|
||||||
</page>
|
</page>
|
||||||
</xpath>
|
</xpath>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue