shack_kit 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,11 @@
1
1
  require 'fileutils'
2
2
  require 'sqlite3'
3
3
  require 'sequel'
4
- require 'simple-spreadsheet'
4
+ require 'maidenhead'
5
+ require 'csv'
6
+ require 'yaml'
7
+ require 'http'
8
+ require 'oga'
5
9
 
6
10
  module ShackKit
7
11
  module Data
@@ -9,8 +13,11 @@ module ShackKit
9
13
  MIGRATIONS_DIR = ShackKit::GEM_ROOT + "/db/migrations"
10
14
  SOURCES_DIR = ShackKit::GEM_ROOT + "/db/sources"
11
15
  DB_FILE = DATA_DIR + "/shack_kit.db"
16
+ CONFIG_FILE = DATA_DIR + "/config.yml"
17
+ CONFIG = File.exists?(CONFIG_FILE) ? YAML.load(File.read(CONFIG_FILE)) : Hash.new.freeze
12
18
  DB = Sequel.sqlite(DB_FILE)
13
19
  CALLSIGN_REGEX = /\A([A-Z]{1,2}|[0-9][A-Z])([0-9])/
20
+ USER_AGENT = "Ruby-gem-shack_kit-#{ShackKit::VERSION}"
14
21
 
15
22
  class << self
16
23
  def db_setup
@@ -35,6 +42,9 @@ end
35
42
 
36
43
  ShackKit::Data.schema_update
37
44
 
45
+ require 'shack_kit/data/ham_qth'
46
+ require 'shack_kit/data/qrz'
47
+ require 'shack_kit/data/qrz_pl'
38
48
  require 'shack_kit/data/sota_calls'
39
49
  require 'shack_kit/data/sota_summits'
40
50
  require 'shack_kit/data/sp_calls'
@@ -0,0 +1,32 @@
1
+ module ShackKit
2
+ module Data
3
+ class HamQTH
4
+ attr_reader :session_key
5
+ QUERY_URL = 'https://www.hamqth.com/xml.php'
6
+
7
+ def initialize(params = {})
8
+ return false unless params[:login] && params[:password] || CONFIG && CONFIG.has_key?('ham_qth')
9
+ login = params[:login] || CONFIG['ham_qth']['login']
10
+ password = params[:password] || CONFIG['ham_qth']['password']
11
+ response = HTTP.get("#{QUERY_URL}?u=#{login}&p=#{password}")
12
+ parsed_response = Oga.parse_xml(response.to_s)
13
+ @session_key = parsed_response.xpath("HamQTH/session/session_id").text
14
+ puts parsed_response.xpath("HamQTH/session/error").text if @session_key.empty?
15
+ end
16
+
17
+ def lookup(callsign)
18
+ return { error: "Can't query HamQTH.com without submitting valid login credentials first" } if @session_key.nil? || @session_key.empty?
19
+ response = HTTP.get("#{QUERY_URL}?id=#{@session_key}&callsign=#{callsign}&prg=#{USER_AGENT}")
20
+ parsed_response = Oga.parse_xml(response.to_s)
21
+ return { error: parsed_response.xpath("HamQTH/session/error").text } if
22
+ parsed_response.xpath("HamQTH/search").text.empty?
23
+ attributes = parsed_response.xpath("HamQTH/search").first.children.select{ |c| c.class == Oga::XML::Element }.map(&:name)
24
+ {}.tap do |output|
25
+ attributes.each do |attribute|
26
+ output[attribute.to_sym] = parsed_response.xpath("HamQTH/search/#{attribute}").text
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ module ShackKit
2
+ module Data
3
+ class QRZ
4
+ attr_reader :session_key
5
+ QUERY_URL = 'https://xmldata.qrz.com/xml/current/'
6
+
7
+ def initialize(params = {})
8
+ return false unless params[:login] && params[:password] || CONFIG && CONFIG.has_key?('qrz_com')
9
+ login = params[:login] || CONFIG['qrz_com']['login']
10
+ password = params[:password] || CONFIG['qrz_com']['password']
11
+ response = HTTP.post(QUERY_URL, form: { username: login, password: password, agent: USER_AGENT })
12
+ parsed_response = Oga.parse_xml(response.to_s)
13
+ @session_key = parsed_response.xpath("QRZDatabase/Session/Key").text
14
+ puts parsed_response.xpath("QRZDatabase/Session/Error").text if @session_key.empty?
15
+ end
16
+
17
+ def lookup(callsign)
18
+ return { error: "Can't query qrz.com, use valid login credentials to get access" } if @session_key.nil? || @session_key.empty?
19
+ response = HTTP.post(QUERY_URL, form: { s: @session_key, callsign: callsign })
20
+ parsed_response = Oga.parse_xml(response.to_s)
21
+ return { error: parsed_response.xpath("QRZDatabase/Session/Error").text } if
22
+ parsed_response.xpath("QRZDatabase/Callsign").text.empty?
23
+ attributes = parsed_response.xpath("QRZDatabase/Callsign").first.children.select{ |c| c.class == Oga::XML::Element }.map(&:name)
24
+ {}.tap do |output|
25
+ attributes.each do |attribute|
26
+ output[attribute.to_sym] = parsed_response.xpath("QRZDatabase/Callsign/#{attribute}").text
27
+ end
28
+ output[:message] = parsed_response.xpath('QRZDatabase/Session/Message').text
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ module ShackKit
2
+ module Data
3
+ class QRZ_PL
4
+ QUERY_URL = "http://qrz.pl/callbook.asp"
5
+
6
+ def self.lookup(callsign)
7
+ response = HTTP.post("http://qrz.pl/callbook.asp", form: { "F_DOMENA": callsign })
8
+ document = Oga.parse_html(response.to_s)
9
+ return { error: "Not found: #{callsign}"} unless
10
+ document.xpath('//span[contains(@class, "znak")]').text == callsign
11
+ details = document.xpath('//span[contains(@class, "dane")]').map(&:text)
12
+ { callsign: callsign, details: details, grid: grid_lookup(details) }
13
+ end
14
+
15
+ private
16
+
17
+ def self.grid_lookup(details)
18
+ return nil unless grid_info = details.select{ |d| d =~ /^LOKATOR\: [A-Z]{2}\d{2}/}.first
19
+ grid_info.split.last
20
+ end
21
+ end
22
+ end
23
+ end
@@ -4,33 +4,35 @@ module ShackKit
4
4
  def self.update(source_file = SOURCES_DIR + "/summitslist.csv")
