[CalendarServer-changes] [9891] CalendarServer/branches/users/gaya/sharedgroups

source_changes at macosforge.org source_changes at macosforge.org
Wed Oct 3 14:21:42 PDT 2012


Revision: 9891
          http://trac.calendarserver.org//changeset/9891
Author:   gaya at apple.com
Date:     2012-10-03 14:21:42 -0700 (Wed, 03 Oct 2012)
Log Message:
-----------
remove INVITE table

Modified Paths:
--------------
    CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py
    CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py
    CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/file.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/sql.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/file.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py
    CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql
    CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py

Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -21,13 +21,13 @@
 of simple commands.
 """
 
-from caldavclientlibrary.admin.xmlaccounts.recordtypes import recordType_users,\
+from caldavclientlibrary.admin.xmlaccounts.recordtypes import recordType_users, \
     recordType_locations, recordType_resources, recordType_groups
 from calendarserver.tap.util import directoryFromConfig
 from calendarserver.tools import tables
 from calendarserver.tools.cmdline import utilityMain
 from pycalendar.datetime import PyCalendarDateTime
-from twext.enterprise.dal.syntax import Select, Parameter, Count, Delete,\
+from twext.enterprise.dal.syntax import Select, Parameter, Count, Delete, \
     Constant
 from twisted.application.service import Service
 from twisted.internet.defer import inlineCallbacks, returnValue
@@ -93,13 +93,13 @@
 def UserNameFromUID(txn, uid):
     record = txn._directory.recordWithGUID(uid)
     return record.shortNames[0] if record else "(%s)" % (uid,)
-    
+
 def UIDFromInput(txn, value):
     try:
         return str(UUID(value)).upper()
     except (ValueError, TypeError):
         pass
-    
+
     record = txn._directory.recordWithShortName(recordType_users, value)
     if record is None:
         record = txn._directory.recordWithShortName(recordType_locations, value)
@@ -108,11 +108,11 @@
     if record is None:
         record = txn._directory.recordWithShortName(recordType_groups, value)
     return record.guid if record else None
-    
+
 class Cmd(object):
-    
+
     _name = None
-    
+
     @classmethod
     def name(cls):
         return cls._name
@@ -122,18 +122,18 @@
 
 
 class TableSizes(Cmd):
-    
+
     _name = "Show Size of each Table"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
+
         results = []
         for dbtable in schema.model.tables: #@UndefinedVariable
             dbtable = getattr(schema, dbtable.name)
             count = yield self.getTableSize(txn, dbtable)
             results.append((dbtable.model.name, count,))
-        
+
         # Print table of results
         table = tables.Table()
         table.addHeader(("Table", "Row Count"))
@@ -142,7 +142,7 @@
                 dbtable,
                 count,
             ))
-        
+
         print "\n"
         print "Database Tables (total=%d):\n" % (len(results),)
         table.printTable()
@@ -150,21 +150,21 @@
     @inlineCallbacks
     def getTableSize(self, txn, dbtable):
         rows = (yield Select(
-            [Count(Constant(1)),],
+            [Count(Constant(1)), ],
             From=dbtable,
         ).on(txn))
         returnValue(rows[0][0])
 
 
 class CalendarHomes(Cmd):
-    
+
     _name = "List Calendar Homes"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
+
         uids = yield self.getAllHomeUIDs(txn)
-        
+
         # Print table of results
         missing = 0
         table = tables.Table()
@@ -177,7 +177,7 @@
                 uid,
                 shortname,
             ))
-        
+
         print "\n"
         print "Calendar Homes (total=%d, missing=%d):\n" % (len(uids), missing,)
         table.printTable()
@@ -186,21 +186,21 @@
     def getAllHomeUIDs(self, txn):
         ch = schema.CALENDAR_HOME
         rows = (yield Select(
-            [ch.OWNER_UID,],
+            [ch.OWNER_UID, ],
             From=ch,
         ).on(txn))
         returnValue(tuple([row[0] for row in rows]))
 
 
 class CalendarHomesSummary(Cmd):
-    
+
     _name = "List Calendar Homes with summary information"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
+
         uids = yield self.getCalendars(txn)
-        
+
         results = {}
         for uid, calname, count in sorted(uids, key=lambda x:x[0]):
             totalname, totalcount = results.get(uid, (0, 0,))
@@ -208,7 +208,7 @@
                 totalname += 1
                 totalcount += count
                 results[uid] = (totalname, totalcount,)
-        
+
         # Print table of results
         table = tables.Table()
         table.addHeader(("Owner UID", "Short Name", "Calendars", "Resources"))
@@ -228,10 +228,10 @@
         table.addFooter((
             "Average",
             "",
-            "%.2f" % ((1.0 * totals[1])/totals[0] if totals[0] else 0,),
-            "%.2f" % ((1.0 * totals[2])/totals[0] if totals[0] else 0,),
+            "%.2f" % ((1.0 * totals[1]) / totals[0] if totals[0] else 0,),
+            "%.2f" % ((1.0 * totals[2]) / totals[0] if totals[0] else 0,),
         ))
-        
+
         print "\n"
         print "Calendars with resource count (total=%d):\n" % (len(results),)
         table.printTable()
@@ -257,14 +257,14 @@
 
 
 class Calendars(Cmd):
-    
+
     _name = "List Calendars"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
+
         uids = yield self.getCalendars(txn)
-        
+
         # Print table of results
         table = tables.Table()
         table.addHeader(("Owner UID", "Short Name", "Calendar", "Resources"))
@@ -276,7 +276,7 @@
                 calname,
                 count
             ))
-        
+
         print "\n"
         print "Calendars with resource count (total=%d):\n" % (len(uids),)
         table.printTable()
@@ -302,20 +302,20 @@
 
 
 class CalendarsByOwner(Cmd):
-    
+
     _name = "List Calendars for Owner UID/Short Name"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
+
         uid = raw_input("Owner UID/Name: ")
         uid = UIDFromInput(txn, uid)
         uids = yield self.getCalendars(txn, uid)
-        
+
         # Print table of results
         table = tables.Table()
         table.addHeader(("Owner UID", "Short Name", "Calendars", "ID", "Resources"))
-        totals = [0, 0,]
+        totals = [0, 0, ]
         for uid, calname, resid, count in sorted(uids, key=lambda x:x[1]):
             shortname = UserNameFromUID(txn, uid)
             table.addRow((
@@ -328,7 +328,7 @@
             totals[0] += 1
             totals[1] += count
         table.addFooter(("Total", "", totals[0], "", totals[1]))
-        
+
         print "\n"
         print "Calendars with resource count (total=%d):\n" % (len(uids),)
         table.printTable()
@@ -356,14 +356,14 @@
 
 
 class Events(Cmd):
-    
+
     _name = "List Events"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
+
         uids = yield self.getEvents(txn)
-        
+
         # Print table of results
         table = tables.Table()
         table.addHeader(("Owner UID", "Short Name", "Calendar", "ID", "Type", "UID"))
@@ -377,7 +377,7 @@
                 caltype,
                 caluid
             ))
-        
+
         print "\n"
         print "Calendar events (total=%d):\n" % (len(uids),)
         table.printTable()
@@ -403,12 +403,12 @@
         returnValue(tuple(rows))
 
 class EventsByCalendar(Cmd):
-    
+
     _name = "List Events for a specific calendar"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
+
         rid = raw_input("Resource-ID: ")
         try:
             int(rid)
@@ -416,7 +416,7 @@
             print 'Resource ID must be an integer'
             returnValue(None)
         uids = yield self.getEvents(txn, rid)
-        
+
         # Print table of results
         table = tables.Table()
         table.addHeader(("Type", "UID", "Resource Name", "Resource ID",))
@@ -427,7 +427,7 @@
                 rname,
                 rid,
             ))
-        
+
         print "\n"
         print "Calendar events (total=%d):\n" % (len(uids),)
         table.printTable()
@@ -470,7 +470,7 @@
         print "\n"
         table.printTable()
         print data
-    
+
     @inlineCallbacks
     def getEventData(self, txn, whereClause, whereParams):
         ch = schema.CALENDAR_HOME
@@ -495,13 +495,13 @@
         returnValue(tuple(rows))
 
 class Event(EventDetails):
-    
+
     _name = "Get Event Data by Resource-ID"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         rid = raw_input("Resource-ID: ")
         try:
             int(rid)
@@ -520,13 +520,13 @@
 
 
 class EventsByUID(EventDetails):
-    
+
     _name = "Get Event Data by iCalendar UID"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         uid = raw_input("UID: ")
         rows = yield self.getData(txn, uid)
         if rows:
@@ -541,13 +541,13 @@
 
 
 class EventsByName(EventDetails):
-    
+
     _name = "Get Event Data by resource name"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         name = raw_input("Resource Name: ")
         rows = yield self.getData(txn, name)
         if rows:
@@ -562,13 +562,13 @@
 
 
 class EventsByOwner(EventDetails):
-    
+
     _name = "Get Event Data by Owner UID/Short Name"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         uid = raw_input("Owner UID/Name: ")
         uid = UIDFromInput(txn, uid)
         rows = yield self.getData(txn, uid)
@@ -584,13 +584,13 @@
 
 
 class EventsByOwnerCalendar(EventDetails):
-    
+
     _name = "Get Event Data by Owner UID/Short Name and calendar name"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         uid = raw_input("Owner UID/Name: ")
         uid = UIDFromInput(txn, uid)
         name = raw_input("Calendar resource name: ")
@@ -608,13 +608,13 @@
 
 
 class EventsByPath(EventDetails):
-    
+
     _name = "Get Event Data by HTTP Path"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         path = raw_input("Path: ")
         pathbits = path.split("/")
         if len(pathbits) != 6:
@@ -646,13 +646,13 @@
 
 
 class EventsByContent(EventDetails):
-    
+
     _name = "Get Event Data by Searching its Text Data"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         uid = raw_input("Search for: ")
         rows = yield self.getData(txn, uid)
         if rows:
@@ -667,13 +667,13 @@
 
 
 class EventsInTimerange(Cmd):
-    
+
     _name = "Get Event Data within a specified time range"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         uid = raw_input("Owner UID/Name: ")
         start = raw_input("Start Time (UTC YYYYMMDDTHHMMSSZ or YYYYMMDD): ")
         if len(start) == 8:
@@ -698,12 +698,12 @@
         if home is None:
             print "Could not find calendar home"
             returnValue(None)
-            
+
         yield self.eventsForEachCalendar(home, uid, timerange)
 
     @inlineCallbacks
     def eventsForEachCalendar(self, home, uid, timerange):
-        
+
         calendars = yield home.calendars()
         for calendar in calendars:
             if calendar.name() == "inbox":
@@ -712,9 +712,9 @@
 
     @inlineCallbacks
     def eventsInTimeRange(self, calendar, uid, timerange):
-        
+
         # Create fake filter element to match time-range
-        filter =  caldavxml.Filter(
+        filter = caldavxml.Filter(
                       caldavxml.ComponentFilter(
                           caldavxml.ComponentFilter(
                               timerange,
@@ -747,13 +747,13 @@
 
 
 class Purge(Cmd):
-    
+
     _name = "Purge all data from tables"
-    
+
     @inlineCallbacks
     def doIt(self, txn):
-        
-        
+
+
         if raw_input("Do you really want to remove all data [y/n]: ")[0].lower() != 'y':
             print "No data removed"
             returnValue(None)
@@ -771,13 +771,12 @@
             #schema.CALENDAR_OBJECT, - cascades
             #schema.TIME_RANGE, - cascades
             #schema.TRANSPARENCY, - cascades
-            
 
+
             schema.CALENDAR_HOME,
             #schema.CALENDAR_HOME_METADATA - cascades
-            schema.INVITE,
             schema.ATTACHMENT,
-            
+
             schema.ADDRESSBOOK_OBJECT_REVISIONS,
 
             schema.ADDRESSBOOK,
@@ -795,13 +794,13 @@
         for tableschema in wipeout:
             yield self.removeTableData(txn, tableschema)
             print "Removed rows in table %s" % (tableschema,)
-            
+
         if calendaruserproxy.ProxyDBService is not None:
             calendaruserproxy.ProxyDBService.clean() #@UndefinedVariable
             print "Removed all proxies"
         else:
             print "No proxy database to clean."
-        
+
         fp = FilePath(config.AttachmentsRoot)
         if fp.exists():
             for child in fp.children():
@@ -825,7 +824,7 @@
 
     def __init__(self, store, options, reactor, config):
         super(DBInspectService, self).__init__()
-        self.store   = store
+        self.store = store
         self.options = options
         self.reactor = reactor
         self.config = config
@@ -839,7 +838,7 @@
         Start the service.
         """
         super(DBInspectService, self).startService()
