zetabot 2.1.2 → 2.2.1

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.
@@ -24,22 +24,22 @@ module Admin
24
24
 
25
25
 
26
26
  def bl_channel(m, chan)
27
- m.reply "#{chan} is already on BlackList" if Blacklist.channels.include? chan
27
+ return m.reply "#{chan} is already on BlackList" if Blacklist.channels.include? chan
28
28
  Blacklist.channels << chan
29
29
  save_blacklist()
30
30
  m.reply "#{chan} is now on the BlackList"
31
31
  end
32
32
 
33
33
  def bl_url(m, url)
34
- m.reply "#{url} is already on BlackList" if Blacklist.channels.include? url
34
+ return m.reply "#{url} is already on BlackList" if Blacklist.urls.include? url
35
35
  Blacklist.urls << url
36
36
  save_blacklist()
37
37
  m.reply "#{url} is now on the BlackList"
38
38
  end
39
39
 
40
40
  def bl_mask(m, mask)
41
- m.reply "#{mask} is already on BlackList" if Blacklist.masks.include? mask
42
- Blacklist.masks << url
41
+ return m.reply "#{mask} is already on BlackList" if Blacklist.masks.include? mask
42
+ Blacklist.masks << mask
43
43
  save_blacklist()
44
44
  m.reply "#{mask} is now on the BlackList"
45
45
  end
@@ -50,10 +50,10 @@ module Admin
50
50
 
51
51
  def bl_defaults(m)
52
52
  clear_blacklist()
53
- Blacklist.urls = Config.options[:blacklist][:urls]
54
- Blacklist.users = Config.options[:blacklist][:users]
55
- Blacklist.masks = Config.options[:blacklist][:masks]
56
- Blacklist.channels = Config.options[:blacklist][:channels]
53
+ Blacklist.urls = Config.options[:blacklist][:urls].dup
54
+ Blacklist.users = Config.options[:blacklist][:users].dup
55
+ Blacklist.masks = Config.options[:blacklist][:masks].dup
56
+ Blacklist.channels = Config.options[:blacklist][:channels].dup
57
57
  save_blacklist()
58
58
  m.reply 'Default Blacklist Loaded'
59
59
  end
@@ -17,14 +17,24 @@ module Admin
17
17
 
18
18
  # Methods
19
19
  def nick(m, nick)
20
+ old_nick = @bot.nick
20
21
  bot.nick = nick
21
22
  synchronize(:nickchange) do
22
- @bot.handlers.dispatch :admin, m, "My nick got changed from #{@bot.last_nick} to #{@bot.nick} by #{m.user.nick}", m.target
23
+ @bot.handlers.dispatch :admin, m, "My nick got changed from #{old_nick} to #{nick} by #{m.user.nick}", m.target
23
24
  end
24
25
  end
25
26
 
26
- def mode(m, nick)
27
- bot.modes = m
27
+ def mode(m, modes)
28
+ add, remove = [], []
29
+ target = add
30
+ modes.strip.each_char do |c|
31
+ case c
32
+ when '+' then target = add
33
+ when '-' then target = remove
34
+ else target << c
35
+ end
36
+ end
37
+ bot.modes = (bot.modes | add) - remove
28
38
  end
29
39
 
30
40
  def quit(m, msg=nil)
@@ -33,7 +33,7 @@ module Admin
33
33
 
34
34
  def botevalmsg(m, s)
35
35
  return unless Config.debug
36
- return m.user.msg eval(s)
36
+ return m.user.send eval(s)
37
37
  rescue => e
38
38
  m.user.send "eval error: %s\n- %s (%s)" % [s, e.message, e.class.name]
39
39
  end
@@ -11,7 +11,7 @@ module Admin
11
11
 
12
12
  def open_fifo(m)
13
13
  # Sometimes FiFo is left open on crash, remove old fifo
14
- if File.exists?(File.join(Dir.home, '.zeta', 'zeta.io'))
14
+ if File.exist?(File.join(Dir.home, '.zeta', 'zeta.io'))
15
15
  File.delete(File.join(Dir.home, '.zeta', 'zeta.io'))
16
16
  end
17
17
 
