recurrence 0.1.1 → 0.1.2

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.
@@ -1,55 +1,54 @@
1
1
  == 0.0.1 2008-09-21
2
2
 
3
- * 1 major enhancement:
4
- * Initial release
3
+ * Initial release
5
4
 
6
5
  == 0.0.2 2008-09-21
7
6
 
8
- * 1 minor enhancement:
9
- * Added `items` and `items!` methods; returns an array with all events
7
+ * Added `items` and `items!` methods; returns an array with all events
10
8
 
11
9
  == 0.0.3 2008-09-22
12
10
 
13
- * 1 major enhancement:
14
- * The recurrence now considers the starting date and its configurations
15
- * Added lots of specs
11
+ * The recurrence now considers the starting date and its configurations
12
+ * Added lots of specs
16
13
 
17
14
  == 0.0.4 2008-09-30
18
15
 
19
- * 1 major enhancement:
20
- * Renamed items method to events
21
- * Added each! method
22
- * Added lots of specs
16
+ * Renamed items method to events
17
+ * Added each! method
18
+ * Added lots of specs
23
19
 
24
20
  == 0.0.5 2008-09-30
25
21
 
26
- * 1 major enhancement:
27
- * Monthly interval now accepts symbols: monthly, bimonthly, quarterly,
28
- semesterly
22
+ * Monthly interval now accepts symbols: monthly, bimonthly, quarterly, semesterly
29
23
 
30
24
  == 0.0.6 2009-01-06
31
25
 
32
- * 1 major enhancement:
33
- * Code refactoring
34
- * Added next and next! methods
35
- * Added more specs
36
- * Yearly interval now accepts symbols: jan-dec and january-december
26
+ * Code refactoring
27
+ * Added next and next! methods
28
+ * Added more specs
29
+ * Yearly interval now accepts symbols: jan-dec and january-december
37
30
 
38
31
  == 0.0.7 2009-01-06
39
32
 
40
- * 1 major enhancement:
41
- * The events method now accepts :starts and :until dates
33
+ * The events method now accepts :starts and :until dates
42
34
 
43
35
  == 0.0.8 2009-01-07
44
36
 
45
- * 1 small enhancement:
46
- * The iteration is stopped when the :until is reached when limiting events
37
+ * The iteration is stopped when the :until is reached when limiting events
47
38
 
48
39
  == 0.1.0 2009-07-18
49
40
 
50
- * 3 major enhancements:
51
- * Allow monthly recurrences to occur by weekday:
52
- Recurrence.new(:every => :month, :on => :first, :weekday => :thursday)
53
- * Allow several weekdays to be given to weekly recurrence:
54
- Recurrence.new(:every => :week, :on => [:monday, :wednesday, :friday])
55
- * Added :daily, :weekly, :monthly and :yearly shortcuts to Recurrence.
41
+ * Allow monthly recurrences to occur by weekday:
42
+ Recurrence.new(:every => :month, :on => :first, :weekday => :thursday)
43
+ * Allow several weekdays to be given to weekly recurrence:
44
+ Recurrence.new(:every => :week, :on => [:monday, :wednesday, :friday])
45
+ * Added :daily, :weekly, :monthly and :yearly shortcuts to Recurrence.
46
+
47
+ == 0.1.1 2009-12-18
48
+
49
+ * Removed ActiveSupport deprecation; should require active_support instead.
50
+
51
+ == 0.1.2 2010-09-09
52
+
53
+ * Refactor, refactor, refactor.
54
+ * Using Recurrence as Rails plugin is now deprecated; install it as a gem instead.
@@ -12,45 +12,34 @@ A simple library to handle recurring events.
12
12
  INSTALLATION:
13
13
  -------------
14
14
 
15
- Recurrence can be installed as Rails plugin or gem. To install it as gem, just
16
- run the command
15
+ Recurrence can be installed by running
17
16
 
18
- sudo gem install fnando-recurrence --source=http://gems.github.com
19
-
20
- Sometimes Github just won't build the gem. You can then do the following
21
-
22
- git clone git://github.com/fnando/recurrence.git
23
- cd recurrence
24
- rake gem:install
25
-
26
- If you prefer it as a plugin, just run the command
27
-
28
- script/plugin install git://github.com/fnando/recurrence.git
17
+ gem install recurrence
29
18
 