-        
+
         # Register commands
         self.registerCommand(TableSizes)
         self.registerCommand(CalendarHomes)
@@ -891,10 +890,10 @@
             yield txn.abort()
 
     def printCommands(self):
-        
+
         print "\n<---- Commands ---->"
         for ctr, name in enumerate(self.commands):
-            print "%d. %s" % (ctr+1, name,)
+            print "%d. %s" % (ctr + 1, name,)
         if self.options["purging"]:
             print "P. Purge\n"
         print "Q. Quit\n"
@@ -904,7 +903,7 @@
         """
         Poll for commands, stopping the reactor when done.
         """
-        
+
         while True:
             self.printCommands()
             cmd = raw_input("Command: ")
@@ -918,9 +917,9 @@
                 except ValueError:
                     print "Invalid command. Try again.\n"
                     continue
-            
-                yield self.runCommandByPosition(position-1)
 
+                yield self.runCommandByPosition(position - 1)
+
         self.reactor.stop()
 
 

Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -679,7 +679,6 @@
 
         if not dryrun:
             (yield storeCalHome.removeUnacceptedShares())
-            (yield storeCalHome.removeInvites())
             notificationHome = (yield txn.notificationsWithUID(uid))
             if notificationHome is not None:
                 (yield notificationHome.remove())
@@ -688,7 +687,7 @@
 
     # Anything in the past is left alone
     whenString = when.getText()
