un_locode 0.0.1

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/data/db.rb ADDED
@@ -0,0 +1,32 @@
1
+ require_relative 'schema.rb'
2
+
3
+ module UnLocode
4
+ class DB
5
+ def initialize(name = 'db.sqlite')
6
+ @database_name = File.expand_path(name.downcase, File.dirname(__FILE__))
7
+ end
8
+
9
+ def reset
10
+ File.delete(@database_name) if File.exists?(@database_name)
11
+ connect_to_db
12
+ Schema.new.change
13
+ end
14
+
15
+ def connect_to_db
16
+ ActiveRecord::Base.configurations.merge!(config)
17
+
18
+ @connection ||= ActiveRecord::Base.establish_connection('un_locode')
19
+ end
20
+
21
+ private
22
+
23
+ def config
24
+ {
25
+ 'un_locode' => {
26
+ 'adapter' => 'sqlite3',
27
+ 'database' => @database_name
28
+ }
29
+ }
30
+ end
31
+ end
32
+ end
data/data/db.sqlite ADDED
Binary file
@@ -0,0 +1,106 @@
1
+ require 'csv'
2
+ require 'pry'
3
+ require 'yaml'
4
+ require_relative 'db'
5
+ require_relative '../lib/un_locode'
6
+
7
+ class LocodeDataUpdate
8
+
9
+ def self.parse
10
+ UnLocode::DB.new.reset
11
+ parse_locodes
12
+ end
13
+
14
+ private
15
+
16
+ def self.parse_locodes
17
+ Dir.glob('./data/csv/*.csv') do |file|
18
+ CSV.parse(File.open(file, 'r:ISO-8859-1')) do |row|
19
+ if country_row?(row)
20
+ parse_country(row)
21
+ else locode_row?(row)
22
+ parse_locode(row)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.parse_country row
29
+ country_code = row[1]
30
+ country_name = row[3].gsub('.', '')
31
+
32
+ UnLocode::Country.create(code: country_code, name: country_name)
33
+ end
34
+
35
+ # sample input: "--34-6--"
36
+ def self.parse_function_attributes str_function
37
+ function_array = str_function.split(//)
38
+ {
39
+ port: function_array[0] == '1',
40
+ rail_terminal: function_array[1] == '2',
41
+ road_terminal: function_array[2] == '3',
42
+ airport: function_array[3] == '4',
43
+ postal_exchange_office: function_array[4] == '5',
44
+ inland_clearance_depot: function_array[5] == '6',
45
+ fixed_transport_functions: function_array[6] == '7',
46
+ border_crossing_function: function_array[7].try(:upcase) == 'B'
47
+ }
48
+ end
49
+
50
+ def self.parse_name_attr name, name_wo_diacritics
51
+ {
52
+ name: name.strip,
53
+ name_wo_diacritics: name_wo_diacritics.strip,
54
+ }
55
+ end
56
+
57
+ #As a service to users, names that have been changed may be included for reference. Such alternative
58
+ #name versions are included as a transitional measure after a name change; they are followed by an
59
+ #equal sign (=), e.g.:
60
+ #
61
+ #Peking = Beijing
62
+ #Leningrad = St Petersburg
63
+ #
64
+ #The code element will be shown only under the new name.
65
+ def self.parse_name_attr_with_alternatives name, name_wo_diacritics
66
+ {
67
+ name: name.split('=').last.strip,
68
+ name_wo_diacritics: name_wo_diacritics.split('=').last.strip,
69
+ alternative_name: name.split('=').first.strip,
70
+ alternative_name_wo_diacritics: name_wo_diacritics.split('=').first.strip
71
+ }
72
+ end
73
+
74
+ def self.has_alternatives? changes
75
+ changes == '='
76
+ end
77
+
78
+ def self.parse_locode row
79
+ country = UnLocode::Country.find_by_code(row[1])
80
+ function_attr = parse_function_attributes(row[6])
81
+ name_attr = has_alternatives?(row[0]) ? parse_name_attr_with_alternatives(row[3], row[4]) : parse_name_attr(row[3], row[4])
82
+
83
+ location_attributes = {
84
+ change_marker: row[0],
85
+ country: country,
86
+ city_code: row[2],
87
+ sub_div: row[5],
88
+ status: row[7],
89
+ date: row[8],
90
+ iata: row[9],
91
+ coordinates: row[10],
92
+ remarks: row[11]
93
+ }
94
+ location_attributes.merge!(function_attr).merge!(name_attr)
95
+
96
+ UnLocode::Locode.create(location_attributes)
97
+ end
98
+
99
+ def self.country_row?(row)
100
+ !!row[1] && !!row[3] && row[3][0] == '.'
101
+ end
102
+
103
+ def self.locode_row?(row)
104
+ !row[2].nil?
105
+ end
106
+ end
data/data/schema.rb ADDED
@@ -0,0 +1,36 @@
1
+ class Schema < ActiveRecord::Migration
2
+
3
+ def change
4
+ create_table :countries do |t|
5
+ t.string :code
6
+ t.string :name
7
+ end
8
+
9
+ create_table :locodes do |t|
10
+ t.string :change_marker
11
+ t.integer :country_id
12
+ t.string :city_code
13
+ t.string :name
14
+ t.string :name_wo_diacritics
15
+ t.string :alternative_name
16
+ t.string :alternative_name_wo_diacritics
17
+ t.string :sub_div
18
+ t.boolean :port
19
+ t.boolean :rail_terminal
20
+ t.boolean :road_terminal
21
+ t.boolean :airport
22
+ t.boolean :postal_exchange_office
23
+ t.boolean :inland_clearance_depot
24
+ t.boolean :fixed_transport_functions
25
+ t.boolean :border_crossing_function
26
+ t.string :status
27
+ t.date :date
28
+ t.string :iata
29
+ t.string :coordinates
30
+ t.string :remarks
31
+ end
32
+
33
+ add_index(:locodes, [:country_id, :city_code, :change_marker])
34
+ end
35
+ end
36
+
data/debug.log ADDED
@@ -0,0 +1,4 @@
1
+ # Logfile created on 2013-11-12 14:10:48 +0100 by logger.rb/36483
2
+ D, [2013-11-12T14:18:24.946578 #12430] DEBUG -- :  (1.1ms) CREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "country_code" varchar(255)) 
3
+ D, [2013-11-12T14:18:24.948119 #12430] DEBUG -- :  (0.9ms) CREATE TABLE "cities" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "city_code" varchar(255), "full_name" varchar(255), "full_name_without_diacritics" varchar(255), "subdivision" varchar(255), "function_classifier" varchar(255), "status" varchar(255), "date" date, "iata_code" varchar(255), "coordinates" varchar(255), "country_id" integer)
4
+ D, [2013-11-12T14:18:24.949447 #12430] DEBUG -- :  (0.8ms) CREATE TABLE "functions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "funciton_id" varchar(255)) 
data/lib/.DS_Store ADDED
Binary file
Binary file
@@ -0,0 +1,6 @@
1
+ module UnLocode
2
+ class BaseRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ establish_connection 'un_locode'
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ module UnLocode
2
+ class Country < BaseRecord
3
+ has_many :locodes
4
+
5
+ def as_json options = {}
6
+ super options.merge(except: [:id])
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ module UnLocode
2
+ FUNCTIONS = [:port,
3
+ :rail_terminal,
4
+ :road_terminal,
5
+ :airport,
6
+ :postal_exchange_office,
7
+ :inland_clearance_depot,
8
+ :fixed_transport_functions,
9
+ :border_crossing_function].freeze
10
+
11
+ class Locode < BaseRecord
12
+ belongs_to :country
13
+
14
+ def self.find_by_fuzzy_name name, limit = 10
15
+ where('name like ? or
16
+ name_wo_diacritics like ? or
17
+ alternative_name like ? or
18
+ alternative_name_wo_diacritics like ?',
19
+ "%#{name}%", "%#{name}%", "%#{name}%", "%#{name}%").limit(limit)
20
+ end
21
+
22
+ def self.find_by_name_and_function name, function, limit = 10
23
+ raise "Unsupported Locode Function! Should be one of #{UnLocode::FUNCTIONS.join(' ')}." unless UnLocode::FUNCTIONS.include?(function)
24
+ find_by_fuzzy_name(name).where(function => true).limit(limit)
25
+ end
26
+
27
+ def as_json options = {}
28
+ super(options.merge!(except: [:id, :country_id])).merge('country' => country.as_json)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,3 @@
1
+ module UnLocode
2
+ VERSION = "0.0.1"
3
+ end
data/lib/un_locode.rb ADDED
@@ -0,0 +1,11 @@
1
+ require 'active_record'
2
+ require_relative '../data/db'
3
+
4
+ module UnLocode
5
+ UnLocode::DB.new().connect_to_db unless ENV['ENV'] == 'test'
6
+ end
7
+
8
+ require 'un_locode/base_record'
9
+ require 'un_locode/version'
10
+ require 'un_locode/country'
11
+ require 'un_locode/locode'
@@ -0,0 +1,30 @@
1
+ ENV['ENV'] ||= 'test'
2
+
3
+ require 'pry'
4
+ require 'active_record'
5
+ require_relative '../data/db'
6
+
7
+ db = UnLocode::DB.new('../tmp/test_db.sqlite')
8
+ db.reset
9
+
10
+ # This file was generated by the `rspec --init` command. Conventionally, all
11
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
12
+ # Require this file using `require "spec_helper"` to ensure that it is only
13
+ # loaded once.
14
+ #
15
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
+ RSpec.configure do |config|
17
+ config.treat_symbols_as_metadata_keys_with_true_values = true
18
+ config.run_all_when_everything_filtered = true
19
+ config.filter_run :focus
20
+
21
+ # Run specs in random order to surface order dependencies. If you find an
22
+ # order dependency and want to debug it, you can fix the order by providing
23
+ # the seed, which is printed after each run.
24
+ # --seed 1234
25
+ config.order = 'random'
26
+
27
+ config.after(:each) do
28
+ UnLocode::Locode.destroy_all
29
+ end
30
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require 'un_locode'
3
+
4
+ describe UnLocode::Locode do
5
+
6
+ describe 'scopes' do
7
+
8
+ describe 'retrieving locodes by name' do
9
+
10
+ let!(:city) { UnLocode::Locode.create(name: 'Eindhoven', name_wo_diacritics: 'Eeindhoven') }
11
+ let!(:other_city) { UnLocode::Locode.create(name: 'Weert') }
12
+
13
+ subject { UnLocode::Locode.find_by_fuzzy_name(search_term) }
14
+
15
+ context 'exact match' do
16
+ let(:search_term) { city.name }
17
+ its(:first) { should eql(city) }
18
+ its(:count) { should eql(1) }
19
+ end
20
+
21
+ context 'fuzzy match' do
22
+ let(:search_term) { city.name[1..4] }
23
+ its(:first) { should eql(city) }
24
+ its(:count) { should eql(1) }
25
+ end
26
+
27
+ [:name, :name_wo_diacritics, :alternative_name, :alternative_name_wo_diacritics].each do |attr|
28
+ context "matches against the #{attr} name fields" do
29
+ let!(:city) { UnLocode::Locode.create(attr => 'Eindhoven') }
30
+ let(:search_term) { 'Eindhoven' }
31
+ its(:first) { should eql(city) }
32
+ its(:count) { should eql(1) }
33
+ end
34
+ end
35
+
36
+ context 'case insensitive names' do
37
+ let(:search_term) { city.name.downcase }
38
+
39
+ its(:first) { should eql(city) }
40
+ its(:count) { should eql(1) }
41
+ end
42
+
43
+ end
44
+
45
+ context 'retrieving locodes by name and function' do
46
+ let!(:port) { UnLocode::Locode.create(name: 'Eindhoven', port: true) }
47
+ let!(:rail_terminal) { UnLocode::Locode.create(name: 'Eindhoven', rail_terminal: true) }
48
+
49
+ context 'with supported functions' do
50
+ subject { UnLocode::Locode.find_by_name_and_function(search_term, :port) }
51
+ let(:search_term) { port.name }
52
+
53
+ its(:first) { should eql(port) }
54
+ its(:count) { should eql(1) }
55
+ end
56
+
57
+ context 'with unsupported function' do
58
+ it 'raises an error' do
59
+ expect { UnLocode::Locode.find_by_name_and_function(search_term, :derp) }.to raise_error
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ describe 'as_json' do
66
+ let!(:country) { UnLocode::Country.create name: 'Belgium', code: 'BE' }
67
+ let!(:location) { UnLocode::Locode.create name: 'Eindhoven', port: true, country: country }
68
+
69
+ subject { location.as_json }
70
+
71
+ its(['country']) { should eql({'code' => 'BE', 'name' => 'Belgium'}) }
72
+ it { should_not have_key('country_id') }
73
+ it { should_not have_key('id') }
74
+ end
75
+ end
76
+
data/un_locode.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'un_locode/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'un_locode'
8
+ spec.version = UnLocode::VERSION
9
+ spec.authors = ['Michel de Graaf', 'Rui Salgado', 'Niels Stevens']
10
+ spec.email = ['michel@kabisa.nl', 'rui.salgado@kabisa.nl', 'niels@kabisa.nl']
11
+ spec.description = %q{The Locode gem gives you the ability to lookup UN/LOCODE codes.}
12
+ spec.summary = %q{The Locode gem gives you the ability to lookup UN/LOCODE codes.}
13
+ spec.homepage = 'https://github.com/kabisaict/un_locode'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.3.5'
22
+ spec.add_development_dependency 'rake', '~> 10.1.0'
23
+ spec.add_development_dependency 'rspec', '~> 2.14.1'
24
+ spec.add_development_dependency 'pry', '~> 0.9.12.3'
25
+ spec.add_development_dependency 'rspec', '~> 2.14.1'
26
+ spec.add_dependency 'activerecord', '~> 4.0.0'
27
+ spec.add_dependency 'sqlite3', '~> 1.3.8'
28
+ end
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: un_locode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michel de Graaf
8
+ - Rui Salgado
9
+ - Niels Stevens
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-11-27 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.3.5
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ version: 1.3.5
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: 10.1.0
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ version: 10.1.0
43
+ - !ruby/object:Gem::Dependency
44
+ name: rspec
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ~>
48
+ - !ruby/object:Gem::Version
49
+ version: 2.14.1
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 2.14.1
57
+ - !ruby/object:Gem::Dependency
58
+ name: pry
59
+ requirement: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ~>
62
+ - !ruby/object:Gem::Version
63
+ version: 0.9.12.3
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: 0.9.12.3
71
+ - !ruby/object:Gem::Dependency
72
+ name: rspec
73
+ requirement: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.14.1
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ~>
83
+ - !ruby/object:Gem::Version
84
+ version: 2.14.1
85
+ - !ruby/object:Gem::Dependency
86
+ name: activerecord
87
+ requirement: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ version: 4.0.0
92
+ type: :runtime
93
+ prerelease: false
94
+ version_requirements: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ~>
97
+ - !ruby/object:Gem::Version
98
+ version: 4.0.0
99
+ - !ruby/object:Gem::Dependency
100
+ name: sqlite3
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ~>
104
+ - !ruby/object:Gem::Version
105
+ version: 1.3.8
106
+ type: :runtime
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ~>
111
+ - !ruby/object:Gem::Version
112
+ version: 1.3.8
113
+ description: The Locode gem gives you the ability to lookup UN/LOCODE codes.
114
+ email:
115
+ - michel@kabisa.nl
116
+ - rui.salgado@kabisa.nl
117
+ - niels@kabisa.nl
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - .DS_Store
123
+ - .gitignore
124
+ - .rspec
125
+ - .ruby-version
126
+ - Gemfile
127
+ - LICENSE.txt
128
+ - README.md
129
+ - Rakefile
130
+ - data/csv/2013-1 UNLOCODE CodeListPart1.csv
131
+ - data/csv/2013-1 UNLOCODE CodeListPart2.csv
132
+ - data/csv/2013-1 UNLOCODE CodeListPart3.csv
133
+ - data/db.rb
134
+ - data/db.sqlite
135
+ - data/locode_data_update.rb
136
+ - data/schema.rb
137
+ - debug.log
138
+ - lib/.DS_Store
139
+ - lib/un_locode.rb
140
+ - lib/un_locode/.DS_Store
141
+ - lib/un_locode/base_record.rb
142
+ - lib/un_locode/country.rb
143
+ - lib/un_locode/locode.rb
144
+ - lib/un_locode/version.rb
145
+ - spec/spec_helper.rb
146
+ - spec/un_locode_spec.rb
147
+ - un_locode.gemspec
148
+ homepage: https://github.com/kabisaict/un_locode
149
+ licenses:
150
+ - MIT
151
+ metadata: {}
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubyforge_project:
168
+ rubygems_version: 2.0.6
169
+ signing_key:
170
+ specification_version: 4
171
+ summary: The Locode gem gives you the ability to lookup UN/LOCODE codes.
172
+ test_files:
173
+ - spec/spec_helper.rb
174
+ - spec/un_locode_spec.rb
175
+ has_rdoc: