kisyo 0.0.2 → 0.1.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,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