def test_fail_dot_file_put_in_calendar(self): """ Make (regular) collection in calendar """ calendar_uri = "/calendars/users/wsanchez/dot_file_in_calendar/" principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez") request = SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authPrincipal=principal) response = yield self.send(request) response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code, )) stream = self.dataPath.child("Holidays").child( "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics").open() try: calendar = str(Component.fromStream(stream)) finally: stream.close() event_uri = "/".join([calendar_uri, ".event.ics"]) request = SimpleStoreRequest(self, "PUT", event_uri, authPrincipal=principal) request.headers.setHeader("content-type", MimeType("text", "calendar")) request.stream = MemoryStream(calendar) response = yield self.send(request) response = IResponse(response) if response.code != responsecode.FORBIDDEN: self.fail("Incorrect response to dot file PUT: %s" % (response.code, ))
def _db_recreate(self, do_commit=True): """ Re-create the database tables from existing calendar data. """ # # Populate the DB with data from already existing resources. # This allows for index recovery if the DB file gets # deleted. # fp = self.resource.fp for name in fp.listdir(): if name.startswith("."): continue try: stream = fp.child(name).open() except (IOError, OSError), e: log.err("Unable to open resource %s: %s" % (name, e)) continue # FIXME: This is blocking I/O try: calendar = Component.fromStream(stream) calendar.validCalendarData() calendar.validCalendarForCalDAV(methodAllowed=True) except ValueError: log.err("Non-calendar resource: %s" % (name,)) else: #log.msg("Indexing resource: %s" % (name,)) self.addResource(name, calendar, True, reCreate=True) finally: stream.close()
def mkcalendar_cb(response): response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) def put_cb(response): response = IResponse(response) if response.code != responsecode.FORBIDDEN: self.fail("Incorrect response to dot file PUT: %s" % (response.code,)) stream = self.dataPath.child( "Holidays").child( "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics" ).open() try: calendar = str(Component.fromStream(stream)) finally: stream.close() event_uri = "/".join([calendar_uri, ".event.ics"]) request = SimpleRequest(self.site, "PUT", event_uri) request.headers.setHeader("content-type", MimeType("text", "calendar")) request.stream = MemoryStream(calendar) return self.send(request, put_cb)
def _db_recreate(self, do_commit=True): """ Re-create the database tables from existing calendar data. """ # # Populate the DB with data from already existing resources. # This allows for index recovery if the DB file gets # deleted. # fp = self.resource.fp for name in fp.listdir(): if name.startswith("."): continue try: stream = fp.child(name).open() except (IOError, OSError), e: log.error("Unable to open resource %s: %s" % (name, e)) continue # FIXME: This is blocking I/O try: calendar = Component.fromStream(stream) calendar.validCalendarData() calendar.validCalendarForCalDAV(methodAllowed=True) except ValueError: log.error("Non-calendar resource: %s" % (name, )) else: #log.info("Indexing resource: %s" % (name,)) self.addResource(name, calendar, True, reCreate=True) finally: stream.close()
def test_fail_dot_file_put_in_calendar(self): """ Make (regular) collection in calendar """ calendar_uri = "/calendars/users/wsanchez/dot_file_in_calendar/" principal = yield self.actualRoot.findPrincipalForAuthID("wsanchez") request = SimpleStoreRequest(self, "MKCALENDAR", calendar_uri, authPrincipal=principal) response = yield self.send(request) response = IResponse(response) if response.code != responsecode.CREATED: self.fail("MKCALENDAR failed: %s" % (response.code,)) stream = self.dataPath.child( "Holidays").child( "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics" ).open() try: calendar = str(Component.fromStream(stream)) finally: stream.close() event_uri = "/".join([calendar_uri, ".event.ics"]) request = SimpleStoreRequest(self, "PUT", event_uri, authPrincipal=principal) request.headers.setHeader("content-type", MimeType("text", "calendar")) request.stream = MemoryStream(calendar) response = yield self.send(request) response = IResponse(response) if response.code != responsecode.FORBIDDEN: self.fail("Incorrect response to dot file PUT: %s" % (response.code,))
def test_duplicate_uids(self): """ Mutiple resources with the same UID. """ stream = self.dataPath.child( "Holidays").child( "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics").open() try: calendar = str(Component.fromStream(stream)) finally: stream.close() return self._test_file_in_calendar( "mutiple resources with the same UID", (MemoryStream(calendar), responsecode.CREATED), (MemoryStream(calendar), responsecode.FORBIDDEN), )
def test_duplicate_uids(self): """ Mutiple resources with the same UID. """ stream = self.dataPath.child("Holidays").child( "C318AA54-1ED0-11D9-A5E0-000A958A3252.ics").open() try: calendar = str(Component.fromStream(stream)) finally: stream.close() return self._test_file_in_calendar( "mutiple resources with the same UID", (MemoryStream(calendar), responsecode.CREATED), (MemoryStream(calendar), responsecode.FORBIDDEN), )
def test_single_events(self): """ Single events in calendar collection """ work = [] stream = self.openHolidays() calendar = Component.fromStream(stream) for subcomponent in calendar.subcomponents(): if subcomponent.name() == "VEVENT": subcalendar = Component("VCALENDAR") subcalendar.addComponent(subcomponent) for property in calendar.properties(): subcalendar.addProperty(property) work.append((MemoryStream(str(subcalendar)), responsecode.CREATED)) return self._test_file_in_calendar("single event in calendar", *work)
def doTest(self, filename, dtstart, dtend, testEqual=True): if testEqual: testMethod = self.assertEqual else: testMethod = self.assertNotEqual calendar = Component.fromStream(file(os.path.join(self.data_dir, filename))) if calendar.name() != "VCALENDAR": self.fail("Calendar is not a VCALENDAR") instances = calendar.expandTimeRanges(datetime.date(2100, 1, 1)) for key in instances: instance = instances[key] start = instance.start end = instance.end testMethod(start, dtstart) testMethod(end, dtend) break;
def doTest(self, filename, dtstart, dtend, testEqual=True): if testEqual: testMethod = self.assertEqual else: testMethod = self.assertNotEqual calendar = Component.fromStream( file(os.path.join(self.data_dir, filename))) if calendar.name() != "VCALENDAR": self.fail("Calendar is not a VCALENDAR") instances = calendar.expandTimeRanges(DateTime(2100, 1, 1)) for key in instances: instance = instances[key] start = instance.start end = instance.end testMethod(start, dtstart) testMethod(end, dtend) break
def splitICalendarFile(inputFileName, outputDirectory): """ Reads iCalendar data from a file and outputs a separate file for each iCalendar component into a directory. This is useful for converting a monolithic iCalendar object into a set of objects that comply with CalDAV's requirements on resources. """ inputFile = open(inputFileName) try: calendar = iComponent.fromStream(inputFile) finally: inputFile.close() assert calendar.name() == "VCALENDAR" topLevelProperties = tuple(calendar.properties()) for subcomponent in calendar.subcomponents(): subcalendar = iComponent("VCALENDAR") # # Add top-level properties from monolithic calendar to # top-level properties of subcalendar. # for property in topLevelProperties: subcalendar.addProperty(property) subcalendar.addComponent(subcomponent) uid = subcalendar.resourceUID() subFileName = os.path.join(outputDirectory, uid + ".ics") print("Writing %s" % (subFileName,)) subcalendar_file = file(subFileName, "w") try: subcalendar_file.write(str(subcalendar)) finally: subcalendar_file.close()
def splitICalendarFile(inputFileName, outputDirectory): """ Reads iCalendar data from a file and outputs a separate file for each iCalendar component into a directory. This is useful for converting a monolithic iCalendar object into a set of objects that comply with CalDAV's requirements on resources. """ inputFile = open(inputFileName) try: calendar = iComponent.fromStream(inputFile) finally: inputFile.close() assert calendar.name() == "VCALENDAR" topLevelProperties = tuple(calendar.properties()) for subcomponent in calendar.subcomponents(): subcalendar = iComponent("VCALENDAR") # # Add top-level properties from monolithic calendar to # top-level properties of subcalendar. # for property in topLevelProperties: subcalendar.addProperty(property) subcalendar.addComponent(subcomponent) uid = subcalendar.resourceUID() subFileName = os.path.join(outputDirectory, uid + ".ics") print("Writing %s" % (subFileName, )) subcalendar_file = file(subFileName, "w") try: subcalendar_file.write(str(subcalendar)) finally: subcalendar_file.close()
class XML (twistedcaldav.test.util.TestCase): """ XML tests """ calendar_file = os.path.join(os.path.dirname(__file__), "data", "Holidays", "C3184A66-1ED0-11D9-A5E0-000A958A3252.ics") calendar = Component.fromStream(file(calendar_file)) calendar.validCalendarData() calendar.validCalendarForCalDAV(methodAllowed=False) def test_ComponentFilter(self): """ Component filter element. """ for component_name, has in ( ("VEVENT", True), ("VTODO", False), ): if has: no = "no " else: no = "" if has != storeComponentFilter( ComponentFilter( ComponentFilter( name=component_name ), name="VCALENDAR" ) ).match(self.calendar, None): self.fail("Calendar has %s%s?" % (no, component_name)) def test_PropertyFilter(self): """ Property filter element. """ for property_name, has in ( ("UID", True), ("BOOGER", False), ): if has: no = "no " else: no = "" if has != storeComponentFilter( ComponentFilter( ComponentFilter( PropertyFilter( name=property_name ), name="VEVENT" ), name="VCALENDAR" ) ).match(self.calendar, None): self.fail("Calendar has %sVEVENT with %s?" % (no, property_name)) def test_ParameterFilter(self): """ Parameter filter element. """ raise SkipTest("test unimplemented") def test_TextMatch(self): """ Text match element. """ for uid, caseless, has in ( ("C3184A66-1ED0-11D9-A5E0-000A958A3252", False, True), ("c3184a66-1ed0-11d9-a5e0-000a958a3252", True, True), ("BOOGER", False, False), ("BOOGER", True, False), ): if has: no = "no " else: no = "" if has != storeComponentFilter( ComponentFilter( ComponentFilter( PropertyFilter( TextMatch.fromString(uid, caseless=caseless), name="UID" ), name="VEVENT" ), name="VCALENDAR" ) ).match(self.calendar, None): self.fail("Calendar has %sVEVENT with UID %s? (caseless=%s)" % (no, uid, caseless)) def test_TimeRange(self): """ Time range match element. """ for start, end, has in ( ("20020101T000000Z", "20020101T000001Z", True), ("20020101T000000Z", "20020101T000000Z", True), # Timespan of zero duration ("20020101", "20020101", True), # Timespan of zero duration ("20020101", "20020102", True), ("20020101", "20020103", True), ("20020102", "20020103", False), ("20011201", "20020101", False), # End is non-inclusive # Expanded recurrence ("20030101T000000Z", "20030101T000001Z", True), ("20030101T000000Z", "20030101T000000Z", True), # Timespan of zero duration ("20030101", "20030101", True), # Timespan of zero duration ("20030101", "20030102", True), ("20030101", "20030103", True), ("20030102", "20030103", False), ("20021201", "20030101", False), # End is non-inclusive ): if has: no = "no " else: no = "" if has != storeFilter( Filter( ComponentFilter( ComponentFilter( TimeRange(start=start, end=end), name="VEVENT" ), name="VCALENDAR" ) ) ).match(self.calendar): self.fail("Calendar has %sVEVENT with timerange %s?" % (no, (start, end))) test_TimeRange.todo = "recurrence expansion"
# limitations under the License. ## # # Splits up the monolithic .Mac holidays calendar into a separate calendar # for each subcomponent therein. # These split-up calendars are useable as CalDAV resources. # import os from twistedcaldav.ical import Component monolithic_filename = os.path.join(os.path.dirname(__file__), "Holidays.ics") calendar = Component.fromStream(file(monolithic_filename)) assert calendar.name() == "VCALENDAR" for subcomponent in calendar.subcomponents(): subcalendar = Component("VCALENDAR") # # Add top-level properties from monolithic calendar to top-level properties # of subcomponent calendar. # for property in calendar.properties(): subcalendar.addProperty(property) subcalendar.addComponent(subcomponent)