texel-recurrence-rule-parser 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +6 -0
- data/Manifest.txt +7 -0
- data/README.txt +53 -0
- data/Rakefile +12 -0
- data/bin/rrule_parser +0 -0
- data/lib/rrule_parser.rb +84 -0
- data/spec/lib/rrule_parser_spec.rb +91 -0
- metadata +78 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
= RruleParser
|
2
|
+
|
3
|
+
* FIX (url)
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
This package takes icalendar events (or any object conforming to their calling conventions),
|
8
|
+
and handles translating recurrence rules into temporal expressions.
|
9
|
+
|
10
|
+
== FEATURES/PROBLEMS:
|
11
|
+
|
12
|
+
Current list of supported expressions:
|
13
|
+
FREQ
|
14
|
+
INTERVAL
|
15
|
+
BYDAY
|
16
|
+
|
17
|
+
== SYNOPSIS:
|
18
|
+
|
19
|
+
code samples forthcoming.
|
20
|
+
|
21
|
+
== REQUIREMENTS:
|
22
|
+
|
23
|
+
requires Runt and Icalendar.
|
24
|
+
requires RSpec if you wish to run the specs.
|
25
|
+
|
26
|
+
== INSTALL:
|
27
|
+
|
28
|
+
sudo gem install texel-rrule-parser
|
29
|
+
|
30
|
+
== LICENSE:
|
31
|
+
|
32
|
+
(The MIT License)
|
33
|
+
|
34
|
+
Copyright (c) 2008 FIX
|
35
|
+
|
36
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
37
|
+
a copy of this software and associated documentation files (the
|
38
|
+
'Software'), to deal in the Software without restriction, including
|
39
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
40
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
41
|
+
permit persons to whom the Software is furnished to do so, subject to
|
42
|
+
the following conditions:
|
43
|
+
|
44
|
+
The above copyright notice and this permission notice shall be
|
45
|
+
included in all copies or substantial portions of the Software.
|
46
|
+
|
47
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
48
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
49
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
50
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
51
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
52
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
53
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/rrule_parser.rb'
|
6
|
+
|
7
|
+
Hoe.new('RruleParser', RruleParser::VERSION) do |p|
|
8
|
+
# p.rubyforge_name = 'RruleParserx' # if different than lowercase project name
|
9
|
+
# p.developer('FIX', 'FIX@example.com')
|
10
|
+
end
|
11
|
+
|
12
|
+
# vim: syntax=Ruby
|
data/bin/rrule_parser
ADDED
File without changes
|
data/lib/rrule_parser.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'runt'
|
2
|
+
require 'icalendar'
|
3
|
+
|
4
|
+
class RruleParser
|
5
|
+
VERSION = '1.0.0'
|
6
|
+
|
7
|
+
DAYS = {
|
8
|
+
"SU" => Runt::Sunday,
|
9
|
+
"MO" => Runt::Monday,
|
10
|
+
"TU" => Runt::Tuesday,
|
11
|
+
"WE" => Runt::Wednesday,
|
12
|
+
"TH" => Runt::Thursday,
|
13
|
+
"FR" => Runt::Friday,
|
14
|
+
"SA" => Runt::Saturday,
|
15
|
+
"SU" => Runt::Sunday
|
16
|
+
}
|
17
|
+
|
18
|
+
ADVERB_MAP = {
|
19
|
+
"DAILY" => "DAY",
|
20
|
+
"WEEKLY" => "WEEK",
|
21
|
+
"MONTHLY" => "MONTH",
|
22
|
+
"YEARLY" => "YEAR"
|
23
|
+
}
|
24
|
+
|
25
|
+
attr_accessor :event
|
26
|
+
attr_accessor :rules
|
27
|
+
|
28
|
+
def initialize(event)
|
29
|
+
@expressions = []
|
30
|
+
self.rules = {}
|
31
|
+
self.event = event
|
32
|
+
self.parse_rules(event)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Parse rules, output temporal expressions
|
36
|
+
def expressions
|
37
|
+
@expressions = []
|
38
|
+
@expressions << parse_frequency_and_interval
|
39
|
+
@expressions << parse_byday
|
40
|
+
@expressions.compact!
|
41
|
+
@expressions
|
42
|
+
end
|
43
|
+
|
44
|
+
def expression
|
45
|
+
self.expressions.inject {|m, v| v & m}
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def parse_rules(event)
|
51
|
+
rrules = event.recurrence_rules
|
52
|
+
|
53
|
+
rrules.each do |rule|
|
54
|
+
pairs = rule.split(";")
|
55
|
+
pairs.each do |pair|
|
56
|
+
array = pair.split('=')
|
57
|
+
self.rules[array[0].downcase.to_sym] = array[1]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Parse comma separated lists.
|
62
|
+
self.rules.each do |key, rule|
|
63
|
+
if rule =~ /,/
|
64
|
+
rules[key] = rule.split(',')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_frequency_and_interval
|
70
|
+
if self.rules[:freq]
|
71
|
+
frequency = self.rules[:freq]
|
72
|
+
interval = self.rules[:interval] ? self.rules[:interval].to_i : 1
|
73
|
+
Runt::EveryTE.new(self.event.start, interval, Runt::DPrecision.const_get(ADVERB_MAP[frequency]))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def parse_byday
|
78
|
+
if self.rules[:byday]
|
79
|
+
self.rules[:byday].map{ |day| Runt::DIWeek.new(RruleParser::DAYS[day]) }.inject do |m, expr|
|
80
|
+
m | expr
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'lib/rrule_parser'
|
2
|
+
require 'icalendar'
|
3
|
+
|
4
|
+
module RruleParserSpecHelper
|
5
|
+
def create_default_event
|
6
|
+
@interval = 2
|
7
|
+
@frequency = "WEEKLY"
|
8
|
+
@byday = "MO,WE,FR"
|
9
|
+
@event = Icalendar::Event.new
|
10
|
+
@event.start = Time.now
|
11
|
+
@event.end = Time.now + 3600
|
12
|
+
@event.recurrence_rules = ["FREQ=#{@frequency};INTERVAL=#{@interval};BYDAY=#{@byday};WKST=SU"]
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_parser(event)
|
16
|
+
@parser = RruleParser.new(event)
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_default_parser
|
20
|
+
create_default_event
|
21
|
+
create_parser(@event)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe RruleParser do
|
26
|
+
include RruleParserSpecHelper
|
27
|
+
|
28
|
+
describe "#new" do
|
29
|
+
context "when passed a valid event object" do
|
30
|
+
before(:each) do
|
31
|
+
create_default_event
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should create a new RruleParser object" do
|
35
|
+
rrp = RruleParser.new(@event)
|
36
|
+
rrp.should be_an_instance_of(RruleParser)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#rules" do
|
42
|
+
context "with a valid event object" do
|
43
|
+
before(:each) do
|
44
|
+
create_default_parser
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should be a hash" do
|
48
|
+
@parser.rules.should be_an_instance_of(Hash)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should have keys corresponding to rules" do
|
52
|
+
%w(FREQ INTERVAL BYDAY WKST).map {|m| m.downcase}.map {|m| m.to_sym}.each do |key|
|
53
|
+
@parser.rules.keys.should include(key)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should split rules containing commas into arrays" do
|
58
|
+
@parser.rules[:byday].should be_an_instance_of(Array)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "#expressions" do
|
64
|
+
before(:each) do
|
65
|
+
create_default_parser
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return an array" do
|
69
|
+
@parser.expressions.should be_an_instance_of(Array)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#parse_frequency_and_interval" do
|
74
|
+
before(:each) do
|
75
|
+
create_default_parser
|
76
|
+
@result = @parser.send(:parse_frequency_and_interval)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "return a valid temporal expression" do
|
80
|
+
@result.should be_an_instance_of(Runt::EveryTE)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should have the correct interval" do
|
84
|
+
@result.instance_variable_get("@interval").should == @interval
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should have the correct frequency" do
|
88
|
+
@result.instance_variable_get("@precision").should == Runt::DPrecision.const_get(RruleParser::ADVERB_MAP[@frequency])
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: texel-recurrence-rule-parser
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Leigh Caplan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-10 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: runt
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.6.0
|
23
|
+
version:
|
24
|
+
- !ruby/object:Gem::Dependency
|
25
|
+
name: icalendar
|
26
|
+
version_requirement:
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
requirements:
|
29
|
+
- - ">"
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 1.0.2
|
32
|
+
version:
|
33
|
+
description: Recurrence Rule Parser helps generate Temporal Expressions from iCalendar events.
|
34
|
+
email: texel1@gmail.com
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files:
|
40
|
+
- History.txt
|
41
|
+
- Manifest.txt
|
42
|
+
- README.txt
|
43
|
+
files:
|
44
|
+
- History.txt
|
45
|
+
- Manifest.txt
|
46
|
+
- README.txt
|
47
|
+
- Rakefile
|
48
|
+
- bin/rrule_parser
|
49
|
+
- lib/rrule_parser.rb
|
50
|
+
has_rdoc: true
|
51
|
+
homepage: http://github.com/texel/recurrence-rule-parser
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options:
|
54
|
+
- --main
|
55
|
+
- README.txt
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: "0"
|
69
|
+
version:
|
70
|
+
requirements: []
|
71
|
+
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.2.0
|
74
|
+
signing_key:
|
75
|
+
specification_version: 2
|
76
|
+
summary: iCalendar to Temporal Expression parser
|
77
|
+
test_files:
|
78
|
+
- spec/lib/rrule_parser_spec.rb
|