@@ -22,7 +22,7 @@ module Admin
22
22
  match 'ignorelist', method: :ignore_list
23
23
 
24
24
  def finalize
25
- save_blacklist()
25
+ save_blacklist
26
26
  end
27
27
 
28
28
  # Methods
@@ -31,7 +31,7 @@ module Admin
31
31
  return m.reply("You can't ignore yourself") if m.user.nick == nickname
32
32
  u = User(nickname)
33
33
  if m.channel.users.member?(u)
34
- if Blacklist.users.include? u
34
+ if Blacklist.users.include? u.to_s
35
35
  m.reply("#{nickname} is already being ignored")
36
36
  else
37
37
  Blacklist.users << u.to_s
@@ -40,7 +40,8 @@ module Admin
40
40
  else
41
41
  m.reply "#{nickname} isn't currently in channel"
42
42
  end
43
- save_blacklist()
43
+
44
+ save_blacklist
44
45
  end
45
46
 
46
47
  def unignore_user(m, nickname)
@@ -52,7 +53,8 @@ module Admin
52
53
  else
53
54
  m.reply "#{nickname} isn't on the ignore list"
54
55
  end
55
- save_blacklist()
56
+
57
+ save_blacklist
56
58
  end
57
59
 
58
60
  def disable_channel(m, channel=nil)
@@ -71,7 +73,8 @@ module Admin
71
73
  m.action_reply "has disabled #{m.channel.to_s} buffer"
72
74
  end
73
75
  end
74
- save_blacklist()
76
+
77
+ save_blacklist
75
78
  end
76
79
 
77
80
  def enable_channel(m, channel=nil)
@@ -90,11 +93,12 @@ module Admin
90
93
  m.reply('Channel is currently enabled')
91
94
  end
92
95
  end
93
- save_blacklist()
96
+
97
+ save_blacklist
94
98
  end
95
99
 
96
100
  def ignore_list(m)
97
- m.reply "Currently ignored users are: #{Blacklist.users.join(', ')}"
101
+ m.reply "Currently, ignored users are: #{Blacklist.users.join(', ')}"
98
102
  end
99
103
 
100
104
 
@@ -30,13 +30,13 @@ module Admin
30
30
  def oper_clearchan(m, chan, confirm=false)
31
31
  if confirm == 'yes' || confirm == 'true'
32
32
  Channel(chan).join
33
- User('OperServ').send("mode #{chan} +o #{Zeta}")
33
+ User('OperServ').send("mode #{chan} +o #{@bot.nick}")
34
34
  User('OperServ').send("mode #{chan} +mi")
35
35
  Channel(chan).send('This channel is being cleared')
36
36
 
37
37
  number_killed = 0
38
38
  Channel(chan).users.each_key do |u|
39
- if u != Zeta
39
+ if u != @bot
40
40
  number_killed += 1
41
41
  @bot.irc.send("KILL #{u.nick} This channel is being cleared")
42
42
  end
@@ -23,25 +23,36 @@ module Admin
23
23
  $1 + "_" + $2
24
24
  }.downcase # we downcase here to also catch the first letter
25
25
 
26
- #file_name = "lib/plugins/#{mapping}.rb"
27
- stdlib_plugin = File.join('Zeta', 'plugins', p.to_s)
28
- custom_plugin = File.join(Dir.home, '.zeta', 'plugins', p.to_s, "#{p.to_s}.rb")
26
+ # Mapping becomes part of a file path; reject anything that could traverse directories
27
+ unless mapping.match?(/\A\w+\z/)
28
+ m.reply "Could not load #{plugin} because #{mapping} is not a valid plugin name."
29
+ return
30
+ end
31
+
32
+ custom_plugin = File.join(Dir.home, '.zeta', 'plugins', mapping, "#{mapping}.rb")
33
+ stdlib_plugin = File.expand_path(File.join('..', 'plugins', "#{mapping}.rb"), __dir__)
34
+ file_name = [custom_plugin, stdlib_plugin].find { |f| File.exist?(f) }
35
+
36
+ unless file_name
37
+ m.reply "Could not load #{plugin} because #{mapping}.rb does not exist."
38
+ return
39
+ end
29
40
 
30
- unless File.exist?(custom_plugin)
31
- m.reply "Could not load #{plugin} because #{file_name} does not exist."
41
+ existing = plugin_class(plugin)
42
+ if existing && @bot.plugins.any? { |p| p.instance_of?(existing) }
43
+ m.reply "#{plugin} is already loaded."
32
44
  return
33
45
  end
34
46
 
35
47
  begin
36
- load(custom_plugin)
37
- rescue
48
+ load(file_name)
49
+ rescue StandardError, ScriptError
38
50
  m.reply "Could not load #{plugin}."
39
51
  raise
40
52
  end
41
53
 
42
- begin
43
- const = Plugins.const_get(plugin)
44
- rescue NameError
54
+ const = plugin_class(plugin)
55
+ unless const
45
56
  m.reply "Could not load #{plugin} because no matching class was found."
46
57
  return
47
58
  end
@@ -51,9 +62,8 @@ module Admin
51
62
  end
52
63
 
53
64
  def unload_plugin(m, plugin)
54
- begin
55
- plugin_class = Plugins.const_get(plugin)
56
- rescue NameError
65
+ plugin_class = plugin_class(plugin)
66
+ unless plugin_class
57
67
  m.reply "Could not unload #{plugin} because no matching class was found."
58
68
  return
59
69
  end
@@ -92,14 +102,23 @@ module Admin
92
102
  end
93
103
 
94
104
  def set_option(m, plugin, option, value)
95
- begin
96
- const = Plugins.const_get(plugin)
97
- rescue NameError
105
+ const = plugin_class(plugin)
106
+ unless const
98
107
  m.reply "Could not set plugin option for #{plugin} because no matching class was found."
99
108
  return
100
109
  end
101
110
  @bot.config.plugins.options[const][option.to_sym] = eval(value)
102
111
  end
112
+
113
+ private
114
+
115
+ # Bare `Plugins` here would resolve to this class, not the ::Plugins namespace.
116
+ def plugin_class(name)
117
+ const = ::Plugins.const_get(name, false)
118
+ const if const.is_a?(Class) && const.include?(Cinch::Plugin)
119
+ rescue NameError
120
+ nil
121
+ end
103
122
  end
104
123
 
105
124
  end
@@ -1,7 +1,9 @@
1
+ require 'fileutils'
2
+
1
3
  BlackListStruct = Struct.new :channels, :users, :plugins, :urls, :masks
2
4
 
3
5
  # Load Cached
4
- if File.exists?(File.join(Dir.home, '.zeta', 'cache', 'blacklist.rb'))
6
+ if File.exist?(File.join(Dir.home, '.zeta', 'cache', 'blacklist.rb'))
5
7
  File.open(File.join(Dir.home, '.zeta', 'cache', 'blacklist.rb')) do |file|
6
8
  Blacklist = Marshal.load(file)
7
9
  end
@@ -23,5 +25,5 @@ def clear_blacklist()
23
25
  Blacklist.channels = []
24
26
  Blacklist.urls = []
25
27
  Blacklist.masks = []
26
- File.delete(File.join(Dir.home, '.zeta', 'cache', 'blacklist.rb'))
28
+ FileUtils.rm_f(File.join(Dir.home, '.zeta', 'cache', 'blacklist.rb'))
27
29
  end
@@ -0,0 +1,3 @@
1
+ Hello I'm {bot_name}.
2
+ I am currently trolling {total_users} users in {total_channels} channels with an uptime of {uptime}
3
+ My master is {owner_name} and he has plugged me with {plugins_count_remaining} plugins
data/lib/Zeta/cinch.rb CHANGED
@@ -1,4 +1,10 @@
1
1
  require 'cinch'
2
+ require 'socket'
3
+
4
+ # Ruby 3.4+ connects with Happy Eyeballs v2, which resolves IPv4/IPv6 separately and
5
+ # prefers IPv6, ignoring the system's address ordering (e.g. /etc/gai.conf).
6
+ # Restore the pre-3.4 behaviour so the OS decides which address family to use.
7
+ Socket.tcp_fast_fallback = false if Socket.respond_to?(:tcp_fast_fallback=)
2
8
 
3
9
  Bot = Cinch::Bot.new do
