montrose 0.1.0
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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rubocop.yml +113 -0
- data/.travis.yml +5 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +13 -0
- data/Guardfile +34 -0
- data/LICENSE.txt +21 -0
- data/README.md +191 -0
- data/Rakefile +21 -0
- data/bin/_guard-core +16 -0
- data/bin/console +7 -0
- data/bin/guard +16 -0
- data/bin/m +16 -0
- data/bin/rake +16 -0
- data/bin/rubocop +16 -0
- data/bin/setup +7 -0
- data/lib/montrose.rb +20 -0
- data/lib/montrose/chainable.rb +210 -0
- data/lib/montrose/clock.rb +77 -0
- data/lib/montrose/errors.rb +5 -0
- data/lib/montrose/frequency.rb +63 -0
- data/lib/montrose/frequency/daily.rb +9 -0
- data/lib/montrose/frequency/hourly.rb +9 -0
- data/lib/montrose/frequency/minutely.rb +9 -0
- data/lib/montrose/frequency/monthly.rb +9 -0
- data/lib/montrose/frequency/weekly.rb +19 -0
- data/lib/montrose/frequency/yearly.rb +9 -0
- data/lib/montrose/options.rb +293 -0
- data/lib/montrose/recurrence.rb +67 -0
- data/lib/montrose/rule.rb +47 -0
- data/lib/montrose/rule/after.rb +27 -0
- data/lib/montrose/rule/before.rb +23 -0
- data/lib/montrose/rule/day_of_month.rb +31 -0
- data/lib/montrose/rule/day_of_week.rb +23 -0
- data/lib/montrose/rule/day_of_year.rb +37 -0
- data/lib/montrose/rule/hour_of_day.rb +23 -0
- data/lib/montrose/rule/month_of_year.rb +23 -0
- data/lib/montrose/rule/nth_day_matcher.rb +32 -0
- data/lib/montrose/rule/nth_day_of_month.rb +63 -0
- data/lib/montrose/rule/nth_day_of_year.rb +63 -0
- data/lib/montrose/rule/time_of_day.rb +33 -0
- data/lib/montrose/rule/total.rb +29 -0
- data/lib/montrose/rule/week_of_year.rb +23 -0
- data/lib/montrose/schedule.rb +42 -0
- data/lib/montrose/stack.rb +51 -0
- data/lib/montrose/utils.rb +32 -0
- data/lib/montrose/version.rb +3 -0
- data/montrose.gemspec +32 -0
- metadata +192 -0
@@ -0,0 +1,42 @@
|
|
1
|
+
module Montrose
|
2
|
+
class Schedule
|
3
|
+
attr_accessor :rules
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@rules = []
|
7
|
+
end
|
8
|
+
|
9
|
+
def <<(rule)
|
10
|
+
@rules << Montrose::Recurrence.new(rule)
|
11
|
+
|
12
|
+
self
|
13
|
+
end
|
14
|
+
alias add <<
|
15
|
+
|
16
|
+
def include?(time)
|
17
|
+
@rules.any? { |r| r.include?(time) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def events(opts = {})
|
21
|
+
enums = @rules.map { |r| r.merge(opts).events }
|
22
|
+
Enumerator.new do |y|
|
23
|
+
loop do
|
24
|
+
enums = active_enums(enums)
|
25
|
+
enum = enums.min_by(&:peek) or break
|
26
|
+
y << enum.next
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def active_enums(enums)
|
34
|
+
enums.each_with_object([]) do |enum, actives|
|
35
|
+
begin
|
36
|
+
actives << enum if enum.peek
|
37
|
+
rescue StopIteration
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "montrose/rule"
|
2
|
+
|
3
|
+
module Montrose
|
4
|
+
# Maintains stack of recurrences rules that apply to
|
5
|
+
# an associated recurrence; manages advancing state
|
6
|
+
# on each rule in stack as time instances are iterated.
|
7
|
+
#
|
8
|
+
class Stack
|
9
|
+
def self.build(opts = {})
|
10
|
+
[
|
11
|
+
Frequency,
|
12
|
+
Rule::After,
|
13
|
+
Rule::Before,
|
14
|
+
Rule::Total,
|
15
|
+
Rule::TimeOfDay,
|
16
|
+
Rule::HourOfDay,
|
17
|
+
Rule::NthDayOfMonth,
|
18
|
+
Rule::NthDayOfYear,
|
19
|
+
Rule::DayOfWeek,
|
20
|
+
Rule::DayOfMonth,
|
21
|
+
Rule::DayOfYear,
|
22
|
+
Rule::WeekOfYear,
|
23
|
+
Rule::MonthOfYear
|
24
|
+
].map { |r| r.from_options(opts) }.compact
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(opts = {})
|
28
|
+
@stack = self.class.build(opts)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Given a time instance, advances state of when all
|
32
|
+
# recurrence rules on the stack match, and yielding
|
33
|
+
# time to the block, otherwise, invokes break? on
|
34
|
+
# non-matching rules.
|
35
|
+
#
|
36
|
+
# @param [Time] time - time instance candidate for recurrence
|
37
|
+
#
|
38
|
+
def advance(time)
|
39
|
+
yes, no = @stack.partition { |rule| rule.include?(time) }
|
40
|
+
|
41
|
+
if no.empty?
|
42
|
+
yes.all? { |rule| rule.advance!(time) } or return false
|
43
|
+
puts time if ENV["DEBUG"]
|
44
|
+
yield time if block_given?
|
45
|
+
true
|
46
|
+
else
|
47
|
+
no.any?(&:continue?)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Montrose
|
2
|
+
module Utils
|
3
|
+
module_function
|
4
|
+
|
5
|
+
MONTHS = Date::MONTHNAMES
|
6
|
+
DAYS = Date::DAYNAMES
|
7
|
+
|
8
|
+
def month_number(name)
|
9
|
+
index = case name
|
10
|
+
when Symbol, String
|
11
|
+
MONTHS.index(name.to_s.titleize)
|
12
|
+
when 1..12
|
13
|
+
name
|
14
|
+
end
|
15
|
+
|
16
|
+
index or fail ConfigurationError, "Did not recognize month #{name}, must be one of #{MONTHS.inspect}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def day_number(name)
|
20
|
+
index = case name
|
21
|
+
when 0..6
|
22
|
+
name
|
23
|
+
when Symbol, String
|
24
|
+
DAYS.index(name.to_s.titleize)
|
25
|
+
when Array
|
26
|
+
day_number name.first
|
27
|
+
end
|
28
|
+
|
29
|
+
index or fail ConfigurationError, "Did not recognize day #{name}, must be one of #{DAYS.inspect}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/montrose.gemspec
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "montrose/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "montrose"
|
8
|
+
spec.version = Montrose::VERSION
|
9
|
+
spec.authors = ["Ross Kaffenberger"]
|
10
|
+
spec.email = ["rosskaff@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "Recurring events in Ruby"
|
13
|
+
spec.description = "A library for specifying, quering, and enumerating recurring events for calendars in Ruby."
|
14
|
+
spec.homepage = "https://github.com/rossta/montrose"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "exe"
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.required_ruby_version = ">= 2.1.0"
|
23
|
+
|
24
|
+
spec.add_dependency "activesupport"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
27
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
28
|
+
spec.add_development_dependency "minitest", "~> 5.8"
|
29
|
+
spec.add_development_dependency "m", "~> 1.4"
|
30
|
+
spec.add_development_dependency "rubocop", "~> 0.36"
|
31
|
+
spec.add_development_dependency "timecop"
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: montrose
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ross Kaffenberger
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.10'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.10'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.8'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.8'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: m
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0.36'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0.36'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: timecop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: A library for specifying, quering, and enumerating recurring events for
|
112
|
+
calendars in Ruby.
|
113
|
+
email:
|
114
|
+
- rosskaff@gmail.com
|
115
|
+
executables: []
|
116
|
+
extensions: []
|
117
|
+
extra_rdoc_files: []
|
118
|
+
files:
|
119
|
+
- ".gitignore"
|
120
|
+
- ".rubocop.yml"
|
121
|
+
- ".travis.yml"
|
122
|
+
- CODE_OF_CONDUCT.md
|
123
|
+
- Gemfile
|
124
|
+
- Guardfile
|
125
|
+
- LICENSE.txt
|
126
|
+
- README.md
|
127
|
+
- Rakefile
|
128
|
+
- bin/_guard-core
|
129
|
+
- bin/console
|
130
|
+
- bin/guard
|
131
|
+
- bin/m
|
132
|
+
- bin/rake
|
133
|
+
- bin/rubocop
|
134
|
+
- bin/setup
|
135
|
+
- lib/montrose.rb
|
136
|
+
- lib/montrose/chainable.rb
|
137
|
+
- lib/montrose/clock.rb
|
138
|
+
- lib/montrose/errors.rb
|
139
|
+
- lib/montrose/frequency.rb
|
140
|
+
- lib/montrose/frequency/daily.rb
|
141
|
+
- lib/montrose/frequency/hourly.rb
|
142
|
+
- lib/montrose/frequency/minutely.rb
|
143
|
+
- lib/montrose/frequency/monthly.rb
|
144
|
+
- lib/montrose/frequency/weekly.rb
|
145
|
+
- lib/montrose/frequency/yearly.rb
|
146
|
+
- lib/montrose/options.rb
|
147
|
+
- lib/montrose/recurrence.rb
|
148
|
+
- lib/montrose/rule.rb
|
149
|
+
- lib/montrose/rule/after.rb
|
150
|
+
- lib/montrose/rule/before.rb
|
151
|
+
- lib/montrose/rule/day_of_month.rb
|
152
|
+
- lib/montrose/rule/day_of_week.rb
|
153
|
+
- lib/montrose/rule/day_of_year.rb
|
154
|
+
- lib/montrose/rule/hour_of_day.rb
|
155
|
+
- lib/montrose/rule/month_of_year.rb
|
156
|
+
- lib/montrose/rule/nth_day_matcher.rb
|
157
|
+
- lib/montrose/rule/nth_day_of_month.rb
|
158
|
+
- lib/montrose/rule/nth_day_of_year.rb
|
159
|
+
- lib/montrose/rule/time_of_day.rb
|
160
|
+
- lib/montrose/rule/total.rb
|
161
|
+
- lib/montrose/rule/week_of_year.rb
|
162
|
+
- lib/montrose/schedule.rb
|
163
|
+
- lib/montrose/stack.rb
|
164
|
+
- lib/montrose/utils.rb
|
165
|
+
- lib/montrose/version.rb
|
166
|
+
- montrose.gemspec
|
167
|
+
homepage: https://github.com/rossta/montrose
|
168
|
+
licenses:
|
169
|
+
- MIT
|
170
|
+
metadata: {}
|
171
|
+
post_install_message:
|
172
|
+
rdoc_options: []
|
173
|
+
require_paths:
|
174
|
+
- lib
|
175
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: 2.1.0
|
180
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
|
+
requirements:
|
182
|
+
- - ">="
|
183
|
+
- !ruby/object:Gem::Version
|
184
|
+
version: '0'
|
185
|
+
requirements: []
|
186
|
+
rubyforge_project:
|
187
|
+
rubygems_version: 2.4.5.1
|
188
|
+
signing_key:
|
189
|
+
specification_version: 4
|
190
|
+
summary: Recurring events in Ruby
|
191
|
+
test_files: []
|
192
|
+
has_rdoc:
|