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 ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm gemset use ree@onthesnow --create
data/CHANGELOG ADDED
@@ -0,0 +1,3 @@
1
+ ## v0.0.1
2
+
3
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in onthesnow.gemspec
4
+ gemspec
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,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+ task :default => :spec
@@ -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,7 @@
1
+ require 'onthesnow/resort/info'
2
+ require 'onthesnow/resort/elevation'
3
+ require 'onthesnow/resort/lifts'
4
+ require 'onthesnow/resort/slopes'
5
+ require 'onthesnow/resort/snow'
6
+ require 'onthesnow/resort/weather'
7
+ require 'onthesnow/resort/resort'
@@ -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'
@@ -0,0 +1,3 @@
1
+ module Onthesnow
2
+ VERSION = "0.0.1"
3
+ end
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 &#x26; 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>