예제 #1
0
    def parse(self, ins):

        result = super(Calendar, self).parse(ins)

        # We need to store all timezones in the static object so they can be accessed by any date object
        from pycalendar.timezonedb import TimezoneDatabase
        TimezoneDatabase.mergeTimezones(self, self.getComponents(definitions.cICalComponent_VTIMEZONE))

        return result
예제 #2
0
    def parse(self, ins):

        result = super(Calendar, self).parse(ins)

        # We need to store all timezones in the static object so they can be accessed by any date object
        from pycalendar.timezonedb import TimezoneDatabase
        TimezoneDatabase.mergeTimezones(self, self.getComponents(definitions.cICalComponent_VTIMEZONE))

        return result
예제 #3
0
 def timeZoneSecondsOffset(self, dt, relative_to_utc=False):
     if self.mUTC:
         return 0
     elif self.mTimezone is None:
         return TimezoneDatabase.getTimezoneOffsetSeconds(Timezone.sDefaultTimezone.getTimezoneID(), dt, relative_to_utc)
     elif isinstance(self.mTimezone, int):
         return self.mTimezone
     else:
         # Look up timezone and resolve date using default timezones
         return TimezoneDatabase.getTimezoneOffsetSeconds(self.mTimezone, dt, relative_to_utc)
예제 #4
0
    def setUp(self):
        super(TestTimezoneDB, self).setUp()

        # Standard components explicitly added
        for vtz in StandardTZs:
            cal = Calendar()
            TimezoneDatabase.getTimezoneDatabase()._addStandardTimezone(cal.parseComponent(StringIO(vtz)))

        # Just parsing will add as non-standard
        for vtz in NonStandardTZs:
            Calendar.parseData(vtz)
예제 #5
0
 def timeZoneSecondsOffset(self, dt, relative_to_utc=False):
     if self.mUTC:
         return 0
     elif self.mTimezone is None:
         return TimezoneDatabase.getTimezoneOffsetSeconds(
             Timezone.sDefaultTimezone.getTimezoneID(), dt, relative_to_utc)
     elif isinstance(self.mTimezone, int):
         return self.mTimezone
     else:
         # Look up timezone and resolve date using default timezones
         return TimezoneDatabase.getTimezoneOffsetSeconds(
             self.mTimezone, dt, relative_to_utc)
예제 #6
0
 def timeZoneDescriptor(self, dt):
     if self.mUTC:
         return "(UTC)"
     elif self.mTimezone is None:
         return TimezoneDatabase.getTimezoneDescriptor(Timezone.sDefaultTimezone.getTimezoneID(), dt)
     elif isinstance(self.mTimezone, int):
         sign = "-" if self.mTimezone < 0 else "+"
         hours = abs(self.mTimezone) / 3600
         minutes = divmod(abs(self.mTimezone) / 60, 60)[1]
         return "%s%02d%02d" % (sign, hours, minutes,)
     else:
         # Look up timezone and resolve date using default timezones
         return TimezoneDatabase.getTimezoneDescriptor(self.mTimezone, dt)
예제 #7
0
    def create(empty=False):
        """
        Create a timezone database from the files pointed to by the config. The empty option is used
        only for testing and will point the DB at an empty directory - i.e., no standard timezones are used.

        @param empty: set to C{True} when doing certain tests that do not want the standard timezone database used.
        @type empty: C{bool}
        """
        if empty:
            TimezoneCache.dirName = ""
        else:
            TimezoneCache.dirName = None
            TimezoneCache.validatePath()
        TimezoneCache.version = TimezoneCache.getTZVersion(TimezoneCache.getDBPath())
        TimezoneDatabase.createTimezoneDatabase(TimezoneCache.getDBPath())
예제 #8
0
    def create(empty=False):
        """
        Create a timezone database from the files pointed to by the config. The empty option is used
        only for testing and will point the DB at an empty directory - i.e., no standard timezones are used.

        @param empty: set to C{True} when doing certain tests that do not want the standard timezone database used.
        @type empty: C{bool}
        """
        if empty:
            TimezoneCache.dirName = ""
        else:
            TimezoneCache.dirName = None
            TimezoneCache.validatePath()
        TimezoneCache.version = TimezoneCache.getTZVersion(TimezoneCache.getDBPath())
        TimezoneDatabase.createTimezoneDatabase(TimezoneCache.getDBPath())
