weatherpup 0.1.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ccf304b879c999b5e58da02ad948c15dc7041847c94e362a970ceaaa20abdf7b
4
+ data.tar.gz: 32c5cc102476833813df34b4d432c02b999ff2e42b8b7cb8dc0163dfee20282b
5
+ SHA512:
6
+ metadata.gz: 9430501c9668e79f68369d01150cd615ce05ccee7b954e8e7ef2cb4607d5e2490d07d7ce16ac03ee83426a22fbf2af55c4d976a9fe6e47dfa18e6e6f4715e4cb
7
+ data.tar.gz: af63828fdc866c270e200d87ef2b935a5c4d3b751696007164b604a5fa8f63648ceeed97b623d7681293208c86629e85cacc36862f1a30c8f466952bac9cecac
data/.gitignore ADDED
@@ -0,0 +1,13 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
12
+ .DS_Store
13
+ NOTES.md
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ rvm:
6
+ - 2.3.6
7
+ before_install: gem install bundler -v 2.0.2
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ Version 0.1.0: Initial working version
2
+ Version 0.1.1: Updated gemspec file
3
+ Version 0.1.2: Fixed bug that caused it not to load
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+ # Specify your gem's dependencies in weatherpup.gemspec
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,51 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ weatherpup (0.1.1)
5
+ colorize (~> 0.8)
6
+ httparty (~> 0.17)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ coderay (1.1.2)
12
+ colorize (0.8.1)
13
+ diff-lcs (1.3)
14
+ httparty (0.17.0)
15
+ mime-types (~> 3.0)
16
+ multi_xml (>= 0.5.2)
17
+ method_source (0.9.2)
18
+ mime-types (3.2.2)
19
+ mime-types-data (~> 3.2015)
20
+ mime-types-data (3.2019.0331)
21
+ multi_xml (0.6.0)
22
+ pry (0.12.2)
23
+ coderay (~> 1.1.0)
24
+ method_source (~> 0.9.0)
25
+ rake (10.4.2)
26
+ rspec (3.8.0)
27
+ rspec-core (~> 3.8.0)
28
+ rspec-expectations (~> 3.8.0)
29
+ rspec-mocks (~> 3.8.0)
30
+ rspec-core (3.8.1)
31
+ rspec-support (~> 3.8.0)
32
+ rspec-expectations (3.8.4)
33
+ diff-lcs (>= 1.2.0, < 2.0)
34
+ rspec-support (~> 3.8.0)
35
+ rspec-mocks (3.8.1)
36
+ diff-lcs (>= 1.2.0, < 2.0)
37
+ rspec-support (~> 3.8.0)
38
+ rspec-support (3.8.2)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ bundler (~> 2.0)
45
+ pry (~> 0.12)
46
+ rake (~> 10.0)
47
+ rspec (~> 3.0)
48
+ weatherpup!
49
+
50
+ BUNDLED WITH
51
+ 2.0.2
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2019 Jeremiah Rodden
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # WeatherPup
2
+
3
+ Welcome to WeatherPup! WeatherPup is a CLI written in Ruby that fetches current weather information based on a user entered US Zip Code or a GPS Coordinate Pair (Latitude and Longitude)
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'weatherpup'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install weatherpup
20
+
21
+ ## Usage
22
+
23
+ After running the `weatherpup` executable from the `bin` folder, you'll be presented with a few options.
24
+
25
+ ```
26
+ 1. Fetch by Zip Code
27
+ 2. Fetch by GPS Coordinates (Latitude and Longitude)
28
+ 3. Fetch previously fetched conditions
29
+ ```
30
+
31
+ Type in `1` to get the current weather conditions by US Zip Code. After doing this, you'll be asked to type in the 5 digit zip code. You'll then be shown the current weather for that zip code. From there you'll have the option to go `back` to the main menu.
32
+
33
+ Type in `2` to get the current weather conditions by GPS Coordinates (Latitude and Longitude pair). After doing this, you'll be asked to type in the latitude in decimal format. Example Latitude in decimal format: `40.705204`
34
+
35
+ You'll then be asked to type in the longitude in decimal format. Example Longitude in decimal format: `-74.013845`
36
+
37
+ Then you'll be shown the current weather for that GPS Coordinate pair. From there you'll have the option to go `back` to the main menu.
38
+
39
+ Type in `3` to get a list of the previously fetched weather conditions. From there you'll have the option to select which previous fetch you would like to view. Type in the corresponding number then you'll view that historic fetch. From there you'll have the option to go `back` to the main menu.
40
+
41
+ To exit the program, if you are not already at the main menu, return to the main menu then type in `exit`.
42
+
43
+ ## Development
44
+
45
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
46
+
47
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
48
+
49
+ ## Contributing
50
+
51
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jrodden1/weatherpup.
52
+
53
+ ## License
54
+
55
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "weatherpup"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/bin/weatherpup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "weatherpup"
5
+
6
+ WeatherPup::CLI.new.call
@@ -0,0 +1,270 @@
1
+ # CLI Controller
2
+ class WeatherPup::CLI
3
+ def call
4
+ system "clear"
5
+ #puts "Welcome to WeatherPup!" #simple intro
6
+ puts <<~WELCOME
7
+       ▒█░░▒█ █▀▀ █░░ █▀▀ █▀▀█ █▀▄▀█ █▀▀   ▀▀█▀▀ █▀▀█
8
+       ▒█▒█▒█ █▀▀ █░░ █░░ █░░█ █░▀░█ █▀▀   ░▒█░░ █░░█
9
+       ▒█▄▀▄█ ▀▀▀ ▀▀▀ ▀▀▀ ▀▀▀▀ ▀░░░▀ ▀▀▀   ░▒█░░ ▀▀▀▀
10
+
11
+   ▒█░░▒█ █▀▀ █▀▀█ ▀▀█▀▀ █░░█ █▀▀ █▀▀█ ▒█▀▀█ █░░█ █▀▀█ █
12
+   ▒█▒█▒█ █▀▀ █▄▄█ ░░█░░ █▀▀█ █▀▀ █▄▄▀ ▒█▄▄█ █░░█ █░░█ ▀
13
+   ▒█▄▀▄█ ▀▀▀ ▀░░▀ ░░▀░░ ▀░░▀ ▀▀▀ ▀░▀▀ ▒█░░░ ░▀▀▀ █▀▀▀ ▄
14
+  
15
+   ░░░░░░░░░░░░░░░░▄██
16
+   ░░░░▄████▄▄▄▄▄▄███████
17
+   ░░▄█▀████████████▀
18
+   ░▄▀░██▀██▀▀▀▀▀██▀▀▄
19
+   ░░░░█▄░▀█▄░░░░▀█▄▀▀
20
+ WELCOME
21
+ main_menu
22
+ end
23
+
24
+ def main_menu
25
+ input = "no input"
26
+ until input.downcase == 'exit'
27
+ puts <<~MAINMENU
28
+
29
+ #{"How would you like me to fetch the current weather conditions for you today?".colorize(:light_red)}
30
+
31
+ #{"1. Fetch by Zip Code".colorize(:green)}
32
+ #{"2. Fetch by GPS Coordinates (Latitude and Longitude)".colorize(:light_blue)}
33
+ #{"3. Fetch previously fetched conditions".colorize(:cyan)}
34
+
35
+ Please type #{"1".colorize(:green)}, #{"2".colorize(:light_blue)}, #{"3".colorize(:cyan)} or type #{"exit".colorize(:red)} to quit.
36
+ MAINMENU
37
+ input = gets.chomp.downcase
38
+
39
+ case input
40
+ when "1"
41
+ self.fetch_by_zip
42
+ when "2"
43
+ self.fetch_by_gps
44
+ when "3"
45
+ self.fetch_previous
46
+ when "exit"
47
+ break
48
+ else
49
+ puts "\nSorry, that isn’t a valid input.".colorize(:red)
50
+ end
51
+ end
52
+ system "clear"
53
+ self.goodbye
54
+ end
55
+
56
+ #fetch the current conditions via zip code input from the user
57
+ def fetch_by_zip
58
+ #may not need zip_code variable declaration here)
59
+ #zip_code = nil
60
+ zip_code_valid = nil
61
+
62
+ #Clear my screen first to make things look nicer
63
+ system "clear"
64
+
65
+ #Ask user for the zip code
66
+ puts "\nOk, Current Weather Conditions by Zip Code!".colorize(:green)
67
+ until zip_code_valid
68
+ puts "\nPlease enter in the 5 Digit Zip Code:".colorize(:green)
69
+ zip_code = gets.chomp
70
+
71
+ #Checking to see if the user wants out of this loop and back to the main menu
72
+ if zip_code.downcase == "back"
73
+ system "clear"
74
+ break
75
+ end
76
+
77
+ #Otherwise, check to see if what the user put in was valid
78
+ zip_code_valid = zip_code_valid?(zip_code)
79
+
80
+ #If the zipcode input is valid, clear the screen, instantiate a new instance of WeatherConditions class, go fetch the raw api data, process it into an attributes hash to mass assign, mass assign the attributes of the WeatherConditions intance using #write_attributes, then print the current conditions to screen gps
81
+ if zip_code_valid
82
+ system "clear"
83
+ zip_weather_conditions = WeatherPup::WeatherConditions.new
84
+ zip_weather_conditions.zip_code = zip_code
85
+ api_raw_data = zip_weather_conditions.zip_api_fetch(zip_code)
86
+ api_processed_data_hash = zip_weather_conditions.zip_process_api_data_to_attribs_hash(api_raw_data)
87
+
88
+ #This next line takes the zip_weather_conditions variable which is a WeatherConditions Object Instance, taps into it and writes all of the attributes that I collected, then it prints the information located in the object itself.
89
+ zip_weather_conditions.tap {|weather_conditions_obj| weather_conditions_obj.write_attributes(api_processed_data_hash)}.print_zip_conditions
90
+
91
+ #Next I wait for the user to type in "back" to return to the main menu
92
+ return_to_main_menu_prompt
93
+ system "clear"
94
+ break
95
+ else
96
+ puts <<~INVALID_ZIP
97
+ \n#{"Invalid zip code detected!".colorize(:light_red)}
98
+
99
+ (Type #{"back".colorize(:red)} to return to the main menu).
100
+ INVALID_ZIP
101
+ end
102
+ end
103
+ end
104
+
105
+ def return_to_main_menu_prompt
106
+ return_to_main = ""
107
+ until return_to_main.downcase == "back"
108
+ puts "\nType #{"back".colorize(:red)} to return to the main menu."
109
+ return_to_main = gets.chomp
110
+ end
111
+ end
112
+
113
+
114
+ def zip_code_valid?(zip_to_check)
115
+ #checks the VALID_US_ZIP_CODES constant to see if the zip code is real
116
+ VALID_US_ZIP_CODES.include?(zip_to_check)
117
+ end
118
+
119
+ #fetch the current conditions via zip code input from the user
120
+ def fetch_by_gps
121
+ latitude = nil
122
+ longitude = nil
123
+ valid_coordinates = nil
124
+ system "clear"
125
+ puts "\nOk, Current Weather Conditions by GPS coordinates!".colorize(:blue)
126
+
127
+ until valid_coordinates
128
+ #Grab the Lat from the user
129
+ puts "\nPlease enter in the ".colorize(:blue) + "latitude".colorize(:green).underline + " in decimal notation:".colorize(:blue)
130
+ latitude = gets.chomp
131
+
132
+ #Checking to see if the user wants out of this loop and back to the main menu
133
+ if latitude.downcase == "back"
134
+ system "clear"
135
+ break
136
+ end
137
+
138
+ #Grab the Long from the user
139
+ puts "\nPlease enter in the ".colorize(:blue) + "longitude".colorize(:magenta).underline + " in decimal notation:".colorize(:blue)
140
+ longitude = gets.chomp
141
+ #Checking to see if the user wants out of this loop and back to the main menu
142
+ if longitude.downcase == "back"
143
+ system "clear"
144
+ break
145
+ end
146
+
147
+ #Checking to see if the coordinates are valid using class method #valid_coordinate_pair?
148
+ valid_coordinates = self.valid_coordinate_pair?(latitude, longitude)
149
+
150
+ # If the coordinates are valid, then then instantiate a new instance of WeatherConditions Object, hit the weather conditions api, write the object's attributes using mass assignment (#write_attributes), then #print_gps_conditions to screen
151
+ if valid_coordinates
152
+ system "clear"
153
+ gps_weather_conditions = WeatherPup::WeatherConditions.new
154
+ api_raw_data = gps_weather_conditions.gps_api_fetch(latitude, longitude)
155
+ api_processed_data_hash = gps_weather_conditions.gps_process_api_data_to_attribs_hash(api_raw_data)
156
+ #This next line takes the gps_weather_conditions variable which is a WeatherConditions Object Instance, taps into it and writes all of the attributes that I collected, then it prints the information located in the object itself.
157
+ gps_weather_conditions.tap {|weather_conditions_obj| weather_conditions_obj.write_attributes(api_processed_data_hash)}.print_gps_conditions
158
+
159
+ return_to_main_menu_prompt
160
+ system "clear"
161
+ break
162
+ else
163
+ puts <<~INVALID_GPS
164
+ \n#{"Invalid coordinates detected!".colorize(:light_red)}
165
+
166
+ (Type #{"back".colorize(:red)} to return to the main menu).
167
+ INVALID_GPS
168
+ end
169
+ end
170
+ end
171
+
172
+ #Do some basic checks to make sure that the coordinates are legit
173
+ def valid_coordinate_pair?(latitude, longitude)
174
+ #If the lat & long user input contains alphabet characters, it's not valid
175
+ if latitude.match(/[a-zA-Z]/) || longitude.match(/[a-zA-Z]/)
176
+ false
177
+ else
178
+ #Checks to see if both the lat & long user input are within valid ranges
179
+ VALID_LAT_RANGE.member?(latitude.to_f) && VALID_LONG_RANGE.member?(longitude.to_f)
180
+ end
181
+ #returns true if the lat and long coordinate pair is valid.
182
+ end
183
+
184
+ def fetch_previous
185
+ system "clear"
186
+ if WeatherPup::WeatherConditions.all == []
187
+ system "clear"
188
+ puts "\nThere are no previous fetches to display!".colorize(:cyan)
189
+ return_to_main_menu_prompt
190
+ system "clear"
191
+ else
192
+ #puts a blank line to give some headroom when displaying
193
+ puts "\n"
194
+ #Can possibly abstract this next section into a method called "list_all_previous" to make the #fetch_previous method a bit less cumbersome to read
195
+ WeatherPup::WeatherConditions.all.each.with_index(1) do |wc_obj, index|
196
+ case wc_obj.current_conditions_means
197
+ when "Zip Code"
198
+ puts "#{index}. Weather by Zip Code: #{wc_obj.zip_code.colorize(:green)} (#{wc_obj.city_name.colorize(:green)}) fetched at #{wc_obj.when_fetched.colorize(:red)}"
199
+ when "GPS Coordinates"
200
+ puts "#{index}. Weather by GPS: #{wc_obj.lat.colorize(:light_blue)}, #{wc_obj.long.colorize(:light_blue)} (#{wc_obj.city_name.colorize(:light_blue)}) fetched at #{wc_obj.when_fetched.colorize(:red)}"
201
+ end
202
+ end
203
+
204
+ valid_input_range = 1..WeatherPup::WeatherConditions.all.length
205
+ valid_input = nil
206
+
207
+ until valid_input
208
+ puts <<~USER_PROMPT
209
+ \nPlease type in the #{"number".colorize(:cyan)} of the previous fetch you would like to view
210
+ or type #{"back".colorize(:red)} to return to the main menu.
211
+ USER_PROMPT
212
+ user_selection = gets.chomp
213
+
214
+ if user_selection.downcase == "back"
215
+ system "clear"
216
+ break
217
+ end
218
+
219
+ user_integer = user_selection.to_i
220
+ valid_input = valid_input_range.member?(user_integer)
221
+
222
+ if valid_input
223
+ selected_wc_obj = WeatherPup::WeatherConditions.all[user_integer - 1]
224
+ type = selected_wc_obj.current_conditions_means
225
+
226
+ case type
227
+ when "Zip Code"
228
+ system "clear"
229
+ selected_wc_obj.print_zip_conditions
230
+ return_to_main_menu_prompt
231
+ system "clear"
232
+ break
233
+ when "GPS Coordinates"
234
+ system "clear"
235
+ selected_wc_obj.print_gps_conditions
236
+ return_to_main_menu_prompt
237
+ system "clear"
238
+ break
239
+ end
240
+ else
241
+ puts "\n#{"Invalid selection.".colorize(:light_red)} Please try again or type #{"back".colorize(:red)} to return to the main menu."
242
+ end
243
+ end
244
+ end
245
+ end
246
+
247
+ #Says thank you and goodbye to user.
248
+ def goodbye
249
+ system "clear"
250
+ puts <<~GOODBYE
251
+       ▀▀█▀▀ █░░█ █▀▀█ █▀▀▄ █░█ █▀▀   █▀▀ █▀▀█ █▀▀█
252
+       ░▒█░░ █▀▀█ █▄▄█ █░░█ █▀▄ ▀▀█   █▀▀ █░░█ █▄▄▀
253
+       ░▒█░░ ▀░░▀ ▀░░▀ ▀░░▀ ▀░▀ ▀▀▀   ▀░░ ▀▀▀▀ ▀░▀▀
254
+
255
+    █▀▀█ █░░ █▀▀█ █░░█ ░▀░ █▀▀▄ █▀▀▀   █▀▀ █▀▀ ▀▀█▀▀ █▀▀ █░░█
256
+    █░░█ █░░ █▄▄█ █▄▄█ ▀█▀ █░░█ █░▀█   █▀▀ █▀▀ ░░█░░ █░░ █▀▀█
257
+    █▀▀▀ ▀▀▀ ▀░░▀ ▄▄▄█ ▀▀▀ ▀░░▀ ▀▀▀▀   ▀░░ ▀▀▀ ░░▀░░ ▀▀▀ ▀░░▀
258
+
259
+           █░░░█ ░▀░ ▀▀█▀▀ █░░█   █▀▄▀█ █▀▀ █
260
+           █▄█▄█ ▀█▀ ░░█░░ █▀▀█   █░▀░█ █▀▀ ▀
261
+           ░▀░▀░ ▀▀▀ ░░▀░░ ▀░░▀   ▀░░░▀ ▀▀▀ ▄
262
+
263
+ Thank you for using WeatherPup!
264
+ Cool Welcome and Goodbye Text by fsymbols.com
265
+ Created by Jeremiah Rodden
266
+ 2019
267
+
268
+ GOODBYE
269
+ end
270
+ end