ircbot 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -59
- data/ircbot.gemspec +28 -0
- data/lib/ircbot.rb +1 -0
- data/lib/ircbot/dm.rb +41 -0
- data/lib/ircbot/plugin.rb +27 -8
- data/lib/ircbot/version.rb +1 -1
- data/plugins/plugins.rb +9 -12
- data/plugins/reminder.rb +27 -24
- data/plugins/youtube.rb +53 -0
- data/spec/its_helper.rb +7 -9
- data/spec/plugin_spec.rb +20 -6
- data/spec/provide_helper.rb +21 -23
- data/spec/spec_helper.rb +2 -2
- metadata +99 -42
- data/config/airi.yml +0 -8
- data/config/wota.yml +0 -9
- data/plugins/tv.rb +0 -262
data/Rakefile
CHANGED
@@ -1,59 +1 @@
|
|
1
|
-
require
|
2
|
-
require 'rake/gempackagetask'
|
3
|
-
|
4
|
-
#require 'merb-core'
|
5
|
-
#require 'merb-core/tasks/merb'
|
6
|
-
|
7
|
-
GEM_NAME = "ircbot"
|
8
|
-
AUTHOR = "maiha"
|
9
|
-
EMAIL = "maiha@wota.jp"
|
10
|
-
SUMMARY = "easy irc bot framework"
|
11
|
-
|
12
|
-
require File.dirname(__FILE__) + '/lib/ircbot/version'
|
13
|
-
GEM_VERSION = Ircbot::VERSION
|
14
|
-
HOMEPAGE = Ircbot::HOMEPAGE
|
15
|
-
|
16
|
-
spec = Gem::Specification.new do |s|
|
17
|
-
s.rubyforge_project = 'asakusarb'
|
18
|
-
s.executables = ["ircbot"]
|
19
|
-
s.name = GEM_NAME
|
20
|
-
s.version = GEM_VERSION
|
21
|
-
s.platform = Gem::Platform::RUBY
|
22
|
-
s.has_rdoc = true
|
23
|
-
s.extra_rdoc_files = ["README", "MIT-LICENSE"]
|
24
|
-
s.summary = SUMMARY
|
25
|
-
s.description = "An irc bot framework that offers easy-to-use by plugins"
|
26
|
-
s.author = AUTHOR
|
27
|
-
s.email = EMAIL
|
28
|
-
s.homepage = HOMEPAGE
|
29
|
-
s.require_path = 'lib'
|
30
|
-
s.add_dependency('extlib', '>= 0.9.14')
|
31
|
-
s.add_dependency('net-irc', '>= 0.0.9')
|
32
|
-
s.files = %w(MIT-LICENSE README Rakefile) + Dir.glob("{lib,spec,plugins,config}/**/*")
|
33
|
-
end
|
34
|
-
|
35
|
-
Rake::GemPackageTask.new(spec) do |pkg|
|
36
|
-
pkg.gem_spec = spec
|
37
|
-
end
|
38
|
-
|
39
|
-
desc "Install the gem"
|
40
|
-
task :install do
|
41
|
-
Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
|
42
|
-
end
|
43
|
-
|
44
|
-
desc "Uninstall the gem"
|
45
|
-
task :uninstall do
|
46
|
-
Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
|
47
|
-
end
|
48
|
-
|
49
|
-
desc "Create a gemspec file"
|
50
|
-
task :gemspec do
|
51
|
-
File.open("#{GEM_NAME}.gemspec", "w") do |file|
|
52
|
-
file.puts spec.to_ruby
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
require 'spec/rake/spectask'
|
57
|
-
#require 'merb-core/test/tasks/spectasks'
|
58
|
-
desc 'Default: run spec examples'
|
59
|
-
task :default => 'spec'
|
1
|
+
require "bundler/gem_tasks"
|
data/ircbot.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
$:.push File.expand_path("../lib", __FILE__)
|
4
|
+
require "ircbot/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "ircbot"
|
8
|
+
s.version = Ircbot::VERSION
|
9
|
+
s.authors = ["maiha"]
|
10
|
+
s.email = ["maiha@wota.jp"]
|
11
|
+
s.homepage = Ircbot::HOMEPAGE
|
12
|
+
s.summary = %q{easy irc bot framework}
|
13
|
+
s.description = %q{An irc bot framework that offers easy-to-use by plugins}
|
14
|
+
|
15
|
+
s.rubyforge_project = "ircbot"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency "dsl_accessor", ">= 0.4.0"
|
23
|
+
s.add_dependency "extlib", ">= 0.9.14"
|
24
|
+
s.add_dependency "net-irc", ">= 0.0.9"
|
25
|
+
|
26
|
+
s.add_development_dependency "rspec", ">= 2.9.0"
|
27
|
+
end
|
28
|
+
|
data/lib/ircbot.rb
CHANGED
data/lib/ircbot/dm.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-migrations'
|
3
|
+
require 'dm-timestamps'
|
4
|
+
|
5
|
+
module Ircbot
|
6
|
+
module DM
|
7
|
+
dsl_accessor :connection
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
extend Connection
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def connect(path = nil)
|
17
|
+
@connection ||= self.class.establish_connection(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
module Connection
|
21
|
+
def establish_connection(path = nil, &block)
|
22
|
+
path = path.to_s
|
23
|
+
path = 'unknown' if path.empty?
|
24
|
+
if DM.connection != path
|
25
|
+
DM.connection = path
|
26
|
+
path = (path[0] == ?/) ? Pathname(path) : Pathname(Dir.getwd) + "db" + "#{path}.db"
|
27
|
+
path = path.expand_path
|
28
|
+
path.parent.mkpath
|
29
|
+
DataMapper.setup(:default, "sqlite3://#{path}")
|
30
|
+
end
|
31
|
+
|
32
|
+
@models.each(&:auto_upgrade!) if @models
|
33
|
+
return DataMapper.repository(:default)
|
34
|
+
end
|
35
|
+
|
36
|
+
def connect(*models)
|
37
|
+
@models = models
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/ircbot/plugin.rb
CHANGED
@@ -46,23 +46,42 @@ module Ircbot
|
|
46
46
|
######################################################################
|
47
47
|
### Operations
|
48
48
|
|
49
|
+
def done(text = nil)
|
50
|
+
throw :done, text
|
51
|
+
end
|
52
|
+
|
49
53
|
def help
|
50
54
|
raise "no helps for #{plugin_name}"
|
51
55
|
end
|
52
56
|
|
57
|
+
######################################################################
|
58
|
+
### Messages
|
59
|
+
|
60
|
+
def direct?
|
61
|
+
message.channel == config.nick
|
62
|
+
end
|
63
|
+
|
64
|
+
def me?
|
65
|
+
!! (message.message =~ /\A#{config.nick}\./)
|
66
|
+
end
|
67
|
+
|
68
|
+
def nick
|
69
|
+
message.prefix.nick
|
70
|
+
end
|
71
|
+
|
72
|
+
def command
|
73
|
+
(message.message =~ /\A#{config.nick}\./) ? $'.to_s.strip.split.first.to_s : ''
|
74
|
+
end
|
75
|
+
|
76
|
+
def arg
|
77
|
+
(message.message =~ /\A#{config.nick}\./) ? (a = $'.to_s.strip.split; a.shift; a.join) : ''
|
78
|
+
end
|
79
|
+
|
53
80
|
private
|
54
81
|
def plugin(name)
|
55
82
|
plugin!(name)
|
56
83
|
rescue
|
57
84
|
Null.new
|
58
85
|
end
|
59
|
-
|
60
|
-
def direct?
|
61
|
-
message.channel == config.nick
|
62
|
-
end
|
63
|
-
|
64
|
-
def nick
|
65
|
-
message.prefix.nick
|
66
|
-
end
|
67
86
|
end
|
68
87
|
end
|
data/lib/ircbot/version.rb
CHANGED
data/plugins/plugins.rb
CHANGED
@@ -14,35 +14,32 @@ commands: load, start, stop, delete
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def reply(text)
|
17
|
-
|
18
|
-
command
|
19
|
-
arg = arg.to_s.strip
|
20
|
-
|
21
|
-
case command.to_s
|
17
|
+
if me?
|
18
|
+
case command
|
22
19
|
when "load", "register"
|
23
20
|
plugins.load arg
|
24
|
-
|
21
|
+
done "Loaded #{arg}"
|
25
22
|
|
26
23
|
when "delete", "remove"
|
27
24
|
plugins.delete arg
|
28
|
-
|
25
|
+
done "Removed #{arg}"
|
29
26
|
|
30
27
|
when "start"
|
31
28
|
plugins.start arg
|
32
|
-
|
29
|
+
done "Started #{arg}"
|
33
30
|
|
34
31
|
when "stop"
|
35
32
|
plugins.stop arg
|
36
|
-
|
33
|
+
done "Stopped #{arg}"
|
37
34
|
|
38
35
|
when "help"
|
39
36
|
if arg.empty?
|
40
|
-
|
37
|
+
done [bot_help, plugins_help].join("\n")
|
41
38
|
else
|
42
|
-
|
39
|
+
done plugins[arg].help
|
43
40
|
end
|
44
41
|
end
|
45
|
-
|
42
|
+
end
|
46
43
|
return nil
|
47
44
|
end
|
48
45
|
|
data/plugins/reminder.rb
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
######################################################################
|
5
5
|
# [Install]
|
6
6
|
#
|
7
|
-
# gem install chawan night-time dm-core dm-migrations dm-timestamps do_sqlite3 data_objects
|
7
|
+
# gem install chawan night-time dm-core dm-migrations dm-timestamps do_sqlite3 data_objects dm-sqlite-adapter -V
|
8
8
|
#
|
9
9
|
|
10
10
|
require 'rubygems'
|
@@ -21,7 +21,8 @@ module Reminder
|
|
21
21
|
@connecteds ||= {}
|
22
22
|
@connecteds[path] ||=
|
23
23
|
(
|
24
|
-
path
|
24
|
+
path ||= Pathname(Dir.getwd) + "db" + "reminder.db"
|
25
|
+
path = Pathname(path).expand_path
|
25
26
|
path.parent.mkpath
|
26
27
|
DataMapper.setup(:default, "sqlite3://#{path}")
|
27
28
|
Reminder::Event.auto_upgrade!
|
@@ -151,11 +152,14 @@ class ReminderPlugin < Ircbot::Plugin
|
|
151
152
|
def reply(text)
|
152
153
|
start_reminder
|
153
154
|
|
155
|
+
# strip noise
|
156
|
+
text = text.sub(/^<.*?>/,'').strip
|
157
|
+
|
154
158
|
case text
|
155
159
|
when %r{^\d{4}.?\d{1,2}.?\d{1,2}}
|
156
160
|
event = Reminder.register(text)
|
157
161
|
text = "Remind you again at %s" % event.alert_at.strftime("%Y-%m-%d %H:%M")
|
158
|
-
|
162
|
+
return text
|
159
163
|
end
|
160
164
|
return nil
|
161
165
|
|
@@ -191,7 +195,8 @@ end
|
|
191
195
|
|
192
196
|
|
193
197
|
######################################################################
|
194
|
-
###
|
198
|
+
### Spec in file:
|
199
|
+
### ruby plugins/reminder.rb
|
195
200
|
|
196
201
|
if $0 == __FILE__
|
197
202
|
|
@@ -206,34 +211,32 @@ if $0 == __FILE__
|
|
206
211
|
end
|
207
212
|
|
208
213
|
spec($0, DATA.read{}) do |tmp|
|
209
|
-
system("
|
214
|
+
system("rspec -cfs #{tmp.path}")
|
210
215
|
end
|
211
216
|
end
|
212
217
|
|
213
218
|
__END__
|
214
219
|
|
215
|
-
require '
|
220
|
+
require 'rspec'
|
216
221
|
require 'ostruct'
|
217
222
|
|
218
|
-
module
|
219
|
-
module
|
220
|
-
module
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
:allday => event.allday,
|
232
|
-
}
|
233
|
-
OpenStruct.new(hash)
|
223
|
+
module RSpec
|
224
|
+
module Core
|
225
|
+
module SharedExampleGroup
|
226
|
+
def parse(text, &block)
|
227
|
+
describe "(#{text})" do
|
228
|
+
subject {
|
229
|
+
event = Reminder.parse(text)
|
230
|
+
hash = {
|
231
|
+
:st => (event.st.strftime("%Y-%m-%d %H:%M:%S") rescue nil),
|
232
|
+
:en => (event.en.strftime("%Y-%m-%d %H:%M:%S") rescue nil),
|
233
|
+
:title => event.title.to_s,
|
234
|
+
:desc => event.title.to_s,
|
235
|
+
:allday => event.allday,
|
234
236
|
}
|
235
|
-
|
236
|
-
|
237
|
+
OpenStruct.new(hash)
|
238
|
+
}
|
239
|
+
instance_eval(&block)
|
237
240
|
end
|
238
241
|
end
|
239
242
|
end
|
data/plugins/youtube.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ircbot'
|
5
|
+
require 'uri'
|
6
|
+
require 'net/http'
|
7
|
+
require 'rack'
|
8
|
+
|
9
|
+
class YoutubePlugin < Ircbot::Plugin
|
10
|
+
def help
|
11
|
+
"[YouTube] automatically download youtube videos"
|
12
|
+
end
|
13
|
+
|
14
|
+
def reply(text)
|
15
|
+
url = URI.extract(text.to_s).grep(%r{^http://www\.youtube}).first
|
16
|
+
request_download(url)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def request_download(url)
|
21
|
+
return nil unless url
|
22
|
+
|
23
|
+
escaped = Rack::Utils.escape(url)
|
24
|
+
http = Net::HTTP.new('localhost', 9111)
|
25
|
+
# http = Net::HTTP.new('localhost', 3058)
|
26
|
+
tags = nick.to_s.gsub(/[0-9_]/,'')
|
27
|
+
response = http.post('/request', "url=#{escaped}&tags=#{tags}")
|
28
|
+
summary = response.body.to_s.split(/\n/).first
|
29
|
+
case response.code
|
30
|
+
when '200'
|
31
|
+
return once("DL登録完了: #{summary}")
|
32
|
+
when '304'
|
33
|
+
return once("DL済: #{summary}")
|
34
|
+
else
|
35
|
+
reason = "%s: %s" % [response.code, summary]
|
36
|
+
return "DL登録失敗: #{reason}"
|
37
|
+
end
|
38
|
+
rescue Errno::ECONNREFUSED
|
39
|
+
return once("ダウンロードサーバが起動してません")
|
40
|
+
end
|
41
|
+
|
42
|
+
def once(text)
|
43
|
+
text = text.to_s.strip
|
44
|
+
@report_once ||= {}
|
45
|
+
if @report_once[text]
|
46
|
+
return nil
|
47
|
+
else
|
48
|
+
@report_once[text] = Time.now
|
49
|
+
return text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
data/spec/its_helper.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
|
-
module
|
2
|
-
module
|
3
|
-
module
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
it(&block)
|
9
|
-
end
|
1
|
+
module RSpec
|
2
|
+
module Core
|
3
|
+
module SharedExampleGroup
|
4
|
+
def its(*args, &block)
|
5
|
+
describe(args.first) do
|
6
|
+
define_method(:subject) { super().send(*args) }
|
7
|
+
it(&block)
|
10
8
|
end
|
11
9
|
end
|
12
10
|
end
|
data/spec/plugin_spec.rb
CHANGED
@@ -44,9 +44,17 @@ describe Ircbot::Plugin do
|
|
44
44
|
context "(not connected)" do
|
45
45
|
subject{ Ircbot::Plugin.new }
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
it "#plugin(:foo) should detect Null plugin" do
|
48
|
+
subject.send(:plugin, :foo).should be_kind_of(Ircbot::Plugin::Null)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "#plugin!(:foo) should raise PluginNotFound" do
|
52
|
+
lambda {
|
53
|
+
subject.send(:plugin!, :foo)
|
54
|
+
}.should raise_error(Ircbot::PluginNotFound)
|
55
|
+
end
|
56
|
+
|
57
|
+
# its(:direct? ) { should == false }
|
50
58
|
end
|
51
59
|
|
52
60
|
######################################################################
|
@@ -62,9 +70,15 @@ describe Ircbot::Plugin do
|
|
62
70
|
end
|
63
71
|
subject{ Ircbot::Plugin.new(@plugins) }
|
64
72
|
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
it "#plugin(:foo) should find the defined foo plugin" do
|
74
|
+
subject.send(:plugin, :foo).should == @foo
|
75
|
+
end
|
76
|
+
|
77
|
+
it "#plugin!(:foo) should find the defined foo plugin" do
|
78
|
+
subject.send(:plugin!, :foo).should == @foo
|
79
|
+
end
|
80
|
+
|
81
|
+
# its(:direct? ) { should == false }
|
68
82
|
end
|
69
83
|
|
70
84
|
end
|
data/spec/provide_helper.rb
CHANGED
@@ -1,33 +1,31 @@
|
|
1
1
|
######################################################################
|
2
2
|
### provide matcher
|
3
|
-
|
3
|
+
RSpec::Matchers.define :provide do |expected|
|
4
4
|
match do |obj|
|
5
5
|
(obj.public_methods + obj.protected_methods + obj.private_methods).include?(expected.to_s)
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
module
|
10
|
-
module
|
11
|
-
module
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
subject.should provide(name)
|
30
|
-
end
|
9
|
+
module RSpec
|
10
|
+
module Core
|
11
|
+
module SharedExampleGroup
|
12
|
+
# == Examples
|
13
|
+
#
|
14
|
+
# describe User do
|
15
|
+
# subject { User.new }
|
16
|
+
# provide :name
|
17
|
+
#
|
18
|
+
# [intead of]
|
19
|
+
#
|
20
|
+
# it "should provide #name" do
|
21
|
+
# methods = subject.public_methods + subject.protected_methods + subject.private_methods
|
22
|
+
# methods.should include("name")
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
def provide(name)
|
27
|
+
it "should provide ##{name}" do
|
28
|
+
subject.should provide(name)
|
31
29
|
end
|
32
30
|
end
|
33
31
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
|
2
|
-
require '
|
2
|
+
require 'rspec'
|
3
3
|
require 'rr'
|
4
4
|
|
5
5
|
require File.join(File.dirname(__FILE__), '/../lib/ircbot')
|
6
|
-
require File.join(File.dirname(__FILE__), '/its_helper')
|
6
|
+
#require File.join(File.dirname(__FILE__), '/its_helper')
|
7
7
|
require File.join(File.dirname(__FILE__), '/provide_helper')
|
8
8
|
|
9
9
|
|
metadata
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ircbot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 17
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
5
11
|
platform: ruby
|
6
12
|
authors:
|
7
13
|
- maiha
|
@@ -9,81 +15,126 @@ autorequire:
|
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
17
|
|
12
|
-
date:
|
18
|
+
date: 2012-03-21 00:00:00 +09:00
|
13
19
|
default_executable:
|
14
20
|
dependencies:
|
15
21
|
- !ruby/object:Gem::Dependency
|
16
|
-
name:
|
22
|
+
name: dsl_accessor
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 15
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 4
|
33
|
+
- 0
|
34
|
+
version: 0.4.0
|
17
35
|
type: :runtime
|
18
|
-
|
19
|
-
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: extlib
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
20
42
|
requirements:
|
21
43
|
- - ">="
|
22
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 39
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
- 9
|
49
|
+
- 14
|
23
50
|
version: 0.9.14
|
24
|
-
|
51
|
+
type: :runtime
|
52
|
+
version_requirements: *id002
|
25
53
|
- !ruby/object:Gem::Dependency
|
26
54
|
name: net-irc
|
27
|
-
|
28
|
-
|
29
|
-
|
55
|
+
prerelease: false
|
56
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
30
58
|
requirements:
|
31
59
|
- - ">="
|
32
60
|
- !ruby/object:Gem::Version
|
61
|
+
hash: 13
|
62
|
+
segments:
|
63
|
+
- 0
|
64
|
+
- 0
|
65
|
+
- 9
|
33
66
|
version: 0.0.9
|
34
|
-
|
67
|
+
type: :runtime
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
prerelease: false
|
72
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 43
|
78
|
+
segments:
|
79
|
+
- 2
|
80
|
+
- 9
|
81
|
+
- 0
|
82
|
+
version: 2.9.0
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id004
|
35
85
|
description: An irc bot framework that offers easy-to-use by plugins
|
36
|
-
email:
|
86
|
+
email:
|
87
|
+
- maiha@wota.jp
|
37
88
|
executables:
|
38
89
|
- ircbot
|
39
90
|
extensions: []
|
40
91
|
|
41
|
-
extra_rdoc_files:
|
42
|
-
|
43
|
-
- MIT-LICENSE
|
92
|
+
extra_rdoc_files: []
|
93
|
+
|
44
94
|
files:
|
45
95
|
- MIT-LICENSE
|
46
96
|
- README
|
47
97
|
- Rakefile
|
48
|
-
-
|
98
|
+
- bin/ircbot
|
99
|
+
- config/sama-zu.yml
|
100
|
+
- config/yml.erb
|
101
|
+
- ircbot.gemspec
|
102
|
+
- lib/ircbot.rb
|
49
103
|
- lib/ircbot/client.rb
|
104
|
+
- lib/ircbot/client/commands.rb
|
50
105
|
- lib/ircbot/client/config.rb
|
51
106
|
- lib/ircbot/client/config/channels.rb
|
52
|
-
- lib/ircbot/client/config/plugins.rb
|
53
107
|
- lib/ircbot/client/config/generator.rb
|
54
|
-
- lib/ircbot/client/
|
108
|
+
- lib/ircbot/client/config/plugins.rb
|
55
109
|
- lib/ircbot/client/core.rb
|
56
|
-
- lib/ircbot/client/
|
57
|
-
- lib/ircbot/client/standalone.rb
|
58
|
-
- lib/ircbot/client/plugins.rb
|
59
|
-
- lib/ircbot/client/logger.rb
|
110
|
+
- lib/ircbot/client/encoding.rb
|
60
111
|
- lib/ircbot/client/eventable.rb
|
112
|
+
- lib/ircbot/client/logger.rb
|
113
|
+
- lib/ircbot/client/plugins.rb
|
114
|
+
- lib/ircbot/client/standalone.rb
|
61
115
|
- lib/ircbot/client/timeout.rb
|
116
|
+
- lib/ircbot/core_ext/delegation.rb
|
62
117
|
- lib/ircbot/core_ext/extending.rb
|
63
118
|
- lib/ircbot/core_ext/message.rb
|
64
|
-
- lib/ircbot/
|
119
|
+
- lib/ircbot/dm.rb
|
120
|
+
- lib/ircbot/framework.rb
|
121
|
+
- lib/ircbot/plugin.rb
|
65
122
|
- lib/ircbot/plugins.rb
|
66
123
|
- lib/ircbot/version.rb
|
67
|
-
-
|
68
|
-
-
|
124
|
+
- plugins/echo.rb
|
125
|
+
- plugins/irc.rb
|
126
|
+
- plugins/plugins.rb
|
127
|
+
- plugins/reminder.rb
|
128
|
+
- plugins/which.rb
|
129
|
+
- plugins/youtube.rb
|
69
130
|
- spec/config_spec.rb
|
70
|
-
- spec/plugin_spec.rb
|
71
|
-
- spec/provide_helper.rb
|
72
131
|
- spec/fixtures/sama-zu.yml
|
73
|
-
- spec/its_helper.rb
|
74
|
-
- spec/spec_helper.rb
|
75
132
|
- spec/framework_spec.rb
|
133
|
+
- spec/its_helper.rb
|
134
|
+
- spec/plugin_spec.rb
|
76
135
|
- spec/plugins_spec.rb
|
77
|
-
-
|
78
|
-
-
|
79
|
-
- plugins/echo.rb
|
80
|
-
- plugins/plugins.rb
|
81
|
-
- plugins/which.rb
|
82
|
-
- plugins/irc.rb
|
83
|
-
- config/wota.yml
|
84
|
-
- config/airi.yml
|
85
|
-
- config/sama-zu.yml
|
86
|
-
- config/yml.erb
|
136
|
+
- spec/provide_helper.rb
|
137
|
+
- spec/spec_helper.rb
|
87
138
|
has_rdoc: true
|
88
139
|
homepage: http://github.com/maiha/ircbot
|
89
140
|
licenses: []
|
@@ -94,21 +145,27 @@ rdoc_options: []
|
|
94
145
|
require_paths:
|
95
146
|
- lib
|
96
147
|
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
none: false
|
97
149
|
requirements:
|
98
150
|
- - ">="
|
99
151
|
- !ruby/object:Gem::Version
|
152
|
+
hash: 3
|
153
|
+
segments:
|
154
|
+
- 0
|
100
155
|
version: "0"
|
101
|
-
version:
|
102
156
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
103
158
|
requirements:
|
104
159
|
- - ">="
|
105
160
|
- !ruby/object:Gem::Version
|
161
|
+
hash: 3
|
162
|
+
segments:
|
163
|
+
- 0
|
106
164
|
version: "0"
|
107
|
-
version:
|
108
165
|
requirements: []
|
109
166
|
|
110
|
-
rubyforge_project:
|
111
|
-
rubygems_version: 1.3.
|
167
|
+
rubyforge_project: ircbot
|
168
|
+
rubygems_version: 1.3.7
|
112
169
|
signing_key:
|
113
170
|
specification_version: 3
|
114
171
|
summary: easy irc bot framework
|
data/config/airi.yml
DELETED
data/config/wota.yml
DELETED
data/plugins/tv.rb
DELETED
@@ -1,262 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
#
|
3
|
-
# tv.rb
|
4
|
-
# Author:
|
5
|
-
# Created: Sun Jan 10 18:44:35 2010
|
6
|
-
|
7
|
-
require 'rubygems'
|
8
|
-
require 'ircbot'
|
9
|
-
require '/git/plugins/ircbot-plugins/lib/tvguide'
|
10
|
-
require '/git/plugins/ircbot-plugins/lib/tv-cast'
|
11
|
-
require 'chawan'
|
12
|
-
|
13
|
-
class TVGuide::Program
|
14
|
-
def id
|
15
|
-
"#{st}:#{sn}"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
class TvPlugin < Ircbot::Plugin
|
20
|
-
######################################################################
|
21
|
-
### Extensions to Plugin
|
22
|
-
|
23
|
-
class WeightedRandomizer
|
24
|
-
def initialize(hash)
|
25
|
-
@hash = construct(hash)
|
26
|
-
end
|
27
|
-
|
28
|
-
def construct(obj)
|
29
|
-
case obj
|
30
|
-
when Hash
|
31
|
-
return obj
|
32
|
-
when Array
|
33
|
-
hash = {}
|
34
|
-
obj.reverse.each_with_index do |val,i|
|
35
|
-
hash[val] = i+1
|
36
|
-
end
|
37
|
-
return hash
|
38
|
-
else
|
39
|
-
raise NotImplementedError, "expected Hash or Array, but got #{hash.class}: #{hash.inspect}"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def execute
|
44
|
-
maps = []
|
45
|
-
stop = 0
|
46
|
-
@hash.each_pair do |val, key|
|
47
|
-
start = stop
|
48
|
-
stop += key
|
49
|
-
maps << [start...stop, val]
|
50
|
-
end
|
51
|
-
hit = rand(stop)
|
52
|
-
maps.each do |(range, val)|
|
53
|
-
return val if range === hit
|
54
|
-
end
|
55
|
-
return @hash.keys.first
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
module ReplyApiFu
|
60
|
-
class Reply < RuntimeError
|
61
|
-
def initialize(text)
|
62
|
-
@text = text
|
63
|
-
end
|
64
|
-
|
65
|
-
def text
|
66
|
-
case @text
|
67
|
-
when Hash
|
68
|
-
WeightedRandomizer.new(@text).execute
|
69
|
-
else
|
70
|
-
@text.to_s
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class Nop < RuntimeError; end
|
76
|
-
|
77
|
-
def nop
|
78
|
-
raise Nop
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
include ReplyApiFu
|
83
|
-
|
84
|
-
######################################################################
|
85
|
-
### TvPlugin
|
86
|
-
|
87
|
-
STATION_ABBRS = {
|
88
|
-
'NHK' => 'NHK総合',
|
89
|
-
'NHKG' => 'NHK総合',
|
90
|
-
'NHKE' => 'NHK教育',
|
91
|
-
'ETV' => 'NHK教育',
|
92
|
-
'日テレ' => '日本テレビ',
|
93
|
-
'NTV' => '日本テレビ',
|
94
|
-
'TBS' => 'TBSテレビ',
|
95
|
-
'フジ' => 'フジテレビ',
|
96
|
-
'CX' => 'フジテレビ',
|
97
|
-
'テレ朝' => 'テレビ朝日',
|
98
|
-
'EX' => 'テレビ朝日',
|
99
|
-
'テレ東' => 'テレビ東京',
|
100
|
-
'TX' => 'テレビ東京',
|
101
|
-
'MX' => 'TOKYO MX',
|
102
|
-
'BS' => 'NHK衛星第一',
|
103
|
-
'BS1' => 'NHK衛星第一',
|
104
|
-
'BS2' => 'NHK衛星第二',
|
105
|
-
}
|
106
|
-
|
107
|
-
class Conversation
|
108
|
-
attr_reader :nick
|
109
|
-
attr_reader :messages
|
110
|
-
|
111
|
-
Message = Struct.new(:time, :text)
|
112
|
-
|
113
|
-
delegate :[], :first, :last, :clear, :to=>"@messages"
|
114
|
-
|
115
|
-
def initialize(nick)
|
116
|
-
@nick = nick
|
117
|
-
@messages = []
|
118
|
-
end
|
119
|
-
|
120
|
-
def <<(text)
|
121
|
-
messages << Message.new(Time.now, text.to_s)
|
122
|
-
end
|
123
|
-
|
124
|
-
class One < Conversation
|
125
|
-
def <<(text)
|
126
|
-
clear
|
127
|
-
super
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
EagarProgram = Struct.new(:nick, :time, :program)
|
133
|
-
class EagarProgram
|
134
|
-
def push(program)
|
135
|
-
self.time = Time.now
|
136
|
-
self.program = program
|
137
|
-
end
|
138
|
-
|
139
|
-
def shift
|
140
|
-
self.time = nil
|
141
|
-
return program
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def reply(text)
|
146
|
-
respond_to_eagar_program
|
147
|
-
|
148
|
-
names = extract_station_names(text)
|
149
|
-
case text
|
150
|
-
when /キャスト/
|
151
|
-
do_cast(names.first)
|
152
|
-
when /(だれ|誰).*(\?|?)/
|
153
|
-
do_who(names.first)
|
154
|
-
else
|
155
|
-
do_summary(names)
|
156
|
-
end
|
157
|
-
|
158
|
-
nop
|
159
|
-
rescue Nop
|
160
|
-
return nil
|
161
|
-
rescue Reply => reply
|
162
|
-
return reply.text
|
163
|
-
end
|
164
|
-
|
165
|
-
def do_summary(names)
|
166
|
-
reports = names.map{|name| summary(current[name])}.compact
|
167
|
-
raise Reply, reports.join("\n")
|
168
|
-
end
|
169
|
-
|
170
|
-
def do_who(name)
|
171
|
-
prog = current[name]
|
172
|
-
if prog.casts.size > 0
|
173
|
-
raise Reply, "#{name}: #{prog.casts.join(',')}"
|
174
|
-
else
|
175
|
-
eagar_program_for(nick).push prog
|
176
|
-
raise Reply, {
|
177
|
-
"知るかよ!" => 80,
|
178
|
-
"#{nick}必死w" => 10,
|
179
|
-
"EPGには記述されていません" => 1,
|
180
|
-
}
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
def do_cast(name)
|
185
|
-
p = current[name]
|
186
|
-
query = "%s %s" % [p.title, name]
|
187
|
-
casts = TvCast.lookup!(query)
|
188
|
-
if casts.size > 0
|
189
|
-
raise Reply, "#{name}: #{casts.join(',')}"
|
190
|
-
else
|
191
|
-
raise Reply, "見つかりませんでした"
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
private
|
196
|
-
|
197
|
-
def extract_station_names(text)
|
198
|
-
text = text.sub(/(誰|キャスト)/, ',\1')
|
199
|
-
nouns = Chawan.parse(text.gsub(/\s+/,',')).compact.noun.map(&:to_s)
|
200
|
-
names = nouns.map{|name| STATION_ABBRS[name] || name} & station_names
|
201
|
-
nop if names.empty?
|
202
|
-
return names
|
203
|
-
end
|
204
|
-
|
205
|
-
def eagar_program_for(nick)
|
206
|
-
@eagar_programs ||= {}
|
207
|
-
@eagar_programs[nick] ||= EagarProgram.new(nick)
|
208
|
-
end
|
209
|
-
|
210
|
-
def respond_to_eagar_program
|
211
|
-
eager = eagar_program_for(nick)
|
212
|
-
if eager.time and Time.now.to_i < eager.time.to_i + 10 and prog = eager.shift
|
213
|
-
query = "%s %s" % [prog.title, prog.station_name]
|
214
|
-
casts = TvCast.lookup!(query)
|
215
|
-
if casts.size > 0
|
216
|
-
random = WeightedRandomizer.new(casts)
|
217
|
-
name = random.execute
|
218
|
-
raise Reply, {
|
219
|
-
"#{name}と思われ" => 50,
|
220
|
-
"#{name}?" => 50,
|
221
|
-
"#{name}の予感!" => 50,
|
222
|
-
"#{casts[0,2].join('か')}のどっちか" => 30,
|
223
|
-
"ググった限り#{name}ぽい>#{prog.title}" => 20,
|
224
|
-
"#{name}に大決定や!(確度#{(100/casts.size).to_i}%)" => 10,
|
225
|
-
casts.inspect => 2,
|
226
|
-
}
|
227
|
-
end
|
228
|
-
raise Reply, text
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
def current
|
233
|
-
@current ||= TVGuide.current
|
234
|
-
end
|
235
|
-
|
236
|
-
def station_names
|
237
|
-
@station_names ||= current.station_names
|
238
|
-
end
|
239
|
-
|
240
|
-
def reporteds
|
241
|
-
@reporteds ||= {}
|
242
|
-
end
|
243
|
-
|
244
|
-
def summary(p)
|
245
|
-
nop if reporteds[p.id]
|
246
|
-
reporteds[p.id] = true
|
247
|
-
time1 = p.st.strftime("%H:%M") rescue ''
|
248
|
-
time2 = p.en.strftime("%H:%M") rescue ''
|
249
|
-
"#{time1}-#{time2} #{p.title} (#{p.sn})"
|
250
|
-
rescue
|
251
|
-
nop
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
|
256
|
-
if $0 == __FILE__
|
257
|
-
$KCODE = 'u'
|
258
|
-
require 'pp'
|
259
|
-
|
260
|
-
# pp TVGuide::TXML301PG.new.map
|
261
|
-
pp TvPlugin.new.reply('NHK総合')
|
262
|
-
end
|