예제 #9
0
    def setUp(self):
        super(TestTimezoneDBCache, self).setUp()

        # Use temp dbpath
        tmpdir = tempfile.mkdtemp()
        TimezoneDatabase.createTimezoneDatabase(tmpdir)

        # Save standard components to temp directory
        for vtz in StandardTZs:
            cal = Calendar()
            tz = cal.parseComponent(StringIO(vtz))
            tzid_parts = tz.getID().split("/")
            if not os.path.exists(os.path.join(tmpdir, tzid_parts[0])):
                os.makedirs(os.path.join(tmpdir, tzid_parts[0]))
            with open(os.path.join(tmpdir, "{}.ics".format(tz.getID())), "w") as f:
                f.write(vtz)
예제 #10
0
    def stripStandardTimezones(self):
        """
        Remove VTIMEZONE components from this L{Calendar} if the corresponding TZIDs are
        in the timezone database.

        @return: L{True} if changes were made, L{False} otherwise
        @rtype: L{bool}
        """
        from pycalendar.timezonedb import TimezoneDatabase
        changed = False
        for component in self.getComponents(definitions.cICalComponent_VTIMEZONE):
            tz = TimezoneDatabase.getTimezone(component.getID())
            if tz is not None and TimezoneDatabase.isStandardTimezone(component.getID()):
                self.removeComponent(component)
                changed = True

        return changed
예제 #11
0
    def stripStandardTimezones(self):
        """
        Remove VTIMEZONE components from this L{Calendar} if the corresponding TZIDs are
        in the timezone database.

        @return: L{True} if changes were made, L{False} otherwise
        @rtype: L{bool}
        """
        from pycalendar.timezonedb import TimezoneDatabase
        changed = False
        for component in self.getComponents(definitions.cICalComponent_VTIMEZONE):
            tz = TimezoneDatabase.getTimezone(component.getID())
            if tz is not None and TimezoneDatabase.isStandardTimezone(component.getID()):
                self.removeComponent(component)
                changed = True

        return changed
예제 #12
0
 def timeZoneDescriptor(self, dt):
     if self.mUTC:
         return "(UTC)"
     elif self.mTimezone is None:
         return TimezoneDatabase.getTimezoneDescriptor(
             Timezone.sDefaultTimezone.getTimezoneID(), dt)
     elif isinstance(self.mTimezone, int):
         sign = "-" if self.mTimezone < 0 else "+"
         hours = abs(self.mTimezone) / 3600
         minutes = divmod(abs(self.mTimezone) / 60, 60)[1]
         return "%s%02d%02d" % (
             sign,
             hours,
             minutes,
         )
     else:
         # Look up timezone and resolve date using default timezones
         return TimezoneDatabase.getTimezoneDescriptor(self.mTimezone, dt)
예제 #13
0
    def includeMissingTimezones(self, includeTimezones=None):
        """
        For each timezone referenced in this L{Calendar}, if the corresponding VTIMEZONE component
        is not present, then add the matching component from the timezone database. L{includeTimezones}
        indicates what set of timezones should be automatically included. If set to L{None} the default
        is L{Calendar.NO_TIMEZONES}. Otherwise, one of L{Calendar.ALL_TIMEZONES}, L{Calendar.NONSTD_TIMEZONES},
        or L{Calendar.NO_TIMEZONES} must be used.

        @param includeTimezones: indicated whether all, only non-standard or no timezones are included
        @type includeTimezones: L{int} or L{None}
        """

        # Don't add anything in this case
        if includeTimezones == Calendar.NO_TIMEZONES:
            return
        if includeTimezones is None:
            includeTimezones = Calendar.NONSTD_TIMEZONES

        # Get timezone names from each component
        tzids = set()
        for component in self.mComponents:
            if component.getType() != definitions.cICalComponent_VTIMEZONE:
                component.getTimezones(tzids)

        # Make sure each timezone is in current calendar
        from pycalendar.timezonedb import TimezoneDatabase
        for tzid in tzids:
            # Skip standard timezones if requested
            if includeTimezones == Calendar.NONSTD_TIMEZONES and TimezoneDatabase.isStandardTimezone(
                    tzid):
                continue
            tz = self.getTimezone(tzid)
            if tz is None:
                # Find it in the static object
                tz = TimezoneDatabase.getTimezone(tzid)
                if tz is not None:
                    dup = tz.duplicate()
                    self.addComponent(dup)
