barometer 0.8.0 → 0.9.0

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.
Files changed (321) hide show
  1. data/.gitignore +2 -0
  2. data/.pelusa.yml +7 -0
  3. data/.travis.yml +6 -3
  4. data/Gemfile +11 -1
  5. data/README.md +89 -244
  6. data/Rakefile +1 -1
  7. data/barometer.gemspec +22 -24
  8. data/lib/barometer.rb +14 -65
  9. data/lib/barometer/base.rb +35 -65
  10. data/lib/barometer/data.rb +15 -20
  11. data/lib/barometer/data/attribute.rb +19 -0
  12. data/lib/barometer/data/attributes/distance.rb +11 -0
  13. data/lib/barometer/data/attributes/float.rb +11 -0
  14. data/lib/barometer/data/attributes/integer.rb +11 -0
  15. data/lib/barometer/data/attributes/location.rb +11 -0
  16. data/lib/barometer/data/attributes/pressure.rb +11 -0
  17. data/lib/barometer/data/attributes/sun.rb +15 -0
  18. data/lib/barometer/data/attributes/temperature.rb +11 -0
  19. data/lib/barometer/data/attributes/time.rb +11 -0
  20. data/lib/barometer/data/attributes/vector.rb +11 -0
  21. data/lib/barometer/data/attributes/zone.rb +11 -0
  22. data/lib/barometer/data/convertable_units.rb +145 -0
  23. data/lib/barometer/data/coordinates.rb +16 -0
  24. data/lib/barometer/data/distance.rb +14 -133
  25. data/lib/barometer/data/geo.rb +22 -59
  26. data/lib/barometer/data/location.rb +14 -20
  27. data/lib/barometer/data/pressure.rb +14 -135
  28. data/lib/barometer/data/sun.rb +24 -24
  29. data/lib/barometer/data/temperature.rb +14 -169
  30. data/lib/barometer/data/vector.rb +44 -0
  31. data/lib/barometer/data/zone.rb +109 -112
  32. data/lib/barometer/query.rb +23 -161
  33. data/lib/barometer/query/base.rb +88 -0
  34. data/lib/barometer/query/converter.rb +64 -0
  35. data/lib/barometer/query/converters/from_coordinates_to_noaa_station_id.rb +30 -0
  36. data/lib/barometer/query/converters/from_geocode_to_coordinates.rb +28 -0
  37. data/lib/barometer/query/converters/from_short_zipcode_to_zipcode.rb +28 -0
  38. data/lib/barometer/query/converters/from_weather_id_to_geocode.rb +30 -0
  39. data/lib/barometer/query/converters/from_woe_id_or_ipv4_to_geocode.rb +32 -0
  40. data/lib/barometer/query/converters/to_geocode.rb +30 -0
  41. data/lib/barometer/query/converters/to_weather_id.rb +30 -0
  42. data/lib/barometer/query/converters/to_woe_id.rb +30 -0
  43. data/lib/barometer/query/format.rb +59 -0
  44. data/lib/barometer/query/formats/base.rb +22 -0
  45. data/lib/barometer/query/formats/coordinates.rb +14 -0
  46. data/lib/barometer/query/formats/geocode.rb +15 -0
  47. data/lib/barometer/query/formats/icao.rb +35 -0
  48. data/lib/barometer/query/formats/ipv4_address.rb +19 -0
  49. data/lib/barometer/query/formats/noaa_station_id.rb +15 -0
  50. data/lib/barometer/query/formats/postalcode.rb +20 -0
  51. data/lib/barometer/query/formats/short_zipcode.rb +15 -0
  52. data/lib/barometer/{translations → query/formats/translations}/icao_country_codes.yml +0 -0
  53. data/lib/barometer/{translations → query/formats/translations}/weather_country_codes.yml +0 -0
  54. data/lib/barometer/query/formats/unknown.rb +14 -0
  55. data/lib/barometer/query/formats/weather_id.rb +33 -0
  56. data/lib/barometer/query/formats/woe_id.rb +28 -0
  57. data/lib/barometer/query/formats/zipcode.rb +15 -0
  58. data/lib/barometer/query/service.rb +13 -0
  59. data/lib/barometer/query/services/apis/geonames_timezone.rb +26 -0
  60. data/lib/barometer/query/services/apis/google_geocode.rb +35 -0
  61. data/lib/barometer/query/services/apis/noaa_station.rb +31 -0
  62. data/lib/barometer/query/services/apis/weather_id.rb +35 -0
  63. data/lib/barometer/query/services/apis/wunderground_timezone.rb +26 -0
  64. data/lib/barometer/query/services/apis/yahoo_placefinder.rb +35 -0
  65. data/lib/barometer/query/services/apis/yahoo_weather.rb +31 -0
  66. data/lib/barometer/query/services/from_weather_id.rb +64 -0
  67. data/lib/barometer/query/services/geonames_timezone.rb +18 -0
  68. data/lib/barometer/query/services/google_geocode.rb +106 -0
  69. data/lib/barometer/query/services/noaa_station_id.rb +28 -0
  70. data/lib/barometer/query/services/to_weather_id.rb +25 -0
  71. data/lib/barometer/query/services/to_woe_id.rb +29 -0
  72. data/lib/barometer/query/services/wunderground_timezone.rb +18 -0
  73. data/lib/barometer/query/services/yahoo_geocode.rb +69 -0
  74. data/lib/barometer/response.rb +12 -0
  75. data/lib/barometer/response/base.rb +57 -0
  76. data/lib/barometer/response/current.rb +27 -0
  77. data/lib/barometer/response/prediction.rb +41 -0
  78. data/lib/barometer/response/prediction_collection.rb +48 -0
  79. data/lib/barometer/utils.rb +17 -0
  80. data/lib/barometer/utils/address.rb +33 -0
  81. data/lib/barometer/utils/api.rb +30 -0
  82. data/lib/barometer/utils/config_reader.rb +40 -0
  83. data/lib/barometer/utils/get.rb +17 -0
  84. data/lib/barometer/utils/json_reader.rb +22 -0
  85. data/lib/barometer/utils/payload.rb +100 -0
  86. data/lib/barometer/utils/payload_request.rb +37 -0
  87. data/lib/barometer/utils/post.rb +24 -0
  88. data/lib/barometer/utils/time.rb +78 -0
  89. data/lib/barometer/{translations → utils/translations}/zone_codes.yml +0 -0
  90. data/lib/barometer/utils/versioned_registration.rb +70 -0
  91. data/lib/barometer/utils/xml_reader.rb +27 -0
  92. data/lib/barometer/utils/zone_code_lookup.rb +30 -0
  93. data/lib/barometer/version.rb +1 -1
  94. data/lib/barometer/weather.rb +44 -173
  95. data/lib/barometer/weather_service.rb +41 -0
  96. data/lib/barometer/weather_services/base.rb +50 -0
  97. data/lib/barometer/weather_services/forecast_io.rb +36 -0
  98. data/lib/barometer/weather_services/forecast_io/api.rb +22 -0
  99. data/lib/barometer/weather_services/forecast_io/query.rb +38 -0
  100. data/lib/barometer/weather_services/forecast_io/response.rb +31 -0
  101. data/lib/barometer/weather_services/forecast_io/response/current_weather.rb +78 -0
  102. data/lib/barometer/weather_services/forecast_io/response/forecasted_weather.rb +74 -0
  103. data/lib/barometer/weather_services/forecast_io/response/location.rb +19 -0
  104. data/lib/barometer/weather_services/forecast_io/response/timezone.rb +25 -0
  105. data/lib/barometer/weather_services/noaa.rb +21 -305
  106. data/lib/barometer/weather_services/noaa/current_api.rb +25 -0
  107. data/lib/barometer/weather_services/noaa/current_query.rb +30 -0
  108. data/lib/barometer/weather_services/noaa/current_response.rb +29 -0
  109. data/lib/barometer/weather_services/noaa/forecast_api.rb +25 -0
  110. data/lib/barometer/weather_services/noaa/forecast_query.rb +39 -0
  111. data/lib/barometer/weather_services/noaa/forecast_response.rb +28 -0
  112. data/lib/barometer/weather_services/noaa/response/current_location.rb +42 -0
  113. data/lib/barometer/weather_services/noaa/response/current_station.rb +46 -0
  114. data/lib/barometer/weather_services/noaa/response/current_weather.rb +82 -0
  115. data/lib/barometer/weather_services/noaa/response/forecasted_weather.rb +90 -0
  116. data/lib/barometer/weather_services/noaa/response/location.rb +19 -0
  117. data/lib/barometer/weather_services/noaa/response/timezone.rb +15 -0
  118. data/lib/barometer/weather_services/response.rb +9 -0
  119. data/lib/barometer/weather_services/response/location.rb +42 -0
  120. data/lib/barometer/weather_services/response/time_zone.rb +19 -0
  121. data/lib/barometer/weather_services/weather_bug.rb +24 -280
  122. data/lib/barometer/weather_services/weather_bug/current_api.rb +26 -0
  123. data/lib/barometer/weather_services/weather_bug/current_response.rb +33 -0
  124. data/lib/barometer/weather_services/weather_bug/forecast_api.rb +26 -0
  125. data/lib/barometer/weather_services/weather_bug/forecast_response.rb +29 -0
  126. data/lib/barometer/weather_services/weather_bug/query.rb +42 -0
  127. data/lib/barometer/weather_services/weather_bug/response/current_weather.rb +82 -0
  128. data/lib/barometer/weather_services/weather_bug/response/forecasted_weather.rb +67 -0
  129. data/lib/barometer/weather_services/weather_bug/response/location.rb +23 -0
  130. data/lib/barometer/weather_services/weather_bug/response/station.rb +43 -0
  131. data/lib/barometer/weather_services/weather_bug/response/sun.rb +32 -0
  132. data/lib/barometer/weather_services/weather_bug/response/time_helper.rb +52 -0
  133. data/lib/barometer/weather_services/weather_bug/response/timezone.rb +15 -0
  134. data/lib/barometer/weather_services/wunderground_v1.rb +32 -0
  135. data/lib/barometer/weather_services/wunderground_v1/current_api.rb +21 -0
  136. data/lib/barometer/weather_services/wunderground_v1/current_response.rb +31 -0
  137. data/lib/barometer/weather_services/wunderground_v1/forecast_api.rb +21 -0
  138. data/lib/barometer/weather_services/wunderground_v1/forecast_response.rb +33 -0
  139. data/lib/barometer/weather_services/wunderground_v1/query.rb +30 -0
  140. data/lib/barometer/weather_services/wunderground_v1/response/current_weather.rb +92 -0
  141. data/lib/barometer/weather_services/wunderground_v1/response/forecasted_weather.rb +87 -0
  142. data/lib/barometer/weather_services/wunderground_v1/response/full_timezone.rb +22 -0
  143. data/lib/barometer/weather_services/wunderground_v1/response/location.rb +43 -0
  144. data/lib/barometer/weather_services/wunderground_v1/response/station.rb +39 -0
  145. data/lib/barometer/weather_services/wunderground_v1/response/sun.rb +53 -0
  146. data/lib/barometer/weather_services/wunderground_v1/response/timezone.rb +15 -0
  147. data/lib/barometer/weather_services/yahoo.rb +16 -198
  148. data/lib/barometer/weather_services/yahoo/api.rb +21 -0
  149. data/lib/barometer/weather_services/yahoo/query.rb +42 -0
  150. data/lib/barometer/weather_services/yahoo/response.rb +39 -0
  151. data/lib/barometer/weather_services/yahoo/response/current_weather.rb +86 -0
  152. data/lib/barometer/weather_services/yahoo/response/forecasted_weather.rb +71 -0
  153. data/lib/barometer/weather_services/yahoo/response/location.rb +47 -0
  154. data/lib/barometer/weather_services/yahoo/response/sun.rb +43 -0
  155. data/lib/barometer/weather_services/yahoo/response/timezone.rb +15 -0
  156. data/spec/barometer_spec.rb +18 -120
  157. data/spec/base_spec.rb +114 -0
  158. data/spec/cassettes/Converter_FromCoordinatesToNoaaStationId.json +1 -0
  159. data/spec/cassettes/Converter_FromWeatherIdToGeocode.json +1 -0
  160. data/spec/cassettes/Converter_FromWoeIdOrIpv4ToGeocode.json +1 -0
  161. data/spec/cassettes/Converter_ToGeocode.json +1 -0
  162. data/spec/cassettes/Converter_ToWeatherId.json +1 -0
  163. data/spec/cassettes/Converter_ToWoeId.json +1 -0
  164. data/spec/cassettes/Service_FromWeatherId.json +1 -0
  165. data/spec/cassettes/Service_GoogleGeocode.json +1 -0
  166. data/spec/cassettes/Service_NoaaStation.json +1 -0
  167. data/spec/cassettes/Service_ToWeatherId.json +1 -0
  168. data/spec/cassettes/Service_ToWoeId.json +1 -0
  169. data/spec/cassettes/Service_YahooGeocode.json +1 -0
  170. data/spec/cassettes/WeatherService_ForecastIo.json +1 -0
  171. data/spec/cassettes/WeatherService_Noaa.json +1 -1
  172. data/spec/cassettes/WeatherService_WeatherBug.json +1 -1
  173. data/spec/cassettes/WeatherService_WundergroundV1.json +1 -0
  174. data/spec/cassettes/WeatherService_Yahoo.json +1 -1
  175. data/spec/data/attributes/distance_spec.rb +60 -0
  176. data/spec/data/attributes/location_spec.rb +41 -0
  177. data/spec/data/attributes/pressure_spec.rb +60 -0
  178. data/spec/data/attributes/sun_spec.rb +33 -0
  179. data/spec/data/attributes/temperature_spec.rb +60 -0
  180. data/spec/data/attributes/time_spec.rb +58 -0
  181. data/spec/data/attributes/vector_spec.rb +43 -0
  182. data/spec/data/attributes/zone_spec.rb +34 -0
  183. data/spec/data/convertable_units_spec.rb +299 -0
  184. data/spec/data/coordinates_spec.rb +15 -0
  185. data/spec/data/distance_spec.rb +49 -333
  186. data/spec/data/geo_spec.rb +72 -71
  187. data/spec/data/location_spec.rb +70 -65
  188. data/spec/data/pressure_spec.rb +49 -333
  189. data/spec/data/sun_spec.rb +57 -81
  190. data/spec/data/temperature_spec.rb +49 -393
  191. data/spec/data/vector_spec.rb +100 -0
  192. data/spec/data/zone_spec.rb +199 -266
  193. data/spec/query/base_spec.rb +296 -0
  194. data/spec/query/converter_spec.rb +98 -0
  195. data/spec/query/converters/from_coordinates_to_noaa_station_id_spec.rb +35 -0
  196. data/spec/query/converters/from_geocode_to_coordinates_spec.rb +25 -0
  197. data/spec/query/converters/from_short_zipcode_to_zipcode_spec.rb +31 -0
  198. data/spec/query/converters/from_weather_id_to_geocode_spec.rb +40 -0
  199. data/spec/query/converters/from_woe_id_or_ipv4_to_geocode_spec.rb +51 -0
  200. data/spec/query/converters/to_geocode_spec.rb +99 -0
  201. data/spec/query/converters/to_weather_id_spec.rb +35 -0
  202. data/spec/query/converters/to_woe_id_spec.rb +74 -0
  203. data/spec/query/formats/base_spec.rb +15 -0
  204. data/spec/query/formats/coordinates_spec.rb +13 -0
  205. data/spec/query/formats/geocode_spec.rb +9 -0
  206. data/spec/query/formats/icao_spec.rb +20 -0
  207. data/spec/query/formats/ipv4_address_spec.rb +33 -0
  208. data/spec/query/formats/noaa_station_id_spec.rb +9 -0
  209. data/spec/query/formats/postalcode_spec.rb +18 -0
  210. data/spec/query/formats/short_zipcode_spec.rb +18 -0
  211. data/spec/query/formats/unknown_spec.rb +9 -0
  212. data/spec/query/formats/weather_id_spec.rb +31 -0
  213. data/spec/query/formats/woe_id_spec.rb +45 -0
  214. data/spec/query/formats/zipcode_spec.rb +18 -0
  215. data/spec/query/formats_spec.rb +55 -0
  216. data/spec/query/services/from_weather_id_spec.rb +54 -0
  217. data/spec/query/services/google_geocode_spec.rb +60 -0
  218. data/spec/query/services/noaa_station_id_spec.rb +23 -0
  219. data/spec/query/services/to_weather_id_spec.rb +23 -0
  220. data/spec/query/services/to_woe_id_spec.rb +51 -0
  221. data/spec/query/services/yahoo_geocode_spec.rb +72 -0
  222. data/spec/response/base_spec.rb +103 -0
  223. data/spec/response/current_spec.rb +33 -0
  224. data/spec/response/predicition_spec.rb +65 -0
  225. data/spec/response/prediction_collection_spec.rb +97 -0
  226. data/spec/spec_helper.rb +14 -12
  227. data/spec/support/key_file_parser.rb +22 -0
  228. data/spec/support/matchers/formats.rb +36 -0
  229. data/spec/support/matchers/have_data.rb +46 -0
  230. data/spec/support/matchers/have_field.rb +128 -0
  231. data/spec/support/matchers/have_forecast.rb +46 -0
  232. data/spec/support/matchers/path.rb +23 -0
  233. data/spec/support/query_factory.rb +20 -0
  234. data/spec/utils/address_spec.rb +67 -0
  235. data/spec/utils/config_reader_spec.rb +157 -0
  236. data/spec/utils/get_spec.rb +22 -0
  237. data/spec/utils/payload_request_spec.rb +69 -0
  238. data/spec/utils/payload_spec.rb +168 -0
  239. data/spec/utils/post_spec.rb +20 -0
  240. data/spec/utils/time_spec.rb +93 -0
  241. data/spec/utils/versioned_registration_spec.rb +105 -0
  242. data/spec/weather_services/base_spec.rb +116 -0
  243. data/spec/weather_services/forecast_io_spec.rb +71 -0
  244. data/spec/weather_services/noaa/current_response_spec.rb +22 -0
  245. data/spec/weather_services/noaa/forecast_response_spec.rb +33 -0
  246. data/spec/weather_services/noaa_spec.rb +68 -166
  247. data/spec/weather_services/weather_bug/current_response_spec.rb +64 -0
  248. data/spec/weather_services/weather_bug/forecast_response_spec.rb +23 -0
  249. data/spec/weather_services/weather_bug_spec.rb +62 -202
  250. data/spec/weather_services/wunderground_v1/current_response_spec.rb +19 -0
  251. data/spec/weather_services/wunderground_v1/forecast_response_spec.rb +62 -0
  252. data/spec/weather_services/wunderground_v1_spec.rb +78 -0
  253. data/spec/weather_services/yahoo/response_spec.rb +73 -0
  254. data/spec/weather_services/yahoo_spec.rb +52 -135
  255. data/spec/weather_services_spec.rb +103 -0
  256. data/spec/weather_spec.rb +167 -347
  257. metadata +342 -123
  258. data/.document +0 -5
  259. data/TODO +0 -60
  260. data/bin/barometer +0 -441
  261. data/lib/barometer/data/local_datetime.rb +0 -145
  262. data/lib/barometer/data/local_time.rb +0 -134
  263. data/lib/barometer/data/speed.rb +0 -158
  264. data/lib/barometer/data/units.rb +0 -49
  265. data/lib/barometer/formats.rb +0 -13
  266. data/lib/barometer/formats/coordinates.rb +0 -57
  267. data/lib/barometer/formats/format.rb +0 -64
  268. data/lib/barometer/formats/geocode.rb +0 -60
  269. data/lib/barometer/formats/icao.rb +0 -37
  270. data/lib/barometer/formats/postalcode.rb +0 -22
  271. data/lib/barometer/formats/short_zipcode.rb +0 -17
  272. data/lib/barometer/formats/weather_id.rb +0 -92
  273. data/lib/barometer/formats/woe_id.rb +0 -150
  274. data/lib/barometer/formats/zipcode.rb +0 -31
  275. data/lib/barometer/key_file_parser.rb +0 -20
  276. data/lib/barometer/measurements/measurement.rb +0 -202
  277. data/lib/barometer/measurements/result.rb +0 -207
  278. data/lib/barometer/measurements/result_array.rb +0 -75
  279. data/lib/barometer/services.rb +0 -19
  280. data/lib/barometer/weather_services/service.rb +0 -189
  281. data/lib/barometer/weather_services/wunderground.rb +0 -264
  282. data/lib/barometer/web_services/geocode.rb +0 -34
  283. data/lib/barometer/web_services/noaa_station_id.rb +0 -53
  284. data/lib/barometer/web_services/placemaker.rb +0 -95
  285. data/lib/barometer/web_services/timezone.rb +0 -38
  286. data/lib/barometer/web_services/weather_id.rb +0 -50
  287. data/lib/barometer/web_services/web_service.rb +0 -29
  288. data/spec/cassettes/Barometer.json +0 -1
  289. data/spec/cassettes/Query.json +0 -1
  290. data/spec/cassettes/Query_Format_Coordinates.json +0 -1
  291. data/spec/cassettes/Query_Format_Geocode.json +0 -1
  292. data/spec/cassettes/Query_Format_WeatherID.json +0 -1
  293. data/spec/cassettes/Query_Format_WoeID.json +0 -1
  294. data/spec/cassettes/WeatherService.json +0 -1
  295. data/spec/cassettes/WeatherService_Wunderground.json +0 -1
  296. data/spec/cassettes/WebService_Geocode.json +0 -1
  297. data/spec/cassettes/WebService_NoaaStation.json +0 -1
  298. data/spec/data/local_datetime_spec.rb +0 -274
  299. data/spec/data/local_time_spec.rb +0 -239
  300. data/spec/data/speed_spec.rb +0 -374
  301. data/spec/data/units_spec.rb +0 -101
  302. data/spec/formats/coordinates_spec.rb +0 -166
  303. data/spec/formats/format_spec.rb +0 -74
  304. data/spec/formats/geocode_spec.rb +0 -163
  305. data/spec/formats/icao_spec.rb +0 -55
  306. data/spec/formats/postalcode_spec.rb +0 -53
  307. data/spec/formats/short_zipcode_spec.rb +0 -47
  308. data/spec/formats/weather_id_spec.rb +0 -182
  309. data/spec/formats/woe_id_spec.rb +0 -211
  310. data/spec/formats/zipcode_spec.rb +0 -103
  311. data/spec/key_file_parser_spec.rb +0 -28
  312. data/spec/measurements/measurement_spec.rb +0 -381
  313. data/spec/measurements/result_array_spec.rb +0 -150
  314. data/spec/measurements/result_spec.rb +0 -632
  315. data/spec/query_spec.rb +0 -498
  316. data/spec/weather_services/services_spec.rb +0 -135
  317. data/spec/weather_services/wunderground_spec.rb +0 -179
  318. data/spec/web_services/geocode_spec.rb +0 -31
  319. data/spec/web_services/noaa_station_id_spec.rb +0 -33
  320. data/spec/web_services/placemaker_spec.rb +0 -41
  321. data/spec/web_services/web_services_spec.rb +0 -20
@@ -0,0 +1,11 @@
1
+ module Barometer
2
+ module Data
3
+ module Attribute
4
+ class Zone < Virtus::Attribute
5
+ def coerce(value)
6
+ value.nil? || value.is_a?(Barometer::Data::Zone) ? value : raise(ArgumentError)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,145 @@
1
+ require 'delegate'
2
+
3
+ module Barometer
4
+ module Data
5
+ class ConvertableUnits < SimpleDelegator
6
+ include Comparable
7
+
8
+ def initialize(*args)
9
+ parse_metric!(args)
10
+ parse_values!(args)
11
+ super(magnitude)
12
+ freeze_all
13
+ end
14
+
15
+ def to_s
16
+ magnitude_to_s
17
+ end
18
+
19
+ def nil?
20
+ magnitude.nil?
21
+ end
22
+
23
+ def <=>(other)
24
+ round(metric) <=> round(other.metric)
25
+ end
26
+
27
+ def metric
28
+ @metric_value || metric_from_imperial
29
+ end
30
+
31
+ def imperial
32
+ @imperial_value || imperial_from_metric
33
+ end
34
+
35
+ def units
36
+ metric? ? 'METRIC' : 'IMPERIAL'
37
+ end
38
+
39
+ def metric?
40
+ !!@metric
41
+ end
42
+
43
+ private
44
+
45
+ def metric=(value)
46
+ if detect_imperial?(value)
47
+ @metric = false
48
+ else
49
+ @metric = true
50
+ end
51
+ end
52
+
53
+ def metric_from_imperial
54
+ return unless @imperial_value
55
+ round(convert_imperial_to_metric(@imperial_value))
56
+ end
57
+
58
+ def convert_imperial_to_metric(value)
59
+ value
60
+ end
61
+
62
+ def imperial_from_metric
63
+ return unless @metric_value
64
+ round(convert_metric_to_imperial(@metric_value))
65
+ end
66
+
67
+ def magnitude
68
+ metric? ? metric : imperial
69
+ end
70
+
71
+ def parse_metric!(args)
72
+ unless detect_number?(args.first)
73
+ self.metric = args.shift
74
+ else
75
+ self.metric = true
76
+ end
77
+ end
78
+
79
+ def parse_values!(args)
80
+ parse_extra_values!(args)
81
+
82
+ if args.length == 1
83
+ parse_single_value!(args.shift)
84
+ else
85
+ parse_multiple_values!(args)
86
+ end
87
+ freeze_magnitude
88
+ end
89
+
90
+ def parse_extra_values!(args)
91
+ args
92
+ end
93
+
94
+ def parse_single_value!(value)
95
+ if metric?
96
+ @metric_value = value
97
+ else
98
+ @imperial_value = value
99
+ end
100
+ end
101
+
102
+ def parse_multiple_values!(values)
103
+ @metric_value = values.shift
104
+ @imperial_value = values.shift
105
+ end
106
+
107
+ def detect_imperial?(value)
108
+ value == :imperial || value.is_a?(FalseClass)
109
+ end
110
+
111
+ def detect_number?(value)
112
+ value.nil? || value.is_a?(Numeric) || string_is_number?(value)
113
+ end
114
+
115
+ def string_is_number?(value)
116
+ value.is_a?(String) &&
117
+ ((value.to_i.to_s == value) || (value.to_f.to_s == value))
118
+ end
119
+
120
+ def round(number)
121
+ (10*number.to_f).round/10.0
122
+ end
123
+
124
+ def magnitude_to_s
125
+ return if magnitude.nil?
126
+ "#{magnitude} #{units}"
127
+ end
128
+
129
+ def freeze_all
130
+ freeze_magnitude
131
+ freeze_extra
132
+ end
133
+
134
+ def freeze_extra
135
+ nil
136
+ end
137
+
138
+ def freeze_magnitude
139
+ @metric_value.freeze
140
+ @imperial_value.freeze
141
+ @metric.freeze
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,16 @@
1
+ require 'virtus'
2
+
3
+ module Barometer
4
+ module Data
5
+ class Coordinates
6
+ include Virtus.value_object
7
+
8
+ attribute :latitude, Float
9
+ attribute :longitude, Float
10
+
11
+ def coordinates
12
+ [latitude, longitude].join(',')
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,141 +1,22 @@
1
1
  module Barometer
2
- #
3
- # A simple Distance class
4
- #
5
- # Think of this like the Integer class. Enhancement
6
- # is that you can create a number (in a certain unit), then
7
- # get that number back already converted to another unit.
8
- #
9
- # All comparison operations will be done in metric
10
- #
11
- # NOTE: this currently only supports the scale of
12
- # kilometers (km) and miles (m). There is currently
13
- # no way to scale to smaller units (eg km -> m -> mm)
14
- #
15
- class Data::Distance < Data::Units
2
+ module Data
3
+ class Distance < ConvertableUnits
4
+ def km; metric; end
5
+ def m; imperial; end
16
6
 
17
- METRIC_UNITS = "km"
18
- IMPERIAL_UNITS = "m"
7
+ def units
8
+ metric? ? 'km' : 'm'
9
+ end
19
10
 
20
- attr_accessor :kilometers, :miles
11
+ private
21
12
 
22
- def initialize(metric=true)
23
- @kilometers = nil
24
- @miles = nil
25
- super(metric)
26
- end
27
-
28
- def metric_default=(value); self.km = value; end
29
- def imperial_default=(value); self.m = value; end
30
-
31
- #
32
- # CONVERTERS
33
- #
34
-
35
- def self.km_to_m(km)
36
- return nil unless km && (km.is_a?(Integer) || km.is_a?(Float))
37
- km.to_f * 0.622
38
- end
39
-
40
- def self.m_to_km(m)
41
- return nil unless m && (m.is_a?(Integer) || m.is_a?(Float))
42
- m.to_f * 1.609
43
- end
44
-
45
- #
46
- # ACCESSORS
47
- #
48
-
49
- # store kilometers
50
- #
51
- def km=(km)
52
- return if !km || !(km.is_a?(Integer) || km.is_a?(Float))
53
- @kilometers = km.to_f
54
- self.update_miles(km.to_f)
55
- end
56
-
57
- # store miles
58
- #
59
- def m=(m)
60
- return if !m || !(m.is_a?(Integer) || m.is_a?(Float))
61
- @miles = m.to_f
62
- self.update_kilometers(m.to_f)
63
- end
64
-
65
- # return the stored kilometers or convert from miles
66
- #
67
- def km(as_integer=true)
68
- km = (@kilometers || Data::Distance.m_to_km(@miles))
69
- km ? (as_integer ? km.to_i : (100*km).round/100.0) : nil
70
- end
71
-
72
- # return the stored miles or convert from kilometers
73
- #
74
- def m(as_integer=true)
75
- m = (@miles || Data::Distance.km_to_m(@kilometers))
76
- m ? (as_integer ? m.to_i : (100*m).round/100.0) : nil
77
- end
78
-
79
- #
80
- # OPERATORS
81
- #
13
+ def convert_imperial_to_metric(imperial_value)
14
+ imperial_value.to_f * 1.609
15
+ end
82
16
 
