onthesnow 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|