4
10
  configure do |c|
data/lib/Zeta/config.rb CHANGED
@@ -34,7 +34,7 @@ ConfigStruct = Struct.new(
34
34
  # Initialize Config
35
35
  Config = ConfigStruct.new
36
36
 
37
- if File.exists? File.join(Dir.home, '.zeta', 'config.rb')
37
+ if File.exist? File.join(Dir.home, '.zeta', 'config.rb')
38
38
  begin
39
39
  require File.join(Dir.home, '.zeta', 'config.rb')
40
40
  rescue => e
data/lib/Zeta/locale.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  def load_locale(file)
2
2
  Config.locale ||= 'en' # Default to english
3
3
 
4
- if File.exists?( File.join(Dir.home, '.zeta', 'locale', Config.locale, "#{file}.yml") )
4
+ if File.exist?( File.join(Dir.home, '.zeta', 'locale', Config.locale, "#{file}.yml") )
5
5
  ## Overide included library if file exists
6
6
  YAML::load_file(
7
7
  File.join(Dir.home, '.zeta', 'locale', Config.locale, "#{file}.yml")
@@ -25,7 +25,8 @@ module Plugins
25
25
 
26
26
  # Methods
27
27
  def execute(m, target=nil)
28
- target = target.rstrip
28
+ target = target&.rstrip
29
+ target = nil if target&.empty?
29
30
  target = m.user.nick if !target.nil? && target.match(/(\bmy\b|\b#{@bot.nick}\S*\b|\b\S*self\b)/i)
30
31
  target.gsub(/(\bmy\b|\b#{@bot.nick}\S*\b|\b\S*self\b)/i,m.user.nick+"'s") if !target.nil?;
31
32
  populate_attacks!
@@ -57,7 +57,7 @@ module Plugins
57
57
  uptime: ChronicDuration.output(Time.now.to_i - @started_at.to_i)
58
58
  }
59
59
 
60
- tf = TagFormatter.new open(File.join(__dir__, '../botinfo.txt'),&:read), tags: tags
60
+ tf = TagFormatter.new File.read(File.join(__dir__, '../botinfo.txt')), tags: tags
61
61
 
62
62
  m.user.notice tf.parse
63
63
  end
@@ -40,7 +40,7 @@ module Plugins
40
40
  )
41
41
  )
42
42
  rescue RestClient::Unauthorized
43
- msg.action_reply "isn't currently authorized to do that"
43
+ return msg.action_reply "isn't currently authorized to do that"
44
44
  end
45
45
 
46
46
  # Turn JSON into an object
@@ -73,7 +73,7 @@ module Plugins
73
73
  )
74
74
  )
75
75
  rescue RestClient::Unauthorized
76
- msg.action_reply "isn't currently authorized to do that"
76
+ return msg.action_reply "isn't currently authorized to do that"
77
77
  end
78
78
 
79
79
  # Turn JSON into an object
@@ -114,7 +114,7 @@ module Plugins
114
114
  )
115
115
  )
116
116
  rescue RestClient::Unauthorized
117
- msg.action_reply "isn't currently authorized to do that"
117
+ return msg.action_reply "isn't currently authorized to do that"
118
118
  end
119
119
 
120
120
  # Turn JSON into an object
@@ -15,7 +15,7 @@ module Plugins
15
15
  def initialize(*args)
16
16
  super
17
17
  @imgurray = []
18
- @last_update = Time
18
+ @last_update = Time.at(0)
19
19
  end
20
20
 
21
21
  match 'randomgif', method: :imgif
@@ -53,11 +53,12 @@ module Plugins
53
53
 
54
54
  def imgur
55
55
  # Cache results for 1 hour
56
- if @imgurray.empty? || @last_update >= (Time.now + 3600)
56
+ if @imgurray.empty? || @last_update < (Time.now - 3600)
57
57
  parser = URI::Parser.new
58
58
 
59
59
  url = parser.escape('http://reddit.com/r/gifs.json')
60
60
  doc = JSON.load(RestClient.get(url).body)
61
+ @imgurray.clear
61
62
 
62
63
  doc['data']['children'].each_with_index do |post, index|
