weather_finder 0.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 +9 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +42 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/weather-finder +6 -0
- data/lib/weather_finder/all_usa_zip.txt +40933 -0
- data/lib/weather_finder/cli.rb +110 -0
- data/lib/weather_finder/version.rb +3 -0
- data/lib/weather_finder/weather-scrapper.rb +59 -0
- data/lib/weather_finder.rb +6 -0
- data/spec.md +9 -0
- data/weather_finder-0.1.0.gem +0 -0
- data/weather_finder.gemspec +36 -0
- metadata +117 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
class WeatherFinder::CLI
|
|
2
|
+
|
|
3
|
+
def call
|
|
4
|
+
input = ""
|
|
5
|
+
|
|
6
|
+
while input != "exit"
|
|
7
|
+
puts "What is the zip code you would like to know the weather at?"
|
|
8
|
+
puts "exit to quit"
|
|
9
|
+
|
|
10
|
+
input = gets.chomp
|
|
11
|
+
state = self.zip_code?(input)#check zip code
|
|
12
|
+
|
|
13
|
+
if state && input.length == 5
|
|
14
|
+
self.weather(input)
|
|
15
|
+
elsif !state && input.downcase != 'exit'
|
|
16
|
+
puts "Invalid Input"
|
|
17
|
+
end
|
|
18
|
+
end# end of while loop
|
|
19
|
+
self.goodbye
|
|
20
|
+
end # call method end
|
|
21
|
+
|
|
22
|
+
def weather(zip_code)# prints current weather
|
|
23
|
+
weather = WeatherFinder::Scrapper.basic_weather(zip_code)
|
|
24
|
+
|
|
25
|
+
puts "**************************************"
|
|
26
|
+
puts "It is currently #{weather[0]}"
|
|
27
|
+
puts "But it feels like #{weather[2]}"
|
|
28
|
+
puts "With a UV index of #{weather[1]}"
|
|
29
|
+
puts "**************************************"
|
|
30
|
+
|
|
31
|
+
self.menu(zip_code)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def weather_hourly(zip_code)
|
|
35
|
+
|
|
36
|
+
hourly_weather = WeatherFinder::Scrapper.hourly_weather(zip_code)
|
|
37
|
+
|
|
38
|
+
puts "------------------------------------------------------------------------"
|
|
39
|
+
hourly_weather.each do |row|
|
|
40
|
+
print "Time:#{row[0]} "
|
|
41
|
+
print "Description:#{row[1]} "
|
|
42
|
+
print "Temp:#{row[2]} "
|
|
43
|
+
print "Feels Like:#{row[3]} "
|
|
44
|
+
print "Percip:#{row[4]} "
|
|
45
|
+
print "Humidity:#{row[5]} "
|
|
46
|
+
puts "Wind:#{row[6]} "
|
|
47
|
+
puts "------------------------------------------------------------------------"
|
|
48
|
+
end
|
|
49
|
+
end# end of weather_hourly
|
|
50
|
+
|
|
51
|
+
def weather_ten_day(zip_code)
|
|
52
|
+
|
|
53
|
+
ten_day_weather = WeatherFinder::Scrapper.ten_day_weather(zip_code)
|
|
54
|
+
|
|
55
|
+
puts "------------------------------------------------------------------------"
|
|
56
|
+
ten_day_weather.each do |row|
|
|
57
|
+
print "Day:#{row[0]} "
|
|
58
|
+
print "Description:#{row[1]} "
|
|
59
|
+
print "High:#{row[2]} "
|
|
60
|
+
print "Low:#{row[3]} "
|
|
61
|
+
print "Percip:#{row[4]} "
|
|
62
|
+
print "Humidity:#{row[5]} "
|
|
63
|
+
puts "Wind:#{row[6]} "
|
|
64
|
+
puts "------------------------------------------------------------------------"
|
|
65
|
+
end
|
|
66
|
+
end# end of weather ten day
|
|
67
|
+
|
|
68
|
+
def menu(zip_code)
|
|
69
|
+
input = ""
|
|
70
|
+
|
|
71
|
+
while input.downcase != 'back' || input.downcase != 'exit'
|
|
72
|
+
|
|
73
|
+
puts "Would you like to look at the hourly or 10 day forcast?"
|
|
74
|
+
puts "Type 'hourly' or '10 day' to choose."
|
|
75
|
+
puts "type 'back' to choose a different zip code."
|
|
76
|
+
puts "Or type 'exit' to quit."
|
|
77
|
+
input = gets.chomp
|
|
78
|
+
|
|
79
|
+
if input.downcase == 'hourly'
|
|
80
|
+
self.weather_hourly(zip_code)
|
|
81
|
+
elsif input.downcase == '10 day' || input.downcase == 'ten day'
|
|
82
|
+
self.weather_ten_day(zip_code)
|
|
83
|
+
elsif input.downcase == 'back'
|
|
84
|
+
self.call
|
|
85
|
+
elsif input.downcase == 'exit'
|
|
86
|
+
self.goodbye
|
|
87
|
+
else
|
|
88
|
+
puts "Do not understand entry."
|
|
89
|
+
puts "Please enter a valid choice."
|
|
90
|
+
end#end of if
|
|
91
|
+
end#end of while
|
|
92
|
+
end#end of menu
|
|
93
|
+
|
|
94
|
+
def goodbye # prints goodbye messages and exits program
|
|
95
|
+
puts "Enjoy your day!"
|
|
96
|
+
exit
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def zip_code?(zip_code) #takes all zip codes and compares them to given zip
|
|
100
|
+
valid = false
|
|
101
|
+
|
|
102
|
+
File.open("../weather_finder/lib/weather_finder/all_usa_zip.txt").each do |zip| #read from file to test valid zip
|
|
103
|
+
if zip.to_i == zip_code.to_i
|
|
104
|
+
valid = true
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
valid
|
|
109
|
+
end#end of zip code validation
|
|
110
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
class WeatherFinder::Scrapper
|
|
2
|
+
attr_accessor :temp, :uv, :feels_like, :ten_day_arraay, :hourly_array
|
|
3
|
+
|
|
4
|
+
def self.basic_weather(zip_code)
|
|
5
|
+
self.basic_scrapper(zip_code)
|
|
6
|
+
[@temp,@uv,@feel_like]
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.basic_scrapper(zip_code)
|
|
10
|
+
doc = Nokogiri::HTML(open("https://weather.com/weather/today/l/#{zip_code}:4:US"))
|
|
11
|
+
@temp = doc.css(".today_nowcard-temp").text
|
|
12
|
+
@uv = doc.css(".today_nowcard-hilo div").text
|
|
13
|
+
@feel_like = doc.css(".deg-feels").text
|
|
14
|
+
@uv.gsub!("UV Index ", "")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.hourly_weather(zip_code)
|
|
18
|
+
@hourly_array = []
|
|
19
|
+
|
|
20
|
+
doc = Nokogiri::HTML(open("https://weather.com/weather/today/l/#{zip_code}:4:US"))
|
|
21
|
+
hourly_url = doc.css("ul li a")[1]['href']
|
|
22
|
+
hourly_doc = Nokogiri::HTML(open("https://weather.com#{hourly_url}"))
|
|
23
|
+
hourly_doc.css("tbody tr").each_with_index do |row, i|
|
|
24
|
+
|
|
25
|
+
time = row.css(".dsx-date").text
|
|
26
|
+
descrip = row.css(".description").text
|
|
27
|
+
temp = row.css(".temp").text
|
|
28
|
+
feels = row.css(".feels").text
|
|
29
|
+
precip = row.css(".precip").text
|
|
30
|
+
humidity = row.css(".humidity").text
|
|
31
|
+
wind = row.css(".wind").text
|
|
32
|
+
|
|
33
|
+
@hourly_array[i] = [time,descrip,temp,feels,precip,humidity,wind]
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
@hourly_array
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.ten_day_weather(zip_code)
|
|
40
|
+
@ten_day_array = []
|
|
41
|
+
doc = Nokogiri::HTML(open("https://weather.com/weather/today/l/#{zip_code}:4:US"))
|
|
42
|
+
ten_day_url = doc.css("ul li a")[2]['href']
|
|
43
|
+
ten_day_doc = Nokogiri::HTML(open("https://weather.com#{ten_day_url}"))
|
|
44
|
+
ten_day_doc.css("tbody tr").each_with_index do |row, i|
|
|
45
|
+
|
|
46
|
+
time = row.css(".date-time").text
|
|
47
|
+
descrip = row.css(".description").text
|
|
48
|
+
high = row.css(".temp span")[0].text
|
|
49
|
+
low = row.css(".temp span")[2].text
|
|
50
|
+
precip = row.css(".precip").text
|
|
51
|
+
humidity = row.css(".humidity").text
|
|
52
|
+
wind = row.css(".wind").text
|
|
53
|
+
|
|
54
|
+
@ten_day_array[i] = [time,descrip,high,low,precip,humidity,wind]
|
|
55
|
+
end
|
|
56
|
+
@ten_day_array
|
|
57
|
+
end#end of ten day weather
|
|
58
|
+
|
|
59
|
+
end
|
data/spec.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Specifications for the CLI Assessment
|
|
2
|
+
|
|
3
|
+
Specs:
|
|
4
|
+
- [x] Have a CLI for interfacing with the application # prints outs weather basics after asking for zip code. Then
|
|
5
|
+
ask if you want an hourly forecast or 10 day forecast.
|
|
6
|
+
- [x] Pull data from an external source #takes data from weather.com to tell the user the weather at their requested
|
|
7
|
+
zip code.
|
|
8
|
+
- [x] Implement both list and detail views # upon entering your zip code the program will print your current weather.
|
|
9
|
+
Then upon request will give you a more detailed forecast in the form of hourly or 10 day forecast.
|
|
Binary file
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require "weather_finder/version"
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "weather_finder"
|
|
8
|
+
spec.version = WeatherFinder::VERSION
|
|
9
|
+
spec.authors = ["'Justin Tooley'"]
|
|
10
|
+
spec.email = ["'jstooley823@gmail.com'"]
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{finds weather near you using zip code}
|
|
13
|
+
spec.homepage = "https://github.com/jstooley/weather_finder.git"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
18
|
+
#if spec.respond_to?(:metadata)
|
|
19
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
|
20
|
+
# else
|
|
21
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
|
22
|
+
# "public gem pushes."
|
|
23
|
+
#end
|
|
24
|
+
|
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
26
|
+
f.match(%r{^(test|spec|features)/})
|
|
27
|
+
end
|
|
28
|
+
spec.bindir = "exe"
|
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ["lib"]
|
|
31
|
+
|
|
32
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
|
33
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
34
|
+
spec.add_development_dependency 'pry', '~> 0'
|
|
35
|
+
spec.add_runtime_dependency 'nokogiri', '~> 0'
|
|
36
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: weather_finder
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- "'Justin Tooley'"
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-09-24 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.15'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.15'
|
|
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: pry
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: nokogiri
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
62
|
+
type: :runtime
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
description:
|
|
70
|
+
email:
|
|
71
|
+
- "'jstooley823@gmail.com'"
|
|
72
|
+
executables: []
|
|
73
|
+
extensions: []
|
|
74
|
+
extra_rdoc_files: []
|
|
75
|
+
files:
|
|
76
|
+
- ".gitignore"
|
|
77
|
+
- CODE_OF_CONDUCT.md
|
|
78
|
+
- Gemfile
|
|
79
|
+
- LICENSE.txt
|
|
80
|
+
- README.md
|
|
81
|
+
- Rakefile
|
|
82
|
+
- bin/console
|
|
83
|
+
- bin/setup
|
|
84
|
+
- bin/weather-finder
|
|
85
|
+
- lib/weather_finder.rb
|
|
86
|
+
- lib/weather_finder/all_usa_zip.txt
|
|
87
|
+
- lib/weather_finder/cli.rb
|
|
88
|
+
- lib/weather_finder/version.rb
|
|
89
|
+
- lib/weather_finder/weather-scrapper.rb
|
|
90
|
+
- spec.md
|
|
91
|
+
- weather_finder-0.1.0.gem
|
|
92
|
+
- weather_finder.gemspec
|
|
93
|
+
homepage: https://github.com/jstooley/weather_finder.git
|
|
94
|
+
licenses:
|
|
95
|
+
- MIT
|
|
96
|
+
metadata: {}
|
|
97
|
+
post_install_message:
|
|
98
|
+
rdoc_options: []
|
|
99
|
+
require_paths:
|
|
100
|
+
- lib
|
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
102
|
+
requirements:
|
|
103
|
+
- - ">="
|
|
104
|
+
- !ruby/object:Gem::Version
|
|
105
|
+
version: '0'
|
|
106
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - ">="
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '0'
|
|
111
|
+
requirements: []
|
|
112
|
+
rubyforge_project:
|
|
113
|
+
rubygems_version: 2.6.13
|
|
114
|
+
signing_key:
|
|
115
|
+
specification_version: 4
|
|
116
|
+
summary: finds weather near you using zip code
|
|
117
|
+
test_files: []
|