Closed l0ga closed 2 years ago
For me it looks like a server error. :-) There is no difference on the library side on weather the uuid contains dashes or not, and the server should not complain that the task already exists when one is trying to do a PUT towards it.
It would be very nice to have a debug log of all the communication with the server, when using caldav library vs when using another caldav client.
Did some more research. Nextcloud-created tasks' URL/URI and UID are not the same. So a task located at /apps/tasks/#/calendars/testcal/tasks/15340142-5713-4847-907D-7539A05E0EA0.ics can have UID inside .ics b6de9389-98c0-483c-a842-8c2908a239ef. Can it be related?
That's right. The file name and UID may not always match, but it's important to PUT things to the correct path. If the caldav library is actually doing a GET from /apps/tasks/#/calendars/testcal/tasks/15340142-5713-4847-907D-7539A05E0EA0.ics
and later a PUT to /apps/tasks/#/calendars/testcal/tasks/b6de9389-98c0-483c-a842-8c2908a239ef.ics
, then that would be a big bug. Are you able to check that up as well?
That's right. The file name and UID may not always match, but it's important to PUT things to the correct path. If the caldav library is actually doing a GET from
/apps/tasks/#/calendars/testcal/tasks/15340142-5713-4847-907D-7539A05E0EA0.ics
and later a PUT to/apps/tasks/#/calendars/testcal/tasks/b6de9389-98c0-483c-a842-8c2908a239ef.ics
, then that would be a big bug. Are you able to check that up as well?
My guess is that exactly this happens and it only gets problematic because the UID and URI are different (which they are allowed to π).
Without knowing your code to well, I guess that this fallback: https://github.com/python-caldav/caldav/blob/8ccf97d13bb6a2b92ffcc7709e249085e387ffc9/caldav/objects.py#L1380-L1384
might be triggered, because when saving a Todo, the url
variable is not given and ends up being None
:
https://github.com/python-caldav/caldav/blob/8ccf97d13bb6a2b92ffcc7709e249085e387ffc9/caldav/objects.py#L601-L608
https://github.com/python-caldav/caldav/blob/8ccf97d13bb6a2b92ffcc7709e249085e387ffc9/caldav/objects.py#L1192
Could that lead to path
being None
as well and triggering the fallback, maybe?
Line 1384 was modified some few days ago in the master branch, but the general logic (default the URL to the uuid) is the same (only difference is that the uuid should be safe-quoted, with slashes being doubly quoted to let it pass more easily through proxies). In any case, line 1384 should only apply when creating new calendar objects, not when editing old ones.
When editing a task, you should basically first load it, edit it and save it - and when loading the URL should be saved in self.url or self.path.
Please do some debugging if you have the chance ... otherwise I'll try to find some time to dig deeper into it.
So, can I help somehow? This behavior can break (at least) all Nextcloud-based setups. Right now the code works only if such tasks are explicitly ignored.
If I can have an URL and some credentials for a Nextcloud caldav server, I will run the functional tests towards it. If they break, then I will have something to look into. If not, then we should try to write up a new test to catch this issue and then look into it.
you can create an account on https://e.foundation/e-email-invite/ which gives you free access to a nextcloud caldav and space with 1Gb
Cool. Maybe I should try their android operating system as well. Managed to set up an account and run the test suite. 2 errors and 4 failures. I've seen it worse :-) I'll do a little bit of digging before bedtime.
Found three issues ... and only one of them is remotely associated with the reported issue
/remote.php/dav/calendars/tobixen@e.email/
). I believe that's a server problem, I believe the URL should have been quoted, anyway I'm trying to make a workaround in the code. It should not be directly related to the problems above, but it is a bit of a similar problem. Possibly there are more places where Nextcloud returns unquoted URLs while we're expecting fully valid URLs.418 I'm a teapot
when I'm trying to take out a sync-token report. I've disabled the tests on sync-tokens.Next I will try to make a test that explicitly creates an task with a UID and a different file name, fetches it, saves it and fetches it again ...
Trying to make a test to replicate the problem ... it would be nice to first know exactly what the problem is. And then I read this ...
if calendars: for c in calendars: todos = c.todos() for todo in todos: ... c.save_todo(todo.data)
Of course this will break! Perhaps the problem is neither on the server side nor on the client side, but in the example code!
The code above reads a list of todos, and then attempts to save the icalendar data back to the calendar. The todo object contains some information, like the URL of the object itself (including the file name). todo.data
only contains the icalendar data. When the caldav library is tasked to saving some ical data to the calendar, it will make up a URL, with "${uuid}.ics"
as the file name. If the task already exists with another filename but the same uuid, the server is in it's full right to politely reject it.
(Why on earth should a "calendar resource object" have a unique file name independent from it's uuid? I don't know. There is a saying that "If all you have is a hammer, everything looks like a nail" - probably the guy inventing or championing the CalDAV protocol had the DAV protocol as his only hammer).
Try replacing it with something like this (untested code ahead - may or may not work):
if calendars:
for c in calendars:
todos = c.todos()
for todo in todos:
...
todo.save()
There seems to be no references to save_todo(todo.data)
in the examples/*.py in the HEAD of the master branch.
Can I close this issue? :-)
Let me run some tests
Hard to say why I'd decided to use c.save_todo(todo.data). Maybe there were not enough different examples/documentation of proper VTODO handling for me :( Still, save_todo(ical_text_here)
IS the way to create a new task, correct?
Right now everything works fine (nextcloud-created tasks included). Thanks! The library is really helpful π
Maybe there were not enough different examples/documentation of proper VTODO handling for me
I should probably look into that
Still,
save_todo(ical_text_here)
IS the way to create a new task, correct?
Yes, indeed
Hello, Thank for providing such an awesome library.
I also happen to make a todo on my selfhosted Nextcloud.
Thanks to the nice examples and docs, I was able to add events and todos to calendars
app.
However it is not possible to add todo to my tasks
app.
here is how my function looks like so far:
my_task = workingcal.save_todo("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VEVENT
UID:20220516T06i3000Z-123401@example.com
DTSTAMP:20220716T060000Z
DTSTART:20220717T060000Z
DTEND:20220717T230000Z
RRULE:FREQ=YEARLY
SUMMARY:Python4 test
END:VEVENT
END:VCALENDAR
""")
Any idea how should I save the app to be shown on tasks? Thanks alot.
Hmm ... maybe this:
my_task = workingcal.save_todo("""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Example Corp.//CalDAV Client//EN
BEGIN:VTODO
UID:20220516T06i3000Z-123401@example.com
DTSTAMP:20220716T060000Z
SUMMARY:Python4 test
END:VTODO
END:VCALENDAR
""")
@tobixen Thanks so much. works perfectly. Any idea where can I read about cardav format? I want to set due date for the task and just play with it. Thanks
https://icalendar.org/RFC-Specifications/iCalendar-RFC-5545/ perhaps.
I'm intending to fix the caldav library so that one can add simple tasks and events without knowing the ics format
I'm intending to fix the caldav library so that one can add simple tasks and events without knowing the ics format
Thanks so much. I'll be happy to contribute as well.
Oh, I have already implemented something, though I haven't tested it very well yet ... try if this works for you:
from datetime import datetime
my_task = workingcal.save_todo(summary="python4 test", due=datetime.now())
Oh, I have already implemented something, though I haven't tested it very well yet ... try if this works for you:
Yes and it seems awesome. Actually last time I've tried it out but got some problems. Will double check it later on.
It looks like there's an issue with the way caldav 0.8.0 handles task editing (or with the way I do it π )
When I try to edit any task (located on Nextcloud 21.0.3 / calendar ver 2.3.3 / tasks ver 0.14.2) with uids that look like, well uuids (22bf21be-9d8f-4cae-98a8-161e370a997e), I constantly get an error. When uids look like a hex strings (d34e3a88a5ab4de08e389b6383610586), I can update tasks without any code corrections.
The code I tried I basically took from examples:
The error itself:
The error can be easily replicated with Nextcloud Tasks (by default it creates tasks with uuids). Maybe it's related to dashes?
I think it's an issue with the library because other caldav clients (2do, nextcloud itself) update tasks with such uids just fine.