user_timezone 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.travis.yml +10 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +116 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/lib/user_timezone/detects_timezone.rb +60 -0
- data/lib/user_timezone/timezone_detector.rb +153 -0
- data/lib/user_timezone/version.rb +3 -0
- data/lib/user_timezone.rb +9 -0
- data/user_timezone.gemspec +37 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 79f9b7d75beac7d2d4e5dbba1aa4b65f4f8bbfba
|
4
|
+
data.tar.gz: 60d17f2f052ba8b82523b4c05b537c1e0eec6e1f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 902ea953a3034d4a01c209eb9435c7da9c4b40dd07d5f7d0b5b60bc2e19c4d8867ce6d56ce366dd37364994a251c349b7120ae75bdb8cdb17a1f845d6ce81e59
|
7
|
+
data.tar.gz: cf343e688ba0df0fcbac918a5ff9400c5d843493ba50b19399a66a1dd0859a8bf0932ff66ebf985b3cad664ce6575e9135a95cada29accbd0c5bda69dca8d7ca
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Jay El-Kaake
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
![](http://i.imgur.com/JlHfMxf.jpg)
|
2
|
+
|
3
|
+
# User Timezone Detector Gem
|
4
|
+
![Travis build for User Timezone Gem](https://travis-ci.org/jayelkaake/user_timezone.svg?branch=master)
|
5
|
+
|
6
|
+
The user timezone detector Gem lets you attach the `detects_timezone` trait to your User, Account or Contact
|
7
|
+
classes and auto-populate the timezone field with detected attributes.
|
8
|
+
|
9
|
+
**Table of Contents**
|
10
|
+
|
11
|
+
* [User Timezone Detector Gem](#user-timezone-detector-gem)
|
12
|
+
* [Installation](#installation)
|
13
|
+
* [Usage](#usage)
|
14
|
+
* [Automatically populating the timezone field](#automatically-populating-the-timezone-field)
|
15
|
+
* [Getting the current time for a user, contact or account](#getting-the-current-time-for-a-user,-contact-or-account)
|
16
|
+
* [Compatible Lookup Combinations](#compatible-lookup-combinations)
|
17
|
+
* [What if my local class attributes are different?](#what-if-my-local-class-attributes-are-different?)
|
18
|
+
* [Development](#development)
|
19
|
+
* [Contributing](#contributing)
|
20
|
+
* [Rate Limits](#rate-limits)
|
21
|
+
* [License](#license)
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
gem 'user_timezone'
|
28
|
+
```
|
29
|
+
|
30
|
+
And then execute:
|
31
|
+
|
32
|
+
$ bundle
|
33
|
+
|
34
|
+
Or install it yourself as:
|
35
|
+
|
36
|
+
$ gem install user_timezone
|
37
|
+
|
38
|
+
## Usage
|
39
|
+
|
40
|
+
### Automatically populating the timezone field
|
41
|
+
This example assumes you have a table called "contacts" and it has a column with "zip" and "country" or some other compatible lookup combinations (see [Compatible Lookup Combinations](#)).
|
42
|
+
```ruby
|
43
|
+
class Contact < ActiveRecord::Base
|
44
|
+
detects_timezone log: true, on: :before_safe
|
45
|
+
end
|
46
|
+
contact = Contact.new(zip: 78729, country: "US")
|
47
|
+
contact.save!
|
48
|
+
puts contact.timezone
|
49
|
+
# OUTPUT: "America/Chicago"
|
50
|
+
```
|
51
|
+
|
52
|
+
### Getting the current time for a user, contact or account
|
53
|
+
Continuing on from the previous example, we can now also get the current time for the user.
|
54
|
+
```ruby
|
55
|
+
contact.current_time
|
56
|
+
# Output: "2016-02-21T16:37:10.064-06:00"
|
57
|
+
```
|
58
|
+
This returns a ruby time object so you can manipulate it whatever way you want.
|
59
|
+
Here's an example where we check to see if the user is awake:
|
60
|
+
```ruby
|
61
|
+
contact_hour = contact.current_time.hour
|
62
|
+
if (contact_hour > 0 && contact_hour < 8)
|
63
|
+
puts "User is still sleeping, don't bother them - it's only #{contact_hour}am their time!"
|
64
|
+
else
|
65
|
+
puts "User is awake, time to party! ┏(-_-)┛ ┗(-_- )┓ ┗(-_-)┛ ┏(-_-)┓ "
|
66
|
+
end
|
67
|
+
# OUTPUT (for example if it's 4am for them): User is still sleeping, don't bother them - it's only 4am their time!
|
68
|
+
```
|
69
|
+
|
70
|
+
### Compatible Lookup Combinations
|
71
|
+
The API will accept any parameters and try to make a best guess of what the timezone is, even if the timezone
|
72
|
+
guess will be very inaccurate when a broad filter is provided (such as only country). The attributes that will be
|
73
|
+
looked at are:
|
74
|
+
* state - as a province code or full province name. It'll be more accurate with the code for North America.
|
75
|
+
* zip - can be any string
|
76
|
+
* country - as a 2-letter ISO country code
|
77
|
+
* city - This can be any string
|
78
|
+
|
79
|
+
All fields are case insensitive.
|
80
|
+
|
81
|
+
### What if my local class attributes are different?
|
82
|
+
If your class's attributes are different than "zip", "state", etc you can map them using
|
83
|
+
the "using" config in your `detects_timezone` call like this:
|
84
|
+
```ruby
|
85
|
+
class Contact < ActiveRecord::Base
|
86
|
+
detects_timezone using: { :province => :state, :postal_code => :zip, :country => :country, :city => :city }
|
87
|
+
end
|
88
|
+
contact = Contact.new(postal_code: 78729, province: "US")
|
89
|
+
contact.save!
|
90
|
+
puts contact.timezone
|
91
|
+
# OUTPUT: "America/Chicago"
|
92
|
+
```
|
93
|
+
|
94
|
+
## Development
|
95
|
+
|
96
|
+
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an
|
97
|
+
interactive prompt that will allow you to experiment.
|
98
|
+
|
99
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
100
|
+
version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version,
|
101
|
+
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
102
|
+
|
103
|
+
## Contributing
|
104
|
+
|
105
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/jayelkaake/user_timezone.
|
106
|
+
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to
|
107
|
+
adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
108
|
+
|
109
|
+
## Rate Limits
|
110
|
+
Since this gem actually hits a free service that links timezones to locations, I've set a rate limit of 60 requests per minute.
|
111
|
+
|
112
|
+
|
113
|
+
## License
|
114
|
+
|
115
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
116
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "user_timezone"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require "active_support/concern"
|
2
|
+
require "user_timezone/timezone_detector"
|
3
|
+
module UserTimezone
|
4
|
+
module DetectsTimezone
|
5
|
+
extend ::ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def detects_timezone(options = {})
|
9
|
+
cattr_accessor :timezone_detector
|
10
|
+
self.timezone_detector = UserTimezone::TimezoneDetector.new(options)
|
11
|
+
include LocalInstanceMethods
|
12
|
+
case options[:on]
|
13
|
+
when :before_save
|
14
|
+
before_save :detect_timezone!
|
15
|
+
when :before_create
|
16
|
+
before_create :detect_timezone!
|
17
|
+
else
|
18
|
+
# Do nothing, but using switch statement
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module LocalInstanceMethods
|
24
|
+
##
|
25
|
+
# @return [String] Uses the configured address fields to return a timezone value such as "America/Chicago"
|
26
|
+
#
|
27
|
+
def detect_timezone
|
28
|
+
self.class.timezone_detector.detect(self)
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Detects the timezone using the self.#detect_timezone then sets the value
|
33
|
+
# into the local timezone field (as configured)
|
34
|
+
# @see #detect_timezone
|
35
|
+
#
|
36
|
+
def detect_timezone!
|
37
|
+
self.send(self.class.timezone_detector.options.as, self.detect_timezone)
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# @return [String] Gets he GMT offset that ruby likes (such as -05:00) in +/-HH:MM form
|
42
|
+
def utc_offset
|
43
|
+
offset = self.class.timezone_detector.detect(self, 'utc_offset')
|
44
|
+
return nil if offset.nil?
|
45
|
+
offset_val = offset.to_i
|
46
|
+
(offset_val < 0 ? '-' : '+') + Time.at(offset_val.abs.to_i).utc.strftime("%H:%M")
|
47
|
+
end
|
48
|
+
alias_method :gmt_offset, :utc_offset
|
49
|
+
|
50
|
+
##
|
51
|
+
# @return [Time] What time is it for this user?
|
52
|
+
def current_time
|
53
|
+
Time.now.utc.getlocal(utc_offset) unless utc_offset.nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
ActiveRecord::Base.send :include, UserTimezone::DetectsTimezone
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'logger'
|
4
|
+
module UserTimezone
|
5
|
+
##
|
6
|
+
# The timezone detector class takes in smoe options, then when given
|
7
|
+
# an object (user, contact, account, whatever) that has address information
|
8
|
+
# returns back the timezone for that person.
|
9
|
+
#
|
10
|
+
class TimezoneDetector
|
11
|
+
|
12
|
+
attr_reader :options
|
13
|
+
##
|
14
|
+
# @param [Hash] options (optional) Options hash... that's a bit weird to say.
|
15
|
+
# Check out https://github.com/jayelkaake/user_timezone for more information
|
16
|
+
# on options
|
17
|
+
def initialize(options = {})
|
18
|
+
@options = default_options.merge(options)
|
19
|
+
@request_cache = {}
|
20
|
+
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# @param [Hash] object What is the subject that we are detecting the timezone for?
|
25
|
+
# or alternatively, what is the hash?
|
26
|
+
# This can be a hash or object, as long as it contains the attributes
|
27
|
+
# that we want (like street, city, country, zip, etc) or has the attributes
|
28
|
+
# mapped by the options array "using" key (see https://github.com/jayelkaake/user_timezone)
|
29
|
+
# @param [String] what_to_detect What should be detected? (default: 'timezone') Also 'current_timestamp' also acceptable.
|
30
|
+
#
|
31
|
+
# @return [String] Timezone value or nil if no timezone was found for the given object.
|
32
|
+
def detect(object, what_to_detect='timezone')
|
33
|
+
request_url = api_request_url(object)
|
34
|
+
results = @request_cache[request_url] ? @request_cache[request_url] : HTTParty.get(request_url)
|
35
|
+
if results.empty?
|
36
|
+
nil
|
37
|
+
else
|
38
|
+
results.first[what_to_detect]
|
39
|
+
end
|
40
|
+
rescue Exception => e
|
41
|
+
err e.inspect
|
42
|
+
raise e if @options[:raise_errors]
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
##
|
48
|
+
# @return [Hash] default options for the timezone detector class
|
49
|
+
def default_options
|
50
|
+
{
|
51
|
+
using: [:city, :state, :country, :zip],
|
52
|
+
raise_errors: false,
|
53
|
+
as: :timezone
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
##
|
59
|
+
# Gets the API request URL with the search parameters
|
60
|
+
#
|
61
|
+
# @param [Hash] object What is the subject that we are detecting the timezone for?
|
62
|
+
# or alternatively, what is the hash?
|
63
|
+
# This can be a hash or object, as long as it contains the attributes
|
64
|
+
# that we want (like street, city, country, zip, etc) or has the attributes
|
65
|
+
# mapped by the options array "using" key (see https://github.com/jayelkaake/user_timezone)
|
66
|
+
#
|
67
|
+
# @return [String] api request URL
|
68
|
+
#
|
69
|
+
def api_request_url(object)
|
70
|
+
api_uri = 'http://timezonedb.wellfounded.ca/api/v1'
|
71
|
+
api_request_url = "#{api_uri}/timezones?"
|
72
|
+
api_request_url << get_filters(object).join('&')
|
73
|
+
log "Making request to #{api_request_url} for timezone."
|
74
|
+
api_request_url
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
##
|
79
|
+
# Gets the API request filter parts
|
80
|
+
#
|
81
|
+
# @param [Hash] object What is the subject that we are detecting the timezone for?
|
82
|
+
# or alternatively, what is the hash?
|
83
|
+
# This can be a hash or object, as long as it contains the attributes
|
84
|
+
# that we want (like street, city, country, zip, etc) or has the attributes
|
85
|
+
# mapped by the options array "using" key (see https://github.com/jayelkaake/user_timezone)
|
86
|
+
#
|
87
|
+
# @return [Array] Gets an array of field_name=value filters for the search
|
88
|
+
#
|
89
|
+
def get_filters(object)
|
90
|
+
if @options[:using].is_a?(Array)
|
91
|
+
get_array_attribute_filters(object, @options[:using])
|
92
|
+
else
|
93
|
+
get_map_attribute_filters(object, @options[:using])
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# Gets the API request URL with the search parameters
|
99
|
+
#
|
100
|
+
# @param [Hash] object What is the subject that we are detecting the timezone for?
|
101
|
+
# or alternatively, what is the hash?
|
102
|
+
# This can be a hash or object, as long as it contains the attributes
|
103
|
+
# that we want (like street, city, country, zip, etc) or has the attributes
|
104
|
+
# mapped by the options array "using" key (see https://github.com/jayelkaake/user_timezone)
|
105
|
+
# @param [Hash] attributes Attributes to use in generating filters
|
106
|
+
# @return [String] api request URL
|
107
|
+
#
|
108
|
+
def get_array_attribute_filters(object, attributes)
|
109
|
+
filters = []
|
110
|
+
attributes.each do |filter_name|
|
111
|
+
filters << get_object_filter(object, filter_name, filter_name)
|
112
|
+
end
|
113
|
+
filters
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_map_attribute_filters(object, map)
|
117
|
+
filters = []
|
118
|
+
map.each do |local_name, filter_name|
|
119
|
+
filters << get_object_filter(object, local_name, filter_name)
|
120
|
+
end
|
121
|
+
filters
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
def get_object_filter(object, local_name, filter_name)
|
126
|
+
if object.is_a?(Hash)
|
127
|
+
filter_val = object[local_name]
|
128
|
+
("#{filter_name}=" << URI::encode(filter_val)) unless filter_val.nil?
|
129
|
+
elsif object.respond_to?(local_name)
|
130
|
+
filter_val = object.send(local_name)
|
131
|
+
("#{filter_name}=" << URI::encode(filter_val)) unless filter_val.nil?
|
132
|
+
else
|
133
|
+
''
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
##
|
138
|
+
# Logs out as 'info' level using whatever logger the system is using
|
139
|
+
#
|
140
|
+
def log(msg)
|
141
|
+
@logger.info("UserTimezone::TimezoneDetector - #{msg}") if @options[:log]
|
142
|
+
end
|
143
|
+
|
144
|
+
##
|
145
|
+
# Log out an error using the system's logger.
|
146
|
+
#
|
147
|
+
# @param [Exception] e exception or error encountered to send to the logger
|
148
|
+
def err(e)
|
149
|
+
@logger.error(e)
|
150
|
+
end
|
151
|
+
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'user_timezone/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "user_timezone"
|
8
|
+
spec.version = UserTimezone::VERSION
|
9
|
+
spec.authors = ["Jay El-Kaake"]
|
10
|
+
spec.email = ["najibkaake@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Detects a user's timezone based on their country/state/city/etc}
|
13
|
+
spec.description = %q{This gem lets you add a 'has_timezone' to a User, Contact or Account that has a city, state, country or zip and it will add the #timezone attribute that will automatically populate the timezone attribute.}
|
14
|
+
spec.homepage = "https://www.github.com/jayelkaake/user_timezone"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# # delete this section to allow pushing this gem to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
# else
|
22
|
+
# raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
+
# end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = "exe"
|
27
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
28
|
+
spec.require_paths = ["lib"]
|
29
|
+
|
30
|
+
spec.add_runtime_dependency 'httparty', '~> 0.13'
|
31
|
+
|
32
|
+
spec.add_development_dependency 'rails', '~> 4.2'
|
33
|
+
spec.add_development_dependency "bundler"
|
34
|
+
spec.add_development_dependency "rake", '~> 10.0'
|
35
|
+
|
36
|
+
spec.add_development_dependency "rspec", '~> 3.4'
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: user_timezone
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jay El-Kaake
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.13'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.13'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.4'
|
83
|
+
description: 'This gem lets you add a ''has_timezone'' to a User, Contact or Account
|
84
|
+
that has a city, state, country or zip and it will add the #timezone attribute that
|
85
|
+
will automatically populate the timezone attribute.'
|
86
|
+
email:
|
87
|
+
- najibkaake@gmail.com
|
88
|
+
executables: []
|
89
|
+
extensions: []
|
90
|
+
extra_rdoc_files: []
|
91
|
+
files:
|
92
|
+
- ".gitignore"
|
93
|
+
- ".travis.yml"
|
94
|
+
- CODE_OF_CONDUCT.md
|
95
|
+
- Gemfile
|
96
|
+
- LICENSE.txt
|
97
|
+
- README.md
|
98
|
+
- Rakefile
|
99
|
+
- bin/console
|
100
|
+
- bin/setup
|
101
|
+
- lib/user_timezone.rb
|
102
|
+
- lib/user_timezone/detects_timezone.rb
|
103
|
+
- lib/user_timezone/timezone_detector.rb
|
104
|
+
- lib/user_timezone/version.rb
|
105
|
+
- user_timezone.gemspec
|
106
|
+
homepage: https://www.github.com/jayelkaake/user_timezone
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubyforge_project:
|
126
|
+
rubygems_version: 2.4.6
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: Detects a user's timezone based on their country/state/city/etc
|
130
|
+
test_files: []
|
131
|
+
has_rdoc:
|