63
64
  if doc['data']['children'][index]['data']['url'].to_s =~ /imgur/
@@ -22,7 +22,7 @@ module Plugins
22
22
 
23
23
  match /reload/, method: :execute_reloadmacros, react_on: :private
24
24
  def execute_reloadmacros m
25
- return unless check_user(m, :admin)
25
+ return unless check?(m, :admin, true)
26
26
  # return unless check_channel(m)
27
27
  begin
28
28
  # @macros = YAML::load_file($root_path + '/locales/macros.yml')
@@ -36,7 +36,8 @@ module Plugins
36
36
  match /(\w+)(?: (.+))?/, method: :execute_macro, group: :macro
37
37
  def execute_macro m, macro, arguments
38
38
  return unless @macros.has_key?(macro)
39
- parse(arguments.to_s.rstrip, @macros[macro], m.channel, m.user)
39
+ input = arguments.to_s.strip
40
+ parse(input.empty? ? nil : input, @macros[macro], m.channel, m.user)
40
41
 
41
42
 
42
43
  # Guide to writing macros:
@@ -44,7 +44,7 @@ module Plugins
44
44
 
45
45
 
46
46
  # Get file and parse metadata
47
- open(url, "rb") do |io|
47
+ URI.open(url, "rb") do |io|
48
48
  reader = PDF::Reader.new(io)
49
49
  creator = reader.info[:Creator] || 'Anon'
50
50
  producer = reader.info[:Producer] || 'Anon'
@@ -18,7 +18,7 @@ module Plugins
18
18
  set plugin_name: "Rainbow", help: "Rainbowificates your text.\nUsage: `?rainbow [text]`.\nUsage: `?eyerape [text]`.", suffix: /$/
19
19
 
20
20
  def rainbowification(s)
21
- s.gsub(/\x03([0-9]{2}(,[0-9]{2})?)?/, "") # Because total function abuse.
21
+ s = s.gsub(/\x03([0-9]{2}(,[0-9]{2})?)?/, "") # Because total function abuse.
22
22
  colour = %w{04 07 08 09 10 06 13}
23
23
  i = Random.new.rand(0..colour.size-1);
24
24
  new_string = ""
@@ -31,7 +31,7 @@ module Plugins
31
31
 
32
32
  def eyerapeification(s)
33
33
  sd = s.dup
34
- sd.gsub(/\x03([0-9]{2}(,[0-9]{2})?)?/, "") # Because total function abuse.
34
+ sd = sd.gsub(/\x03([0-9]{2}(,[0-9]{2})?)?/, "") # Because total function abuse.
35
35
  colour = %w{04 07 08 09 10 06 13}
36
36
  offset = Random.new.rand(0..colour.size-1)
