Coder Social home page Coder Social logo

caldav's Introduction

caldav's People

Contributors

abdulg avatar achimh3011 avatar azmeuk avatar b3niup avatar bchardin avatar bjokash avatar cyrilrbt avatar daniele-athome avatar danigm avatar earlchew avatar jammon avatar jelmer avatar m42e avatar maddinat0r avatar mtorange avatar mzyy94 avatar neonfighter28 avatar notmarrco avatar paxswill avatar red-hood avatar rianhunter avatar sblondon avatar scop avatar sim0nx avatar sobolevn avatar tamarinvs19 avatar thimic avatar tobixen avatar yuwash avatar zocker1999net 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

caldav's Issues

Unintended object mutation

in caldav/davclient.py:
DAVClient.request lines 221-222:
combined_headers = self.headers
combined_headers.update(headers)
First line makes combined_headers to be a reference to self.headers, and therefore second line, in fact, updates self.headers with values from headers, affecting all subsequent requests.
The combined_headers should be a copy instead:
combined_headers = dict(self.headers)
combined_headers.update(headers)

How to filter events by property

I'm sorry, what is the recommended way to filter/search a calendar by a property? For example, "fetch me all the events with 'HOLIDAY' as summary"

date_search fails on Baikal 0.4.5 and 0.4.6

This server from test.py works: http://baikal.tobixen.no
It is reportedly the "older" Baikal, but I don't know what version it's running.

This server from test.py is not reachable: http://baikal-test.caldav-servers.tobixen.no

On recent (0.4.5 and 0.4.6) versions of Baikal, date_search(datetime) works (with only one argument), but date_search(datetime(), datetime()) with two arguments generates an internal server error (500).

Considering that functions properly on older Baikal servers, this does not appear to be a regression in python-caldav but rather something broken by updates to Baikal. I have not tried this against raw sabre/dav.

Imports not working?

Hi,

I'm not sure if I'm doing something completely wrong, but I can't get this lib working. I've copied the example from the docs and still failing at the imports...

$ python -V
Python 2.7.15
$ pip list
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Package         Version 
--------------- --------
caldav          0.6.0   
certifi         2019.3.9
chardet         3.0.4   
idna            2.8     
lxml            4.3.3   
pip             19.0.3  
python-dateutil 2.8.0   
pytz            2018.9  
requests        2.21.0  
setuptools      40.8.0  
six             1.12.0  
tzlocal         1.5.1   
urllib3         1.24.1  
vobject         0.9.6.1 
wheel           0.33.1  
$ python caldav.py 
Traceback (most recent call last):
  File "caldav.py", line 2, in <module>
    import caldav
  File "/home/mb/projects/inoio/sogo-connector/caldav.py", line 3, in <module>
    from caldav.elements import dav, cdav
ImportError: No module named elements

What am I missing?

Fix test code so it can run cleanly on servers not supporting mkcalendars

According to the RFC, it's perfectly allowed for a caldav server to deny creating new calendars. Also, even if it should be possible to make new calendars, we've seen problems with it on some servers. Currently pretty much all the functional tests starts by creating a new test calendar. We need to make support in the test framework for running as many tests as possible towards the default calendar rather than making a new test calendar.

implement ctag/etag based sync from (and maybe to) server

Hi,

the (old fashioned) sync-flow is described http://sabre.io/dav/building-a-caldav-client/ - it uses etags for event change tracking.

Could someone elaborate (give hints where what to change) if I want to have :

most important

  1. date_search/events could return etag:
    • alongside calendar-data (for initial sync)
    • without calendar-data (to check for changes)
    • ps.: date_search seems to be generalization of events (but for now not DRY)?

less important

  1. ctag
    getctag, which is from "http://calendarserver.org/ns/" namespace which I don't find mentioned in source (should be similar to getetag)...

  2. calendar-multiget REPORT (for batched get)

  3. if-Match header support (for "to server" update/delete)

ps.: I need this for SOGo and Google CalDaV API

event object properties

Hi

I am discovering caldav so this is maybe a dummy question.
I successfully fetch calendars and retrieve event using the date_search.
But I don't get how I get details from each event. What are the event objects properties available ?
Let's say I want to get start and end of each event I retrieve from a date_search

freebusy request

I cannot figure out how to make a freebusy request. Is there anywhere that I can see an example? See below for what I've tried:

client = caldav.DAVClient(url)
principal = client.principal()
calendars = principal.calendars()

