[tryton-debian-vcs] tryton-modules-calendar branch debian updated. debian/3.0.2-2-4-g7b81086

Mathias Behrle tryton-debian-vcs at alioth.debian.org
Tue Apr 22 13:06:32 UTC 2014


The following commit has been merged in the debian branch:
https://alioth.debian.org/plugins/scmgit/cgi-bin/gitweb.cgi/?p=tryton/tryton-modules-calendar.git;a=commitdiff;h=debian/3.0.2-2-4-g7b81086

commit 7b81086c1c76895e180de6cce963332adddbb8de
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Tue Apr 22 14:59:45 2014 +0200

    Bumping minimal required Python version to 2.7.

diff --git a/debian/control b/debian/control
index 1d2407e..889b612 100644
--- a/debian/control
+++ b/debian/control
@@ -9,7 +9,7 @@ Standards-Version: 3.9.5
 Homepage: http://www.tryton.org/
 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=tryton/tryton-modules-calendar.git
 Vcs-Git: git://anonscm.debian.org/tryton/tryton-modules-calendar.git
-X-Python-Version: >= 2.6
+X-Python-Version: >= 2.7
 
 Package: tryton-modules-calendar
 Architecture: all
commit b605a9b97fb9b371da9a0c83c6ea923d2258aa4c
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Tue Apr 22 14:45:48 2014 +0200

    Updating copyright.

diff --git a/debian/copyright b/debian/copyright
index 45bd26f..802aee0 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,9 +1,9 @@
 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 
 Files: *
-Copyright: 2009-2013 Cédric Krier
+Copyright: 2009-2014 Cédric Krier
            2009-2013 Bertrand Chenal
