Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.

This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

- Add support for the `DTSTAMP` field.
If not provided, it is initialized to the current UTC DateTime when serializing.

## v1.1.2 - 2022-01-16

- Handle calendars that wrap output such as Google Calendar
Expand Down
1 change: 1 addition & 0 deletions lib/icalendar/event.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule ICalendar.Event do
dtend: nil,
rrule: nil,
exdates: [],
dtstamp: nil,
description: nil,
location: nil,
url: nil,
Expand Down
8 changes: 8 additions & 0 deletions lib/icalendar/util/deserialize.ex
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,14 @@ defmodule ICalendar.Util.Deserialize do
%{acc | dtend: timestamp}
end

def parse_attr(
%Property{key: "DTSTAMP", value: dtstamp, params: params},
acc
) do
{:ok, timestamp} = to_date(dtstamp, params)
%{acc | dtstamp: timestamp}
end

def parse_attr(
%Property{key: "RRULE", value: rrule},
acc
Expand Down
4 changes: 4 additions & 0 deletions lib/icalendar/util/kv.ex
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ defmodule ICalendar.Util.KV do
"ATTENDEE;CN=James SM;PARTSTAT=ACCEPTED:mailto:[email protected]\n"

"""
def build("DTSTAMP", nil) do
"DTSTAMP:#{Value.to_ics(DateTime.utc_now())}Z\n"
end

def build(_, nil) do
""
end
Expand Down
2 changes: 2 additions & 0 deletions test/icalendar/deserialize_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ defmodule ICalendar.DeserializeTest do
COMMENT:Don't forget to take something to eat !
SUMMARY:Going fishing
DTEND:20151224T084500Z
DTSTAMP:20151224T080000Z
DTSTART:20151224T083000Z
LOCATION:123 Fun Street\\, Toronto ON\\, Canada
STATUS:TENTATIVE
Expand All @@ -25,6 +26,7 @@ defmodule ICalendar.DeserializeTest do
assert event == %Event{
dtstart: Timex.to_datetime({{2015, 12, 24}, {8, 30, 0}}),
dtend: Timex.to_datetime({{2015, 12, 24}, {8, 45, 0}}),
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 00, 0}}),
summary: "Going fishing",
description: "Escape from the world. Stare at some water.",
location: "123 Fun Street, Toronto ON, Canada",
Expand Down
54 changes: 41 additions & 13 deletions test/icalendar/event_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ defmodule ICalendar.EventTest do
alias ICalendar.Event

test "ICalendar.to_ics/1 of event" do
ics = %Event{} |> ICalendar.to_ics()
ics = %Event{dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})} |> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTSTAMP:20151224T084500Z
END:VEVENT
"""
end
Expand All @@ -17,14 +18,16 @@ defmodule ICalendar.EventTest do
%Event{
summary: "Going fishing",
description: "Escape from the world. Stare at some water.",
comment: "Don't forget to take something to eat !"
comment: "Don't forget to take something to eat !",
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
COMMENT:Don't forget to take something to eat !
DESCRIPTION:Escape from the world. Stare at some water.
DTSTAMP:20151224T084500Z
SUMMARY:Going fishing
END:VEVENT
"""
Expand All @@ -34,13 +37,15 @@ defmodule ICalendar.EventTest do
ics =
%Event{
dtstart: Timex.to_date({2015, 12, 24}),
dtend: Timex.to_date({2015, 12, 24})
dtend: Timex.to_date({2015, 12, 24}),
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTEND:20151224
DTSTAMP:20151224T084500Z
DTSTART:20151224
END:VEVENT
"""
Expand All @@ -50,13 +55,15 @@ defmodule ICalendar.EventTest do
ics =
%Event{
dtstart: Timex.to_datetime({{2015, 12, 24}, {8, 30, 00}}),
dtend: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
dtend: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}}),
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTEND:20151224T084500Z
DTSTAMP:20151224T084500Z
DTSTART:20151224T083000Z
END:VEVENT
"""
Expand All @@ -72,12 +79,17 @@ defmodule ICalendar.EventTest do
|> Timex.to_datetime("America/Chicago")

ics =
%Event{dtstart: dtstart, dtend: dtend}
%Event{
dtstart: dtstart,
dtend: dtend,
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTEND;TZID=America/Chicago:20151224T084500
DTSTAMP:20151224T084500Z
DTSTART;TZID=America/Chicago:20151224T083000
END:VEVENT
"""
Expand All @@ -89,13 +101,15 @@ defmodule ICalendar.EventTest do
summary: "Going fishing",
description:
"See this link http://example.com/pub" <>
"/calendars/jsmith/mytime.ics"
"/calendars/jsmith/mytime.ics",
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DESCRIPTION:See this link http://example.com/pub/calendars/jsmith/mytime.ics
DTSTAMP:20151224T084500Z
SUMMARY:Going fishing
END:VEVENT
"""
Expand All @@ -104,12 +118,14 @@ defmodule ICalendar.EventTest do
test "ICalendar.to_ics/1 with url" do
ics =
%Event{
url: "http://example.com/pub/calendars/jsmith/mytime.ics"
url: "http://example.com/pub/calendars/jsmith/mytime.ics",
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTSTAMP:20151224T084500Z
URL:http://example.com/pub/calendars/jsmith/mytime.ics
END:VEVENT
"""
Expand All @@ -118,12 +134,14 @@ defmodule ICalendar.EventTest do
test "ICalendar.to_ics/1 with integer UID" do
ics =
%Event{
uid: 815
uid: 815,
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTSTAMP:20151224T084500Z
UID:815
END:VEVENT
"""
Expand All @@ -132,12 +150,14 @@ defmodule ICalendar.EventTest do
test "ICalendar.to_ics/1 with string UID" do
ics =
%Event{
uid: "0815"
uid: "0815",
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTSTAMP:20151224T084500Z
UID:0815
END:VEVENT
"""
Expand All @@ -146,12 +166,14 @@ defmodule ICalendar.EventTest do
test "ICalendar.to_ics/1 with geo" do
ics =
%Event{
geo: {43.6978819, -79.3810277}
geo: {43.6978819, -79.3810277},
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTSTAMP:20151224T084500Z
GEO:43.6978819;-79.3810277
END:VEVENT
"""
Expand All @@ -160,26 +182,30 @@ defmodule ICalendar.EventTest do
test "ICalendar.to_ics/1 with categories" do
ics =
%Event{
categories: ["Fishing", "Nature", "Sport"]
categories: ["Fishing", "Nature", "Sport"],
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
CATEGORIES:Fishing,Nature,Sport
DTSTAMP:20151224T084500Z
END:VEVENT
"""
end

test "ICalendar.to_ics/1 with status" do
ics =
%Event{
status: :tentative
status: :tentative,
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
DTSTAMP:20151224T084500Z
STATUS:TENTATIVE
END:VEVENT
"""
Expand All @@ -188,13 +214,15 @@ defmodule ICalendar.EventTest do
test "ICalendar.to_ics/1 with class" do
ics =
%Event{
class: :private
class: :private,
dtstamp: Timex.to_datetime({{2015, 12, 24}, {8, 45, 00}})
}
|> ICalendar.to_ics()

assert ics == """
BEGIN:VEVENT
CLASS:PRIVATE
DTSTAMP:20151224T084500Z
END:VEVENT
"""
end
Expand Down
Loading