def removeOtherProperties(sqlStore): """ Remove the following properties: DAV:acl DAV:getcontenttype DAV:resource-id {urn:ietf:params:xml:ns:caldav}originator {urn:ietf:params:xml:ns:caldav}recipient {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set {http://calendarserver.org/ns/}getctag {http://twistedmatrix.com/xml_namespace/dav/private/}quota-used {http://twistedmatrix.com/xml_namespace/dav/}getcontentmd5 {http://twistedmatrix.com/xml_namespace/dav/}schedule-auto-respond """ sqlTxn = sqlStore.newTransaction() yield removeProperty(sqlTxn, PropertyName.fromElement(element.ACL)) yield removeProperty(sqlTxn, PropertyName.fromElement(element.GETContentType)) yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceID)) yield removeProperty(sqlTxn, PropertyName(caldavxml.caldav_namespace, "originator")) yield removeProperty(sqlTxn, PropertyName(caldavxml.caldav_namespace, "recipient")) yield removeProperty(sqlTxn, PropertyName.fromElement(caldavxml.SupportedCalendarComponentSet)) yield removeProperty(sqlTxn, PropertyName.fromElement(customxml.GETCTag)) yield removeProperty(sqlTxn, PropertyName.fromElement(TwistedQuotaUsedProperty)) yield removeProperty(sqlTxn, PropertyName.fromElement(TwistedGETContentMD5)) yield removeProperty(sqlTxn, PropertyName(element.twisted_dav_namespace, "schedule-auto-respond")) yield sqlTxn.commit() yield cleanPropertyStore()
def moveCalendarTimezoneProperties(sqlStore): """ Need to move all the CalDAV:calendar-timezone properties in the RESOURCE_PROPERTY table to the new CALENDAR_BIND table columns, extracting the new value from the XML property. """ cb = schema.CALENDAR_BIND rp = schema.RESOURCE_PROPERTY try: calendars_for_id = {} while True: sqlTxn = sqlStore.newTransaction() rows = (yield rowsForProperty(sqlTxn, caldavxml.CalendarTimeZone, with_uid=True, batch=BATCH_SIZE)) if len(rows) == 0: yield sqlTxn.commit() break delete_ids = [] for calendar_rid, value, viewer in rows: delete_ids.append(calendar_rid) if calendar_rid not in calendars_for_id: ids = yield Select( [cb.CALENDAR_HOME_RESOURCE_ID, cb.BIND_MODE, ], From=cb, Where=cb.CALENDAR_RESOURCE_ID == calendar_rid, ).on(sqlTxn) calendars_for_id[calendar_rid] = ids if viewer: calendarHome = (yield sqlTxn.calendarHomeWithUID(viewer)) else: calendarHome = None for row in calendars_for_id[calendar_rid]: home_id, bind_mode = row if bind_mode == _BIND_MODE_OWN: calendarHome = (yield sqlTxn.calendarHomeWithResourceID(home_id)) break if calendarHome is not None: prop = WebDAVDocument.fromString(value).root_element calendar = (yield calendarHome.childWithID(calendar_rid)) if calendar is not None: yield calendar.setTimezone(prop.calendar()) # Always delete the rows so that batch processing works correctly yield Delete( From=rp, Where=(rp.RESOURCE_ID.In(Parameter("ids", len(delete_ids)))).And (rp.NAME == PropertyName.fromElement(caldavxml.CalendarTimeZone).toString()), ).on(sqlTxn, ids=delete_ids) yield sqlTxn.commit() yield cleanPropertyStore() except RuntimeError: f = Failure() yield sqlTxn.abort() f.raiseException()
def removeOtherProperties(sqlStore): """ Remove the following properties: DAV:acl DAV:getcontenttype DAV:resource-id {urn:ietf:params:xml:ns:caldav}originator {urn:ietf:params:xml:ns:caldav}recipient {urn:ietf:params:xml:ns:caldav}supported-calendar-component-set {http://calendarserver.org/ns/}getctag {http://twistedmatrix.com/xml_namespace/dav/private/}quota-used {http://twistedmatrix.com/xml_namespace/dav/}getcontentmd5 {http://twistedmatrix.com/xml_namespace/dav/}schedule-auto-respond """ logUpgradeStatus("Starting Calendar Remove Other Properties") sqlTxn = sqlStore.newTransaction(label="calendar_upgrade_from_4_to_5.removeOtherProperties") yield removeProperty(sqlTxn, PropertyName.fromElement(element.ACL)) yield removeProperty(sqlTxn, PropertyName.fromElement(element.GETContentType)) yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceID)) yield removeProperty(sqlTxn, PropertyName(caldavxml.caldav_namespace, "originator")) yield removeProperty(sqlTxn, PropertyName(caldavxml.caldav_namespace, "recipient")) yield removeProperty(sqlTxn, PropertyName.fromElement(caldavxml.SupportedCalendarComponentSet)) yield removeProperty(sqlTxn, PropertyName.fromElement(customxml.GETCTag)) yield removeProperty(sqlTxn, PropertyName.fromElement(TwistedQuotaUsedProperty)) yield removeProperty(sqlTxn, PropertyName.fromElement(TwistedGETContentMD5)) yield removeProperty(sqlTxn, PropertyName(element.twisted_dav_namespace, "schedule-auto-respond")) yield sqlTxn.commit() yield cleanPropertyStore() logUpgradeStatus("End Calendar Remove Other Properties")
def removeResourceType(sqlStore): logUpgradeStatus("Starting Calendar Remove Resource Type") sqlTxn = sqlStore.newTransaction() yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType)) yield sqlTxn.commit() yield cleanPropertyStore() logUpgradeStatus("End Calendar Remove Resource Type")
def updateCalendarHome(txn, homeResourceID): """ For this calendar home, update the associated properties on the home or its owned calendars. """ home = yield txn.calendarHomeWithResourceID(homeResourceID) yield moveCalendarTimezoneProperties(home) yield moveCalendarAvailabilityProperties(home) yield cleanPropertyStore()
def removeResourceType(sqlStore): logUpgradeStatus("Starting Addressbook Remove Resource Type") sqlTxn = sqlStore.newTransaction(label="addressbook_upgrade_from_1_to_2.removeResourceType") yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType)) yield sqlTxn.commit() yield cleanPropertyStore() logUpgradeStatus("End Addressbook Remove Resource Type")
def removeResourceType(sqlStore): logUpgradeStatus("Starting Calendar Remove Resource Type") sqlTxn = sqlStore.newTransaction(label="calendar_upgrade_from_3_to_4.removeResourceType") yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType)) yield sqlTxn.commit() yield cleanPropertyStore() logUpgradeStatus("End Calendar Remove Resource Type")
def updateCalendarHome(txn, homeResourceID): """ For this calendar home, update the associated properties on the home or its owned calendars. """ home = yield txn.calendarHomeWithResourceID(homeResourceID) yield moveCalendarTimezoneProperties(home) yield moveCalendarAvailabilityProperties(home) yield cleanPropertyStore()
def removeResourceType(sqlStore): logUpgradeStatus("Starting Addressbook Remove Resource Type") sqlTxn = sqlStore.newTransaction(label="addressbook_upgrade_from_1_to_2.removeResourceType") yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType)) yield sqlTxn.commit() yield cleanPropertyStore() logUpgradeStatus("End Addressbook Remove Resource Type")
def updateCalendarHome(txn, homeResourceID): """ For this calendar home, update the associated properties on the home or its owned calendars. """ home = yield txn.calendarHomeWithResourceID(homeResourceID) yield moveDefaultCalendarProperties(home) yield moveCalendarTranspProperties(home) yield moveDefaultAlarmProperties(home) yield cleanPropertyStore()
def updateCalendarHome(txn, homeResourceID): """ For this calendar home, update the associated properties on the home or its owned calendars. """ home = yield txn.calendarHomeWithResourceID(homeResourceID) yield moveDefaultCalendarProperties(home) yield moveCalendarTranspProperties(home) yield moveDefaultAlarmProperties(home) yield cleanPropertyStore()
def moveCalendarAvailabilityProperties(sqlStore): """ Need to move all the CS:calendar-availability properties in the RESOURCE_PROPERTY table to the new CALENDAR_BIND table columns, extracting the new value from the XML property. """ cb = schema.CALENDAR_BIND rp = schema.RESOURCE_PROPERTY try: while True: sqlTxn = sqlStore.newTransaction() rows = (yield rowsForProperty(sqlTxn, customxml.CalendarAvailability, batch=BATCH_SIZE)) if len(rows) == 0: yield sqlTxn.commit() break # Map each calendar to a home id using a single query for efficiency calendar_ids = [row[0] for row in rows] home_map = yield Select( [cb.CALENDAR_RESOURCE_ID, cb.CALENDAR_HOME_RESOURCE_ID, ], From=cb, Where=(cb.CALENDAR_RESOURCE_ID.In(Parameter("ids", len(calendar_ids)))).And(cb.BIND_MODE == _BIND_MODE_OWN), ).on(sqlTxn, ids=calendar_ids) calendar_to_home = dict(home_map) # Move property to each home for calendar_rid, value in rows: if calendar_rid in calendar_to_home: calendarHome = (yield sqlTxn.calendarHomeWithResourceID(calendar_to_home[calendar_rid])) if calendarHome is not None: prop = WebDAVDocument.fromString(value).root_element yield calendarHome.setAvailability(prop.calendar()) # Always delete the rows so that batch processing works correctly yield Delete( From=rp, Where=(rp.RESOURCE_ID.In(Parameter("ids", len(calendar_ids)))).And (rp.NAME == PropertyName.fromElement(customxml.CalendarAvailability).toString()), ).on(sqlTxn, ids=calendar_ids) yield sqlTxn.commit() yield cleanPropertyStore() except RuntimeError: f = Failure() yield sqlTxn.abort() f.raiseException()
def _processDefaultCalendarProperty(sqlStore, propname, colname): """ Move the specified property value to the matching CALENDAR_HOME_METADATA table column. Since the number of calendar homes may well be large, we need to do this in batches. """ cb = schema.CALENDAR_BIND rp = schema.RESOURCE_PROPERTY try: while True: sqlTxn = sqlStore.newTransaction() rows = (yield rowsForProperty(sqlTxn, propname, batch=BATCH_SIZE)) if len(rows) == 0: yield sqlTxn.commit() break delete_ids = [] for inbox_rid, value in rows: delete_ids.append(inbox_rid) ids = yield Select( [cb.CALENDAR_HOME_RESOURCE_ID, ], From=cb, Where=cb.CALENDAR_RESOURCE_ID == inbox_rid, ).on(sqlTxn) if len(ids) > 0: calendarHome = (yield sqlTxn.calendarHomeWithResourceID(ids[0][0])) if calendarHome is not None: prop = WebDAVDocument.fromString(value).root_element defaultCalendar = str(prop.children[0]) parts = defaultCalendar.split("/") if len(parts) == 5: calendarName = parts[-1] calendarHomeUID = parts[-2] expectedHome = (yield sqlTxn.calendarHomeWithUID(calendarHomeUID)) if expectedHome is not None and expectedHome.id() == calendarHome.id(): calendar = (yield calendarHome.calendarWithName(calendarName)) if calendar is not None: yield calendarHome.setDefaultCalendar( calendar, tasks=(propname == customxml.ScheduleDefaultTasksURL) ) # Always delete the rows so that batch processing works correctly yield Delete( From=rp, Where=(rp.RESOURCE_ID.In(Parameter("ids", len(delete_ids)))).And (rp.NAME == PropertyName.fromElement(propname).toString()), ).on(sqlTxn, ids=delete_ids) yield sqlTxn.commit() yield cleanPropertyStore() except RuntimeError: f = Failure() yield sqlTxn.abort() f.raiseException()
def removeResourceType(sqlStore): sqlTxn = sqlStore.newTransaction() yield removeProperty(sqlTxn, PropertyName.fromElement(element.ResourceType)) yield sqlTxn.commit() yield cleanPropertyStore()
def _processDefaultAlarmProperty(sqlStore, propname, vevent, timed): """ Move the specified property value to the matching CALENDAR_HOME_METADATA or CALENDAR_BIND table column. Since the number of properties may well be large, we need to do this in batches. """ hm = schema.CALENDAR_HOME_METADATA cb = schema.CALENDAR_BIND rp = schema.RESOURCE_PROPERTY try: calendars_for_id = {} while True: sqlTxn = sqlStore.newTransaction() rows = (yield rowsForProperty(sqlTxn, propname, with_uid=True, batch=BATCH_SIZE)) if len(rows) == 0: yield sqlTxn.commit() break delete_ids = [] for rid, value, viewer in rows: delete_ids.append(rid) prop = WebDAVDocument.fromString(value).root_element alarm = str(prop.children[0]) if prop.children else None # First check if the rid is a home - this is the most common case ids = yield Select( [hm.RESOURCE_ID, ], From=hm, Where=hm.RESOURCE_ID == rid, ).on(sqlTxn) if len(ids) > 0: # Home object calendarHome = (yield sqlTxn.calendarHomeWithResourceID(ids[0][0])) if calendarHome is not None: yield calendarHome.setDefaultAlarm(alarm, vevent, timed) else: # rid is a calendar - we need to find the per-user calendar for the resource viewer if rid not in calendars_for_id: ids = yield Select( [cb.CALENDAR_HOME_RESOURCE_ID, cb.BIND_MODE, ], From=cb, Where=cb.CALENDAR_RESOURCE_ID == rid, ).on(sqlTxn) calendars_for_id[rid] = ids if viewer: calendarHome = (yield sqlTxn.calendarHomeWithUID(viewer)) else: calendarHome = None for row in calendars_for_id[rid]: home_id, bind_mode = row if bind_mode == _BIND_MODE_OWN: calendarHome = (yield sqlTxn.calendarHomeWithResourceID(home_id)) break if calendarHome is not None: calendar = yield calendarHome.childWithID(rid) if calendar is not None: yield calendar.setDefaultAlarm(alarm, vevent, timed) # Always delete the rows so that batch processing works correctly yield Delete( From=rp, Where=(rp.RESOURCE_ID.In(Parameter("ids", len(delete_ids)))).And (rp.NAME == PropertyName.fromElement(propname).toString()), ).on(sqlTxn, ids=delete_ids) yield sqlTxn.commit() yield cleanPropertyStore() except RuntimeError: f = Failure() yield sqlTxn.abort() f.raiseException()