예제 #14
0
    def test_isStandardTimezone(self):
        """
        L{TimezoneDatabase.isStandardTimezone} returns correct result.
        """

        data = (
            ("America/New_York", True),
            ("America/Los_Angeles", True),
            ("America/Cupertino", False),
            ("America/FooBar", False),
        )

        for tzid, result in data:
            self.assertEqual(TimezoneDatabase.isStandardTimezone(tzid), result, "Failed {}".format(tzid))
예제 #15
0
def readVTZ(tzid):
    """
    Try to load the specified TZID as a calendar object from the database. Raise if not found.
    """

    if tzid not in cachedVTZs:

        tzcal = TimezoneDatabase.getTimezoneInCalendar(tzid)
        if tzcal:
            cachedVTZs[tzid] = tzcal
        else:
            raise TimezoneException("Unknown time zone: %s" % (tzid, ))

    return cachedVTZs[tzid]
예제 #16
0
def readVTZ(tzid):
    """
    Try to load the specified TZID as a calendar object from the database. Raise if not found.
    """

    if tzid not in cachedVTZs:

        tzcal = TimezoneDatabase.getTimezoneInCalendar(tzid)
        if tzcal:
            cachedVTZs[tzid] = tzcal
        else:
            raise TimezoneException("Unknown time zone: %s" % (tzid,))

    return cachedVTZs[tzid]
예제 #17
0
    def includeMissingTimezones(self, includeTimezones=None):
        """
        For each timezone referenced in this L{Calendar}, if the corresponding VTIMEZONE component
        is not present, then add the matching component from the timezone database. L{includeTimezones}
        indicates what set of timezones should be automatically included. If set to L{None} the default
        is L{Calendar.NO_TIMEZONES}. Otherwise, one of L{Calendar.ALL_TIMEZONES}, L{Calendar.NONSTD_TIMEZONES},
        or L{Calendar.NO_TIMEZONES} must be used.

        @param includeTimezones: indicated whether all, only non-standard or no timezones are included
        @type includeTimezones: L{int} or L{None}
        """

        # Don't add anything in this case
        if includeTimezones == Calendar.NO_TIMEZONES:
            return
        if includeTimezones is None:
            includeTimezones = Calendar.NONSTD_TIMEZONES

        # Get timezone names from each component
        tzids = set()
        for component in self.mComponents:
            if component.getType() != definitions.cICalComponent_VTIMEZONE:
                component.getTimezones(tzids)

        # Make sure each timezone is in current calendar
        from pycalendar.timezonedb import TimezoneDatabase
        for tzid in tzids:
            # Skip standard timezones if requested
            if includeTimezones == Calendar.NONSTD_TIMEZONES and TimezoneDatabase.isStandardTimezone(tzid):
                continue
            tz = self.getTimezone(tzid)
            if tz is None:
                # Find it in the static object
                tz = TimezoneDatabase.getTimezone(tzid)
                if tz is not None:
                    dup = tz.duplicate()
                    self.addComponent(dup)
예제 #18
0
    def test_getTimezoneInCalendar(self):
        """
        L{TimezoneDatabase.getTimezoneInCalendar} returns correct result.
        """

        data = (
            ("America/New_York", True),
            ("America/Los_Angeles", True),
            ("America/Cupertino", True),
            ("America/FooBar", False),
        )

        for tzid, result in data:
            cal = TimezoneDatabase.getTimezoneInCalendar(tzid)
            if result:
                self.assertTrue(cal is not None)
                self.assertEqual(cal.getComponents()[0].getID(), tzid)
            else:
                self.assertTrue(cal is None)