30
19
  USAGE:
31
20
  ------
32
-
21
+
33
22
  require 'rubygems'
34
23
  require 'recurrence'
35
-
24
+
36
25
  # Daily
37
26
  r = Recurrence.new(:every => :day)
38
27
  r = Recurrence.new(:every => :day, :interval => 9)
39
-
28
+
40
29
  # Weekly
41
30
  r = Recurrence.new(:every => :week, :on => 5)
42
31
  r = Recurrence.new(:every => :week, :on => :monday)
43
32
  r = Recurrence.new(:every => :week, :on => [:monday, :friday])
44
33
  r = Recurrence.new(:every => :week, :on => [:monday, :wednesday, :friday])
45
34
  r = Recurrence.new(:every => :week, :on => :friday, :interval => 2)
46
-
35
+
47
36
  # Monthly by month day
48
37
  r = Recurrence.new(:every => :month, :on => 15)
49
38
  r = Recurrence.new(:every => :month, :on => 31)
50
39
  r = Recurrence.new(:every => :month, :on => 7, :interval => 2)
51
40
  r = Recurrence.new(:every => :month, :on => 7, :interval => :monthly)
52
41
  r = Recurrence.new(:every => :month, :on => 7, :interval => :bimonthly)
53
-
42
+
54
43
  # Monthly by week day
55
44
  r = Recurrence.new(:every => :month, :on => :first, :weekday => :sunday)
56
45
  r = Recurrence.new(:every => :month, :on => :third, :weekday => :monday)
@@ -58,47 +47,47 @@ USAGE:
58
47
  r = Recurrence.new(:every => :month, :on => :last, :weekday => :friday, :interval => 2)
59
48
  r = Recurrence.new(:every => :month, :on => :last, :weekday => :friday, :interval => :quarterly)
60
49
  r = Recurrence.new(:every => :month, :on => :last, :weekday => :friday, :interval => :semesterly)
61
-
50
+
62
51
  # Yearly
63
52
  r = Recurrence.new(:every => :year, :on => [7, 4]) # => [month, day]
64
53
  r = Recurrence.new(:every => :year, :on => [10, 31], :interval => 3)
65
54
  r = Recurrence.new(:every => :year, :on => [:jan, 31])
66
55
  r = Recurrence.new(:every => :year, :on => [:january, 31])
67
-
56
+
68
57
  # Limit recurrence
69
58
  # :starts defaults to Date.today
70
59
  # :until defaults to 2037-12-31
71
60
  r = Recurrence.new(:every => :day, :starts => Date.today)
72
61
  r = Recurrence.new(:every => :day, :until => '2010-01-31')
73
62
  r = Recurrence.new(:every => :day, :starts => Date.today, :until => '2010-01-31')
74
-
63
+
75
64
  # Getting an array with all events
76
65
  r.events.each {|date| puts date.to_s } # => Memoized array
77
66
  r.events!.each {|date| puts date.to_s } # => reset items cache and re-execute it
78
67
  r.events(:starts => '2009-01-01').each {|date| puts date.to_s }
79
68
  r.events(:until => '2009-01-10').each {|date| puts date.to_s }
80
69
  r.events(:starts => '2009-01-05', :until => '2009-01-10').each {|date| puts date.to_s }
81
-
70
+
82
71
  # Iterating events
83
72
  r.each { |date| puts date.to_s } # => Use items method
84
73
  r.each! { |date| puts date.to_s } # => Use items! method
85
-
74
+
86
75
  # Check if a date is included
87
76
  r.include?(Date.today) # => true or false
88
77
  r.include?('2008-09-21')
89
-
78
+
90
79
  # Get next available date
91
80
  r.next # => Keep the original date object
92
81
  r.next! # => Change the internal date object to the next available date
93
82
 
94
83
  MAINTAINER
95
84
  ----------
