icalendar2 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +4 -1
- data/README.md +2 -0
- data/lib/icalendar2/calendar.rb +10 -7
- data/lib/icalendar2/calendar_property.rb +2 -1
- data/lib/icalendar2/component/alarm.rb +9 -0
- data/lib/icalendar2/component/base.rb +8 -7
- data/lib/icalendar2/component/freebusy.rb +16 -0
- data/lib/icalendar2/component/journal.rb +18 -0
- data/lib/icalendar2/component/timezone.rb +9 -0
- data/lib/icalendar2/component/todo.rb +19 -0
- data/lib/icalendar2/component.rb +2 -1
- data/lib/icalendar2/property/base.rb +9 -3
- data/lib/icalendar2/property.rb +1 -1
- data/lib/icalendar2/tokens.rb +1 -1
- data/lib/icalendar2/value/text_value.rb +5 -8
- data/lib/icalendar2/value.rb +2 -1
- data/lib/icalendar2/version.rb +1 -1
- data/lib/icalendar2.rb +5 -0
- metadata +54 -34
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# icalendar2 - generate, consume and validate iCalendar feeds
|
2
2
|
|
3
|
+
[](https://travis-ci.org/ericcf/icalendar2)
|
4
|
+
|
3
5
|
## Warning
|
4
6
|
|
5
7
|
This is NOT production ready yet. It has not been extensively tested, and you
|
data/lib/icalendar2/calendar.rb
CHANGED
@@ -8,10 +8,10 @@ module Icalendar2
|
|
8
8
|
Event::VALUE => []
|
9
9
|
}
|
10
10
|
@properties = {
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
"calscale" => Property::Nil.new,
|
12
|
+
"method" => Property::Nil.new,
|
13
|
+
"prodid" => Property::Nil.new,
|
14
|
+
"version" => Property::Nil.new
|
15
15
|
}
|
16
16
|
end
|
17
17
|
|
@@ -32,7 +32,7 @@ module Icalendar2
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def set_property(property_name, value, parameters = {})
|
35
|
-
property = property_name.downcase
|
35
|
+
property = property_name.to_s.downcase
|
36
36
|
if value.nil?
|
37
37
|
@properties[property].value.to_s
|
38
38
|
elsif (factory = CalendarProperty.get_factory(property_name))
|
@@ -64,7 +64,9 @@ module Icalendar2
|
|
64
64
|
str = "#{Tokens::COMPONENT_BEGIN}:#{VALUE}#{Tokens::CRLF}"
|
65
65
|
str << body_to_ical
|
66
66
|
str << "#{Tokens::COMPONENT_END}:#{VALUE}#{Tokens::CRLF}"
|
67
|
-
str.encode("UTF-8")
|
67
|
+
str = str.encode("UTF-8") if str.respond_to?(:encode)
|
68
|
+
|
69
|
+
str
|
68
70
|
end
|
69
71
|
|
70
72
|
def add_component(component)
|
@@ -78,7 +80,8 @@ module Icalendar2
|
|
78
80
|
private
|
79
81
|
|
80
82
|
def body_to_ical
|
81
|
-
|
83
|
+
sorted_properties = @properties.zip.map(&:first).sort
|
84
|
+
str = sorted_properties.map { |p| p[1] && p[1].to_ical }.join
|
82
85
|
str << events.map(&:to_ical).join
|
83
86
|
end
|
84
87
|
end
|
@@ -3,7 +3,8 @@ module Icalendar2
|
|
3
3
|
def self.get_factory(calendar_property_name)
|
4
4
|
# "VERSION" => CalendarProperty::Version, etc.
|
5
5
|
begin
|
6
|
-
|
6
|
+
property_class_name = calendar_property_name.to_s.capitalize
|
7
|
+
const_get(property_class_name) if const_defined?(property_class_name)
|
7
8
|
rescue NameError
|
8
9
|
nil
|
9
10
|
end
|
@@ -31,7 +31,7 @@ module Icalendar2
|
|
31
31
|
def valid?
|
32
32
|
present_property_names = @properties.keys
|
33
33
|
@properties.values.flatten.all?(&:valid?) &&
|
34
|
-
self.class.required_property_names.all? { |p| present_property_names.include?(p) }
|
34
|
+
self.class.required_property_names.all? { |p| present_property_names.include?(p.to_s) }
|
35
35
|
end
|
36
36
|
|
37
37
|
def set_property(property_name, value, parameters = {})
|
@@ -61,9 +61,9 @@ module Icalendar2
|
|
61
61
|
define_method(property_sym) do |*args|
|
62
62
|
value, parameters = *args
|
63
63
|
if value.nil?
|
64
|
-
@properties[property_sym]
|
64
|
+
@properties[property_sym.to_s]
|
65
65
|
else
|
66
|
-
@properties[property_sym] = Property.get_factory(property_sym).new(value, parameters)
|
66
|
+
@properties[property_sym.to_s] = Property.get_factory(property_sym).new(value, parameters)
|
67
67
|
end
|
68
68
|
end
|
69
69
|
alias_method "#{property_sym}=", property_sym
|
@@ -72,18 +72,19 @@ module Icalendar2
|
|
72
72
|
def self.define_multiple_accessor(property_sym)
|
73
73
|
property_factory = Property.get_factory(property_sym)
|
74
74
|
define_method(property_factory::PLURAL) do
|
75
|
-
@properties[property_sym]
|
75
|
+
@properties[property_sym.to_s]
|
76
76
|
end
|
77
77
|
define_method(property_sym) do |*args|
|
78
78
|
value, parameters = *args
|
79
|
-
@properties[property_sym] ||= []
|
80
|
-
@properties[property_sym] << property_factory.new(value, parameters)
|
79
|
+
@properties[property_sym.to_s] ||= []
|
80
|
+
@properties[property_sym.to_s] << property_factory.new(value, parameters)
|
81
81
|
end
|
82
82
|
alias_method "#{property_sym}=", property_sym
|
83
83
|
end
|
84
84
|
|
85
85
|
def properties_to_ical
|
86
|
-
@properties.
|
86
|
+
sorted_properties = @properties.zip.map(&:first).sort
|
87
|
+
sorted_properties.map { |p| p[1] && p[1].to_ical }.join
|
87
88
|
end
|
88
89
|
end
|
89
90
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Icalendar2
|
2
|
+
# See http://tools.ietf.org/html/rfc5545#section-3.6.4
|
3
|
+
class Freebusy < Component::Base
|
4
|
+
VALUE = "VFREEBUSY"
|
5
|
+
|
6
|
+
requires :exactly_one => [:dtstamp, :uid]
|
7
|
+
accepts :exactly_one => [:contact, :dtstart, :dtend, :organizer, :url],
|
8
|
+
:one_or_more => [:attendee, :comment, :freebusy, :rstatus]
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super
|
12
|
+
self.uid = new_uid
|
13
|
+
self.dtstamp = new_timestamp
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Icalendar2
|
2
|
+
# See http://tools.ietf.org/html/rfc5545#section-3.6.3
|
3
|
+
class Journal < Component::Base
|
4
|
+
VALUE = "VJOURNAL"
|
5
|
+
|
6
|
+
requires :exactly_one => [:dtstamp, :uid]
|
7
|
+
accepts :exactly_one => [:klass, :created, :dtstart, :last_mod, :organizer,
|
8
|
+
:recurid, :seq, :status, :summary, :url],
|
9
|
+
:one_or_more => [:rrule, :attach, :attendee, :categories, :comment,
|
10
|
+
:contact, :description, :exdate, :related_to, :rdate, :rstatus]
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
super
|
14
|
+
self.uid = new_uid
|
15
|
+
self.dtstamp = new_timestamp
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Icalendar2
|
2
|
+
# See http://tools.ietf.org/html/rfc5545#section-3.6.2
|
3
|
+
class Todo < Component::Base
|
4
|
+
VALUE = "VTODO"
|
5
|
+
|
6
|
+
requires :exactly_one => [:dtstamp, :uid]
|
7
|
+
accepts :exactly_one => [:klass, :completed, :created, :description,
|
8
|
+
:dtstart, :geo, :last_mod, :location, :organizer, :percent, :priority,
|
9
|
+
:recurid, :seq, :status, :summary, :url, :due, :duration],
|
10
|
+
:one_or_more => [:rrule, :attach, :attendee, :categories, :comment,
|
11
|
+
:contact, :exdate, :rstatus, :related_to, :resources, :rdate]
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
super
|
15
|
+
self.uid = new_uid
|
16
|
+
self.dtstamp = new_timestamp
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/icalendar2/component.rb
CHANGED
@@ -2,7 +2,8 @@ module Icalendar2
|
|
2
2
|
module Component
|
3
3
|
def self.get_factory(component_name)
|
4
4
|
# "VFOO" => "Foo", etc.
|
5
|
-
|
5
|
+
component_class_name = component_name.gsub(/^V/, "").capitalize
|
6
|
+
Icalendar2.const_get(component_class_name) if Icalendar2.const_defined?(component_class_name)
|
6
7
|
end
|
7
8
|
end
|
8
9
|
end
|
@@ -2,7 +2,6 @@ module Icalendar2
|
|
2
2
|
module Property
|
3
3
|
class Base
|
4
4
|
MAX_LINE_LENGTH = 75
|
5
|
-
LIST_SEPARATOR = /(?<!\\),/
|
6
5
|
|
7
6
|
attr_reader :value, :parameters
|
8
7
|
|
@@ -26,7 +25,7 @@ module Icalendar2
|
|
26
25
|
|
27
26
|
def initialize(value, parameters = {})
|
28
27
|
@value = if list?
|
29
|
-
value_list = value.respond_to?(:
|
28
|
+
value_list = value.respond_to?(:gsub) ? split_list(value) : value
|
30
29
|
value_list.map { |v| value_object(v) }
|
31
30
|
else
|
32
31
|
value_object(value)
|
@@ -55,9 +54,11 @@ module Icalendar2
|
|
55
54
|
|
56
55
|
private
|
57
56
|
|
57
|
+
LIST_SEPARATOR = /([^\\]),/
|
58
|
+
|
58
59
|
def validate
|
59
60
|
@valid = if @value.is_a? Array
|
60
|
-
@value.all?(&:valid?)
|
61
|
+
@value.compact.all?(&:valid?)
|
61
62
|
else
|
62
63
|
@value.valid?
|
63
64
|
end
|
@@ -75,6 +76,11 @@ module Icalendar2
|
|
75
76
|
def fold(str)
|
76
77
|
str.scan(/.{1,#{MAX_LINE_LENGTH}}/).join("#{Tokens::CRLF} ")
|
77
78
|
end
|
79
|
+
|
80
|
+
def split_list(str)
|
81
|
+
# Ruby 1.8.7 doesn't support negative lookbehind, so using this hack...
|
82
|
+
str.gsub(LIST_SEPARATOR, "\\1x,").split(/x,/)
|
83
|
+
end
|
78
84
|
end
|
79
85
|
end
|
80
86
|
end
|
data/lib/icalendar2/property.rb
CHANGED
@@ -3,7 +3,7 @@ module Icalendar2
|
|
3
3
|
def self.get_factory(property_sym)
|
4
4
|
# :foo => "Foo", :bar_baz => "BarBaz", etc.
|
5
5
|
property_name = property_sym.to_s.split(/_/).map(&:capitalize).join('')
|
6
|
-
const_get(property_name
|
6
|
+
const_get(property_name) if const_defined?(property_name)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/icalendar2/tokens.rb
CHANGED
@@ -13,7 +13,7 @@ module Icalendar2
|
|
13
13
|
QSAFE_CHAR = /[^"#{CONTROL_CHARS}]/
|
14
14
|
SAFE_CHAR = /[^"#{CONTROL_CHARS};:,]/
|
15
15
|
VALUE_CHAR = /[^#{CONTROL_CHARS}]/
|
16
|
-
NON_US_ASCII_CHARS = "\x80-\xFF"
|
16
|
+
NON_US_ASCII_CHARS = "\x80-\xFF"
|
17
17
|
QUOTED_STRING = /#{DQUOTE}(?:#{SAFE_CHAR})*#{DQUOTE}/
|
18
18
|
PARAM_VALUE = "(?:#{SAFE_CHAR})*|#{QUOTED_STRING}"
|
19
19
|
IANA_TOKEN = "[-a-zA-Z0-9]+"
|
@@ -4,14 +4,11 @@ module Icalendar2
|
|
4
4
|
class TextValue < Value
|
5
5
|
|
6
6
|
def initialize(value)
|
7
|
-
|
8
|
-
'
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
"\r" => "\n"
|
13
|
-
}
|
14
|
-
super(value.respond_to?(:gsub) ? value.gsub(/\\|;|,|\r\n|\r/, replacements) : value)
|
7
|
+
if value.respond_to?(:gsub)
|
8
|
+
super(value.gsub(/\\/, "\\\\\\").gsub(';', '\;').gsub(',', '\,').gsub("\r\n", "\n").gsub("\r", "\n"))
|
9
|
+
else
|
10
|
+
super(value)
|
11
|
+
end
|
15
12
|
end
|
16
13
|
end
|
17
14
|
end
|
data/lib/icalendar2/value.rb
CHANGED
@@ -13,7 +13,8 @@ module Icalendar2
|
|
13
13
|
def self.get_factory(value_sym)
|
14
14
|
# :foo => "Foo", :bar_baz => "BarBaz", etc.
|
15
15
|
value_name = value_sym.to_s.split(/_/).map(&:capitalize).join('')
|
16
|
-
|
16
|
+
value_class_name = "#{value_name}Value"
|
17
|
+
Icalendar2.const_get(value_class_name) if Icalendar2.const_defined?(value_class_name)
|
17
18
|
end
|
18
19
|
|
19
20
|
def initialize(value)
|
data/lib/icalendar2/version.rb
CHANGED
data/lib/icalendar2.rb
CHANGED
@@ -8,6 +8,11 @@ module Icalendar2
|
|
8
8
|
|
9
9
|
autoload :Component, "icalendar2/component"
|
10
10
|
autoload :Event, "icalendar2/component/event"
|
11
|
+
autoload :Todo, "icalendar2/component/todo"
|
12
|
+
autoload :Journal, "icalendar2/component/journal"
|
13
|
+
autoload :Freebusy, "icalendar2/component/freebusy"
|
14
|
+
autoload :Timezone, "icalendar2/component/timezone"
|
15
|
+
autoload :Alarm, "icalendar2/component/alarm"
|
11
16
|
module Component
|
12
17
|
autoload :Base, "icalendar2/component/base"
|
13
18
|
end
|
metadata
CHANGED
@@ -1,50 +1,60 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: icalendar2
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Eric Carty-Fickes
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2012-12-13 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: rspec
|
16
|
-
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
|
-
requirements:
|
19
|
-
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
version: '2'
|
22
|
-
type: :development
|
23
22
|
prerelease: false
|
24
|
-
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
24
|
none: false
|
26
|
-
requirements:
|
25
|
+
requirements:
|
27
26
|
- - ~>
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 7
|
29
|
+
segments:
|
30
|
+
- 2
|
31
|
+
version: "2"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Borrows fromt the API used by the icalendar Ruby gem. Outputs iCalendar (RFC 5545) formatted text.
|
35
|
+
email:
|
33
36
|
- ericcf@northwestern.edu
|
34
37
|
executables: []
|
38
|
+
|
35
39
|
extensions: []
|
36
|
-
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
37
42
|
- CHANGELOG.md
|
38
43
|
- README.md
|
39
|
-
files:
|
44
|
+
files:
|
40
45
|
- lib/icalendar2/calendar.rb
|
41
46
|
- lib/icalendar2/calendar_property/calscale.rb
|
42
47
|
- lib/icalendar2/calendar_property/method.rb
|
43
48
|
- lib/icalendar2/calendar_property/prodid.rb
|
44
49
|
- lib/icalendar2/calendar_property/version.rb
|
45
50
|
- lib/icalendar2/calendar_property.rb
|
51
|
+
- lib/icalendar2/component/alarm.rb
|
46
52
|
- lib/icalendar2/component/base.rb
|
47
53
|
- lib/icalendar2/component/event.rb
|
54
|
+
- lib/icalendar2/component/freebusy.rb
|
55
|
+
- lib/icalendar2/component/journal.rb
|
56
|
+
- lib/icalendar2/component/timezone.rb
|
57
|
+
- lib/icalendar2/component/todo.rb
|
48
58
|
- lib/icalendar2/component.rb
|
49
59
|
- lib/icalendar2/parameter/altrep.rb
|
50
60
|
- lib/icalendar2/parameter/base.rb
|
@@ -106,26 +116,36 @@ files:
|
|
106
116
|
- README.md
|
107
117
|
homepage: https://github.com/ericcf/icalendar2
|
108
118
|
licenses: []
|
119
|
+
|
109
120
|
post_install_message:
|
110
121
|
rdoc_options: []
|
111
|
-
|
122
|
+
|
123
|
+
require_paths:
|
112
124
|
- lib
|
113
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
126
|
none: false
|
115
|
-
requirements:
|
116
|
-
- -
|
117
|
-
- !ruby/object:Gem::Version
|
118
|
-
|
119
|
-
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
hash: 3
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
version: "0"
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
135
|
none: false
|
121
|
-
requirements:
|
122
|
-
- -
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
hash: 3
|
140
|
+
segments:
|
141
|
+
- 0
|
142
|
+
version: "0"
|
125
143
|
requirements: []
|
144
|
+
|
126
145
|
rubyforge_project:
|
127
146
|
rubygems_version: 1.8.24
|
128
147
|
signing_key:
|
129
148
|
specification_version: 3
|
130
149
|
summary: iCalendar (RFC 5545) Ruby library
|
131
150
|
test_files: []
|
151
|
+
|