actv 1.1.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.
- data/.gitignore +30 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +64 -0
- data/Gemfile +4 -0
- data/Guardfile +20 -0
- data/LICENSE +22 -0
- data/README.md +63 -0
- data/Rakefile +17 -0
- data/actv.gemspec +34 -0
- data/lib/actv.rb +48 -0
- data/lib/actv/address.rb +9 -0
- data/lib/actv/article.rb +89 -0
- data/lib/actv/article_search_results.rb +15 -0
- data/lib/actv/asset.rb +186 -0
- data/lib/actv/asset_channel.rb +13 -0
- data/lib/actv/asset_component.rb +8 -0
- data/lib/actv/asset_description.rb +15 -0
- data/lib/actv/asset_description_type.rb +12 -0
- data/lib/actv/asset_image.rb +13 -0
- data/lib/actv/asset_legacy_data.rb +20 -0
- data/lib/actv/asset_price.rb +11 -0
- data/lib/actv/asset_seo_url.rb +5 -0
- data/lib/actv/asset_status.rb +17 -0
- data/lib/actv/asset_tag.rb +9 -0
- data/lib/actv/asset_topic.rb +11 -0
- data/lib/actv/base.rb +148 -0
- data/lib/actv/channel.rb +13 -0
- data/lib/actv/client.rb +330 -0
- data/lib/actv/configurable.rb +39 -0
- data/lib/actv/default.rb +87 -0
- data/lib/actv/error.rb +32 -0
- data/lib/actv/error/bad_gateway.rb +11 -0
- data/lib/actv/error/bad_request.rb +10 -0
- data/lib/actv/error/client_error.rb +39 -0
- data/lib/actv/error/enhance_your_calm.rb +10 -0
- data/lib/actv/error/forbidden.rb +10 -0
- data/lib/actv/error/internal_server_error.rb +11 -0
- data/lib/actv/error/not_acceptable.rb +10 -0
- data/lib/actv/error/not_found.rb +10 -0
- data/lib/actv/error/server_error.rb +19 -0
- data/lib/actv/error/service_unavailable.rb +11 -0
- data/lib/actv/error/unauthorized.rb +10 -0
- data/lib/actv/event.rb +213 -0
- data/lib/actv/event_result.rb +8 -0
- data/lib/actv/event_search_results.rb +11 -0
- data/lib/actv/evergreen.rb +53 -0
- data/lib/actv/facet.rb +16 -0
- data/lib/actv/facet_term.rb +5 -0
- data/lib/actv/facet_value.rb +7 -0
- data/lib/actv/identity.rb +28 -0
- data/lib/actv/interest.rb +39 -0
- data/lib/actv/null_object.rb +19 -0
- data/lib/actv/phone_number.rb +9 -0
- data/lib/actv/place.rb +24 -0
- data/lib/actv/popular_interest.rb +18 -0
- data/lib/actv/popular_interest_search_results.rb +12 -0
- data/lib/actv/request/multipart_with_file.rb +37 -0
- data/lib/actv/response/parse_json.rb +29 -0
- data/lib/actv/response/raise_client_error.rb +21 -0
- data/lib/actv/response/raise_server_error.rb +18 -0
- data/lib/actv/search_results.rb +30 -0
- data/lib/actv/sub_event.rb +15 -0
- data/lib/actv/tag.rb +9 -0
- data/lib/actv/topic.rb +9 -0
- data/lib/actv/user.rb +38 -0
- data/lib/actv/version.rb +3 -0
- data/spec/actv/article_search_results_spec.rb +16 -0
- data/spec/actv/article_spec.rb +44 -0
- data/spec/actv/asset_channel_spec.rb +17 -0
- data/spec/actv/asset_description_spec.rb +17 -0
- data/spec/actv/asset_image_spec.rb +27 -0
- data/spec/actv/asset_price_spec.rb +23 -0
- data/spec/actv/asset_spec.rb +172 -0
- data/spec/actv/asset_status_spec.rb +24 -0
- data/spec/actv/base_spec.rb +51 -0
- data/spec/actv/client/articles_spec.rb +130 -0
- data/spec/actv/client/assets_spec.rb +87 -0
- data/spec/actv/client/event_results_spec.rb +35 -0
- data/spec/actv/client/events_spec.rb +99 -0
- data/spec/actv/client/search_spec.rb +58 -0
- data/spec/actv/client/system_health_spec.rb +16 -0
- data/spec/actv/client/users_spec.rb +31 -0
- data/spec/actv/client_spec.rb +140 -0
- data/spec/actv/event_spec.rb +331 -0
- data/spec/actv/evergreen_spec.rb +33 -0
- data/spec/actv/identifiable_spec.rb +31 -0
- data/spec/actv/null_object_spec.rb +24 -0
- data/spec/actv/place_spec.rb +25 -0
- data/spec/actv/search_results_spec.rb +44 -0
- data/spec/actv/user_spec.rb +25 -0
- data/spec/actv_spec.rb +60 -0
- data/spec/faraday/response_spec.rb +0 -0
- data/spec/fixtures/me.json +21 -0
- data/spec/fixtures/system_health.json +1 -0
- data/spec/fixtures/valid_article.json +187 -0
- data/spec/fixtures/valid_asset.json +185 -0
- data/spec/fixtures/valid_event.json +188 -0
- data/spec/fixtures/valid_event_results.json +23 -0
- data/spec/fixtures/valid_evergreen.json +1 -0
- data/spec/fixtures/valid_evergreen_child_1.json +1 -0
- data/spec/fixtures/valid_search.json +1282 -0
- data/spec/fixtures/valid_search_no_event_results.json +5 -0
- data/spec/fixtures/valid_search_no_results.json +9 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/helper.rb +43 -0
- metadata +432 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
module ACTV
|
|
2
|
+
module Configurable
|
|
3
|
+
|
|
4
|
+
# Convenience method to allow configuration options to be set in a block
|
|
5
|
+
def configure
|
|
6
|
+
yield self
|
|
7
|
+
self
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
CONFIG_KEYS = [
|
|
11
|
+
:connection_options,
|
|
12
|
+
:endpoint,
|
|
13
|
+
:media_endpoint,
|
|
14
|
+
:middleware,
|
|
15
|
+
:search_endpoint,
|
|
16
|
+
:api_key
|
|
17
|
+
] unless defined? CONFIG_KEYS
|
|
18
|
+
|
|
19
|
+
attr_accessor *CONFIG_KEYS
|
|
20
|
+
|
|
21
|
+
AUTH_KEYS = [
|
|
22
|
+
:consumer_key,
|
|
23
|
+
:consumer_secret,
|
|
24
|
+
:oauth_token,
|
|
25
|
+
:oauth_token_secret,
|
|
26
|
+
] unless defined? AUTH_KEYS
|
|
27
|
+
|
|
28
|
+
attr_writer *AUTH_KEYS
|
|
29
|
+
|
|
30
|
+
class << self
|
|
31
|
+
|
|
32
|
+
def keys
|
|
33
|
+
@keys ||= CONFIG_KEYS + AUTH_KEYS
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
data/lib/actv/default.rb
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
require 'faraday'
|
|
2
|
+
require 'actv/configurable'
|
|
3
|
+
require 'actv/request/multipart_with_file'
|
|
4
|
+
require 'actv/response/parse_json'
|
|
5
|
+
require 'actv/response/raise_client_error'
|
|
6
|
+
require 'actv/response/raise_server_error'
|
|
7
|
+
# require 'twitter/response/rate_limit'
|
|
8
|
+
require 'actv/version'
|
|
9
|
+
|
|
10
|
+
module ACTV
|
|
11
|
+
module Default
|
|
12
|
+
class << self
|
|
13
|
+
|
|
14
|
+
def options
|
|
15
|
+
Hash[ACTV::Configurable.keys.map{|key| [key, send(key)]}]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @note This is configurable in case you want to use HTTP instead of HTTPS or use a Active-compatible endpoint.
|
|
19
|
+
# @see http://en.blog.wordpress.com/2009/12/12/twitter-api/
|
|
20
|
+
# @see http://staff.tumblr.com/post/287703110/api
|
|
21
|
+
# @see http://developer.typepad.com/typepad-twitter-api/twitter-api.html
|
|
22
|
+
def endpoint
|
|
23
|
+
@endpoint ||= 'https://api.active.com'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def media_endpoint
|
|
27
|
+
@media_endpoint ||= 'https://upload.active.com'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def search_endpoint
|
|
31
|
+
@search_endpoint ||= 'https://search.active.com'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def connection_options
|
|
35
|
+
@connection_options ||= {
|
|
36
|
+
:headers => {
|
|
37
|
+
:accept => 'application/json',
|
|
38
|
+
:user_agent => "Active Ruby Gem #{ACTV::VERSION}"
|
|
39
|
+
},
|
|
40
|
+
:open_timeout => 5,
|
|
41
|
+
:raw => true,
|
|
42
|
+
:ssl => {:verify => false},
|
|
43
|
+
:timeout => 10,
|
|
44
|
+
}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @note Faraday's middleware stack implementation is comparable to that of Rack middleware. The order of middleware is important: the first middleware on the list wraps all others, while the last middleware is the innermost one.
|
|
48
|
+
# @see https://github.com/technoweenie/faraday#advanced-middleware-usage
|
|
49
|
+
# @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
|
|
50
|
+
def middleware
|
|
51
|
+
@middleware ||= Faraday::Builder.new(
|
|
52
|
+
&Proc.new do |builder|
|
|
53
|
+
builder.use ACTV::Request::MultipartWithFile # Convert file uploads to Faraday::UploadIO objects
|
|
54
|
+
builder.use Faraday::Request::Multipart # Checks for files in the payload
|
|
55
|
+
builder.use Faraday::Request::UrlEncoded # Convert request params as "www-form-urlencoded"
|
|
56
|
+
builder.use ACTV::Response::RaiseClientError # Handle 4xx server responses
|
|
57
|
+
builder.use ACTV::Response::ParseJson # Parse JSON response bodies using MultiJson
|
|
58
|
+
builder.use ACTV::Response::RaiseServerError # Handle 5xx server responses
|
|
59
|
+
# builder.use ACTV::Response::RateLimit # Update RateLimit object
|
|
60
|
+
builder.adapter Faraday.default_adapter # Set Faraday's HTTP adapter
|
|
61
|
+
end
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def consumer_key
|
|
66
|
+
ENV['ACTV_CONSUMER_KEY']
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def consumer_secret
|
|
70
|
+
ENV['ACTV_CONSUMER_SECRET']
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def oauth_token
|
|
74
|
+
ENV['ACTV_OAUTH_TOKEN']
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def oauth_token_secret
|
|
78
|
+
ENV['ACTV_OAUTH_TOKEN_SECRET']
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def api_key
|
|
82
|
+
nil
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
data/lib/actv/error.rb
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module ACTV
|
|
2
|
+
# Custom error class for rescuing from all Twitter errors
|
|
3
|
+
class Error < StandardError
|
|
4
|
+
attr_reader :wrapped_exception
|
|
5
|
+
|
|
6
|
+
def self.errors
|
|
7
|
+
@errors ||= Hash[descendants.map{|klass| [klass.const_get(:HTTP_STATUS_CODE), klass]}]
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.descendants
|
|
11
|
+
ObjectSpace.each_object(::Class).select{|klass| klass < self}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Initializes a new Error object
|
|
15
|
+
#
|
|
16
|
+
# @param exception [Exception, String]
|
|
17
|
+
# @return [Twitter::Error]
|
|
18
|
+
def initialize(exception=$!)
|
|
19
|
+
if exception.respond_to?(:backtrace)
|
|
20
|
+
super(exception.message)
|
|
21
|
+
@wrapped_exception = exception
|
|
22
|
+
else
|
|
23
|
+
super(exception.to_s)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def backtrace
|
|
28
|
+
@wrapped_exception ? @wrapped_exception.backtrace : super
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'actv/error/server_error'
|
|
2
|
+
|
|
3
|
+
module ACTV
|
|
4
|
+
class Error
|
|
5
|
+
# Raised when Active returns the HTTP status code 502
|
|
6
|
+
class BadGateway < ACTV::Error::ServerError
|
|
7
|
+
HTTP_STATUS_CODE = 502
|
|
8
|
+
MESSAGE = "A3PI, or something it depends on (like Asset Service) is down."
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'actv/error'
|
|
2
|
+
|
|
3
|
+
module ACTV
|
|
4
|
+
class Error
|
|
5
|
+
# Raised when Active returns a 4xx HTTP status code or there's an error in Faraday
|
|
6
|
+
class ClientError < ACTV::Error
|
|
7
|
+
|
|
8
|
+
# Create a new error from an HTTP environment
|
|
9
|
+
#
|
|
10
|
+
# @param body [Hash]
|
|
11
|
+
# @return [ACTV::Error]
|
|
12
|
+
def self.from_response_body(body)
|
|
13
|
+
new(parse_error(body))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def self.parse_error(body)
|
|
19
|
+
if body.nil?
|
|
20
|
+
''
|
|
21
|
+
elsif body[:error]
|
|
22
|
+
if body[:error].is_a? Hash
|
|
23
|
+
body[:error].fetch(:message, "")
|
|
24
|
+
else
|
|
25
|
+
body[:error]
|
|
26
|
+
end
|
|
27
|
+
elsif body[:errors]
|
|
28
|
+
first = Array(body[:errors]).first
|
|
29
|
+
if first.kind_of?(Hash)
|
|
30
|
+
first[:message].chomp
|
|
31
|
+
else
|
|
32
|
+
first.chomp
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'actv/error/server_error'
|
|
2
|
+
|
|
3
|
+
module ACTV
|
|
4
|
+
class Error
|
|
5
|
+
# Raised when Active returns the HTTP status code 500
|
|
6
|
+
class InternalServerError < ACTV::Error::ServerError
|
|
7
|
+
HTTP_STATUS_CODE = 500
|
|
8
|
+
MESSAGE = "Something is technically wrong."
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'actv/error'
|
|
2
|
+
|
|
3
|
+
module ACTV
|
|
4
|
+
class Error
|
|
5
|
+
# Raised when Active returns a 5xx HTTP status code
|
|
6
|
+
class ServerError < ACTV::Error
|
|
7
|
+
MESSAGE = "Server Error"
|
|
8
|
+
|
|
9
|
+
# Initializes a new ServerError object
|
|
10
|
+
#
|
|
11
|
+
# @param message [String]
|
|
12
|
+
# @return [Twitter::Error::ServerError]
|
|
13
|
+
def initialize(message=nil)
|
|
14
|
+
super(message || self.class.const_get(:MESSAGE))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'actv/error/server_error'
|
|
2
|
+
|
|
3
|
+
module ACTV
|
|
4
|
+
class Error
|
|
5
|
+
# Raised when Active returns the HTTP status code 503
|
|
6
|
+
class ServiceUnavailable < ACTV::Error::ServerError
|
|
7
|
+
HTTP_STATUS_CODE = 503
|
|
8
|
+
MESSAGE = "(__-){ Active is over capacity."
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
data/lib/actv/event.rb
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
require 'actv/asset'
|
|
2
|
+
|
|
3
|
+
module ACTV
|
|
4
|
+
class Event < ACTV::Asset
|
|
5
|
+
attr_reader :salesStartDate, :salesEndDate, :activityStartDate, :activityEndDate
|
|
6
|
+
alias sales_start_date salesStartDate
|
|
7
|
+
alias sales_end_date salesEndDate
|
|
8
|
+
alias activity_start_date activityStartDate
|
|
9
|
+
alias activity_end_date activityEndDate
|
|
10
|
+
|
|
11
|
+
def online_registration_available?
|
|
12
|
+
if is_present?(self.registrationUrlAdr)
|
|
13
|
+
if is_present?(self.legacy_data) && is_present?(self.legacy_data.onlineRegistration)
|
|
14
|
+
self.legacy_data.onlineRegistration.downcase == 'true'
|
|
15
|
+
else
|
|
16
|
+
true
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
false
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def registration_open?
|
|
24
|
+
if online_registration_available?
|
|
25
|
+
is_now_between? authoritative_reg_start_date, authoritative_reg_end_date
|
|
26
|
+
else
|
|
27
|
+
false
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def registration_closed?
|
|
32
|
+
if online_registration_available?
|
|
33
|
+
is_now_after? authoritative_reg_end_date
|
|
34
|
+
else
|
|
35
|
+
false
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def registration_not_yet_open?
|
|
40
|
+
if online_registration_available?
|
|
41
|
+
is_now_before? authoritative_reg_start_date
|
|
42
|
+
else
|
|
43
|
+
false
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def event_ended?
|
|
48
|
+
if is_present? activity_end_date
|
|
49
|
+
is_now_after? "#{activity_end_date.split('T').first}T23:59:59"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def registration_opening_soon?(time_in_days=3)
|
|
54
|
+
@reg_open_soon ||= begin
|
|
55
|
+
if online_registration_available?
|
|
56
|
+
if self.sales_start_date
|
|
57
|
+
if now_in_utc >= utc_time(self.sales_start_date) - time_in_days.days and
|
|
58
|
+
now_in_utc < utc_time(self.sales_start_date)
|
|
59
|
+
return true
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
false
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def registration_closing_soon?(time_in_days=3)
|
|
69
|
+
@reg_closing_soon ||= begin
|
|
70
|
+
if online_registration_available?
|
|
71
|
+
if self.sales_end_date
|
|
72
|
+
if now_in_utc >= utc_time(self.sales_end_date) - time_in_days.days and
|
|
73
|
+
now_in_utc < utc_time(self.end_date)
|
|
74
|
+
return true
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
false
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def display_close_date
|
|
84
|
+
@display_close_date ||= begin
|
|
85
|
+
val = tag_by_description 'displayclosedate'
|
|
86
|
+
if val
|
|
87
|
+
val.downcase == 'true'
|
|
88
|
+
else
|
|
89
|
+
true
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
alias display_close_date? display_close_date
|
|
94
|
+
|
|
95
|
+
############
|
|
96
|
+
|
|
97
|
+
# Returns the asset's registration open date
|
|
98
|
+
# in UTC. This is pulled from the salesStartDate
|
|
99
|
+
def registration_open_date
|
|
100
|
+
Time.parse "#{authoritative_reg_start_date} UTC"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Returns the asset's registration end date
|
|
104
|
+
# in UTC. This is pulled from the salesEndDate
|
|
105
|
+
def registration_close_date
|
|
106
|
+
Time.parse "#{authoritative_reg_end_date} UTC"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Returns the asset's start date
|
|
110
|
+
# in UTC. This is pulled from the activityStartDate.
|
|
111
|
+
def event_start_date
|
|
112
|
+
Time.parse "#{activity_start_date} #{format_timezone_offset(timezone_offset)}"
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Returns the asset's end date
|
|
116
|
+
# in UTC. This is pulled from the activityEndDate.
|
|
117
|
+
def event_end_date
|
|
118
|
+
Time.parse "#{activity_end_date} #{format_timezone_offset(timezone_offset)}"
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def timezone_offset
|
|
122
|
+
place.timezoneOffset + place.timezoneDST
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
############
|
|
126
|
+
|
|
127
|
+
def image_url
|
|
128
|
+
defaultImage = 'http://www.active.com/images/events/hotrace.gif'
|
|
129
|
+
image = ''
|
|
130
|
+
|
|
131
|
+
self.assetImages.each do |i|
|
|
132
|
+
if i.imageUrlAdr.downcase != defaultImage
|
|
133
|
+
image = i.imageUrlAdr
|
|
134
|
+
break
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
if image.blank?
|
|
139
|
+
if (self.logoUrlAdr && self.logoUrlAdr != defaultImage && self.logoUrlAdr =~ URI::regexp)
|
|
140
|
+
image = self.logoUrlAdr
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
image
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
alias online_registration? online_registration_available?
|
|
147
|
+
alias reg_open? registration_open?
|
|
148
|
+
alias reg_closed? registration_closed?
|
|
149
|
+
alias registration_not_open? registration_not_yet_open?
|
|
150
|
+
alias reg_not_open? registration_not_yet_open?
|
|
151
|
+
alias reg_not_yet_open? registration_not_yet_open?
|
|
152
|
+
alias ended? event_ended?
|
|
153
|
+
|
|
154
|
+
private
|
|
155
|
+
|
|
156
|
+
# EG: -7 => "-0700"
|
|
157
|
+
def format_timezone_offset(offset)
|
|
158
|
+
(offset < 0 ? "-" : "") << offset.abs.to_s.rjust(2,'0') << '00'
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def authoritative_reg_end_date
|
|
162
|
+
if is_present? sales_end_date
|
|
163
|
+
sales_end_date
|
|
164
|
+
elsif is_present? activity_end_date
|
|
165
|
+
"#{activity_end_date.split('T').first}T23:59:59"
|
|
166
|
+
elsif is_present? activity_start_date
|
|
167
|
+
activity_start_date
|
|
168
|
+
else
|
|
169
|
+
"2100-12-31T23:59:59"
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def authoritative_reg_start_date
|
|
174
|
+
if is_present? sales_start_date
|
|
175
|
+
sales_start_date
|
|
176
|
+
else
|
|
177
|
+
"1970-01-01T00:00:00"
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def is_now_before? date_string
|
|
182
|
+
now_in_utc < utc_time(date_string)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def is_now_after? date_string
|
|
186
|
+
!is_now_before? date_string
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def is_now_between? start_date_string, end_date_string
|
|
190
|
+
utc_time(start_date_string) < now_in_utc && now_in_utc < utc_time(end_date_string)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def is_present? obj
|
|
194
|
+
!is_empty? obj
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def is_empty? obj
|
|
198
|
+
obj.respond_to?(:empty?) ? obj.empty? : !obj
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def now_in_utc
|
|
202
|
+
Time.now.utc
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def utc_time(time_string)
|
|
206
|
+
return nil if time_string.nil? or time_string.empty?
|
|
207
|
+
return Time.parse(time_string).utc
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
|