volt 0.9.6 → 0.9.7.pre2
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 +4 -4
- data/.gitignore +2 -1
- data/CHANGELOG.md +26 -0
- data/Gemfile +6 -1
- data/README.md +2 -0
- data/Rakefile +1 -0
- data/app/volt/models/active_volt_instance.rb +8 -6
- data/app/volt/models/user.rb +11 -2
- data/app/volt/models/volt_app_property.rb +8 -0
- data/app/volt/tasks/query_tasks.rb +23 -31
- data/app/volt/tasks/store_tasks.rb +2 -2
- data/app/volt/tasks/volt_admin_tasks.rb +24 -0
- data/docs/UPGRADE_GUIDE.md +6 -0
- data/lib/volt.rb +19 -12
- data/lib/volt/boot.rb +1 -0
- data/lib/volt/cli.rb +19 -8
- data/lib/volt/cli/console.rb +0 -1
- data/lib/volt/cli/generators.rb +14 -3
- data/lib/volt/cli/migrate.rb +26 -0
- data/lib/volt/config.rb +17 -4
- data/lib/volt/controllers/http_controller.rb +12 -0
- data/lib/volt/data_stores/base_adaptor_client.rb +2 -2
- data/lib/volt/data_stores/base_adaptor_server.rb +2 -0
- data/lib/volt/data_stores/data_store.rb +20 -14
- data/lib/volt/extra_core/class.rb +28 -14
- data/lib/volt/extra_core/hash.rb +5 -0
- data/lib/volt/extra_core/string.rb +3 -1
- data/lib/volt/helpers/time.rb +9 -43
- data/lib/volt/helpers/time/calculations.rb +204 -0
- data/lib/volt/helpers/time/distance.rb +63 -0
- data/lib/volt/helpers/time/duration.rb +71 -0
- data/lib/volt/helpers/time/local_calculations.rb +49 -0
- data/lib/volt/helpers/time/local_volt_time.rb +23 -0
- data/lib/volt/helpers/time/numeric.rb +59 -0
- data/lib/volt/helpers/time/volt_time.rb +170 -0
- data/lib/volt/models.rb +5 -0
- data/lib/volt/models/array_model.rb +33 -6
- data/lib/volt/models/associations.rb +146 -23
- data/lib/volt/models/buffer.rb +38 -41
- data/lib/volt/models/cursor.rb +15 -0
- data/lib/volt/models/errors.rb +11 -0
- data/lib/volt/models/field_helpers.rb +108 -68
- data/lib/volt/models/helpers/array_model.rb +4 -0
- data/lib/volt/models/helpers/base.rb +8 -1
- data/lib/volt/models/helpers/change_helpers.rb +31 -12
- data/lib/volt/models/helpers/defaults.rb +15 -0
- data/lib/volt/models/location.rb +20 -6
- data/lib/volt/models/migrations/migration.rb +23 -0
- data/lib/volt/models/migrations/migration_runner.rb +146 -0
- data/lib/volt/models/model.rb +38 -1
- data/lib/volt/models/permissions.rb +8 -1
- data/lib/volt/models/persistors/array_store.rb +87 -8
- data/lib/volt/models/persistors/base.rb +19 -0
- data/lib/volt/models/persistors/model_store.rb +1 -1
- data/lib/volt/models/persistors/page.rb +4 -1
- data/lib/volt/models/persistors/query/query_identifier.rb +102 -0
- data/lib/volt/models/persistors/query/query_listener.rb +57 -12
- data/lib/volt/models/root_models/root_models.rb +19 -0
- data/lib/volt/models/url.rb +11 -2
- data/lib/volt/models/validations/validations.rb +5 -2
- data/lib/volt/models/validators/type_validator.rb +11 -0
- data/lib/volt/models/validators/unique_validator.rb +2 -2
- data/lib/volt/page/bindings/attribute_binding.rb +23 -1
- data/lib/volt/page/targets/attribute_section.rb +7 -0
- data/lib/volt/page/targets/binding_document/component_node.rb +44 -18
- data/lib/volt/page/targets/binding_document/tag_node.rb +41 -0
- data/lib/volt/page/tasks.rb +16 -8
- data/lib/volt/queries/live_query.rb +109 -0
- data/lib/volt/queries/live_query_pool.rb +58 -0
- data/lib/volt/queries/live_subquery.rb +0 -0
- data/lib/volt/queries/query_association_splitter.rb +31 -0
- data/lib/volt/queries/query_diff.rb +100 -0
- data/lib/volt/queries/query_runner.rb +110 -0
- data/lib/volt/queries/query_subscription.rb +80 -0
- data/lib/volt/queries/query_subscription_pool.rb +37 -0
- data/lib/volt/reactive/eventable.rb +8 -0
- data/lib/volt/reactive/reactive_array.rb +0 -4
- data/lib/volt/router/routes.rb +81 -31
- data/lib/volt/server/message_bus/base_message_bus.rb +9 -3
- data/lib/volt/server/message_bus/peer_to_peer.rb +6 -6
- data/lib/volt/server/message_bus/peer_to_peer/server_tracker.rb +1 -1
- data/lib/volt/server/middleware/default_middleware_stack.rb +12 -8
- data/lib/volt/server/rack/component_paths.rb +31 -4
- data/lib/volt/server/rack/http_content_types.rb +62 -0
- data/lib/volt/server/rack/http_resource.rb +1 -1
- data/lib/volt/server/rack/index_files.rb +8 -1
- data/lib/volt/server/rack/opal_files.rb +16 -1
- data/lib/volt/server/rack/sprockets_helpers_setup.rb +32 -1
- data/lib/volt/server/socket_connection_handler.rb +16 -7
- data/lib/volt/server/template_handlers/sprockets_component_handler.rb +5 -3
- data/lib/volt/spec/capybara.rb +4 -3
- data/lib/volt/spec/setup.rb +5 -0
- data/lib/volt/tasks/dispatcher.rb +3 -1
- data/lib/volt/utils/data_transformer.rb +4 -4
- data/lib/volt/utils/ejson.rb +19 -6
- data/lib/volt/utils/promise_extensions.rb +1 -1
- data/lib/volt/utils/time_opal_patch.rb +749 -0
- data/lib/volt/utils/time_patch.rb +11 -4
- data/lib/volt/version.rb +1 -1
- data/lib/volt/volt/app.rb +19 -11
- data/lib/volt/volt/properties.rb +24 -0
- data/lib/volt/volt/server_setup/app.rb +30 -7
- data/lib/volt/volt/users.rb +15 -3
- data/spec/apps/kitchen_sink/Gemfile +5 -1
- data/spec/apps/kitchen_sink/app/main/config/routes.rb +1 -0
- data/spec/apps/kitchen_sink/app/main/controllers/save_controller.rb +1 -1
- data/spec/apps/kitchen_sink/app/main/controllers/server/simple_http_controller.rb +4 -0
- data/spec/apps/kitchen_sink/app/main/controllers/todos_controller.rb +4 -2
- data/spec/apps/kitchen_sink/app/main/models/post.rb +0 -1
- data/spec/apps/kitchen_sink/app/main/models/todo.rb +4 -0
- data/spec/apps/kitchen_sink/app/main/views/mailers/reset_password.html +10 -0
- data/spec/apps/kitchen_sink/app/main/views/todos/index.html +2 -0
- data/spec/apps/kitchen_sink/config/app.rb +2 -0
- data/spec/apps/migrations/config/db/migrations/1445111704_migration1.rb +7 -0
- data/spec/apps/migrations/config/db/migrations/1445113517_migration2.rb +7 -0
- data/spec/apps/migrations/config/db/migrations/1445115200_migration3.rb +7 -0
- data/spec/extra_core/class_spec.rb +10 -0
- data/spec/helpers/distance_spec.rb +35 -0
- data/spec/helpers/duration_spec.rb +160 -0
- data/spec/helpers/volt_time_spec.rb +275 -0
- data/spec/integration/callbacks_spec.rb +2 -1
- data/spec/integration/http_endpoints_spec.rb +4 -0
- data/spec/integration/save_spec.rb +1 -1
- data/spec/integration/todos_spec.rb +7 -5
- data/spec/models/array_model_spec.rb +17 -3
- data/spec/models/associations_spec.rb +48 -1
- data/spec/models/field_helpers_spec.rb +7 -3
- data/spec/models/migrations/migration_runner_spec.rb +69 -0
- data/spec/models/model_spec.rb +42 -8
- data/spec/models/permissions_spec.rb +20 -8
- data/spec/models/persistors/array_store_spec.rb +18 -0
- data/spec/models/persistors/page_spec.rb +15 -10
- data/spec/models/persistors/store_spec.rb +13 -3
- data/spec/models/url_spec.rb +4 -3
- data/spec/models/user_spec.rb +6 -3
- data/spec/models/user_validation_spec.rb +3 -3
- data/spec/models/validations_spec.rb +4 -0
- data/spec/models/validators/block_validations_spec.rb +9 -5
- data/spec/models/validators/email_validator_spec.rb +2 -0
- data/spec/models/validators/lifecycle_callbacks_spec.rb +86 -0
- data/spec/models/validators/unique_validator_spec.rb +1 -0
- data/spec/page/path_string_renderer_spec.rb +5 -0
- data/spec/queries/live_query_spec.rb +16 -0
- data/spec/queries/query_association_splitter_spec.rb +14 -0
- data/spec/queries/query_diff_spec.rb +132 -0
- data/spec/queries/query_identifier_spec.rb +98 -0
- data/spec/queries/query_runner_spec.rb +63 -0
- data/spec/queries/query_tracker_spec.rb +141 -0
- data/spec/router/routes_spec.rb +52 -21
- data/spec/server/middleware/rack_content_types_spec.rb +78 -0
- data/spec/server/rack/asset_files_spec.rb +38 -30
- data/spec/spec_helper.rb +8 -0
- data/spec/utils/ejson_spec.rb +9 -8
- data/spec/utils/ejson_volt_time_spec.rb +65 -0
- data/templates/migration/migration.rb.tt +9 -0
- data/templates/newgem/gitignore.tt +1 -0
- data/templates/project/Gemfile.tt +19 -2
- data/templates/project/README.md.tt +6 -1
- data/templates/project/app/main/config/dependencies.rb +6 -0
- data/templates/project/config/app.rb.tt +18 -4
- data/volt.gemspec +2 -2
- metadata +73 -16
- data/app/volt/tasks/live_query/live_query_pool.rb +0 -48
- data/app/volt/tasks/live_query/query_tracker.rb +0 -92
- data/spec/tasks/live_query_spec.rb +0 -18
- data/spec/tasks/query_tasks.rb +0 -7
- data/spec/tasks/query_tracker_spec.rb +0 -145
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module Volt
|
|
2
|
+
class Duration
|
|
3
|
+
UNIT_MAP = {
|
|
4
|
+
:years => 31536000,
|
|
5
|
+
:months => 2592000,
|
|
6
|
+
:weeks => 604800,
|
|
7
|
+
:days => 86400,
|
|
8
|
+
:hours => 3600,
|
|
9
|
+
:minutes => 60,
|
|
10
|
+
:seconds => 1
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
# Returns a string representation of the duration.
|
|
14
|
+
#
|
|
15
|
+
# @param How many places in time units to show.
|
|
16
|
+
# @param The minimum unit to show, anything below will be ignored. Results
|
|
17
|
+
# will be rounded up the the nearest min_unit.
|
|
18
|
+
def duration_in_words(places=2, min_unit=:minutes, recent_message='just now')
|
|
19
|
+
parts = []
|
|
20
|
+
secs = to_i
|
|
21
|
+
UNIT_MAP.each_pair do |unit, count|
|
|
22
|
+
val = (secs / count).floor
|
|
23
|
+
secs = secs % count
|
|
24
|
+
|
|
25
|
+
parts << [val, unit] if val > 0
|
|
26
|
+
break if unit == min_unit
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Trim number of units
|
|
30
|
+
parts = parts.take(places) if places
|
|
31
|
+
|
|
32
|
+
parts = parts.map do |val, unit|
|
|
33
|
+
pl_units = val == 1 ? unit.singularize : unit
|
|
34
|
+
"#{val} #{pl_units}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Round up to the nearest unit
|
|
38
|
+
if parts.size == 0
|
|
39
|
+
parts << recent_message
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
parts.to_sentence
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
class VoltTime
|
|
48
|
+
def time_distance_in_words(from_time=VoltTime.live_now(60), places=2, min_unit=:minutes, recent_message='just now')
|
|
49
|
+
dist = from_time - self
|
|
50
|
+
|
|
51
|
+
direction = dist >= 0 ? 'ago' : 'from now'
|
|
52
|
+
|
|
53
|
+
duration = dist.abs.seconds
|
|
54
|
+
|
|
55
|
+
dist_in_words = duration.duration_in_words(places, min_unit, recent_message)
|
|
56
|
+
|
|
57
|
+
unless dist_in_words == recent_message
|
|
58
|
+
dist_in_words += ' ' + direction
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
dist_in_words
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Much of this class was borrowed from ActiveSupport:
|
|
2
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/duration.rb
|
|
3
|
+
|
|
4
|
+
module Volt
|
|
5
|
+
class Duration
|
|
6
|
+
attr_accessor :value, :parts
|
|
7
|
+
|
|
8
|
+
def initialize(value, parts)
|
|
9
|
+
@value, @parts = value, parts
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Compares with the value on another Duration if Duration is passed
|
|
13
|
+
# or just compares value with the other object
|
|
14
|
+
def ==(other)
|
|
15
|
+
if other.is_a?(Volt::Duration)
|
|
16
|
+
other.value == value
|
|
17
|
+
else
|
|
18
|
+
other == value
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Adds durations or duration to a VoltTime or seconds to the duration
|
|
23
|
+
def +(other)
|
|
24
|
+
if other.is_a?(Volt::Duration)
|
|
25
|
+
Volt::Duration.new(value + other.value, parts + other.parts)
|
|
26
|
+
else
|
|
27
|
+
Volt::Duration.new(value + other, parts + [[:seconds, other]])
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Calculates a new Time which is the Duration in the future.
|
|
32
|
+
# The default is since the current time
|
|
33
|
+
def since(time = VoltTime.now)
|
|
34
|
+
sum(1, time)
|
|
35
|
+
end
|
|
36
|
+
alias :from_now :since
|
|
37
|
+
|
|
38
|
+
# Calculates a new Time which is the Duration in the past
|
|
39
|
+
# The default is since the current time
|
|
40
|
+
def ago(time = VoltTime.now)
|
|
41
|
+
sum(-1, time)
|
|
42
|
+
end
|
|
43
|
+
alias :until :ago
|
|
44
|
+
|
|
45
|
+
# Ensure that the Duration responds like the value to other methods
|
|
46
|
+
def respond_to_missing?(method, include_private=false)
|
|
47
|
+
@value.respond_to?(method, include_private)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def inspect
|
|
51
|
+
parts.
|
|
52
|
+
reduce(::Hash.new(0)) { |h,(l,r)| h[l] += r; h }.
|
|
53
|
+
sort_by {|unit, _ | [:years, :months, :days, :minutes, :seconds, :secs].index(unit)}.
|
|
54
|
+
map {|unit, val| "#{val} #{val == 1 ? unit.to_s.chop : unit.to_s}"}.
|
|
55
|
+
to_sentence
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def sum(sign, time = VoltTime.now)
|
|
59
|
+
parts.inject(time) do |t, (type, number)|
|
|
60
|
+
t.advance({type => number*sign})
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
# Ensures that the Duration responds like the value to other methods
|
|
66
|
+
def method_missing(method, *args, &block)
|
|
67
|
+
value.send(method, *args, &block)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Local calculations for use on the client only
|
|
2
|
+
|
|
3
|
+
class VoltTime
|
|
4
|
+
|
|
5
|
+
def change_local(options)
|
|
6
|
+
t = @time.getlocal
|
|
7
|
+
new_year = options.fetch(:year, t.year)
|
|
8
|
+
new_month = options.fetch(:month, t.month)
|
|
9
|
+
new_day = options.fetch(:day, t.day)
|
|
10
|
+
new_hour = options.fetch(:hour, t.hour)
|
|
11
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : t.min)
|
|
12
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : t.sec)
|
|
13
|
+
|
|
14
|
+
t = Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
|
15
|
+
VoltTime.from_time(t)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Returns a new VoltTime representing the beginning of the local day, 00:00:00
|
|
19
|
+
def local_beginning_of_day
|
|
20
|
+
change_local(hour: 0, min: 0, min: 0)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Returns a new VoltTime representing the end of the local day, 23:59:59.999
|
|
24
|
+
def local_end_of_day
|
|
25
|
+
t = @time.getlocal
|
|
26
|
+
t = Time.new(t.year, t.month, t.day, 23, 59, 59.999)
|
|
27
|
+
VoltTime.from_time(t)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns a new VoltTime representing the middle of the local day, 12:00:00
|
|
31
|
+
def local_middle_of_day
|
|
32
|
+
change_local(hour: 12)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Returns the number of seconds since 00:00:00 of the current local day
|
|
36
|
+
def local_seconds_since_midnight
|
|
37
|
+
to_f - change_local(hour: 0).to_f
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Returns the number of seconds until 23:59:59.999 of current local day
|
|
41
|
+
def local_seconds_until_end_of_day
|
|
42
|
+
local_end_of_day.to_f - to_f
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Returns a Range for the start to end of day
|
|
46
|
+
def local_all_day
|
|
47
|
+
local_beginning_of_day..local_end_of_day
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
class VoltTime
|
|
2
|
+
|
|
3
|
+
# Returns a string representation of the local time
|
|
4
|
+
def local_to_s
|
|
5
|
+
@time.getlocal.to_s
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Returns a canonical representation of the local time
|
|
9
|
+
def local_asctime
|
|
10
|
+
@time.getlocal.asctime
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Returns a canonical representation of the local time
|
|
14
|
+
def local_ctime
|
|
15
|
+
@time.getlocal.ctime
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Formats the local time according to the provided string
|
|
19
|
+
def local_strftime(string)
|
|
20
|
+
@time.getlocal.strftime(string)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Much of this class was borrowed from ActiveSupport:
|
|
2
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/numeric/time.rb
|
|
3
|
+
# and
|
|
4
|
+
# https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/integer/time.rb
|
|
5
|
+
|
|
6
|
+
require 'volt/helpers/time/duration'
|
|
7
|
+
|
|
8
|
+
class Numeric
|
|
9
|
+
|
|
10
|
+
# Returns a duration for the number of seconds provided.
|
|
11
|
+
def seconds
|
|
12
|
+
Volt::Duration.new(self, [[:secs, self]])
|
|
13
|
+
end
|
|
14
|
+
alias :second :seconds
|
|
15
|
+
|
|
16
|
+
# Returns a duration for the number of minutes provided.
|
|
17
|
+
def minutes
|
|
18
|
+
Volt::Duration.new(self * 60, [[:secs, self * 60]])
|
|
19
|
+
end
|
|
20
|
+
alias :minute :minutes
|
|
21
|
+
|
|
22
|
+
# Returns a duration for the number of hours provided.
|
|
23
|
+
def hours
|
|
24
|
+
Volt::Duration.new(self * 60 * 60, [[:secs, self * 60 * 60]])
|
|
25
|
+
end
|
|
26
|
+
alias :hour :hours
|
|
27
|
+
|
|
28
|
+
# Returns a duration for the number of days provided.
|
|
29
|
+
def days
|
|
30
|
+
Volt::Duration.new(self * 24.hours, [[:days, self]])
|
|
31
|
+
end
|
|
32
|
+
alias :day :days
|
|
33
|
+
|
|
34
|
+
# Returns a duration for the number of weeks provided.
|
|
35
|
+
def weeks
|
|
36
|
+
Volt::Duration.new(self * 7.days, [[:days, self * 7]])
|
|
37
|
+
end
|
|
38
|
+
alias :week :weeks
|
|
39
|
+
|
|
40
|
+
# Returns a duration for the number of fortnights provided.
|
|
41
|
+
def fortnights
|
|
42
|
+
Volt::Duration.new(self * 14.days, [[:days, self * 14]])
|
|
43
|
+
end
|
|
44
|
+
alias :fortnight :fortnights
|
|
45
|
+
|
|
46
|
+
# Returns a duration for the number of months provided.
|
|
47
|
+
# Ignores any fractional part of months
|
|
48
|
+
def months
|
|
49
|
+
Volt::Duration.new(self.to_i * 30.days, [[:months, self.to_i]])
|
|
50
|
+
end
|
|
51
|
+
alias :month :months
|
|
52
|
+
|
|
53
|
+
# Returns a duration for the number of years provided
|
|
54
|
+
# Ignores any fractional part of years
|
|
55
|
+
def years
|
|
56
|
+
Volt::Duration.new(self.to_i * 365.25.days, [[:years, self.to_i]])
|
|
57
|
+
end
|
|
58
|
+
alias :year :years
|
|
59
|
+
end
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Volt needs its own date/time class because of the differences between
|
|
2
|
+
# how Opal (i.e. JavaScript) and Ruby handle timezones. In JavaScript
|
|
3
|
+
# there are only two possible timezones, the local zone and UTC, while
|
|
4
|
+
# in Ruby any timezone can be set.
|
|
5
|
+
# VoltTime is always stored in UTC but can be converted to the local timezone.
|
|
6
|
+
# Because of Opal issue , VoltTime could not be Volt::Time.
|
|
7
|
+
# Because of Opal issue , VoltTime could not be a subclass of ::Time
|
|
8
|
+
|
|
9
|
+
class VoltTime
|
|
10
|
+
# Since VoltTime is required by the user, we don't add it to the FIELD_CASTS
|
|
11
|
+
# list until after it is included, since we don't have access to the class
|
|
12
|
+
# here.
|
|
13
|
+
if defined?(Volt::FieldHelpers)
|
|
14
|
+
Volt::FieldHelpers::FIELD_CASTS[VoltTime] = nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# A VoltTime can be initialized from either local or UTC timezone.
|
|
18
|
+
# If no parameters are provided then the current time is initialized.
|
|
19
|
+
# Zone must be specified (as :local or :utc) if any parts of the date are given
|
|
20
|
+
# to be clear whether VoltTime should assume that the parameters
|
|
21
|
+
# are for a local or utc time.
|
|
22
|
+
def initialize(zone = nil, year = nil, month = nil, day = nil, hour = nil, min = nil, sec = nil)
|
|
23
|
+
|
|
24
|
+
# Case when all params are nil - create time now
|
|
25
|
+
if !zone || !year
|
|
26
|
+
@time = ::Time.new.getutc
|
|
27
|
+
elsif zone == :utc
|
|
28
|
+
t = ::Time.new(year, month, day, hour, min, sec)
|
|
29
|
+
@time = (t + t.utc_offset).getutc
|
|
30
|
+
elsif zone == :local
|
|
31
|
+
@time = ::Time.new(year, month, day, hour, min, sec).getutc
|
|
32
|
+
else
|
|
33
|
+
raise ArgumentError, "Specify zone as :utc or :local"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class << self
|
|
38
|
+
|
|
39
|
+
# Returns a VoltTime from a ::Time
|
|
40
|
+
def from_time(time)
|
|
41
|
+
VoltTime.new.set_time(time)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the time now in the UTC timezone
|
|
45
|
+
def now
|
|
46
|
+
VoltTime.new
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Live now acts just like now, except it invalidates any computations the
|
|
50
|
+
# VoltTime object is used in at every interval. This makes it easy to
|
|
51
|
+
# display live timer's.
|
|
52
|
+
def live_now(interval=1000)
|
|
53
|
+
dep = Volt::Dependency.new
|
|
54
|
+
dep.depend
|
|
55
|
+
Volt::Timers.client_set_timeout(interval) do
|
|
56
|
+
dep.changed!
|
|
57
|
+
end
|
|
58
|
+
VoltTime.new
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Returns the time as seconds from the epoch Jan 1 1970
|
|
62
|
+
def at(secs, usecs = 0)
|
|
63
|
+
VoltTime.new.set_time(::Time.at(secs, usecs))
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Returns the name of the current local timezone
|
|
67
|
+
def current_zone
|
|
68
|
+
::Time.new.zone
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Return the local timezone offset from UTC in hours
|
|
72
|
+
# in seconds
|
|
73
|
+
def current_offset
|
|
74
|
+
::Time.new.utc_offset
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Sets Volt::Time from a ::Time object, converting to UTC if necessary
|
|
80
|
+
def set_time(time)
|
|
81
|
+
@time = time.getutc
|
|
82
|
+
return self
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def <=> (other)
|
|
86
|
+
if other.is_a?(::Time)
|
|
87
|
+
@time <=> other
|
|
88
|
+
else
|
|
89
|
+
@time <=> other.getutc
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def == (other)
|
|
94
|
+
if other.is_a?(::Time)
|
|
95
|
+
@time == other
|
|
96
|
+
else
|
|
97
|
+
@time == other.getutc
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def to_s
|
|
102
|
+
@time.to_s
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def inspect
|
|
106
|
+
@time.inspect
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def + (other)
|
|
110
|
+
if other.is_a?(Volt::Duration)
|
|
111
|
+
other.sum(1, self)
|
|
112
|
+
else
|
|
113
|
+
VoltTime.from_time(@time + other)
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def - (other)
|
|
118
|
+
if other.is_a?(VoltTime)
|
|
119
|
+
@time - other.getutc
|
|
120
|
+
elsif other.is_a?(::Time)
|
|
121
|
+
@time - other
|
|
122
|
+
elsif other.is_a?(Volt::Duration)
|
|
123
|
+
other.sum(-1, self)
|
|
124
|
+
else
|
|
125
|
+
VoltTime.from_time(@time - other)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Redefining getlocal without a timezone parameter
|
|
130
|
+
def getlocal
|
|
131
|
+
@time.getlocal
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Redefining localtime without a timezone parameter
|
|
135
|
+
def localtime
|
|
136
|
+
# Opal 0.9.0 has no localtime method so use getlocal instead
|
|
137
|
+
@time.getlocal
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Get the local offset from UTC
|
|
141
|
+
def local_offset
|
|
142
|
+
@time.getlocal.utc_offset
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def respond_to?(method_name, include_private = false)
|
|
146
|
+
@time.respond_to?(method_name, include_private)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
unless RUBY_PLATFORM == 'opal'
|
|
150
|
+
# Marshal support for drb and ForkingServer
|
|
151
|
+
def _dump(level)
|
|
152
|
+
@time.to_i.to_s
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def self._load(args)
|
|
156
|
+
at(args.to_i)
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
private
|
|
161
|
+
|
|
162
|
+
def method_missing(method, *args, &block)
|
|
163
|
+
@time.send(method, *args, &block)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
167
|
+
@time.respond_to?(method_name, include_private)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
end
|