calendar = calendars[1]
freebusy = calendar.freebusy_request(datetime.today(), datetime.today())

This returns the following error:
'caldav.lib.error.ReportError: 406 Not Acceptable'

Directly instantiate Calendar object knowing the URL

Hi, I noted that to get a Calendar instance I have to instantiate a client, then get a Principal and after that get the calendar. I logged the requests made and I saw that this process does 3 different requests to the server:

In [30]: c=caldav.DAVClient('https://user:pwd@myhost/nextcloud/remote.php/dav').principal().calendar(cal_id='mycalendar')
DEBUG:requests.packages.urllib3.connectionpool:https://myhost "PROPFIND /nextcloud/remote.php/dav/ HTTP/1.1" 401 555
DEBUG:requests.packages.urllib3.connectionpool:https://myhost "PROPFIND /nextcloud/remote.php/dav/ HTTP/1.1" 207 611
DEBUG:requests.packages.urllib3.connectionpool:https://myhost "PROPFIND /nextcloud/remote.php/dav/principals/users/myusername/ HTTP/1.1" 207 627

In [31]: c.url
Out[31]: URL(https://myhost/nextcloud/remote.php/dav/calendars/myusername/mycalendar)

I would like to skip this process if I already know the calendar URL to improve performance by instanciating Calendar directly, but I can't do it without getting an error:

In [40]: caldav.Calendar(url=c.url, name='name', id='id').events()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-40-911c65d16a1e> in <module>()
----> 1 caldav.Calendar(url=c.url, name='name', id='id').events()

/lib/python3.6/site-packages/caldav/objects.py in events(self)
    674         root = cdav.CalendarQuery() + [prop, filter]
    675 
--> 676         response = self._query(root, 1, query_method='report')
    677         results = self._handle_prop_response(response, props=[cdav.CalendarData()])
    678         for r in results:

/lib/python3.6/site-packages/caldav/objects.py in _query(self, root, depth, query_method, url, expected_return_value)
    124             body = etree.tostring(root.xmlelement(), encoding="utf-8",
    125                                   xml_declaration=True)
--> 126         ret = getattr(self.client, query_method)(
    127             url, body, depth)
    128         if ret.status == 404:

AttributeError: 'NoneType' object has no attribute 'report'

I also tried serializing the calendar instance using pickle, but I get a RecursionError exception when deserializing.

How do you recomend to achieve this? I don't want to do so many requests to get a simple list of events!

KeyError: exception_by_method['proppach']

Repetitevely running example from Quickstart https://pythonhosted.org/caldav/#quickstart
I got Error:

Renaming
Traceback (most recent call last):
  File "caldav_demo.py", line 34, in <module>
    calendar.set_properties([dav.DisplayName("Test calendar"),])
  File "caldav/objects.py", line 250, in set_properties
    r = self._query(root, query_method='proppatch')
  File "caldav/objects.py", line 167, in _query
    raise error.exception_by_method[query_method](errmsg(ret))
KeyError: 'proppatch'

caldav 0.6.1
py: 3.5

*** I suspect proppatch is related to propset here

Feature: support icalendar objects

Today we have a dependency on vobjects, and we've discussed a bit forth and back if we could get rid of this dependency. It was most pressing in 2015 and early 2016 as the vobjects development was frozen and the official vobjects release didn't support python3. Today this is a non-pressing issue, but there is still a wish out there that we'd support icalendar as well. Even my calendar-cli tool is importing and using the icalendar library, not vobjects.

Perhaps the best way to do it would be to let the current "instance" property yield a vObject (for compatibility reasons), while we make new methods "toVObject" and "toIcalendar" methods (or similar). Imports of the libraries should be done only when they are needed.

I believe some of the task management code I wrote actually depends on the instance to work. This complicates things a bit.

This is a non-urgent task, as long as there aren't any proper (backward-compatible) pull requests, I probably won't bother prioritizing it.

See also https://bitbucket.org/cyrilrbt/caldav/issues/41 and https://bitbucket.org/cyrilrbt/caldav/pull-requests/17/replace-vobject-by-icalendar

Ensure compatibility with Xandikos

Steps to Reproduce:

import caldav

#url = "http://localhost:8080"
#url = "http://:@localhost:8080"
url = "http://localhost:8080/user/calendars/calendar/"

client = caldav.DAVClient(url)
principal = client.principal()
principal.make_calendar(name="Test Calendar")

Expected Result:
Calendar is created.

Actual Result:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/site-packages/caldav/objects.py", line 324, in make_calendar
    return self.calendar_home_set.make_calendar(name, cal_id, supported_calendar_component_set=supported_calendar_component_set)
  File "/usr/lib/python3.7/site-packages/caldav/objects.py", line 335, in calendar_home_set
    chs = self.get_properties([cdav.CalendarHomeSet()])
  File "/usr/lib/python3.7/site-packages/caldav/objects.py", line 192, in get_properties
    raise Exception("The CalDAV server you are using has "
Exception: The CalDAV server you are using has a problem with path handling.

.todos() ignores all tasks without a progress status

I am running version 0.5 and I cannot get my todos without the status. I thought it would be fixed since this issues. I am only getting the todos to sync on which I set a status, however all tasks sync (including the finished one) when I set the include_completed=True parameter.

Icloud not fully supported

Updated summary

Updated 2021-03-08.

The library can be used for basic access into events on calendars in iCloud, as well as to save changes.

As far as I've understood, Apple has never officially said that they do support CalDAV in iCloud. iCloud does use some variant of the Apple CalendarServer, which is supposed to be very standards-compliant, but development on the CalendarServer has unfortunately been discontinued ... and whatever version Apple is using, there are lots of regression issues, pushing out new features in iCloud obviously have higher priority than to keep the calendar compliant with the standards. The things that doesn't work now will probably never work, and I haven't planned to do more work on improving iCloud compatibility as for now.

I will close this issue, as no more work is planned to be done on icloud support.

Some things to be aware of:

  • Ref @markus0m one may need to use app-specific passwords, see https://support.apple.com/en-us/HT204397
  • It doesn't seem like iCloud supports journal entries (but who cares ... does anyone use those anyway?)
  • iCloud doesn't support freebusy-requests.
  • While iCloud do have some "task" system, it does not seem like it's possible to access those through the caldav interface (If you have iCloud and a tasklist with tasks - try using .objects() rather than .todos() and see if you get any tasks?)
  • All test code dealing with recurring events have been disabled, it seems like they don't support recurring events through their CalDAV interface. It's probably possible to do more research on this one ... but it's not on my list.
  • Icloud uses calendar URLs like https://p12-caldav.icloud.com/17112341234/calendars/[email protected]/ - the numbers (even in the host name) differs from account to account. There is no need to wonder too much about this, specify the caldav url to be https://caldav.icloud.com/, and the library can figure out the rest - code examples at #3 (comment)
  • As per the comment above ... I'm not much happy with the way the specific URL gets stored, I think it's a quite dirty hack (objects.py, Principal.calendar_home_set, the url in the associated DAVClient objects gets changed), an unexpected side effect that is bound to cause unexpected behaviour further down the road.
  • The test code is (by default) creating and deleting the same calendar repeatedly. I did observe some times that events stored on the calendar would not disappear if the calendar was deleted and then recreated. I consider that to be a bug, but a bug that never should be encountered in ordinary use cases. (could be that the bug is in the test code - did not investigate much).
  • It seems that one unique calendar object with one unique uid cannot be on two calendars at the same time. I'm not sure what the RFC says about this - I think it's a common use case scenario to have one and the same event on multiple calendars, and then it ought to have the same uid also.
  • A test doing a propfind failed and has been skipped. Not sure if it's something wrong with the iCloud or if it's something wrong with the test.
  • The method object_by_uid (as well as event_by_uid) fails. I vaguely remember someone telling me there was an issue with it on Google as well. Should be investigated, perhaps the logic should be rewritten or some workaround should be found for iCloud (and Google?).
  • I had to do some minor workaround in the code for fetching event lists - the calendar URL is sometimes passed in the response together with the events, causing the library to handle it as an extra event. I haven't bothered checking the RFC, but wrote up some lines to check for this and throw it away.

Except for those things ... all tests passes by now.

This ticket is closed as for now, but feel free to update it if you have more information. If it's possible to work around any of the problems above without introducing too much complexity in the library, this issue may be reopened.

Parser error in X-APPLE-STRUCTURED-EVENT field

Hello,

the date_search() method issues a parser error, if an event contains a X-APPLE-STRUCTURED-LOCATION record. I think it has something to do with the double-backslash-escaped newlines. Other caldav clients do not complain about it. Do you think it is a icalendar syntax problem? Could there be a workaround?

Thank you very much,
Florian

    ...
    results = calendar.date_search(start, end)
  File "/usr/lib/python3.4/site-packages/caldav/objects.py", line 510, in date_search
    Event(self.client, url=self.url.join(r), data=results[r][cdav.CalendarData.tag], parent=self))
  File "/usr/lib/python3.4/site-packages/caldav/objects.py", line 724, in __init__
    self.data = data
  File "/usr/lib/python3.4/site-packages/caldav/objects.py", line 801, in _set_data
    self._instance = vobject.readOne(to_unicode(self._data))
  File "/usr/lib/python3.4/site-packages/vobject/base.py", line 1156, in readOne
    allowQP))
  File "/usr/lib/python3.4/site-packages/vobject/base.py", line 1101, in readComponents
    vline = textLineToContentLine(line, n)
  File "/usr/lib/python3.4/site-packages/vobject/base.py", line 925, in textLineToContentLine
    return ContentLine(*parseLine(text, n), **{'encoded': True,
  File "/usr/lib/python3.4/site-packages/vobject/base.py", line 813, in parseLine
    raise ParseError("Failed to parse line: {0!s}".format(line), lineNumber)
vobject.base.ParseError: At line 15: Failed to parse line: X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-MAPKIT-HANDLE=CAESvAEaEgmX5esy/OVJQBGXkXpP5aQYQCJiCgtEZXV0c2NobGFuZBICREUaE05vcmRyaGVpbi1XZXN0ZmFsZW4qBUtsZXZlMgVLbGV2ZToFNDc1MzNSDkp1bmdmZXJuZ3JhYmVuWgIyNWIRSnVuZ2Zlcm5ncmFiZW4gMjUqEUp1bmdmZXJuZ3JhYmVuIDI1MhFKdW5nZmVybmdyYWJlbiAyNTILNDc1MzMgS2xldmUyC0RldXRzY2hsYW5kODlAAA==;X-APPLE-RADIUS=70.58738448026273;X-APPLE-REFERENCEFRAME=1;X-TITLE=Löschzug Kellen\

Here is the event that fails:

BEGIN:VEVENT
CREATED:20190103T070318Z
DTEND;TZID=Europe/Berlin:20190117T230000
DTSTAMP:20190103T070319Z
DTSTART;TZID=Europe/Berlin:20190117T180000
LAST-MODIFIED:20190103T070318Z
LOCATION:Löschzug Kellen\nJungferngraben 25\n47533 Kleve\nDeutschland
RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=20191231T225959Z;BYDAY=TH;WKST=SU
SEQUENCE:0
SUMMARY:Arbeitsgruppe
TRANSP:OPAQUE
UID:B4D490C2-1261-471A-93E8-7D27FB5DA3C8
URL;VALUE=URI:
X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-MAPKIT-HANDLE=CAESvAEaEgmX      
 5esy/OVJQBGXkXpP5aQYQCJiCgtEZXV0c2NobGFuZBICREUaE05vcmRyaGVpbi1XZXN0ZmFs     
 ZW4qBUtsZXZlMgVLbGV2ZToFNDc1MzNSDkp1bmdmZXJuZ3JhYmVuWgIyNWIRSnVuZ2Zlcm5n     
 cmFiZW4gMjUqEUp1bmdmZXJuZ3JhYmVuIDI1MhFKdW5nZmVybmdyYWJlbiAyNTILNDc1MzMg     
 S2xldmUyC0RldXRzY2hsYW5kODlAAA==;X-APPLE-RADIUS=70.58738448026273;X-APPL     
 E-REFERENCEFRAME=1;X-TITLE=Löschzug Kellen\\nJungferngraben 25\\n47533 K     
 leve\\nDeutschland:geo:51.796759,6.161031
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC
BEGIN:VALARM
ACTION:NONE
TRIGGER;VALUE=DATE-TIME:19760401T005545Z
END:VALARM
END:VEVENT

Assume local timezone when none is given in date_search

One test breaks now with bedework, possibly due to timestamp passed in a date search being without any time zone specified.

Data sent to server:

<?xml version='1.0' encoding='utf-8'?>
<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:D="DAV" xmlns:I="http://apple.com/ns/ical/">
  <ns0:prop xmlns:ns0="DAV:">
    <C:calendar-data>
      <C:expand start="20060713T170000" end="20060715T170000"/>
    </C:calendar-data>
  </ns0:prop>
  <C:filter>
    <C:comp-filter name="VCALENDAR">
      <C:comp-filter name="VEVENT">
        <C:time-range start="20060713T170000" end="20060715T170000"/>
      </C:comp-filter>
    </C:comp-filter>
  </C:filter>
</C:calendar-query>

Data received from server:

<?xml version="1.0" encoding="UTF-8" ?>

<DAV:error xmlns="urn:ietf:params:xml:ns:caldav"
              xmlns:AI="http://apple.com/ns/ical/"
              xmlns:ical="http://www.w3.org/2002/12/cal/ical#"
              xmlns:BSS="http://bedeworkcalserver.org/ns/"
              xmlns:CS="http://calendarserver.org/ns/"
              xmlns:DAV="DAV:">
  <valid-filter>Not UTC</valid-filter>
</DAV:error>

I think this is release-critical, ref #27.

Exception when attempting open ended date_search()

Date searches can be open at either end:

https://icalendar.org/CalDAV-Access-RFC-4791/9-9-caldav-time-range-xml-element.html

The "start" attribute specifies the inclusive start of the time range, and the "end" attribute specifies the non-inclusive end of the time range. Both attributes MUST be specified as "date with UTC time" value. Time ranges open at one end can be specified by including only one attribute; however, at least one attribute MUST always be present in the CALDAV:time-range element. If either the "start" or "end" attribute is not specified in the CALDAV:time- range XML element, assume "-infinity" and "+infinity" as their value, respectively. If both "start" and "end" are present, the value of the "end" attribute MUST be greater than the value of the "start" attribute.

Using v0.5.0, an exception occurs when date_search() is invoked with start=None and end specified:

Traceback (most recent call last):
  ...
  File ".../lib/caldav/objects.py", line 494, in date_search
    data = cdav.CalendarData() + cdav.Expand(start, end)
  File "...//lib/caldav/elements/cdav.py", line 72, in __init__
    self.attributes['start'] = start.strftime("%Y%m%dT%H%M%SZ")

Search with dtstart==dtend

Searching with date_search(start,end) does not work when dtstart is equal to dtend.

1 File "location/calendar/lib/python3.7/site-packages/caldav/objects.py", line 510, in date_search
2 Event(self.client, url=self.url.join(r), data=results[r][cdav.CalendarData.tag], parent=self))
3 File "location/calendar/lib/python3.7/site-packages/caldav/objects.py", line 724, in init
4 self.data = data
5 File "location/calendar/lib/python3.7/site-packages/caldav/objects.py", line 801, in _set_data
6 self._instance = vobject.readOne(to_unicode(self._data))
7 File "location/calendar/lib/python3.7/site-packages/vobject/base.py", line 1156, in readOne
8 allowQP))
9 File "location/calendar/lib/python3.7/site-packages/vobject/base.py", line 1128, in readComponents
10 component.transformChildrenToNative()
11 File "location/calendar/lib/python3.7/site-packages/vobject/base.py", line 674, in transformChildrenToNative
12 child.transformChildrenToNative()
13 File "location/calendar/lib/python3.7/site-packages/vobject/base.py", line 673, in transformChildrenToNative
14 child = child.transformToNative()
15 File "location/calendar/lib/python3.7/site-packages/vobject/base.py", line 185, in transformToNative
16 return self.behavior.transformToNative(self)
17 File "location/calendar/lib/python3.7/site-packages/vobject/icalendar.py", line 1454, in transformToNative
18 raise ParseError("DURATION must have a single duration string.")
19 vobject.base.ParseError: At line 27: DURATION must have a single duration string.

i hope someone can help me with this problem.

Bug with URL quote/unquote

in caldav/objects.py:
DAVObject._handle_prop_response() unqotes key it returns:
line 174:
href = unquote(r.find('.//' + dav.Href.tag).text)
but in DAVObject.get_properties it is compared to URL path, which is quoted:
lines 209-218:
path = self.url.path
exchange_path = self.url.path + '/'

    if path in list(properties.keys()):
        rc = properties[path]
    elif exchange_path in list(properties.keys()):
        rc = properties[exchange_path]
    else:
        raise Exception("The CalDAV server you are using has "
                        "a problem with path handling.")

So, if base path contains quoted characters, they do not match and the server is blamed.
Following modification makes it working for me:
lines 209-210:
path = unquote(self.url.path)
exchange_path = path + '/'

Also, a small optimisation in lines 212 and 214:
'in properties' is equivalent of 'in list(properties.keys())', but more effective.

Tag new versions

Hi,

There are some Git tags for versions up to 0.3. Would it be possible to add also git tags for versions 0.4 and 0.5?

I tend to think this is clearer than branches to show where a particular version stopped, but more important I think it is really useful to have a single way to pinpoint versions (either tags or branches, but not a mix, as it confuses people).

Thanks!

fix proper support for expandable calendar search

