time_zone_scheduler 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2fb3de5fe652050bd39dd7d0c9f701d03192bcaa
4
- data.tar.gz: 82b688ff61898698f7c02fc003884df2233e8680
3
+ metadata.gz: 8893fdc4ca33c5f42c0491fbe22a5b1f7622b761
4
+ data.tar.gz: 622570aac4c0b1bd5a2bcd893d94cfb0a7b2ee4c
5
5
  SHA512:
6
- metadata.gz: b2b4553f90d2ad11373a4ae9aaee1edc9f4c8bea5f922bcf92346a6fb1b8e19d0e9332b12ac4929677c786fae4d2457d974d2f11292d49c252561c63a8a47dd4
7
- data.tar.gz: 3a3cd0847f7561c700f86f1a1286f1fc877bfbe17740d2ee0b424acdbd4301261696f1e3455d717945fd8f8facdcf63e899a8319059d1ed94d3d3e9b94596762
6
+ metadata.gz: 55b0629af3ff87ed95329d7baabcc25d6eb349c0d4e359596287cee288cba5cec6efdcc69f04569f5a09dab3a24e6a1ee0e5467b1fc92ec29dc31ab573c76cfa
7
+ data.tar.gz: 5da1e804698e831fe6ed453c99a91eb09dae87c2b84f1521cdbd1c4413f59e013bbd6e0e19f47bfbd8080c90f248af29728cabd85c3a1010125b8082f0bfe4ee
data/README.md CHANGED
@@ -5,6 +5,9 @@
5
5
  A Ruby library that assists in scheduling events whilst taking time zones into account. E.g. when to best deliver
6
6
  notifications such as push notifications or emails.
7
7
 
8
+ It includes a ORM ‘view’ that is able to partition a collection by time zone and extends the partitions with the
9
+ TimeZoneScheduler API.
10
+
8
11
  NOTE: _It is not yet battle-tested. This will all follow over the next few weeks._
9
12
 
10
13
  ## Installation
@@ -25,7 +28,47 @@ Or install it yourself as:
25
28
 
26
29
  ## Usage
27
30
 
