cogbot 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,102 @@
1
+ # thx dominikh for this code :) (then slightly modified)
2
+ module Cinch
3
+ module Plugins
4
+ class Manager
5
+ include Cinch::Plugin
6
+
7
+ match(/m list/, method: :list_plugins)
8
+ match(/m load (\S+)/, method: :load_plugin)
9
+ match(/m unload (\S+)/, method: :unload_plugin)
10
+ match(/m reload (\S+)/, method: :reload_plugin)
11
+ match(/m set (\S+) (\S+) (.+)$/, method: :set_option)
12
+
13
+ def list_plugins(m)
14
+ back = ''
15
+ @bot.plugins.each { |p| back += "#{p.class.name.split('::').last.downcase} " }
16
+ m.reply back
17
+ end
18
+
19
+ def load_plugin(m, mapping)
20
+ plugin = mapping.downcase.camelize
21
+ p plugin
22
+ p mapping
23
+
24
+ file_name = "#{ROOT_DIR}/plugins/#{mapping.downcase}.rb"
25
+ unless File.exist?(file_name)
26
+ m.reply "Could not load #{plugin} because #{file_name} does not exist."
27
+ return
28
+ end
29
+
30
+ begin
31
+ load(file_name)
32
+ rescue Exception
33
+ m.reply "Could not load #{plugin}."
34
+ raise
35
+ end
36
+
37
+ begin
38
+ const = Cinch::Plugins.const_get(plugin)
39
+ rescue NameError
40
+ m.reply "Could not load #{plugin} because no matching class was found."
41
+ return
42
+ end
43
+
44
+ @bot.plugins.register_plugin(const)
45
+ m.reply "Successfully loaded #{plugin}"
46
+ end
47
+
48
+ def unload_plugin(m, plugin)
49
+ begin
50
+ plugin_class = Cinch::Plugins.const_get(plugin.downcase.camelize)
51
+ rescue NameError
52
+ m.reply "Could not unload #{plugin} because no matching class was found."
53
+ return
54
+ end
55
+
56
+ @bot.plugins.select {|p| p.class == plugin_class}.each do |p|
57
+ @bot.plugins.unregister_plugin(p)
58
+ end
59
+
60
+ ## FIXME not doing this at the moment because it'll break
61
+ ## plugin options. This means, however, that reloading a
62
+ ## plugin is relatively dirty: old methods will not be removed
63
+ ## but only overwritten by new ones. You will also not be able
64
+ ## to change a classes superclass this way.
65
+ # Cinch::Plugins.__send__(:remove_const, plugin)
66
+
67
+ # Because we're not completely removing the plugin class,
68
+ # reset everything to the starting values.
69
+ plugin_class.hooks.clear
70
+ plugin_class.matchers.clear
71
+ plugin_class.listeners.clear
72
+ plugin_class.timers.clear
73
+ plugin_class.ctcps.clear
74
+ plugin_class.react_on = :message
75
+ plugin_class.plugin_name = nil
76
+ plugin_class.help = nil
77
+ plugin_class.prefix = nil
78
+ plugin_class.suffix = nil
79
+ plugin_class.required_options.clear
80
+
81
+ m.reply "Successfully unloaded #{plugin}"
82
+ end
83
+
84
+ def reload_plugin(m, plugin)
85
+ unload_plugin(m, plugin)
86
+ load_plugin(m, plugin)
87
+ end
88
+
89
+ def set_option(m, plugin, option, value)
90
+ begin
91
+ const = Cinch::Plugins.const_get(plugin.downcase.camelize)
92
+ rescue NameError
93
+ m.reply "Could not set plugin option for #{plugin} because no matching class was found."
94
+ return
95
+ end
96
+ @bot.config.plugins.options[const][option.to_sym] = eval(value)
97
+
98
+ m.reply "Successfuly set option."
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,61 @@
1
+ require 'open-uri'
2
+ require 'yajl'
3
+ require 'cgi'
4
+
5
+ module Cinch
6
+ module Plugins
7
+ class Redmine
8
+ include Cinch::Plugin
9
+
10
+ timer 60, method: :check_redmine
11
+
12
+ set :plugin_name, 'redmine'
13
+ set :help, <<EOT
14
+ Redmine plugins checks the new issues in the specified redmine instance
15
+ EOT
16
+
17
+ def check_redmine
18
+ @issues ||= Array.new
19
+ api_key = @bot.config.options['cogconf']['redmine']['api_key']
20
+ redmine_url = "%s/issues.json?project_id=%s&limit=20" % [
21
+ @bot.config.options['cogconf']['redmine']['url'],
22
+ @bot.config.options['cogconf']['redmine']['project']
23
+ ]
24
+ res = Yajl::Parser.parse(open(redmine_url, "X-Redmine-API-Key" => api_key))
25
+ subjs = Hash[ res['issues'].map { |i| [ i['id'], i['subject'] ] } ]
26
+ issues = subjs.keys
27
+ newones = Array.new
28
+ if @issues.count == 0
29
+ @issues = issues
30
+ else
31
+ issues.each { |i| newones << i unless @issues.include? i }
32
+ if newones.count > 0
33
+ newones.each do |i|
34
+ @issues.push i
35
+ @bot.config.options['cogconf']['main']['channels'].each do |channel|
36
+ Channel(channel).msg "[%s] >>> %s - %s/issues/%s" % [
37
+ @bot.config.options['cogconf']['redmine']['project'],
38
+ subjs[i],
39
+ @bot.config.options['cogconf']['redmine']['url'],
40
+ i
41
+ ]
42
+ end
43
+ end
44
+ @issues = @issues[0..50]
45
+ end
46
+ end
47
+ # puts "redmine: done #{newones.count} new issues, #{@issues.count} cached"
48
+ rescue Exception => e
49
+ puts "*** #{e.class}\n"
50
+ puts e.to_s
51
+ puts e.backtrace
52
+ end
53
+
54
+ def new(bot)
55
+ @bot = bot
56
+ @issues = Array.new
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,51 @@
1
+ require 'open-uri'
2
+ require 'yajl'
3
+ require 'cgi'
4
+
5
+ module Cinch
6
+ module Plugins
7
+ class Rubygems
8
+ include Cinch::Plugin
9
+
10
+ match /r (.*)$/
11
+
12
+ set :plugin_name, 'rubygems'
13
+ set :help, <<EOT
14
+ Rubygems queries http://rubygems.org for finding gems
15
+ EOT
16
+
17
+ def query(query)
18
+ url = "https://rubygems.org/api/v1/search.json?query=#{CGI.escape(query)}"
19
+ back = "Requesting ... \n"
20
+ begin
21
+ file = open(url)
22
+ if file.class == StringIO
23
+ json = Yajl::Parser.parse(file)
24
+ if json.empty?
25
+ return "Nothing matches '#{query}'"
26
+ end
27
+ else
28
+ json = Yajl::Parser.parse(File.read(file))
29
+ end
30
+ 4.times do |it|
31
+ back += "#{json[it]['name']} : #{json[it]['homepage_uri']}\n"
32
+ end
33
+ rescue Exception => e
34
+ p file.class
35
+ back = "*** #{e.class}\n"
36
+ back += e.to_s
37
+ end
38
+ return back
39
+ end
40
+
41
+ def new(bot)
42
+ @bot = bot
43
+ end
44
+
45
+ def execute(m,words)
46
+ m.reply(query(words.strip))
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ require 'open-uri'
2
+
3
+ module Cinch
4
+ module Plugins
5
+ class Shorturl
6
+ include Cinch::Plugin
7
+
8
+ match /(http:\/\/[^ ]*)/, :use_prefix => false
9
+
10
+ set :plugin_name, 'shorturl'
11
+ set :help, <<EOT
12
+ Shorturl catches urls said on channel and shorten then
13
+ EOT
14
+
15
+ def shorten(url)
16
+ url = open("http://tinyurl.com/api-create.php?url=#{URI.escape(url)}").read
17
+ url == "Error" ? nil : url
18
+ rescue OpenURI::HTTPError
19
+ nil
20
+ end
21
+
22
+ def new(bot)
23
+ @bot = bot
24
+ end
25
+
26
+ def execute(m,url)
27
+ m.reply("Shortening: " + shorten(url))
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ require 'open-uri'
2
+ require 'json'
3
+
4
+ class Stackoverflow
5
+ include Cinch::Plugin
6
+
7
+ match /s (.+)/
8
+
9
+ set :plugin_name, 'stackoverflow'
10
+ set :help, <<EOT
11
+ Stackoverflow returns the first match on a search
12
+ .s <keywords> : searches on those keywords
13
+ EOT
14
+
15
+ def new(bot)
16
+ @bot = bot
17
+ end
18
+
19
+ def search(query)
20
+ url = "http://api.stackoverflow.com/docs/search#site=stackoverflow&sort=activity&intitle=#{CGI.escape(query)}"
21
+ p url
22
+ res = JSON.parse(open(url))
23
+ p res
24
+ res.items.each do |i|
25
+ title = i.title
26
+ link = i.link
27
+ desc = i.tags.join(', ')
28
+ end
29
+ "#{title} - #{desc} (#{link})"
30
+ rescue
31
+ "No results found"
32
+ end
33
+
34
+ def execute(m, query)
35
+ m.reply(search(query))
36
+ end
37
+ end
data/plugins/tests.rb ADDED
@@ -0,0 +1,18 @@
1
+ class Tests
2
+ include Cinch::Plugin
3
+
4
+ set :plugin_name, 'tests'
5
+ set :help, 'just a plugin for dev tests'
6
+
7
+ match /hey you/
8
+
9
+ def new(bot)
10
+ @bot = bot
11
+ end
12
+
13
+
14
+ def execute(m)
15
+ m.reply "Who ? me ?"
16
+ end
17
+
18
+ end
data/plugins/tweet.rb ADDED
@@ -0,0 +1,54 @@
1
+ require 'twitter'
2
+
3
+ module Cinch
4
+ module Plugins
5
+ class Tweet
6
+ include Cinch::Plugin
7
+
8
+ match /t ?([^ ]*)?( ?.*)/
9
+
10
+ set :plugin_name, 'tweet'
11
+ set :help, <<EOT
12
+ Tweet makes the bot can query twittter API
13
+ .t search <term> : searches the public timelines
14
+ EOT
15
+
16
+ =begin
17
+ Twitter.configure do |c|
18
+ c.consumer_key = @bot.config.options.cogconf['tweet']['consumer_key']
19
+ c.consumer_secret = @bot.config.options.cogconf['tweet']['consumer_secret']
20
+ c.oauth_token = @bot.config.options.cogconf['tweet']['oauth_token']
21
+ c.oauth_token_secret = @bot.config.options.cogconf['tweet']['oauth_token_secret']
22
+ end
23
+ =end
24
+
25
+ def new(bot)
26
+ @bot = bot
27
+ end
28
+
29
+ def exec(command,args)
30
+ back = ''
31
+ #back += "command: #{command} / args: #{args}\n"
32
+ begin
33
+ case command
34
+ when 'search'
35
+ Twitter.search(args, { :lang => 'en', :rpp => '3' }).each do|status|
36
+ back += status.full_text + "\n"
37
+ end
38
+ else
39
+ back += Twitter.send(command,args.split(','))
40
+ end
41
+ rescue Exception => e
42
+ back += "Bad request\n"
43
+ back += e.inspect
44
+ end
45
+ return back
46
+ end
47
+
48
+ def execute(m,command,args)
49
+ m.reply(exec(command,args.strip))
50
+ end
51
+
52
+ end
53
+ end
54
+ end
data/plugins/urban.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'open-uri'
2
+ require 'nokogiri'
3
+ require 'cgi'
4
+
5
+ module Cinch
6
+ module Plugins
7
+ class Urban
8
+ include Cinch::Plugin
9
+
10
+ match /u (.*)$/
11
+
12
+ set :plugin_name, 'urban'
13
+ set :help, <<EOT
14
+ Urban connects to urban dictionary and returns the first result for a given query, replying with the result directly to the sender
15
+ EOT
16
+
17
+ def query(query)
18
+ url = "http://www.urbandictionary.com/define.php?term=#{CGI.escape(query)}"
19
+ begin
20
+ CGI.unescape_html Nokogiri::HTML(open(url)).at("div.definition").text.gsub(/\s+/, ' ')
21
+ rescue
22
+ "no result found"
23
+ end
24
+ end
25
+
26
+ def new(bot)
27
+ @bot = bot
28
+ end
29
+
30
+ def execute(m,words)
31
+ m.reply(query(words.strip))
32
+ end
33
+
34
+ end
35
+ end
36
+ end
data/plugins/users.rb ADDED
@@ -0,0 +1,39 @@
1
+
2
+ module Cinch
3
+ module Plugins
4
+ class Users
5
+
6
+ class UserStruct < Struct.new(:user, :channel, :text, :time)
7
+ end
8
+
9
+ include Cinch::Plugin
10
+
11
+ def initialize(*args)
12
+ super
13
+ storage[:users] ||= {}
14
+ end
15
+
16
+ match /u (.+ )?([^\s]+)( .+)/
17
+
18
+ def exec(query,nick)
19
+ back ''
20
+ query.strip! rescue ''
21
+ nick.strip! rescue ''
22
+ if query.blank?
23
+ else
24
+ case query
25
+ when 'add'
26
+ else
27
+ back = "Unknown command #{query}."
28
+ end
29
+ end
30
+ return back
31
+ end
32
+
33
+ def execute(m, query, nick, msg)
34
+ m.reply(exec(query, nick, msg))
35
+ end
36
+
37
+ end
38
+ end
39
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'minitest/ci'
2
+ require 'simplecov'
3
+ require 'simplecov-rcov'
4
+
5
+ SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
6
+ SimpleCov.start
7
+
8
+ if $0 == __FILE__
9
+ TestHelpers::load_env
10
+ puts ENV.inspect
11
+ end
12
+
13
+ MiniTest::Ci.auto_clean = false