5
5
  summits = DB[:sota_summits]
6
6
  summits.delete
7
- csv = SimpleSpreadsheet::Workbook.read(source_file, ".csv")
8
- 3.upto(csv.last_row) do |line|
7
+ CSV.foreach(source_file, headers: true, skip_lines: /SOTA Summits List/) do |row|
9
8
  summits.insert(
10
- summit_code: csv.cell(line, 1),
11
- association_name: csv.cell(line, 2),
12
- region_name: csv.cell(line, 3),
13
- summit_name: csv.cell(line, 4),
14
- alt_m: csv.cell(line, 5).to_i,
15
- alt_ft: csv.cell(line, 6).to_i,
16
- grid_ref1: csv.cell(line, 7),
17
- grid_ref2: csv.cell(line, 8),
18
- longitude: csv.cell(line, 9).to_f,
19
- latitude: csv.cell(line, 10).to_f,
20
- points: csv.cell(line, 11).to_i,
21
- bonus_points: csv.cell(line, 12).to_i,
22
- valid_from: Date.parse(csv.cell(line, 13)),
23
- valid_to: Date.parse(csv.cell(line, 14)),
24
- activation_count: csv.cell(line, 15).to_i,
25
- activation_date: csv.cell(line, 16).nil? ? nil : Date.parse(csv.cell(line, 16)),
26
- activation_call: csv.cell(line, 17)
9
+ summit_code: row["SummitCode"],
10
+ association_name: row["AssociationName"],
11
+ region_name: row["RegionName"],
12
+ summit_name: row["SummitName"],
13
+ alt_m: row["AltM"].to_i,
14
+ alt_ft: row["AltFt"].to_i,
15
+ grid_ref1: row["GridRef1"],
16
+ grid_ref2: row["GridRef2"],
17
+ longitude: row["Longitude"].to_f,
18
+ latitude: row["Latitude"].to_f,
19
+ points: row["Points"].to_i,
20
+ bonus_points: row["BonusPoints"].to_i,
21
+ valid_from: Date.parse(row["ValidFrom"]),
22
+ valid_to: Date.parse(row["ValidTo"]),
23
+ activation_count: row["ActivationCount"].to_i,
24
+ activation_date: row["ActivationDate"].nil? ? nil : Date.parse(row["ActivationDate"]),
25
+ activation_call: row["ActivationCall"]
27
26
  )
28
27
  end
29
28
  summits.count
30
29
  end
31
30
 
32
31
  def self.check(reference)
33
- DB[:sota_summits].where(summit_code: reference).first
32
+ summit = DB[:sota_summits].where(summit_code: reference).first
33
+ return false if summit.nil?
34
+ locator = Maidenhead.to_maidenhead(summit[:latitude], summit[:longitude], 3)
35
+ summit.merge(maidenhead_locator: locator)
34
36
  end
35
37
  end
36
38
  end
@@ -5,8 +5,8 @@ module ShackKit
5
5
  sources = [source_file] + other_source_files
6
6
  calls = DB[:sp_calls]
7
7
  calls.delete
