示例#1
0
    def publish(self, collection, displayName=None, activity=None, filters=None,
        overwrite=False, options=None):

        from ics import ICSSerializer
        from translator import SharingTranslator
        from eimml import EIMMLSerializer


        rv = self.itsView

        # Stamp the collection
        if not pim.has_stamp(collection, SharedItem):
            SharedItem(collection).add()

        conduit = webdav_conduit.WebDAVRecordSetConduit(itsView=rv,
            account=self)

        # Interrogate the server associated with the account

        location = self.getLocation()
        if not location.endswith("/"):
            location += "/"
        handle = conduit._getServerHandle()
        resource = handle.getResource(location)

        logger.debug('Examining %s ...', location.encode('utf8', 'replace'))
        exists = handle.blockUntil(resource.exists)
        if not exists:
            logger.debug("...doesn't exist")
            raise errors.NotFound(_(u"%(location)s does not exist.") %
                {'location': location})

        isCalendar = handle.blockUntil(resource.isCalendar)
        logger.debug('...Calendar?  %s', isCalendar)
        isCollection =  handle.blockUntil(resource.isCollection)
        logger.debug('...Collection?  %s', isCollection)

        response = handle.blockUntil(resource.options)
        dav = response.headers.getHeader('DAV')
        logger.debug('...DAV:  %s', dav)
        allowed = response.headers.getHeader('Allow')
        logger.debug('...Allow:  %s', allowed)
        supportsTickets = handle.blockUntil(resource.supportsTickets)
        logger.debug('...Tickets?:  %s', supportsTickets)

        conduit.delete(True) # Clean up the temporary conduit


        # Prepare the share

        share = None

        try:

            if isCalendar:
                # We've been handed a calendar directly.  Just publish directly
                # into this calendar collection rather than making a new one.
                # Create a CalDAV share with empty sharename, doing a GET and
                # PUT

                share = Share(itsView=rv, contents=collection)
                conduit = caldav_conduit.CalDAVRecordSetConduit(itsParent=share,
                    account=self, shareName=u"", translator=SharingTranslator,
                    serializer=ICSSerializer)
                share.conduit = conduit
                if filters:
                    conduit.filters = filters

                share.displayName = displayName or collection.displayName

                alias = 'main'
                try:
                    SharedItem(collection).shares.append(share, alias)
                except ValueError:
                    # There is already a 'main' share for this collection
                    SharedItem(collection).shares.append(share)

                share.sync(activity=activity)

            else:
                # the collection should be published
                # determine a share name
                existing = utility.getExistingResources(self)
                displayName = displayName or collection.displayName

                shareName = displayName

                alias = 'main'

                # See if there are any non-ascii characters, if so, just use
                # UUID
                try:
                    shareName.encode('ascii')
                    pattern = re.compile('[^A-Za-z0-9]')
                    shareName = re.sub(pattern, "_", shareName)
                except UnicodeEncodeError:
                    shareName = unicode(collection.itsUUID)

                # Append .ics extension of publishing a monolithic .ics file
                if options.get('ics', False):
                    shareName = shareName + ".ics"

                shareName = self._uniqueName(shareName, existing)

                if ('calendar-access' in dav or 'MKCALENDAR' in allowed):
                    # We're speaking to a CalDAV server

                    share = Share(itsView=rv, contents=collection)
                    conduit = caldav_conduit.CalDAVRecordSetConduit(
                        itsParent=share,
                        account=self, shareName=shareName,
                        translator=SharingTranslator, serializer=ICSSerializer)
                    share.conduit = conduit
                    if filters:
                        conduit.filters = filters

                    share.displayName = displayName or collection.displayName

                    try:
                        SharedItem(collection).shares.append(share, alias)
                    except ValueError:
                        # There is already a 'main' share for this collection
                        SharedItem(collection).shares.append(share)

                    if share.exists():
                        raise errors.SharingError(_(u"Collection already exists on server."))

                    share.create()
                    # bug 8128, this setDisplayName shouldn't be required, but
                    # cosmo isn't accepting setting displayname in MKCALENDAR
                    share.conduit.setDisplayName(displayName)

                    share.put(activity=activity)

                    # tickets after putting
                    if supportsTickets:
                        share.conduit.createTickets()


                elif dav is not None:

                    # We're speaking to a WebDAV server
                    # Use monolithic ics if options['ics'], else use EIMML

                    share = Share(itsView=rv, contents=collection)

                    if options.get('ics', False):
                        # ICS
                        conduit = webdav_conduit.WebDAVMonolithicRecordSetConduit(
                            itsParent=share,
                            shareName=shareName, account=self,
                            translator=SharingTranslator,
                            serializer=ICSSerializer)

                    else:
                        conduit = webdav_conduit.WebDAVRecordSetConduit(
                            itsParent=share,
                            shareName=shareName, account=self,
                            translator=SharingTranslator,
                            serializer=EIMMLSerializer)

                    share.conduit = conduit
                    if filters:
                        conduit.filters = filters

                    try:
                        SharedItem(collection).shares.append(share, alias)
                    except ValueError:
                        # There is already a 'main' share for this collection
                        SharedItem(collection).shares.append(share)

                    if share.exists():
                        raise errors.SharingError(_(u"Collection already exists on server."))

                    share.create()
                    share.put(activity=activity)

                    if supportsTickets:
                        share.conduit.createTickets()


        except (errors.SharingError,
                zanshin.error.Error,
                M2Crypto.SSL.Checker.WrongHost,
                CertificateVerificationError,
                twisted.internet.error.TimeoutError), e:

            # Clean up share objects
            try:
                share.delete(True)
            except:
                pass # ignore stale shares

            # Note: the following "raise e" line used to just read "raise".
            # However, if the try block immediately preceeding this comment
            # raises an exception, the "raise" following this comment was
            # raising that *new* exception instead of the original exception
            # that got us here, "e".
            raise e
