Giter Site home page Giter Site logo

icalevents's Introduction

iCalEvents

Simple Python 3 library to download, parse and query iCal sources.

PyPI versionJazzband

Build info

last push: run pytest

master: Run pytest

Documentation

https://icalevents.readthedocs.io/en/latest/

Usage

iCloud:

from icalevents.icalevents import events

es  = events(<iCloud URL>, fix_apple=True)

Google:

from icalevents.icalevents import events

es  = events(<Google Calendar URL>)

Contributing

You will need poetry and pre-commit installed and than run.

pre-commit install

Happy contributing!

icalevents's People

Contributors

arhell avatar carloshanson avatar chansonit avatar dependabot[bot] avatar dlichtistw avatar eigenmannmartin avatar elizaaverywilson avatar hultner avatar infanf avatar irgangla avatar jameselks avatar jezdez avatar kaitlynmcgoldrick avatar mabre avatar madsmtm avatar mhdzumair avatar mueller-patrick avatar ndw avatar pablocastellano avatar pall-valmundsson avatar pre-commit-ci[bot] avatar rahularanger avatar sh0oki avatar tahouse-amazon avatar tdaff avatar thir820 avatar thomux avatar tomirgang avatar tresni avatar wrecker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

icalevents's Issues

Add encoding parameter to events, etc.

I have a calendar URL that is encoded in latin_1 (olympic events provided by ecal.com)

It would be great if the top level events() API allowed overriding the encoding of UTF-8. Instead, I have to invoke ICalDownload directly so that I can specify the encoding.

Support for recurring events with BYDAY attribute

If you have a recurring event with BYDAY attribute, and if you retrieve all events within a period, you will only get all occurences of the recurring event having a weekday equal to the weekday of the first occurence.

Supporting this would require enhancements in the create_recurring_events method of the icalparser.py module.

for example:
Event description: b'Peak'
Event datestart : 2018-02-01 08:00:00+01:00
Event dateend : 2018-02-01 18:00:00+01:00
Event recurrence rule: vRecur({'FREQ': ['WEEKLY'], 'BYDAY': ['MO', 'TU', 'WE', 'TH', 'FR']})
Search period start: 2017-07-12
Search period end: 2018-02-24
Number of events found: 4

NEW EVENT
Event description: Peak
Event datestart : 2018-02-01 08:00:00+01:00
Event dateend : 2018-02-01 18:00:00+01:00
NEW EVENT
Event datestart : 2018-02-08 08:00:00+01:00
Event dateend : 2018-02-08 18:00:00+01:00
NEW EVENT
Event datestart : 2018-02-15 08:00:00+01:00
Event dateend : 2018-02-15 18:00:00+01:00
NEW EVENT
Event datestart : 2018-02-22 08:00:00+01:00
Event dateend : 2018-02-22 18:00:00+01:00

Would it be possible to implement this?
Thanks,
Laurent

Random SSL: WRONG_VERSION_NUMBER from google calendar url

I use icalevents 0.1.22 and google calendar url. I think I'm pulling to often but I tough the http cache was there for that...

...
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\site-packages\icalevents\icalevents.py", line 32, in events
    content = ICalDownload().data_from_url(url, apple_fix=fix_apple)
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\site-packages\icalevents\icaldownload.py", line 56, in data_from_url
    _, content = self.http.request(url)
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\site-packages\httplib2\__init__.py", line 1953, in request
    cachekey,
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\site-packages\httplib2\__init__.py", line 1618, in _request
    conn, request_uri, method, body, headers
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\site-packages\httplib2\__init__.py", line 1556, in _conn_request
    response = conn.getresponse()
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 1336, in getresponse
    response.begin()
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 306, in begin
    version, status, reason = self._read_status()
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\http\client.py", line 267, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\socket.py", line 589, in readinto
    return self._sock.recv_into(b)
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 1071, in recv_into
    return self.read(nbytes, buffer)
  File "C:\Users\Steeve\AppData\Local\Programs\Python\Python37\lib\ssl.py", line 929, in read
    return self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:2508)

Release 0.1.26 missing on pypi

The latest release on pypi is 0.1.25. Are there plans to release 0.1.26 also on pypi?

I would really appreciate this.

Thanks!

Write Permissions on .cache in httplib2

I'm seeing this failure:

eventList = events(url=tier1A, file=None, start=today, end=one_year_from_now)
File "/var/task/icalevents/icalevents.py", line 38, in events
ical_download = ICalDownload(http=http)
File "/var/task/icalevents/icaldownload.py", line 37, in init
http = Http('.cache')
File "/var/task/httplib2/init.py", line 1461, in init
self.cache = FileCache(cache)
File "/var/task/httplib2/init.py", line 925, in init
os.makedirs(self.cache)
File "/var/lang/lib/python3.7/os.py", line 221, in makedirs
mkdir(name, mode)
OSError: [Errno 30] Read-only file system: '.cache'

Which I take it was meant to be resolved via #52

I'm running 0.1.24 via serverless framework on aws lambda.

Event Location.

Location isn't getting read and store in the event array after parsing.

Wrong `all_day` computation for recurring events

Recurrent all-day events are set to be not all-day events. Here is one problematic case (part of the ics file exported from Google Calendar):

BEGIN:VEVENT
DTSTART;VALUE=DATE:20181030
DTEND;VALUE=DATE:20181031
RRULE:FREQ=WEEKLY;BYDAY=TU
DTSTAMP:20181113T191224Z
UID:[email protected]
CREATED:20181113T191200Z
DESCRIPTION:
LAST-MODIFIED:20181113T191214Z
LOCATION:
SEQUENCE:3
STATUS:CONFIRMED
SUMMARY:Game Tag Day
TRANSP:TRANSPARENT
END:VEVENT
ipdb> event.summary
'Game Tag Day'
ipdb> event.all_day
False
ipdb> event.start
datetime.datetime(2018, 11, 13, 0, 0, tzinfo=tzfile('/usr/share/zoneinfo/America/Los_Angeles'))
ipdb> event.end
datetime.datetime(2018, 11, 14, 0, 0, tzinfo=tzfile('/usr/share/zoneinfo/America/Los_Angeles'))

Yearly repeating events raise an error

Consider this fragment:

RRULE:FREQ=YEARLY;INTERVAL=1;UNTIL=20190328
DTEND;VALUE=DATE:20170330
DTSTART;VALUE=DATE:20170329

When icalevents loads this event, it will normalize the date into a datetime. But when dateutil.rrule is called subsequently, it will object:

RRULE UNTIL values must be specified in UTC when DTSTART is timezone-aware

Unfortunately, there are several places where start and end times are compared and the possibility of a mixture of date and datetime objects isn't handled.

Some events are missing if all_day event is within list

Consider the following settings:
startdate: 01.12.2020 00:00:00
enddate: 31.12.2020 23:59:59

Events:
10.12.2020 18:00:00 EventA
22.12.2020 AllDay EventB
31.12.2020 17:00:00 EventC

While iterating through the calendar, the enddate-settings are reseted during the allday-event to 31.12.2020 00:00:00 and then EventC is missing in the list!

Using dateutil.rrule