-    filter =  caldavxml.Filter(
+    filter = caldavxml.Filter(
           caldavxml.ComponentFilter(
               caldavxml.ComponentFilter(
                   TimeRange(start=whenString,),
@@ -842,8 +841,8 @@
         # Remove VCards
         storeAbHome = (yield txn.addressbookHomeWithUID(uid))
         if storeAbHome is not None:
-            for abColl in list( (yield storeAbHome.addressbooks()) ):
-                for card in list( (yield abColl.addressbookObjects()) ):
+            for abColl in list((yield storeAbHome.addressbooks())):
+                for card in list((yield abColl.addressbookObjects())):
                     cardName = card.name()
                     if verbose:
                         uri = "/addressbooks/__uids__/%s/%s/%s" % (uid, abColl.name(), cardName)

Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -967,164 +967,6 @@
         return self._shareeHomeChild.shareMessage()
 
 
-class LegacyInvite(object):
-
-    def __init__(self, inviteuid, userid, principalUID, common_name, access, state, summary):
-        self.inviteuid = inviteuid
-        self.principalUID = principalUID
-        self.access = access
-        self.state = state
-        self.summary = summary
-
-
-class InvitesDatabase(AbstractSQLDatabase, LoggingMixIn):
-
-    db_basename = db_prefix + "invites"
-    schema_version = "1"
-    db_type = "invites"
-
-    def __init__(self, resource):
-        """
-        @param resource: the L{CalDAVResource} resource for
-            the shared collection. C{resource} must be a calendar/addressbook collection.)
-        """
-        self.resource = resource
-        db_filename = os.path.join(self.resource.fp.path, InvitesDatabase.db_basename)
-        super(InvitesDatabase, self).__init__(db_filename, True, autocommit=True)
-
-
-    def create(self):
-        """
-        Create the index and initialize it.
-        """
-        self._db()
-
-
-    def get_dbpath(self):
-        return self.resource.fp.child(InvitesDatabase.db_basename).path
-
-
-    def set_dbpath(self, newpath):
-        pass
-
-    dbpath = property(get_dbpath, set_dbpath)
-
-    def allRecords(self):
-
-        records = self._db_execute("select * from INVITE order by USERID")
-        return [self._makeRecord(row) for row in (records if records is not None else ())]
-
-
-    def recordForUserID(self, userid):
-
-        row = self._db_execute("select * from INVITE where USERID = :1", userid)
-        return self._makeRecord(row[0]) if row else None
-
-
-    def recordForPrincipalUID(self, principalUID):
-
-        row = self._db_execute("select * from INVITE where PRINCIPALUID = :1", principalUID)
-        return self._makeRecord(row[0]) if row else None
-
-
-    def recordForInviteUID(self, inviteUID):
-
-        row = self._db_execute("select * from INVITE where INVITEUID = :1", inviteUID)
-        return self._makeRecord(row[0]) if row else None
-
-
-    def addOrUpdateRecord(self, record):
-
-        self._db_execute("""insert or replace into INVITE (INVITEUID, USERID, PRINCIPALUID, NAME, ACCESS, STATE, SUMMARY)
-            values (:1, :2, :3, :4, :5, :6, :7)
-            """, record.inviteuid, "userid", record.principalUID, "name", record.access, record.state, record.summary,
-        )
-
-
-    def removeRecordForInviteUID(self, inviteUID):
-
-        self._db_execute("delete from INVITE where INVITEUID = :1", inviteUID)
-
-
-    def remove(self):
-
-        self._db_close()
-        os.remove(self.dbpath)
-
-
-    def _db_version(self):
-        """
-        @return: the schema version assigned to this index.
-        """
-        return InvitesDatabase.schema_version
-
-
-    def _db_type(self):
-        """
-        @return: the collection type assigned to this index.
-        """
-        return InvitesDatabase.db_type
-
-
-    def _db_init_data_tables(self, q):
-        """
-        Initialise the underlying database tables.
-        @param q:           a database cursor to use.
-        """
-        #
-        # INVITE table is the primary table
-        #   INVITEUID: UID for this invite
-        #   USERID: identifier of invitee
-        #   PRINCIPALUID: principal-UID of invitee
-        #   NAME: common name of invitee
-        #   ACCESS: Access mode for share
-        #   STATE: Invite response status
-        #   SUMMARY: Invite summary
-        #
-        q.execute(
-            """
-            create table INVITE (
-                INVITEUID      text unique,
-                USERID         text unique,
-                PRINCIPALUID   text unique,
-                NAME           text,
-                ACCESS         text,
-                STATE          text,
-                SUMMARY        text
-            )
-            """
-        )
-
-        q.execute(
-            """
-            create index USERID on INVITE (USERID)
-            """
-        )
-        q.execute(
-            """
-            create index PRINCIPALUID on INVITE (PRINCIPALUID)
-            """
-        )
-        q.execute(
-            """
-            create index INVITEUID on INVITE (INVITEUID)
-            """
-        )
-
-
-    def _db_upgrade_data_tables(self, q, old_version):
-        """
-        Upgrade the data from an older version of the DB.
-        """
-
-        # Nothing to do as we have not changed the schema
-        pass
-
-
-    def _makeRecord(self, row):
-
-        return LegacyInvite(*[str(item) if type(item) == types.UnicodeType else item for item in row])
-
 class SharedHomeMixin(LinkFollowerMixIn):
     """
     A mix-in for calendar/addressbook homes that defines the operations for

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/file.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/file.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/file.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -46,13 +46,12 @@
 from twistedcaldav.caldavxml import ScheduleCalendarTransp, Opaque
 from twistedcaldav.config import config
 from twistedcaldav.ical import InvalidICalendarDataError
-from twistedcaldav.sharing import InvitesDatabase
 
 from txdav.caldav.icalendarstore import IAttachment
 from txdav.caldav.icalendarstore import ICalendar, ICalendarObject
 from txdav.caldav.icalendarstore import ICalendarHome
 
-from txdav.caldav.datastore.index_file import Index as OldIndex,\
+from txdav.caldav.datastore.index_file import Index as OldIndex, \
     IndexSchedule as OldInboxIndex
 from txdav.caldav.datastore.util import (
     validateCalendarComponent, dropboxIDFromCalendarObject, CalendarObjectBase,
@@ -131,7 +130,7 @@
 
     @inlineCallbacks
     def hasCalendarResourceUIDSomewhereElse(self, uid, ok_object, type):
-        
+
         objectResources = (yield self.objectResourcesWithUID(uid, ("inbox",)))
         for objectResource in objectResources:
             if ok_object and objectResource._path == ok_object._path:
@@ -139,18 +138,18 @@
             matched_type = "schedule" if objectResource.isScheduleObject else "calendar"
             if type == "schedule" or matched_type == "schedule":
                 returnValue(True)
-            
+
         returnValue(False)
 
     @inlineCallbacks
     def getCalendarResourcesForUID(self, uid, allow_shared=False):
-        
+
         results = []
         objectResources = (yield self.objectResourcesWithUID(uid, ("inbox",)))
         for objectResource in objectResources:
             if allow_shared or objectResource._parentCollection.owned():
                 results.append(objectResource)
-            
+
         returnValue(results)
 
     @inlineCallbacks
@@ -188,16 +187,16 @@
         defaultCal = self.createCalendarWithName("calendar")
         props = defaultCal.properties()
         props[PropertyName(*ScheduleCalendarTransp.qname())] = ScheduleCalendarTransp(Opaque())
-        
+
         # Check whether components type must be separate
         if config.RestrictCalendarsToOneComponentType:
             defaultCal.setSupportedComponents("VEVENT")
-            
+
             # Default tasks
             defaultTasks = self.createCalendarWithName("tasks")
             props = defaultTasks.properties()
             defaultTasks.setSupportedComponents("VTODO")
-            
+
         self.createCalendarWithName("inbox")
 
     def ensureDefaultCalendarsExist(self):
@@ -224,7 +223,7 @@
                         newname = str(uuid.uuid4())
                     newcal = self.createCalendarWithName(newname)
                     newcal.setSupportedComponents(support_component)
-            
+
             _requireCalendarWithType("VEVENT", "calendar")
             _requireCalendarWithType("VTODO", "tasks")
 
@@ -252,7 +251,6 @@
         super(Calendar, self).__init__(name, calendarHome, owned, realName=realName)
 
         self._index = Index(self)
-        self._invites = Invites(self)
         self._objectResourceClass = CalendarObject
 
 
@@ -294,7 +292,7 @@
         Update the private property with the supported components. Technically this should only happen once
         on collection creation, but for migration we may need to change after the fact - hence a separate api.
         """
-        
+
         pname = PropertyName.fromElement(customxml.TwistedCalendarSupportedComponents)
         if supported_components:
             self.properties()[pname] = customxml.TwistedCalendarSupportedComponents.fromString(supported_components)
@@ -337,7 +335,7 @@
         each containing only one component type. When doing this make sure properties and sharing state are preserved
         on any new calendars created.
         """
-        
+
         # TODO: implement this for filestore
         pass
 
@@ -360,7 +358,7 @@
         @param component: Component type to split out
         @type component: C{str}
         """
-        
+
         # TODO: implement this for filestore
         pass
 
@@ -368,15 +366,15 @@
         """
         If the current calendar is shared, make the new calendar shared in the same way, but tweak the name.
         """
-        
+
         # TODO: implement this for filestore
         pass
-    
+
     def _transferCalendarObjects(self, newcalendar, component):
         """
         Move all calendar components of the specified type to the specified calendar.
         """
-        
+
         # TODO: implement this for filestore
         pass
 
@@ -391,7 +389,7 @@
     def __init__(self, name, calendar, metadata=None):
         super(CalendarObject, self).__init__(name, calendar)
         self._attachments = {}
-        
+
         if metadata is not None:
             self.accessMode = metadata.get("accessMode", "")
             self.isScheduleObject = metadata.get("isScheduleObject", False)
@@ -430,7 +428,7 @@
             if self._path.exists():
                 backup = hidden(self._path.temporarySibling())
                 self._path.moveTo(backup)
-            
+
             fh = self._path.open("w")
             try:
                 # FIXME: concurrency problem; if this write is interrupted
@@ -478,7 +476,7 @@
 
         if unfixed:
             self.log_error("Calendar data at %s had unfixable problems:\n  %s" % (self._path.path, "\n  ".join(unfixed),))
-        
+
         if fixed:
             self.log_error("Calendar data at %s had fixable problems:\n  %s" % (self._path.path, "\n  ".join(fixed),))
 
@@ -518,7 +516,7 @@
                     "File corruption detected (improper start) in file: %s"
                     % (self._path.path,)
                 )
-        
+
         self._objectText = text
         return text
 
@@ -537,7 +535,7 @@
 
     def getMetadata(self):
         metadata = {}
-        metadata["accessMode"] = self.accessMode 
+        metadata["accessMode"] = self.accessMode
         metadata["isScheduleObject"] = self.isScheduleObject
         metadata["scheduleTag"] = self.scheduleTag
         metadata["scheduleEtags"] = self.scheduleEtags
@@ -866,13 +864,3 @@
 
             yield calendarObject
 
-
-class Invites(object):
-    #
-    # OK, here's where we get ugly.
-    # The index code needs to be rewritten also, but in the meantime...
-    #
-    def __init__(self, calendar):
-        self.calendar = calendar
-        stubResource = CalendarStubResource(calendar)
-        self._oldInvites = InvitesDatabase(stubResource)

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/sql.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/caldav/datastore/sql.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -39,27 +39,27 @@
 from twistedcaldav import caldavxml, customxml
 from twistedcaldav.caldavxml import ScheduleCalendarTransp, Opaque
 from twistedcaldav.config import config
-from twistedcaldav.dateops import normalizeForIndex, datetimeMktime,\
+from twistedcaldav.dateops import normalizeForIndex, datetimeMktime, \
     parseSQLTimestamp, pyCalendarTodatetime, parseSQLDateToPyCalendar
 from twistedcaldav.ical import Component, InvalidICalendarDataError
 from twistedcaldav.instance import InvalidOverriddenInstanceError
 from twistedcaldav.memcacher import Memcacher
 
 from txdav.base.propertystore.base import PropertyName
-from txdav.caldav.datastore.util import validateCalendarComponent,\
+from txdav.caldav.datastore.util import validateCalendarComponent, \
     dropboxIDFromCalendarObject
-from txdav.caldav.icalendarstore import ICalendarHome, ICalendar, ICalendarObject,\
+from txdav.caldav.icalendarstore import ICalendarHome, ICalendar, ICalendarObject, \
     IAttachment
-from txdav.common.datastore.sql import CommonHome, CommonHomeChild,\
+from txdav.common.datastore.sql import CommonHome, CommonHomeChild, \
     CommonObjectResource, ECALENDARTYPE
-from txdav.common.datastore.sql_legacy import PostgresLegacyIndexEmulator,\
+from txdav.common.datastore.sql_legacy import PostgresLegacyIndexEmulator, \
     PostgresLegacyInboxIndexEmulator
-from txdav.common.datastore.sql_tables import CALENDAR_TABLE,\
-    CALENDAR_BIND_TABLE, CALENDAR_OBJECT_REVISIONS_TABLE, CALENDAR_OBJECT_TABLE,\
-    _ATTACHMENTS_MODE_NONE, _ATTACHMENTS_MODE_READ, _ATTACHMENTS_MODE_WRITE,\
-    CALENDAR_HOME_TABLE, CALENDAR_HOME_METADATA_TABLE,\
-    CALENDAR_AND_CALENDAR_BIND, CALENDAR_OBJECT_REVISIONS_AND_BIND_TABLE,\
-    CALENDAR_OBJECT_AND_BIND_TABLE, _BIND_STATUS_INVITED, schema
+from txdav.common.datastore.sql_tables import CALENDAR_TABLE, \
+    CALENDAR_BIND_TABLE, CALENDAR_OBJECT_REVISIONS_TABLE, CALENDAR_OBJECT_TABLE, \
+    _ATTACHMENTS_MODE_NONE, _ATTACHMENTS_MODE_READ, _ATTACHMENTS_MODE_WRITE, \
+    CALENDAR_HOME_TABLE, CALENDAR_HOME_METADATA_TABLE, \
+    CALENDAR_AND_CALENDAR_BIND, CALENDAR_OBJECT_REVISIONS_AND_BIND_TABLE, \
+    CALENDAR_OBJECT_AND_BIND_TABLE, schema
 from twext.enterprise.dal.syntax import Select, Count, ColumnSyntax
 from twext.enterprise.dal.syntax import Insert
 from twext.enterprise.dal.syntax import Update
@@ -72,8 +72,8 @@
 from txdav.caldav.icalendarstore import QuotaExceeded
 
 from txdav.caldav.datastore.util import StorageTransportBase
-from txdav.common.icommondatastore import IndexedSearchException,\
-    InternalDataStoreError, HomeChildNameAlreadyExistsError,\
+from txdav.common.icommondatastore import IndexedSearchException, \
+    InternalDataStoreError, HomeChildNameAlreadyExistsError, \
     HomeChildNameNotAllowedError
 
 from pycalendar.datetime import PyCalendarDateTime
@@ -271,20 +271,20 @@
 
     @inlineCallbacks
     def createdHome(self):
-        
+
         # Default calendar
         defaultCal = yield self.createCalendarWithName("calendar")
         props = defaultCal.properties()
         props[PropertyName(*ScheduleCalendarTransp.qname())] = ScheduleCalendarTransp(Opaque())
-        
+
         # Check whether components type must be separate
         if config.RestrictCalendarsToOneComponentType:
             yield defaultCal.setSupportedComponents("VEVENT")
-            
+
             # Default tasks
             defaultTasks = yield self.createCalendarWithName("tasks")
             yield defaultTasks.setSupportedComponents("VTODO")
-            
+
         yield self.createCalendarWithName("inbox")
 
     @inlineCallbacks
@@ -292,17 +292,17 @@
         """
         Split all regular calendars by component type
         """
-        
+
         # Make sure the loop does not operate on any new calendars created during the loop
         self.log_warn("Splitting calendars for user %s" % (self._ownerUID,))
         calendars = yield self.calendars()
         for calendar in calendars:
-            
+
             # Ignore inbox - also shared calendars are not part of .calendars() 
             if calendar.name() == "inbox":
                 continue
             split_count = yield calendar.splitCollectionByComponentTypes()
-            self.log_warn("  Calendar: '%s', split into %d" % (calendar.name(), split_count+1,))
+            self.log_warn("  Calendar: '%s', split into %d" % (calendar.name(), split_count + 1,))
 
         yield self.ensureDefaultCalendarsExist()
 
@@ -338,52 +338,6 @@
             yield _requireCalendarWithType("VTODO", "tasks")
 
 
-    @classproperty
-    def _unacceptedSharesQuery(cls): #@NoSelf
-        cb = schema.CALENDAR_BIND
-        return Select([cb.CALENDAR_RESOURCE_NAME],
-            From=cb,
-            Where=(cb.CALENDAR_HOME_RESOURCE_ID == Parameter("homeResourceID")).And(cb.BIND_STATUS == _BIND_STATUS_INVITED))
-
-
-    @inlineCallbacks
-    def removeUnacceptedShares(self):
-        """
-        Unbinds any collections that have been shared to this home but not yet
-        accepted.  Associated invite entries are also removed.
-        """
-        inv = schema.INVITE
-        cb = schema.CALENDAR_BIND
-        rows = yield self._unacceptedSharesQuery.on(self._txn, homeResourceID=self._resourceID)
-        for (resourceName,) in rows:
-            kwds = { "ResourceName" : resourceName }
-            yield Delete(
-                From=inv,
-                Where=(
-                    inv.INVITE_UID == Parameter("ResourceName")
-                ),
-            ).on(self._txn, **kwds)
-
-            yield Delete(
-                From=cb,
-                Where=(
-                    cb.CALENDAR_RESOURCE_NAME == Parameter("ResourceName")
-                ),
-            ).on(self._txn, **kwds)
-
-
-    @inlineCallbacks
-    def removeInvites(self):
-        """
-        Remove all remaining invite entries for this home.
-        """
-        inv = schema.INVITE
-        kwds = { "HomeResourceID" : self._resourceID }
-        yield Delete(
-            From=inv,
-            Where=(inv.HOME_RESOURCE_ID == Parameter("HomeResourceID"))
-        ).on(self._txn, **kwds)
-
 CalendarHome._register(ECALENDARTYPE)
 
 
@@ -431,15 +385,15 @@
         different child classes to have their own type specific data, but still make use of the
         common base logic.
         """
-        
+
         # Common behavior is to have created and modified
-        
+
         return (
             cls._homeChildMetaDataSchema.CREATED,
             cls._homeChildMetaDataSchema.MODIFIED,
             cls._homeChildMetaDataSchema.SUPPORTED_COMPONENTS,
         )
-        
+
     @classmethod
     def metadataAttributes(cls):
         """
@@ -447,15 +401,15 @@
         different child classes to have their own type specific data, but still make use of the
         common base logic.
         """
-        
+
         # Common behavior is to have created and modified
-        
+
         return (
             "_created",
             "_modified",
             "_supportedComponents",
         )
-        
+
     @property
     def _calendarHome(self):
         return self._home
@@ -549,7 +503,7 @@
         on any new calendars created. Also restrict the new calendars to only the one appropriate component type. Return
         the number of splits done.
         """
-        
+
         # First see how many different component types there are
         split_count = 0
         components = yield self._countComponentTypes()
@@ -560,11 +514,11 @@
             yield self.setSupportedComponents(component.upper())
 
             returnValue(split_count)
-        
+
         # We will leave the component type with the highest count in the current calendar and create new calendars
         # for the others which will be moved over
         maxComponent = max(components, key=lambda x:x[1])[0]
-        
+
         for component, _ignore_count in components:
             if component == maxComponent:
                 continue
@@ -595,7 +549,7 @@
         rows = yield _componentsQuery.on(self._txn, calID=self._resourceID)
         result = tuple([(componentType, componentCount) for componentType, componentCount in sorted(rows, key=lambda x:x[0])])
         returnValue(result)
-        
+
     @inlineCallbacks
     def _splitComponentType(self, component):
         """
@@ -605,7 +559,7 @@
         @param component: Component type to split out
         @type component: C{str}
         """
-        
+
         # Create the new calendar
         try:
             newcalendar = yield self._home.createCalendarWithName("%s-%s" % (self._name, component.lower(),))
@@ -613,25 +567,25 @@
             # If the name we want exists, try repeating with up to ten more
             for ctr in range(10):
                 try:
-                    newcalendar = yield self._home.createCalendarWithName("%s-%s-%d" % (self._name, component.lower(), ctr+1,))
+                    newcalendar = yield self._home.createCalendarWithName("%s-%s-%d" % (self._name, component.lower(), ctr + 1,))
                 except HomeChildNameAlreadyExistsError:
                     continue
             else:
                 # At this point we are stuck
                 raise HomeChildNameNotAllowedError
-        
+
         # Restrict calendar to single component type
         yield newcalendar.setSupportedComponents(component.upper())
-        
+
         # Transfer properties over
         yield newcalendar._properties.copyAllProperties(self._properties)
-        
+
         # Transfer sharing
         yield self._transferSharingDetails(newcalendar, component)
-        
+
         # Now move calendar data over
         yield self._transferCalendarObjects(newcalendar, component)
-        
+
     @inlineCallbacks
     def _transferSharingDetails(self, newcalendar, component):
         """
@@ -646,21 +600,21 @@
             Where=(cb.CALENDAR_RESOURCE_ID == Parameter('calID')).And(
                 cb.CALENDAR_HOME_RESOURCE_ID != Parameter('homeID'))
         )
-        
+
         rows = yield _bindQuery.on(
             self._txn,
             calID=self._resourceID,
             homeID=self._home._resourceID,
         )
-        
+
         if len(rows) == 0:
             returnValue(None)
-        
+
         for row in rows:
             columnMap = dict(zip(columns, row))
             columnMap[cb.CALENDAR_RESOURCE_ID] = newcalendar._resourceID
             columnMap[cb.CALENDAR_RESOURCE_NAME] = "%s-%s" % (columnMap[cb.CALENDAR_RESOURCE_NAME], component.lower(),)
-            yield Insert(columnMap).on(self._txn)   
+            yield Insert(columnMap).on(self._txn)
 
     @inlineCallbacks
     def _transferCalendarObjects(self, newcalendar, component):
@@ -682,10 +636,10 @@
             calID=self._resourceID,
             componentType=component,
         )
-        
+
         if len(rows) == 0:
             returnValue(None)
-        
+
         for row in rows:
             resourceID = row[0]
             child = yield self.objectResourceWithID(resourceID)
@@ -743,7 +697,7 @@
     Component.ACCESS_CONFIDENTIAL: 3,
     Component.ACCESS_RESTRICTED  : 4,
 }
-accesstype_to_accessMode = dict([(v, k) for k,v in accessMode_to_type.items()])
+accesstype_to_accessMode = dict([(v, k) for k, v in accessMode_to_type.items()])
 
 def _pathToName(path):
     return path.rsplit(".", 1)[0]
@@ -854,7 +808,7 @@
         # freebusy related properties have changed (e.g. an attendee reply and refresh). In those cases
         # the component will have a special attribute present to let us know to suppress the instance indexing.
         instanceIndexingRequired = not hasattr(component, "noInstanceIndexing") or inserting or reCreate
-        
+
         if instanceIndexingRequired:
 
             # Decide how far to expand based on the component. doInstanceIndexing will indicate whether we
@@ -862,28 +816,28 @@
             # operation.
             doInstanceIndexing = False
             master = component.masterComponent()
-            if ( master is None or not component.isRecurring() ):
+            if (master is None or not component.isRecurring()):
                 # When there is no master we have a set of overridden components -
                 #   index them all.
                 # When there is one instance - index it.
                 expand = PyCalendarDateTime(2100, 1, 1, 0, 0, 0, tzid=PyCalendarTimezone(utc=True))
                 doInstanceIndexing = True
             else:
-    
+
                 # If migrating or re-creating or config option for delayed indexing is off, always index
                 if reCreate or txn._migrating or (not config.FreeBusyIndexDelayedExpand and not isInboxItem):
                     doInstanceIndexing = True
-    
+
                 # Duration into the future through which recurrences are expanded in the index
                 # by default.  This is a caching parameter which affects the size of the index;
                 # it does not affect search results beyond this period, but it may affect
                 # performance of such a search.
                 expand = (PyCalendarDateTime.getToday() +
                           PyCalendarDuration(days=config.FreeBusyIndexExpandAheadDays))
-    
+
                 if expand_until and expand_until > expand:
                     expand = expand_until
-    
+
                 # Maximum duration into the future through which recurrences are expanded in the
                 # index.  This is a caching parameter which affects the size of the index; it
                 # does not affect search results beyond this period, but it may affect
@@ -899,7 +853,7 @@
                 if expand > (PyCalendarDateTime.getToday() +
                              PyCalendarDuration(days=config.FreeBusyIndexExpandMaxDays)):
                     raise IndexedSearchException
-    
+
             if config.FreeBusyIndexLowerLimitDays:
                 truncateLowerLimit = PyCalendarDateTime.getToday()
                 truncateLowerLimit.offsetDay(-config.FreeBusyIndexLowerLimitDays)
@@ -915,7 +869,7 @@
             except InvalidOverriddenInstanceError, e:
                 self.log_error("Invalid instance %s when indexing %s in %s" %
                                (e.rid, self._name, self._calendar,))
-    
+
                 if txn._migrating:
                     # TODO: fix the data here by re-writing component then re-index
                     instances = component.expandTimeRanges(expand, lowerLimit=truncateLowerLimit, ignoreInvalidInstances=True)
@@ -923,7 +877,7 @@
                     recurrenceLowerLimit = instances.lowerLimit
                 else:
                     raise
-    
+
             # Now coerce indexing to off if needed
             if not doInstanceIndexing:
                 instances = None
@@ -1003,7 +957,7 @@
                         Where=co.RESOURCE_ID == self._resourceID
                     ).on(txn)
                 )[0][0]
-                
+
                 # Need to wipe the existing time-range for this and rebuild if required
                 if instanceIndexingRequired:
                     yield Delete(
@@ -1029,8 +983,8 @@
 
         if instanceIndexingRequired and doInstanceIndexing:
             yield self._addInstances(component, instances, truncateLowerLimit, txn)
-    
-    
+
+
     @inlineCallbacks
     def _addInstances(self, component, instances, truncateLowerLimit, txn):
         """
@@ -1148,7 +1102,7 @@
         """
         co = schema.CALENDAR_OBJECT
         return Select(
-            [co.RECURRANCE_MIN, co.RECURRANCE_MAX,],
+            [co.RECURRANCE_MIN, co.RECURRANCE_MAX, ],
             From=co,
             Where=co.RESOURCE_ID == Parameter("resourceID"),
         )

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/file.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/file.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/carddav/datastore/file.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -35,7 +35,6 @@
 
 from twisted.python import hashlib
 
-from twistedcaldav.sharing import InvitesDatabase
 from twistedcaldav.vcard import Component as VComponent, InvalidVCardDataError
 from txdav.carddav.datastore.index_file import AddressBookIndex as OldIndex
 
@@ -43,8 +42,8 @@
 from txdav.carddav.iaddressbookstore import IAddressBook, IAddressBookObject
 from txdav.carddav.iaddressbookstore import IAddressBookHome
 
-from txdav.common.datastore.file import CommonDataStore, CommonHome,\
-    CommonStoreTransaction, CommonHomeChild, CommonObjectResource,\
+from txdav.common.datastore.file import CommonDataStore, CommonHome, \
+    CommonStoreTransaction, CommonHomeChild, CommonObjectResource, \
     CommonStubResource
 from txdav.common.icommondatastore import NoSuchObjectResourceError, InternalDataStoreError
 from txdav.base.datastore.file import hidden, writeOperation
@@ -108,11 +107,10 @@
         will eventually have on disk.
         @type realName: C{str}
         """
-        
+
         super(AddressBook, self).__init__(name, addressbookHome, owned, realName=realName)
 
         self._index = Index(self)
-        self._invites = Invites(self)
         self._objectResourceClass = AddressBookObject
 
     @property
@@ -238,7 +236,7 @@
 
         if unfixed:
             self.log_error("Address data at %s had unfixable problems:\n  %s" % (self._path.path, "\n  ".join(unfixed),))
-        
+
         if fixed:
             self.log_error("Address data at %s had fixable problems:\n  %s" % (self._path.path, "\n  ".join(fixed),))
 
@@ -270,7 +268,7 @@
                 "File corruption detected (improper start) in file: %s"
                 % (self._path.path,)
             )
-        
+
         self._objectText = text
         return text
 
@@ -332,12 +330,3 @@
             yield addressbookObject
 
 
-class Invites(object):
-    #
-    # OK, here's where we get ugly.
-    # The index code needs to be rewritten also, but in the meantime...
-    #
-    def __init__(self, addressbook):
-        self.addressbook = addressbook
-        stubResource = AddressBookStubResource(addressbook)
-        self._oldInvites = InvitesDatabase(stubResource)

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -80,7 +80,7 @@
 
 from txdav.common.icommondatastore import ConcurrentModification
 from twistedcaldav.customxml import NotificationType
-from twistedcaldav.dateops import datetimeMktime, parseSQLTimestamp,\
+from twistedcaldav.dateops import datetimeMktime, parseSQLTimestamp, \
     pyCalendarTodatetime
 
 from txdav.base.datastore.util import normalizeUUIDOrNot
@@ -229,12 +229,12 @@
     Used to log each SQL query and statistics about that query during the course of a single transaction.
     Results can be printed out where ever needed at the end of the transaction.
     """
-    
+
     def __init__(self, label, logFileName=None):
         self.label = label
         self.logFileName = logFileName
         self.statements = []
-    
+
     def startStatement(self, sql, args):
         """
         Called prior to an SQL query being run.
@@ -263,12 +263,12 @@
         index, tstamp = context
         self.statements[index][1] = len(rows) if rows else 0
         self.statements[index][2] = time.time() - tstamp
-        
+
     def printReport(self):
         """
         Print a report of all the SQL statements executed to date.
         """
-        
+
         toFile = StringIO()
         toFile.write("*** SQL Stats ***\n")
         toFile.write("\n")
@@ -283,7 +283,7 @@
             toFile.write("Rows: %s\n" % (rows,))
             toFile.write("Time (ms): %.3f\n" % (t,))
         toFile.write("***\n\n")
-        
+
         if self.logFileName:
             open(self.logFileName, "a").write(toFile.getvalue())
         else:
@@ -294,7 +294,7 @@
     Object that monitors the state of a transaction over time and logs or times out
     the transaction.
     """
-    
+
     callLater = reactor.callLater
 
     def __init__(self, txn, logTimerSeconds, timeoutSeconds):
@@ -303,13 +303,13 @@
         self.delayedTimeout = None
         self.logTimerSeconds = logTimerSeconds
         self.timeoutSeconds = timeoutSeconds
-        
+
         self.txn.postCommit(self._cleanTxn)
         self.txn.postAbort(self._cleanTxn)
-        
+
         self._installLogTimer()
         self._installTimeout()
-    
+
     def _cleanTxn(self):
         self.txn = None
         if self.delayedLog:
@@ -327,7 +327,7 @@
 
         if self.logTimerSeconds:
             self.delayedLog = self.callLater(self.logTimerSeconds, _logTransactionWait)
-    
+
     def _installTimeout(self):
         def _forceAbort():
             if self.txn is not None:
@@ -439,7 +439,7 @@
     def _calendarserver(cls): #@NoSelf
         cs = schema.CALENDARSERVER
         return Select(
-            [cs.VALUE,],
+            [cs.VALUE, ],
             From=cs,
             Where=cs.NAME == Parameter('name'),
         )
@@ -759,7 +759,7 @@
         """
         Execute some SQL (delegate to L{IAsyncTransaction}).
         """
-        if self._stats:        
+        if self._stats:
             statsContext = self._stats.startStatement(a[0], a[1])
         self.currentStatement = a[0]
         if self._store.logTransactionWaits and a[0].split(" ", 1)[0].lower() in ("insert", "update", "delete",):
@@ -773,7 +773,7 @@
             results = (yield self._sqlTxn.execSQL(*a, **kw))
         finally:
             self.currentStatement = None
-            if self._stats:        
+            if self._stats:
                 self._stats.endStatement(statsContext, results)
         returnValue(results)
 
@@ -828,9 +828,9 @@
             ],
             From=ch.join(co).join(cb).join(tr),
             Where=(
-                ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID     ).And(
-                tr.CALENDAR_OBJECT_RESOURCE_ID == co.RESOURCE_ID   ).And(
-                cb.CALENDAR_RESOURCE_ID == tr.CALENDAR_RESOURCE_ID ).And(
+                ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID).And(
+                tr.CALENDAR_OBJECT_RESOURCE_ID == co.RESOURCE_ID).And(
+                cb.CALENDAR_RESOURCE_ID == tr.CALENDAR_RESOURCE_ID).And(
                 cb.BIND_MODE == _BIND_MODE_OWN
             ),
             GroupBy=(
@@ -943,7 +943,7 @@
         count = 0
         for dropboxID, path in results:
             attachment = Attachment(self, dropboxID, path)
-            (yield attachment.remove( ))
+            (yield attachment.remove())
             count += 1
         returnValue(count)
 
@@ -969,10 +969,10 @@
     _notifierPrefix = None
     _revisionsTable = None
     _notificationRevisionsTable = NOTIFICATION_OBJECT_REVISIONS_TABLE
-    
+
     _dataVersionKey = None
     _dataVersionValue = None
-    
+
     _cacher = None  # Initialize in derived classes
 
     def __init__(self, transaction, ownerUID, notifiers):
@@ -1189,7 +1189,7 @@
 
         @return: an iterable of C{str}s.
         """
-        
+
         if self._childrenLoaded:
             return succeed(self._children.keys())
         else:
@@ -1201,7 +1201,7 @@
         Retrieve the names of the invited children in this home.
 
         @return: an iterable of C{str}s.
-        """ 
+        """
         return self._childClass.listInvitedObjects(self)
 
 
@@ -1380,12 +1380,12 @@
                                     rev.RESOURCE_ID == shareID)).on(self._txn))
                     if name
                 ]
