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