-           2009-2013 B2CK SPRL
+           2009-2014 B2CK SPRL
 License: GPL-3+
 
 Files: debian/*
commit af0dacf4f49742509361da2e770058a0255df303
Author: Mathias Behrle <mathiasb at m9s.biz>
Date:   Tue Apr 22 14:21:19 2014 +0200

    Merging upstream version 3.2.0.

diff --git a/CHANGELOG b/CHANGELOG
index 72b52d7..b4cdbac 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,4 @@
-Version 3.0.2 - 2014-01-18
-* Bug fixes (see mercurial logs for details)
-
-Version 3.0.1 - 2013-12-04
+Version 3.2.0 - 2014-04-21
 * Bug fixes (see mercurial logs for details)
 
 Version 3.0.0 - 2013-10-21
diff --git a/COPYRIGHT b/COPYRIGHT
index a005001..9d9d0a6 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,6 +1,6 @@
-Copyright (C) 2009-2013 Cédric Krier.
+Copyright (C) 2009-2014 Cédric Krier.
 Copyright (C) 2009-2013 Bertrand Chenal.
-Copyright (C) 2009-2013 B2CK SPRL.
+Copyright (C) 2009-2014 B2CK SPRL.
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
diff --git a/INSTALL b/INSTALL
index 6ed7bd6..463e08a 100644
--- a/INSTALL
+++ b/INSTALL
@@ -4,7 +4,7 @@ Installing trytond_calendar
 Prerequisites
 -------------
 
- * Python 2.6 or later (http://www.python.org/)
+ * Python 2.7 or later (http://www.python.org/)
  * trytond (http://www.tryton.org/)
  * vobject >= 0.8.0 (http://vobject.skyhouseconsulting.com/)
  * pywebdav >= 0.9.8 (http://sourceforge.net/projects/pywebdav/)
diff --git a/MANIFEST.in b/MANIFEST.in
index 18ce53c..4cf1634 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,11 +1,9 @@
 include INSTALL
 include README
-include TODO
 include COPYRIGHT
 include CHANGELOG
 include LICENSE
 include tryton.cfg
 include *.xml
 include view/*.xml
-include *.odt
 include locale/*.po
diff --git a/PKG-INFO b/PKG-INFO
index c2472fa..372a523 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: trytond_calendar
-Version: 3.0.2
+Version: 3.2.0
 Summary: Tryton module for CalDAV
 Home-page: http://www.tryton.org/
 Author: Tryton
-Author-email: UNKNOWN
+Author-email: issue_tracker at tryton.org
 License: GPL-3
-Download-URL: http://downloads.tryton.org/3.0/
+Download-URL: http://downloads.tryton.org/3.2/
 Description: trytond_calendar
         ================
         
@@ -44,6 +44,7 @@ Description: trytond_calendar
         
           http://www.tryton.org/
         
+Keywords: tryton calendar caldav
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Plugins
@@ -64,6 +65,5 @@ Classifier: Natural Language :: Russian
 Classifier: Natural Language :: Slovenian
 Classifier: Natural Language :: Spanish
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Topic :: Office/Business
diff --git a/calendar.xml b/calendar.xml
index dbf7e8c..bd3055a 100644
--- a/calendar.xml
+++ b/calendar.xml
@@ -18,7 +18,8 @@ this repository contains the full copyright notices and license terms. -->
             <field name="group" ref="group_calendar_admin"/>
         </record>
 
-        <menuitem name="Calendar" sequence="8" id="menu_calendar"/>
+        <menuitem name="Calendar" sequence="8" id="menu_calendar"
+            icon="tryton-calendar"/>
 
         <record model="ir.ui.view" id="calendar_view_tree">
             <field name="model">calendar.calendar</field>
@@ -148,7 +149,7 @@ this repository contains the full copyright notices and license terms. -->
         <record model="ir.action.act_window" id="act_event_form3">
             <field name="name">Events</field>
             <field name="res_model">calendar.event</field>
-            <field name="domain">[('parent', '=', None), ('calendar', '=', Eval('active_id'))]</field>
+            <field name="domain">[('parent', '=', None), ('calendar', 'in', Eval('active_ids'))]</field>
         </record>
         <record model="ir.action.act_window.view" id="act_event_form3_view1">
             <field name="sequence" eval="10"/>
diff --git a/calendar_.py b/calendar_.py
index df155e3..093b490 100644
--- a/calendar_.py
+++ b/calendar_.py
@@ -62,8 +62,8 @@ class Calendar(ModelSQL, ModelView):
         return calendars
 
     @classmethod
-    def write(cls, calendars, vals):
-        super(Calendar, cls).write(calendars, vals)
+    def write(cls, calendars, values, *args):
+        super(Calendar, cls).write(calendars, values, *args)
         # Restart the cache for get_name
         cls._get_name_cache.clear()
 
@@ -524,12 +524,6 @@ class Event(ModelSQL, ModelView):
         return 'opaque'
 
     @staticmethod
-    def default_timezone():
-        User = Pool().get('res.user')
-        user = User(Transaction().user)
-        return user.timezone
-
-    @staticmethod
     def timezones():
         return [(x, x) for x in pytz.common_timezones] + [('', '')]
 
@@ -631,28 +625,36 @@ class Event(ModelSQL, ModelView):
             'location': self.location.id if self.location else None,
             'status': self.status,
             'organizer': self.organizer,
-            'rdates': [('delete_all',)] + [('create', [rdate._date2update()
+            'rdates': [('delete', [r.id for r in self.rdates])]
+            + [('create', [rdate._date2update()
                         for rdate in self.rdates])],
-            'exdates': [('delete_all',)] + [('create', [exdate._date2update()
+            'exdates': [('delete', [r.id for r in self.exdates])]
+            + [('create', [exdate._date2update()
                         for exdate in self.exdates])],
-            'rrules': [('delete_all',)] + [('create', [rrule._date2update()
+            'rrules': [('delete', [r.id for r in self.rrules])]
+            + [('create', [rrule._date2update()
                         for rrule in self.rrules])],
-            'exrules': [('delete_all',)] + [('create', [exrule._date2update()
+            'exrules': [('delete', [r.id for r in self.exrules])]
+            + [('create', [exrule._date2update()
                         for exrule in self.exrules])],
             }
 
     @classmethod
-    def write(cls, events, values):
+    def write(cls, *args):
         pool = Pool()
         Calendar = pool.get('calendar.calendar')
         Collection = pool.get('webdav.collection')
         cursor = Transaction().cursor
 
-        values = values.copy()
-        if 'sequence' in values:
-            del values['sequence']
+        actions = iter(args)
+        args = []
+        for events, values in zip(actions, actions):
+            values = values.copy()
+            if 'sequence' in values:
+                del values['sequence']
+            args.extend((events, values))
 
-        super(Event, cls).write(events, values)
+        super(Event, cls).write(*args)
 
         table = cls.__table__()
         for i in range(0, len(events), cursor.IN_MAX):
@@ -663,69 +665,72 @@ class Event(ModelSQL, ModelView):
                     values=[table.sequence + 1],
                     where=red_sql))
 
-        if not values:
-            return
-        for event in events:
-            if (event.calendar.owner
-                    and (event.organizer == event.calendar.owner.email
-                        or (event.parent
-                            and event.parent.organizer
-                            == event.calendar.owner.email))):
-                if event.organizer == event.calendar.owner.email:
-                    attendee_emails = [x.email for x in event.attendees
-                            if x.status != 'declined'
-                            and x.email != event.organizer]
-                else:
-                    attendee_emails = [x.email for x in event.parent.attendees
+        actions = iter(args)
+        for events, values in zip(actions, actions):
+            if not values:
+                continue
+            for event in events:
+                if (event.calendar.owner
+                        and (event.organizer == event.calendar.owner.email
+                            or (event.parent
+                                and event.parent.organizer
+                                == event.calendar.owner.email))):
+                    if event.organizer == event.calendar.owner.email:
+                        attendee_emails = [x.email for x in event.attendees
+                                if x.status != 'declined'
+                                and x.email != event.organizer]
+                    else:
+                        attendee_emails = [x.email
+                            for x in event.parent.attendees
                             if x.status != 'declined'
                             and x.email != event.parent.organizer]
-                with Transaction().set_user(0):
-                    events2 = cls.search([
-                            ('uuid', '=', event.uuid),
-                            ('id', '!=', event.id),
-                            ('recurrence', '=', event.recurrence),
-                            ])
-                    for event2 in events2[:]:
-                        if event2.calendar.owner.email in attendee_emails:
-                            attendee_emails.remove(
-                                    event2.calendar.owner.email)
-                        else:
-                            events2.remove(event2)
-                            cls.delete([event2])
-                    if events2:
-                        cls.write(events2, event._event2update())
-                if attendee_emails:
                     with Transaction().set_user(0):
-                        calendars = Calendar.search([
-                                ('owner.email', 'in', attendee_emails),
+                        events2 = cls.search([
+                                ('uuid', '=', event.uuid),
+                                ('id', '!=', event.id),
+                                ('recurrence', '=', event.recurrence),
                                 ])
-                        if not event.recurrence:
-                            for calendar in calendars:
-                                new_event, = cls.copy([event], default={
-                                        'calendar': calendar.id,
-                                        'occurences': None,
-                                        'uuid': event.uuid,
-                                        })
-                                for occurence in event.occurences:
-                                    cls.copy([occurence], default={
+                        for event2 in events2[:]:
+                            if event2.calendar.owner.email in attendee_emails:
+                                attendee_emails.remove(
+                                        event2.calendar.owner.email)
+                            else:
+                                events2.remove(event2)
+                                cls.delete([event2])
+                        if events2:
+                            cls.write(events2, event._event2update())
+                    if attendee_emails:
+                        with Transaction().set_user(0):
+                            calendars = Calendar.search([
+                                    ('owner.email', 'in', attendee_emails),
+                                    ])
+                            if not event.recurrence:
+                                for calendar in calendars:
+                                    new_event, = cls.copy([event], default={
                                             'calendar': calendar.id,
-                                            'parent': new_event.id,
-                                            'uuid': occurence.uuid,
+                                            'occurences': None,
+                                            'uuid': event.uuid,
+                                            })
+                                    for occurence in event.occurences:
+                                        cls.copy([occurence], default={
+                                                'calendar': calendar.id,
+                                                'parent': new_event.id,
+                                                'uuid': occurence.uuid,
+                                                })
+                            else:
+                                parents = cls.search([
+                                        ('uuid', '=', event.uuid),
+                                        ('calendar.owner.email', 'in',
+                                            attendee_emails),
+                                        ('id', '!=', event.id),
+                                        ('recurrence', '=', None),
+                                        ])
+                                for parent in parents:
+                                    cls.copy([event], default={
+                                            'calendar': parent.calendar.id,
+                                            'parent': parent.id,
+                                            'uuid': event.uuid,
                                             })
-                        else:
-                            parents = cls.search([
-                                    ('uuid', '=', event.uuid),
-                                    ('calendar.owner.email', 'in',
-                                        attendee_emails),
-                                    ('id', '!=', event.id),
-                                    ('recurrence', '=', None),
-                                    ])
-                            for parent in parents:
-                                cls.copy([event], default={
-                                        'calendar': parent.calendar.id,
-                                        'parent': parent.id,
-                                        'uuid': event.uuid,
-                                        })
         # Restart the cache for event
         Collection._event_cache.clear()
 
@@ -876,6 +881,7 @@ class Event(ModelSQL, ModelView):
             res['status'] = vevent.status.value.lower()
         else:
             res['status'] = ''
+        res['categories'] = [('remove', [c.id for c in event.categories])]
         if hasattr(vevent, 'categories'):
             with Transaction().set_context(active_test=False):
                 categories = Category.search([
@@ -892,9 +898,7 @@ class Event(ModelSQL, ModelView):
                             })
             if to_create:
                 categories += Category.create(to_create)
-            res['categories'] = [('set', map(int, categories))]
-        else:
-            res['categories'] = [('unlink_all',)]
+            res['categories'] += [('add', map(int, categories))]
         if hasattr(vevent, 'class'):
             if getattr(vevent, 'class').value.lower() in \
                     dict(cls.classification.selection):
@@ -1052,15 +1056,9 @@ class Event(ModelSQL, ModelView):
         '''
         Return an iCalendar instance of vobject for event
         '''
-        pool = Pool()
-        User = pool.get('res.user')
-
-        user = User(Transaction().user)
         if self.timezone:
             tzevent = pytz.timezone(self.timezone)
             tzevent = dateutil.tz.gettz(self.timezone)
-        elif user.timezone:
-            tzevent = dateutil.tz.gettz(user.timezone)
         else:
             tzevent = tzlocal
 
@@ -1264,15 +1262,19 @@ class EventAlarm(AlarmMixin, ModelSQL, ModelView):
         return super(EventAlarm, cls).create(vlist)
 
     @classmethod
-    def write(cls, event_alarms, values):
+    def write(cls, *args):
         Event = Pool().get('calendar.event')
-        events = [x.event for x in event_alarms]
-        if values.get('event'):
-            events.append(Event(values['event']))
+
+        actions = iter(args)
+        events = []
+        for event_alarms, values in zip(actions, actions):
+            events += [x.event for x in event_alarms]
+            if values.get('event'):
+                events.append(Event(values['event']))
         if events:
             # Update write_date of event
             Event.write(events, {})
-        return super(EventAlarm, cls).write(event_alarms, values)
+        super(EventAlarm, cls).write(*args)
 
     @classmethod
     def delete(cls, event_alarms):
@@ -1420,21 +1422,28 @@ class EventAttendee(AttendeeMixin, ModelSQL, ModelView):
         return event_attendees
 
     @classmethod
-    def write(cls, event_attendees, values):
+    def write(cls, *args):
         Event = Pool().get('calendar.event')
-        events = [x.event for x in event_attendees]
-        if values.get('event'):
-            events.append(Event(values['event']))
+
+        actions = iter(args)
+        args = []
+        events = []
+        for event_attendees, values in zip(actions, actions):
+            events += [x.event for x in event_attendees]
+            if values.get('event'):
+                events.append(Event(values['event']))
+            if 'email' in values:
+                values = values.copy()
+                del values['email']
+            args.extend((event_attendees, values))
+
         if events:
             # Update write_date of event
             Event.write(events, {})
 
-        if 'email' in values:
-            values = values.copy()
-            del values['email']
+        super(EventAttendee, cls).write(*args)
 
-        super(EventAttendee, cls).write(event_attendees, values)
-        for event_attendee in event_attendees:
+        for event_attendee in sum(args[::2], []):
             event = event_attendee.event
             if (event.calendar.owner
                     and (event.organizer == event.calendar.owner.email
@@ -1606,15 +1615,19 @@ class EventRDate(DateMixin, ModelSQL, ModelView):
         return super(EventRDate, cls).create(vlist)
 
     @classmethod
-    def write(cls, event_rdates, values):
+    def write(cls, *args):
         Event = Pool().get('calendar.event')
-        events = [x.event for x in event_rdates]
-        if values.get('event'):
-            events.append(Event(values['event']))
+
+        actions = iter(args)
+        events = []
+        for event_rdates, values in zip(actions, actions):
+            events += [x.event for x in event_rdates]
+            if values.get('event'):
+                events.append(Event(values['event']))
         if events:
             # Update write_date of event
             Event.write(events, {})
-        super(EventRDate, cls).write(event_rdates, values)
+        super(EventRDate, cls).write(*args)
 
     @classmethod
     def delete(cls, event_rdates):
@@ -1912,15 +1925,19 @@ class EventRRule(RRuleMixin, ModelSQL, ModelView):
         return super(EventRRule, cls).create(vlist)
 
     @classmethod
-    def write(cls, event_rrules, values):
+    def write(cls, *args):
         Event = Pool().get('calendar.event')
-        events = [x.event for x in event_rrules]
-        if values.get('event'):
-            events.append(Event(values['event']))
+
+        actions = iter(args)
+        events = []
+        for event_rrules, values in zip(actions, actions):
+            events += [x.event for x in event_rrules]
+            if values.get('event'):
+                events.append(Event(values['event']))
         if events:
             # Update write_date of event
             Event.write(events, {})
-        super(EventRRule, cls).write(event_rrules, values)
+        super(EventRRule, cls).write(*args)
 
     @classmethod
     def delete(cls, event_rrules):
diff --git a/locale/bg_BG.po b/locale/bg_BG.po
index f74ad13..9137db1 100644
--- a/locale/bg_BG.po
+++ b/locale/bg_BG.po
@@ -964,6 +964,10 @@ msgctxt "selection:calendar.event.exrule,freq:"
 msgid "Yearly"
 msgstr ""
 
+msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
 #, fuzzy
 msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
@@ -1027,6 +1031,10 @@ msgctxt "selection:calendar.event.rrule,freq:"
 msgid "Yearly"
 msgstr ""
 
+msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
 #, fuzzy
 msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
diff --git a/locale/ca_ES.po b/locale/ca_ES.po
index 30c7902..9f992f8 100644
--- a/locale/ca_ES.po
+++ b/locale/ca_ES.po
@@ -8,7 +8,7 @@ msgstr "Un usuari només pot tenir un calendari."
 
 msgctxt "error:calendar.calendar:"
 msgid "Calendar name \"%s\" can not end with .ics"
-msgstr "El nom del calendari \"%s\" no ha de finalitzar amb la extensió .ics"
+msgstr "El nom del calendari \"%s\" no ha de finalitzar amb l'extensió .ics"
 
 msgctxt "error:calendar.calendar:"
 msgid "The name of calendar must be unique."
@@ -144,7 +144,7 @@ msgstr "Propietari"
 
 msgctxt "field:calendar.calendar,read_users:"
 msgid "Read Users"
-msgstr "Usuaris amb lectura"
+msgstr "Usuaris amb permisos de lectura"
 
 msgctxt "field:calendar.calendar,rec_name:"
 msgid "Name"
@@ -160,7 +160,7 @@ msgstr "Usuari modificació"
 
 msgctxt "field:calendar.calendar,write_users:"
 msgid "Write Users"
-msgstr "Usuaris amb escriptura"
+msgstr "Usuaris amb permisos d'escriptura"
 
 msgctxt "field:calendar.calendar-read-res.user,calendar:"
 msgid "Calendar"
@@ -276,11 +276,11 @@ msgstr "Propietari"
 
 msgctxt "field:calendar.event,calendar_read_users:"
 msgid "Read Users"
-msgstr "Usuaris amb lectura"
+msgstr "Usuaris amb permisos de lectura"
 
 msgctxt "field:calendar.event,calendar_write_users:"
 msgid "Write Users"
-msgstr "Usuaris amb escriptura"
+msgstr "Usuaris amb permisos d'escriptura"
 
 msgctxt "field:calendar.event,categories:"
 msgid "Categories"
@@ -468,7 +468,7 @@ msgstr "Usuari creació"
 
 msgctxt "field:calendar.event.attendee,email:"
 msgid "Email"
-msgstr "Email"
+msgstr "Correu electrònic"
 
 msgctxt "field:calendar.event.attendee,event:"
 msgid "Event"
@@ -568,7 +568,7 @@ msgstr "Per dia de l'any"
 
 msgctxt "field:calendar.event.exrule,count:"
 msgid "Count"
-msgstr "Contador"
+msgstr "Comptador"
 
 msgctxt "field:calendar.event.exrule,create_date:"
 msgid "Create Date"
@@ -592,7 +592,7 @@ msgstr "ID"
 
 msgctxt "field:calendar.event.exrule,interval:"
 msgid "Interval"
-msgstr "Intèrval"
+msgstr "Interval"
 
 msgctxt "field:calendar.event.exrule,rec_name:"
 msgid "Name"
@@ -692,7 +692,7 @@ msgstr "Per dia de l'any"
 
 msgctxt "field:calendar.event.rrule,count:"
 msgid "Count"
-msgstr "Contador"
+msgstr "Comptador"
 
 msgctxt "field:calendar.event.rrule,create_date:"
 msgid "Create Date"
@@ -716,7 +716,7 @@ msgstr "ID"
 
 msgctxt "field:calendar.event.rrule,interval:"
 msgid "Interval"
-msgstr "Intèrval"
+msgstr "Interval"
 
 msgctxt "field:calendar.event.rrule,rec_name:"
 msgid "Name"
@@ -776,29 +776,29 @@ msgstr "Calendaris"
 
 msgctxt "help:calendar.calendar,owner:"
 msgid "The user must have an email"
-msgstr "L'usuari ha de tenir un correu electrònic"
+msgstr "L'usuari ha de tenir un correu electrònic."
 
 msgctxt "help:calendar.event,uuid:"
 msgid "Universally Unique Identifier"
-msgstr "Identificador universal únic"
+msgstr "Identificador universal únic."
 
 msgctxt "help:calendar.event.exdate,date:"
 msgid "Ignore time of field \"Date\", but handle as date only."
-msgstr "Ingnora la hora del camp \"Data\", però utilitza com a única data."
+msgstr "Ignora la hora del camp \"Data\", però utilitza com a única data."
 
 msgctxt "help:calendar.event.exrule,until_date:"
 msgid "Ignore time of field \"Until Date\", but handle as date only."
 msgstr ""
-"Ingnora la hora del camp \"Fins a la data\", però utilitza com a única data."
+"Ignora la hora del camp \"Fins a la data\", però utilitza com a única data."
 
 msgctxt "help:calendar.event.rdate,date:"
 msgid "Ignore time of field \"Date\", but handle as date only."
-msgstr "Ingnora la hora del camp \"Data\", però utilitza com a única data."
+msgstr "Ignora la hora del camp \"Data\", però utilitza com a única data."
 
 msgctxt "help:calendar.event.rrule,until_date:"
 msgid "Ignore time of field \"Until Date\", but handle as date only."
 msgstr ""
-"Ingnora la hora del camp \"Fins a la data\", però utilitza com a única data."
+"Ignora la hora del camp \"Fins a la data\", però utilitza com a única data."
 
 msgctxt "model:calendar.calendar,name:"
 msgid "Calendar"
@@ -878,7 +878,7 @@ msgstr "Esdeveniments"
 
 msgctxt "model:res.group,name:group_calendar_admin"
 msgid "Calendar Administration"
-msgstr "Administració de calendari"
+msgstr "Administració de calendaris"
 
 msgctxt "selection:calendar.event,classification:"
 msgid "Confidential"
@@ -942,7 +942,7 @@ msgstr "Temptatiu"
 
 msgctxt "selection:calendar.event.exrule,freq:"
 msgid "Daily"
-msgstr "Diariament"
+msgstr "Diàriament"
 
 msgctxt "selection:calendar.event.exrule,freq:"
 msgid "Hourly"
@@ -969,6 +969,10 @@ msgid "Yearly"
 msgstr "Anualment"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Divendres"
 
@@ -998,7 +1002,7 @@ msgstr "Dimecres"
 
 msgctxt "selection:calendar.event.rrule,freq:"
 msgid "Daily"
-msgstr "Diariament"
+msgstr "Diàriament"
 
 msgctxt "selection:calendar.event.rrule,freq:"
 msgid "Hourly"
@@ -1025,6 +1029,10 @@ msgid "Yearly"
 msgstr "Anualment"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Divendres"
 
diff --git a/locale/cs_CZ.po b/locale/cs_CZ.po
index 2a615b2..d7152bd 100644
--- a/locale/cs_CZ.po
+++ b/locale/cs_CZ.po
@@ -959,6 +959,10 @@ msgid "Yearly"
 msgstr ""
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr ""
 
@@ -1015,6 +1019,10 @@ msgid "Yearly"
 msgstr ""
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr ""
 
diff --git a/locale/de_DE.po b/locale/de_DE.po
index 314f9c1..527edfb 100644
--- a/locale/de_DE.po
+++ b/locale/de_DE.po
@@ -8,7 +8,7 @@ msgstr "Es kann nur ein Kalender pro Benutzer eingetragen werden."
 
 msgctxt "error:calendar.calendar:"
 msgid "Calendar name \"%s\" can not end with .ics"
-msgstr "Der Name des Kalenders darf nicht mit .ics enden"
+msgstr "Der Name von Kalender \"%s\" darf nicht mit .ics enden"
 
 msgctxt "error:calendar.calendar:"
 msgid "The name of calendar must be unique."
@@ -121,7 +121,7 @@ msgstr "Erstellt durch"
 
 msgctxt "field:calendar.calendar,description:"
 msgid "Description"
-msgstr "Bezeichnung"
+msgstr "Beschreibung"
 
 msgctxt "field:calendar.calendar,id:"
 msgid "ID"
@@ -293,7 +293,7 @@ msgstr "Erstellt durch"
 
 msgctxt "field:calendar.event,description:"
 msgid "Description"
-msgstr "Bezeichnung"
+msgstr "Beschreibung"
 
 msgctxt "field:calendar.event,dtend:"
 msgid "End Date"
@@ -437,7 +437,7 @@ msgstr "Name"
 
 msgctxt "field:calendar.event.alarm,valarm:"
 msgid "valarm"
-msgstr ""
+msgstr "Alarm"
 
 msgctxt "field:calendar.event.alarm,write_date:"
 msgid "Write Date"
@@ -968,6 +968,10 @@ msgid "Yearly"
 msgstr "Jährlich"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Freitag"
 
@@ -1024,6 +1028,10 @@ msgid "Yearly"
 msgstr "Jährlich"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Freitag"
 
diff --git a/locale/es_AR.po b/locale/es_AR.po
index 9805a8d..dfda857 100644
--- a/locale/es_AR.po
+++ b/locale/es_AR.po
@@ -973,6 +973,10 @@ msgid "Yearly"
 msgstr "Anualmente"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Viernes"
 
@@ -1029,6 +1033,10 @@ msgid "Yearly"
 msgstr "Anualmente"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Viernes"
 
diff --git a/locale/es_CO.po b/locale/es_CO.po
index 867a4bb..591cc01 100644
--- a/locale/es_CO.po
+++ b/locale/es_CO.po
@@ -296,7 +296,7 @@ msgstr "Descripción"
 
 msgctxt "field:calendar.event,dtend:"
 msgid "End Date"
-msgstr "Fecha Fin"
+msgstr "Fecha Final"
 
 msgctxt "field:calendar.event,dtstart:"
 msgid "Start Date"
@@ -360,7 +360,7 @@ msgstr "Resumen"
 
 msgctxt "field:calendar.event,timezone:"
 msgid "Timezone"
-msgstr "Zona horaria"
+msgstr "Zona Horaria"
 
 msgctxt "field:calendar.event,transp:"
 msgid "Time Transparency"
@@ -600,7 +600,7 @@ msgstr "Esta Fecha"
 
 msgctxt "field:calendar.event.exrule,wkst:"
 msgid "Week Day"
-msgstr "Día de la Semana"
+msgstr "Día de Semana"
 
 msgctxt "field:calendar.event.exrule,write_date:"
 msgid "Write Date"
@@ -724,7 +724,7 @@ msgstr "Esta Fecha"
 
 msgctxt "field:calendar.event.rrule,wkst:"
 msgid "Week Day"
-msgstr "Día de la Semana"
+msgstr "Día de Semana"
 
 msgctxt "field:calendar.event.rrule,write_date:"
 msgid "Write Date"
@@ -772,7 +772,7 @@ msgstr "El usuario debe tener un email"
 
 msgctxt "help:calendar.event,uuid:"
 msgid "Universally Unique Identifier"
-msgstr "Idenitificador Universal Único"
+msgstr "Identificador Único Universal"
 
 msgctxt "help:calendar.event.exdate,date:"
 msgid "Ignore time of field \"Date\", but handle as date only."
@@ -963,6 +963,10 @@ msgid "Yearly"
 msgstr "Anualmente"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Viernes"
 
@@ -1019,6 +1023,10 @@ msgid "Yearly"
 msgstr "Anualmente"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Viernes"
 
diff --git a/locale/es_ES.po b/locale/es_ES.po
index eb130f3..d6c2baa 100644
--- a/locale/es_ES.po
+++ b/locale/es_ES.po
@@ -148,7 +148,7 @@ msgstr "Propietario"
 
 msgctxt "field:calendar.calendar,read_users:"
 msgid "Read Users"
-msgstr "Usuarios con lectura"
+msgstr "Usuarios con permisos de lectura"
 
 msgctxt "field:calendar.calendar,rec_name:"
 msgid "Name"
@@ -164,7 +164,7 @@ msgstr "Usuario modificación"
 
 msgctxt "field:calendar.calendar,write_users:"
 msgid "Write Users"
-msgstr "Usuarios con escritura"
+msgstr "Usuarios con permisos de escritura"
 
 msgctxt "field:calendar.calendar-read-res.user,calendar:"
 msgid "Calendar"
@@ -280,11 +280,11 @@ msgstr "Propietario"
 
 msgctxt "field:calendar.event,calendar_read_users:"
 msgid "Read Users"
-msgstr "Usuarios con lectura"
+msgstr "Usuarios con permisos de lectura"
 
 msgctxt "field:calendar.event,calendar_write_users:"
 msgid "Write Users"
-msgstr "Usuarios con escritura"
+msgstr "Usuarios con permisos de escritura"
 
 msgctxt "field:calendar.event,categories:"
 msgid "Categories"
@@ -488,7 +488,7 @@ msgstr "Nombre"
 
 msgctxt "field:calendar.event.attendee,status:"
 msgid "Participation Status"
-msgstr "Estat de participacions"
+msgstr "Estado de participación"
 
 msgctxt "field:calendar.event.attendee,write_date:"
 msgid "Write Date"
@@ -596,7 +596,7 @@ msgstr "ID"
 
 msgctxt "field:calendar.event.exrule,interval:"
 msgid "Interval"
-msgstr "Intérvalo"
+msgstr "Intervalo"
 
 msgctxt "field:calendar.event.exrule,rec_name:"
 msgid "Name"
@@ -720,7 +720,7 @@ msgstr "ID"
 
 msgctxt "field:calendar.event.rrule,interval:"
 msgid "Interval"
-msgstr "Intérvalo"
+msgstr "Intervalo"
 
 msgctxt "field:calendar.event.rrule,rec_name:"
 msgid "Name"
@@ -788,19 +788,19 @@ msgstr "Identificador universal único."
 
 msgctxt "help:calendar.event.exdate,date:"
 msgid "Ignore time of field \"Date\", but handle as date only."
-msgstr "Ingnora la hora del campo \"Fecha\", pero usar como única fecha."
+msgstr "Ignora la hora del campo \"Fecha\", pero usar como única fecha."
 
 msgctxt "help:calendar.event.exrule,until_date:"
 msgid "Ignore time of field \"Until Date\", but handle as date only."
-msgstr "Ingnora la hora del campo \"Hasta la fecha\", pero usar como única fecha."
+msgstr "Ignora la hora del campo \"Hasta la fecha\", pero usar como única fecha."
 
 msgctxt "help:calendar.event.rdate,date:"
 msgid "Ignore time of field \"Date\", but handle as date only."
-msgstr "Ingnora la hora del campo \"Fecha\", pero usar como única fecha."
+msgstr "Ignora la hora del campo \"Fecha\", pero usar como única fecha."
 
 msgctxt "help:calendar.event.rrule,until_date:"
 msgid "Ignore time of field \"Until Date\", but handle as date only."
-msgstr "Ingnora la hora del campo \"Hasta la fecha\", pero usar como única fecha."
+msgstr "Ignora la hora del campo \"Hasta la fecha\", pero usar como única fecha."
 
 msgctxt "model:calendar.calendar,name:"
 msgid "Calendar"
@@ -880,7 +880,7 @@ msgstr "Eventos"
 
 msgctxt "model:res.group,name:group_calendar_admin"
 msgid "Calendar Administration"
-msgstr "Administración de calendario"
+msgstr "Administración de calendarios"
 
 msgctxt "selection:calendar.event,classification:"
 msgid "Confidential"
@@ -924,7 +924,7 @@ msgstr ""
 
 msgctxt "selection:calendar.event.attendee,status:"
 msgid "Accepted"
-msgstr "Acceptado"
+msgstr "Aceptado"
 
 msgctxt "selection:calendar.event.attendee,status:"
 msgid "Declined"
@@ -971,6 +971,10 @@ msgid "Yearly"
 msgstr "Anualmente"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Viernes"
 
@@ -1027,6 +1031,10 @@ msgid "Yearly"
 msgstr "Anualmente"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Viernes"
 
diff --git a/locale/fr_FR.po b/locale/fr_FR.po
index 3bdb16c..696c0f5 100644
--- a/locale/fr_FR.po
+++ b/locale/fr_FR.po
@@ -868,7 +868,7 @@ msgstr "Évenement"
 
 msgctxt "model:res.group,name:group_calendar_admin"
 msgid "Calendar Administration"
-msgstr "Administration calendrier"
+msgstr "Administration des calendriers"
 
 msgctxt "selection:calendar.event,classification:"
 msgid "Confidential"
@@ -959,6 +959,10 @@ msgid "Yearly"
 msgstr "Annuel"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Vendredi"
 
@@ -1015,6 +1019,10 @@ msgid "Yearly"
 msgstr "Annuel"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Vendredi"
 
diff --git a/locale/nl_NL.po b/locale/nl_NL.po
index c1b5a15..354dfa1 100644
--- a/locale/nl_NL.po
+++ b/locale/nl_NL.po
@@ -990,6 +990,10 @@ msgid "Yearly"
 msgstr ""
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr ""
 
@@ -1046,6 +1050,10 @@ msgid "Yearly"
 msgstr ""
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr ""
 
diff --git a/locale/ru_RU.po b/locale/ru_RU.po
index e5bb5c8..107ac2e 100644
--- a/locale/ru_RU.po
+++ b/locale/ru_RU.po
@@ -967,6 +967,10 @@ msgid "Yearly"
 msgstr "Ежегодно"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Пятница"
 
@@ -1023,6 +1027,10 @@ msgid "Yearly"
 msgstr "Ежегодно"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Пятница"
 
diff --git a/locale/sl_SI.po b/locale/sl_SI.po
index 4d76c5b..4ef6075 100644
--- a/locale/sl_SI.po
+++ b/locale/sl_SI.po
@@ -128,7 +128,7 @@ msgstr "ID"
 
 msgctxt "field:calendar.calendar,name:"
 msgid "Name"
-msgstr "Ident"
+msgstr "Naziv"
 
 msgctxt "field:calendar.calendar,owner:"
 msgid "Owner"
@@ -959,6 +959,10 @@ msgid "Yearly"
 msgstr "Letno"
 
 msgctxt "selection:calendar.event.exrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.exrule,wkst:"
 msgid "Friday"
 msgstr "Petek"
 
@@ -1015,6 +1019,10 @@ msgid "Yearly"
 msgstr "Letno"
 
 msgctxt "selection:calendar.event.rrule,wkst:"
+msgid ""
+msgstr ""
+
+msgctxt "selection:calendar.event.rrule,wkst:"
 msgid "Friday"
 msgstr "Petek"
 
diff --git a/setup.py b/setup.py
index 4267a73..eba837b 100644
--- a/setup.py
+++ b/setup.py
@@ -11,34 +11,52 @@ import ConfigParser
 def read(fname):
     return open(os.path.join(os.path.dirname(__file__), fname)).read()
 
+
+def get_require_version(name):
+    if minor_version % 2:
+        require = '%s >= %s.%s.dev0, < %s.%s'
+    else:
+        require = '%s >= %s.%s, < %s.%s'
+    require %= (name, major_version, minor_version,
+        major_version, minor_version + 1)
+    return require
+
 config = ConfigParser.ConfigParser()
 config.readfp(open('tryton.cfg'))
 info = dict(config.items('tryton'))
 for key in ('depends', 'extras_depend', 'xml'):
     if key in info:
         info[key] = info[key].strip().splitlines()
-major_version, minor_version, _ = info.get('version', '0.0.1').split('.', 2)
+version = info.get('version', '0.0.1')
+major_version, minor_version, _ = version.split('.', 2)
 major_version = int(major_version)
 minor_version = int(minor_version)
+name = 'trytond_calendar'
+
+download_url = 'http://downloads.tryton.org/%s.%s/' % (
+    major_version, minor_version)
+if minor_version % 2:
+    version = '%s.%s.dev0' % (major_version, minor_version)
+    download_url = (
+        'hg+http://hg.tryton.org/modules/%s#egg=%s-%s' % (
+            name[8:], name, version))
 
 requires = ['vobject >= 0.8.0', 'PyWebDAV >= 0.9.8', 'python-dateutil', 'pytz',
     'python-sql']
 for dep in info.get('depends', []):
     if not re.match(r'(ir|res|webdav)(\W|$)', dep):
-        requires.append('trytond_%s >= %s.%s, < %s.%s' %
-            (dep, major_version, minor_version, major_version,
-                minor_version + 1))
-requires.append('trytond >= %s.%s, < %s.%s' %
-    (major_version, minor_version, major_version, minor_version + 1))
+        requires.append(get_require_version('trytond_%s' % dep))
+requires.append(get_require_version('trytond'))
 
-setup(name='trytond_calendar',
-    version=info.get('version', '0.0.1'),
+setup(name=name,
+    version=version,
     description='Tryton module for CalDAV',
     long_description=read('README'),
     author='Tryton',
+    author_email='issue_tracker at tryton.org',
     url='http://www.tryton.org/',
-    download_url=("http://downloads.tryton.org/" +
-        info.get('version', '0.0.1').rsplit('.', 1)[0] + '/'),
+    download_url=download_url,
+    keywords='tryton calendar caldav',
     package_dir={'trytond.modules.calendar': '.'},
     packages=[
         'trytond.modules.calendar',
@@ -68,7 +86,6 @@ setup(name='trytond_calendar',
         'Natural Language :: Slovenian',
         'Natural Language :: Spanish',
         'Operating System :: OS Independent',
-        'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 2.7',
         'Topic :: Office/Business',
         ],
diff --git a/tests/scenario_calendar.py b/tests/scenario_calendar.py
index 50903f7..d05c3d4 100644
--- a/tests/scenario_calendar.py
+++ b/tests/scenario_calendar.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python
 #This file is part of Tryton.  The COPYRIGHT file at the top level of
 #this repository contains the full copyright notices and license terms.
-from optparse import OptionParser
+from argparse import ArgumentParser
 from urlparse import urlparse
 import unittest
 import sys
@@ -158,12 +158,12 @@ class TestCase(unittest.TestCase):
                     ]), [])
 
 if __name__ == '__main__':
-    parser = OptionParser()
-    parser.add_option('--xmlrpc', dest='xmlrpc', metavar='URL',
+    parser = ArgumentParser()
+    parser.add_argument('--xmlrpc', dest='xmlrpc', metavar='URL',
         help='use trytond XML-RPC at URL')
-    parser.add_option('--url', dest='url', metavar='URL',
+    parser.add_argument('--url', dest='url', metavar='URL',
         help='use calendar at URL')
-    (options, args) = parser.parse_args()
+    options = parser.parse_args()
     config = config.set_xmlrpc(options.xmlrpc)
     xmlrpc_user = urlparse(options.xmlrpc).username
     user = urlparse(options.url).username
diff --git a/tests/test_calendar.py b/tests/test_calendar.py
index 55fabea..70a076b 100644
--- a/tests/test_calendar.py
+++ b/tests/test_calendar.py
@@ -1,37 +1,22 @@
-#!/usr/bin/env python
 #This file is part of Tryton.  The COPYRIGHT file at the top level of
 #this repository contains the full copyright notices and license terms.
-
-import sys
-import os
-DIR = os.path.abspath(os.path.normpath(os.path.join(__file__,
-    '..', '..', '..', '..', '..', 'trytond')))
-if os.path.isdir(DIR):
-    sys.path.insert(0, os.path.dirname(DIR))
-
 import unittest
 import trytond.tests.test_tryton
 from trytond.tests.test_tryton import test_view, test_depends
 
 
 class CalendarTestCase(unittest.TestCase):
-    '''
-    Test Calendar module.
-    '''
+    'Test Calendar module'
 
     def setUp(self):
         trytond.tests.test_tryton.install_module('calendar')
 
     def test0005views(self):
-        '''
-        Test views.
-        '''
+        'Test views'
         test_view('calendar')
 
     def test0006depends(self):
-        '''
-        Test depends.
-        '''
+        'Test depends'
         test_depends()
 
 
@@ -40,6 +25,3 @@ def suite():
     suite.addTests(unittest.TestLoader().loadTestsFromTestCase(
         CalendarTestCase))
     return suite
-
-if __name__ == '__main__':
-    unittest.TextTestRunner(verbosity=2).run(suite())
diff --git a/tryton.cfg b/tryton.cfg
index 92f6eb4..3c9466d 100644
--- a/tryton.cfg
+++ b/tryton.cfg
@@ -1,5 +1,5 @@
 [tryton]
-version=3.0.2
+version=3.2.0
 depends:
     ir
     res
diff --git a/trytond_calendar.egg-info/PKG-INFO b/trytond_calendar.egg-info/PKG-INFO
index 3f610cf..ccce22b 100644
--- a/trytond_calendar.egg-info/PKG-INFO
+++ b/trytond_calendar.egg-info/PKG-INFO
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: trytond-calendar
-Version: 3.0.2
+Version: 3.2.0
 Summary: Tryton module for CalDAV
 Home-page: http://www.tryton.org/
 Author: Tryton
-Author-email: UNKNOWN
+Author-email: issue_tracker at tryton.org
 License: GPL-3
-Download-URL: http://downloads.tryton.org/3.0/
+Download-URL: http://downloads.tryton.org/3.2/
 Description: trytond_calendar
         ================
         
@@ -44,6 +44,7 @@ Description: trytond_calendar
         
           http://www.tryton.org/
         
+Keywords: tryton calendar caldav
 Platform: UNKNOWN
 Classifier: Development Status :: 5 - Production/Stable
 Classifier: Environment :: Plugins
@@ -64,6 +65,5 @@ Classifier: Natural Language :: Russian
 Classifier: Natural Language :: Slovenian
 Classifier: Natural Language :: Spanish
 Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Topic :: Office/Business
diff --git a/trytond_calendar.egg-info/requires.txt b/trytond_calendar.egg-info/requires.txt
index 67ab9f8..f9cf2a5 100644
--- a/trytond_calendar.egg-info/requires.txt
+++ b/trytond_calendar.egg-info/requires.txt
@@ -3,7 +3,7 @@ PyWebDAV >= 0.9.8
 python-dateutil
 pytz
 python-sql
-trytond >= 3.0, < 3.1
+trytond >= 3.2, < 3.3
 
 [test]
 caldav
\ No newline at end of file
-- 
tryton-modules-calendar



More information about the tryton-debian-vcs mailing list