-    
+
                 for path, name, wasdeleted in results:
                     if wasdeleted:
                         if sharetoken:
                             deleted.append("%s/%s" % (path, name,))
-    
+
                 for path, name, wasdeleted in results:
                     changed.append("%s/%s" % (path, name,))
 
@@ -1551,7 +1551,7 @@
                                            resourceID=self._resourceID)
             self._quotaUsedBytes = 0
 
-    
+
     def addNotifier(self, notifier):
         if self._notifiers is None:
             self._notifiers = ()
@@ -1614,7 +1614,7 @@
             yield self._lockLastModifiedQuery.on(subtxn, resourceID=self._resourceID)
             result = (yield self._changeLastModifiedQuery.on(subtxn, resourceID=self._resourceID))
             returnValue(result)
-            
+
         try:
             self._modified = (yield self._txn.subtransaction(_bumpModified, retries=0, failureOK=True))[0][0]
             queryCacher = self._txn._queryCacher
@@ -1642,7 +1642,20 @@
             self._txn.notificationAddedForObject(self)
 
 
+    @inlineCallbacks
+    def removeUnacceptedShares(self):
+        """
+        Unbinds any collections that have been shared to this home but not yet
+        accepted.  Associated invite entries are also removed.
+        """
+        bind = self._bindSchema
+        kwds = {"homeResourceID" : self._resourceID}
+        yield Delete(
+            From=bind,
+            Where=(bind.HOME_RESOURCE_ID == Parameter("homeResourceID")).And(bind.BIND_STATUS != _BIND_STATUS_ACCEPTED)
+        ).on(self._txn, **kwds)
 