83
- def <=>(other)
84
- self.km <=> other.km
17
+ def convert_metric_to_imperial(metric_value)
18
+ metric_value.to_f * 0.622
19
+ end
85
20
  end
86
-
87
- #
88
- # HELPERS
89
- #
90
-
91
- # will just return the value (no units)
92
- #
93
- def to_i(metric=nil)
94
- (metric || (metric.nil? && self.metric?)) ? self.km : self.m
95
- end
96
-
97
- # will just return the value (no units) with more precision
98
- #
99
- def to_f(metric=nil)
100
- (metric || (metric.nil? && self.metric?)) ? self.km(false) : self.m(false)
101
- end
102
-
103
- # will return the value with units
104
- #
105
- def to_s(metric=nil)
106
- (metric || (metric.nil? && self.metric?)) ? "#{self.km} #{METRIC_UNITS}" : "#{self.m} #{IMPERIAL_UNITS}"
107
- end
108
-
109
- # will just return the units (no value)
110
- #
111
- def units(metric=nil)
112
- (metric || (metric.nil? && self.metric?)) ? METRIC_UNITS : IMPERIAL_UNITS
113
- end
114
-
115
- # when we set miles, it is possible the a non-equivalent value of
116
- # kilometers remains. if so, clear it.
117
- def update_kilometers(m)
118
- return unless @kilometers
119
- difference = Data::Distance.m_to_km(m.to_f) - @kilometers
120
- # only clear kilometers if the stored kilometers is off be more then 1 unit
121
- # then the conversion of miles
122
- @kilometers = nil unless difference.abs <= 1.0
123
- end
124
-
125
- # when we set kilometers, it is possible the a non-equivalent value of
126
- # miles remains. if so, clear it.
127
- #
128
- def update_miles(km)
129
- return unless @miles
130
- difference = Data::Distance.km_to_m(km.to_f) - @miles
131
- # only clear miles if the stored miles is off be more then 1 unit
132
- # then the conversion of kilometers
133
- @miles = nil unless difference.abs <= 1.0
134
- end
135
-
136
- def nil?
137
- (@kilometers || @miles) ? false : true
138
- end
139
-
140
21
  end
