caldav_sync: fix a bug where deleting an event fails to remove it from iCloud calendars.

This commit is contained in:
Marc Durepos 2024-07-05 09:04:51 -04:00
parent 8d9fc7db46
commit 4e4068446c
6 changed files with 42 additions and 42 deletions

View file

@ -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"],

View file

@ -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>

View file

@ -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."
@ -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

View file

@ -0,0 +1,3 @@
caldav==1.3.9
icalendar==5.0.13
bs4==0.0.2

View file

@ -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

View file

@ -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>