8
- sources.each do |source_file|
9
- CSV.foreach(source_file, col_sep: ";", encoding: "Windows-1250:UTF-8", headers: true) do |row|
8
+ sources.each do |source|
9
+ CSV.foreach(source, col_sep: ";", encoding: "Windows-1250:UTF-8", headers: true) do |row|
10
10
  individual = row["operator_1"].nil?
11
11
  calls.insert(
12
12
  callsign: row["call_sign"],
@@ -1,3 +1,3 @@
1
1
  module ShackKit
2
- VERSION = "0.1.2"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shack_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcin Bajer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-04-01 00:00:00.000000000 Z
11
+ date: 2016-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -107,25 +107,65 @@ dependencies:
107
107
  - !ruby/object:Gem::Version
108
108
  version: '4.28'
109
109
  - !ruby/object:Gem::Dependency
110
- name: simple-spreadsheet
110
+ name: maidenhead
111
111
  requirement: !ruby/object:Gem::Requirement
112
112
  requirements:
113
113
  - - "~>"
114
114
  - !ruby/object:Gem::Version
115
- version: '0.4'
115
+ version: '1.0'
116
116
  - - ">="
117
117
  - !ruby/object:Gem::Version
118
- version: 0.4.1
118
+ version: 1.0.1
119
119
  type: :runtime
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '0.4'
125
+ version: '1.0'
126
126
  - - ">="
127
127
  - !ruby/object:Gem::Version
128
- version: 0.4.1
128
+ version: 1.0.1
129
+ - !ruby/object:Gem::Dependency
130
+ name: oga
131
+ requirement: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: '2.3'
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '2.3'
139
+ type: :runtime
140
+ prerelease: false
141
+ version_requirements: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '2.3'
146
+ - - ">="
147
+ - !ruby/object:Gem::Version
148
+ version: '2.3'
149
+ - !ruby/object:Gem::Dependency
150
+ name: http
151
+ requirement: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - "~>"
154
+ - !ruby/object:Gem::Version
155
+ version: '2.0'
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: 2.0.3
159
+ type: :runtime
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '2.0'
166
+ - - ">="
167
+ - !ruby/object:Gem::Version
168
+ version: 2.0.3
129
169
  description: Set of HAM radio tools, currently limited to SP and SOTA-related stuff
130
170
  email:
131
171
  - bajer@tigana.pl
@@ -133,32 +173,27 @@ executables: []
133
173
  extensions: []
134
174
  extra_rdoc_files: []
135
175
  files:
136
- - ".gitignore"
137
- - ".ruby-gemset"
138
- - ".ruby-version"
139
- - ".travis.yml"
140
176
  - CHANGELOG.md
141
- - Gemfile
142
177
  - LICENSE.txt
143
178
  - README.md
144
- - Rakefile
145
179
  - bin/console
146
180
  - bin/setup
147
181
  - db/migrations/001_create_sota_calls.rb
148
182
  - db/migrations/002_create_sp_calls.rb
149
183
  - db/migrations/003_create_sota_summits.rb
150
- - db/sources/201511 - RA2WWW_ok.xls
151
- - db/sources/clubs_2016-04-01.csv
152
- - db/sources/individuals_2016-04-01.csv
184
+ - db/sources/clubs_2016-08-25.csv
185
+ - db/sources/individuals_2016-08-25.csv
153
186
  - db/sources/masterSOTA.scp
154
187
  - db/sources/summitslist.csv
155
188
  - lib/shack_kit.rb
156
189
  - lib/shack_kit/data/base.rb
190
+ - lib/shack_kit/data/ham_qth.rb
191
+ - lib/shack_kit/data/qrz.rb
192
+ - lib/shack_kit/data/qrz_pl.rb
157
193
  - lib/shack_kit/data/sota_calls.rb
158
194
  - lib/shack_kit/data/sota_summits.rb
159
195
  - lib/shack_kit/data/sp_calls.rb
160
196
  - lib/shack_kit/version.rb
161
- - shack_kit.gemspec
162
197
  homepage: https://github.com/rrrodrigo/shack_kit
163
198
  licenses:
164
199
  - MIT
@@ -180,7 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
215
  version: '0'
181
216
  requirements: []
182
217
  rubyforge_project:
183
- rubygems_version: 2.4.6
218
+ rubygems_version: 2.5.1
184
219
  signing_key:
185
220
  specification_version: 4
186
221
  summary: Set of HAM radio tools packaged by SQ9OZM
data/.gitignore DELETED
@@ -1,10 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- *.gem
data/.ruby-gemset DELETED
@@ -1 +0,0 @@
1
- shack-kit
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 2.2
data/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.3
4
- before_install: gem install bundler -v 1.10.6
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in shack_kit.gemspec
4
- gemspec
data/Rakefile DELETED
@@ -1,10 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList['test/**/*_test.rb']
8
- end
9
-
10
- task :default => :test
Binary file