local_ski_report 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c81b4413be043fb88b8cc99bba6ed827c7e94332
4
+ data.tar.gz: 7c1535b05eae57d6ed8a2253a35ebcb62d762144
5
+ SHA512:
6
+ metadata.gz: ef284304987708aee661fb925e5d66b7c12917ccd5f8e34bba6f909ef8a30078f2fe91081cc4d7bacc5dff44fd05f231a654b6d00b9dfd21c414078839b95451
7
+ data.tar.gz: 2588426c252a1e889187746f3bef1bb7ffd58f1fa94c84d7a62f986adecd5bb519b5c9fd700a62183b57ac594c12adb72b8578f03f47703727dee5e5de3da275
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ require "bundler/setup"
3
+ require_relative "../lib/local_ski_report"
4
+
5
+ LocalSkiReport::CLI.new.call
@@ -0,0 +1,9 @@
1
+ require 'pry'
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+ require 'terminal-table'
5
+
6
+ require_relative '../lib/local_ski_report/cli'
7
+ require_relative '../lib/local_ski_report/report'
8
+ require_relative '../lib/local_ski_report/resort'
9
+ require_relative '../lib/local_ski_report/scraper'
@@ -0,0 +1,163 @@
1
+ # Our CLI Controller
2
+ class LocalSkiReport::CLI
3
+
4
+ attr_accessor :resort
5
+
6
+ STATES_WITH_RESORTS = [
7
+ { :midwest => ["Illinois", "Indiana", "Iowa", "Kansas", "Michigan", "Minnesota", "Missouri", "Ohio","Wisconsin"] },
8
+ { :northeast => ["Connecticut", "Maine", "Massachusetts", "New Hampshire", "New Jersey", "New York", "Pennsylvania", "Rhode Island", "Vermont"] },
9
+ { :northwest => ["Alaska", "Idaho", "Oregon", "Washington"] },
10
+ { :rockies => ["Colorado", "Montana", "New Mexico", "Utah", "Wyoming"] },
11
+ { :southeast => ["Alabama", "Georgia", "Maryland", "North Carolina", "Tennessee", "Virginia", "West Virginia"] },
12
+ { :west_coast => ["Arizona", "California", "Nevada"] }
13
+ ]
14
+
15
+ def initialize
16
+ LocalSkiReport::Scraper.scrap_resorts_page("united-states")
17
+ end
18
+
19
+ def call
20
+ greeting
21
+ menu
22
+ exit_msg
23
+ end
24
+
25
+ def menu
26
+ region_num = select_region
27
+ user_region = get_key(region_num)
28
+ separator(50)
29
+
30
+ state_num = select_state(region_num, user_region)
31
+ user_state = get_state(region_num, user_region, state_num)
32
+ separator(50)
33
+
34
+ select_resort(user_state)
35
+ display_report
36
+
37
+ input = nil
38
+ while input != "exit"
39
+ puts "Type: 'more' for detailed report, 'new' for new search, 'exit' to Quit."
40
+ input = gets.chomp.downcase
41
+
42
+ case input
43
+ when "new"
44
+ menu
45
+ break
46
+ when "more"
47
+ display_xt_report
48
+ when "exit"
49
+ puts
50
+ puts
51
+ break
52
+ else
53
+ puts "Invalid command entered."
54
+ end
55
+ end
56
+ end
57
+
58
+ def greeting
59
+ separator(40)
60
+ puts "Welcome to Local Ski Report gem"
61
+ separator(40)
62
+ puts "Let's Get Your Local Ski Report"
63
+ puts " "
64
+ end
65
+
66
+ def get_key(num)
67
+ STATES_WITH_RESORTS[num].keys[0]
68
+ end
69
+
70
+ def get_state(reg_num, user_reg, st_num)
71
+ STATES_WITH_RESORTS[reg_num][user_reg][st_num] + ", USA"
72
+ end
73
+
74
+ def list_resorts(state)
75
+ resorts = LocalSkiReport::Resort.find_by_location(state)
76
+ # resorts = LocalSkiReport::Scraper.scrap_resorts_page(state)
77
+ resorts.each.with_index(1) { |r, i| puts "#{i}. #{r.name}" }
78
+ resorts
79
+ end
80
+
81
+ def list_regions
82
+ i = 1
83
+ STATES_WITH_RESORTS.each do |region|
84
+ region.each_key do |k|
85
+ puts "#{i}. #{k.to_s.gsub("_", " ").upcase}"
86
+ i += 1
87
+ end
88
+ end
89
+ end
90
+
91
+ def list_states(num)
92
+ STATES_WITH_RESORTS[num].each_value do |states|
93
+ states.each.with_index(1) { |state, i| puts "#{i}. #{state}" }
94
+ end
95
+ end
96
+
97
+ def select_region
98
+ list_regions
99
+ separator(50)
100
+ puts "Select a region to check? type number: "
101
+ input = gets.chomp.to_i - 1
102
+ if input.between?(0, STATES_WITH_RESORTS.size - 1)
103
+ input
104
+ else
105
+ separator(55)
106
+ puts "Invalid number. Please select a number between 1 - #{STATES_WITH_RESORTS.size}: "
107
+ separator(55)
108
+ select_region
109
+ end
110
+ end
111
+
112
+ def select_resort(state)
113
+ resorts_arr = list_resorts(state)
114
+ separator(50)
115
+ puts "Select a Resort or Ski-Area for the latest Report: "
116
+ input = gets.chomp.to_i - 1
117
+ if input.between?(0, resorts_arr.size - 1)
118
+ @resort = resorts_arr[input]
119
+ else
120
+ separator(60)
121
+ puts "Invalid Choice. Please choose a Resort # between 1 - #{resorts_arr.size}."
122
+ separator(60)
123
+ select_resort(state)
124
+ end
125
+ end
126
+
127
+ def select_state(region_num, region_key)
128
+ list_states(region_num)
129
+ separator(50)
130
+ puts "Select a State to check? type number: "
131
+ input = gets.chomp.to_i - 1
132
+ if input.between?(0, STATES_WITH_RESORTS[region_num][region_key].size - 1)
133
+ input
134
+ else
135
+ separator(55)
136
+ puts "Invalid Choice. Please choose a Resort # between 1 - #{STATES_WITH_RESORTS[region_num][region_key].size}."
137
+ separator(55)
138
+ select_state(region_num, region_key)
139
+ end
140
+ end
141
+
142
+ def separator(num)
143
+ puts "-" * num
144
+ end
145
+
146
+ def display_xt_report
147
+ report = resort.reports.first
148
+ LocalSkiReport::Scraper.scrap_report_page(report)
149
+ puts report.xt_report
150
+ end
151
+
152
+ def display_report
153
+ puts @resort.reports.first.report
154
+ end
155
+
156
+ def exit_msg
157
+ separator(60)
158
+ puts "Check back later for the latest Ski reports."
159
+ puts "Thanks for using Local Ski Report gem!"
160
+ separator(60)
161
+ end
162
+
163
+ end
@@ -0,0 +1,86 @@
1
+ class LocalSkiReport::Report
2
+ attr_accessor :date, :url, :status, :new_snow, :base, :lifts_open, :resort, :elevation, :trails, :tickets
3
+
4
+ @@all = []
5
+
6
+ def initialize(date, url, status, new_snow, base, lifts_open)
7
+ @date = date
8
+ @url = url
9
+ @status = status
10
+ @new_snow = new_snow
11
+ @base = base
12
+ @lifts_open = lifts_open
13
+ @@all << self
14
+ end
15
+
16
+ def self.all
17
+ @@all
18
+ end
19
+
20
+ def self.clear
21
+ @@all.clear
22
+ end
23
+
24
+ def self.create(html)
25
+ date = html.css('div.lUpdate').text
26
+ url = html.css('td')[3].css('a').first['href']
27
+ status = self.get_status(html.css('td')[1].css('div').first['class'].split(" ").pop)
28
+ if html.css('td')[2].css('b')[0]
29
+ new_snow = html.css('td')[2].css('b')[0].text
30
+ else
31
+ new_snow = 'N/A'
32
+ end
33
+ base = html.css('td')[3].css('b')[0].text
34
+ lifts_open = self.get_lift_status(html)
35
+ self.new(date, url, status, new_snow, base, lifts_open)
36
+ end
37
+
38
+ def self.get_lift_status(html)
39
+ if html.css('td')[4].text.split("/").first == ""
40
+ 0
41
+ else
42
+ html.css('td')[4].text.split("/").first
43
+ end
44
+ end
45
+
46
+ def self.get_status(state)
47
+ case state
48
+ when "stateD1"
49
+ "Open"
50
+ when "stateD2"
51
+ "Closed"
52
+ else
53
+ "Weekends Only"
54
+ end
55
+ end
56
+
57
+ def get_ticket_prices(row)
58
+ arr = row.css('td').text.gsub("US","").split
59
+ [arr[1], arr[3]]
60
+ end
61
+
62
+ def report
63
+ rows = []
64
+ rows << [self.resort.name, {:value => self.date, :alignment => :center}, self.status, {:value => self.new_snow, :alignment => :center},{:value => self.base, :alignment => :center}, {:value => "#{self.lifts_open}/#{resort.lifts}", :alignment => :right}]
65
+ Terminal::Table.new :title => "Ski Report", :headings => ['Resort Name', 'Updated On', 'Status', 'New Snow', 'Base Depth', 'Lifts Open'], :rows => rows
66
+ end
67
+
68
+ def get_xt_report_info(html)
69
+ table = html.css('table')
70
+ rows = table.css('tr')
71
+ @elevation = rows[1].css('td').text.split(" - ")
72
+ @trails = rows[2].css('td').text.gsub("|","").split
73
+ @tickets = get_ticket_prices(rows[4])
74
+ end
75
+
76
+ def xt_report
77
+ rows = []
78
+ rows << ['ELEVATION', "Base:", "#{elevation[0]}", "Summit:", "#{elevation[1]}"]
79
+ rows << ["TRAILS", "Beginner: #{trails[0]}", "Intermediate: #{trails[1]}", "Advanced: #{trails[2]}", "Expert: #{trails[3]}"]
80
+ rows << ["TICKET PRICES", "Starting at:", "#{tickets[0]}", {:value => "to", :alignment => :center}, "#{tickets[1]}"]
81
+ table = Terminal::Table.new :title => "#{self.resort.name} Full Report", :rows => rows
82
+ table.style = {:all_separators => true}
83
+ table
84
+ end
85
+
86
+ end
@@ -0,0 +1,44 @@
1
+ class LocalSkiReport::Resort
2
+ attr_accessor :name, :url, :location, :lifts, :reports
3
+
4
+ @@all = []
5
+
6
+ def initialize(name, url, location, lifts)
7
+ @reports = []
8
+ @name = name
9
+ @url = url
10
+ @location = location
11
+ @lifts = lifts
12
+ @@all << self
13
+ end
14
+
15
+ def add_report(report)
16
+ report.resort = self
17
+ self.reports << report
18
+ end
19
+
20
+ def self.all
21
+ @@all
22
+ end
23
+
24
+ def self.clear
25
+ @@all.clear
26
+ end
27
+
28
+ def self.create(html)
29
+ name = html.css('td div.name').text
30
+ url = html.css('div.name a').first['href']
31
+ location = html.css('td div.rRegion').text
32
+ lifts = html.css('td')[4].text.split("/").last
33
+ self.new(name, url, location, lifts)
34
+ end
35
+
36
+ def self.find_by_location(location)
37
+ self.all.find_all { |resort| resort.location == location }
38
+ end
39
+
40
+ def self.sort_by_lifts_desc
41
+ self.all.sort { |x, y| y.lifts.to_i <=> x.lifts.to_i }
42
+ end
43
+
44
+ end
@@ -0,0 +1,36 @@
1
+ class LocalSkiReport::Scraper
2
+
3
+ def self.get_page(url)
4
+ html = open(url)
5
+ Nokogiri::HTML(html)
6
+ end
7
+
8
+ def self.get_table(html)
9
+ table = html.css('table')
10
+ table_rows = table.css('tr')
11
+ table_rows.slice(2, table_rows.size - 3)
12
+ end
13
+
14
+ def self.scrap_resorts_page(state_url)
15
+ url = "http://www.onthesnow.com/#{state_url}/skireport.html"
16
+ doc = self.get_page(url)
17
+ table = get_table(doc)
18
+ self.create_resort_report(table)
19
+ end
20
+
21
+ def self.create_resort_report(table)
22
+ table.collect do |row|
23
+ new_resort = LocalSkiReport::Resort.create(row)
24
+ new_report = LocalSkiReport::Report.create(row)
25
+ new_resort.add_report(new_report)
26
+ new_resort
27
+ end
28
+ end
29
+
30
+ def self.scrap_report_page(report)
31
+ url = "http://www.onthesnow.com#{report.resort.url}"
32
+ doc = self.get_page(url)
33
+ report.get_xt_report_info(doc)
34
+ end
35
+
36
+ end
@@ -0,0 +1,6 @@
1
+
2
+ module LocalSkiReport
3
+
4
+ end
5
+
6
+ require_relative '../config/environment'
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: local_ski_report
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.3
5
+ platform: ruby
6
+ authors:
7
+ - Nick Alan DAmico
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-08-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.14'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.14'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: terminal-table
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.8.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.8.0
97
+ description: Find the latest ski report from your local ski area or resort.
98
+ email:
99
+ - nickalan82@icloud.com
100
+ executables:
101
+ - local_ski_report
102
+ extensions: []
103
+ extra_rdoc_files: []
104
+ files:
105
+ - bin/local_ski_report
106
+ - config/environment.rb
107
+ - lib/local_ski_report.rb
108
+ - lib/local_ski_report/cli.rb
109
+ - lib/local_ski_report/report.rb
110
+ - lib/local_ski_report/resort.rb
111
+ - lib/local_ski_report/scraper.rb
112
+ homepage: https://github.com/Nick-Damico/local-ski-report-cli-gem
113
+ licenses:
114
+ - MIT
115
+ metadata: {}
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ required_rubygems_version: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project:
132
+ rubygems_version: 2.5.1
133
+ signing_key:
134
+ specification_version: 4
135
+ summary: Ski Reports from local Ski Areas
136
+ test_files: []