+
 class _SharedSyncLogic(object):
     """
     Logic for maintaining sync-token shared between notification collections and
@@ -1690,7 +1703,7 @@
 
     @inlineCallbacks
     def resourceNamesSinceToken(self, token):
-        
+
         if token is None:
             token = 0
         elif isinstance(token, str):
@@ -1913,16 +1926,16 @@
                 self._syncTokenRevision = rows[0][0]
             else:
                 action = "insert"
-        
+
         if action == "insert":
             # Note that an "insert" may happen for a resource that previously
             # existed and then was deleted. In that case an entry in the
             # REVISIONS table still exists so we have to detect that and do db
             # INSERT or UPDATE as appropriate
 
-            found = bool( (
+            found = bool((
                 yield self._insertFindPreviouslyNamedQuery.on(
-                    self._txn, resourceID=self._resourceID, name=name)) )
+                    self._txn, resourceID=self._resourceID, name=name)))
             if found:
                 self._syncTokenRevision = (
                     yield self._updatePreviouslyNamedQuery.on(
@@ -1957,19 +1970,19 @@
 
     _objectResourceClass = None
 
-    _bindSchema              = None
-    _homeSchema              = None
-    _homeChildSchema          = None
+    _bindSchema = None
+    _homeSchema = None
+    _homeChildSchema = None
     _homeChildMetaDataSchema = None
-    _revisionsSchema          = None
-    _objectSchema              = None
+    _revisionsSchema = None
+    _objectSchema = None
 
-    _bindTable           = None
-    _homeChildTable      = None
-    _homeChildBindTable  = None
-    _revisionsTable      = None
-    _revisionsBindTable  = None
-    _objectTable         = None
+    _bindTable = None
+    _homeChildTable = None
+    _homeChildBindTable = None
+    _revisionsTable = None
+    _revisionsBindTable = None
+    _objectTable = None
 
 
     def __init__(self, home, name, resourceID, mode, status, message=None, ownerHome=None):
@@ -1981,20 +1994,20 @@
         else:
             notifiers = None
 
-        self._home              = home
-        self._name              = name
-        self._resourceID        = resourceID
-        self._bindMode          = mode
-        self._bindStatus         = status
-        self._bindMessage         = message
-        self._ownerHome         = home if ownerHome is None else ownerHome
-        self._created           = None
-        self._modified          = None
-        self._objects           = {}
-        self._objectNames       = None
+        self._home = home
+        self._name = name
+        self._resourceID = resourceID
+        self._bindMode = mode
+        self._bindStatus = status
+        self._bindMessage = message
+        self._ownerHome = home if ownerHome is None else ownerHome
+        self._created = None
+        self._modified = None
+        self._objects = {}
+        self._objectNames = None
         self._syncTokenRevision = None
-        self._notifiers         = notifiers
-        self._index             = None  # Derived classes need to set this
+        self._notifiers = notifiers
+        self._index = None  # Derived classes need to set this
 
 
     @classproperty
@@ -2013,14 +2026,14 @@
         different child classes to have their own type specific data, but still make use of the
         common base logic.
         """
