recurrence 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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