37
37
  sd = "\x02" + sd.upcase.split(" ").map { |c|
@@ -84,7 +84,7 @@ module Plugins
84
84
 
85
85
  def end_game(channel, premature=false)
86
86
  @games.delete channel.name
87
- channel.msg "Oh vell, it vas fun vhile it lasted." if premature
87
+ channel.send "Oh vell, it vas fun vhile it lasted." if premature
88
88
  sleep 1
89
89
  channel.action "holsters the pistol."
90
90
  end
@@ -24,7 +24,7 @@ module Plugins
24
24
 
25
25
  def listen(m)
26
26
  return if m.channel == '#services'
27
- @users[m.user.nick] = SeenStruct.new(m.user, m.channel, Time.now)
27
+ @users[m.user.nick] = SeenStruct.new(m.user.nick, m.channel.name, Time.now)
28
28
  end
29
29
 
30
30
  def execute(m, nick)
@@ -33,7 +33,7 @@ module Plugins
33
33
  m.reply 'You are a Stupid human!'
34
34
  elsif nick == m.user.nick
35
35
  m.reply "Unfortunately, I see an idiot by the name of #{m.user.nick}"
36
- elsif @users.key?(nick) && (@users[nick].where == m.channel)
36
+ elsif @users.key?(nick) && (@users[nick].where.to_s == m.channel.name)
37
37
  time_ago = time_ago_in_words(Time.at(@users[nick].time))
38
38
  m.reply "Seen ∴ \x0304#{@users[nick].who}\x0F was last seen talking in here about \x02#{time_ago}\x0F ago."
39
39
  else
@@ -53,7 +53,7 @@ module Plugins
53
53
  end
54
54
 
55
55
  def load_seen
56
- if File.exists?(File.join(Dir.home, '.zeta', 'cache', 'seen.rb'))
56
+ if File.exist?(File.join(Dir.home, '.zeta', 'cache', 'seen.rb'))
57
57
  begin
58
58
  File.open(File.join(Dir.home, '.zeta', 'cache', 'seen.rb')) do |file|
59
59
  return Marshal.load(file)
@@ -71,8 +71,8 @@ module Plugins
71
71
 
72
72
  def halloween(m, tz = nil)
73
73
  tz ||= "-00:00"
74
- tz = tzparser(tz)
75
74
  begin
75
+ tz = tzparser(tz)
76
76
  today = Time.now.localtime(tz)
77
77
  hw = Time.new(today.year, 10, 31, 0, 0, 0, tz)
78
78
  hw = hw.next_year if hw.to_date.past?
@@ -93,8 +93,8 @@ module Plugins
93
93
 
94
94
  def xmas(m, tz = nil)
95
95
  tz ||= "-00:00"
96
- tz = tzparser(tz)
97
96
  begin
97
+ tz = tzparser(tz)
98
98
  today = Time.now.localtime(tz)
99
99
  xmas = Time.new(today.year, 12, 25, 0, 0, 0, tz)
100
100
  xmas = xmas.next_year if xmas.to_date.past?
@@ -115,8 +115,8 @@ module Plugins
115
115
 
116
116
  def newyear(m, tz = nil)
117
117
  tz ||= "-00:00"
118
- tz = tzparser(tz)
119
118
  begin
119
+ tz = tzparser(tz)
120
120
  today = Time.now.localtime(tz)
121
121
  nyear = Time.new(today.year.succ, 1, 1, 0, 0, 0, tz)
122
122
  #nyear = nyear.next_year if nyear.to_date.past?
@@ -137,8 +137,8 @@ module Plugins
137
137
 
138
138
  def tz(m, tz = nil)
139
139
  tz ||= "-00:00"
140
- tz = tzparser(tz)
141
140
  begin
141
+ tz = tzparser(tz)
142
142
  today = Time.now.localtime(tz)
143
143
  message = today.to_s
144
144
  rescue ArgumentError => ae
@@ -46,7 +46,7 @@ module Plugins
46
46
  meta tags, and paste the result back into the channel.
47
47
  HELP
48
48
 
49
- match %r{\b((https?:\/\/)?(([0-9a-zA-Z_!~*'().&=+$%-]+:)?[0-9a-zA-Z_!~*'().&=+$%-]+\@)?(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+\.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z]\.[a-zA-Z]{2,6})(:[0-9]{1,4})?((\/[0-9a-zA-Z_!~*'().;?:\@&=+$,%#-]+)*\/?))}i,
49
+ match %r{\b((https?:\/\/)?(([0-9a-zA-Z_!~*'().&=+$%-]+:)?[0-9a-zA-Z_!~*'().&=+$%-]+\@)?(([0-9]{1,3}\.){3}[0-9]{1,3}|([0-9a-zA-Z_!~*'()-]+\.)*([0-9a-zA-Z][0-9a-zA-Z-]{0,61})?[0-9a-zA-Z]\.[a-zA-Z]{2,63})(:[0-9]{1,5})?((\/[0-9a-zA-Z_!~*'().;?:\@&=+$,%#-]+)*\/?))}i,
50
50
  use_prefix: false,
51
51
  react_on: :channel
52
52
 
@@ -151,7 +151,7 @@ module Plugins
151
151
  error "[408] #{msg.user} - #{url}"
152
152
  msg.reply 'URL was forced Timed out'
153
153
  rescue => e
154
- error e
154
+ error "#{e.class.name}: #{e.message}"
155
155
  error "[404] #{msg.user} - #{url}"
156
156
  msg.safe_reply 'I am unable to load that URL'
157
157
  end
@@ -1,4 +1,5 @@
1
1
  require 'ostruct'
2
+ require 'cgi/escape'
2
3
  require 'persist'
3
4
  require 'open-uri'
4
5
  require 'json'
@@ -24,8 +25,6 @@ module Plugins
24
25
  match /setw (.+)/, method: :set_location
25
26
  match /wx (.+)/, method: :weather
26
27
  match /weather (.+)/, method: :weather
27
- match /almanac (.+)/, method: :almanac
28
- match /hurricane/, method: :hurricane
29
28
 
30
29
  #####
31
30
  def initialize(*args)
@@ -41,7 +40,9 @@ module Plugins
41
40
  if !@store[msg.user.to_s].nil? && query.nil?
42
41
  stored_location, stored_source = @store[msg.user.to_s].split('::')
43
42
  stored_source = @api_src.include?(stored_source) ? stored_source : 'owm'
44
- data = send("#{stored_source}_src", stored_location)
43
+ true_src = stored_source
44
+ query = stored_location
45
+ data = send("#{true_src}_src", query)
45
46
  # location = geolookup(@store[msg.user.to_s])
46
47
  # data = wunderground_src(stored_location, false)
47
48
  elsif query.nil?
@@ -74,9 +75,9 @@ module Plugins
74
75
  return msg.reply "No results found for #{query}." if data.nil?
75
76
 
76
77
  # Store and display general location
77
- serial_location = "#{query}::#{src}"
78
+ serial_location = "#{query}::#{true_src}"
78
79
  @store[msg.user.to_s] = serial_location unless data.nil?
79
- msg.reply "Your location is now set to #{data.ac.name}, #{data.ac.c}!"
80
+ msg.reply "Your location is now set to #{data.ac.formatted_address}!"
80
81
  end
81
82
 
82
83
  # -private
@@ -92,7 +93,7 @@ module Plugins
92
93
  ).body, object_class: OpenStruct
93
94
  )
94
95
 
95
- return nil if ac.results.nil? ## Unable to locate
96
+ return nil if ac.results.blank? ## Unable to locate
96
97
 
97
98
  ac = ac.results[0]
98
99
  lat = ac.geometry.location.lat
@@ -108,6 +109,7 @@ module Plugins
108
109
  pressure = Unitwise(data.main.pressure.to_f, 'mbar')
109
110
  wind = Unitwise(data.wind.speed, 'kilometer')
110
111
 
112
+ data.ac = ac
111
113
  data.reply = "OWM ∴ #{ac.formatted_address} " \
112
114
  "≈ #{(Time.now.utc + data.timezone.seconds).strftime("%c")} " \
113
115
  "≈ #{data.weather[0].description}, #{temp.convert_to('[degF]').to_i.round(2)} F (#{temp.convert_to('Cel').to_i.round(2)} C) " \
@@ -127,7 +129,7 @@ module Plugins
127
129
  RestClient.get("https://maps.googleapis.com/maps/api/geocode/json?address=#{location}&key=#{Config.secrets[:google]}").body,
128
130
  object_class: OpenStruct
129
131
  )
130
- return nil if ac.results.nil? ## Unable to locate
132
+ return nil if ac.results.blank? ## Unable to locate
131
133
 
132
134
  ac = ac.results[0]
133
135
  lat = ac.geometry.location.lat
@@ -140,13 +142,13 @@ module Plugins
140
142
  return nil if stations.nil? ## Unable to find station. probably not in the USA
141
143
 
142
144
  parsed = JSON.parse(
143
- RestClient.get("#{CGI.escape(stations['observationStations'][0])}/observations/current").body,
145
+ RestClient.get("#{stations['observationStations'][0]}/observations/current").body,
144
146
  object_class: OpenStruct
145
147
  )
146
148
 
147
149
  data = parsed.properties
148
150
  data.ac = ac
149
- f = data.temperature.value * 9 / 5
151
+ f = data.temperature.value * 9 / 5.0 + 32
150
152
  temp = "#{f.round(2)} F (#{data.temperature.value.to_i.round(2)} C) "
151
153
  wind = "Gusts: #{data.windGust.value} avg: #{data.windSpeed.value.to_i.round(2)}"
152
154
  feelslike = "#{data.windChill.value.to_i.round(2)} C"