-        
+
         # Common behavior is to have created and modified
-        
+
         return (
             cls._homeChildMetaDataSchema.CREATED,
             cls._homeChildMetaDataSchema.MODIFIED,
         )
-        
+
     @classmethod
     def metadataAttributes(cls):
         """
@@ -2028,14 +2041,14 @@
         different child classes to have their own type specific data, but still make use of the
         common base logic.
         """
-        
+
         # Common behavior is to have created and modified
-        
+
         return (
             "_created",
             "_modified",
         )
-        
+
     @classmethod
     @inlineCallbacks
     def listObjects(cls, home):
@@ -2137,10 +2150,10 @@
         @return: the name of the shared calendar in the new calendar home.
         @rtype: L{str}
         """
-        
+
         if status is None:
             status = _BIND_STATUS_ACCEPTED
-        
+
         @inlineCallbacks
         def doInsert(subt):
             newName = str(uuid4())
@@ -2160,7 +2173,7 @@
                 mode=mode, status=status, message=message,
                 resourceID=self._resourceID, homeID=shareeHome._resourceID
             ))[0][0]
-                
+
         # Must send notification to ensure cache invalidation occurs
         yield self.notifyChanged()
 
@@ -2200,24 +2213,24 @@
 
         #remove None parameters, and substitute None for empty string
         bind = self._bindSchema
-        columnMap = dict([(k, v if v else None) 
-                          for k,v in {bind.BIND_MODE:mode,
+        columnMap = dict([(k, v if v else None)
+                          for k, v in {bind.BIND_MODE:mode,
                             bind.BIND_STATUS:status,
                             bind.MESSAGE:message,
                             bind.RESOURCE_NAME:name}.iteritems() if v is not None])
-                                
+
         if len(columnMap):
-            
+
             #TODO:  with bit of parameter wrangling, call shareWith() here instead.
             sharedname = yield self._updateBindColumnsQuery(columnMap).on(
                             self._txn,
                             resourceID=self._resourceID, homeID=shareeView._home._resourceID
                         )
-            
+
             #update affected attributes
             if mode:
                 shareeView._bindMode = columnMap[bind.BIND_MODE]
-                
+
             if status:
                 shareeView._bindStatus = columnMap[bind.BIND_STATUS]
                 if shareeView._bindStatus == _BIND_STATUS_ACCEPTED:
@@ -2227,21 +2240,21 @@
 
             if message:
                 shareeView._bindMessage = columnMap[bind.MESSAGE]
-            
+
             queryCacher = self._txn._queryCacher
             if queryCacher:
                 cacheKey = queryCacher.keyForObjectWithName(shareeView._home._resourceID, shareeView._name)
                 queryCacher.invalidateAfterCommit(self._txn, cacheKey)
-            
+
             shareeView._name = sharedname[0][0]
 
             # Must send notification to ensure cache invalidation occurs
             yield self.notifyChanged()
-                    
+
         returnValue(shareeView._name)
-        
 
 
+
     @inlineCallbacks
     def unshareWith(self, shareeHome):
         """
