snafu 0.1.2 → 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.
- data/.gitignore +1 -0
- data/CHANGELOG.textile +12 -1
- data/README.textile +68 -7
- data/lib/snafu.rb +9 -2
- data/lib/snafu/achievements.rb +17 -0
- data/lib/snafu/client.rb +33 -23
- data/lib/snafu/giants.rb +35 -0
- data/lib/snafu/models.rb +4 -1
- data/lib/snafu/models/achievement.rb +24 -0
- data/lib/snafu/models/giant.rb +21 -0
- data/lib/snafu/models/glitch_time.rb +116 -0
- data/lib/snafu/models/hub.rb +5 -2
- data/lib/snafu/models/location.rb +3 -3
- data/lib/snafu/models/street.rb +13 -5
- data/lib/snafu/util.rb +12 -0
- data/lib/snafu/version.rb +1 -1
- data/snafu.gemspec +2 -2
- data/spec/snafu/achievements_spec.rb +51 -0
- data/spec/snafu/client_spec.rb +37 -15
- data/spec/snafu/giants_spec.rb +60 -0
- data/spec/snafu/locations_spec.rb +33 -32
- data/spec/snafu/models/achievement_spec.rb +31 -0
- data/spec/snafu/models/giant_spec.rb +38 -0
- data/spec/snafu/models/glitch_image_spec.rb +7 -17
- data/spec/snafu/models/glitch_time_spec.rb +176 -0
- data/spec/snafu/models/hub_spec.rb +2 -2
- data/spec/snafu/models/street_spec.rb +1 -1
- data/spec/snafu/models/util_spec.rb +22 -0
- data/spec/snafu_spec.rb +4 -3
- data/spec/spec_helper.rb +17 -16
- metadata +46 -54
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_accept_a_hash_of_POST_arguments.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_automatically_pass_in_the_oauth_token_if.yml +0 -36
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_automatically_pass_in_the_oauth_token_if_authenticate.yml +0 -36
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_automatically_pass_in_the_oauth_token_if_authenticate_called_with_true.yml +0 -36
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_automatically_pass_in_the_oauth_token_if_called_with_authenticate.yml +0 -36
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_automatically_pass_in_the_oauth_token_if_called_with_authenticate_true.yml +0 -36
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_automatically_pass_in_the_oauth_token_if_called_with_true.yml +0 -36
- data/spec/fixtures/vcr_cassettes/Snafu_Client/call_should_raise_a_GlitchAPIError_if_receiving_an_unsucessful_response_from_the_Glitch_API.yml +0 -36
- data/spec/fixtures/vcr_cassettes/Snafu_Locations/get_hub_should_return_a_valid_hub_if_given_a_valid_Hub_ID.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Locations/get_hub_should_return_an_array_of_valid_street_information_if_given_a_valid_Hub_ID.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Locations/get_hubs_should_populated_the_returned_Hub_objects_with_an_id_and_name.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Locations/get_hubs_should_return_an_array_of_Hub_objects.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Locations/get_hubs_should_return_an_array_of_all_hubs.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Locations/get_street_should_return_a_complete_street_if_given_a_valid_street_ID.yml +0 -40
- data/spec/fixtures/vcr_cassettes/Snafu_Models_Hub/initialize_should_populate_values_if_given_the_raw_JSON_response_from_HTTParty.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Models_Hub/initialize_should_populate_values_if_given_the_raw_response_from_Glitch.yml +0 -39
- data/spec/fixtures/vcr_cassettes/Snafu_Models_Street/initialize_should_populate_values_if_given_the_raw_JSON_response_from_HTTParty.yml +0 -40
- data/spec/fixtures/vcr_cassettes/Snafu_Models_Street_new/should_populate_values_if_given_the_raw_JSON_response_from_HTTParty.yml +0 -40
- data/spec/fixtures/vcr_cassettes/calendar_getHoldays/valid_calendar.yml +0 -39
data/.gitignore
CHANGED
data/CHANGELOG.textile
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
+
h2. 0.2.0
|
2
|
+
|
3
|
+
* Hub#streets now contains an array of Street objects
|
4
|
+
* Support for in-game Date & Time
|
5
|
+
* Support for the "achievements.listAll" method
|
6
|
+
* Support for the "giants.list" method
|
7
|
+
* Support for the "giants.getFavor" method
|
8
|
+
|
1
9
|
h2. 0.1.2
|
2
|
-
|
10
|
+
|
11
|
+
* Glitch Locations (Hubs, Streets, etc.) may have strings or integers for their IDs. Street#id, and Hub#id now always returns a String
|
3
12
|
|
4
13
|
h2. 0.1.1
|
14
|
+
|
5
15
|
* Fixed an issue where Hub.new would not populate steet names when given the raw result from Glitch
|
6
16
|
|
7
17
|
h2. 0.1.0
|
18
|
+
|
8
19
|
* Initial release
|
data/README.textile
CHANGED
@@ -1,20 +1,65 @@
|
|
1
1
|
h1. Snafu
|
2
2
|
|
3
|
-
Snafu is a Ruby gem that provides an interface to the "
|
3
|
+
Snafu is a Ruby gem that provides an interface to the "API":http://api.glitch.com for "Glitch":http://glitch.com, a browser-based MMO created by "Tiny Speck":http://tinyspeck.com.
|
4
|
+
|
5
|
+
h2. API Support
|
6
|
+
|
7
|
+
h3. Currently Supported
|
8
|
+
|
9
|
+
* In-Game Time & Date (See the GlitchTime class for more info)
|
10
|
+
* Giants
|
11
|
+
** giants.list (Snafu::Giants#get_giants)
|
12
|
+
* Locations
|
13
|
+
** locations.getHubs (Snafu::Locations#get_hubs)
|
14
|
+
** locations.getStreets (Snafu::Locations#get_hub)
|
15
|
+
** locations.streetInfo (Snafu::Locations#get_street)
|
16
|
+
|
17
|
+
h3. Not Yet Supported
|
18
|
+
|
19
|
+
* Achievements
|
20
|
+
* Auctions
|
21
|
+
* Avatar
|
22
|
+
* Players
|
23
|
+
* Skills
|
4
24
|
|
5
25
|
h2. Usage
|
6
26
|
|
7
|
-
To get started, instantiate
|
27
|
+
To get started, instantiate the client with either no options or with the OAuth token of an authenticated user if 'identity' scope or higher is required.
|
8
28
|
|
9
29
|
<pre lang="ruby">
|
10
30
|
snafu = Snafu.new(:oauth_token => "your-oauth-token")
|
11
31
|
</pre>
|
12
32
|
|
13
|
-
Snafu currently does not support Glitch's OAuth authentication. There are other gems that support authenticating with Glitch
|
33
|
+
Snafu currently does not support Glitch's OAuth authentication. There are other gems that support authenticating with Glitch such as "OmniAuth":https://github.com/intridea/omniauth.
|
34
|
+
|
35
|
+
h3. In-Game Time & Date
|
14
36
|
|
15
|
-
|
37
|
+
Note that the hour, minute, day of week, day of year, and day of month are all zero-based.
|
16
38
|
|
17
|
-
|
39
|
+
To get the current in-game date and time:
|
40
|
+
|
41
|
+
<pre lang="ruby">
|
42
|
+
current_time = snafu.glitch_time
|
43
|
+
current_time.year
|
44
|
+
=> 20
|
45
|
+
current_time.month
|
46
|
+
=> "Spork"
|
47
|
+
current_time.day
|
48
|
+
=> "Hairday"
|
49
|
+
</pre>
|
50
|
+
|
51
|
+
h3. Giants
|
52
|
+
|
53
|
+
<pre lang="ruby">
|
54
|
+
# giants.list
|
55
|
+
giants = snafu.get_giants
|
56
|
+
giants.first.name
|
57
|
+
=> "Alph"
|
58
|
+
</pre>
|
59
|
+
|
60
|
+
h3. Locations
|
61
|
+
|
62
|
+
All locations.* methods are supported. Each method returns a Ruby object representing the returned data.
|
18
63
|
|
19
64
|
<pre lang="ruby">
|
20
65
|
# locations.*
|
@@ -23,9 +68,21 @@ Currently, only the locations.* methods are supported via helper methods. Each m
|
|
23
68
|
street = snafu.get_street(street_tsid) # "locations.streetInfo"
|
24
69
|
</pre>
|
25
70
|
|
26
|
-
|
71
|
+
h3. Achievements
|
72
|
+
|
73
|
+
<pre lang="ruby">
|
74
|
+
achievements = snafu.get_achievements # "achievements.listAll"
|
75
|
+
achievements.first.name
|
76
|
+
=> "1-Star Cuisinartist"
|
77
|
+
achievements.first.desc
|
78
|
+
=> "Whipped up 11 meals with an Awesome Pot"
|
79
|
+
</pre>
|
80
|
+
|
81
|
+
h3. Manual Method Calls
|
27
82
|
|
28
|
-
You can also receive raw data from the Glitch API by passing
|
83
|
+
You can also receive raw data from the Glitch API by passing any method name into #call and supplying any required parameters via an options hash. This returns a Hash representation of the JSON returned by Glitch.
|
84
|
+
|
85
|
+
For example, to manually call the Glitch *calendar.getholidays* method:
|
29
86
|
|
30
87
|
<pre lang="ruby">
|
31
88
|
snafu.call("calendar.getHolidays")
|
@@ -63,3 +120,7 @@ You can also receive raw data from the Glitch API by passing in any method as a
|
|
63
120
|
=> }
|
64
121
|
</pre>
|
65
122
|
|
123
|
+
h2. Credits
|
124
|
+
|
125
|
+
"Jeff Browning":http://github.com/jbrowning - Original author
|
126
|
+
"Lee Jensen":https://github.com/outerim - Contributions to GlitchTime
|
data/lib/snafu.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
|
1
3
|
require 'httparty'
|
2
4
|
|
3
5
|
require "snafu/version"
|
4
6
|
require "snafu/locations"
|
5
|
-
require "snafu/
|
6
|
-
require "snafu/
|
7
|
+
require "snafu/models"
|
8
|
+
require "snafu/achievements"
|
9
|
+
require "snafu/giants"
|
10
|
+
require "snafu/util"
|
11
|
+
|
12
|
+
# Must be required last
|
13
|
+
require "snafu/client"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Snafu
|
2
|
+
module Achievements
|
3
|
+
def get_achievements
|
4
|
+
result = []
|
5
|
+
response = self.call("achievements.listAll", :per_page => self.achievement_count)
|
6
|
+
response["items"].each do |achievement|
|
7
|
+
result << Models::Achievement.new(achievement[1])
|
8
|
+
end
|
9
|
+
result
|
10
|
+
end
|
11
|
+
|
12
|
+
def achievement_count
|
13
|
+
response = self.call("achievements.listAll")
|
14
|
+
response["total"]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/snafu/client.rb
CHANGED
@@ -9,12 +9,15 @@ module Snafu
|
|
9
9
|
# it's p-p-p-party time
|
10
10
|
include HTTParty
|
11
11
|
|
12
|
-
# include other classes & modules so they can be called on
|
12
|
+
# include other classes & modules so they can be called on self
|
13
13
|
include Snafu::Locations
|
14
|
-
|
14
|
+
include Snafu::Achievements
|
15
|
+
include Snafu::Giants
|
16
|
+
include Snafu::Util
|
17
|
+
|
15
18
|
base_uri API_URL
|
16
19
|
|
17
|
-
attr_accessor :oauth_token
|
20
|
+
attr_accessor :oauth_token, :last_request_result
|
18
21
|
|
19
22
|
def initialize(options={})
|
20
23
|
@oauth_token = options[:oauth_token]
|
@@ -30,39 +33,46 @@ module Snafu
|
|
30
33
|
# snafu = snafu.call("players.stats", :authenticate => true)
|
31
34
|
#
|
32
35
|
# Invalid method calls will raise a <tt>GlitchAPIError</tt>
|
33
|
-
|
34
36
|
def call(method, query_parameters={})
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
options[:query] = query_parameters
|
39
|
-
if options[:query].has_key?(:authenticate) && options[:query][:authenticate] == true
|
40
|
-
if self.oauth_token.nil?
|
41
|
-
raise GlitchAPIError.new("You cannot do an authenticated call without an oauth token")
|
42
|
-
end
|
37
|
+
unless method.is_a? String
|
38
|
+
raise ArgumentError.new("Method argument must be a string")
|
39
|
+
end
|
43
40
|
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
options = { :format => :json }
|
42
|
+
unless query_parameters.empty?
|
43
|
+
options[:query] = query_parameters
|
44
|
+
if options[:query].has_key?(:authenticate) && options[:query][:authenticate] == true
|
45
|
+
if self.oauth_token.nil?
|
46
|
+
raise GlitchAuthenticationError.new("You cannot perform an authenticated call without an oauth token")
|
47
47
|
end
|
48
|
+
|
49
|
+
# Replace the authenticate key with the oauth token
|
50
|
+
options[:query].delete(:authenticate)
|
51
|
+
options[:query].update(:oauth_token => @oauth_token)
|
48
52
|
end
|
49
|
-
request_uri = "/#{method}"
|
50
|
-
parse_response(self.class.get(request_uri, options))
|
51
|
-
else
|
52
|
-
raise ArgumentError.new("Method argument must be a string")
|
53
53
|
end
|
54
|
+
request_uri = "/#{method}"
|
55
|
+
parse_response(self.class.get(request_uri, options))
|
54
56
|
end
|
55
57
|
|
56
58
|
def parse_response(response)
|
57
|
-
if response["
|
58
|
-
raise
|
59
|
+
if response["error"] == "invalid_token"
|
60
|
+
raise GlitchAuthenticationError.new("Invalid Token")
|
61
|
+
elsif response["ok"] == 0
|
62
|
+
if response["error"] == "missing_scope"
|
63
|
+
raise GlitchAuthenticationError.new("The token supplied has insufficient scope for this API method")
|
64
|
+
elsif response["error"] == "not_authenticated"
|
65
|
+
raise GlitchAuthenticationError.new("This API method requires authentication and no OAuth token has been supplied")
|
66
|
+
else
|
67
|
+
raise GlitchAPIError.new(response["error"])
|
68
|
+
end
|
59
69
|
else
|
70
|
+
@last_request_result = response
|
60
71
|
response
|
61
72
|
end
|
62
73
|
end
|
63
74
|
end
|
64
75
|
|
65
|
-
|
66
|
-
|
67
76
|
class GlitchAPIError < StandardError;end
|
77
|
+
class GlitchAuthenticationError < StandardError;end
|
68
78
|
end
|
data/lib/snafu/giants.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
module Snafu
|
2
|
+
module Giants
|
3
|
+
|
4
|
+
# Accesses the "giants.list" method from the Glitch API and returns an array of the
|
5
|
+
# Giant information
|
6
|
+
def get_giants
|
7
|
+
giants = []
|
8
|
+
response = self.call("giants.list")
|
9
|
+
response["giants"].each do |short_name, long_name|
|
10
|
+
giants << Models::Giant.new(:name => long_name)
|
11
|
+
end
|
12
|
+
giants
|
13
|
+
end
|
14
|
+
|
15
|
+
# Accesses the "giants.getFavor" method from the Glitch API and returns an array of
|
16
|
+
# giants with their respective favor for the authenticated users
|
17
|
+
#
|
18
|
+
# Requires an OAuth token with *read* scope
|
19
|
+
#
|
20
|
+
def get_giants_favor
|
21
|
+
giants = []
|
22
|
+
reponse = self.call("giants.getFavor", :authenticate => true)
|
23
|
+
reponse["giants"].each do |giant_short_name, giant_values|
|
24
|
+
giants << Models::Giant.new(
|
25
|
+
:name => giant_values["name"],
|
26
|
+
:cur_favor => giant_values["cur_favor"],
|
27
|
+
:max_favor => giant_values["max_favor"],
|
28
|
+
:cur_daily_favor => giant_values["cur_daily_favor"],
|
29
|
+
:max_daily_favor => giant_values["max_daily_favor"]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
giants
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/snafu/models.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require 'snafu/models/glitch_image'
|
2
2
|
require 'snafu/models/location'
|
3
3
|
require 'snafu/models/hub'
|
4
|
-
require 'snafu/models/street'
|
4
|
+
require 'snafu/models/street'
|
5
|
+
require 'snafu/models/glitch_time'
|
6
|
+
require 'snafu/models/achievement'
|
7
|
+
require 'snafu/models/giant'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Snafu
|
2
|
+
module Models
|
3
|
+
class Achievement
|
4
|
+
attr_reader :name, :description, :url, :image_60, :image_180
|
5
|
+
alias_method :desc, :description
|
6
|
+
def initialize(options = {})
|
7
|
+
@name = options["name"]
|
8
|
+
@description = options["description"] || options["desc"]
|
9
|
+
@url = options["url"]
|
10
|
+
@image_60 = parse_image options["image_60"]
|
11
|
+
@image_180 = parse_image options["image_180"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def parse_image(image)
|
15
|
+
if image.is_a? String
|
16
|
+
return GlitchImage.new(url: image)
|
17
|
+
elsif image.is_a? GlitchImage
|
18
|
+
return image
|
19
|
+
end
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Snafu
|
2
|
+
module Models
|
3
|
+
# Defines a class for Glitch Giants
|
4
|
+
#
|
5
|
+
class Giant
|
6
|
+
attr_reader :name, :cur_favor, :max_favor, :cur_daily_favor, :max_daily_favor
|
7
|
+
|
8
|
+
alias_method :current_favor, :cur_favor
|
9
|
+
alias_method :current_daily_favor, :cur_daily_favor
|
10
|
+
|
11
|
+
def initialize(options={})
|
12
|
+
@name = options[:name] || options["name"]
|
13
|
+
@cur_favor = (options[:cur_favor] || options["cur_favor"] || 0).to_i
|
14
|
+
@max_favor = (options[:max_favor] || options["max_favor"] || 0).to_i
|
15
|
+
@cur_daily_favor = (options[:cur_daily_favor] || options["cur_daily_favor"] || 0).to_i
|
16
|
+
@max_daily_favor = (options[:max_daily_favor] || options["max_daily_favor"] || 0).to_i
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Snafu
|
2
|
+
module Models
|
3
|
+
# Class representing a Glitch date and time
|
4
|
+
#
|
5
|
+
# there are 4435200 real seconds in a game year
|
6
|
+
# there are 115200 real seconds in a game week
|
7
|
+
# there are 14400 real seconds in a game day
|
8
|
+
# there are 600 real seconds in a game hour
|
9
|
+
# there are 10 real seconds in a game minute
|
10
|
+
#
|
11
|
+
class GlitchTime
|
12
|
+
class InvalidTimestampError < Exception; end
|
13
|
+
|
14
|
+
GLITCH_EPOCH = 1238562000
|
15
|
+
Y_SECS = 4435200
|
16
|
+
D_SECS = 14400
|
17
|
+
H_SECS = 600
|
18
|
+
M_SECS = 10
|
19
|
+
DAYS_IN_MONTH = [29, 3, 53, 17, 73, 19, 13, 37, 5, 47, 11, 1]
|
20
|
+
MONTH_NAMES = %w(Primuary Spork Bruise Candy Fever Junuary Septa Remember Doom Widdershins Eleventy Recurse)
|
21
|
+
DAY_NAMES = %w(Hairday Moonday Twoday Weddingday Theday Fryday Standday Fabday Recurse)
|
22
|
+
|
23
|
+
attr_reader :timestamp, :seconds_since_epoch
|
24
|
+
|
25
|
+
def initialize(new_timestamp = Time.now)
|
26
|
+
@timestamp = new_timestamp.to_i
|
27
|
+
raise InvalidTimestampError if @timestamp < GLITCH_EPOCH
|
28
|
+
@timestamp = timestamp
|
29
|
+
@seconds_since_epoch = @timestamp - GLITCH_EPOCH
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns the number of years since the Glitch epoch
|
33
|
+
def year
|
34
|
+
(seconds_since_epoch / Y_SECS).to_i
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns the 0-based day of the current Glitch year
|
38
|
+
def day_of_year
|
39
|
+
(seconds_since_start_of_year / D_SECS).to_i
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns the 0-based month of the year
|
43
|
+
def month
|
44
|
+
running_days = -1
|
45
|
+
DAYS_IN_MONTH.each_with_index do |days, idx|
|
46
|
+
running_days += days
|
47
|
+
return idx if day_of_year <= running_days
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Returns the name of the month
|
52
|
+
def name_of_month
|
53
|
+
MONTH_NAMES[self.month]
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns the 0-based day of the month
|
57
|
+
def day_of_month
|
58
|
+
return self.day_of_year if self.month == 0
|
59
|
+
self.day_of_year - DAYS_IN_MONTH.slice(0, (month)).inject(:+)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns the 0-based day of the week
|
63
|
+
def day_of_week
|
64
|
+
return -1 if day_of_year == 307
|
65
|
+
days_since_epoch % 8
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns the name of the day
|
69
|
+
def name_of_day
|
70
|
+
DAY_NAMES[day_of_week]
|
71
|
+
end
|
72
|
+
|
73
|
+
# Returns the number of game days since epoch
|
74
|
+
def days_since_epoch
|
75
|
+
self.day_of_year + (307 * year)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the hour of the day
|
79
|
+
def hour
|
80
|
+
# seconds_since_start_of_day / H_SECS
|
81
|
+
(seconds_since_start_of_day / H_SECS).to_i
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns the minute of the hour
|
85
|
+
#
|
86
|
+
# == Options
|
87
|
+
#
|
88
|
+
# +:padded+ - If true, will return a zero-padded string if the minute value is less than 10
|
89
|
+
def minute(padded = false)
|
90
|
+
min = (seconds_since_start_of_hour / M_SECS).to_i
|
91
|
+
if padded && min < 10
|
92
|
+
min = "0#{min}"
|
93
|
+
end
|
94
|
+
min
|
95
|
+
end
|
96
|
+
|
97
|
+
def to_s
|
98
|
+
"#{self.hour}:#{self.minute(padded: true)}, #{self.name_of_day} #{self.day_of_month + 1} of #{self.name_of_month}, year #{self.year}"
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def seconds_since_start_of_year
|
103
|
+
seconds_since_epoch - (Y_SECS * self.year)
|
104
|
+
end
|
105
|
+
|
106
|
+
def seconds_since_start_of_day
|
107
|
+
seconds_since_start_of_year - (D_SECS * self.day_of_year)
|
108
|
+
end
|
109
|
+
|
110
|
+
def seconds_since_start_of_hour
|
111
|
+
seconds_since_start_of_day - (H_SECS * self.hour)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|