weather-report 0.3.3 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1405fd897fc7a64fae00781e20a88ec49034fbe3
4
- data.tar.gz: a9e8e87ae7e13ca35a1da79586301c10f3bf901d
2
+ SHA256:
3
+ metadata.gz: 91182fd85a0f2daafaf887d39b5e29e8688bc5352edf4a1f7a7cd23a3d655b87
4
+ data.tar.gz: a532ba5d0c9e80671354f62dcab66b5dd726676b7844831922beb1e3e317dd89
5
5
  SHA512:
6
- metadata.gz: 22abbaa9166755a1d2356444467aeade704adfb97fcb94fa9fad918c5d5d808484b08ad6ab27c50bd64b54afd49d95d626b6edf358115b07b2133d838fc25ce0
7
- data.tar.gz: 7ee452d24c48801b26f09684d0dde397021ec29f4fc8ea21c9916f938751b01b4e08116abccca24490b2d8471c7714e58438b8d3c5484a2aee36a457d1b40466
6
+ metadata.gz: 2d12cf105a1f36d726378d16ca6758181fab1887793b13dc02b3c615550777456ce509515084c0c3ec6516fd917f73cc3ff0ae116e9dc9ad49cd5c15b3bb4b24
7
+ data.tar.gz: 3b145a1828e505b00b602afc2addd3a0b17a984df4ecfdd8e902a4ceb53806ed259ecf0bed0185f09964a84a5e818da885246b4f5193faac17f158d4d0365d68
data/.gitignore CHANGED
@@ -3,7 +3,7 @@
3
3
  .bundle
4
4
  .config
5
5
  .yardoc
6
- Gemfile.lock
6
+ .ruby-version
7
7
  InstalledFiles
8
8
  _yardoc
9
9
  coverage
@@ -1,7 +1,9 @@
1
1
  language: ruby
2
+ cache: bundler
2
3
  rvm:
3
- - "1.9.2"
4
- - "1.9.3"
5
- - "2.0.0"
6
- - jruby-19mode # JRuby in 1.9 mode
7
- - rbx-19mode
4
+ - "2.5"
5
+ - "2.6"
6
+ - "2.7"
7
+ # - jruby
8
+ # - rbx-3
9
+ before_install: gem install bundler -v 2.1.4
@@ -0,0 +1,44 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ weather-report (0.4.0)
5
+ nokogiri
6
+ slop (~> 4.0.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ ansi (1.5.0)
12
+ builder (3.2.4)
13
+ growl (1.0.3)
14
+ guard-compat (1.2.1)
15
+ guard-minitest (2.4.6)
16
+ guard-compat (~> 1.2)
17
+ minitest (>= 3.0)
18
+ mini_portile2 (2.4.0)
19
+ minitest (5.14.2)
20
+ minitest-reporters (1.4.2)
21
+ ansi
22
+ builder
23
+ minitest (>= 5.0)
24
+ ruby-progressbar
25
+ nokogiri (1.10.10)
26
+ mini_portile2 (~> 2.4.0)
27
+ rake (13.0.1)
28
+ rb-fsevent (0.10.4)
29
+ ruby-progressbar (1.10.1)
30
+ slop (4.0.0)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ growl
37
+ guard-minitest
38
+ minitest-reporters
39
+ rake
40
+ rb-fsevent
41
+ weather-report!
42
+
43
+ BUNDLED WITH
44
+ 2.1.4
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Weather Report
2
2
 
3
- A Ruby library and CLI to get Japanese Weather via Livedoor Weather Web Service(http://weather.livedoor.com/weather_hacks/webservice).
3
+ A Ruby library and CLI to get Japanese Weather via 天気予報 API(https://weather.tsukumijima.net/) which is compatible with Livedoor Weather Web Service.
4
4
 
5
5
  [![Build Status](https://travis-ci.org/zakuni/weather-report.png)](https://travis-ci.org/zakuni/weather-report)
6
6
 
@@ -1,30 +1,47 @@
1
1
  #!/usr/bin/env ruby
2
-
2
+ # -*- coding: utf-8 -*-
3
+ require 'rubygems'
4
+ $:.unshift File.expand_path '../lib', File.dirname(__FILE__)
3
5
  require 'weather-report'
4
- require 'optparse'
5
- require 'ostruct'
6
-
7
- exit 1 if ARGV.empty?
8
-
9
- options = OpenStruct.new
6
+ require 'slop'
10
7
 
11
- opt_parser = OptionParser.new do |opts|
12
- opts.banner = 'Usage: weather-report CITY [options]'
8
+ opts = Slop.parse(help: true) do
9
+ banner 'Usage: weather-report CITY [options]'
13
10
 
14
- opts.separator ""
15
- opts.separator "Common options:"
11
+ separator ""
12
+ separator "Common options:"
16
13
 
17
- opts.on_tail("-h", "--help", "Show this message") do
18
- puts opts
14
+ on :l, :list, 'Show city list' do
15
+ WeatherReport.cities.each do |city|
16
+ puts city
17
+ end
19
18
  exit
20
19
  end
21
20
 
22
- opts.on_tail("-v", "--version", "Show version") do
23
- puts WeatherReport::Version
21
+ on :v, :version, "Show version" do
22
+ puts "weather-report v#{WeatherReport::VERSION}"
24
23
  exit
25
24
  end
26
25
  end
27
26
 
28
- city = opt_parser.parse(ARGV)
27
+ exit if opts.help?
28
+
29
+ if ARGV.empty?
30
+ puts opts.help
31
+ exit
32
+ end
33
+
34
+ city = ARGV
29
35
  weather = WeatherReport::Weather.new(WeatherReport::Weather.request_cityid(*city))
30
- puts weather.to_h
36
+
37
+ [weather.today, weather.tomorrow, weather.day_after_tomorrow].each do |day|
38
+ begin
39
+ print "#{day.date.year}年#{day.date.month}月#{day.date.day}日の天気 #{day.telop}"
40
+ print " 最低気温#{day.temperature_min}度" if day.temperature_min
41
+ print " 最高気温#{day.temperature_max}度" if day.temperature_max
42
+ puts
43
+ rescue NoMethodError
44
+ next
45
+ end
46
+ end
47
+ puts weather.link
@@ -8,10 +8,22 @@ require 'weather-report/day'
8
8
  require 'weather-report/version'
9
9
 
10
10
  module WeatherReport
11
- class WeatherReportError < StandardError; end
11
+ class Error < StandardError; end
12
+ class ArgumentError < Error; end
13
+ class NoCityError < Error; end
14
+ class NoForecastError < Error; end
12
15
 
13
16
  # @return [Weather] get weather of the city
14
17
  def self.get(city_name)
15
18
  Weather.new(Weather.request_cityid(city_name))
16
19
  end
20
+
21
+ # @return [Array] get city list
22
+ def self.cities
23
+ proxy = Weather.parse_proxy(ENV["http_proxy"])
24
+ doc = Nokogiri::XML(open("https://weather.tsukumijima.net/primary_area.xml", :proxy_http_basic_authentication => [proxy.server, proxy.user, proxy.pass]))
25
+ doc.xpath("//city").map{|i|
26
+ i["title"]
27
+ }
28
+ end
17
29
  end
@@ -5,8 +5,9 @@ module WeatherReport
5
5
  attr_reader :date, :telop, :temperature_min, :temperature_max
6
6
 
7
7
  def initialize(forecasts, dateLabel)
8
+ raise ArgumentError, "dateLabel must be 今日, 明日 or 明後日" unless dateLabel =~ /(今日|明日|明後日)/
8
9
  @forecast = forecast(forecasts, dateLabel)
9
- end
10
+ end
10
11
 
11
12
  # @return [Boolean] return true if it rains.
12
13
  def rain?
@@ -34,19 +35,19 @@ module WeatherReport
34
35
  @telop ||= @forecast["telop"]
35
36
  end
36
37
 
37
- # @return [Fixnum] the minimum temperature.
38
+ # @return [Fixnum] the minimum temperature.
38
39
  # Temperature of today could be nil.
39
40
  def temperature_min
40
41
  min = @forecast["temperature"]["min"]
41
- @temperature ||=
42
+ @temperature ||=
42
43
  min ? min["celsius"].to_i : nil
43
44
  end
44
45
 
45
- # @return [Fixnum] the maximum temperature.
46
+ # @return [Fixnum] the maximum temperature.
46
47
  # Temperature of today could be nil.
47
48
  def temperature_max
48
49
  max = @forecast["temperature"]["max"]
49
- @temperature_max ||=
50
+ @temperature_max ||=
50
51
  max ? max["celsius"].to_i : nil
51
52
  end
52
53
 
@@ -64,6 +65,7 @@ module WeatherReport
64
65
 
65
66
  def forecast(forecasts, dateLabel)
66
67
  forecasts["forecasts"].each {|elem| return elem if elem["dateLabel"] == dateLabel}
68
+ raise NoForecastError
67
69
  end
68
70
  end
69
71
  end
@@ -1,3 +1,3 @@
1
1
  module WeatherReport
2
- VERSION = "0.3.3"
2
+ VERSION = '0.4.0'.freeze
3
3
  end
@@ -5,16 +5,17 @@ module WeatherReport
5
5
  attr_reader :today, :tomorrow, :day_after_tomorrow
6
6
 
7
7
  def initialize(city_id)
8
- @uri = URI.parse("http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city_id}")
8
+ @uri = URI.parse("https://weather.tsukumijima.net/api/forecast?city=#{city_id}")
9
9
  end
10
10
 
11
11
  # @return [String] the id of given city
12
12
  def self.request_cityid(city_name)
13
+ raise ArgumentError, "City name must be String." unless city_name.kind_of?(String)
13
14
  proxy = Weather.parse_proxy(ENV["http_proxy"])
14
- doc = Nokogiri::XML(open("http://weather.livedoor.com/forecast/rss/primary_area.xml", :proxy_http_basic_authentication => [proxy.server, proxy.user, proxy.pass]))
15
+ doc = Nokogiri::XML(open("https://weather.tsukumijima.net/primary_area.xml", :proxy_http_basic_authentication => [proxy.server, proxy.user, proxy.pass]))
15
16
  doc.search("//city[@title='#{city_name}']").attr("id").value
16
- rescue => e
17
- raise WeatherReportError
17
+ rescue NoMethodError
18
+ raise NoCityError, "It seems like city #{city_name} does not exist.\nPlease look at https://weather.tsukumijima.net/primary_area.xml for city list."
18
19
  end
19
20
 
20
21
  def self.parse_proxy(proxy)
@@ -25,8 +26,8 @@ module WeatherReport
25
26
  host, port = server.split(":")
26
27
  account = raccount.nil? ? "" : raccount.reverse.split(":")
27
28
  user, pass = account
28
-
29
- proxy = OpenStruct.new({
29
+
30
+ proxy = OpenStruct.new({
30
31
  "server" => server.empty? ? nil : "http://#{server}",
31
32
  "user" => user.nil? ? "" : user,
32
33
  "pass" => pass.nil? ? "" : pass
@@ -73,7 +74,7 @@ module WeatherReport
73
74
  def read
74
75
  @response ||= JSON.parse(@uri.read)
75
76
  rescue => e
76
- raise WeatherReportError
77
+ raise Error
77
78
  end
78
79
  end
79
80
  end
@@ -7,27 +7,60 @@ class TestDay < MiniTest::Unit::TestCase
7
7
 
8
8
  def setup
9
9
  city_id = Weather.request_cityid("東京")
10
- uri = URI.parse("http://weather.livedoor.com/forecast/webservice/json/v1?city=#{city_id}")
10
+ uri = URI.parse("https://weather.tsukumijima.net/api/forecast?city=#{city_id}")
11
11
  @forecasts = JSON.parse(uri.read)
12
12
  @day = Day.new(@forecasts, "明日")
13
13
  end
14
14
 
15
15
  def test_initialize
16
16
  assert_instance_of Day, Day.new(@forecasts, "明日")
17
+ assert_raises(ArgumentError) do
18
+ Day.new(@forecasts, "昨日")
19
+ end
17
20
  end
18
21
 
19
22
  def test_rain?
20
23
  assert_respond_to @day, :rain?
24
+ @day.stub(:telop, '晴れ') do
25
+ assert_equal @day.rain?, false
26
+ end
27
+ @day.stub(:telop, '雨') do
28
+ assert_equal @day.rain?, true
29
+ end
30
+ @day.stub(:telop, '晴れ時々雨') do
31
+ assert_equal @day.rain?, true
32
+ end
21
33
  end
22
34
 
23
35
  def test_snow?
24
36
  assert_respond_to @day, :snow?
37
+ @day.stub(:telop, '晴れ') do
38
+ assert_equal @day.snow?, false
39
+ end
40
+ @day.stub(:telop, '雪') do
41
+ assert_equal @day.snow?, true
42
+ end
43
+ @day.stub(:telop, '雪のち晴れ') do
44
+ assert_equal @day.snow?, true
45
+ end
25
46
  end
26
47
 
27
48
  def test_umbrella?
28
49
  assert_respond_to @day, :umbrella?
50
+ @day.stub(:telop, '晴れ') do
51
+ assert_equal @day.umbrella?, false
52
+ end
53
+ @day.stub(:telop, '雨') do
54
+ assert_equal @day.umbrella?, true
55
+ end
56
+ @day.stub(:telop, '晴れのち雨') do
57
+ assert_equal @day.umbrella?, true
58
+ end
59
+ @day.stub(:telop, '曇りのち晴れ') do
60
+ assert_equal @day.umbrella?, false
61
+ end
29
62
  end
30
-
63
+
31
64
  def test_date
32
65
  assert_respond_to @day, :date
33
66
  assert_instance_of Date, @day.date
@@ -51,4 +84,12 @@ class TestDay < MiniTest::Unit::TestCase
51
84
  def test_to_h
52
85
  assert_respond_to @day, :to_h
53
86
  end
87
+
88
+ def test_forecast
89
+ forecasts = {"forecasts" => [{"dateLabel" => "明日"}]}
90
+ refute_nil @day.send(:forecast, forecasts, "明日")
91
+ assert_raises NoForecastError do
92
+ @day.send(:forecast, forecasts, "明後日")
93
+ end
94
+ end
54
95
  end
@@ -6,4 +6,4 @@ require 'minitest/pride'
6
6
  $:.unshift File.expand_path '../lib', File.dirname(__FILE__)
7
7
  require 'weather-report'
8
8
 
9
- MiniTest::Reporters.use! [MiniTest::Reporters::DefaultReporter.new, MiniTest::Reporters::GuardReporter.new]
9
+ MiniTest::Reporters.use! [MiniTest::Reporters::DefaultReporter.new]
@@ -8,4 +8,11 @@ class TestWeatherReport < MiniTest::Unit::TestCase
8
8
  assert_respond_to WeatherReport, :get
9
9
  assert_instance_of WeatherReport::Weather, WeatherReport.get("横浜")
10
10
  end
11
+
12
+ def test_cities
13
+ cities = WeatherReport.cities
14
+ assert_instance_of Array, cities
15
+ assert cities.include? "東京"
16
+ assert cities.include? "横浜"
17
+ end
11
18
  end
@@ -11,7 +11,7 @@ class TestWeather < MiniTest::Unit::TestCase
11
11
  end
12
12
 
13
13
  def test_initialize
14
- assert_raises ArgumentError do
14
+ assert_raises ::ArgumentError do
15
15
  Weather.new
16
16
  end
17
17
  assert_instance_of Weather, Weather.new(@id)
@@ -47,9 +47,12 @@ class TestWeather < MiniTest::Unit::TestCase
47
47
  assert_respond_to Weather, :request_cityid
48
48
  assert_equal "130010", Weather.request_cityid("東京")
49
49
  assert_equal "140010", Weather.request_cityid("横浜")
50
- assert_raises(WeatherReportError) do
50
+ assert_raises(ArgumentError) do
51
51
  Weather.request_cityid(nil)
52
52
  end
53
+ assert_raises(NoCityError) do
54
+ Weather.request_cityid("存在しない街")
55
+ end
53
56
  end
54
57
 
55
58
  def test_to_h
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_dependency "nokogiri"
22
- spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_dependency "slop", "~> 4.0.0"
23
23
  spec.add_development_dependency "rake"
24
24
  spec.add_development_dependency "guard-minitest"
25
25
  spec.add_development_dependency "rb-fsevent"
metadata CHANGED
@@ -1,111 +1,111 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: weather-report
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - zakuni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-18 00:00:00.000000000 Z
11
+ date: 2020-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: slop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '1.3'
34
- type: :development
33
+ version: 4.0.0
34
+ type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '1.3'
40
+ version: 4.0.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: guard-minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rb-fsevent
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: minitest-reporters
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '>='
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '>='
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: growl
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - '>='
101
+ - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '0'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - '>='
108
+ - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  description: A Ruby library and CLI to get Japanese Weather via Livedoor Weather Web
@@ -117,9 +117,10 @@ executables:
117
117
  extensions: []
118
118
  extra_rdoc_files: []
119
119
  files:
120
- - .gitignore
121
- - .travis.yml
120
+ - ".gitignore"
121
+ - ".travis.yml"
122
122
  - Gemfile
123
+ - Gemfile.lock
123
124
  - Guardfile
124
125
  - LICENSE.txt
125
126
  - README.md
@@ -144,17 +145,16 @@ require_paths:
144
145
  - lib
145
146
  required_ruby_version: !ruby/object:Gem::Requirement
146
147
  requirements:
147
- - - '>='
148
+ - - ">="
148
149
  - !ruby/object:Gem::Version
149
150
  version: '0'
150
151
  required_rubygems_version: !ruby/object:Gem::Requirement
151
152
  requirements:
152
- - - '>='
153
+ - - ">="
153
154
  - !ruby/object:Gem::Version
154
155
  version: '0'
155
156
  requirements: []
156
- rubyforge_project:
157
- rubygems_version: 2.0.2
157
+ rubygems_version: 3.1.2
158
158
  signing_key:
159
159
  specification_version: 4
160
160
  summary: A Ruby client of Livedoor Weather Web Service.