141
22
  end
@@ -1,68 +1,31 @@
1
1
  module Barometer
2
- #
3
- # A simple Geo class
4
- #
5
- # Used to store location data
6
- #
7
- class Data::Geo
8
-
9
- attr_accessor :latitude, :longitude, :query
10
- attr_accessor :locality, :region, :country, :country_code, :address
11
-
12
- def initialize(location=nil)
13
- return unless location
14
- raise ArgumentError unless location.is_a?(Hash)
15
- self.build_from_hash(location)
16
- self
17
- end
18
-
19
- def build_from_hash(location=nil)
20
- return nil unless location
21
- raise ArgumentError unless location.is_a?(Hash)
22
-
23
- if location["geometry"] && location["geometry"]["location"]
24
- @latitude = location["geometry"]["location"]["lat"].to_f
25
- @longitude = location["geometry"]["location"]["lng"].to_f
2
+ module Data
3
+ class Geo < Coordinates
4
+ attribute :query, String
5
+ attribute :address, String
6
+ attribute :locality, String
7
+ attribute :region, String
8
+ attribute :country, String
9
+ attribute :country_code, String
10
+ attribute :postal_code, String
11
+
12
+ def to_s
13
+ [address, locality, region, country || country_code].
14
+ compact.reject(&:empty?).join(', ')
26
15
  end