ref tobixen/calendar-cli#52

  • one user reported that he was unable to fetch events where recurrances are within the time range. Make sure this works, and make options to explicitly request this from the server
  • also, currently the server does not expand recurring events into multiple objects in a date search. We need this feature for good agendas in calendar-cli.

Documentation should be refreshed

Ref #54 ... the online documentation points to version 0.5.0. Everything should be reviewed. Is the example code still best practice? Is the other content there up-to-date?

0.6.2-release

@cyrilrbt, I think it's time for another minor release.

Quite some embarrassing bugs have been found in 0.6.1, I hope they are properly ironed out now. To reduce the risk of new bugs entering the master branch, by now unit tests and functional tests are run every time commits are pushed to github, or pull requests are submitted.
Still, the 0.6.2-release is admittedly under-tested - the public test servers I was running towards are currently down. Anyway, I believe the risk of introducing new bugs is low compared to the benefit of ironing out known bugs.

Here are the release-notes:

  • The timezone handling introduced in 0.6 was not very well tested, thanks to feedback from Achim Herwig this has been fixed. In python 3.6 and higher, it's possible to convert between local time and utc without introducing the pytz/tzlocal dependencies.
  • Quite some other bugs have been found and fixed.
  • Some work has been done with the test framework:
    • Since the external public test servers have been notoriously unreliable, by default the tests will not be executed towards the external public test servers (and they are all down as of writing)
    • Xandikos is written in python, can be spawned up easily from python and has no other run-time dependencies than write access to a file system. Spawning up a xandikos server instance from the test code was an easy thing to do, so by default now the tests are executed towards Xandikos. However, Xandikos is python3-only, so this only applies when running tests from python3.
    • Unit tests are now run on every commit pushed to github, and on every github pull request. This should stop the most embarrassing bugs from entering the master branch.