Is there a reason not to use dateutil.rrule for handling recurring events? It claims to implement a superset of iCal rrules, handles exdates, exrules and DST transitions (apparently, it doesn't). If there is no reason against it, I would propose to rewrite the whole recurring events logic.

Requirements.txt should list setuptools

I tried to install this package using PIP but failed because I lacked setuptools. It was an easy fix, but it should be listed as a dependency in requirements.txt. Thanks in advance.

recurring events without end date throw exception

Hello,

when the (iCloud) calendar contains an item without end date (i have it for birthdays), icalparser.py throws "ValueError: RRULE UNTIL values must be specified in UTC when DTSTART is timezone-aware"

i guess this is because RRULE UNTIL in this case is empty.

Exception is thrown: can't compare offset-naive and offset-aware datetimes

Hello, I am trying to use the icalevents library to parse a iCal feed generated by Bamboo HR for our company time offs.

Here is the code that I am using:

evs = events(url=url, start=date(2020, 9, 1), end=date(2020, 9, 30))
for event in evs:
  print(event)

This throws the following error:

  File "/home/sahab/anaconda3/lib/python3.7/site-packages/icalevents/icalparser.py", line 91, in __str__
    if self.end > n > self.start:
TypeError: can't compare offset-naive and offset-aware datetimes

Not sure if I'm doing something wrong, if the iCal is malformed for whatever reason, or if there is a bug in the library, but I've attached the calendar in question to start:

holidays.ics.txt

Any thoughts on this?

Windows timezones raise dateutil rrule exception

I have a problem using Outlook calendar with "Romance Standard Time". gettz returns None since the python program is not run on Windows. It is also falling back to UTC with normal events.

However, with rrules it becomes worse. The normalize function will set the timezone of dtstart to None and rrulestr will throw an exception: ValueError: RRULE UNTIL values must be specified in UTC when DTSTART is timezone-aware since dtstart has no timezone and is supposed to have one.

So there are two problems:

  1. Windows timezones are only supported on Windows (according to the doc, not tested)
  2. When gettz gets an unsupported timezone it breaks the default fallback to UTC and causes an exception later.

The second one is easy to fix by checking the return value.
The first one might be problematic, it depends on what is wanted.
Cross platform support of timezones can be brought with a module such as pytz or by embedding a big dictionary, as long as bringing this support it is wanted for the project.

[Discussion] Transfer ownership of project to jazzband or similar?

Background

I was talking with Martin Eigenmann (@eigenmannmartin) in private.
He reached out to me since he's got some contributions he want to merge (#80). I've tried for a while to review and merge PRs but without any ability to cut new releases which are pushed to PyPi it started to feel a bit pointless after a while.

Suggestion

Move ownership of the project to https://jazzband.co/ (or similar) collective ownership organisation. This way we could continue to maintain the project easier.
@irgangla: I'd love to hear your thoughts on this? I'm no longer a user of the library so I'm not that heavily invested these days but it's a bit sad if the project would slowly be weathering into obsolesce without any new releases. For these kinds of libraries I'm very much for the collective ownership model.

Exception dictionary is not cleared between events

icalparser.py :280

The exceptions dictionary isn't cleared before each VEVENT item, so that exceptions compound accross VEVENTS and so valid events are rejected because of exception from previously processed items.

Line 280 should be moved inside the loop on line 281

for component in calendar.walk():

Duplicate events returned on a day when one instance of a recurring event changes time

A recurring event was created in the past.
One instance had a time change.
On the date of the event, two events are returned.

The combination of the UID and the SEQUENCE needs to be observed. In this case, both events have the same UID in the calendar, so the one with the higher SEQUENCE should be returned.

Right now, recurring events are copied with each new date and the UID is changed for each by appending a random integer. I don't think the UID should be changed, but I need to test some different recurring scenarios to be sure that keeping the same UID will be okay.

I will work on this, but feel free to add any suggestions while I do.

Parsing of the calendar failed

Traceback (most recent call last):
  File "C:/Userdir/PycharmProjects/EPDUI/main.py", line 18, in <module>
    frame.eventlist(0, 3, 0, 10, 5, "https://calendar.google.com/calendar/ical/**********/basic.ics")
  File "C:\Userdir\PycharmProjects\EPDUI\epdui\epdui.py", line 85, in eventlist
    ev = events(ical_url)
  File "C:\Userdir\Anaconda3\envs\EPDUI\lib\site-packages\icalevents\icalevents.py", line 30, in events
    found_events += parse_events(content)
  File "C:\Userdir\Anaconda3\envs\EPDUI\lib\site-packages\icalevents\icalparser.py", line 247, in parse_events
    e = create_event(component)
  File "C:\Userdir\Anaconda3\envs\EPDUI\lib\site-packages\icalevents\icalparser.py", line 159, in create_event
    event.summary = str(component.get('summary'))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 28: ordinal not in range(128)

bitmoji

Invalid timezone parsing

I'm trying to parse iCalendar file, generated by Microsoft Outlook 2016.
While parsing itself works fine, I did stuck with the timezone.

The calendar header(excluding events) looks like this:

BEGIN:VCALENDAR
PRODID:-//Microsoft Corporation//Outlook 16.0 MIMEDIR//EN
VERSION:2.0
METHOD:PUBLISH
X-CALSTART:20190527T093000Z
X-CALEND:20190614T170000Z
X-CLIPSTART:20190430T210000Z
X-CLIPEND:20190616T210000Z
X-WR-RELCALID:{0000002E-65C8-5317-F094-6C7ABA69683A}
X-WR-CALNAME:Schedule
BEGIN:VTIMEZONE
TZID:Russian Standard Time
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:+0300
TZOFFSETTO:+0300
END:STANDARD
END:VTIMEZONE
BEGIN:VTIMEZONE
TZID:Unnamed Time Zone 1
BEGIN:STANDARD
DTSTART:16010101T000000
TZOFFSETFROM:+0300
TZOFFSETTO:+0300
END:STANDARD
END:VTIMEZONE

As dateutil.tz.gettz() returns None to Russian Standard Time in parser: https://github.com/irgangla/icalevents/blob/master/icalevents/icalparser.py#L224
it all falls back to the UTC. However, why don't you check offset value?
From what it seems, solemnly relying on value of TZID is not safe.
Also, you might provide ability to override timezone via argument of events function.

FileExistsError: [Errno 17] File exists: '.cache'

version 0.1.25

FileExistsError: [Errno 17] File exists: '.cache'
<snip>
  File "<my-own-code>", line 26, in get_ical_events
    raw_events = events(ical_link, start=from_date, end=to_date)
  File "icalevents/icalevents.py", line 38, in events
    ical_download = ICalDownload(http=http)
  File "icalevents/icaldownload.py", line 37, in __init__
    http = Http('.cache')
  File "__init__.py", line 1249, in __init__
    self.cache = FileCache(cache)
  File "__init__.py", line 771, in __init__
    os.makedirs(self.cache)
  File "os.py", line 225, in makedirs
    mkdir(name, mode)

I'm guessing that due to concurrent calls to events where they both try and create .cache at the exact same time, the check

        if not os.path.exists(cache):
            os.makedirs(self.cache)

in httplib2 races.

Fixing upstream: httplib2/httplib2#224

All day events not recognized

I am parsing an iCalendar from Google calendar, but icalevents fails to recognize all day events. They are imported, but with all_day == False.

I think, I tracked down the problem to one line in the create_event method.
https://github.com/irgangla/icalevents/blob/652f522e578183908f6a7936f0ac5b291e93c6db/icalevents/icalparser.py#L161
But the type of all day events' start attribute is date, not datetime.date. Hence, the flag should probably be set as
event.all_day = type(component.get('dtstart').dt) is date

Add typing

I am thinking about adding typing and mypy to this project. What is your take on this? @alex @Pro70

Recurring events off by 24 hours when time zone offset is less than start time of event

Yes, really :D

My calendar source has two timezones: Australia/Sydney and Australia/Melbourne. These are both +11:00.

I have a recurring event that starts at 09:00 Australia/Sydney on Sundays:

DTSTART;TZID=Australia/Sydney:20211017T090000

Because there are two time zones in the calendar, the cal_tz is set to UTC and the event is changed to 22:00 UTC on Saturday.

However the rrule is weekly on Sunday:

RRULE:FREQ=WEEKLY;BYDAY=SU

This means that when the iterator creates events it is taking the 22:00 and applying it to each Sunday. Which, of course, moves the event to 09:00 Australia/Sydney ON MONDAY.

Possible solutions in order of best-ness:

  • The event has a time zone in the DTSTART. Use it rather than the cal_tz. Normalise the result to cal_tz rather than the event.
  • Use the first time zone as the cal_tz, no matter how many time zones are in the file
  • Allow the constructor to specify a specific cal_tz

Test file (rename to .ics obviously!)
calendar.ics.txt

Can't find the docs??

As above, really - there's a two-line "usage" in README, but I can't find any documentation of how you actually use it..

Add a 'recurring' attribute to Event object

My use-case is I need to distinguish between recurring and non-recurring events. Without this attribute there is no way to tell if an event is a single event or part of a recurring series of events.

ValueError: RRULE UNTIL values must be specified in UTC when DTSTART is timezone-aware

It might be the problem of google calendar or other ics handling applications.

I found an event that is repeatedly scheduled.
And I got an error when I load the calendar like icalevents.icalevents.events(url=https://xx/x/xx.ics, start=start, end=end) where start and end are datetime.datetime object:
ValueError: RRULE UNTIL values must be specified in UTC when DTSTART is timezone-aware

If I read the *.ics file, there is an event which is something like this:

DTSTART;TZID=Asia/Tokyo:20200610T103000
DTEND;TZID=Asia/Tokyo:20200610T110000
RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20201130;BYDAY=WE
DTSTAMP:20200903T041214Z
ORGANIZER;[email protected]:mailto:[email protected]
UID:[email protected]
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Some One;X-NUM-GUESTS=0:mailto:[email protected]
CREATED:20200304T015134Z
DESCRIPTION: description
LAST-MODIFIED:20200902T120609Z
LOCATION: somewhere
SEQUENCE:2
STATUS:CONFIRMED
SUMMARY: repeating events name
TRANSP:OPAQUE
ATTACH;FILENAME=hey hey hey;FMTTYPE=application/vnd.google-ap
 ps.document:https://docs.google.com/a/xxx/document/d/1fjwfwfjwoefijowefjeowfjEME/edit?usp=drive_web
END:VEVENT

As mentioned by the error message, UNTIL is 20201130 which is only date information not datetime with timezone.
But can we assume date object as date + datetime.datetime.time(0, 0) in the same timezone?
OR prepare a method to fix the *ics?

Implement Jazzband guidelines for icalevents

This issue tracks the implementation of the Jazzband guidelines for the project icalevents

It was initiated by @irgangla who was automatically assigned in addition to the Jazzband roadies.

See the TODO list below for the generally required tasks, but feel free to update it in case the project requires it.

Feel free to ping a Jazzband roadie if you have any question.

TODOs

Project details

Description Python module for iCal URL/file parsing and querying.
Homepage None
Stargazers 79
Open issues 27
Forks 48
Default branch master
Is a fork False
Has Wiki True
Has Pages False

Reading Event with Duration causes exception

I printed the component def create_event(component):

The Event in ical file is

BEGIN:VEVENT
UID:10613
DTSTAMP:20180223T130634Z
SUMMARY:A great event Day
CLASS:PUBLIC
STATUS:CONFIRMED
PRIORITY:0
SEQUENCE:0
DTSTART:20180126
DURATION:P1D
LAST-MODIFIED:20180102T224058Z
TRANSP:OPAQUE
END:VEVENT

Component is
VEVENT({'DTSTART': <icalendar.prop.vDDDTypes object at 0x10b9e3240>, 'SUMMARY': vText('b'A great event Day ''), 'DURATION': <icalendar.prop.vDDDTypes object at 0x10b9ba588>, 'STATUS': vText('b'CONFIRMED''), 'PRIORITY': 0, 'LAST-MODIFIED': <icalendar.prop.vDDDTypes object at 0x10b9bacc0>, 'TRANSP': vText('b'OPAQUE''), 'UID': vText('b'10613''), 'SEQUENCE': 0, 'DTSTAMP': <icalendar.prop.vDDDTypes object at 0x10b9baf98>, 'CLASS': vText('b'PUBLIC'')})
Traceback (most recent call last):
File "/Users/anaconda2/envs_env/bin/flask", line 11, in
sys.exit(main())
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/flask/cli.py", line 513, in main
cli.main(args=args, prog_name=name)
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/flask/cli.py", line 380, in main
return AppGroup.main(self, *args, **kwargs)
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/click/core.py", line 697, in main
rv = self.invoke(ctx)
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/click/core.py", line 1066, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/click/core.py", line 895, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/click/decorators.py", line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/flask/cli.py", line 257, in decorator
return __ctx.invoke(f, *args, **kwargs)
File "/Users/anaconda2/envs_env/lib/python3.5/site-packages/click/core.py", line 535, in invoke
return callback(*args, **kwargs)
File "/Users/populate_events.py", line 46, in populate_events
all_events = events(url=school.calender_url)
File "/Users/icalevents/icalevents/icalevents.py", line 40, in events
found_events += parse_events(content, start=start, end=end)
File "/Users/icalevents/icalevents/icalparser.py", line 257, in parse_events
e = create_event(component)
File "/Users/icalevents/icalevents/icalparser.py", line 155, in create_event
event_end = normalize(component.get('dtend').dt)
AttributeError: 'NoneType' object has no attribute 'dt'

Timezone handling issue

I think there is an issue when handling timezones.
I have imported a calendar generated from gmail, with a timezone of Europe/Brussels (calendar and events).
An event was created to start at 8 AM (local time) on 30 MAR 2018.
When I display the event DTSTART, it show the time with a +01:00 time zone.
But at that time of the year, the timezone in Belgium should be +02:00.

Using the method "events" of class "icalevents" indicates that you need to biais the "start" parameter to match the event.

See the attached files:
1/ The exported google calendar
2/ the code used for highlighting the issue.
3/ The output.

MyCal2.txt
essai2.txt
output.txt

parse_events is unordered?

I was using the parse_events() function, and didn't realize until a bit of experimentation that the return value from this function is not chronologically ordered. Would it be possible to sort the array before returning like this: .sort(key=lambda i: i.start) or be documented? Thanks!

Support for floating dates

The ical RFC states that dates without timezone indications are to be interpreted as "floating", which means in the local timezone (of the affected user). icalevents currently interprets them as being UTC instead.

From the RFC:

The date with local time form is simply a date-time value that does not contain the UTC designator nor does it reference a time zone. For example, the following represents Janurary 18, 1998, at 11 PM:

DTSTART:19980118T230000

Date-time values of this type are said to be "floating" and are not bound to any time zone in particular. They are used to represent the same hour, minute, and second value regardless of which time zone is currently being observed. For example, an event can be defined that indicates that an individual will be busy from 11:00 AM to 1:00 PM every day, no matter which time zone the person is in. In these cases, a local time can be specified. The recipient of an iCalendar object with a property value consisting of a local time, without any relative time zone information, SHOULD interpret the value as being fixed to whatever time zone the ATTENDEE is in at any given moment. This means that two ATTENDEEs, in different time zones, receiving the same event definition as a floating time, may be participating in the event at different actual times. Floating time SHOULD only be used where that is the reasonable behavior.

In most cases, a fixed time is desired. To properly communicate a fixed time in a property value, either UTC time or local time with time zone reference MUST be specified.

The use of local time in a DATE-TIME value without the TZID property parameter is to be interpreted as floating time, regardless of the existence of "VTIMEZONE" calendar components in the iCalendar object.

How to iterate over recurring events with a time constraint?

I could not find any documentation so sorry if this is explained somewhere.

I accessed a Google Calendar URL to retrieve a calendar. It has two recurring events. What I get as a reply is a list of these two events.

  • how can I access the actual, atomic events (say that the event is repeated every Monday, how do I get a list of these Monday events?)
  • how can I time-constrain the query (for the example above, getting all the events between now and a month from now should give ~4 events, generated from the single recurring events)

PermissionError when running in directory with no write permissions

When importing the module from a directory with no write permissions, the call to create the default Http cache fails. There is no way to avoid this if, for example, the filesystem is read-only, or running some web service on a managed host where the web user should not have write permissions.

>>> from icalevents import icalevents
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/tdd20/.local/Virtualenvs/icalevents/lib/python3.6/site-packages/icalevents/icalevents.py", line 4, in <module>
    from .icaldownload import ICalDownload
  File "/home/tdd20/.local/Virtualenvs/icalevents/lib/python3.6/site-packages/icalevents/icaldownload.py", line 8, in <module>
    default_http = Http('.cache')
  File "/home/tdd20/.local/Virtualenvs/icalevents/lib/python3.6/site-packages/httplib2/__init__.py", line 1419, in __init__
    self.cache = FileCache(cache)
  File "/home/tdd20/.local/Virtualenvs/icalevents/lib/python3.6/site-packages/httplib2/__init__.py", line 905, in __init__
    os.makedirs(self.cache)
  File "/home/tdd20/.local/Virtualenvs/icalevents/lib/python3.6/os.py", line 220, in makedirs
    mkdir(name, mode)
PermissionError: [Errno 13] Permission denied: '.cache'

Recurring event monthly third saturday

Using icalevents==0.1.7, I think I've found a bug in a recurring event:

BEGIN:VEVENT
DTSTART;TZID=Europe/Madrid:20180421T140000
DTEND;TZID=Europe/Madrid:20180421T200000
RRULE:FREQ=MONTHLY;BYDAY=3SA
EXDATE;TZID=Europe/Madrid:20180818T140000
EXDATE;TZID=Europe/Madrid:20180721T140000
DTSTAMP:20180915T142029Z
UID:[email protected]
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=MADE (
 public) Calendar;X-NUM-GUESTS=0:mailto:[email protected]
 endar.google.com
CREATED:20180321T092815Z
DESCRIPTION:What about if we meet a day each month and we have some Pizza\,
  Beers\, Music\, and we:\n\n\nIntroduce projects we are working or we have 
 made and Invite people to introduce their projects as well\n\nWork together
  in speed projects for that day or team up to repair or make things for Mad
 e.\n\nAsk and give some advice for the projects we are working.\n\n...
LAST-MODIFIED:20180519T151438Z
LOCATION:MADE Makerspace\, Carrer de la Noguera Pallaresa\, 59\, Bajos\, 08
 014 Barcelona\, Spain
SEQUENCE:1
STATUS:CONFIRMED
SUMMARY:Made Day 
TRANSP:TRANSPARENT
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR;ACKNOWLEDGED=20180519T151437Z:AUTOMATIC
BEGIN:VALARM
ACTION:NONE
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
X-WR-ALARMUID:DEA4C94D-22CA-4BEF-9B4F-FC08E7782EBC
UID:DEA4C94D-22CA-4BEF-9B4F-FC08E7782EBC
ACKNOWLEDGED:20180519T151437Z
END:VALARM
END:VEVENT

The important part:

RRULE:FREQ=MONTHLY;BYDAY=3SA

From the RRULE I understand that the event is configured to be recurrent every month, on the third Saturday. For September 2018, it should happen today (Saturday 15th). However it shows as happening on Friday 21st.

You can see this calendar at http://made-bcn.org/ (google calendar iframe) and download the calendar from https://calendar.google.com/calendar/ical/6l9ppc6fipscpnlmpin810ktko%40group.calendar.google.com/public/basic.ics

The following snippet shows the bug:

#!/usr/bin/env python3
import datetime

from icalevents.icalevents import events

url = "https://calendar.google.com/calendar/ical/6l9ppc6fipscpnlmpin810ktko%40group.calendar.google.com/public/basic.ics"


def print_summary(day1, day2):
    for event in events(url, start=day1, end=day2):
        print("FROM: ({}) TO ({})".format(event.start, event.end))
        print("SUMMARY: {}".format(event.summary))
        print("DESCRIPTION: {}".format(event.description))
        print()


if __name__ == "__main__":
    print("------------------------- 2018-09-15 -------------------")
    day1 = datetime.date(2018, 9, 15)
    day2 = datetime.date(2018, 9, 16)
    print_summary(day1, day2)
    print("------------------------- 2018-09-21 -------------------")
    day1 = datetime.date(2018, 9, 21)
    day2 = datetime.date(2018, 9, 22)
    print_summary(day1, day2)

This is the output:

------------------------- 2018-09-15 -------------------
FROM: (2018-09-15 09:00:00+00:00) TO (2018-09-15 15:00:00+00:00)
SUMMARY: SAT-urday
DESCRIPTION: Workshop on how to build your own NOAA antenna.
NOOA = National Oceanic and Atmospheric Administration
Come and get some amazing images!!!

------------------------- 2018-09-21 -------------------
FROM: (2018-09-21 14:00:00+00:00) TO (2018-09-21 20:00:00+00:00)
SUMMARY: Made Day 
DESCRIPTION: What about if we meet a day each month and we have some Pizza, Beers, Music, and we:


Introduce projects we are working or we have made and Invite people to introduce their projects as well

Work together in speed projects for that day or team up to repair or make things for Made.

Ask and give some advice for the projects we are working.

...

Error handling recurring events with timezones

Following code snippet do not yield the expected result:

from datetime import datetime
from icalevents.icalevents import events
import textwrap
import zoneinfo

tz = zoneinfo.ZoneInfo("Europe/Berlin")
ics = textwrap.dedent(
"""\
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:STANDARD
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
END:DAYLIGHT
END:VTIMEZONE
BEGIN:VEVENT
DTSTART;TZID=Europe/Berlin:20211129T000000
DTEND;TZID=Europe/Berlin:20211129T080000
RRULE:FREQ=WEEKLY;UNTIL=20221230T230000Z;BYDAY=MO,TU,WE
END:VEVENT
END:VCALENDAR
"""
).encode()

events = events(
    string_content=ics,
    start=datetime(2022, 1, 11, 7, 0, 1, tzinfo=tz),
    end=datetime(2022, 1, 11, 8, 0, 1, tzinfo=tz),
)
assert len(events) == 1
print(events[0])

I would expect the currently active recurring event instance. This holds for all start values of the last hour of the recurring event.

Git bisect yields efb7fbe as the first bad commit introduced in #80

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.