@@ -2255,14 +2268,14 @@
 
         @return: a L{Deferred} which will fire with the previously-used name.
         """
-        
-        
+
+
         #remove sync tokens
         shareeChildren = yield shareeHome.children()
         for shareeChild in shareeChildren:
             if not shareeChild.owned() and shareeChild._resourceID == self._resourceID:
                 shareeChild._deletedSyncToken(sharedRemoval=True);
- 
+
                 queryCacher = self._txn._queryCacher
                 if queryCacher:
                     cacheKey = queryCacher.keyForObjectWithName(shareeHome._resourceID, shareeChild._name)
@@ -2278,15 +2291,15 @@
             Return=bind.RESOURCE_NAME,
         ).on(self._txn, resourceID=self._resourceID,
              homeID=shareeHome._resourceID)
-        
+
         resourceName = None
         if rows:
             resourceName = rows[0][0]
             shareeHome._children.pop(resourceName, None)
-        
+
         # Must send notification to ensure cache invalidation occurs
         yield self.notifyChanged()
-       
+
         returnValue(resourceName)
 
 
@@ -2361,9 +2374,9 @@
                             .And(bind.BIND_STATUS == _BIND_STATUS_ACCEPTED)
                             .And(bind.BIND_MODE != _BIND_MODE_OWN)
                             )
-    
 
 
+
     @inlineCallbacks
     def asShared(self):
         """
@@ -2422,7 +2435,7 @@
         """
         if not self.owned():
             returnValue([])
-        
+
         rows = yield self._invitedBindForResourceID.on(
             self._txn, resourceID=self._resourceID, homeID=self._home._resourceID,
         )
@@ -2459,7 +2472,7 @@
         dataRows = (yield cls._childrenAndMetadataForHomeID.on(home._txn, homeID=home._resourceID))
 
         if dataRows:
-            
+
             # Get property stores for all these child resources (if any found)
             propertyStores = (yield PropertyStore.forMultipleResources(
                 home.uid(), home._txn,
@@ -2481,8 +2494,8 @@
         # Create the actual objects merging in properties
         for items in dataRows:
             bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage = items[:6] #@UnusedVariable
-            metadata=items[7:]
-            
+            metadata = items[7:]
+
             if bindStatus == _BIND_MODE_OWN:
                 ownerHome = home
             else:
@@ -2537,7 +2550,7 @@
             returnValue(None)
 
         bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage = rows[0] #@UnusedVariable
-        
+
         #TODO:  combine with _invitedBindForNameAndHomeID and sort results
         ownerHomeID = (yield cls._ownerHomeWithResourceID.on(
                         home._txn, resourceID=resourceID))[0][0]
@@ -2578,16 +2591,16 @@
         """
         rows = None
         queryCacher = home._txn._queryCacher
-        
+
         if queryCacher:
             # Retrieve data from cache
             cacheKey = queryCacher.keyForObjectWithName(home._resourceID, name)
             rows = yield queryCacher.get(cacheKey)
-            
+
         if rows is None:
             # No cached copy
             rows = yield cls._childForNameAndHomeID.on(home._txn, name=name, homeID=home._resourceID)
-                    
+
             if rows:
                 bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage = rows[0] #@UnusedVariable
                 # get ownerHomeID                
