weather-forecasts 1.1.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.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +10 -0
- data/LICENSE +20 -0
- data/README.md +135 -0
- data/bin/wf-console +21 -0
- data/lib/weather-forecasts.rb +1 -0
- data/lib/weather_forecasts.rb +23 -0
- data/lib/weather_forecasts/client.rb +65 -0
- data/lib/weather_forecasts/client/error.rb +18 -0
- data/lib/weather_forecasts/client/help_console.rb +9 -0
- data/lib/weather_forecasts/client/query.rb +155 -0
- data/lib/weather_forecasts/client/query/query_property.rb +68 -0
- data/lib/weather_forecasts/client/query/query_utilities.rb +16 -0
- data/lib/weather_forecasts/client/query/select_by_days_query.rb +35 -0
- data/lib/weather_forecasts/client/query/select_coordinates_by_cities_query.rb +47 -0
- data/lib/weather_forecasts/client/query/select_coordinates_by_zip_query.rb +34 -0
- data/lib/weather_forecasts/client/query/select_corner_coordinates_query.rb +38 -0
- data/lib/weather_forecasts/client/query/select_gridpoint_coordinates_query.rb +35 -0
- data/lib/weather_forecasts/client/query/select_linepoint_coordinates_query.rb +33 -0
- data/lib/weather_forecasts/client/query/select_query.rb +48 -0
- data/lib/weather_forecasts/client/query/select_square_coordinates_query.rb +35 -0
- data/lib/weather_forecasts/client/query/selection_attributes.rb +19 -0
- data/lib/weather_forecasts/client/version.rb +5 -0
- data/lib/weather_forecasts/dwml.rb +38 -0
- data/lib/weather_forecasts/dwml/data_extractor.rb +55 -0
- data/lib/weather_forecasts/dwml/head_extractor.rb +49 -0
- data/lib/weather_forecasts/dwml/location.rb +33 -0
- data/lib/weather_forecasts/dwml/parameter_extractor.rb +281 -0
- data/lib/weather_forecasts/dwml/time_layout.rb +55 -0
- data/spec/fixtures/vcr_cassettes/select_by_days_query.yml +557 -0
- data/spec/fixtures/vcr_cassettes/select_coordinates_by_cities_query.yml +437 -0
- data/spec/fixtures/vcr_cassettes/select_coordinates_by_zip_query.yml +437 -0
- data/spec/fixtures/vcr_cassettes/select_corner_coordinates_query.yml +438 -0
- data/spec/fixtures/vcr_cassettes/select_gridpoint_coordinates_query.yml +467 -0
- data/spec/fixtures/vcr_cassettes/select_linepoint_coordinates_query.yml +440 -0
- data/spec/fixtures/vcr_cassettes/select_query.yml +1647 -0
- data/spec/fixtures/vcr_cassettes/select_square_coordinates_query.yml +443 -0
- data/spec/lib/ndfd/client/query/query_property_spec.rb +41 -0
- data/spec/lib/ndfd/client/query/select_by_days_query_spec.rb +35 -0
- data/spec/lib/ndfd/client/query/select_coordinates_by_cities_query_spec.rb +33 -0
- data/spec/lib/ndfd/client/query/select_coordinates_by_zip_query_spec.rb +34 -0
- data/spec/lib/ndfd/client/query/select_corner_coordinates_query_spec.rb +35 -0
- data/spec/lib/ndfd/client/query/select_gridpoint_coordinates_query_spec.rb +37 -0
- data/spec/lib/ndfd/client/query/select_linepoint_coordinates_query_spec.rb +36 -0
- data/spec/lib/ndfd/client/query/select_query_spec.rb +46 -0
- data/spec/lib/ndfd/client/query/select_square_coordinates_query_spec.rb +37 -0
- data/spec/lib/ndfd/client/query/selection_attributes_spec.rb +13 -0
- data/spec/lib/ndfd/client/query_spec.rb +91 -0
- data/spec/lib/ndfd/client_spec.rb +61 -0
- data/spec/spec_helper.rb +33 -0
- data/spec/support/resources/sample_document.xml +61 -0
- data/weather-forecasts.gemspec +39 -0
- metadata +224 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 371ec85a41177e5776b3a7c75403e9c6542cbc3b
|
4
|
+
data.tar.gz: 175d691d93110a1420fe7418677ea2abe0791896
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0d418743f91fb40d802efd1bd5d7d98168df72b28c9c143046511a67b423f684eb5cf2dea4824588dd1c8086ef82fd68e2f0f3381472fd87fd27a2771c173352
|
7
|
+
data.tar.gz: 1cef93374ea71318d02dc1588d6cabe709c12a4035def8b31baf6e8a0665b7984f911d334ca46b89751e5d0e92dd1bdcab94616f3fe3e89b457e54def4f6b227
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 greencoder
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
# Weather Forecasts for Ruby
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/weather-forecasts)
|
4
|
+
[](https://travis-ci.org/alakra/weather-forecasts)
|
5
|
+
[](https://gemnasium.com/alakra/weather-forecasts)
|
6
|
+
[](https://coveralls.io/r/alakra/weather-forecasts?branch=master)
|
7
|
+
|
8
|
+
[](https://codeclimate.com/github/alakra/weather-forecasts) |
|
9
|
+
[](http://inch-pages.github.io/github/alakra/weather-forecasts)
|
10
|
+
|
11
|
+
## Summary
|
12
|
+
|
13
|
+
This library provides API client access to NOAA's NDFD database
|
14
|
+
for access to weather forecast information via Ruby.
|
15
|
+
|
16
|
+
## NDFD Features
|
17
|
+
|
18
|
+
You can [see the available forecast information](http://www.nws.noaa.gov/ndfd/technical.htm#elements) that is accessible via the API on the NDFD technical description page.
|
19
|
+
|
20
|
+
In general, you can get the following:
|
21
|
+
|
22
|
+
* Specific forecast dimensions (min/max temperature, wind speed, etc.) out to 168 hours.
|
23
|
+
* Climate outlook probabilities (estimated averages/totals of temperature and precipitation)
|
24
|
+
* Convective Outlook Hazard Probabilities (hazard outlook, tornadoes, etc.)
|
25
|
+
* Probabilistic Tropical Cyclone Surface Wind Speed (measured in knots)
|
26
|
+
|
27
|
+
## Client Features
|
28
|
+
|
29
|
+
The client offers a easy to use query interface and will hand back data to you in hashes, arrays and XML documents.
|
30
|
+
Validates requests and data types on execution of requests (will raise contextual errors on poorly formed data in queries)
|
31
|
+
|
32
|
+
## Runtime Dependencies
|
33
|
+
|
34
|
+
Ruby versions supported:
|
35
|
+
|
36
|
+
* 2.1.x
|
37
|
+
* 2.0.x
|
38
|
+
* 1.9.3
|
39
|
+
|
40
|
+
Ruby versions not supported (but will be):
|
41
|
+
|
42
|
+
* JRuby 1.7+
|
43
|
+
* Rubinius 2.2+
|
44
|
+
|
45
|
+
Ruby versions that will not be supported:
|
46
|
+
|
47
|
+
* <= 1.9.2 (including REE)
|
48
|
+
|
49
|
+
Libraries used:
|
50
|
+
|
51
|
+
* savon (for SOAP support)
|
52
|
+
* activesupport (for TimeWithZone support)
|
53
|
+
* nokogiri (for XML/XSLT parsing)
|
54
|
+
* http_logger (for controlling logging output from savon)
|
55
|
+
|
56
|
+
## Installation
|
57
|
+
|
58
|
+
gem install weather-forecasts
|
59
|
+
|
60
|
+
## Usage
|
61
|
+
|
62
|
+
`WeatherForecasts.client` is the top-level start point from whence all API calls are executed.
|
63
|
+
|
64
|
+
Most calls follow the form of:
|
65
|
+
|
66
|
+
WeatherForecasts.client.
|
67
|
+
select(:maxt, :mint, :temp, etc.).
|
68
|
+
where(conditions).
|
69
|
+
execute
|
70
|
+
|
71
|
+
This will return an `Array` or `Hash` containing the data from the
|
72
|
+
response depending on the type of the request.
|
73
|
+
|
74
|
+
**NOTE**: Dates and times passed to the `where` must be
|
75
|
+
ActiveSupport::TimeWithZone objects.
|
76
|
+
|
77
|
+
**NOTE**: `NDFDgen` and `NDFDgenByDay` are not implemented in favor of
|
78
|
+
using the equivalent collection-based functions.
|
79
|
+
|
80
|
+
**NOTE**: `GmlLatLonList`, `GmlTimeSeries` are not implemented because
|
81
|
+
of their limited use (and my inability to figure out what parameters
|
82
|
+
to use to make a valid request). It appears to be [discontinued](http://www.nws.noaa.gov/om/notification/tin10-59ending_wfs.htm).
|
83
|
+
|
84
|
+
<table>
|
85
|
+
<tr>
|
86
|
+
<th>Query Method</th>
|
87
|
+
<th>API server function</th>
|
88
|
+
<th>Description</th>
|
89
|
+
</tr>
|
90
|
+
<tr>
|
91
|
+
<td><code>select</code></td>
|
92
|
+
<td><code>NDFDgenLatLonList</code></td>
|
93
|
+
<td>Returns a <code>Hash</code> of forecast metrics for multiple latitudes/longitudes.</td>
|
94
|
+
</tr>
|
95
|
+
<tr>
|
96
|
+
<td><code>select_by_days</code></td>
|
97
|
+
<td><code>NDFDgenByDayLatLonList</code></td>
|
98
|
+
<td>Returns a <code>Hash</code> of forecast metrics for multiple latitudes/longitudes in a 24/12 hour period for a number of days.</td>
|
99
|
+
</tr>
|
100
|
+
<tr>
|
101
|
+
<td><code>select_coordinates_by_zip</code></td>
|
102
|
+
<td><code>LatLonListZipCode</code></td>
|
103
|
+
<td>Returns a <code>Hash</code> of latitudes/longitudes for every zip code requested.</td>
|
104
|
+
</tr>
|
105
|
+
<tr>
|
106
|
+
<td><code>select_coordinates_by_cities</code></td>
|
107
|
+
<td><code>LatLonListCityNames</code></td>
|
108
|
+
<td>Returns a <code>Hash</code> of latitudes/longitudes for a pre-defined set of cities.</td>
|
109
|
+
</tr>
|
110
|
+
<tr>
|
111
|
+
<td><code>select_square_coordinates</code></td>
|
112
|
+
<td><code>LatLonListSquare</code></td>
|
113
|
+
<td>Returns a <code>Array</code> of latitudes/longitudes for the requested rectangular area.</td>
|
114
|
+
</tr>
|
115
|
+
<tr>
|
116
|
+
<td><code>select_gridpoint_coordinates</code></td>
|
117
|
+
<td><code>LatLonListSubgrid</code></td>
|
118
|
+
<td>Returns a <code>Array</code> of latitudes/longitudes for the requested subgrid.</td>
|
119
|
+
</tr>
|
120
|
+
<tr>
|
121
|
+
<td><code>select_linepoint_coordinates</code></td>
|
122
|
+
<td><code>LatLonListLine</code></td>
|
123
|
+
<td>Returns a <code>Array</code> of latitudes/longitudes between a start and end coordinate.</td>
|
124
|
+
</tr>
|
125
|
+
<tr>
|
126
|
+
<td><code>select_corner_coordinates</code></td>
|
127
|
+
<td><code>CornerPoints</code></td>
|
128
|
+
<td>Returns a <code>Array</code> of latitudes/longitudes of the corners of one of the NDFD grids.</td>
|
129
|
+
</tr>
|
130
|
+
</table>
|
131
|
+
|
132
|
+
To see a description of the NDFD Spatial Reference System (used for collecting lat/longs in an area)
|
133
|
+
http://graphical.weather.gov/docs/ndfdSRS.htm
|
134
|
+
|
135
|
+
To see more detailed documention, view the [API Documentation](http://rdoc.info/github/alakra/weather-forecasts/frames)
|
data/bin/wf-console
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler/setup'
|
5
|
+
|
6
|
+
require 'nokogiri'
|
7
|
+
|
8
|
+
$: << File.join(File.dirname(__FILE__), "..", "lib")
|
9
|
+
|
10
|
+
require 'weather_forecasts'
|
11
|
+
require 'weather_forecasts/client/help_console'
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
require 'pp'
|
15
|
+
|
16
|
+
client = WeatherForecasts.client
|
17
|
+
|
18
|
+
h = WeatherForecasts::Client::HelpConsole.new
|
19
|
+
h.display_welcome
|
20
|
+
|
21
|
+
IRB.start
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'weather_forecasts'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module WeatherForecasts
|
2
|
+
module_function
|
3
|
+
|
4
|
+
def env
|
5
|
+
@@env ||= (ENV['ENV'] || :production)
|
6
|
+
end
|
7
|
+
|
8
|
+
def client(options = {})
|
9
|
+
Client.new(options)
|
10
|
+
end
|
11
|
+
|
12
|
+
def root_path
|
13
|
+
File.expand_path(File.join(File.dirname(__FILE__), "../"))
|
14
|
+
end
|
15
|
+
|
16
|
+
def vendor_path
|
17
|
+
File.join(root_path, "vendor")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'weather_forecasts/dwml'
|
22
|
+
require 'weather_forecasts/client'
|
23
|
+
require 'weather_forecasts/client/version'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'savon'
|
3
|
+
require 'http_logger'
|
4
|
+
|
5
|
+
require 'weather_forecasts/client/error'
|
6
|
+
require 'weather_forecasts/client/query'
|
7
|
+
|
8
|
+
# Original web service description: http://graphical.weather.gov/xml/
|
9
|
+
module WeatherForecasts
|
10
|
+
class Client
|
11
|
+
DEFAULT_WSDL = "http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl"
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@options = options
|
15
|
+
|
16
|
+
if options[:wsdl].blank?
|
17
|
+
@options.merge!(:wsdl => DEFAULT_WSDL)
|
18
|
+
end
|
19
|
+
|
20
|
+
if options[:logger].present?
|
21
|
+
HttpLogger.logger = options[:logger]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def soap_client
|
26
|
+
@soap_client ||= Savon.client(@options)
|
27
|
+
end
|
28
|
+
|
29
|
+
#
|
30
|
+
# Query Methods
|
31
|
+
############################################################################
|
32
|
+
|
33
|
+
def select(*options)
|
34
|
+
SelectQuery.new(soap_client, options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def select_by_days
|
38
|
+
SelectByDaysQuery.new(soap_client)
|
39
|
+
end
|
40
|
+
|
41
|
+
def select_coordinates_by_zip
|
42
|
+
SelectCoordinatesByZipQuery.new(soap_client)
|
43
|
+
end
|
44
|
+
|
45
|
+
def select_coordinates_by_cities
|
46
|
+
SelectCoordinatesByCitiesQuery.new(soap_client)
|
47
|
+
end
|
48
|
+
|
49
|
+
def select_square_coordinates
|
50
|
+
SelectSquareCoordinatesQuery.new(soap_client)
|
51
|
+
end
|
52
|
+
|
53
|
+
def select_gridpoint_coordinates
|
54
|
+
SelectGridpointCoordinatesQuery.new(soap_client)
|
55
|
+
end
|
56
|
+
|
57
|
+
def select_linepoint_coordinates
|
58
|
+
SelectLinepointCoordinatesQuery.new(soap_client)
|
59
|
+
end
|
60
|
+
|
61
|
+
def select_corner_coordinates
|
62
|
+
SelectCornerCoordinatesQuery.new(soap_client)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module WeatherForecasts
|
2
|
+
class Client
|
3
|
+
class InvalidSelectionAttributeError < ArgumentError
|
4
|
+
end
|
5
|
+
|
6
|
+
class InvalidPropertyTypeError < ArgumentError
|
7
|
+
end
|
8
|
+
|
9
|
+
class InvalidOptionSpecifiedError < ArgumentError
|
10
|
+
end
|
11
|
+
|
12
|
+
class RequiredPropertyError < ArgumentError
|
13
|
+
end
|
14
|
+
|
15
|
+
class RequiredKeysMissingError < ArgumentError
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'active_support/time'
|
2
|
+
require 'active_support/time_with_zone'
|
3
|
+
|
4
|
+
Time.zone ||= "UTC"
|
5
|
+
|
6
|
+
require 'weather_forecasts/client/query/query_property'
|
7
|
+
require 'weather_forecasts/client/query/selection_attributes'
|
8
|
+
require 'weather_forecasts/client/query/query_utilities'
|
9
|
+
|
10
|
+
module WeatherForecasts
|
11
|
+
class Client
|
12
|
+
class Query
|
13
|
+
FORECAST_ELEMENTS = {
|
14
|
+
:maxt => "Maximum Temperature",
|
15
|
+
:mint => "Minimum Temperature",
|
16
|
+
:temp => "3 Hourly Temperature",
|
17
|
+
:dew => "Dewpoint Temperature",
|
18
|
+
:appt => "Apparent Temperature",
|
19
|
+
:pop12 => "12 Hour Probability of Precipitation",
|
20
|
+
:qpf => "Liquid Precipitation Amount",
|
21
|
+
:snow => "Snowfall Amount",
|
22
|
+
:sky => "Cloud Cover Amount",
|
23
|
+
:rh => "Relative Humidity",
|
24
|
+
:wspd => "Wind Speed",
|
25
|
+
:wdir => "Wind Direction",
|
26
|
+
:wx => "Weather",
|
27
|
+
:icons => "Weather Icons",
|
28
|
+
:waveh => "Wave Height",
|
29
|
+
:incw34 => "Probabilistic Tropical Cyclone Wind Speed >34 Knots (Incremental)",
|
30
|
+
:incw50 => "Probabilistic Tropical Cyclone Wind Speed >50 Knots (Incremental)",
|
31
|
+
:incw64 => "Probabilistic Tropical Cyclone Wind Speed >64 Knots (Incremental)",
|
32
|
+
:cumw34 => "Probabilistic Tropical Cyclone Wind Speed >34 Knots (Cumulative)",
|
33
|
+
:cumw50 => "Probabilistic Tropical Cyclone Wind Speed >50 Knots (Cumulative)",
|
34
|
+
:cumw64 => "Probabilistic Tropical Cyclone Wind Speed >64 Knots (Cumulative)",
|
35
|
+
:wgust => "Wind Gust",
|
36
|
+
:critfireo => "Fire Weather from Wind and Relative Humidity",
|
37
|
+
:dryfireo => "Fire Weather from Dry Thunderstorms",
|
38
|
+
:conhazo => "Convective Hazard Outlook",
|
39
|
+
:ptornado => "Probability of Tornadoes",
|
40
|
+
:phail => "Probability of Hail",
|
41
|
+
:ptstmwinds => "Probability of Damaging Thunderstorm Winds",
|
42
|
+
:pxtornado => "Probability of Extreme Tornadoes",
|
43
|
+
:pxhail => "Probability of Extreme Hail",
|
44
|
+
:pxtstmwinds => "Probability of Extreme Thunderstorm Winds",
|
45
|
+
:ptotsvrtstm => "Probability of Severe Thunderstorms",
|
46
|
+
:pxtotsvrtstm => "Probability of Extreme Severe Thunderstorms",
|
47
|
+
:tmpabv14d => "Probability of 8- To 14-Day Average Temperature Above Normal",
|
48
|
+
:tmpblw14d => "Probability of 8- To 14-Day Average Temperature Below Normal",
|
49
|
+
:tmpabv30d => "Probability of One-Month Average Temperature Above Normal",
|
50
|
+
:tmpblw30d => "Probability of One-Month Average Temperature Below Normal",
|
51
|
+
:tmpabv90d => "Probability of Three-Month Average Temperature Above Normal",
|
52
|
+
:tmpblw90d => "Probability of Three-Month Average Temperature Below Normal",
|
53
|
+
:prcpabv14d => "Probability of 8- To 14-Day Total Precipitation Above Median",
|
54
|
+
:prcpblw14d => "Probability of 8- To 14-Day Total Precipitation Below Median",
|
55
|
+
:prcpabv30d => "Probability of One-Month Total Precipitation Above Median",
|
56
|
+
:prcpblw30d => "Probability of One-Month Total Precipitation Below Median",
|
57
|
+
:prcpabv90d => "Probability of Three-Month Total Precipitation Above Median",
|
58
|
+
:prcpblw90d => "Probability of Three-Month Total Precipitation Below Median",
|
59
|
+
:precipa_r => "Real-time Mesoscale Analysis Precipitation",
|
60
|
+
:sky_r => "Real-time Mesoscale Analysis GOES Effective Cloud Amount",
|
61
|
+
:td_r => "Real-time Mesoscale Analysis Dewpoint Temperature",
|
62
|
+
:temp_r => "Real-time Mesoscale Analysis Temperature",
|
63
|
+
:wdir_r => "Real-time Mesoscale Analysis Wind Direction",
|
64
|
+
:wspd_r => "Real-time Mesoscale Analysis Wind Speed",
|
65
|
+
:wwa => "Watches, Warnings, and Advisories",
|
66
|
+
:iceaccum => "Ice Accumulation",
|
67
|
+
:maxrh => "Maximum Relative Humidity",
|
68
|
+
:minrh => "Minimum Relative Humidity"
|
69
|
+
}
|
70
|
+
|
71
|
+
attr_reader :soap_client, :select_attributes, :conditions
|
72
|
+
|
73
|
+
def initialize(soap_client, select_attributes = [])
|
74
|
+
@soap_client = soap_client
|
75
|
+
@select_attributes = select_attributes
|
76
|
+
@conditions = {}
|
77
|
+
end
|
78
|
+
|
79
|
+
def where(params)
|
80
|
+
conditions.merge!(params)
|
81
|
+
set_defaults_as_needed
|
82
|
+
|
83
|
+
self
|
84
|
+
end
|
85
|
+
|
86
|
+
def execute
|
87
|
+
raise NotImplementedError, "Must be implemented in subclass."
|
88
|
+
end
|
89
|
+
|
90
|
+
def validate
|
91
|
+
validate_selection_attributes
|
92
|
+
validate_conditions
|
93
|
+
end
|
94
|
+
|
95
|
+
class << self
|
96
|
+
def properties
|
97
|
+
@@properties ||= {}
|
98
|
+
end
|
99
|
+
|
100
|
+
def property(attr, options = {})
|
101
|
+
properties[self] ||= []
|
102
|
+
properties[self] << QueryProperty.new(attr, options)
|
103
|
+
end
|
104
|
+
|
105
|
+
def selection_attributes
|
106
|
+
@@selection_attributes ||= {}
|
107
|
+
end
|
108
|
+
|
109
|
+
def set_selection_attributes(*attrs)
|
110
|
+
selection_attributes[self] = SelectionAttributes.new(attrs)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
protected
|
115
|
+
|
116
|
+
def available_selections
|
117
|
+
self.class.selection_attributes[self.class]
|
118
|
+
end
|
119
|
+
|
120
|
+
def set_defaults_as_needed
|
121
|
+
query_properties = self.class.properties[self.class]
|
122
|
+
return unless query_properties
|
123
|
+
|
124
|
+
query_properties.select(&:default).each do |query_property|
|
125
|
+
next if conditions.has_key?(query_property.name)
|
126
|
+
conditions.merge!(query_property.name => query_property.default)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def validate_selection_attributes
|
131
|
+
select_attributes.each do |attr|
|
132
|
+
available_selections && available_selections.valid?(attr)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def validate_conditions
|
137
|
+
query_properties = self.class.properties[self.class]
|
138
|
+
return unless query_properties
|
139
|
+
|
140
|
+
query_properties.each do |query_property|
|
141
|
+
query_property.valid?(conditions)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
require 'weather_forecasts/client/query/select_by_days_query'
|
149
|
+
require 'weather_forecasts/client/query/select_coordinates_by_cities_query'
|
150
|
+
require 'weather_forecasts/client/query/select_coordinates_by_zip_query'
|
151
|
+
require 'weather_forecasts/client/query/select_corner_coordinates_query'
|
152
|
+
require 'weather_forecasts/client/query/select_gridpoint_coordinates_query'
|
153
|
+
require 'weather_forecasts/client/query/select_linepoint_coordinates_query'
|
154
|
+
require 'weather_forecasts/client/query/select_square_coordinates_query'
|
155
|
+
require 'weather_forecasts/client/query/select_query'
|