CAVEAT 1: some of the timezone handling has been moved from object.py to elements/cdav.py, and a minor incompatibility with 0.6.1 has been introduced; if you were using cdav/elements.py directly (and not using the higher-level methods in objects.py) and passing naive timestamps to it, they would be treated as UTC-time in 0.6.1 while they are assumed to be localtime in 0.6.2. It seems very unlikely that this incompatibility issue would hit anyone.
CAVEAT 2: The 0.6.2-release is under-tested, all the servers/accounts used when testing 0.6.0 is currently down or unavailable. (Please help! Check tests/conf_private.py.EXAMPLE).

Caldav test servers

This was last updated 2022-04-24, prior to the v0.9-release

Call for help

I need servers to test the library with!

To be able to release the caldav library with the least amount of regression issues, I need to be able to run the test suite towards as many calendar servers as possible. While I may be able to set up and maintain a few calendar servers and cloud accounts myself, I don't really have the time nor capacity to cover everything myself. It's quite outside the scope of the caldav library maintenance. I need your help supplying me with test accounts I can use - an URL, a username, a password and a short description of what kind of server I will find. I expect the accounts given to work on a long term, but ad-hoc access when doing research on bugs or when doing releases may also work out.

The credentials plus contact information will be kept unencrypted ("encryption on rest" on the storage/file system level) on a private server of mine and on my laptop, plus an encrypted backup. It will only be used for running the test suite. The testing will create test calendars and will delete them when done, it should not touch any calendaring data on the account (though no guarantees given), I'm using my personal calendaring accounts on some systems.