@@ -2597,21 +2610,21 @@
                     ownerHomeID = (yield cls._ownerHomeWithResourceID.on(
                                     home._txn, resourceID=resourceID))[0][0]
                 rows[0].append(ownerHomeID)
-            
+
             if rows and queryCacher:
                 # Cache the result
                 queryCacher.setAfterCommit(home._txn, cacheKey, rows)
-        
+
         if not rows:
             returnValue(None)
-        
+
         bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage, ownerHomeID = rows[0] #@UnusedVariable
-        
+
         if bindMode == _BIND_MODE_OWN:
             ownerHome = home
         else:
             ownerHome = yield home._txn.homeWithResourceID(home._homeType, ownerHomeID)
-            
+
         child = cls(
             home=home,
             name=name, resourceID=resourceID,
@@ -2632,8 +2645,8 @@
         return cls._bindFor((bind.RESOURCE_ID == Parameter("resourceID"))
                                .And(bind.HOME_RESOURCE_ID == Parameter("homeID"))
                                )
-                               
-                               
+
+
     @classmethod
     @inlineCallbacks
     def objectWithID(cls, home, resourceID):
@@ -2650,9 +2663,9 @@
             home._txn, resourceID=resourceID, homeID=home._resourceID)
         if not rows:
             returnValue(None)
-                
+
         bindMode, homeID, resourceID, resourceName, bindStatus, bindMessage = rows[0] #@UnusedVariable
-        
+
         if bindMode == _BIND_MODE_OWN:
             ownerHome = home
         else:
@@ -2663,7 +2676,7 @@
             home=home,
             name=resourceName, resourceID=resourceID,
             mode=bindMode, status=bindStatus,
-            message=bindMessage,  ownerHome=ownerHome,
+            message=bindMessage, ownerHome=ownerHome,
         )
         yield child.initFromStore()
         returnValue(child)
@@ -2887,9 +2900,9 @@
 
         # Set to non-existent state
         self._resourceID = None
-        self._created    = None
-        self._modified   = None
-        self._objects    = {}
+        self._created = None
+        self._modified = None
+        self._objects = {}
 
         yield self.notifyChanged()
 
@@ -3140,7 +3153,7 @@
 
     @inlineCallbacks
     def removeObjectResourceWithName(self, name):
-        
+
         child = (yield self.objectResourceWithName(name))
         if child is None:
             raise NoSuchObjectResourceError
@@ -3149,7 +3162,7 @@
 
     @inlineCallbacks
     def removeObjectResourceWithUID(self, uid):
-        
+
         child = (yield self.objectResourceWithUID(uid))
         if child is None:
             raise NoSuchObjectResourceError
@@ -3161,7 +3174,7 @@
         uid = child.uid()
         try:
             yield child.remove()
-        finally:        
+        finally:
             self._objects.pop(name, None)
             self._objects.pop(uid, None)
             yield self._deleteRevision(name)
@@ -3209,7 +3222,7 @@
         self._objects.pop(child._resourceID, None)
         yield self._deleteRevision(name)
         yield self.notifyChanged()
-        
+
         # Adjust the child to be a child of the new parent and update ancillary tables
         yield self._moveParentUpdateQuery.on(
             self._txn,
@@ -3279,7 +3292,7 @@
         if self._notifiers is None:
             self._notifiers = ()
         self._notifiers += (notifier,)
- 
+
     def notifierID(self, label="default"):
         if self._notifiers:
             return self._notifiers[0].getID(label)
@@ -3387,7 +3400,7 @@
         self._created = None
         self._modified = None
         self._objectText = None
-        
+
         self._locked = False
 
 
@@ -3458,9 +3471,9 @@
             result_batch = (yield cls._loadAllObjectsWithNames(parent, names[:cls.BATCH_LOAD_SIZE]))
             results.extend(result_batch)
             names = names[cls.BATCH_LOAD_SIZE:]
-        
+
         returnValue(results)
-            
+
     @classmethod
     @inlineCallbacks
     def _loadAllObjectsWithNames(cls, parent, names):
@@ -3525,14 +3538,14 @@
 
         if name.startswith("."):
             raise ObjectResourceNameNotAllowedError(name)
-        
+
         objectResource = cls(parent, name, None, None, metadata=metadata)
         yield objectResource.setComponent(component, inserting=True)
         yield objectResource._loadPropertyStore(created=True)
 
         # Note: setComponent triggers a notification, so we don't need to
         # call notify( ) here like we do for object removal.
-        
+
         returnValue(objectResource)
 
 
@@ -3644,7 +3657,7 @@
         self.initPropertyStore(props)
         self._propertyStore = props
 
-    
+
     def properties(self):
         return self._propertyStore
 
@@ -3695,7 +3708,7 @@
         @raise: L{NoSuchObjectResourceError} if resource does not exist, other L{Exception}
                 if already locked and NOWAIT is used.
         """
-        
+
         txn = txn if txn is not None else self._txn
         yield self._selectForUpdateQuery(not wait).on(txn, NoSuchObjectResourceError, resourceID=self._resourceID)
         self._locked = True
@@ -3920,16 +3933,16 @@
 
     def uid(self):
         return self._uid
-    
 
+
     def owned(self):
         return True
 
 
     def ownerHome(self):
         return self._home
-    
 
+
     def viewerHome(self):
         return self._home
 
@@ -4056,7 +4069,7 @@
         if self._notifiers is None:
             self._notifiers = ()
         self._notifiers += (notifier,)
- 
+
     def notifierID(self, label="default"):
         if self._notifiers:
             return self._notifiers[0].getID(label)

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql	2012-10-03 21:21:42 UTC (rev 9891)
@@ -81,24 +81,7 @@
 );
 
 
-------------------------
--- Sharing Invitation --
-------------------------
 
-create table INVITE (
-    INVITE_UID         varchar(255) not null,
-    NAME               varchar(255) not null,
-    RECIPIENT_ADDRESS  varchar(255) not null,
-    HOME_RESOURCE_ID   integer      not null,
-    RESOURCE_ID        integer      not null
-
-    -- Need primary key on (INVITE_UID, NAME, RECIPIENT_ADDRESS)?
-);
-
-create index INVITE_INVITE_UID on INVITE(INVITE_UID);
-create index INVITE_RESOURCE_ID on INVITE(RESOURCE_ID);
-create index INVITE_HOME_RESOURCE_ID on INVITE(HOME_RESOURCE_ID);
-
 ---------------------------
 -- Sharing Notifications --
 ---------------------------

Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py	2012-10-03 09:52:28 UTC (rev 9890)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py	2012-10-03 21:21:42 UTC (rev 9891)
@@ -22,7 +22,7 @@
 from hashlib import md5
 from random import Random
 from zope.interface.verify import verifyObject
-from zope.interface.exceptions import BrokenMethodImplementation,\
+from zope.interface.exceptions import BrokenMethodImplementation, \
     DoesNotImplement
 
 from twext.python.filepath import CachingFilePath
@@ -96,7 +96,7 @@
         return PostgresService(
             dbRoot, serviceFactory, current_sql_schema, resetSchema=True,
             databaseName="caldav",
-            options = [
+            options=[
                 "-c log_lock_waits=TRUE",
                 "-c log_statement=all",
                 "-c log_line_prefix='%p.%x '",
@@ -206,8 +206,7 @@
         )
         # TODO: should be getting these tables from a declaration of the schema
         # somewhere.
-        tables = ['INVITE',
-                  'RESOURCE_PROPERTY',
+        tables = ['RESOURCE_PROPERTY',
                   'ATTACHMENT',
                   'NOTIFICATION_OBJECT_REVISIONS',
                   'ADDRESSBOOK_OBJECT_REVISIONS',
@@ -224,7 +223,7 @@
                   'NOTIFICATION_HOME']
         for table in tables:
             try:
-                yield cleanupTxn.execSQL("delete from "+table, [])
+                yield cleanupTxn.execSQL("delete from " + table, [])
             except:
                 log.err()
         yield cleanupTxn.commit()
@@ -376,7 +375,7 @@
                         yield calendar.createCalendarObjectWithName(
                             objectName,
                             VComponent.fromString(updateToCurrentYear(objData)),
-                            metadata = metadata,
+                            metadata=metadata,
                         )
     yield populateTxn.commit()
 
@@ -385,7 +384,7 @@
     """
     Update the supplied iCalendar data so that all dates are updated to the current year.
     """
-    
+
     nowYear = PyCalendarDateTime.getToday().getYear()
     return data % {"now":nowYear}
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121003/8351c8bc/attachment-0001.html>


More information about the calendarserver-changes mailing list