lita-forecast 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +33 -0
- data/.rspec +2 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/LICENSE +21 -0
- data/README.md +100 -0
- data/Rakefile +13 -0
- data/lib/lita/handlers/forecast/current.rb +65 -0
- data/lib/lita/handlers/forecast/future.rb +65 -0
- data/lib/lita/handlers/forecast/location.rb +31 -0
- data/lib/lita/handlers/forecast/mixins.rb +26 -0
- data/lib/lita/handlers/forecast/persistence.rb +18 -0
- data/lib/lita/handlers/forecast/response.rb +24 -0
- data/lib/lita/handlers/forecast/weather.rb +25 -0
- data/lib/lita/handlers/forecast.rb +57 -0
- data/lib/lita/handlers/forecast_locations.rb +97 -0
- data/lib/lita/handlers/location_search.rb +44 -0
- data/lib/lita-forecast/version.rb +7 -0
- data/lib/lita-forecast.rb +6 -0
- data/lita-forecast.gemspec +34 -0
- data/spec/lita/handlers/forecast/current_spec.rb +264 -0
- data/spec/lita/handlers/forecast/future_spec.rb +260 -0
- data/spec/lita/handlers/forecast/location_spec.rb +116 -0
- data/spec/lita/handlers/forecast/mixins_spec.rb +126 -0
- data/spec/lita/handlers/forecast/persistence_spec.rb +27 -0
- data/spec/lita/handlers/forecast/response_spec.rb +115 -0
- data/spec/lita/handlers/forecast/weather_spec.rb +147 -0
- data/spec/lita/handlers/forecast_locations_spec.rb +296 -0
- data/spec/lita/handlers/forecast_spec.rb +75 -0
- data/spec/lita/handlers/location_search_spec.rb +101 -0
- data/spec/lita_forecast/version_spec.rb +11 -0
- data/spec/spec_helper.rb +12 -0
- metadata +242 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 818e612a4379d01e51b89a449d6c594c93484844
|
4
|
+
data.tar.gz: 4d082b73283ba8bc5618064543d8cfd9a6cb74df
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ffe26f94a9f842179ee7abf1524029fa5e711d6511282c68b113320cf82ad8d57d792633cf470b6394cfb70327f53a3c5dee164b2a16d72b825e56d422ef3480
|
7
|
+
data.tar.gz: be690554ce1e9acdbd1574590cf8693a60aebdbc336624b0ed8a06b3a12bcfe58104e0874daeb470ea94677ffac4943e459f503fbc2b79b6a0588072e5f8b171
|
data/.gitignore
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
coverage
|
6
|
+
InstalledFiles
|
7
|
+
lib/bundler/man
|
8
|
+
pkg
|
9
|
+
rdoc
|
10
|
+
spec/reports
|
11
|
+
test/tmp
|
12
|
+
test/version_tmp
|
13
|
+
tmp
|
14
|
+
Gemfile.lock
|
15
|
+
|
16
|
+
## Documentation cache and generated files:
|
17
|
+
/.yardoc/
|
18
|
+
/_yardoc/
|
19
|
+
/doc/
|
20
|
+
/rdoc/
|
21
|
+
|
22
|
+
## Environment normalisation:
|
23
|
+
/.bundle/
|
24
|
+
/lib/bundler/man/
|
25
|
+
|
26
|
+
# for a library or gem, you might want to ignore these files since the code is
|
27
|
+
# intended to run in multiple environments; otherwise, check them in:
|
28
|
+
# Gemfile.lock
|
29
|
+
# .ruby-version
|
30
|
+
# .ruby-gemset
|
31
|
+
|
32
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
33
|
+
.rvmrc
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Tim Heckman
|
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 all
|
13
|
+
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 THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
lita-forecast
|
2
|
+
=============
|
3
|
+
[![Build Status](https://img.shields.io/travis/theckman/lita-forecast/master.svg)](https://travis-ci.org/theckman/lita-forecast)
|
4
|
+
[![MIT License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://tldrlegal.com/license/mit-license)
|
5
|
+
[![RubyGems :: RMuh Gem Version](http://img.shields.io/gem/v/lita-forecast.svg)](https://rubygems.org/gems/lita-forecast)
|
6
|
+
[![Coveralls Coverage](https://img.shields.io/coveralls/theckman/lita-forecast/master.svg)](https://coveralls.io/r/theckman/lita-forecast)
|
7
|
+
[![Code Climate](https://img.shields.io/codeclimate/github/theckman/lita-forecast.svg)](https://codeclimate.com/github/theckman/lita-forecast)
|
8
|
+
[![Gemnasium](https://img.shields.io/gemnasium/theckman/lita-forecast.svg)](https://gemnasium.com/theckman/lita-forecast)
|
9
|
+
|
10
|
+
Forecast.io plugin for Lita
|
11
|
+
|
12
|
+
LICENSE
|
13
|
+
-------
|
14
|
+
[lita-forecast](https://github.com/theckman/lita-forecast) is released under
|
15
|
+
the [MIT](http://opensource.org/licenses/MIT) license. The full license is
|
16
|
+
provided in the `LICENSE` file.
|
17
|
+
|
18
|
+
CONTRIBUTING
|
19
|
+
------------
|
20
|
+
Something wrong or you want to submit an improvement? Fork the repo, make your
|
21
|
+
changes on a feature branch, write some tests, and submit a pull request. I
|
22
|
+
only ask that the commits have useful information and use proper/complete
|
23
|
+
sentences.
|
24
|
+
|
25
|
+
INSTALLATION
|
26
|
+
------------
|
27
|
+
Simply add `lita-forecast` to the `Gemfile` for your Lita instance.
|
28
|
+
|
29
|
+
```Ruby
|
30
|
+
gem 'lita-forecast'
|
31
|
+
```
|
32
|
+
|
33
|
+
CONFIGURATION
|
34
|
+
-------------
|
35
|
+
There is only one required configuration option for this plugin, and that's
|
36
|
+
your Forecast.io API key
|
37
|
+
[Forecast.io Developer Site](https://developer.forecast.io/register)
|
38
|
+
|
39
|
+
```Ruby
|
40
|
+
config.handlers.forecast.api_key = '<API_KEY>'
|
41
|
+
```
|
42
|
+
|
43
|
+
COMMANDS
|
44
|
+
-----
|
45
|
+
* `wx <alias/location>` - get the weather forecast for a location in US units.
|
46
|
+
* `wc <alias/location>` - get the weather forecast for a location in CA units.
|
47
|
+
* `ws <location>` - returns the lat. and long. for your search string so that
|
48
|
+
you can add a weather alias
|
49
|
+
* `wl` - list known weather aliases
|
50
|
+
* `wadd <alias> <lat> <long> [<description>]` - add an alias to your bot
|
51
|
+
* `wrm alias` - remove an alias added to your bot
|
52
|
+
|
53
|
+
USAGE
|
54
|
+
-----
|
55
|
+
```
|
56
|
+
>> Lita wx San Francisco, CA
|
57
|
+
San Francisco, CA:
|
58
|
+
|
59
|
+
Now: 55.5F (feels like 55.5F) Mostly Cloudy; Winds WSW 8.6mph; Humidity 66%; Dew Pt 44.2F; Pressure 1019.2mb; Cloud cover 82%.
|
60
|
+
Next hour: Mostly cloudy for the hour. Next 24h: Rain throughout the day.
|
61
|
+
|
62
|
+
Summary: Light rain today through Thursday, with temperatures bottoming out at 52°F on Tuesday.
|
63
|
+
Today: Mostly cloudy throughout the day. High 57F, Low 51F. 90% chance of rain. Winds W 7mph.
|
64
|
+
Tomorrow: Rain throughout the day. High 55F, Low 51F. 100% chance of rain. Winds SSW 9mph.
|
65
|
+
|
66
|
+
>> Lita wc San Francisco, CA
|
67
|
+
San Francisco, CA:
|
68
|
+
|
69
|
+
Now: 13.1C (feels like 13.1C) Mostly Cloudy; Winds WSW 12.6kmph; Humidity 65%; Dew Pt 6.7C; Pressure 1019.2mb; Cloud cover 82%.
|
70
|
+
Next hour: Mostly cloudy for the hour. Next 24h: Rain throughout the day.
|
71
|
+
|
72
|
+
Summary: Light rain today through Thursday, with temperatures bottoming out at 11°C on Tuesday.
|
73
|
+
Today: Mostly cloudy throughout the day. High 14C, Low 10C. 90% chance of rain. Winds W 11kmph.
|
74
|
+
Tomorrow: Rain throughout the day. High 13C, Low 10C. 100% chance of rain. Winds SSW 15kmph.
|
75
|
+
|
76
|
+
>> Lita wl
|
77
|
+
There are no weather aliases
|
78
|
+
|
79
|
+
>> Lita ws 501 2nd St, 94107
|
80
|
+
San Francisco, CA: 37.7830503, -122.3933962 :: !wadd <alias> 37.7830503 -122.3933962 <description/city name>
|
81
|
+
|
82
|
+
>> Lita wadd sf 37.7749295 -122.4194155 PagerDuty San Francisco
|
83
|
+
sf added to the cache at [37.7749295, -122.4194155]
|
84
|
+
|
85
|
+
>> Lita wx sf
|
86
|
+
PagerDuty San Francisco:
|
87
|
+
|
88
|
+
Now: 55.6F (feels like 55.6F) Mostly Cloudy; Winds WSW 7.8mph; Humidity 65%; Dew Pt 44.0F; Pressure 1019.2mb; Cloud cover 82%.
|
89
|
+
Next hour: Mostly cloudy for the hour. Next 24h: Rain throughout the day.
|
90
|
+
|
91
|
+
Summary: Light rain today through Thursday, with temperatures bottoming out at 52°F on Tuesday.
|
92
|
+
Today: Mostly cloudy throughout the day. High 57F, Low 51F. 90% chance of rain. Winds W 7mph.
|
93
|
+
Tomorrow: Rain throughout the day. High 55F, Low 51F. 100% chance of rain. Winds SSW 9mph.
|
94
|
+
|
95
|
+
>> Lita wl
|
96
|
+
Known weather aliases: sf
|
97
|
+
|
98
|
+
>> Lita wrm sf
|
99
|
+
Alias removed!
|
100
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# -*- coding: UTF-8 -*_
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubocop/rake_task'
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
Rubocop::RakeTask.new(:rubocop) do |t|
|
8
|
+
t.patterns =
|
9
|
+
%w( Rakefile Gemfile lita-forecast.gemspec lib/**/*.rb spec/*_spec.rb )
|
10
|
+
t.fail_on_error = true
|
11
|
+
end
|
12
|
+
|
13
|
+
task default: [:rubocop, :spec]
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'lita/handlers/forecast/mixins'
|
3
|
+
|
4
|
+
module LitaForecast
|
5
|
+
# LitaForecast::Current
|
6
|
+
#
|
7
|
+
class Current
|
8
|
+
include LitaForecast::Mixins
|
9
|
+
|
10
|
+
def initialize(forecast)
|
11
|
+
@f = forecast
|
12
|
+
end
|
13
|
+
|
14
|
+
def conditions
|
15
|
+
c = currently
|
16
|
+
"#{temp} (feels like #{feels}) #{c['summary']}; Winds #{wind}; " \
|
17
|
+
"Humidity #{humidity}; Dew Pt #{dew_pt}; Pressure #{pressure}; Cloud " \
|
18
|
+
"cover #{clouds}.\n" \
|
19
|
+
"Next hour: #{next_hour} Next 24h: #{today}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def currently
|
25
|
+
@f['currently']
|
26
|
+
end
|
27
|
+
|
28
|
+
def temp
|
29
|
+
"#{currently['temperature'].round(1)}#{units(@f)[:t]}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def feels
|
33
|
+
"#{currently['apparentTemperature'].round(1)}#{units(@f)[:t]}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def wind
|
37
|
+
direction = Compass::Rose.direction(currently['windBearing'], 16)[:abbr]
|
38
|
+
"#{direction} #{currently['windSpeed'].round(1)}#{units(@f)[:w]}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def humidity
|
42
|
+
"#{(currently['humidity'] * 100).round(0)}%"
|
43
|
+
end
|
44
|
+
|
45
|
+
def dew_pt
|
46
|
+
"#{currently['dewPoint'].round(1)}#{units(@f)[:t]}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def pressure
|
50
|
+
"#{currently['pressure'].round(1)}mb"
|
51
|
+
end
|
52
|
+
|
53
|
+
def clouds
|
54
|
+
"#{(currently['cloudCover'] * 100).round(0)}%"
|
55
|
+
end
|
56
|
+
|
57
|
+
def next_hour
|
58
|
+
@f['minutely']['summary']
|
59
|
+
end
|
60
|
+
|
61
|
+
def today
|
62
|
+
@f['hourly']['summary']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'English'
|
3
|
+
require 'compass_rose'
|
4
|
+
require 'lita/handlers/forecast/mixins'
|
5
|
+
|
6
|
+
module LitaForecast
|
7
|
+
# LitaForecast::Future
|
8
|
+
#
|
9
|
+
class Future
|
10
|
+
include LitaForecast::Mixins
|
11
|
+
|
12
|
+
def method_missing(method, *args, &block)
|
13
|
+
super unless /^generate_(.*)$/.match(method)
|
14
|
+
m = $LAST_MATCH_INFO
|
15
|
+
super unless %w(today tomorrow).include?(m[1])
|
16
|
+
i = { today: 0, tomorrow: 1 }[m[1].to_sym]
|
17
|
+
generate_day(i, m[1])
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(forecast)
|
21
|
+
@f = forecast
|
22
|
+
end
|
23
|
+
|
24
|
+
def conditions
|
25
|
+
future = generate_summary
|
26
|
+
future << generate_today
|
27
|
+
future << generate_tomorrow
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def daily
|
33
|
+
@f['daily']['data']
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate_summary
|
37
|
+
"Summary: #{@f['daily']['summary']}\n"
|
38
|
+
end
|
39
|
+
|
40
|
+
def generate_day(index, day)
|
41
|
+
@i = daily[index]
|
42
|
+
@d = day
|
43
|
+
"#{summary} #{high_low} #{precip} #{wind}\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
def summary
|
47
|
+
"#{@d.capitalize}: #{@i['summary']}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def high_low
|
51
|
+
"High #{@i['temperatureMax'].round(0)}#{units(@f)[:t]}, " \
|
52
|
+
"Low #{@i['temperatureMin'].round(0)}#{units(@f)[:t]}."
|
53
|
+
end
|
54
|
+
|
55
|
+
def precip
|
56
|
+
type = @i['precipType'] || 'precipitation'
|
57
|
+
"#{(@i['precipProbability'] * 100).round(0)}% chance of #{type}."
|
58
|
+
end
|
59
|
+
|
60
|
+
def wind
|
61
|
+
direction = Compass::Rose.direction(@i['windBearing'], 16)[:abbr]
|
62
|
+
"Winds #{direction} #{@i['windSpeed'].round(0)}#{units(@f)[:w]}."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'geocoder'
|
3
|
+
require 'lita/handlers/forecast/mixins'
|
4
|
+
|
5
|
+
module LitaForecast
|
6
|
+
# LitaForecast class for determining someone's location
|
7
|
+
#
|
8
|
+
class Location
|
9
|
+
include LitaForecast::Mixins
|
10
|
+
|
11
|
+
attr_accessor :lita_redis
|
12
|
+
|
13
|
+
def initialize(redis)
|
14
|
+
@lita_redis = redis
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_location(search)
|
18
|
+
loc = lita_redis.hgetall("alias:#{search}").symbolize_keys!
|
19
|
+
|
20
|
+
if loc.empty?
|
21
|
+
g = Geocoder.search(search)[0].data
|
22
|
+
gl = geo_location(g)
|
23
|
+
loc = { lat: g['geometry']['location']['lat'],
|
24
|
+
lng: g['geometry']['location']['lng'],
|
25
|
+
desc: "#{gl[:city]}, #{gl[:state]}" }
|
26
|
+
end
|
27
|
+
|
28
|
+
loc
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
|
3
|
+
module LitaForecast
|
4
|
+
# The random mixins I'll need, eventually
|
5
|
+
#
|
6
|
+
module Mixins
|
7
|
+
def geo_location(result)
|
8
|
+
h = {}
|
9
|
+
result['address_components'].each do |a|
|
10
|
+
a['types'].each do |t|
|
11
|
+
h[:city] = a['long_name'] if t == 'locality'
|
12
|
+
h[:state] = a['short_name'] if t == 'administrative_area_level_1'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
h
|
16
|
+
end
|
17
|
+
|
18
|
+
def units(forecast)
|
19
|
+
if forecast['flags']['units'] == 'us'
|
20
|
+
{ t: 'F', w: 'mph', v: 'mi' }
|
21
|
+
else
|
22
|
+
{ t: 'C', w: 'kmph', v: 'km' }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'lita'
|
3
|
+
require 'redis-namespace'
|
4
|
+
|
5
|
+
# LitaForecast module
|
6
|
+
#
|
7
|
+
module LitaForecast
|
8
|
+
FORECAST_NAMESPACE = 'handlers:forecast'
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def redis
|
12
|
+
@forecastredis ||= begin
|
13
|
+
Redis::Namespace.new(FORECAST_NAMESPACE, redis: Lita.redis)
|
14
|
+
end
|
15
|
+
@forecastredis
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'compass_rose'
|
3
|
+
require 'lita/handlers/forecast/current'
|
4
|
+
require 'lita/handlers/forecast/future'
|
5
|
+
|
6
|
+
module LitaForecast
|
7
|
+
# LutaForecast::Response
|
8
|
+
#
|
9
|
+
class Response
|
10
|
+
def initialize(forecast, location)
|
11
|
+
@forecast = forecast
|
12
|
+
@location = location
|
13
|
+
@current = LitaForecast::Current.new(@forecast)
|
14
|
+
@future = LitaForecast::Future.new(@forecast)
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate
|
18
|
+
response = "#{@location}:\n\n"
|
19
|
+
response << "Now: #{@current.conditions}\n\n"
|
20
|
+
response << @future.conditions
|
21
|
+
response
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'forecast_io'
|
3
|
+
require 'lita/handlers/forecast/location'
|
4
|
+
require 'lita/handlers/forecast/response'
|
5
|
+
|
6
|
+
# The thing
|
7
|
+
#
|
8
|
+
module LitaForecast
|
9
|
+
# Module
|
10
|
+
#
|
11
|
+
module Weather
|
12
|
+
def weather_forecast(api_key, l = {})
|
13
|
+
ForecastIO.api_key = api_key
|
14
|
+
l = { params: { exclude: 'alerts' } }.merge(l)
|
15
|
+
ForecastIO.forecast(l[:lat].to_f, l[:lng].to_f, params: l[:params])
|
16
|
+
end
|
17
|
+
|
18
|
+
def weather(response, api_key, units = 'us')
|
19
|
+
location = LitaForecast::Location.new(LitaForecast.redis)
|
20
|
+
.find_location(response.args.join(' '))
|
21
|
+
f = weather_forecast(api_key, location.merge(params: { units: units }))
|
22
|
+
LitaForecast::Response.new(f, location[:desc]).generate
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'lita/handlers/forecast/mixins'
|
3
|
+
require 'lita/handlers/forecast/weather'
|
4
|
+
|
5
|
+
module Lita
|
6
|
+
module Handlers
|
7
|
+
# Lita Forecast.io plugin!
|
8
|
+
# this provides handlers for US and Canadian units
|
9
|
+
#
|
10
|
+
class Forecast < Handler
|
11
|
+
include LitaForecast::Mixins
|
12
|
+
include LitaForecast::Weather
|
13
|
+
|
14
|
+
def self.default_config(config)
|
15
|
+
config.api_key = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
route(
|
19
|
+
/^wx\s(.*)$/,
|
20
|
+
:weather_us,
|
21
|
+
command: true,
|
22
|
+
help: {
|
23
|
+
'wx san francisco' => 'Get the weather for San Francisco'
|
24
|
+
}
|
25
|
+
)
|
26
|
+
|
27
|
+
route(
|
28
|
+
/^wc\s(.*)$/,
|
29
|
+
:weather_ca,
|
30
|
+
command: true,
|
31
|
+
help: {
|
32
|
+
'wc toronto' => 'You want the weather for Toronto, eh?'
|
33
|
+
}
|
34
|
+
)
|
35
|
+
|
36
|
+
def weather_us(response)
|
37
|
+
response.reply(build_weather('us', response))
|
38
|
+
end
|
39
|
+
|
40
|
+
def weather_ca(response)
|
41
|
+
response.reply(build_weather('ca', response))
|
42
|
+
end
|
43
|
+
|
44
|
+
def build_weather(units, response)
|
45
|
+
weather(response, api_key, units)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def api_key
|
51
|
+
Lita.config.handlers.forecast.api_key
|
52
|
+
end
|
53
|
+
|
54
|
+
Lita.register_handler(Forecast)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'lita/handlers/forecast/persistence'
|
3
|
+
|
4
|
+
module Lita
|
5
|
+
module Handlers
|
6
|
+
# Lita::Handlers::ForecastLocations
|
7
|
+
#
|
8
|
+
class ForecastLocations < Handler
|
9
|
+
route(
|
10
|
+
/^wadd\s(.+?)\s([0-9.,\-]+?)\s([0-9.,\-]+)\s*(.*)$/,
|
11
|
+
:location_add,
|
12
|
+
command: true,
|
13
|
+
help: {
|
14
|
+
'wadd sf 37.78439928029 -122.39204721970 PagerDuty San Francisco' =>
|
15
|
+
'Add the lat and long of the office with the alias "sf"'
|
16
|
+
}
|
17
|
+
)
|
18
|
+
|
19
|
+
route(
|
20
|
+
/^wrm\s(.+?)$/,
|
21
|
+
:location_rm,
|
22
|
+
command: true,
|
23
|
+
help: {
|
24
|
+
'wrm sf' =>
|
25
|
+
'Remove the specified alias, in this case "sf"'
|
26
|
+
}
|
27
|
+
)
|
28
|
+
|
29
|
+
route(
|
30
|
+
/^wl$/,
|
31
|
+
:locations,
|
32
|
+
command: true,
|
33
|
+
help: {
|
34
|
+
'wl' => 'List known weather aliases'
|
35
|
+
}
|
36
|
+
)
|
37
|
+
|
38
|
+
def self.default_config(config)
|
39
|
+
config.api_key = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def location_add(response)
|
43
|
+
r = response.matches[0]
|
44
|
+
return response.reply('Already there!') if alias_exists?(r[0])
|
45
|
+
|
46
|
+
d = saved_location_hash(r)
|
47
|
+
add_to_cache(d)
|
48
|
+
|
49
|
+
response.reply("#{r[0]} added to the cache at [#{r[1]}, #{r[2]}]")
|
50
|
+
end
|
51
|
+
|
52
|
+
def location_rm(response)
|
53
|
+
key = "alias:#{response.matches[0][0]}"
|
54
|
+
return response.reply('Alias not found') unless alias_exists?(key)
|
55
|
+
rm_from_cache(key)
|
56
|
+
if LitaForecast.redis.keys(key).empty?
|
57
|
+
return response.reply('Alias removed!')
|
58
|
+
else
|
59
|
+
return response.reply('Somehow that failed... I need an adult!')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def locations(response)
|
64
|
+
k = LitaForecast.redis.keys('alias:*').map { |v| v.gsub('alias:', '') }
|
65
|
+
return response.reply('There are no weather aliases') if k.empty?
|
66
|
+
response.reply("Known weather aliases: #{k.join(', ')}")
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def alias_exists?(key)
|
72
|
+
return true unless LitaForecast.redis.hgetall(key).empty?
|
73
|
+
false
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_to_cache(location)
|
77
|
+
key = "alias:#{location[:name]}"
|
78
|
+
LitaForecast.redis.pipelined do
|
79
|
+
[:lat, :lng, :desc].each do |k|
|
80
|
+
LitaForecast.redis.hset(key, k.to_s, location[k])
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def rm_from_cache(key)
|
86
|
+
LitaForecast.redis.del(key)
|
87
|
+
end
|
88
|
+
|
89
|
+
def saved_location_hash(r)
|
90
|
+
d = (r[3].nil? || r[3].empty?) ? r[0] : r[3].slice(0..29)
|
91
|
+
{ name: r[0], lat: r[1], lng: r[2], desc: d }
|
92
|
+
end
|
93
|
+
|
94
|
+
Lita.register_handler(ForecastLocations)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# -*- coding: UTF-8 -*-
|
2
|
+
require 'geocoder'
|
3
|
+
require 'lita/handlers/forecast/mixins'
|
4
|
+
|
5
|
+
module Lita
|
6
|
+
module Handlers
|
7
|
+
# Lita::Handlers::LocationSearch
|
8
|
+
#
|
9
|
+
class LocationSearch < Handler
|
10
|
+
include LitaForecast::Mixins
|
11
|
+
|
12
|
+
route(
|
13
|
+
/^ws\s(.*)$/,
|
14
|
+
:search,
|
15
|
+
command: true,
|
16
|
+
help: { 'ws san francisco' =>
|
17
|
+
'find the lat and long for the location' }
|
18
|
+
)
|
19
|
+
|
20
|
+
def search(response)
|
21
|
+
s = response.args.join(' ')
|
22
|
+
r = search_geocoder(s)
|
23
|
+
return response.reply('You made that up...') if r.empty?
|
24
|
+
response.reply(generate_response(r))
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def search_geocoder(search)
|
30
|
+
Geocoder.search(search)[0].data
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate_response(result)
|
34
|
+
l = geo_location(result)
|
35
|
+
lat = result['geometry']['location']['lat']
|
36
|
+
lng = result['geometry']['location']['lng']
|
37
|
+
"#{l[:city]}, #{l[:state]}: #{lat}, #{lng} :: "\
|
38
|
+
"!wadd <alias> #{lat} #{lng} <description/city name>"
|
39
|
+
end
|
40
|
+
|
41
|
+
Lita.register_handler(LocationSearch)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|