-
Notifications
You must be signed in to change notification settings - Fork 0
/
code.rb
76 lines (67 loc) · 2.43 KB
/
code.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
require 'open-uri'
require 'nokogiri'
require_relative 'exceptions'
def scrape_page (
url = 'http://www.marinetraffic.com/en/ais/details/ships/shipid:4199684/mmsi:244670249/vessel:STORMALONG'
)
open(url)
end
def find_string (
opened_url = scrape_page,
css_selector = '.details_data_link'
)
if opened_url.nil?
raise RetryException.new(true), "Transient read error"
end
# no need to break this one into smaller methods
# bc we test the interface, not the implementation
Nokogiri::HTML(opened_url).css(css_selector)[0].children.text
end
def find_array (
string = find_string,
divider = '/'
)
# no need to break the 2 methods
string.gsub(/[\ °]/,"").split(divider)
end
def find_lat_lng (
clean_string_array = find_array
)
lat_lng_float = clean_string_array.map(&:to_f) # shorter way to write it
# These cases are not rescued, bc they are not proper Ruby errors. We just print
# a custom message instead of wrong lat/lng numbers.
# Ideally we should define and raise custom errors in these cases instead of
# simply printing strings. An idea for the next refactoring :)
case
# in this case we are ~almost certainly~ converting something wrong to float
when lat_lng_float == [0.0, 0.0]
@error = "An error occurred:\nLat and Lng are not numbers.\nPlease enter Lat and Lng manually."
return @error
# in this case we only received one value (wrong divider?)
when lat_lng_float.length < 2
@error = "An error occurred:\nWe got only one value instead of two.\nPlease enter Lat and Lng manually."
return @error
# in this case lat is out of the world's limits
when lat_lng_float[0] > 90 || lat_lng_float[0] < -90
@error = "An error occurred:\nThe Lat value is not correct.\nPlease enter Lat and Lng manually."
return @error
# in this case lng is out of the world's limits
when lat_lng_float[1] > 180 || lat_lng_float[1] < -180
@error = "An error occurred:\nThe Lng value is not correct.\nPlease enter Lat and Lng manually."
return @error
else
lat_lng_float
end
end
begin
result = find_lat_lng
# Raise custom error if no data is retrieved
rescue RetryException => error_message
retry if error_message.ok_to_retry
raise
# This is where I catch all the StandardErrors and print them for whoever runs the code
rescue => error_message
puts "An error occurred:\n#{error_message}\nPlease enter Lat and Lng manually."
else
puts result
end