예제 #19
0
    def test_getTimezone(self):
        """
        L{TimezoneDatabase.getTimezone} returns correct result.
        """

        data = (
            ("America/New_York", True),
            ("America/Los_Angeles", True),
            ("America/Cupertino", True),
            ("America/FooBar", False),
        )

        for tzid, result in data:
            tz = TimezoneDatabase.getTimezone(tzid)
            if result:
                self.assertTrue(tz is not None)
                self.assertEqual(tz.getID(), tzid)
            else:
                self.assertTrue(tz is None)
예제 #20
0
 def clear():
     TimezoneDatabase.clearTimezoneDatabase()
예제 #21
0
 def tearDown(self):
     TimezoneDatabase.clearTimezoneDatabase()
예제 #22
0
    def parseComponent(self, ins):

        result = None

        LOOK_FOR_VCALENDAR = 0
        GET_PROPERTY_OR_COMPONENT = 1
        GOT_VCALENDAR = 4

        state = LOOK_FOR_VCALENDAR

        # Get lines looking for start of calendar
        lines = [None, None]
        comp = self
        compend = None
        componentstack = []
        got_timezone = False

        while readFoldedLine(ins, lines):

            line = lines[0]

            if state == LOOK_FOR_VCALENDAR:

                # Look for start
                if line == self.getBeginDelimiter():
                    # Next state
                    state = GET_PROPERTY_OR_COMPONENT

                # Handle blank line
                elif len(line) == 0:
                    # Raise if requested, otherwise just ignore
                    if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE:
                        raise InvalidData("iCalendar data has blank lines")

                # Unrecognized data
                else:
                    raise InvalidData("iCalendar data not recognized", line)

            elif state == GET_PROPERTY_OR_COMPONENT:

                # Parse property or look for start of component
                if line.startswith("BEGIN:"):

                    # Push previous details to stack
                    componentstack.append((comp, compend,))

                    # Start a new component
                    comp = self.sComponentType.makeComponent(line[6:], comp)
                    compend = comp.getEndDelimiter()

                    # Cache as result - but only the first one, we ignore the rest
                    if result is None:
                        result = comp

                    # Look for timezone component to trigger timezone merge only if one is present
                    if comp.getType() == definitions.cICalComponent_VTIMEZONE:
                        got_timezone = True

                elif line == self.getEndDelimiter():

                    # Change state
                    state = GOT_VCALENDAR

                # Look for end of current component
                elif line == compend:

                    # Finalise the component (this caches data from the properties)
                    comp.finalise()

                    # Embed component in parent and reset to use parent
                    componentstack[-1][0].addComponent(comp)
                    comp, compend = componentstack.pop()

                # Blank line
                elif len(line) == 0:
                    # Raise if requested, otherwise just ignore
                    if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE:
                        raise InvalidData("iCalendar data has blank lines")

                # Ignore top-level items
                elif comp is self:
                    pass

                # Must be a property
                else:

                    # Parse parameter/value for top-level calendar item
                    prop = self.sPropertyType.parseText(line)

                    # Check for valid property
                    if comp is not self:
                        comp.addProperty(prop)

            # Exit if we have one - ignore all the rest
            if state == GOT_VCALENDAR:
                break

        # We need to store all timezones in the static object so they can be accessed by any date object
        # Only do this if we read in a timezone
        if got_timezone:
            from pycalendar.timezonedb import TimezoneDatabase
            TimezoneDatabase.mergeTimezones(self, self.getComponents(definitions.cICalComponent_VTIMEZONE))

        return result
예제 #23
0
 def setUp(self):
     TimezoneDatabase.createTimezoneDatabase(None)
예제 #24
0
 def clear():
     TimezoneDatabase.clearTimezoneDatabase()
예제 #25
0
 def setUp(self):
     TimezoneDatabase.createTimezoneDatabase(None)
