city_utc 1.0.3

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e9e1ce9b68125ef57c5f00a5f4ff372e851d76c4
4
+ data.tar.gz: 01dba33affe44d348cc00b09b7516629cd55b6e5
5
+ SHA512:
6
+ metadata.gz: 92e90ee4e18720738e8903834facd3295195f214c95352c61a1e70460d1e45bf8a8d0e1f25ee9fe583d36427477a15aa4e7ca791bddcf0c7d6873408fbb0e46b
7
+ data.tar.gz: 9825559d32534fc920875ededc2ac42664a0bae23504d15aefe756b73d4933c7fb4ac3d938d29e60bd5b65394a01ced7ac7cab175a3d9516c1b4bdae4a1426f4
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'rake'
6
+
7
+ gemspec
8
+
9
+ group :development do
10
+ gem 'nearest_time_zone', '~> 0.0.4', require: false
11
+
12
+ gem 'webmock', '~> 2.3.2'
13
+ gem 'rspec', '~> 3.5.0'
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) <2016> Kuzichev Michael
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+
3
+ require 'bundler'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new
7
+ task default: :spec
8
+
9
+ # Loads *.rake files from /tasks
10
+ Dir.entries(File.join(__dir__, 'tasks')).each do |file|
11
+ load File.join(__dir__, 'tasks', file) if File.extname(file) == '.rake'
12
+ end
data/server/config.ru ADDED
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ require File.expand_path(File.join(__dir__, '../sources', 'city_utc.rb'))
4
+
5
+ run CityUTC::WebServer
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ #
4
+ # @author Kuzichev Michael
5
+ # @license MIT
6
+ module CityUTC
7
+ require File.join __dir__, 'city_utc', 'project_structure'
8
+ end # module CityUTC
@@ -0,0 +1,39 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module CityUTC
4
+ # == Schema for `cities` table
5
+ #
6
+ # CREATE TABLE `cities` (
7
+ # `id` INTEGER PRIMARY KEY AUTOINCREMENT,
8
+ # `city` TEXT,
9
+ # `country` TEXT,
10
+ # `latitude` REAL,
11
+ # `longitude` REAL,
12
+ # `population` INTEGER,
13
+ # `timezone_code` INTEGER
14
+ # );
15
+ class City < Sequel::Model
16
+
17
+ ##
18
+ # Returns timezone for city.
19
+ #
20
+ # When more than one city was found it returns timezone for city with
21
+ # biggest population.
22
+ #
23
+ # @param [String] city_name
24
+ #
25
+ # @return [String]
26
+ # Returns +"NilZone"+ when nothing was found.
27
+
28
+ def self.timezone_for_biggest(city_name)
29
+ tz = City.select(:timezone)
30
+ .where(city: city_name.downcase)
31
+ .reverse(:population)
32
+ .limit(1)
33
+ .join(:timezones, code: :timezone_code)
34
+ .first
35
+
36
+ tz ? tz[:timezone] : "NilZone"
37
+ end
38
+ end # class City
39
+ end # module CityUTC
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module CityUTC
4
+ # == Schema for `timezones` table
5
+ #
6
+ # CREATE TABLE `timezones` (
7
+ # `timezone` TEXT,
8
+ # `code` INTEGER,
9
+ # PRIMARY KEY(`code`)
10
+ # );
11
+ class Timezone < Sequel::Model
12
+ end # class Timezone
13
+ end # module CityUTC
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module CityUTC
4
+ # Dependencies from rubygems.org
5
+
6
+ require 'sinatra'
7
+ require 'timezone'
8
+ require 'sqlite3'
9
+ require 'sequel'
10
+
11
+ # Project structure loader
12
+
13
+ ##
14
+ # Loads *.rb files in requested order
15
+
16
+ def self.load(**params)
17
+ Array(params[:files]).each do |f|
18
+ require File.join __dir__, params[:folder].to_s, f
19
+ end
20
+ end
21
+ private_class_method :load
22
+
23
+ load files: %w(sqlite)
24
+
25
+ load folder: 'models',
26
+ files: %w(city timezone)
27
+
28
+ load files: %w(utc_time web_server)
29
+ end # module CityUTC
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module CityUTC
4
+ module Sqlite
5
+
6
+ def self.restore_database # no-doc
7
+ path_to_folder = File.join(__dir__, "..", "database")
8
+ path_to_archive = File.join(path_to_folder, 'sqlite.db.gz')
9
+
10
+ `gzip -d #{path_to_archive}`
11
+ end
12
+ private_class_method :restore_database
13
+
14
+ def self.restorable? # no-doc
15
+ archive = File.join(__dir__, '..', 'database', 'sqlite.db.gz')
16
+ database = File.join(__dir__, '..', 'database', 'sqlite.db')
17
+
18
+ File.exist?(archive) && !File.exist?(database)
19
+ end
20
+ private_class_method :restorable?
21
+
22
+ def self.connect_to_db # no-doc
23
+ path_to_database =
24
+ File.join(__dir__, '..', 'database', 'sqlite.db')
25
+
26
+ Sequel.connect "sqlite://#{path_to_database}"
27
+ end
28
+ private_class_method :connect_to_db
29
+
30
+ restore_database if restorable?
31
+ connect_to_db
32
+ end # module Sqlite
33
+ end # module CityUTC
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module CityUTC
4
+ module UTC_Time # no-doc
5
+
6
+ ##
7
+ # Returns UTC time for +city_name+.
8
+ #
9
+ # @param [String] city_name
10
+ #
11
+ # @return [String]
12
+ # Pretty formatted Universal Time (UTC) for recognized city.
13
+ # when city unrecognized it returns 'UNKNOWN'.
14
+
15
+ def self.for_city(city_name)
16
+ time_zone = City.timezone_for_biggest(city_name)
17
+
18
+ if (tz = ::Timezone[time_zone]).is_a? ::Timezone::NilZone
19
+ return "UNKNOWN"
20
+ else
21
+ utc_time = tz.utc_to_local(Time.now)
22
+
23
+ return UTC_Time.pretty_formatted(utc_time, city_name)
24
+ end
25
+ end
26
+
27
+ ##
28
+ # Presents time instance as pretty formatted string.
29
+ #
30
+ # @example
31
+ # time # ==> 2017-01-13 12:37:34 UTC
32
+ # formatted(time) # ==> "UTC: 2017-01-13 12:37:34"
33
+ #
34
+ # @param [Time] time
35
+ #
36
+ # @param [String] prefix
37
+ # Overrides +UTC+ prefix when used.
38
+ #
39
+ # @return [String]
40
+
41
+ def self.pretty_formatted(time, prefix = nil)
42
+ time = time.utc unless time.utc?
43
+
44
+ if prefix
45
+ return time.strftime "#{prefix}: %Y-%m-%d %H:%M:%S"
46
+ else
47
+ return time.strftime "%Z: %Y-%m-%d %H:%M:%S"
48
+ end
49
+ end
50
+ end # module UTC_Time
51
+ end # module CityUTC
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ module CityUTC
4
+ class WebServer < Sinatra::Base # no-doc
5
+ get "/time" do # no-doc
6
+ plain_text = CityUTC::UTC_Time.pretty_formatted(Time.now)
7
+
8
+ cities =
9
+ if request.params.empty?
10
+ []
11
+ else
12
+ request.params.keys.first.split(',')
13
+ end
14
+
15
+ cities.each { |city| plain_text += "\n#{UTC_Time.for_city(city)}" }
16
+
17
+ body plain_text
18
+ status 200 # OK
19
+ end
20
+
21
+ get /.*/ do # no-doc
22
+ plain_text =
23
+ "Please use get http request for 'time' api endpoint," \
24
+ " examples: '/time?Moscow,New%20York', '/time', '/time?Pskov' and so on."
25
+
26
+ body plain_text
27
+ status 400 # Bad request
28
+ end
29
+ end # class WebServer
30
+ end # module CityUTC
Binary file
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe "As database." do
5
+ it 'it creates valid Sequel::Model relation for Cities table' do
6
+ cities = CityUTC::City
7
+
8
+ expect(cities.count).to be > 0
9
+ expect(cities.select(:city, :population)
10
+ .reverse(:population)
11
+ .limit(3)
12
+ .to_a.collect(&:city)
13
+ ).to contain_exactly "tokyo", "shanghai", "bombay"
14
+ end
15
+ end # describe "As database."
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'net/http'
4
+
5
+ # To pass this tests launch the server!
6
+ # TODO add rspec helper to check server state and launch up when s isn't started
7
+ describe "As Web Server." do
8
+ context 'When client sends valid request' do
9
+ it 'returns time' do
10
+ uri = URI('http://127.0.0.1/time?')
11
+ uri.port = 30042
12
+
13
+ http = Net::HTTP.start(uri.host, uri.port)
14
+ request = Net::HTTP::Get.new uri
15
+ response = http.request request
16
+
17
+ expect(response.body).to match /UTC:\s\d*-\d*-\d* \d*:\d*/
18
+ end
19
+
20
+ it 'returns time for each param for request with optional queries' do
21
+ url = 'http://127.0.0.1/time?Moscow,New%20York,vladivostok,' \
22
+ 'berlin,washington,ufa'
23
+
24
+ uri = URI(url)
25
+ uri.port = 30042
26
+
27
+ http = Net::HTTP.start(uri.host, uri.port)
28
+ request = Net::HTTP::Get.new uri
29
+ response = http.request request
30
+
31
+ (response.body).split("\n").each do |line|
32
+ expect(line).to match /\w*:\s\d*-\d*-\d* \d*:\d*/
33
+ end
34
+ end
35
+
36
+ it 'returns an +UNKNOWN+ for city with unknown coordinates' do
37
+ uri = URI('http://127.0.0.1/time?this_this_never_exists')
38
+ uri.port = 30042
39
+
40
+ http = Net::HTTP.start(uri.host, uri.port)
41
+ request = Net::HTTP::Get.new uri
42
+ response = http.request request
43
+
44
+ expect(response.body).to match /UNKNOWN/
45
+ end
46
+ end # context 'valid request'
47
+
48
+ # ----------------------------------------------------
49
+
50
+ context 'When client sends invalid request' do
51
+ it 'returns an error message' do
52
+ uri = URI('http://127.0.0.1/smdfasf?')
53
+ uri.port = 30042
54
+
55
+ http = Net::HTTP.start(uri.host, uri.port)
56
+ request = Net::HTTP::Get.new uri
57
+ response = http.request request
58
+
59
+ expect(response.body)
60
+ .to match /Please use get http request for 'time' api endpoint/
61
+ end
62
+ end # context 'invalid request'
63
+ end # describe "As Web Server. When client sends"
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require 'webmock/rspec'
3
+
4
+ require_relative '../sources/city_utc'
5
+
6
+ RSpec.configure do |config|
7
+ # Internet connection locked, localhost connections still allowed
8
+ WebMock.disable_net_connect! allow_localhost: true
9
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ module CityUTC
5
+ describe UTC_Time do
6
+ before :each do
7
+ local_time = Time.new(2015,04,11,13,30,50,"+03:00")
8
+ allow(Time).to receive(:now).and_return local_time
9
+ end
10
+
11
+ context '#by_location' do
12
+ it "returns +'UNKNOWN'+ when +:local_location+ unrecognized" do
13
+ expect(described_class.for_city('there_is_no_city_with_dat_name'))
14
+ .to be_eql "UNKNOWN"
15
+ end
16
+
17
+ # https://www.timeanddate.com/worldclock/converted.html?iso=20011129T1430&p1=179&p2=4305
18
+ it 'returns valid UTC time for New York' do
19
+ # Note: New York (US) UTC is -5, so it should be eql 05:30:50 UTC
20
+ #
21
+ # But Timezone gem so sweety it holds daylights (+/- 1 hour) time changes
22
+ # for us. Real New York UTC Time is 06:30:50.
23
+ expect(described_class.for_city('New York').to_s)
24
+ .to be_eql("New York: 2015-04-11 06:30:50")
25
+ end
26
+
27
+ it 'returns valid UTC time for Ufa' do
28
+ # UTC +05:00 from 10:30:50 UTC
29
+ expect(described_class.for_city('Ufa').to_s)
30
+ .to be_eql("Ufa: 2015-04-11 15:30:50")
31
+ end
32
+ end # context '#by_location'
33
+
34
+ # ----------------------------------------------------
35
+
36
+ context '#formatted' do
37
+ it 'presents time as expected(formatted string)' do
38
+ expect(described_class.pretty_formatted(Time.now.utc))
39
+ .to be_eql("UTC: 2015-04-11 10:30:50")
40
+ end
41
+
42
+ it 'overrides utc prefix when +location+ param is used' do
43
+ expect(described_class.pretty_formatted(Time.now.utc, "PREFIX"))
44
+ .to be_eql("PREFIX: 2015-04-11 10:30:50")
45
+ end
46
+ end # context '#formatted'
47
+ end # describe CityUTC
48
+ end # module CityUTC
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ desc 'Restores database'
4
+ task :restore_database! do
5
+ path_to_folder = File.join(__dir__, "..", "sources", "database")
6
+ path_to_database = File.join(path_to_folder, 'sqlite.db.gz')
7
+
8
+ Kernel.system "gzip -d #{path_to_database} #{path_to_folder}"
9
+ end
10
+
11
+ desc 'Compresses database'
12
+ task :compress_database! do
13
+ path_to_folder = File.join(__dir__, "..", "sources", "database")
14
+ path_to_database = File.join(path_to_folder, 'sqlite.db')
15
+
16
+ Kernel.system "gzip -k #{path_to_database} #{path_to_folder}"
17
+ end
data/tasks/server.rake ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ desc 'Launches web-server (CityUTC#WebServer)'
4
+ task :launch_web_server! do
5
+ settings = [
6
+ '--max-conns 2048',
7
+ '--address 127.0.0.1',
8
+ '--max-persistent-conns 1024',
9
+ '--threaded',
10
+ '--port 30042',
11
+ '--tag thin_CityUTC_WebServer_30042'
12
+ ].join(' ')
13
+ path_to_config = File.join(__dir__, "..", "server", "config.ru")
14
+
15
+ Kernel.system "thin #{settings} -R '#{path_to_config}' start"
16
+ end
17
+
18
+ # desc 'Shows status for web-server (CityUTC#WebServer)'
19
+ # task :status do
20
+ # end
21
+ #
22
+ # desc 'Terminates web-server (CityUTC#WebServer)'
23
+ # task :terminate_web_server! do
24
+ # end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+ desc "DEVELOPMENT ONLY !!! (Requests ruby >= 2.4.0" \
4
+ "Creates two csv files for later import into sqlite db. " \
5
+ "Original file can been downloaded by following link: " \
6
+ "http://download.maxmind.com/download/worldcities/worldcitiespop.txt.gz"
7
+ # Note for csv to sqlite.db converting 'DB Browser for SQLite' was used.
8
+ task :prepare_for_import_to_db do
9
+ require 'csv'
10
+ require 'nearest_time_zone' # TODO remove dependency with original csv database
11
+ require 'timezone'
12
+
13
+ origin_csv = File.join(__dir__, '..', 'tmp', 'worldcitiespop.txt')
14
+ timezone_mapping = Hash.new
15
+
16
+ zones = Timezone.names.sort_by &:to_s
17
+ zones.each_with_index { |zone, index| timezone_mapping[zone] = index }
18
+
19
+ list = []
20
+ CSV.foreach(origin_csv, encoding: 'iso-8859-1:utf-8', headers: true,
21
+ liberal_parsing: true) do |row|
22
+
23
+ city_name = row.fetch("City")
24
+ country = row.fetch("Country")
25
+ lat = row.fetch("Latitude").to_f.round(3)
26
+ lng = row.fetch("Longitude").to_f.round(3)
27
+ population = row.fetch("Population").to_i
28
+ timezone = NearestTimeZone.to(lat, lng)
29
+
30
+ list << [ city_name, country, lat, lng,
31
+ population, timezone_mapping[timezone] ]
32
+ end
33
+
34
+ path_to_mapping = File.join(__dir__, '..', 'tmp', 'timezones.csv')
35
+ CSV.open(path_to_mapping , "wb") do |csv|
36
+ csv << ["timezone", "code"]
37
+ timezone_mapping.each_pair { |key, value| csv << [key, value] }
38
+ end
39
+
40
+ path_to_new_csv = File.join(__dir__, '..', 'tmp', 'cities.csv')
41
+ CSV.open(path_to_new_csv, "wb") do |csv|
42
+ csv << ["city", "country", "latitude", "longitude", "population", "timezone_code"]
43
+ list.each { |row| csv << row }
44
+ end
45
+ end
metadata ADDED
@@ -0,0 +1,162 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: city_utc
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Kuzichev Michael
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-01-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thin
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.7.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.7'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.7.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: sinatra
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.4'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.4.7
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.4'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.4.7
53
+ - !ruby/object:Gem::Dependency
54
+ name: sqlite3
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '1.3'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 1.3.13
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '1.3'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 1.3.13
73
+ - !ruby/object:Gem::Dependency
74
+ name: sequel
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '4.42'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 4.42.1
83
+ type: :runtime
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.42'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 4.42.1
93
+ - !ruby/object:Gem::Dependency
94
+ name: timezone
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: '1.0'
100
+ type: :runtime
101
+ prerelease: false
102
+ version_requirements: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - "~>"
105
+ - !ruby/object:Gem::Version
106
+ version: '1.0'
107
+ description:
108
+ email: kMedvedu@gmail.com
109
+ executables: []
110
+ extensions: []
111
+ extra_rdoc_files: []
112
+ files:
113
+ - Gemfile
114
+ - LICENSE
115
+ - Rakefile
116
+ - server/config.ru
117
+ - sources/city_utc.rb
118
+ - sources/city_utc/models/city.rb
119
+ - sources/city_utc/models/timezone.rb
120
+ - sources/city_utc/project_structure.rb
121
+ - sources/city_utc/sqlite.rb
122
+ - sources/city_utc/utc_time.rb
123
+ - sources/city_utc/web_server.rb
124
+ - sources/database/sqlite.db.gz
125
+ - spec/integration/city_utc_db_spec.rb
126
+ - spec/integration/city_utc_web_spec.rb
127
+ - spec/spec_helper.rb
128
+ - spec/tserver/utc_time_spec.rb
129
+ - tasks/database.rake
130
+ - tasks/server.rake
131
+ - tasks/timezones_converter.rake
132
+ homepage: https://github.com/Medvedu/City-UTC
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message: Sqlite
137
+ rdoc_options: []
138
+ require_paths:
139
+ - sources
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '2.1'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.6.8
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: This project consist of two parts. First part includes sqlite database with
156
+ two tables (see Readme.md for details) with cities, coordinates and timezones. Second
157
+ part is thin (web) application for work with the database.
158
+ test_files:
159
+ - spec/tserver/utc_time_spec.rb
160
+ - spec/spec_helper.rb
161
+ - spec/integration/city_utc_db_spec.rb
162
+ - spec/integration/city_utc_web_spec.rb