weathercli 0.2.0

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5d4382e8b6b054419cb4f627c5d59260220e68d0
4
+ data.tar.gz: f45a6dca7648a0c0678d9b4c965dcafc3825a0e9
5
+ SHA512:
6
+ metadata.gz: ab2b19f5541792886c38e4e6650da8f222afb3312df7013d7bc557ac1f57391dd5f3ba5c6d045be404d204cd127d9505b393fe910148ddfd4be77cf77157f6f1
7
+ data.tar.gz: 1632b5f36ece5b43e74e4c98fbd075ae8ad7da50418938368591675d50c77c1458868166022f5b34e4a77ea9a936554f44e7dc67c53a5a29ff86fa5eacfbf05d
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rspec', '3.1.0'
4
+ gem 'json', '1.8.2'
5
+
6
+ group :development do
7
+ gem 'jeweler', '2.0.1'
8
+ end
@@ -0,0 +1,69 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ addressable (2.3.6)
5
+ builder (3.2.2)
6
+ descendants_tracker (0.0.4)
7
+ thread_safe (~> 0.3, >= 0.3.1)
8
+ diff-lcs (1.2.5)
9
+ faraday (0.9.1)
10
+ multipart-post (>= 1.2, < 3)
11
+ git (1.2.9.1)
12
+ github_api (0.12.2)
13
+ addressable (~> 2.3)
14
+ descendants_tracker (~> 0.0.4)
15
+ faraday (~> 0.8, < 0.10)
16
+ hashie (>= 3.3)
17
+ multi_json (>= 1.7.5, < 2.0)
18
+ nokogiri (~> 1.6.3)
19
+ oauth2
20
+ hashie (3.3.2)
21
+ highline (1.6.21)
22
+ jeweler (2.0.1)
23
+ builder
24
+ bundler (>= 1.0)
25
+ git (>= 1.2.5)
26
+ github_api
27
+ highline (>= 1.6.15)
28
+ nokogiri (>= 1.5.10)
29
+ rake
30
+ rdoc
31
+ json (1.8.2)
32
+ jwt (1.2.1)
33
+ mini_portile (0.6.2)
34
+ multi_json (1.10.1)
35
+ multi_xml (0.5.5)
36
+ multipart-post (2.0.0)
37
+ nokogiri (1.6.6.2)
38
+ mini_portile (~> 0.6.0)
39
+ oauth2 (1.0.0)
40
+ faraday (>= 0.8, < 0.10)
41
+ jwt (~> 1.0)
42
+ multi_json (~> 1.3)
43
+ multi_xml (~> 0.5)
44
+ rack (~> 1.2)
45
+ rack (1.6.0)
46
+ rake (10.4.2)
47
+ rdoc (4.2.0)
48
+ json (~> 1.4)
49
+ rspec (3.1.0)
50
+ rspec-core (~> 3.1.0)
51
+ rspec-expectations (~> 3.1.0)
52
+ rspec-mocks (~> 3.1.0)
53
+ rspec-core (3.1.7)
54
+ rspec-support (~> 3.1.0)
55
+ rspec-expectations (3.1.2)
56
+ diff-lcs (>= 1.2.0, < 2.0)
57
+ rspec-support (~> 3.1.0)
58
+ rspec-mocks (3.1.3)
59
+ rspec-support (~> 3.1.0)
60
+ rspec-support (3.1.2)
61
+ thread_safe (0.3.4)
62
+
63
+ PLATFORMS
64
+ ruby
65
+
66
+ DEPENDENCIES
67
+ jeweler (= 2.0.1)
68
+ json (= 1.8.2)
69
+ rspec (= 3.1.0)
@@ -0,0 +1,25 @@
1
+ # WeatherCli
2
+
3
+ Simple weather updates on the command line
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ gem install 'weathercli'
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ weather
15
+ ```
16
+
17
+ ## Testing
18
+
19
+ To run the test suite simply execute:
20
+
21
+ ```
22
+ rspec
23
+ ```
24
+
25
+ (c) Keith McHugh 2015
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "weathercli"
18
+ gem.executables = ['weather']
19
+ gem.homepage = "http://gitlab.com/kmcq/weathercli"
20
+ gem.license = "MIT"
21
+ gem.summary = "Weather updates on the command line."
22
+ gem.description = "weathercli asks Yahoo for the current weather a few forecasts. You can have a default location or specify one when calling it."
23
+ gem.authors = ["kmcq"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+ require 'weathercli'
3
+
4
+ CONFIG_FILE = File.join(Dir.home, ".weathercli")
5
+
6
+ def save_default_location(location)
7
+ File.open(CONFIG_FILE, 'w').write(location)
8
+ end
9
+
10
+ def location
11
+ location_args = ARGV.join unless ARGV.empty?
12
+ if location_args
13
+ print "Save as default location? [y/n]: "
14
+ if STDIN.gets.chomp.downcase == 'y'
15
+ save_default_location(location_args)
16
+ end
17
+ location_args
18
+ elsif File.file?(CONFIG_FILE)
19
+ File.read(CONFIG_FILE)
20
+ else
21
+ print "Add default location [e.g. San Francisco, CA]: "
22
+ location = gets
23
+ save_default_location(location)
24
+ location
25
+ end
26
+ end
27
+
28
+ puts WeatherCli::Weather.new(location)
@@ -0,0 +1 @@
1
+ require 'weathercli/weather.rb'
@@ -0,0 +1,54 @@
1
+ module WeatherCli
2
+ require 'net/http'
3
+ require 'json'
4
+
5
+ class Weather
6
+ attr_reader :location, :conditions, :options, :title, :forecasts
7
+
8
+ def initialize(location, *options)
9
+ @options = Hash[options.map { |o| [o, true] }]
10
+ get_weather(location)
11
+ end
12
+
13
+ def to_s
14
+ todays_forecast = forecasts.first
15
+ tomorrows_forecast = forecasts.last
16
+ [
17
+ title,
18
+ "#{conditions['temp']} degrees Farenheit; #{conditions['text']}",
19
+ "Today's forecast: High of #{todays_forecast['high']}, Low of #{todays_forecast['low']}; #{todays_forecast['text']}",
20
+ "Tomorrow's forecast: High of #{tomorrows_forecast['high']}, Low of #{tomorrows_forecast['low']}; #{tomorrows_forecast['text']}"
21
+ ].join("\n")
22
+ end
23
+
24
+ private
25
+
26
+ def get_weather(location)
27
+ query = construct_query(location)
28
+ url = construct_url(query)
29
+ parse_api_results(retrieve_api_results(url))
30
+ end
31
+
32
+ def construct_query(location)
33
+ "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"#{location}\")"
34
+ end
35
+
36
+ def construct_url(query)
37
+ base_url = "https://query.yahooapis.com/v1/public/yql"
38
+ encoded_query = URI.encode(query).gsub('=', '%3D')
39
+ options = "&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
40
+ "#{base_url}?q=#{encoded_query}#{options}"
41
+ end
42
+
43
+ def retrieve_api_results(url)
44
+ JSON.parse(Net::HTTP::get(URI.parse(url)))['query']['results']['channel']['item']
45
+ end
46
+
47
+ def parse_api_results(results)
48
+ @title = results['title']
49
+ @conditions = results['condition'].keep_if { |k,v| ['temp','text'].include? k }
50
+ @forecasts = results['forecast'].first(2)
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Keith McHugh
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.
@@ -0,0 +1,2 @@
1
+ $:<< File.join(File.dirname(__FILE__), '..')
2
+ require 'lib/weathercli'
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe WeatherCli::Weather do
4
+ let(:location) { 'San Francisco' }
5
+ let(:weather) { WeatherCli::Weather.new(location, 'option1', 'option2') }
6
+ let(:correct_query) { "select * from weather.forecast where woeid in (select woeid from geo.places(1) where text=\"#{location}\")" }
7
+ let(:api_results) {
8
+ {
9
+ "title"=>"Conditions for San Francisco, CA at 2:52 pm PST",
10
+ "condition"=>{"code"=>"28", "date"=>"Sat, 17 Jan 2015 2:52 pm PST", "temp"=>"57", "text"=>"Mostly Cloudy"},
11
+ "forecast"=>[
12
+ {"code"=>"30", "date"=>"17 Jan 2015", "day"=>"Sat", "high"=>"60", "low"=>"53", "text"=>"Partly Cloudy"},
13
+ {"code"=>"30", "date"=>"18 Jan 2015", "day"=>"Sun", "high"=>"61", "low"=>"49", "text"=>"AM Clouds/PM Sun"},
14
+ {"code"=>"28", "date"=>"19 Jan 2015", "day"=>"Mon", "high"=>"62", "low"=>"50", "text"=>"Mostly Cloudy"},
15
+ {"code"=>"30", "date"=>"20 Jan 2015", "day"=>"Tue", "high"=>"61", "low"=>"48", "text"=>"AM Clouds/PM Sun"},
16
+ {"code"=>"32", "date"=>"21 Jan 2015", "day"=>"Wed", "high"=>"64", "low"=>"48", "text"=>"Sunny"}
17
+ ]
18
+ }
19
+ }
20
+ let(:title) { "Conditions for San Francisco, CA at 2:52 pm PST" }
21
+ let(:forecasts) {
22
+ [
23
+ {"code"=>"30", "date"=>"17 Jan 2015", "day"=>"Sat", "high"=>"60", "low"=>"53", "text"=>"Partly Cloudy"},
24
+ {"code"=>"30", "date"=>"18 Jan 2015", "day"=>"Sun", "high"=>"61", "low"=>"49", "text"=>"AM Clouds/PM Sun"}
25
+ ]
26
+ }
27
+ let(:conditions) {
28
+ {
29
+ "temp"=>"57", "text"=>"Mostly Cloudy"
30
+ }
31
+ }
32
+
33
+ before do
34
+ allow_any_instance_of(WeatherCli::Weather).to receive(:retrieve_api_results).and_return(api_results)
35
+ end
36
+
37
+ context '#initialize' do
38
+
39
+ it 'should construct the correct query' do
40
+ expect(weather.send(:construct_query, location)).to eq(correct_query)
41
+ end
42
+
43
+ it 'should construct the correct URL' do
44
+ encoded_location = URI.encode(location)
45
+ correct_url = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22#{encoded_location}%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys"
46
+ expect(weather.send(:construct_url, correct_query)).to eq(correct_url)
47
+ end
48
+
49
+ it 'should have a title' do
50
+ expect(weather.title).to eq(title)
51
+ end
52
+
53
+ it 'should have the current condition' do
54
+ expect(weather.conditions).to eq(conditions)
55
+ end
56
+
57
+ it 'should have the forecast for today and tomorrow' do
58
+ expect(weather.forecasts.length).to eq(2)
59
+ expect(weather.forecasts).to eq(forecasts)
60
+ end
61
+
62
+ it 'should map any options to a truthy hash' do
63
+ expect(weather.options).to eq({'option1' => true, 'option2' => true})
64
+ end
65
+ end
66
+
67
+ context '#to_s' do
68
+
69
+ it 'should print out the weather nicely' do
70
+ output_string = [
71
+ 'Conditions for San Francisco, CA at 2:52 pm PST',
72
+ '57 degrees Farenheit; Mostly Cloudy',
73
+ "Today's forecast: High of 60, Low of 53; Partly Cloudy",
74
+ "Tomorrow's forecast: High of 61, Low of 49; AM Clouds/PM Sun"
75
+ ].join("\n")
76
+ expect(weather.to_s).to eq(output_string)
77
+ end
78
+
79
+ end
80
+
81
+ end
@@ -0,0 +1,57 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: weathercli 0.2.0 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "weathercli"
9
+ s.version = "0.2.0"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["kmcq"]
14
+ s.date = "2015-01-25"
15
+ s.description = "weathercli asks Yahoo for the current weather a few forecasts. You can have a default location or specify one when calling it."
16
+ s.executables = ["weather"]
17
+ s.extra_rdoc_files = [
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ "Gemfile",
22
+ "Gemfile.lock",
23
+ "README.md",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "bin/weather",
27
+ "lib/weathercli.rb",
28
+ "lib/weathercli/weather.rb",
29
+ "license.md",
30
+ "spec/spec_helper.rb",
31
+ "spec/weather_spec.rb",
32
+ "weathercli.gemspec"
33
+ ]
34
+ s.homepage = "http://gitlab.com/kmcq/weathercli"
35
+ s.licenses = ["MIT"]
36
+ s.rubygems_version = "2.3.0"
37
+ s.summary = "Weather updates on the command line."
38
+
39
+ if s.respond_to? :specification_version then
40
+ s.specification_version = 4
41
+
42
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
43
+ s.add_runtime_dependency(%q<rspec>, ["= 3.1.0"])
44
+ s.add_runtime_dependency(%q<json>, ["= 1.8.2"])
45
+ s.add_development_dependency(%q<jeweler>, ["= 2.0.1"])
46
+ else
47
+ s.add_dependency(%q<rspec>, ["= 3.1.0"])
48
+ s.add_dependency(%q<json>, ["= 1.8.2"])
49
+ s.add_dependency(%q<jeweler>, ["= 2.0.1"])
50
+ end
51
+ else
52
+ s.add_dependency(%q<rspec>, ["= 3.1.0"])
53
+ s.add_dependency(%q<json>, ["= 1.8.2"])
54
+ s.add_dependency(%q<jeweler>, ["= 2.0.1"])
55
+ end
56
+ end
57
+
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: weathercli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - kmcq
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 3.1.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 3.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: jeweler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 2.0.1
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 2.0.1
55
+ description: weathercli asks Yahoo for the current weather a few forecasts. You can
56
+ have a default location or specify one when calling it.
57
+ email:
58
+ executables:
59
+ - weather
60
+ extensions: []
61
+ extra_rdoc_files:
62
+ - README.md
63
+ files:
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - README.md
67
+ - Rakefile
68
+ - VERSION
69
+ - bin/weather
70
+ - lib/weathercli.rb
71
+ - lib/weathercli/weather.rb
72
+ - license.md
73
+ - spec/spec_helper.rb
74
+ - spec/weather_spec.rb
75
+ - weathercli.gemspec
76
+ homepage: http://gitlab.com/kmcq/weathercli
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.3.0
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Weather updates on the command line.
100
+ test_files: []