Giter VIP home page Giter VIP logo

ex_ical's Introduction

I'm Michał Kalbarczyk 🥷 Software Ninjaneer

Technologies

Social

Stats


ex_ical's People

Contributors

ellocsys avatar fazibear avatar leesharma avatar rhumbertgz avatar tcitworld avatar

Stargazers

 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

ex_ical's Issues

Outlook generated timezone can´t be parsed

DTSTART;TZID=W. Europe Standard Time:20181227T130000 or
DTSTART;TZID="W. Europe Standard Time":20181227T130000

leads to

 start: {:error, {:invalid_timezone, "W. Europe Standard Time"}},

Reason seems to be the missing lookup:
https://github.com/bitwalker/timex/blob/master/priv/standard_to_olson.exs

I´m not sure where and how to do it, but there needs be something like this:
Timex.Timezone.Utils.to_olson("W. Europe Standard ") which replaces it with "Europe/Berlin"

ExIcal is locked to an old version of Timex

Current Behavior

ex_ical is locked on to an old release of timex ({:timex, "~> 1.0"}, they're currently at 3.x).

This means that in order to use ex_ical in a project (assuming that the project isn't using timex ~> 1.0, a developer needs to not only include an extra library/version, but they will also need to write their own adapter from the old Timex datetime formats into whatever library they're using in their application.

Desired Behavior

This library should be able to work with current DateTime libraries.

Since Date and DateTime were only just added to Elixir (end even then, they aren't a complete implementation), there are a number of libraries available (timex, calendar, good_times, etc.) Ideally, using ex_ical shouldn't lock you into having to use a specific version of a specific library–it should be able to work with a number of options. Just upgrading to timex ~> 3.0 makes the situation better, but it won't solve the full problem. I think that using an adapter pattern and letting the user specify their library/adapter is the best way to handle this.

Possible Interface

Ideally, something like the following interface would work. It should be able to handle a default case with minimal boilerplate required; common cases with a small amount of configuration; and "unsupported" cases with a bit more configuration.

Using the default datetime library (Timex, current version)

# mix.exs

def applications do
  [applications: [:timex, ...]]
end

def deps do
  [
    {:timex, "~> 3.0"},
    {:ex_ical, "~> 1.0"},
    ...
  ]
end

Using calendar, another popular DateTime library

# mix.exs

def applications do
  [applications: [:calendar, ...]]
end

def deps do
  [
    {:calendar, "~> 1.0"},
    {:ex_ical, "~> 1.0"},
    ....
  ]
end


# config/config.exs

config :ex_ical,
  datetime_library: :calendar

Using an unsupported or "bespoke" DateTime solution

# mix.exs

def applications do
  [applications: [...]]
end

def deps do
  [{:ex_ical, "~> 1.0"}, ...]
end


# config/config.exs

config :ex_ical,
  datetime_library: :bespoke_datetime,
  datetime_adapter: BespokeDateTime.Adapter  # the user writes this module

Not all valid iCalendar Date/Date-Time formats can be parsed

Current Behavior

Some of the valid date/date-time formats (as defined in RFC 2445) are not parsable.
For example, when trying to parse a DTSTART using a datetime with the local timezone:

iex> ical = """
            BEGIN:VEVENT
            DTSTART:19690620T201804
            END:VEVENT
            """ # local time
iex> ExIcal.parse ical
** (FunctionClauseError) no function clause matching in ExIcal.DateParser.parse/2
    (ex_ical) lib/ex_ical/date_parser.ex:7: ExIcal.DateParser.parse("19690620T201804", nil)
    (ex_ical) lib/ex_ical/parser.ex:15: ExIcal.Parser.parse_line/2
     (elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ex_ical) lib/ex_ical/parser.ex:8: ExIcal.Parser.parse/1

From what I can tell, Form 1 and Form 3 (below) are not currently handled.

Expected Behavior

I'd expect all formats defined in the specs to be parsable by this library.
There are four valid input forms:

Also, these inline time zones need to interact in a reasonable way with the global calendar time zones–inline time zones (Forms 2 & 3) should take precedence over global zones.

Here are some possible rules:

# Example Line When no global TZID is set When TZID:Europe/Berlin
1 DTSTART:19690620 No timezone (date) No timezone (date)
2* DTSTART:19690620Z No timezone (date) No timezone (date)
3 DTSTART:19690620T201804 No timezone (local) Europe/Berlin
4 DTSTART:19690620T201804Z UTD UTD (priority to zulu time marker)
5 DTSTART;TZID=America/New_York:19690620T201804 America/New_York America/New_York (priority to inline tzid)
6* DTSTART;TZID=America/New_York:19690620T201804Z UDT (priority to zulu time marker) UDT (priority to zulu time marker)

*L2 & L6 are not in the spec, but I included them here for error tolerance

System Information

  • ExIcal: observed on 0.0.3
  • Elixir: 1.3.2
  • Erlang/OTP: 19
  • OS: Mac OS X 10.11.5

Can't parse date in "YYYYMMDD" format

I tried to use this tool to parse a Facebook birthday .ics file, but it failed with an argument error. Here is the format of the iCal file:

BEGIN:VCALENDAR
... (irrelevant header stuff)
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
BEGIN:VEVENT
DTSTART:20160611
SUMMARY:Foo Bar's birthday
RRULE:FREQ=YEARLY
DURATION:P1D
UID:[email protected]
END:VEVENT
...
END:VCALENDAR

This is the full text of the error:

** (ArgumentError) argument error
     (stdlib) :ets.lookup(:tzdata_current_release, :release_version)
              lib/tzdata/release_reader.ex:41: Tzdata.ReleaseReader.current_release_from_table/0
              lib/tzdata/release_reader.ex:13: Tzdata.ReleaseReader.simple_lookup/1
              lib/tzdata/release_reader.ex:7: Tzdata.ReleaseReader.zone_and_link_list/0
              lib/tzdata.ex:61: Tzdata.zone_exists?/1
              lib/timezone/timezone.ex:130: Timex.Timezone.get/2
    (ex_ical) lib/ex_ical/date_parser.ex:23: ExIcal.DateParser.parse/2
    (ex_ical) lib/ex_ical/parser.ex:12: ExIcal.Parser.parse_line/2

Following the stack trace, it looks like there's no pattern for the YYYYMMDD input string with a timezone of nil. When DateParser tried to parse DTSTART, it tried to pass nil to Timezone.get/1, throwing an argument error.

This looks like it won't be a hard fix; I'll open a pull request with the bugfix/tests.

ArgumentError when parsing a date with a time zone

Current behavior

Trying to parse an ical file with a TZID (either set calendar-wide or for a specific date) blows up with an ArgumentError on :ets.lookup/2 (called from Tzdata).

iex> calendar_wide_tzid = "BEGIN:VEVENT\nTZID=America/New_York\nDTSTART:19690620"
iex> date_specific_tzid = "BEGIN:VEVENT\nDTSTART;TZID=America/New_York:19690620"
iex> ExIcal.parse calendar_wide_tzid
** (ArgumentError) argument error
     (stdlib) :ets.lookup(:tzdata_current_release, :release_version)
              lib/tzdata/release_reader.ex:41: Tzdata.ReleaseReader.current_release_from_table/0
              lib/tzdata/release_reader.ex:13: Tzdata.ReleaseReader.simple_lookup/1
              lib/tzdata/release_reader.ex:7: Tzdata.ReleaseReader.zone_and_link_list/0
              lib/tzdata.ex:61: Tzdata.zone_exists?/1
              lib/timezone/timezone.ex:130: Timex.Timezone.get/2
    (ex_ical) lib/ex_ical/date_parser.ex:70: ExIcal.DateParser.datetime_from_params/3
    (ex_ical) lib/ex_ical/parser.ex:15: ExIcal.Parser.parse_line/2
iex> ExIcal.parse date_specific_tzid
** (ArgumentError) argument error
     (stdlib) :ets.lookup(:tzdata_current_release, :release_version)
     ...

This can be seen more directly with the DateParser:

iex> alias ExIcal.DateParser
iex> tzid = "America/New_York"
iex> date = "19690620"
iex> DateParser.parse(date, tzid)
** (ArgumentError) argument error
     (stdlib) :ets.lookup(:tzdata_current_release, :release_version)
      ...

Expected Behavior

The parser should create a new event given a valid time zone:

iex> ical = "BEGIN:VEVENT\nDTSTART;TZID=America/New_York:19690620"
iex> ExIcal.parse ical
[%ExIcal.Event{description: nil, end: nil, rrule: nil, stamp: nil,
  start: %Timex.DateTime{calendar: :gregorian, day: 20, hour: 0, minute: 0,
   month: 6, ms: 0, second: 0,
   timezone: %Timex.TimezoneInfo{abbreviation: "EDT",
    from: {:sunday, {{2016, 3, 13}, {2, 0, 0}}}, full_name: "America/New_York",
    offset_std: 60, offset_utc: -300,
    until: {:sunday, {{2016, 11, 6}, {1, 0, 0}}}}, year: 1969}, summary: nil}]

System Configuration

ExIcal: observed on 0.0.3
Elixir: 1.3.2
Erlang/OTP: 19
OS: Mac OS X 10.11.5

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.