96
-
85
+
97
86
  * Nando Vieira (<http://simplesideias.com.br/>)
98
87
 
99
88
  CONTRIBUTORS
100
89
  ------------
101
-
90
+
102
91
  * José Valim (<http://josevalim.blogspot.com/>)
103
92
 
104
93
  LICENSE:
data/Rakefile CHANGED
@@ -1,76 +1,26 @@
1
- require 'rake'
2
-
3
- PKG_FILES = %w(init.rb Rakefile recurrence.gemspec History.txt License.txt README.markdown) +
4
- Dir["lib/**/*"]
5
-
6
- spec = Gem::Specification.new do |s|
7
- s.name = "recurrence"
8
- s.version = "0.1.1"
9
- s.summary = "A simple library to handle recurring events"
10
- s.authors = ["Nando Vieira"]
11
- s.email = ["fnando.vieira@gmail.com"]
12
- s.homepage = "http://github.com/fnando/recurrence"
13
- s.description = ""
14
- s.has_rdoc = false
15
- s.files = PKG_FILES
16
-
17
- s.add_dependency "activesupport", ">=2.1.1"
18
- end
19
-
20
- namespace :gem do
21
- # Thanks to the Merb project for this code.
22
- desc "Update Github Gemspec"
23
- task :update_gemspec do
24
- skip_fields = %w(new_platform original_platform specification_version loaded required_ruby_version rubygems_version platform)
25
-
26
- result = "# WARNING : RAKE AUTO-GENERATED FILE. DO NOT MANUALLY EDIT!\n"
27
- result << "# RUN : 'rake gem:update_gemspec'\n\n"
28
- result << "Gem::Specification.new do |s|\n"
29
-
30
- spec.instance_variables.each do |ivar|
31
- value = spec.instance_variable_get(ivar)
32
- name = ivar.split("@").last
33
- next if name == "date"
34
-
35
- next if skip_fields.include?(name) || value.nil? || value == "" || (value.respond_to?(:empty?) && value.empty?)
36
- if name == "dependencies"
37
- value.each do |d|
38
- dep, *ver = d.to_s.split(" ")
39
- result << " s.add_dependency #{dep.inspect}, #{ver.join(" ").inspect.gsub(/[()]/, "").gsub(", runtime", "")}\n"
40
- end
41
- else
42
- case value
43
- when Array
44
- value = name != "files" ? value.inspect : value.inspect.split(",").join(",\n")
45
- when FalseClass
46
- when TrueClass
47
- when Fixnum
48
- when String
49
- value = value.inspect
50
- else
51
- value = value.to_s.inspect
52
- end
53
- result << " s.#{name} = #{value}\n"
54
- end
55
- end
56
-
57
- result << "end"
58
- File.open(File.join(File.dirname(__FILE__), "#{spec.name}.gemspec"), "w"){|f| f << result}
59
- end
60
-
61
- desc "Build gem"
62
- task :build => [:update_gemspec] do
63
- system "rm *.gem"
64
- system "gem build #{spec.instance_variable_get('@name')}.gemspec"
1
+ require "rspec/core/rake_task"
2
+ require "lib/recurrence/version"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ begin
7
+ require "jeweler"
8
+
9
+ JEWEL = Jeweler::Tasks.new do |gem|
10
+ gem.name = "recurrence"
11
+ gem.version = Recurrence::Version::STRING
12
+ gem.summary = "A simple library to handle recurring events"
13
+ gem.description = ""
14
+ gem.authors = ["Nando Vieira"]
15
+ gem.email = "fnando.vieira@gmail.com"
16
+ gem.homepage = "http://github.com/fnando/recurrence"
17
+ gem.has_rdoc = false
18
+ gem.files = FileList["History.txt", "init.rb", "License.txt", "Rakefile", "README.markdown", "recurrence.gemspec", "{lib,spec}/**/*"]
19
+ gem.add_development_dependency "rspec", ">= 2.0.0"
20
+ gem.add_dependency "activesupport"
65
21
  end
66
22
 
67
- desc "Install gem"
68
- task :install => [:update_gemspec, :build] do
69
- system "sudo gem install #{spec.instance_variable_get('@name')}"
70
- end
71
- end
72
-
73
- desc "Execute specs"
74
- task :spec do
75
- system "spec spec/recurrence_spec.rb -c -f s"
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError => e
25
+ puts "You don't have Jeweler installed, so you won't be able to build gems."
76
26
  end
data/init.rb CHANGED
@@ -1 +1,2 @@
1
- require "recurrence"
1
+ require "recurrence"
2
+ warn "Using Recurrence as a Rails plugin is deprecated and won't be supported in future versions."
@@ -1,17 +1,141 @@
1
- require 'rubygems'
2
- require 'date'
3
- require 'active_support'
4
-
5
- dirname = File.dirname(__FILE__)
6
- require dirname + '/recurrence/base'
7
- require dirname + '/recurrence/shortcuts'
8
- require dirname + '/recurrence/event'
9
- require dirname + '/recurrence/event/daily'
10
- require dirname + '/recurrence/event/weekly'
11
- require dirname + '/recurrence/event/monthly'
12
- require dirname + '/recurrence/event/yearly'
1
+ require "date"
2
+ require "active_support/all"
13
3
 
14
4
  class Recurrence
15
- include Base
16
- extend Shortcuts
5
+ autoload :Event, "recurrence/event"
6
+
7
+ FREQUENCY = %w(day week month year)
8
+
9
+ attr_reader :event
10
+
11
+ def self.default_until_date
12
+ @default_until_date ||= Date.new(2037, 12, 31)
13
+ end
14
+
15
+ def self.default_until_date=(date)
16
+ @default_until_date = if date.is_a?(String)
17
+ Date.parse(date)
18
+ else
19
+ date
20
+ end
21
+ end
22
+
23
+ def self.daily(options = {})
24
+ options[:every] = :day
25
+ new(options)
26
+ end
27
+
28
+ def self.weekly(options = {})
29
+ options[:every] = :week
30
+ new(options)
31
+ end
32
+
33
+ def self.monthly(options = {})
34
+ options[:every] = :month
35
+ new(options)
36
+ end
37
+
38
+ def self.yearly(options = {})
39
+ options[:every] = :year
40
+ new(options)
41
+ end
42
+
43
+ def initialize(options)
44
+ raise ArgumentError, ":every option is required" unless options.key?(:every)
45
+ raise ArgumentError, "invalid :every option" unless FREQUENCY.include?(options[:every].to_s)
46
+
47
+ @options = initialize_dates(options)
48
+ @options[:interval] ||= 1
49
+
50
+ @event = case @options[:every].to_sym
51
+ when :day
52
+ Recurrence::Event::Daily.new(@options)
53
+ when :week
54
+ Recurrence::Event::Weekly.new(@options)
55
+ when :month
56
+ Recurrence::Event::Monthly.new(@options)
57
+ when :year
58
+ Recurrence::Event::Yearly.new(@options)
59
+ end
60
+ end
61
+
62
+ def reset!
63
+ @event.reset!
64
+ @events = nil
65
+ end
66
+
67
+ def include?(required_date)
68
+ required_date = Date.parse(required_date) if required_date.is_a?(String)
69
+
70
+ if required_date < @options[:starts] || required_date > @options[:until]
71
+ false
72
+ else
73
+ each do |date|
74
+ return true if date == required_date
75
+ end
76
+ end
77
+
78
+ return false
79
+ end
80
+
81
+ def next
82
+ @event.next
83
+ end
84
+
85
+ def next!
86
+ @event.next!
87
+ end
88
+
89
+ def events(options={})
90
+ options[:starts] = Date.parse(options[:starts]) if options[:starts].is_a?(String)
91
+ options[:until] = Date.parse(options[:until]) if options[:until].is_a?(String)
92
+
93
+ reset! if options[:starts] || options[:until]
94
+
95
+ @events ||= begin
96
+ _events = []
97
+
98
+ loop do
99
+ date = @event.next!
100
+
101
+ break if date.nil?
102
+
103
+ valid_start = options[:starts].nil? || date >= options[:starts]
104
+ valid_until = options[:until].nil? || date <= options[:until]
105
+ _events << date if valid_start && valid_until
106
+
107
+ break if options[:until] && options[:until] <= date
108
+ end
109
+
110
+ _events
111
+ end
112
+ end
113
+
114
+ def events!(options={})
115
+ reset!
116
+ events(options)
117
+ end
118
+
119
+ def each!(&block)
120
+ reset!
121
+ each(&block)
122
+ end
123
+
124
+ def each(&block)
125
+ events.each do |item|
126
+ yield item
127
+ end
128
+ end
129
+
130
+ private
131
+ def initialize_dates(options) #:nodoc:
132
+ [:starts, :until].each do |name|
133
+ options[name] = Date.parse(options[name]) if options[name].is_a?(String)
134
+ end
135
+
136
+ options[:starts] ||= Date.today
137
+ options[:until] ||= self.class.default_until_date
138
+
139
+ options
140
+ end
17
141
  end