28
- See [the documentation](http://www.rubydoc.info/gems/time_zone_scheduler).
31
+ For full details, see [the documentation](http://www.rubydoc.info/gems/time_zone_scheduler).
32
+
33
+ Here’s an example that uses the ‘view’ ORM helper. This example uses Mongoid, but its usage is pretty much the same with
34
+ ActiveRecord.
35
+
36
+ ```ruby
37
+ require 'time_zone_scheduler/view'
38
+
39
+ class User
40
+ include Mongoid::Document
41
+
42
+ field :time_zone, type: String
43
+
44
+ extend TimeZoneScheduler::View
45
+ view_field_as_time_zone :time_zone
46
+ end
47
+
48
+ User.create(time_zone: 'Europe/Amsterdam') # => #<User ID=1>
49
+ User.create(time_zone: 'Europe/Paris') # => #<User ID=2>
50
+ User.create(time_zone: 'America/New_York') # => #<User ID=3>
51
+
52
+ time_zone_views = User.in_time_zones
53
+ p time_zone_views.map { |view| view.map(&:id) } # => [[1], [2], [3]]
54
+ p time_zone_views.map { |view| view.map(&:class) } # => [Mongoid::Criteria, Mongoid::Criteria, Mongoid::Criteria]
55
+ p time_zone_views.map { |view| view.time_zone } # => ['Europe/Amsterdam', 'Europe/Paris', 'America/New_York']
56
+ ```
57
+
58
+ Now consider, for instance, that you want to schedule the delivery of Apple Push Notifications, but do want to respect
59
+ the user and so, regardless of the user’s time zone, always deliver on Friday, January the 15th of 2016, at 10AM:
60
+
61
+ ```ruby
62
+ date_and_time = Time.parse('2016-01-15 10:00')
63
+
64
+ User.in_time_zones.each do |users|
65
+ # Calculate the system time that corresponds to the date and time in the user’s time zone.
66
+ run_at = users.schedule_on_date(date_and_time)
67
+ # Perform the delivery of the push notifications on the calculated time.
68
+ # (This example uses the DelayedJob API to delay delivery.)
69
+ PushNotification.delay(run_at: run_at).deliver(users)
70
+ end
71
+ ```
29
72
 
30
73
  ## Contributing
31
74
 
@@ -1,3 +1,3 @@
1
1
  class TimeZoneScheduler
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,95 @@
1
+ require 'time_zone_scheduler'
2
+ require 'forwardable'
3
+
4
+ class TimeZoneScheduler
5
+ module View
6
+ # Defines a singleton method called `in_time_zones` which returns a list of
7
+ # views on the model partitioned by the time zones available in the specified
8
+ # time zone model field.
9
+ #
10
+ # It is able to extend ActiveRecord and Mongoid models.
11
+ #
12
+ # @see View#in_time_zones
13
+ #
14
+ # @param [Symbol] time_zone_field
15
+ # the model field that holds the time zone names.
16
+ #
17
+ # @param [String] default_time_zone
18
+ # the time zone to use if the value of the field can be `nil`.
19
+ #
20
+ # @return [void]
21
+ #
22
+ def view_field_as_time_zone(time_zone_field, default_time_zone = nil)
23
+ time_zone_scopes = lambda do |scope, time_zones|
24
+ time_zones.map do |time_zone|
25
+ scope.where(time_zone_field => time_zone).tap do |scope|
26
+ scope.extend Mixin
27
+ scope.time_zone_scheduler = TimeZoneScheduler.new(time_zone || default_time_zone)
28
+ end
29
+ end
30
+ end
31
+
32
+ if respond_to?(:scope)
33
+ # ActiveRecord
34
+ define_singleton_method :in_time_zones do
35
+ time_zone_scopes.call(scope, scope.select(time_zone_field).distinct)
36
+ end
37
+ elsif respond_to?(:scoped)
38
+ # Mongoid
39
+ define_singleton_method :in_time_zones do
40
+ time_zone_scopes.call(scoped, scoped.distinct(time_zone_field))
41
+ end
42
+ else
43
+ raise 'Unknown ORM.'
44
+ end
45
+ end
46
+
47
+ # Defines a singleton method called `in_time_zones` which returns a list of
48
+ # views on the model partitioned by the time zones available in the specified
49
+ # time zone model field.
50
+ #
51
+ # Returns views that are regular `Mongoid::Criteria` or `ActiveRecord::Relation` instances created from the current
52
+ # scope (and narrowed down by time zone), but are extended with the `TimeZoneScheduler` API.
53
+ #
54
+ # @see https://github.com/alloy/time_zone_scheduler
55
+ # @see http://www.rubydoc.info/gems/time_zone_scheduler/TimeZoneScheduler
56
+ #
57
+ # @example
58
+ #
59
+ # class User
60
+ # field :time_zone, type: String
61
+ #
62
+ # extend TimeZoneScheduler::View
63
+ # view_field_as_time_zone :time_zone
64
+ # end
65
+ #
66
+ # User.create(time_zone: 'Europe/Amsterdam')
67
+ # time_zone_view = User.in_time_zones.first
68
+ #
69
+ # p time_zone_view # => #<User where: { time_zone: 'Europe/Amsterdam' }>
70
+ # p time_zone_view.time_zone # => 'Europe/Amsterdam'
71
+ # p time_zone_view.time_zone_scheduler # => #<TimeZoneScheduler>
72
+ #
73
+ # # See TimeZoneScheduler for documentation on these available methods.
74
+ # time_zone_view.schedule_on_date(time)
75
+ # time_zone_view.schedule_in_timeframe(time, timeframe)
76
+ # time_zone_view.in_timeframe?(time, timeframe)
77
+ #
78
+ # @return [Array<Mongoid::Criteria, ActiveRecord::Relation, TimeZoneScheduler::View::Mixin>]
79
+ # a list of criteria partitioned by time zone and extended with the {Mixin} module.
80
+ #
81
+ def in_time_zones
82
+ raise 'Need to call view_field_as_time_zone first.'
83
+ end
84
+
85
+ module Mixin
86
+ extend Forwardable
87
+
88
+ attr_accessor :time_zone_scheduler
89
+ def_delegator :time_zone_scheduler, :destination_time_zone, :time_zone
90
+ def_delegator :time_zone_scheduler, :schedule_on_date
91
+ def_delegator :time_zone_scheduler, :schedule_in_timeframe
92
+ def_delegator :time_zone_scheduler, :in_timeframe?
93
+ end
94
+ end
95
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: time_zone_scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eloy Durán
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-14 00:00:00.000000000 Z
11
+ date: 2016-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -96,6 +96,7 @@ files:
96
96
  - Rakefile
97
97
  - lib/time_zone_scheduler.rb
98
98
  - lib/time_zone_scheduler/version.rb
99
+ - lib/time_zone_scheduler/view.rb
99
100
  - time_zone_scheduler.gemspec
100
101
  homepage: https://github.com/alloy/time_zone_scheduler
101
102
  licenses: