onthesnow 0.0.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.
- data/.gitignore +4 -0
- data/.rvmrc +1 -0
- data/CHANGELOG +3 -0
- data/Gemfile +4 -0
- data/README.md +55 -0
- data/Rakefile +6 -0
- data/lib/onthesnow/api.rb +22 -0
- data/lib/onthesnow/config.rb +29 -0
- data/lib/onthesnow/helper.rb +37 -0
- data/lib/onthesnow/region/region.rb +31 -0
- data/lib/onthesnow/region.rb +1 -0
- data/lib/onthesnow/resort/elevation.rb +23 -0
- data/lib/onthesnow/resort/info.rb +23 -0
- data/lib/onthesnow/resort/lifts.rb +43 -0
- data/lib/onthesnow/resort/resort.rb +65 -0
- data/lib/onthesnow/resort/slopes.rb +27 -0
- data/lib/onthesnow/resort/snow.rb +23 -0
- data/lib/onthesnow/resort/weather.rb +31 -0
- data/lib/onthesnow/resort.rb +7 -0
- data/lib/onthesnow/state/state.rb +45 -0
- data/lib/onthesnow/state.rb +1 -0
- data/lib/onthesnow/version.rb +3 -0
- data/lib/onthesnow.rb +26 -0
- data/onthesnow.gemspec +28 -0
- data/spec/fixtures/alaska_snow.rss +63 -0
- data/spec/fixtures/alyska_profile.html +2310 -0
- data/spec/fixtures/site_map_rss.html +1528 -0
- data/spec/onthesnow_parser_spec.rb +209 -0
- data/spec/spec_helper.rb +6 -0
- metadata +163 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm gemset use ree@onthesnow --create
|
data/CHANGELOG
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# onthesnow
|
2
|
+
|
3
|
+
This is a very small API to get informations from http://www.onthesnow.com
|
4
|
+
I need it in [another project](https://github.com/janowiesniak/snowcat-rhoconnect) to fill a redis store, that is why all api calls return hashes.
|
5
|
+
|
6
|
+
Install
|
7
|
+
--------
|
8
|
+
|
9
|
+
```shell
|
10
|
+
gem install onthesnow
|
11
|
+
```
|
12
|
+
or add the following line to Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem 'onthesnow'
|
16
|
+
```
|
17
|
+
and run `bundle install` from your shell.
|
18
|
+
|
19
|
+
Usage
|
20
|
+
----------------
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
api = OnTheSnow::API.instance
|
24
|
+
|
25
|
+
api.regions
|
26
|
+
=> {"1"=>{"name"=>"USA"}, "2"=>{"name"=>"Europe"}}
|
27
|
+
|
28
|
+
api.states
|
29
|
+
=> {"1"=>{"region"=>"USA", "name"=>"Alaska", "rss"=>"http://www.onthesnow.com/AK/snow.rss"}}
|
30
|
+
|
31
|
+
# this crawl over ALL resorts and could take really really long!
|
32
|
+
api.resorts
|
33
|
+
=> hash of all resorts
|
34
|
+
|
35
|
+
# probably you should use resort directly. Initialize it with the profile page.
|
36
|
+
resort = OnTheSnow::Resort::Resort.new("http://www.onthesnow.com/dolomiti-superski/plan-de-corones-kronplatz/profile.html")
|
37
|
+
|
38
|
+
resort.infos
|
39
|
+
=> {"name"=>"Plan de Corones / Kronplatz", "url"=>"http://www.onthesnow.com/dolomiti-superski/plan-de-corones-kronplatz/profile.html", "states"=>["All Italy", "Bolzano-Bozen", "Dolomiti Superski", "Italy", "S\303\274dtirol"]}
|
40
|
+
|
41
|
+
resort.weather
|
42
|
+
=> {"condition"=>"Mostly Cloudy", "date"=>"Jan 22", "temperature"=>{"c"=>"1\302\260C", "f"=>"34\302\260F"}}
|
43
|
+
|
44
|
+
resort.slopes
|
45
|
+
=> {"beginner"=>"80%", "advanced"=>"0%", "intermediate"=>"20%", "expert"=>"0%"}
|
46
|
+
|
47
|
+
resort.elevation
|
48
|
+
=> {"peak"=>"8858Ft.", "valley"=>"3117Ft.", "height_difference"=>"3701Ft."}
|
49
|
+
|
50
|
+
resort.lifts
|
51
|
+
=> {"quad"=>"1", "fast_quads"=>"", "trams"=>"22", "fast_sixes"=>"0", "surface"=>"5", "total"=>"0", "double"=>"0", "triple"=>"4"}
|
52
|
+
|
53
|
+
resort.to_hash
|
54
|
+
=> {"weather"=>{"condition"=>"Mostly Cloudy", "date"=>"Jan 22", "temperature"=>{"c"=>"1\302\260C", "f"=>"34\302\260F"}}, "elevation"=>{"peak"=>"8858Ft.", "valley"=>"3117Ft.", "height_difference"=>"3701Ft."}, "lifts"=>{"quad"=>"1", "fast_quads"=>"", "trams"=>"22", "fast_sixes"=>"0", "surface"=>"5", "total"=>"0", "double"=>"0", "triple"=>"4"}, "snow"=>{"last_24"=>"0in.", "last_48"=>"0in.", "last_72"=>"0in."}, "info"=>{"name"=>"Plan de Corones / Kronplatz", "url"=>"http://www.onthesnow.com/dolomiti-superski/plan-de-corones-kronplatz/profile.html", "states"=>["All Italy", "Bolzano-Bozen", "Dolomiti Superski", "Italy", "S\303\274dtirol"]}, "slopes"=>{"beginner"=>"80%", "advanced"=>"0%", "intermediate"=>"20%", "expert"=>"0%"}}
|
55
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
class API
|
3
|
+
include OnTheSnow::Helper
|
4
|
+
private_class_method :new
|
5
|
+
|
6
|
+
def self.instance
|
7
|
+
@@instance ||= new
|
8
|
+
end
|
9
|
+
|
10
|
+
def regions
|
11
|
+
OnTheSnow::Region::Region.all
|
12
|
+
end
|
13
|
+
|
14
|
+
def states
|
15
|
+
OnTheSnow::State::State.all
|
16
|
+
end
|
17
|
+
|
18
|
+
def resorts
|
19
|
+
OnTheSnow::Resort::Resort.all
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
class Config
|
3
|
+
def initialize(&block)
|
4
|
+
@hash = {}
|
5
|
+
if block_given?
|
6
|
+
yield self
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def [](key)
|
11
|
+
@hash[key]
|
12
|
+
end
|
13
|
+
|
14
|
+
def []=(key, value)
|
15
|
+
@hash[key] = value
|
16
|
+
end
|
17
|
+
|
18
|
+
def method_missing(meth, *args, &blk)
|
19
|
+
if block_given?
|
20
|
+
self[meth] = self.class.new(&blk)
|
21
|
+
else
|
22
|
+
raise "only one argument supported" if args.size > 1
|
23
|
+
|
24
|
+
return self[meth] if args.size == 0
|
25
|
+
return self[meth] = args.first
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Helper
|
3
|
+
|
4
|
+
def url
|
5
|
+
@url ||= ::OnTheSnow.config.url
|
6
|
+
end
|
7
|
+
|
8
|
+
def site_map_rss_url
|
9
|
+
@site_map_rss_url ||= ::OnTheSnow.config.site_map_rss_url
|
10
|
+
end
|
11
|
+
|
12
|
+
def sitemap
|
13
|
+
@sitemap ||= Nokogiri::HTML(open(site_map_rss_url))
|
14
|
+
end
|
15
|
+
|
16
|
+
def rss_url(state)
|
17
|
+
"#{url}/#{state}/snow.rss"
|
18
|
+
end
|
19
|
+
|
20
|
+
def rss(url)
|
21
|
+
SimpleRSS.parse(open(url))
|
22
|
+
end
|
23
|
+
|
24
|
+
def profile(url)
|
25
|
+
Nokogiri::HTML(open(url))
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_profile_url_from_snow_resort_url(url)
|
29
|
+
url.split("/")[0..-2].join("/").concat("/profile.html")
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove_chars(element)
|
33
|
+
element.gsub(/Ski Report.*$/,"").strip
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Region
|
3
|
+
class Region
|
4
|
+
attr_reader :name
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.all
|
11
|
+
if @regions
|
12
|
+
@regions
|
13
|
+
else
|
14
|
+
@regions = {}
|
15
|
+
@api = OnTheSnow::API.instance
|
16
|
+
@api.sitemap.css('#site_map_rss .colA h3 ,#site_map_rss .colB h3').each_with_index{|element,index|
|
17
|
+
region_name = @api.remove_chars(element.children.to_s)
|
18
|
+
region = new(region_name)
|
19
|
+
@regions["#{index+1}"] = region.to_hash
|
20
|
+
}
|
21
|
+
@regions
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_hash
|
26
|
+
{"name" => name}
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'onthesnow/region/region'
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Resort
|
3
|
+
module Elevation
|
4
|
+
|
5
|
+
def elevation
|
6
|
+
@elevation ||= {"peak" => peak, "height_difference" => height_difference, "valley" => valley} unless dom(:elevation).empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def peak
|
10
|
+
@peak ||= dom(:elevation).search("ul li")[0].search(".white_pill").children.text.split.join unless dom(:elevation).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def height_difference
|
14
|
+
@height ||= dom(:elevation).search("ul li")[1].search(".white_pill").children.text.split.join unless dom(:elevation).empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def valley
|
18
|
+
@valley ||= dom(:elevation).search("ul li")[2].search(".white_pill").children.text.split.join unless dom(:elevation).empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Resort
|
3
|
+
module Info
|
4
|
+
|
5
|
+
def infos
|
6
|
+
@infos ||= {"name" => name, "states" => states, "url" => url} unless dom(:info).empty? && dom(:states).empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def name
|
10
|
+
@name ||= dom(:info).text unless dom(:info).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def states
|
14
|
+
@states ||= dom(:states).map{|e| e.text} unless dom(:states).empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def url
|
18
|
+
@url
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Resort
|
3
|
+
module Lifts
|
4
|
+
|
5
|
+
def lifts
|
6
|
+
@lifts ||= {"total" => total_lifts, "trams" => trams_lifts, "fast_sixes" => fast_sixes_lifts, "fast_quads" => fast_quads_lifts, "quad" => quad_lifts, "triple" => triple_lifts, "double" => double_lifts, "surface" => surface_lifts} unless dom(:lifts).empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def total_lifts
|
10
|
+
@total_lifts ||= dom(:lifts).search("ul .total strong").text.split.join unless dom(:lifts).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def trams_lifts
|
14
|
+
@trams_lifts ||= dom(:lifts).search("ul .trams strong").text.split.join unless dom(:lifts).empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def fast_sixes_lifts
|
18
|
+
@fast_sixes_lifts ||= dom(:lifts).search("ul .fast_sixes strong").text.split.join unless dom(:lifts).empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
def fast_quads_lifts
|
22
|
+
@fast_quads_lifts ||= dom(:lifts).search("ul .fast_quads strong").text.split.join unless dom(:lifts).empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
def quad_lifts
|
26
|
+
@quad_lifts ||= dom(:lifts).search("ul .quad strong").text.split.join unless dom(:lifts).empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
def triple_lifts
|
30
|
+
@triple_lifts ||= dom(:lifts).search("ul .triple strong").text.split.join unless dom(:lifts).empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def double_lifts
|
34
|
+
@double_lifts ||= dom(:lifts).search("ul .double strong").text.split.join unless dom(:lifts).empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
def surface_lifts
|
38
|
+
@surface_lifts ||= dom(:lifts).search("ul .surface strong").text.split.join unless dom(:lifts).empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Resort
|
3
|
+
class Resort
|
4
|
+
include OnTheSnow::Resort::Info
|
5
|
+
include OnTheSnow::Resort::Lifts
|
6
|
+
include OnTheSnow::Resort::Slopes
|
7
|
+
include OnTheSnow::Resort::Elevation
|
8
|
+
include OnTheSnow::Resort::Snow
|
9
|
+
include OnTheSnow::Resort::Weather
|
10
|
+
|
11
|
+
def initialize(url)
|
12
|
+
@url = url
|
13
|
+
@api = OnTheSnow::API.instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_hash
|
17
|
+
@hash ||= {"info" => infos, "elevation" => elevation, "lifts" => lifts, "slopes" => slopes, "snow" => snow, "weather" => weather}
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.all
|
21
|
+
if @resorts
|
22
|
+
@resorts
|
23
|
+
else
|
24
|
+
@resorts = {}
|
25
|
+
@resorts_count = 0
|
26
|
+
@api = OnTheSnow::API.instance
|
27
|
+
@api.states.each_value do |state|
|
28
|
+
@api.rss(state["rss"]).items.each do |item|
|
29
|
+
url = @api.build_profile_url_from_snow_resort_url(item.guid)
|
30
|
+
resort = new(url)
|
31
|
+
@resorts[(@resorts_count+=1).to_s] = resort.to_hash
|
32
|
+
#warn "grab #{resort.infos["name"]} => #{resort.inspect}\n"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
@resorts
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def dom(name)
|
41
|
+
css_selector = case name
|
42
|
+
when :elevation
|
43
|
+
"#resort_elevation"
|
44
|
+
when :info
|
45
|
+
".resort_name"
|
46
|
+
when :lifts
|
47
|
+
"#resort_lifts"
|
48
|
+
when :slopes
|
49
|
+
"#resort_terrain"
|
50
|
+
when :snow
|
51
|
+
".snow_report"
|
52
|
+
when :weather
|
53
|
+
".forecast_content"
|
54
|
+
when :states
|
55
|
+
".rel_regions a"
|
56
|
+
else
|
57
|
+
raise "Missing dom element"
|
58
|
+
end
|
59
|
+
|
60
|
+
@api.profile(url).search(css_selector)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Resort
|
3
|
+
module Slopes
|
4
|
+
|
5
|
+
def slopes
|
6
|
+
@slopes ||= {"beginner" => beginner_slopes, "intermediate" => intermediate_slopes, "advanced" => advanced_slopes, "expert" => expert_slopes} unless dom(:slopes).empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def beginner_slopes
|
10
|
+
@beginner_slopes ||= dom(:slopes).search(".beginner").text.split.join unless dom(:slopes).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def intermediate_slopes
|
14
|
+
@intermediate_slopes ||= dom(:slopes).search(".intermediate").text.split.join unless dom(:slopes).empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def advanced_slopes
|
18
|
+
@advanced_slopes ||= dom(:slopes).search(".advanced").text.split.join unless dom(:slopes).empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
def expert_slopes
|
22
|
+
@expert_slopes ||= dom(:slopes).search(".expert").text.split.join unless dom(:slopes).empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Resort
|
3
|
+
module Snow
|
4
|
+
|
5
|
+
def snow
|
6
|
+
@snow ||= {"last_24" => last_24, "last_48" => last_48, "last_72" => last_72} unless dom(:snow).empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def last_24
|
10
|
+
@last_24 ||= dom(:snow).search(".white_pill")[0].text.split.join unless dom(:snow).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def last_48
|
14
|
+
@last_48 ||= dom(:snow).search(".white_pill")[1].text.split.join unless dom(:snow).empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def last_72
|
18
|
+
@last_72 ||= dom(:snow).search(".white_pill")[2].text.split.join unless dom(:snow).empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module Resort
|
3
|
+
module Weather
|
4
|
+
|
5
|
+
def weather
|
6
|
+
@weather ||= {"date" => date, "temperature" => {"f" => degree_in_f, "c" => degree_in_c}, "condition" => condition} unless dom(:weather).empty?
|
7
|
+
end
|
8
|
+
|
9
|
+
def date
|
10
|
+
@date ||= dom(:weather).search(".today p").first.text unless dom(:weather).empty?
|
11
|
+
end
|
12
|
+
|
13
|
+
def degree
|
14
|
+
@degree ||= dom(:weather).search(".temperature").first.text unless dom(:weather).empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def degree_in_f
|
18
|
+
@degree_in_f ||= degree.split(" / ")[0] unless dom(:weather).empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
def degree_in_c
|
22
|
+
@degree_in_c ||= degree.split(" / ")[1] unless dom(:weather).empty?
|
23
|
+
end
|
24
|
+
|
25
|
+
def condition
|
26
|
+
@condition ||= dom(:weather).search(".condition").text unless dom(:weather).empty?
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module OnTheSnow
|
2
|
+
module State
|
3
|
+
class State
|
4
|
+
attr_reader :state_name, :region_name, :state_rss
|
5
|
+
|
6
|
+
def initialize(state_name, region_name, state_rss)
|
7
|
+
@state_name = state_name
|
8
|
+
@region_name = region_name
|
9
|
+
@state_rss = state_rss
|
10
|
+
@api = OnTheSnow::API.instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.all
|
14
|
+
if @states
|
15
|
+
@states
|
16
|
+
else
|
17
|
+
@states = {}
|
18
|
+
@api = OnTheSnow::API.instance
|
19
|
+
@api.sitemap.css('#site_map_rss').each{|element|
|
20
|
+
cols = [".colA",".colB"]
|
21
|
+
@states_count = 0
|
22
|
+
cols.each do |col|
|
23
|
+
region = element.css(col)
|
24
|
+
states = region.css('p a')
|
25
|
+
|
26
|
+
states.each do |state|
|
27
|
+
region_name = @api.remove_chars(element.css("#{col} h3").children.to_s)
|
28
|
+
state_name = @api.remove_chars(state.children.to_s)
|
29
|
+
state_rss = "#{::OnTheSnow.config.url}#{state.attributes["href"].value}"
|
30
|
+
state_instance = new(state_name, region_name, state_rss)
|
31
|
+
@states[(@states_count+=1).to_s] = state_instance.to_hash
|
32
|
+
end
|
33
|
+
end
|
34
|
+
}
|
35
|
+
end
|
36
|
+
@states
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_hash
|
40
|
+
{"name" => state_name, "region" => region_name, "rss" => state_rss}
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'onthesnow/state/state'
|
data/lib/onthesnow.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'simple-rss'
|
4
|
+
|
5
|
+
require "onthesnow/version"
|
6
|
+
require 'onthesnow/helper'
|
7
|
+
require 'onthesnow/api'
|
8
|
+
require 'onthesnow/region'
|
9
|
+
require 'onthesnow/state'
|
10
|
+
require 'onthesnow/resort'
|
11
|
+
require 'onthesnow/config'
|
12
|
+
|
13
|
+
module OnTheSnow
|
14
|
+
def self.config(&block)
|
15
|
+
if block_given?
|
16
|
+
yield config
|
17
|
+
else
|
18
|
+
@__config ||= OnTheSnow::Config.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
OnTheSnow.config do |c|
|
24
|
+
c.url "http://www.onthesnow.com"
|
25
|
+
c.site_map_rss_url "http://www.onthesnow.com/site_map_rss.html"
|
26
|
+
end
|
data/onthesnow.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "onthesnow/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "onthesnow"
|
7
|
+
s.version = Onthesnow::VERSION
|
8
|
+
s.authors = ["Jan Owiesniak"]
|
9
|
+
s.email = ["jowiesniak@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{"Small API to communicate with http://www.onthesnow.com"}
|
12
|
+
s.description = %q{""}
|
13
|
+
|
14
|
+
s.rubyforge_project = "onthesnow"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "fakeweb"
|
24
|
+
s.add_development_dependency "mocha"
|
25
|
+
|
26
|
+
s.add_runtime_dependency "nokogiri"
|
27
|
+
s.add_runtime_dependency "simple-rss"
|
28
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<rss version="2.0"
|
3
|
+
xmlns:blogChannel="http://backend.userland.com/blogChannelModule"
|
4
|
+
xmlns:ots="http://www.onthesnow.com/ots_rss_namespace/"
|
5
|
+
>
|
6
|
+
<channel>
|
7
|
+
<title>Alaska Ski & Snow Report | OnTheSnow.com</title>
|
8
|
+
<link>http://www.onthesnow.com/alaska/skireport.html?XE_AFF=rss</link>
|
9
|
+
<description>Includes the Alaska ski report and weather reports for all ski resorts in Alaska. OnTheSnow is primary source of all Alaska snow reports on the web.</description>
|
10
|
+
<language>en-us</language>
|
11
|
+
<copyright>Copyright 2010, OnTheSnow. Commercial use of this feed is prohibited without specific written approval from Mountain News. For commercial use feeds, please visit MountainNews.com</copyright>
|
12
|
+
<image>
|
13
|
+
<title>OnTheSnow</title>
|
14
|
+
<url>http://images.onthesnow.com/ots/images/logo_image/en/snow-report.gif</url>
|
15
|
+
<link>http://www.onthesnow.com</link>
|
16
|
+
</image>
|
17
|
+
<item>
|
18
|
+
<title>Alyeska</title>
|
19
|
+
<description>Open / Past 48 Hours: 0in. / Primary: Packed Powder / Base Depth: 112in.</description>
|
20
|
+
<guid isPermaLink="true">http://www.onthesnow.com/alaska/alyeska-resort/skireport.html?XE_AFF=rss</guid>
|
21
|
+
<pubDate>Fri, 20 Jan 2012 12:17:50 -0500</pubDate>
|
22
|
+
<ots:open_staus>Open</ots:open_staus>
|
23
|
+
<ots:resort_id>11</ots:resort_id>
|
24
|
+
<ots:base_depth>112</ots:base_depth>
|
25
|
+
<ots:snowfall_48hr>0</ots:snowfall_48hr>
|
26
|
+
<ots:region_name>Alaska</ots:region_name>
|
27
|
+
<ots:surface_condition>Packed Powder</ots:surface_condition>
|
28
|
+
<ots:base_depth_metric>inches</ots:base_depth_metric>
|
29
|
+
<ots:snowfall_48hr_metric>inches</ots:snowfall_48hr_metric>
|
30
|
+
<ots:resort_rss_link>http://www.onthesnow.com/alaska/alyeska-resort/snow.rss</ots:resort_rss_link>
|
31
|
+
</item>
|
32
|
+
<item>
|
33
|
+
<title>Eaglecrest</title>
|
34
|
+
<description>Open / Past 48 Hours: 0in. / Primary: Packed Powder / Base Depth: 148in.</description>
|
35
|
+
<guid isPermaLink="true">http://www.onthesnow.com/alaska/eaglecrest-ski-area/skireport.html?XE_AFF=rss</guid>
|
36
|
+
<pubDate>Fri, 20 Jan 2012 10:56:23 -0500</pubDate>
|
37
|
+
<ots:open_staus>Open</ots:open_staus>
|
38
|
+
<ots:resort_id>141</ots:resort_id>
|
39
|
+
<ots:base_depth>148</ots:base_depth>
|
40
|
+
<ots:snowfall_48hr>0</ots:snowfall_48hr>
|
41
|
+
<ots:region_name>Alaska</ots:region_name>
|
42
|
+
<ots:surface_condition>Packed Powder</ots:surface_condition>
|
43
|
+
<ots:base_depth_metric>inches</ots:base_depth_metric>
|
44
|
+
<ots:snowfall_48hr_metric>inches</ots:snowfall_48hr_metric>
|
45
|
+
<ots:resort_rss_link>http://www.onthesnow.com/alaska/eaglecrest-ski-area/snow.rss</ots:resort_rss_link>
|
46
|
+
</item>
|
47
|
+
<item>
|
48
|
+
<title>Hilltop</title>
|
49
|
+
<description>Open / Past 48 Hours: 0in. / Primary: Machine Groomed / Base Depth: 12in.</description>
|
50
|
+
<guid isPermaLink="true">http://www.onthesnow.com/alaska/hilltop-ski-area/skireport.html?XE_AFF=rss</guid>
|
51
|
+
<pubDate>Fri, 20 Jan 2012 08:24:41 -0500</pubDate>
|
52
|
+
<ots:open_staus>Open</ots:open_staus>
|
53
|
+
<ots:resort_id>2908</ots:resort_id>
|
54
|
+
<ots:base_depth>12</ots:base_depth>
|
55
|
+
<ots:snowfall_48hr>0</ots:snowfall_48hr>
|
56
|
+
<ots:region_name>Alaska</ots:region_name>
|
57
|
+
<ots:surface_condition>Machine Groomed</ots:surface_condition>
|
58
|
+
<ots:base_depth_metric>inches</ots:base_depth_metric>
|
59
|
+
<ots:snowfall_48hr_metric>inches</ots:snowfall_48hr_metric>
|
60
|
+
<ots:resort_rss_link>http://www.onthesnow.com/alaska/hilltop-ski-area/snow.rss.html</ots:resort_rss_link>
|
61
|
+
</item>
|
62
|
+
</channel>
|
63
|
+
</rss>
|