Tests will be run ad-hoc when working towards releases, by average probably around once a day.

The test code spawn quite a lot of communication, as it makes sure all previously used test calendars are properly deleted before every test. I should probably refactor this code. Please get in touch with me if this is an issue for you.

Contributing with access to a test account is a win-win-situation, as you can be sure exactly your server is regularly tested.

Local test servers

If installed, those python-based servers will be spawned up locally by the test framework:

  • xandikos
  • radicale

Those are run directly from the pyhon-code, hence they have to be available in the PYTHONPATH of the python version being used when running tests.

Public test servers

My plan was to manage some public test servers, and at some point I had some of them running - but currently this idea is shelved. I also had the alternative idea to create some script to spin up servers locally using docker. Perhaps at some point in the future ...

Nextcloud has a public test server ... from https://try.nextcloud.com/ it's possible to generate a username that is valid for one hour (should probably try looking into automating things here)

Private test servers

The v0.9 was tested against those: (work in progress)

  • Nextcloud (several implementations)
  • eCloud (but also a NextCloud clone, I believe)
  • Baikal
  • Zimbra
  • DAViCal (older version)

Earlier test servers

Those has been tested at some earlier point in history, but the 0.9-release was not tested against those:

  • SOGo
  • Bedework
  • iCloud
  • Google (but only their deprecated endpoint as for now)
  • Fastmail

