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 +4 -4
- data/README.md +44 -1
- data/lib/time_zone_scheduler/version.rb +1 -1
- data/lib/time_zone_scheduler/view.rb +95 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8893fdc4ca33c5f42c0491fbe22a5b1f7622b761
|
4
|
+
data.tar.gz: 622570aac4c0b1bd5a2bcd893d94cfb0a7b2ee4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
|
@@ -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.
|
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-
|
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:
|