ruboty-tenki 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,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e5730ffbba4b056578e4398a5e0c6544fec30c6653947782738a84c87eba4902
4
+ data.tar.gz: a13ed01c9ef78e5db7081ff7a536963114480f9dc0135417c67a587912bc2e50
5
+ SHA512:
6
+ metadata.gz: c19d9a46001eb81909134e129d658cb705a0ae08aca4bc61615e8639cb74603ace3997b9841081a4fb16ca2642f6753481f9c2d75ce650afee1b0ab7e52e1bb2
7
+ data.tar.gz: 782b8b89a4680202acf31a3cf0dadc9a491f4665170480efb0e7b38e1ad509af6a08c4ca59207286ef0df25e660697a7b22fe6e9eb5b5129fbbfd0a6df88c97c
@@ -0,0 +1,11 @@
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
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.5.0
5
+ before_install: gem install bundler -v 1.16.1
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
+
5
+ # Specify your gem's dependencies in ruboty-tenki.gemspec
6
+ gemspec
@@ -0,0 +1,52 @@
1
+ # Ruboty::Tenki
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'ruboty-tenki'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install ruboty-tenki
18
+
19
+ ## Usage
20
+
21
+ ```shell
22
+ > ruboty 今日の東京の天気は
23
+ 日本、東京都東京
24
+ 2018/02/01 の天気
25
+ 00:00 雲 3℃ 75% 1038hPa
26
+ 03:00 雲 7℃ 91% 1038hPa
27
+ 06:00 曇りがち 6℃ 82% 1037hPa
28
+ 09:00 小雨 3℃ 87% 1038hPa
29
+ 12:00 小雨 2℃ 92% 1039hPa
30
+ 15:00 小雨 1℃ 94% 1040hPa
31
+ 18:00 小雨 0℃ 96% 1039hPa
32
+ 21:00 雪 0℃ 92% 1039hPa
33
+ ```
34
+
35
+
36
+ ## ENV
37
+
38
+ ```
39
+ RUBOTY_TENKI_GOOGLE_MAP_APIKEY - Google Maps Geocoding API:https://developers.google.com/maps/documentation/geocoding/start
40
+ RUBOTY_TENKI_OPEN_WEATHER_MAP_APPID - OpenWeatherMap API:https://openweathermap.org/
41
+ ```
42
+
43
+
44
+ ## Development
45
+
46
+ 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.
47
+
48
+ 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).
49
+
50
+ ## Contributing
51
+
52
+ Bug reports and pull requests are welcome on GitHub at https://github.com/osyo-manga/gem-ruboty-tenki.
@@ -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
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ruboty/tenki"
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__)
@@ -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
@@ -0,0 +1,15 @@
1
+ require_relative "../tenki.rb"
2
+
3
+ module Ruboty module Handlers
4
+ class Tenki < Base
5
+ on(
6
+ Ruboty::Tenki.query_matcher,
7
+ name: "tenki",
8
+ description: "天気"
9
+ )
10
+
11
+ def weather message
12
+ message.reply(Ruboty::Tenki.get message.body)
13
+ end
14
+ end
15
+ end end
@@ -0,0 +1,153 @@
1
+ require "ruboty/tenki/version"
2
+
3
+ using Module.new {
4
+ refine Hash do
5
+ def to_struct
6
+ Struct.new(*keys).new(*values)
7
+ end
8
+ end
9
+ }
10
+
11
+ module Ruboty module Tenki
12
+ module_function
13
+ def http_get_json url, query
14
+ res = Faraday.get url, query
15
+ JSON[res.body, symbolize_names: true]
16
+ end
17
+
18
+ def query_matcher
19
+ dates_regexp = "今日|きょう|明日|あした|明後日|あさって|今|いま|3日後|3日後|4日後|4日後"
20
+ @query_matcher ||= /
21
+ (
22
+ (?<city>.*)の(?<day>#{dates_regexp})の(天気|てんき).*
23
+ )|(
24
+ (?<day>#{dates_regexp})の(?<city>.*)の(天気|てんき)
25
+ )
26
+ /ux
27
+ end
28
+
29
+ def query_match? str
30
+ str =~ Tenki.query_matcher
31
+ end
32
+
33
+ def query_parse str
34
+ if str =~ Tenki.query_matcher
35
+ data = Regexp.last_match
36
+ day = data[:day]
37
+ case day
38
+ when /今日|きょう/u
39
+ day = :today
40
+ when /明日|あした/u
41
+ day = :tomorrow
42
+ when /明後日|あさって/u
43
+ day = :day_after_tomorrow
44
+ when /3日後|3日後/
45
+ day = 3
46
+ when /4日後|4日後/
47
+ day = 4
48
+ when /今|いま/
49
+ day = :current
50
+ end
51
+
52
+ OpenStruct.new(city: data[:city], day: day)
53
+ else
54
+ nil
55
+ end
56
+ end
57
+
58
+ def get_geocode address
59
+ url = "https://maps.googleapis.com/maps/api/geocode/json"
60
+ request = { address: address, key: ENV["RUBOTY_TENKI_GOOGLE_MAP_APIKEY"], language: :ja }
61
+
62
+ res = http_get_json url, request
63
+ if res[:status] != "OK"
64
+ return
65
+ end
66
+
67
+ res[:results].first.yield_self { |it|
68
+ {
69
+ address: it[:formatted_address],
70
+ location: it.dig(:geometry, :location)
71
+ }
72
+ }
73
+ end
74
+
75
+ def weather query
76
+ return unless option = Tenki.query_parse(query)
77
+ return unless geocode = Tenki.get_geocode(option.city)
78
+
79
+ request = {
80
+ lat: geocode.dig(:location, :lat),
81
+ lon: geocode.dig(:location, :lng),
82
+ units: "metric",
83
+ APPID: ENV["RUBOTY_TENKI_OPEN_WEATHER_MAP_APPID"],
84
+ lang: "ja"
85
+ }
86
+
87
+ forecast = proc { |date|
88
+ http_get_json("http://api.openweathermap.org/data/2.5/forecast", request).yield_self { |res|
89
+ res[:list].select! { |it|
90
+ date_ = DateTime.parse(it[:dt_txt])
91
+ date_.day == date.day
92
+ }
93
+ res.merge(date: date)
94
+ }
95
+ }
96
+
97
+ case option.day
98
+ when :current
99
+ http_get_json "http://api.openweathermap.org/data/2.5/weather", request
100
+ when :today
101
+ forecast.call Date.today
102
+ when :tomorrow
103
+ forecast.call (Date.today + 1)
104
+ when :day_after_tomorrow
105
+ forecast.call (Date.today + 2)
106
+ end.merge(day: option.day, request: request, geocode: geocode)
107
+ end
108
+
109
+ using Module.new {
110
+ refine Hash do
111
+ def to_str_weather
112
+ <<~EOS
113
+ 天候:#{self[:weather][0][:description]}
114
+ 気温:#{dig(:main, :temp)}℃
115
+ 湿度:#{dig(:main, :humidity)}%
116
+ 気圧:#{dig(:main, :pressure)}hPa
117
+ EOS
118
+ end
119
+
120
+ def to_str_weather_line
121
+ main = self[:main]
122
+ data = {
123
+ time: DateTime.parse(self[:dt_txt]).strftime("%H:%M"),
124
+ weather: "%10s" % self[:weather][0][:description],
125
+ temp: "%3d" % main[:temp].round,
126
+ humidity: "%3d" % main[:humidity],
127
+ pressure: "%4d" % main[:pressure],
128
+ }
129
+ "#{data[:time]} #{data[:weather]} #{data[:temp]}℃ #{data[:humidity]}% #{data[:pressure]}hPa"
130
+ end
131
+ end
132
+ }
133
+
134
+ def get query
135
+ res = Tenki.weather(query)
136
+
137
+ if res.nil? || res[:cod].to_i != 200
138
+ return "見つかりませんでした"
139
+ end
140
+ if res[:day] == :current
141
+ <<~EOS
142
+ #{res.dig(:geocode, :address)}の天気
143
+ #{res.to_str_weather}
144
+ EOS
145
+ else
146
+ <<~EOS
147
+ #{res.dig(:geocode, :address)}
148
+ #{res[:date].strftime("%Y/%m/%d")} の天気
149
+ #{res[:list].map(&:to_str_weather_line).join("\n")}
150
+ EOS
151
+ end.chomp
152
+ end
153
+ end end
@@ -0,0 +1,5 @@
1
+ module Ruboty
2
+ module Tenki
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,28 @@
1
+
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "ruboty/tenki/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ruboty-tenki"
8
+ spec.version = Ruboty::Tenki::VERSION
9
+ spec.authors = ["manga_osyo"]
10
+ spec.email = ["manga.osyo@gmail.com"]
11
+
12
+ spec.summary = %q{Ruboty weather handler.}
13
+ spec.description = %q{Ruboty weather handler.}
14
+ spec.homepage = "https://github.com/osyo-manga/gem-ruboty-tenki"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
+ f.match(%r{^(test|spec|features)/})
18
+ end
19
+ spec.bindir = "exe"
20
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
+ spec.require_paths = ["lib"]
22
+
23
+ spec.add_dependency "faraday"
24
+ spec.add_development_dependency "bundler", "~> 1.16"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "rspec", "~> 3.0"
27
+ spec.add_development_dependency "ruboty"
28
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruboty-tenki
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - manga_osyo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2018-02-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
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.16'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.16'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: ruboty
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Ruboty weather handler.
84
+ email:
85
+ - manga.osyo@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - README.md
95
+ - Rakefile
96
+ - bin/console
97
+ - bin/setup
98
+ - lib/ruboty/handlers/tenki.rb
99
+ - lib/ruboty/tenki.rb
100
+ - lib/ruboty/tenki/version.rb
101
+ - ruboty-tenki.gemspec
102
+ homepage: https://github.com/osyo-manga/gem-ruboty-tenki
103
+ licenses: []
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.7.3
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Ruboty weather handler.
125
+ test_files: []