예제 #26
0
    def test_isStandardTimezone(self):
        """
        L{TimezoneDatabase.isStandardTimezone} returns correct result when the database
        cache is initially empty.
        """

        data = (
            ("America/New_York", True),
            ("America/Los_Angeles", True),
            ("America/Cupertino", False),
            ("America/FooBar", False),
        )

        TimezoneDatabase.getTimezoneDatabase().clear()

        # Do twice to excersise the cache
        for _ in range(2):
            for tzid, result in data:
                self.assertEqual(TimezoneDatabase.isStandardTimezone(tzid), result, "Failed {}".format(tzid))

        self.assertTrue("America/New_York" in TimezoneDatabase.getTimezoneDatabase().stdtzcache)
        self.assertTrue("America/Los_Angeles" in TimezoneDatabase.getTimezoneDatabase().stdtzcache)
        self.assertFalse("America/Cupertino" in TimezoneDatabase.getTimezoneDatabase().stdtzcache)
        self.assertFalse("America/FooBar" in TimezoneDatabase.getTimezoneDatabase().stdtzcache)

        self.assertFalse("America/New_York" in TimezoneDatabase.getTimezoneDatabase().notstdtzcache)
        self.assertFalse("America/Los_Angeles" in TimezoneDatabase.getTimezoneDatabase().notstdtzcache)
        self.assertTrue("America/Cupertino" in TimezoneDatabase.getTimezoneDatabase().notstdtzcache)
        self.assertTrue("America/FooBar" in TimezoneDatabase.getTimezoneDatabase().notstdtzcache)
예제 #27
0
    def parseComponent(self, ins):

        result = None

        LOOK_FOR_VCALENDAR = 0
        GET_PROPERTY_OR_COMPONENT = 1
        GOT_VCALENDAR = 4

        state = LOOK_FOR_VCALENDAR

        # Get lines looking for start of calendar
        lines = [None, None]
        comp = self
        compend = None
        componentstack = []
        got_timezone = False

        while readFoldedLine(ins, lines):

            line = lines[0]

            if state == LOOK_FOR_VCALENDAR:

                # Look for start
                if line == self.getBeginDelimiter():
                    # Next state
                    state = GET_PROPERTY_OR_COMPONENT

                # Handle blank line
                elif len(line) == 0:
                    # Raise if requested, otherwise just ignore
                    if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE:
                        raise InvalidData("iCalendar data has blank lines")

                # Unrecognized data
                else:
                    raise InvalidData("iCalendar data not recognized", line)

            elif state == GET_PROPERTY_OR_COMPONENT:

                # Parse property or look for start of component
                if line.startswith("BEGIN:"):

                    # Push previous details to stack
                    componentstack.append((comp, compend,))

                    # Start a new component
                    comp = self.sComponentType.makeComponent(line[6:], comp)
                    compend = comp.getEndDelimiter()

                    # Cache as result - but only the first one, we ignore the rest
                    if result is None:
                        result = comp

                    # Look for timezone component to trigger timezone merge only if one is present
                    if comp.getType() == definitions.cICalComponent_VTIMEZONE:
                        got_timezone = True

                elif line == self.getEndDelimiter():

                    # Change state
                    state = GOT_VCALENDAR

                # Look for end of current component
                elif line == compend:

                    # Finalise the component (this caches data from the properties)
                    comp.finalise()

                    # Embed component in parent and reset to use parent
                    componentstack[-1][0].addComponent(comp)
                    comp, compend = componentstack.pop()

                # Blank line
                elif len(line) == 0:
                    # Raise if requested, otherwise just ignore
                    if ParserContext.BLANK_LINES_IN_DATA == ParserContext.PARSER_RAISE:
                        raise InvalidData("iCalendar data has blank lines")

                # Ignore top-level items
                elif comp is self:
                    pass

                # Must be a property
                else:

                    # Parse parameter/value for top-level calendar item
                    prop = self.sPropertyType.parseText(line)

                    # Check for valid property
                    if comp is not self:
                        comp.addProperty(prop)

            # Exit if we have one - ignore all the rest
            if state == GOT_VCALENDAR:
                break

        # We need to store all timezones in the static object so they can be accessed by any date object
        # Only do this if we read in a timezone
        if got_timezone:
            from pycalendar.timezonedb import TimezoneDatabase
            TimezoneDatabase.mergeTimezones(self, self.getComponents(definitions.cICalComponent_VTIMEZONE))

        return result
예제 #28
0
 def tearDown(self):
     TimezoneDatabase.clearTimezoneDatabase()