-
Notifications
You must be signed in to change notification settings - Fork 0
/
qrz.rb
84 lines (73 loc) · 2.19 KB
/
qrz.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
require 'cgi'
require 'net/http'
require 'uri'
class Qrz
AGENT = "https://ragchew.app"
BASE_URL = "https://xmldata.qrz.com/xml/current/"
class Error < StandardError; end
class NotFound < Error; end
class WrongUsernamePassword < Error; end
class SessionTimeout < Error; end
def initialize(session:)
@session = session
end
attr_reader :session
def lookup(call_sign)
result = self.class.call(s: @session, callsign: call_sign)
if result =~ /<Error>(.*?)<\/Error>/
message = $1.strip
case message
when /^not found/i
raise NotFound, message
when /session timeout/i
raise SessionTimeout, message
else
raise Error, message
end
else
parse_result(result)
end
end
def self.login(username:, password:)
result = call(username:, password:)
if result =~ /<Error>(.*?)<\/Error>/m
message = $1.strip
if message.downcase == 'username/password incorrect'
raise WrongUsernamePassword, message
else
raise Error, message
end
elsif result =~ /<Key>([A-Fa-f0-9]+)<\/Key>/
new(session: $1)
else
raise Error, "unknown error occurred: #{result}"
end
end
def self.call(**params)
params.merge!(agent: AGENT)
params_string = params.map { |k, v| "#{k}=#{CGI.escapeURIComponent(v)}" }.join(';')
url = "#{BASE_URL}?#{params_string}"
puts "GET #{url}"
Net::HTTP.get(URI(url))
end
private
def parse_result(result)
station = Nokogiri::XML(result).at_css('Callsign')
call_sign = station&.at_css('call')&.content
raise Error, "unknown error occurred: #{result}" unless call_sign
{
call_sign:,
first_name: station.at_css('fname')&.content,
last_name: station.at_css('name')&.content,
image: station.at_css('image')&.content,
grid_square: station.at_css('grid')&.content,
street: station.at_css('addr1')&.content,
city: station.at_css('addr2')&.content,
state: station.at_css('state')&.content,
zip: station.at_css('zip')&.content,
county: station.at_css('county')&.content,
country: station.at_css('country')&.content,
dxcc: station.at_css('dxcc')&.content,
}
end
end