示例#2
0
    def publish(self,
                collection,
                displayName=None,
                activity=None,
                filters=None,
                overwrite=False,
                options=None):

        from ics import ICSSerializer
        from translator import SharingTranslator
        from eimml import EIMMLSerializer

        rv = self.itsView

        # Stamp the collection
        if not pim.has_stamp(collection, SharedItem):
            SharedItem(collection).add()

        conduit = webdav_conduit.WebDAVRecordSetConduit(itsView=rv,
                                                        account=self)

        # Interrogate the server associated with the account

        location = self.getLocation()
        if not location.endswith("/"):
            location += "/"
        handle = conduit._getServerHandle()
        resource = handle.getResource(location)

        logger.debug('Examining %s ...', location.encode('utf8', 'replace'))
        exists = handle.blockUntil(resource.exists)
        if not exists:
            logger.debug("...doesn't exist")
            raise errors.NotFound(
                _(u"%(location)s does not exist.") % {'location': location})

        isCalendar = handle.blockUntil(resource.isCalendar)
        logger.debug('...Calendar?  %s', isCalendar)
        isCollection = handle.blockUntil(resource.isCollection)
        logger.debug('...Collection?  %s', isCollection)

        response = handle.blockUntil(resource.options)
        dav = response.headers.getHeader('DAV')
        logger.debug('...DAV:  %s', dav)
        allowed = response.headers.getHeader('Allow')
        logger.debug('...Allow:  %s', allowed)
        supportsTickets = handle.blockUntil(resource.supportsTickets)
        logger.debug('...Tickets?:  %s', supportsTickets)

        conduit.delete(True)  # Clean up the temporary conduit

        # Prepare the share

        share = None

        try:

            if isCalendar:
                # We've been handed a calendar directly.  Just publish directly
                # into this calendar collection rather than making a new one.
                # Create a CalDAV share with empty sharename, doing a GET and
                # PUT

                share = Share(itsView=rv, contents=collection)
                conduit = caldav_conduit.CalDAVRecordSetConduit(
                    itsParent=share,
                    account=self,
                    shareName=u"",
                    translator=SharingTranslator,
                    serializer=ICSSerializer)
                share.conduit = conduit
                if filters:
                    conduit.filters = filters

                share.displayName = displayName or collection.displayName

                alias = 'main'
                try:
                    SharedItem(collection).shares.append(share, alias)
                except ValueError:
                    # There is already a 'main' share for this collection
                    SharedItem(collection).shares.append(share)

                share.sync(activity=activity)

            else:
                # the collection should be published
                # determine a share name
                existing = utility.getExistingResources(self)
                displayName = displayName or collection.displayName

                shareName = displayName

                alias = 'main'

                # See if there are any non-ascii characters, if so, just use
                # UUID
                try:
                    shareName.encode('ascii')
                    pattern = re.compile('[^A-Za-z0-9]')
                    shareName = re.sub(pattern, "_", shareName)
                except UnicodeEncodeError:
                    shareName = unicode(collection.itsUUID)

                # Append .ics extension of publishing a monolithic .ics file
                if options.get('ics', False):
                    shareName = shareName + ".ics"

                shareName = self._uniqueName(shareName, existing)

                if ('calendar-access' in dav or 'MKCALENDAR' in allowed):
                    # We're speaking to a CalDAV server

                    share = Share(itsView=rv, contents=collection)
                    conduit = caldav_conduit.CalDAVRecordSetConduit(
                        itsParent=share,
                        account=self,
                        shareName=shareName,
                        translator=SharingTranslator,
                        serializer=ICSSerializer)
                    share.conduit = conduit
                    if filters:
                        conduit.filters = filters

                    share.displayName = displayName or collection.displayName

                    try:
                        SharedItem(collection).shares.append(share, alias)
                    except ValueError:
                        # There is already a 'main' share for this collection
                        SharedItem(collection).shares.append(share)

                    if share.exists():
                        raise errors.SharingError(
                            _(u"Collection already exists on server."))

                    share.create()
                    # bug 8128, this setDisplayName shouldn't be required, but
                    # cosmo isn't accepting setting displayname in MKCALENDAR
                    share.conduit.setDisplayName(displayName)

                    share.put(activity=activity)

                    # tickets after putting
                    if supportsTickets:
                        share.conduit.createTickets()

                elif dav is not None:

                    # We're speaking to a WebDAV server
                    # Use monolithic ics if options['ics'], else use EIMML

                    share = Share(itsView=rv, contents=collection)

                    if options.get('ics', False):
                        # ICS
                        conduit = webdav_conduit.WebDAVMonolithicRecordSetConduit(
                            itsParent=share,
                            shareName=shareName,
                            account=self,
                            translator=SharingTranslator,
                            serializer=ICSSerializer)

                    else:
                        conduit = webdav_conduit.WebDAVRecordSetConduit(
                            itsParent=share,
                            shareName=shareName,
                            account=self,
                            translator=SharingTranslator,
                            serializer=EIMMLSerializer)

                    share.conduit = conduit
                    if filters:
                        conduit.filters = filters

                    try:
                        SharedItem(collection).shares.append(share, alias)
                    except ValueError:
                        # There is already a 'main' share for this collection
                        SharedItem(collection).shares.append(share)

                    if share.exists():
                        raise errors.SharingError(
                            _(u"Collection already exists on server."))

                    share.create()
                    share.put(activity=activity)

                    if supportsTickets:
                        share.conduit.createTickets()

        except (errors.SharingError, zanshin.error.Error,
                M2Crypto.SSL.Checker.WrongHost, CertificateVerificationError,
                twisted.internet.error.TimeoutError), e:

            # Clean up share objects
            try:
                share.delete(True)
            except:
                pass  # ignore stale shares

            # Note: the following "raise e" line used to just read "raise".
            # However, if the try block immediately preceeding this comment
            # raises an exception, the "raise" following this comment was
            # raising that *new* exception instead of the original exception
            # that got us here, "e".
            raise e