kisyo 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,35 @@
1
+ module Kisyo
2
+ class Cache
3
+ CACHE_SIZE = 100
4
+
5
+ def initialize
6
+ @keys = []
7
+ @values = {}
8
+ @m = Mutex.new
9
+ end
10
+
11
+ def get(key)
12
+ values[key]
13
+ end
14
+
15
+ def set(key, value)
16
+ m.synchronize do
17
+ if values[key]
18
+ return
19
+ end
20
+
21
+ keys << key
22
+ values[key] = value
23
+
24
+ if keys.size > CACHE_SIZE
25
+ oldest_key = keys.shift
26
+ values.delete(oldest_key)
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader :keys, :values, :m
34
+ end
35
+ end
data/lib/kisyo/daily.rb CHANGED
@@ -3,32 +3,47 @@ require 'open-uri'
3
3
 
4
4
  module Kisyo
5
5
  class Daily
6
+ CACHE_SIZE = 100
7
+
6
8
  def initialize(location)
7
9
  @location = location
10
+ @cache = Cache.new
8
11
  end
9
12
 
10
13
  def at(date)
11
- url = 'http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=%i&block_no=%i&year=%i&month=%i&day=01&view=p1' % [
12
- @location.prefecture_id,
13
- @location.block_id,
14
- date.year,
15
- date.month
16
- ]
17
-
18
- content = open(url).read
19
- doc = Nokogiri::HTML(content)
14
+ key = [date.year, date.month, date.day].join(',')
15
+
16
+ if value = cache.get(key)
17
+ return value
18
+ end
19
+
20
+ url =
21
+ 'http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=%s&block_no=%s&year=%i&month=%i&day=01&view=p1' % [
22
+ location.prefecture_id,
23
+ location.block_id,
24
+ date.year,
25
+ date.month
26
+ ]
27
+
28
+ content = URI.open(url).read
29
+ doc = Nokogiri.HTML(content)
20
30
  days = doc.css('div.a_print')
21
31
 
22
32
  raise WeatherInformationNotAvailable if days.size == 0
23
33
 
24
34
  days.each do |el|
25
- if el.text.to_i == date.day
26
- tr = el.parent.parent
27
- values = tr.css('td').map(&:text)
35
+ tr = el.parent.parent
36
+ values = tr.css('td').map(&:text)
28
37
 
29
- return Element::Day.new(*values[1 .. -1])
30
- end
38
+ k = [date.year, date.month, values[0]].join(',')
39
+ cache.set(k, Element::Day.new(*values[1..-1]))
31
40
  end
41
+
42
+ cache.get(key)
32
43
  end
44
+
45
+ private
46
+
47
+ attr_reader :cache, :location
33
48
  end
34
49
  end
@@ -1,7 +1,30 @@
1
+ require 'csv'
2
+
1
3
  module Kisyo
2
4
  class Location
3
5
  attr_reader :prefecture_id, :block_id
4
6
 
7
+ def self.dms_to_degrees(d, m, s = 0)
8
+ d + m / 60.0 + s / 3600.0
9
+ end
10
+
11
+ def self.nearest(lat, lng)
12
+ CSV.open(File.dirname(__FILE__) + '/../blocks.csv') do |csv|
13
+ distances =
14
+ csv.map do |row|
15
+ la = dms_to_degrees(row[5].to_f, row[6].to_f)
16
+ ln = dms_to_degrees(row[7].to_f, row[8].to_f)
17
+
18
+ [Math.sqrt((lat - la)**2 + (lng - ln)**2), row]
19
+ end
20
+
21
+ distance = distances.min_by { |(dist, _)| dist }
22
+ row = distance[1]
23
+
24
+ new(row[3], row[4])
25
+ end
26
+ end
27
+
5
28
  def initialize(prefecture_id, block_id)
6
29
  @prefecture_id = prefecture_id
7
30
  @block_id = block_id
data/lib/kisyo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Kisyo
2
- VERSION = "0.0.2"
2
+ VERSION = '0.1.0'
3
3
  end
data/lib/kisyo.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require "kisyo/error"
2
2
  require "kisyo/location"
3
+ require "kisyo/cache"
3
4
  require "kisyo/daily"
4
5
  require "kisyo/elements/day"
5
6
  require "kisyo/version"
@@ -2,73 +2,85 @@
2
2
  require File.dirname(__FILE__) + '/../spec_helper'
3
3
 
4
4
  describe Kisyo::Daily do
5
- let(:date) {
6
- Date.parse('2016-11-02')
7
- }
8
-
9
- let(:location) {
10
- Kisyo::Location.new(44, 47662)
11
- }
12
-
13
- let(:daily) {
14
- Kisyo::Daily.new(location)
15
- }
5
+ let(:date) { Date.parse('2016-11-02') }
6
+ let(:location) { Kisyo::Location.new('44', '47662') }
7
+ let(:daily) { Kisyo::Daily.new(location) }
16
8
 
17
9
  describe '#at' do
18
- let(:url) {
10
+ let(:url) do
19
11
  'http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?block_no=47662&day=01&month=11&prec_no=44&view=p1&year=2016'
20
- }
12
+ end
21
13
 
22
- let(:fixture_file_name) {
23
- '201611.html'
24
- }
14
+ let(:fixture_file_name) { '201611.html' }
25
15
 
26
- before do
27
- stub_request(:get, url).
28
- to_return(:body => read_fixture_file(fixture_file_name))
29
- end
16
+ context 'single request' do
17
+ before do
18
+ stub_request(:get, url).to_return(
19
+ body: read_fixture_file(fixture_file_name)
20
+ )
21
+ end
30
22
 
31
- context 'information is available' do
32
- it 'returns weather information for given day' do
33
- info = daily.at(date)
23
+ context 'information is available' do
24
+ it 'returns weather information for given day' do
25
+ info = daily.at(date)
34
26
 
35
- expect(info.precipitation_total).to eql(1.5)
36
- expect(info.precipitation_hourly_max).to eql(1.0)
37
- expect(info.precipitation_10min_max).to eql(0.5)
38
- expect(info.temperature_avg).to eql(10.9)
39
- expect(info.temperature_max).to eql(12.2)
40
- expect(info.temperature_min).to eql(8.6)
41
- expect(info.humidity_avg).to eql(68.0)
42
- expect(info.humidity_min).to eql(53.0)
43
- expect(info.day_length).to eql(0.0)
44
- expect(info.general_weather_condition_day).to eql('曇後時々雨')
45
- expect(info.general_weather_condition_night).to eql('雨時々曇')
27
+ expect(info.precipitation_total).to eql(1.5)
28
+ expect(info.precipitation_hourly_max).to eql(1.0)
29
+ expect(info.precipitation_10min_max).to eql(0.5)
30
+ expect(info.temperature_avg).to eql(10.9)
31
+ expect(info.temperature_max).to eql(12.2)
32
+ expect(info.temperature_min).to eql(8.6)
33
+ expect(info.humidity_avg).to eql(68.0)
34
+ expect(info.humidity_min).to eql(53.0)
35
+ expect(info.day_length).to eql(0.0)
36
+ expect(info.general_weather_condition_day).to eql('曇後時々雨')
37
+ expect(info.general_weather_condition_night).to eql('雨時々曇')
38
+ end
46
39
  end
47
- end
48
40
 
49
- context 'information is not available' do
50
- let(:fixture_file_name) {
51
- 'ng.html'
52
- }
41
+ context 'information is not available' do
42
+ let(:fixture_file_name) { 'ng.html' }
53
43
 
54
- it 'raises error' do
55
- expect {
56
- daily.at(date)
57
- }.to raise_error(Kisyo::WeatherInformationNotAvailable)
44
+ it 'raises error' do
45
+ expect { daily.at(date) }.to raise_error(
46
+ Kisyo::WeatherInformationNotAvailable
47
+ )
48
+ end
49
+ end
50
+
51
+ context 'value is "--"' do
52
+ let(:date) { Date.parse('2016-11-04') }
53
+
54
+ it '"--" is converted to nil' do
55
+ info = daily.at(date)
56
+
57
+ expect(info.precipitation_total).to be_nil
58
+ expect(info.precipitation_hourly_max).to be_nil
59
+ expect(info.precipitation_10min_max).to be_nil
60
+ end
58
61
  end
59
62
  end
63
+ context 'multiple request' do
64
+ before do
65
+ stub_request(:get, url)
66
+ .to_return(body: read_fixture_file(fixture_file_name))
67
+ .times(number_of_request)
68
+ end
69
+
70
+ context '2016-11-01 - 2016-11-05' do
71
+ let(:number_of_request) { 1 }
60
72
 
61
- context 'value is "--"' do
62
- let(:date) {
63
- Date.parse('2016-11-04')
64
- }
73
+ it 'caches and reuses first response' do
74
+ date = Date.parse('2016-11-01')
65
75
 
66
- it '"--" is converted to nil' do
67
- info = daily.at(date)
76
+ expect(daily.at(date).precipitation_total).to eql(10.0)
77
+ expect(daily.at(date + 1).precipitation_total).to eql(1.5)
78
+ expect(daily.at(date + 2).precipitation_total).to eql(3.0)
79
+ expect(daily.at(date + 3).precipitation_total).to be_nil
80
+ expect(daily.at(date + 4).precipitation_total).to eql(0.0)
68
81
 
69
- expect(info.precipitation_total).to be_nil
70
- expect(info.precipitation_hourly_max).to be_nil
71
- expect(info.precipitation_10min_max).to be_nil
82
+ expect(a_request(:get, url)).to have_been_made.times(1)
83
+ end
72
84
  end
73
85
  end
74
86
  end
@@ -0,0 +1,13 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/../spec_helper'
3
+
4
+ describe Kisyo::Location do
5
+ describe '.nearest' do
6
+ it 'returns the location closest to the specified latitude and longitude' do
7
+ loc = Kisyo::Location.nearest(35.6809591, 139.7673068)
8
+
9
+ expect(loc.prefecture_id).to eql('44')
10
+ expect(loc.block_id).to eql('47662')
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kisyo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - youpy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-09 00:00:00.000000000 Z
11
+ date: 2022-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -24,34 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: bundler
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.7'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.7'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: rake
43
29
  requirement: !ruby/object:Gem::Requirement
44
30
  requirements:
45
- - - "~>"
31
+ - - ">="
46
32
  - !ruby/object:Gem::Version
47
- version: '10.0'
33
+ version: 12.3.3
48
34
  type: :development
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
- - - "~>"
38
+ - - ">="
53
39
  - !ruby/object:Gem::Version
54
- version: '10.0'
40
+ version: 12.3.3
55
41
  - !ruby/object:Gem::Dependency
56
42
  name: rspec
57
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,7 +80,9 @@ files:
94
80
  - README.md
95
81
  - Rakefile
96
82
  - kisyo.gemspec
83
+ - lib/blocks.csv
97
84
  - lib/kisyo.rb
85
+ - lib/kisyo/cache.rb
98
86
  - lib/kisyo/daily.rb
99
87
  - lib/kisyo/elements/day.rb
100
88
  - lib/kisyo/error.rb
@@ -103,6 +91,7 @@ files:
103
91
  - spec/fixtures/201611.html
104
92
  - spec/fixtures/ng.html
105
93
  - spec/kisyo/daily_spec.rb
94
+ - spec/kisyo/location_spec.rb
106
95
  - spec/spec_helper.rb
107
96
  homepage: ''
108
97
  licenses:
@@ -123,8 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
123
112
  - !ruby/object:Gem::Version
124
113
  version: '0'
125
114
  requirements: []
126
- rubyforge_project:
127
- rubygems_version: 2.5.1
115
+ rubygems_version: 3.1.6
128
116
  signing_key:
129
117
  specification_version: 4
130
118
  summary: A ruby tool for getting weather information from www.data.jma.go.jp
@@ -132,4 +120,5 @@ test_files:
132
120
  - spec/fixtures/201611.html
133
121
  - spec/fixtures/ng.html
134
122
  - spec/kisyo/daily_spec.rb
123
+ - spec/kisyo/location_spec.rb
135
124
  - spec/spec_helper.rb