From d6b3f279cb9e7a7192c85ad1c6e4a682fdccd925 Mon Sep 17 00:00:00 2001 From: "P. Christeas" Date: Thu, 14 Oct 2010 10:00:09 +0300 Subject: [PATCH] CalDAV: alias for node filenames, keep one sent by client. Since some clients keep referring to the created .ics nodes with the filename they sent us, allow them to find that node. bzr revid: p_christ@hol.gr-20101014070009-2vcro7p9krnwxm9s --- addons/caldav/caldav_node.py | 32 +++++++++++++++++++--- addons/caldav/calendar.py | 24 ++++++++++++++++ addons/caldav/security/ir.model.access.csv | 1 + 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/addons/caldav/caldav_node.py b/addons/caldav/caldav_node.py index d91db94fc90..b735d853025 100644 --- a/addons/caldav/caldav_node.py +++ b/addons/caldav/caldav_node.py @@ -286,22 +286,31 @@ class node_calendar(nodes.node_class): ctx = self.context.context.copy() ctx.update(self.dctx) where = [] + bc_obj = dirobj.pool.get('basic.calendar') + if name: if name.endswith('.ics'): name = name[:-4] try: - where.append(('id','=',int(name))) + if name.isdigit(): + where.append(('id','=',int(name))) + else: + bca_obj = dirobj.pool.get('basic.calendar.alias') + bc_alias = bca_obj.search(cr, uid, + [('cal_line_id.calendar_id', '=', self.calendar_id), + ('name', '=', name)] ) + if not bc_alias: + return [] + bc_val = bca_obj.read(cr, uid, bc_alias, ['res_id',]) + where.append(('id', '=', bc_val[0]['res_id'])) except ValueError: # if somebody requests any other name than the ones we # generate (non-numeric), it just won't exist - # FIXME: however, this confuses Evolution (at least), which - # thinks the .ics node hadn't been saved. return [] if not domain: domain = [] - bc_obj = dirobj.pool.get('basic.calendar') # we /could/ be supplying an invalid calendar id to bc_obj, it has to check res = bc_obj.get_calendar_objects(cr, uid, [self.calendar_id], self, domain=where, context=ctx) return res @@ -325,6 +334,21 @@ class node_calendar(nodes.node_class): assert isinstance(res[0], (int, long)) fnodes = fil_obj.get_calendar_objects(cr, uid, [self.calendar_id], self, domain=[('id','=',res[0])], context=ctx) + if self.context.get('DAV-client','') in ('iPhone', 'iCalendar',): + # For those buggy clients, register the alias + bca_obj = fil_obj.pool.get('basic.calendar.alias') + ourcal = fil_obj.browse(cr, uid, self.calendar_id) + line_id = None + for line in ourcal.line_ids: + if line.name == ourcal.type: + line_id = line.id + break + assert line_id, "Calendar #%d must have at least one %s line" % \ + (ourcal.id, ourcal.type) + if path.endswith('.ics'): + path = path[:-4] + bca_obj.create(cr, uid, { 'cal_line_id': line_id, + 'res_id': res[0], 'name': path}, context=ctx) return fnodes[0] # If we reach this line, it means that we couldn't import any useful # (and matching type vs. our node kind) data from the iCal content. diff --git a/addons/caldav/calendar.py b/addons/caldav/calendar.py index 9ca6b924e4d..ccc4bf39fac 100644 --- a/addons/caldav/calendar.py +++ b/addons/caldav/calendar.py @@ -776,6 +776,30 @@ line "%s" more than once' % (vals.get('name')))) basic_calendar_line() +class basic_calendar_alias(osv.osv): + """ Mapping of client filenames to ORM ids of calendar records + + Since some clients insist on putting arbitrary filenames on the .ics data + they send us, and they won't respect the redirection "Location:" header, + we have to store those filenames and allow clients to call our calendar + records with them. + Note that adding a column to all tables that would possibly hold calendar- + mapped data won't work. The user is always allowed to specify more + calendars, on any arbitrary ORM object, without need to alter those tables' + data or structure + """ + _name = 'basic.calendar.alias' + _columns = { + 'name': fields.char('Filename', size=512, required=True, select=1), + 'cal_line_id': fields.many2one('basic.calendar.lines', 'Calendar', required=True, + select=1, help='The calendar/line this mapping applies to'), + 'res_id': fields.integer('Res. ID', required=True, select=1), + } + + _sql_constraints = [ ('name_cal_uniq', 'UNIQUE(cal_line_id, name)', + _('The same filename cannot apply to two records!')), ] + +basic_calendar_alias() class basic_calendar_attribute(osv.osv): _name = 'basic.calendar.attributes' diff --git a/addons/caldav/security/ir.model.access.csv b/addons/caldav/security/ir.model.access.csv index bb16603b904..ce3f3c90e32 100644 --- a/addons/caldav/security/ir.model.access.csv +++ b/addons/caldav/security/ir.model.access.csv @@ -3,3 +3,4 @@ "access_basic_calendar_attributes","basic.calendar.attributes","model_basic_calendar_attributes","base.group_user",1,1,1,1 "access_basic_calendar_fields","basic.calendar.fields","model_basic_calendar_fields","base.group_user",1,1,1,1 "access_basic_calendar","basic.calendar","model_basic_calendar","base.group_user",1,1,1,1 +"access_basic_calendar_alias","basic.calendar.alias","model_basic_calendar_alias","base.group_user",1,1,1,1