Test servers currently missing

  • Open eXchange
  • up-to-date versions of DAViCal
  • Googles new caldav endpoints
  • The now abandoned Apple CalendarServer project

Others?

Other

Only python 3.10 and python 3.8 tested as of the 0.9-release.

Should eventually look through https://en.wikipedia.org/wiki/Comparison_of_CalDAV_and_CardDAV_implementations#Server_implementations

Error in date_search with default end=None

File "caldav_demo.py", line 43, in <module>
     results = calendar.date_search( datetime(2010, 5, 1) )
File "caldav/objects.py", line 567, in date_search
    end = _fix_tz(end)
  File "caldav/objects.py", line 40, in _fix_tz
    return dt.replace(tzinfo=tzlocal.get_localzone())
AttributeError: 'NoneType' object has no attribute 'replace'

Pushing to PyPI?

Hi,

Any plans to push master into PyPI? It has a fix for an issue I'm experiencing.

Thanks!

Delay vobject instantiation

We should not instantiate vobject on object loading, only when/if we need a vobject instance. Should be a workaround for various vobject-related issues (like #36, #37 and several others)

Delete recurring event?

How to delete only a single occurrence of a recurring event? The delete()-method deletes every occurrence.

Missing tag for 0.6.0

As per $SUBJ the tag for the latest release on pypi is missing, could you please add it?

nose and coverage should probably be test_requires

Hi,

I noticed that nose and coverage were listed in the set of install_requires, should they actually be tests_require? as they're only needed when running the unittest?

Perhaps something like this:

--- a/setup.py
+++ b/setup.py
@@ -27,5 +27,6 @@
         packages=find_packages(exclude="tests"),
         include_package_data=True,
         zip_safe=False,
-        install_requires=['vobject', 'lxml', 'nose', 'coverage', 'requests', 'six'],
+        install_requires=['vobject', 'lxml', 'requests', 'six'],
+        tests_require=['nose', 'coverage']
     )

Two license files present - which one is right?

There is one GPLv3 license file and one with Apache 2.0. Dual licensing makes no sense here, as Apache v2 can already be used together with GPLv3.

I'd prefer Apache 2.0 in order to license a derived package as Apache 2.0 itself.

how to delete calendar

I can successfully create a calendar via make_calendar but I have not found a way to delete a calendar.

calling cal.delete() result in an error.

I do this:

client = caldav.DAVClient(url)
principal = client.principal()
calendars = principal.calendars()

for c in calendars:
    if c.name == 'orgtodo':
        c.delete()

which gives me:

Login to https://xhz:[email protected]:443/
Traceback (most recent call last):
  File "test.py", line 38, in <module>
    c.delete()
  File "/usr/local/lib/python2.7/site-packages/caldav/objects.py", line 238, in delete
    raise error.DeleteError(errmsg(r))
caldav.lib.error.DeleteError: 400 Bad Request

<html><head><title>Bad Request</title></head><body><h1>Bad Request</h1><p>Client sent illegal depth header value for DELETE: 1</p></body></html>

Is this icloud specific or is delete broken or not the right way to do it ?

Thunderbird VEVENT with the greater SEQUENCE is not given in event.instance.vevent

From Thunderbird Lighting I got events with two VEVENT-Parts in it. The first part is with a "X-MOZ-FAKED-MASTER" which have no summary and other missing stuff. Directly with the same UID there is another vevent with the right stuff inside and a SEQUENCE. But with caldav I just get the first broken VEVENT. How can I get the one with the highest SEQUENCE, or maybe just both, I can choose the right SEQUENCE by myself? As myevent is not iterable, I have no chance to see the second part of this ics.

Sample Code:

import caldav
events = calendar.date_search(start, end)
for event in events :
                myevent = event.instance.vevent

Here the ics-File I get the wrong SEQUENCE:

BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
TZID:Europe/Berlin
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
TZNAME:CEST
DTSTART:19700329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
TZNAME:CET
DTSTART:19701025T030000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
CREATED:20180315T201819Z
LAST-MODIFIED:20180315T201840Z
DTSTAMP:20180315T201840Z
UID:7c7c51c4-d0ae-4837-b7d9-f3379292314c
RDATE;VALUE=DATE-TIME:20180830T140000Z
DTSTART;TZID=Europe/Berlin:20180830T160000
DTEND;TZID=Europe/Berlin:20180830T160000
X-MOZ-FAKED-MASTER:1
X-MOZ-GENERATION:1
END:VEVENT
BEGIN:VEVENT
CREATED:20180315T201802Z
LAST-MODIFIED:20180315T201840Z
DTSTAMP:20180315T201840Z
UID:7c7c51c4-d0ae-4837-b7d9-f3379292314c
SUMMARY:This is the true date
RECURRENCE-ID;TZID=Europe/Berlin:20180830T160000
DTSTART;TZID=Europe/Berlin:20180830T160000
DTEND;TZID=Europe/Berlin:20180830T180000
DESCRIPTION:My Date\n
SEQUENCE:1
END:VEVENT
END:VCALENDAR

A workaroung might be giving me all VEVENTs, and I decide which one to use.

Parsing fails for events with a duration set to "DURATION:P"

Hi,

I am parsing a calendar which unfortunately has a number of events with the following entry:
DURATION:P

Which fails with
lib/python3.6/site-packages/vobject/icalendar.py", line 1387, in transformToNative raise ParseError("DURATION must have a single duration string.") vobject.base.ParseError: At line 14: DURATION must have a single duration string.
I am not sure if this is relevant but the event in question has the same end time as start time.

Any ideas ?

Calendar.date_search ignores dates given

dates passed into Calendar.date_searchare supposed to get their timezones fixed if pytz timezones are employed. However, the second return statement (taking care of non-pytz case) is incorrectly indented, making the functione return None and thus removing the date filter.

exclude list in find_packages

It seems, that the exclude keyword have to be list. See:

>>> find_packages(exclude="tests")
['tests', 'caldav', 'caldav.lib', 'caldav.elements']

and this:

>>> find_packages(exclude=["tests"])
['caldav', 'caldav.lib', 'caldav.elements']

regards

TextMatch Filter not work

` all = []
data = cdav.CalendarData()
prop = dav.Prop() + data

    filter = \
        cdav.Filter().append(
            cdav.CompFilter("VCALENDAR").append(
                cdav.CompFilter("VEVENT").append(
                    cdav.PropFilter("SUMMARY").append(
                        [cdav.TextMatch("Holiday", negate=True)]))))

    root = cdav.CalendarQuery() + [prop, filter]
    
    response = self._query(root, 1, query_method='report')
    results = self._handle_prop_response(
        response, props=[cdav.CalendarData()])
    for r in results:
        all.append(Event(
            self.client, url=self.url.join(r),
            data=results[r][cdav.CalendarData.tag], parent=self))

    return all`

XML:

<C:calendar-query xmlns:C="urn:ietf:params:xml:ns:caldav" xmlns:D="DAV">
<ns0:prop xmlns:ns0="DAV:">
<C:calendar-data/>
</ns0:prop>
<C:filter>
<C:comp-filter name="VCALENDAR">
<C:comp-filter name="VEVENT">
<C:prop-filter name="SUMMARY">
<C:text-match negate-condition="yes" collation="i;octet">Holiday</C:text-match>
</C:prop-filter>
</C:comp-filter>
</C:comp-filter>
</C:filter>
</C:calendar-query>

Google Calendar CalDav

It always return all events.

Can't open my Baikal calDAV with caldav

I'm sorry to ask you but I tried every possible format for the URL and I didn't get access to my data with this python library.

My Baikal server runs at https://myserver.de/Baikal/.

And I tried .../cal.php/principals/myusername/, .../cal.php/calendars/myusername/oneofthecalendars and much more. And just the server name, too. But it didn't work.

The first part of my script is just:

caldav.DAVClient(url, user, pwd)
principal = client.principal()

And the second line results in an error:

requests.exceptions.ProxyError: HTTPSConnectionPool(host='myserver.de', port=443): Max retries exceeded with url: /Baikal/cal.php/calendars/myusername/oneofmycalendars/ (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7f5ff9b4a630>: Failed to establish a new connection: [Errno -2] Name or service not known',)))

Maybe you can help me with that issue to get Baikal running within my Python codes.
Thanks a lot!

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.