time_zone_scheduler 0.1.1 → 0.2.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 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: