From 7e3d05470fa145797555a97db60fb0339fab4be2 Mon Sep 17 00:00:00 2001 From: Marc Durepos Date: Thu, 23 May 2024 12:50:14 -0400 Subject: [PATCH] update readme, remove controller from init, add icon --- caldav_sync/README.rst | 52 ++++++++++++++++++++++++ caldav_sync/__init__.py | 1 - caldav_sync/__manifest__.py | 26 ++++++------ caldav_sync/static/description/icon.png | Bin 0 -> 20840 bytes 4 files changed, 66 insertions(+), 13 deletions(-) create mode 100644 caldav_sync/README.rst create mode 100644 caldav_sync/static/description/icon.png diff --git a/caldav_sync/README.rst b/caldav_sync/README.rst new file mode 100644 index 0000000..0e77a37 --- /dev/null +++ b/caldav_sync/README.rst @@ -0,0 +1,52 @@ +CalDAV Synchronization +====================== + +Bemade Inc. + +Copyright (C) 2023-June Bemade Inc. (). +Author: Marc Durepos (Contact : mdurepos@durpro.com) + +This program is under the terms of the GNU Lesser General Public License (LGPL-3) +For details, visit https://www.gnu.org/licenses/lgpl-3.0.en.html + +Overview +-------- + +The CalDAV Synchronization module for Odoo allows users to synchronize their calendar events with CalDAV servers. This enables seamless integration of Odoo calendar with external applications like Apple Calendar or Thunderbird. + +Features +-------- + +- Synchronize Odoo calendar events with CalDAV servers. +- Create, update, and delete events in Odoo and reflect changes on the CalDAV server. +- Poll CalDAV server for changes and update Odoo calendar accordingly. +- Allow users to select which calendar to synchronize with on the CalDAV server. + +Configuration +------------- + +1. Install the module in Odoo. +2. Go to the User settings in Odoo. +3. Enter the CalDAV server URL, username, and password. +4. Fetch the available calendars from the CalDAV server and select the one to synchronize with. + +Usage +----- + +1. Create a calendar event in Odoo and it will be synchronized with the selected CalDAV calendar. +2. Update the event in Odoo and the changes will reflect on the CalDAV server. +3. Delete the event in Odoo and it will be removed from the CalDAV server. +4. Changes made to the calendar on the CalDAV server will be polled and updated in Odoo. + +Technical Details +----------------- + +- The module extends the `calendar.event` model to add CalDAV synchronization functionality. +- It uses the `icalendar` library to format events and the `caldav` library to interact with CalDAV servers. +- Polling for changes on the CalDAV server can be triggered manually or set up as a scheduled job in Odoo. + +License +------- + +This program is under the terms of the GNU Lesser General Public License (LGPL-3) +For details, visit https://www.gnu.org/licenses/lgpl-3.0.en.html diff --git a/caldav_sync/__init__.py b/caldav_sync/__init__.py index 3b38916..a0fdc10 100644 --- a/caldav_sync/__init__.py +++ b/caldav_sync/__init__.py @@ -1,3 +1,2 @@ # -*- coding: utf-8 -*- from . import models -from . import controllers diff --git a/caldav_sync/__manifest__.py b/caldav_sync/__manifest__.py index b1cf7d1..5e84d78 100644 --- a/caldav_sync/__manifest__.py +++ b/caldav_sync/__manifest__.py @@ -1,4 +1,3 @@ -# # Bemade Inc. # # Copyright (C) 2023-June Bemade Inc. (). @@ -8,22 +7,25 @@ # For details, visit https://www.gnu.org/licenses/lgpl-3.0.en.html { - 'name': 'CalDAV Sync', - 'version': '1.0', - 'category': 'Calendar', - 'summary': 'Synchronize Odoo Calendar with a CalDAV Server', - 'description': """ - This module allows Odoo to synchronize calendar events with a CalDAV server. - """, - 'author': 'Your Name', + 'name': 'CalDAV Synchronization', + 'version': '17.0.0.2.0', 'license': 'LGPL-3', + 'category': 'Productivity', + '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.', + 'website': 'https://www.bemade.org', 'depends': ['base', 'calendar'], - 'external_dependencies': { - 'python': ['caldav'], - }, 'data': [ + 'security/ir.model.access.csv', + 'views/res_users_views.xml', 'data/caldav_sync_data.xml', ], 'installable': True, 'application': True, + 'auto_install': False, } diff --git a/caldav_sync/static/description/icon.png b/caldav_sync/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..2da875737494dcfa766535745a5dd54e01121db5 GIT binary patch literal 20840 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 DgCXao literal 0 HcmV?d00001