27
16
 
28
- query_parts = []
29
- if location["address_components"]
30
- location["address_components"].each do |address_components|
31
- skip unless address_components["types"]
32
- # sublocality trumps locality
33
- if address_components["types"].include?('sublocality')
34
- @locality = address_components["long_name"]
35
- end
36
- if address_components["types"].include?('locality')
37
- @locality ||= address_components["long_name"]
38
- end
39
- if address_components["types"].include?('administrative_area_level_1')
40
- #@region = address_components["long_name"]
41
- @region = address_components["short_name"]
42
- end
43
- if address_components["types"].include?('country')
44
- @country = address_components["long_name"]
45
- @country_code = address_components["short_name"]
46
- end
47
- if !(address_components["types"] & location["types"]).empty?
48
- query_parts << address_components["long_name"]
49
- end
50
- end
17
+ def merge(other_geo)
18
+ return unless other_geo.is_a?(Data::Geo)
19
+ Data::Geo.new(merged_attributes(other_geo))
51
20
  end
52
21
 
53
- @query = query_parts.join(', ')
54
- @address = ""
55
- end
56
-
57
- def coordinates
58
- [@latitude, @longitude].join(',')
59
- end
22
+ private
60
23
 
61
- def to_s
62
- s = [@address, @locality, @region, @country || @country_code]
63
- s.delete("")
64
- s.compact.join(', ')
24
+ def merged_attributes(other_geo)
25
+ attributes.merge(other_geo.attributes) do |key, oldval, newval|
26
+ oldval || newval
27
+ end
28
+ end
65
29
  end
66
-
67
30
  end
68
31
  end
@@ -1,25 +1,19 @@
1
1
  module Barometer
2
- #
3
- # A simple Location class
4
- #
5
- # Used to store location information about the station that
6
- # gave the measurement data for a weather query, or the location
7
- # that was queried
8
- #
9
- class Data::Location
2
+ module Data
3
+ class Location < Coordinates
4
+ attribute :id, String
5
+ attribute :name, String
6
+ attribute :city, String
7
+ attribute :state_name, String
8
+ attribute :state_code, String
9
+ attribute :country, String
10
+ attribute :country_code, String
11
+ attribute :zip_code, String
10
12
 
11
- attr_accessor :id, :name, :city
12
- attr_accessor :state_name, :state_code, :country, :country_code, :zip_code
13
- attr_accessor :latitude, :longitude
14
-
15
- def coordinates
16
- [@latitude, @longitude].join(',')
17
- end
18
-
19
- def to_s
20
- [@name, @city, @state_name || @state_cocde,
21
- @country || @country_code].compact.join(', ')
13
+ def to_s
14
+ [name, city, state_name || state_code,
15
+ country || country_code].compact.join(', ')
16
+ end
22
17
  end
23
-
24
18
  end
25
19
  end