{"id":24967051,"url":"https://github.com/software-mansion-labs/elixir-caldav-client","last_synced_at":"2025-04-11T02:13:44.222Z","repository":{"id":43339062,"uuid":"337096937","full_name":"software-mansion-labs/elixir-caldav-client","owner":"software-mansion-labs","description":"CalDAV client in the Elixir language","archived":false,"fork":false,"pushed_at":"2024-06-18T05:43:46.000Z","size":49,"stargazers_count":42,"open_issues_count":4,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-24T23:41:19.390Z","etag":null,"topics":["caldav","caldav-client","calendar","elixir","elixir-lang","elixir-library"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/caldav_client","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/software-mansion-labs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-08T14:09:36.000Z","updated_at":"2024-12-28T01:37:52.000Z","dependencies_parsed_at":"2022-09-19T17:42:02.983Z","dependency_job_id":null,"html_url":"https://github.com/software-mansion-labs/elixir-caldav-client","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/software-mansion-labs%2Felixir-caldav-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/software-mansion-labs%2Felixir-caldav-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/software-mansion-labs%2Felixir-caldav-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/software-mansion-labs%2Felixir-caldav-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/software-mansion-labs","download_url":"https://codeload.github.com/software-mansion-labs/elixir-caldav-client/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248328163,"owners_count":21085261,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caldav","caldav-client","calendar","elixir","elixir-lang","elixir-library"],"created_at":"2025-02-03T12:36:54.751Z","updated_at":"2025-04-11T02:13:44.199Z","avatar_url":"https://github.com/software-mansion-labs.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Elixir CalDAV Client\n\n[![Hex.pm](https://img.shields.io/hexpm/v/caldav_client.svg)](https://hex.pm/packages/caldav_client)\n[![API Docs](https://img.shields.io/badge/api-docs-brightgreen.svg)](https://hexdocs.pm/caldav_client/readme.html)\n\n\nThis library allows for managing calendars and events on a remote calendar server according to CalDAV specification ([RFC 4791](https://tools.ietf.org/html/rfc4791)). Supports time zones, recurrence expansion and ETags. Internally uses [Tesla](https://github.com/teamon/tesla) HTTP client.\n\nPlease note that conversion between native Elixir structures and iCalendar format ([RFC 5545](https://tools.ietf.org/html/rfc5545)) is beyond the scope of this library. The following packages are recommended:\n\n* [ICalendar](https://github.com/lpil/icalendar)\n* [Calibex](https://github.com/kbrw/calibex)\n\n## Installation\n\nCalDAV Client is published on [Hex](https://hex.pm/packages/caldav_client). Add it to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:caldav_client, \"~\u003e 2.0\"},\n\n    # time zone database\n    {:tzdata, \"~\u003e 1.1\"},\n\n    # recommended Tesla adapter\n    {:hackney, \"~\u003e 1.18\"},\n  ]\nend\n```\n\nThen run `mix deps.get` to install the package and its dependencies.\n\nIt is also required to configure the time zone database and the default Tesla adapter in the `config/config.exs` of your project:\n\n```elixir\n# config/config.exs\n\nimport Config\n\nconfig :elixir, :time_zone_database, Tzdata.TimeZoneDatabase\n\nconfig :tesla, adapter: Tesla.Adapter.Hackney\n```\n\n\u003e The default Tesla adapter is Erlang's built-in `httpc`, but currently it does not support custom HTTP methods such as `MKCALENDAR` or `REPORT`.\n\n## Documentation\n\nAvailable at [HexDocs](https://hexdocs.pm/caldav_client).\n\n## Examples\n\n### Client\n\nThe `%CalDAVClient.Client{}` struct aggregates the connection details such as the server address and user credentials.\n\n```elixir\nclient = %CalDAVClient.Client{\n  server_url: \"http://127.0.0.1:8800/cal.php\",\n  auth: %CalDAVClient.Auth.Basic{\n    username: \"username\",\n    password: \"password\"\n  }\n}\n```\n\nThe library supports Basic, Digest and Bearer authentication:\n\n```elixir\n%CalDAVClient.Auth.Basic{\n  username: \"username\",\n  password: \"password\"\n}\n\n%CalDAVClient.Auth.Digest{\n  username: \"username\",\n  password: \"password\"\n}\n\n%CalDAVClient.Auth.Bearer{\n  token: \"token\"\n}\n```\n\n### Calendar\n\nEach calendar user (or principal, according to CalDAV terminology) can have multiple calendars, which are identified by URLs.\n\n```elixir\ncalendar_url = CalDAVClient.URL.Builder.build_calendar_url(\"username\", \"example\")\n# \"/calendars/username/example\"\n\n:ok =\n  client\n  |\u003e CalDAVClient.Calendar.create(calendar_url,\n    name: \"Example calendar\",\n    description: \"This is an example calendar.\"\n  )\n\n:ok = client |\u003e CalDAVClient.Calendar.update(calendar_url, name: \"Lorem ipsum\")\n\n:ok = client |\u003e CalDAVClient.Calendar.delete(calendar_url)\n```\n\nIn case of any failure, `{:error, reason}` tuple will be returned.\n\n### Event\n\n```elixir\nevent_url = CalDAVClient.URL.Builder.build_event_url(calendar_url, \"event.ics\")\n# \"/calendars/username/example/event.ics\"\n\nevent_icalendar = \"\"\"\nBEGIN:VCALENDAR\nPRODID:-//Elixir//CalDAV//EN\nVERSION:2.0\nBEGIN:VEVENT\nUID:totally-random-uid\nDTSTAMP:20210101T120000Z\nDTSTART:20210101T140000Z\nEND:VEVENT\nEND:VCALENDAR\n\"\"\"\n\n{:ok, etag} = client |\u003e CalDAVClient.Event.create(event_url, event_icalendar)\n```\n\n`CalDAVClient.Event.create/3` returns\n`{:error, :unsupported_media_type}` on malformed payload or `{:error, :already_exists}` when the specified URL is already taken (see [If-None-Match](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match)).\n\nYou may get a single event by its URL address:\n\n```elixir\n{:ok, icalendar, etag} = client |\u003e CalDAVClient.Event.get(event_url)\n```\n\nIt is also possible to find the event with a specific `UID` property within the calendar:\n\n```elixir\n{:ok, %CalDAVClient.Event{url: url, icalendar: icalendar, etag: etag}} =\n  client |\u003e CalDAVClient.Event.find_by_uid(calendar_url, event_uid)\n```\n\nBoth `CalDAVClient.Event.get/2` and `CalDAVClient.Event.find_by_uid/3` return\n`{:error, :not_found}` when the event does not exist.\n\nWhen modifying an event, you may optionally include the `etag` option in order to prevent simultaneous updates and ensure that the appropriate version of the event will be overwritten (see [ETag](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag)).\n\n```elixir\n{:ok, etag} = client |\u003e CalDAVClient.Event.update(event_url, event_icalendar, etag: etag)\n```\n\n```elixir\n:ok = client |\u003e CalDAVClient.Event.delete(event_url, etag: etag)\n```\n\nWhen `ETag` does not match, both `CalDAVClient.Event.update/4` and `CalDAVClient.Event.delete/3` return `{:error, :bad_etag}`.\n\n### Events\n\nCalDAV specification defines a way to retrieve all events that meet certain criteria, which can be used to list all events within a specified time range.\n\n```elixir\nfrom = DateTime.from_naive!(~N[2021-01-01 00:00:00], \"Europe/Warsaw\")\nto = DateTime.from_naive!(~N[2021-02-01 00:00:00], \"Europe/Warsaw\")\n\n{:ok, events} = client |\u003e CalDAVClient.Event.get_events(calendar_url, from, to)\n```\n\nYou may also pass `expand: true` option to enable recurrence expansion, which will force the calendar server to convert all events having the `RRULE` property into a series of occurrences within the specified time range with the `RECURRENCE-ID` property set.\n\n```elixir\n{:ok, events} = client |\u003e CalDAVClient.Event.get_events(calendar_url, from, to, expand: true)\n```\n\nIt is also possible to retrieve only the events with an alarm (`VALARM`) within a specified time range:\n\n```elixir\n{:ok, events} = client |\u003e CalDAVClient.Event.get_events_by_alarm(calendar_url, from, to)\n```\n\nFor custom event reports, pass the XML request body to `CalDAVClient.Event.get_events_by_xml/3` function:\n```elixir\n{:ok, events} = client |\u003e CalDAVClient.Event.get_events_by_xml(calendar_url, request_xml)\n```\n\nIn all cases above, `events` is a list of `%CalDAVClient.Event{}` structs with `url`, `icalendar` and `etag` fields.\n\n## Testing\n\nBy default, `mix test` will execute only the unit tests which check XML building and parsing as well as URL generation and iCalendar date-time serialization.\n\nThe full test suite requires a connection to a calendar server, e.g. [Baïkal](https://github.com/sabre-io/Baikal) (Docker image available [here](https://hub.docker.com/r/ckulka/baikal)).\nWhen installed and configured, create a test user account and provide credentials along with the server details in `config/test.exs` in this library.\n\n\u003e Please note that the test suite operates directly on the calendar server and will automatically create and delete the test calendar during execution.\n\n```elixir\n# config/test.exs\n\nconfig :caldav_client, :test_server,\n  server_url: \"http://127.0.0.1:8800/cal.php\",\n  username: \"username\",\n  password: \"password\"\n```\n\nWhen configured, the test suite including integration tests can be executed by running:\n\n```sh\nmix test --include integration\n```\n\n## Copyright and License\n\nCopyright 2022, [Software Mansion](https://swmansion.com/?utm_source=git\u0026utm_medium=readme\u0026utm_campaign=elixir-caldav-client)\n\n[![Software Mansion](https://logo.swmansion.com/logo?color=white\u0026variant=desktop\u0026width=200\u0026tag=elixir-caldav-client-github)](https://swmansion.com/?utm_source=git\u0026utm_medium=readme\u0026utm_campaign=elixir-caldav-client)\n\nThe code located in this repository is licensed under the [Apache License, Version 2.0](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftware-mansion-labs%2Felixir-caldav-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoftware-mansion-labs%2Felixir-caldav-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftware-mansion-labs%2Felixir-caldav-client/lists"}