jsn-rbot 0.9.14
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +193 -0
- data/bin/rbot +122 -0
- data/bin/rbot-remote +76 -0
- metadata +60 -0
data/Rakefile
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
|
5
|
+
task :default => [:buildext]
|
6
|
+
|
7
|
+
SPECFILE = 'rbot.gemspec'
|
8
|
+
# The Rakefile is also used after installing the gem, to build
|
9
|
+
# the .mo files. Since in this case the SPECFILE is not available,
|
10
|
+
# we must (and can) skip defining the gem packaging tasks.
|
11
|
+
if File.exist? SPECFILE
|
12
|
+
spec = eval(File.read(SPECFILE), nil, SPECFILE)
|
13
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
14
|
+
pkg.need_zip = true
|
15
|
+
pkg.need_tar = true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# normalize a po/pot file
|
20
|
+
def normalize_po(fn)
|
21
|
+
content = File.read(fn)
|
22
|
+
|
23
|
+
# sort the messages by file location
|
24
|
+
if MSGCAT
|
25
|
+
sorted = `#{MSGCAT} --width=79 --sort-by-file #{fn}`
|
26
|
+
if sorted != content
|
27
|
+
content = sorted
|
28
|
+
modified = true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# replace project-id-version placholder
|
33
|
+
modified |= content.sub!(/^("Project-Id-Version: )PACKAGE VERSION(\\n")$/) {
|
34
|
+
"#{$1}rbot#{$2}"
|
35
|
+
}
|
36
|
+
|
37
|
+
if modified
|
38
|
+
File.open(fn, 'w') {|f| f.write content}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
PLUGIN_FILES = FileList['data/rbot/plugins/**/*.rb']
|
43
|
+
NON_PLUGIN_FILES = FileList["{lib,bin,data}/**/*.{rb,rhtml}"] - PLUGIN_FILES
|
44
|
+
|
45
|
+
# this task defines how po files and pot files are made. those rules are not defined
|
46
|
+
# normally because po and pot files should be only updated in the updatepo task,
|
47
|
+
# but po files are also prereqs for makemo
|
48
|
+
task :define_po_rules do
|
49
|
+
# generate pot file from rb files
|
50
|
+
rgettext_proc = proc do |t|
|
51
|
+
require 'gettext/utils'
|
52
|
+
source_files, pot_file = t.prerequisites, t.name
|
53
|
+
new_pot_file = "#{pot_file}.new"
|
54
|
+
puts "#{source_files.join(', ')} => #{pot_file}"
|
55
|
+
GetText.rgettext(source_files, new_pot_file)
|
56
|
+
|
57
|
+
# only use the new pot file if it contains unique messages
|
58
|
+
if File.exists?(pot_file) && MSGCOMM && `#{MSGCOMM} --unique #{pot_file} #{new_pot_file}`.empty?
|
59
|
+
rm new_pot_file
|
60
|
+
else
|
61
|
+
mv new_pot_file, pot_file
|
62
|
+
end
|
63
|
+
|
64
|
+
normalize_po(pot_file)
|
65
|
+
|
66
|
+
# save all this work until rb files are updated again
|
67
|
+
touch pot_file
|
68
|
+
end
|
69
|
+
|
70
|
+
# generate pot file for non-plugin files
|
71
|
+
file('po/rbot.pot' => NON_PLUGIN_FILES, &rgettext_proc)
|
72
|
+
|
73
|
+
# generate pot files for plugin files
|
74
|
+
rule(%r'^po/.+\.pot$' => proc {|fn|
|
75
|
+
PLUGIN_FILES.select {|f| f.pathmap('rbot-%n') == fn.pathmap('%n')}
|
76
|
+
}, &rgettext_proc)
|
77
|
+
|
78
|
+
# map the po file to its source pot file
|
79
|
+
pot_for_po = proc {|fn| fn.pathmap '%{^po/.+/,po/}X.pot'}
|
80
|
+
|
81
|
+
# update po file from pot file
|
82
|
+
msgmerge_proc = proc do |t|
|
83
|
+
require 'gettext/utils'
|
84
|
+
po_file, pot_file = t.name, t.source
|
85
|
+
puts "#{pot_file} => #{po_file}"
|
86
|
+
if File.exists? po_file
|
87
|
+
sh "#{MSGMERGE} --backup=off --update #{po_file} #{pot_file}"
|
88
|
+
elsif MSGINIT
|
89
|
+
locale = po_file[%r'^po/(.+)/.+\.po$', 1]
|
90
|
+
sh "#{MSGINIT} --locale=#{locale} --no-translator --input=#{pot_file} --output-file=#{po_file}"
|
91
|
+
else
|
92
|
+
warn "#{po_file} is missing and cannot be generated without msginit"
|
93
|
+
next
|
94
|
+
end
|
95
|
+
normalize_po(po_file)
|
96
|
+
touch po_file
|
97
|
+
end
|
98
|
+
|
99
|
+
# generate English po files
|
100
|
+
file(%r'^po/en_US/.+\.po$' => pot_for_po) do |t|
|
101
|
+
po_file, pot_file = t.name, t.source
|
102
|
+
if MSGEN
|
103
|
+
sh "#{MSGEN} --output-file=#{po_file} #{pot_file}"
|
104
|
+
normalize_po(po_file)
|
105
|
+
touch po_file
|
106
|
+
else
|
107
|
+
msgmerge_proc.call t
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# update po files
|
112
|
+
rule(%r'^po/.+/.+\.po$' => pot_for_po, &msgmerge_proc)
|
113
|
+
end
|
114
|
+
|
115
|
+
# generate mo files
|
116
|
+
rule(%r'^data/locale/.+/LC_MESSAGES/.+\.mo$' => proc {|fn|
|
117
|
+
[ fn.pathmap('%{^data/locale,po;LC_MESSAGES/,}X.po'),
|
118
|
+
# the directory is created if not existing
|
119
|
+
fn.pathmap('%d') ]
|
120
|
+
}) do |t|
|
121
|
+
po_file, mo_file = t.source, t.name
|
122
|
+
puts "#{po_file} => #{mo_file}"
|
123
|
+
require 'gettext/utils'
|
124
|
+
GetText.rmsgfmt po_file, mo_file
|
125
|
+
end
|
126
|
+
|
127
|
+
task :check_po_tools do
|
128
|
+
have = {}
|
129
|
+
|
130
|
+
po_tools = {
|
131
|
+
'msgmerge' => {
|
132
|
+
:options => %w[--backup= --update],
|
133
|
+
:message => 'Cannot update po files' },
|
134
|
+
'msginit' => {
|
135
|
+
:options => %w[--locale= --no-translator --input= --output-file=],
|
136
|
+
:message => 'Cannot generate missing po files' },
|
137
|
+
'msgcomm' => {
|
138
|
+
:options => %w[--unique],
|
139
|
+
:message => 'Pot files may be modified even without message change' },
|
140
|
+
'msgen' => {
|
141
|
+
:options => %w[--output-file],
|
142
|
+
:message => 'English po files will not be generated' },
|
143
|
+
'msgcat' => {
|
144
|
+
:options => %w[--width= --sort-by-file],
|
145
|
+
:message => 'Pot files will not be normalized' }
|
146
|
+
}
|
147
|
+
|
148
|
+
po_tools.each_pair do |command, value|
|
149
|
+
path = ENV["#{command.upcase}_PATH"] || command
|
150
|
+
have_it = have[command] = value[:options].all? do |option|
|
151
|
+
`#{path} --help`.include? option
|
152
|
+
end
|
153
|
+
Object.const_set(command.upcase, have_it ? path : false)
|
154
|
+
warn "#{command} not found. #{value[:message]}" unless have_it
|
155
|
+
end
|
156
|
+
abort unless MSGMERGE
|
157
|
+
end
|
158
|
+
|
159
|
+
PLUGIN_BASENAMES = PLUGIN_FILES.map {|f| f.pathmap('%n')}
|
160
|
+
LOCALES = FileList['po/*/'].map {|d| d.pathmap('%n')}
|
161
|
+
|
162
|
+
LOCALES.each do |l|
|
163
|
+
directory "data/locale/#{l}/LC_MESSAGES"
|
164
|
+
end
|
165
|
+
|
166
|
+
desc 'Update po files'
|
167
|
+
task :updatepo => [:define_po_rules, :check_po_tools] + LOCALES.map {|l|
|
168
|
+
["po/#{l}/rbot.po"] +
|
169
|
+
PLUGIN_BASENAMES.map {|n| "po/#{l}/rbot-#{n}.po"}
|
170
|
+
}.flatten
|
171
|
+
|
172
|
+
desc 'Normalize po files'
|
173
|
+
task :normalizepo => :check_po_tools do
|
174
|
+
FileList['po/*/*.po'].each {|fn| normalize_po(fn)}
|
175
|
+
end
|
176
|
+
|
177
|
+
# this task invokes makemo if ruby-gettext is available, but otherwise succeeds
|
178
|
+
# with a warning instead of failing. it is to be used by Gem's extension builder
|
179
|
+
# to make installation not fail because of lack of ruby-gettext
|
180
|
+
task :buildext do
|
181
|
+
begin
|
182
|
+
require 'gettext/utils'
|
183
|
+
Rake::Task[:makemo].invoke
|
184
|
+
rescue LoadError
|
185
|
+
warn 'Ruby-gettext cannot be located, so mo files cannot be built and installed'
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
desc 'Generate mo files'
|
190
|
+
task :makemo =>
|
191
|
+
FileList['po/*/*.po'].pathmap('%{^po,data/locale}d/LC_MESSAGES/%n.mo')
|
192
|
+
|
193
|
+
|
data/bin/rbot
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
=begin rdoc
|
4
|
+
|
5
|
+
= rbot main executable
|
6
|
+
|
7
|
+
Usage:
|
8
|
+
|
9
|
+
% rbot [options] [config directory]
|
10
|
+
|
11
|
+
== Options
|
12
|
+
|
13
|
+
[-h, --help]
|
14
|
+
display a help message and exit
|
15
|
+
[-v, --version]
|
16
|
+
display version information and exit
|
17
|
+
[-d, --debug]
|
18
|
+
enable debug messages
|
19
|
+
[-l, --loglevel _level_]
|
20
|
+
sets the minimum log level verbosity
|
21
|
+
[-b, --background]
|
22
|
+
background (daemonize) the bot
|
23
|
+
[-p, --pidfile _filename_]
|
24
|
+
write the bot pid to _filename_
|
25
|
+
|
26
|
+
The default config directory is <tt>~/.rbot</tt>.
|
27
|
+
|
28
|
+
The default pidfile is <tt><i>botdir</i>/rbot.pid</tt>.
|
29
|
+
|
30
|
+
The logfile is located at <tt><i>botdir</i>/<i>botname</i>.log</tt>, and
|
31
|
+
the default loglevel is 1 (INFO messages). Possible values for the loglevel
|
32
|
+
are 0 (DEBUG), 1 (INFO), 2 (WARN), 3 (ERROR), 4 (FATAL).
|
33
|
+
|
34
|
+
Please note that the logfile doesn't contain IRC logs (which are located at
|
35
|
+
<tt><i>botdir</i>/logs/*</tt>, but only rbot diagnostic messages.
|
36
|
+
|
37
|
+
=end
|
38
|
+
|
39
|
+
# Copyright (C) 2002-2006 Tom Gilbert.
|
40
|
+
# Copyright (C) 2007-2008 Giuseppe Bilotta and the rbot development team
|
41
|
+
#
|
42
|
+
# This is free software, see COPYING for licensing details
|
43
|
+
|
44
|
+
$VERBOSE=true
|
45
|
+
|
46
|
+
require 'etc'
|
47
|
+
require 'getoptlong'
|
48
|
+
require 'fileutils'
|
49
|
+
|
50
|
+
$version ||= '0.9.15-git'
|
51
|
+
$version_timestamp ||= 0
|
52
|
+
$opts = Hash.new
|
53
|
+
|
54
|
+
orig_opts = ARGV.dup
|
55
|
+
|
56
|
+
opts = GetoptLong.new(
|
57
|
+
["--background", "-b", GetoptLong::NO_ARGUMENT],
|
58
|
+
["--debug", "-d", GetoptLong::NO_ARGUMENT],
|
59
|
+
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
60
|
+
["--loglevel", "-l", GetoptLong::REQUIRED_ARGUMENT],
|
61
|
+
["--trace", "-t", GetoptLong::REQUIRED_ARGUMENT],
|
62
|
+
["--pidfile", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
63
|
+
["--version", "-v", GetoptLong::NO_ARGUMENT]
|
64
|
+
)
|
65
|
+
|
66
|
+
$debug = $DEBUG
|
67
|
+
$daemonize = false
|
68
|
+
|
69
|
+
opts.each {|opt, arg|
|
70
|
+
$debug = true if(opt == "--debug")
|
71
|
+
$daemonize = true if(opt == "--background")
|
72
|
+
$opts[opt.sub(/^-+/, "")] = arg
|
73
|
+
}
|
74
|
+
|
75
|
+
$cl_loglevel = $opts["loglevel"].to_i if $opts["loglevel"]
|
76
|
+
|
77
|
+
if ($opts["trace"])
|
78
|
+
set_trace_func proc { |event, file, line, id, binding, classname|
|
79
|
+
if classname.to_s == $opts["trace"]
|
80
|
+
printf "TRACE: %8s %s:%-2d %10s %8s\n", event, File.basename(file), line, id, classname
|
81
|
+
end
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
defaultlib = File.expand_path(File.dirname($0) + '/../lib')
|
86
|
+
|
87
|
+
if File.directory? "#{defaultlib}/rbot"
|
88
|
+
unless $:.include? defaultlib
|
89
|
+
$:.unshift defaultlib
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
begin
|
94
|
+
require 'rbot/ircbot'
|
95
|
+
rescue LoadError => e
|
96
|
+
puts "Error: couldn't find the rbot/ircbot module (or one of its dependencies)\n"
|
97
|
+
puts e
|
98
|
+
exit 2
|
99
|
+
end
|
100
|
+
|
101
|
+
if ($opts["version"])
|
102
|
+
puts "rbot #{$version}"
|
103
|
+
exit 0
|
104
|
+
end
|
105
|
+
|
106
|
+
if ($opts["help"])
|
107
|
+
puts "usage: rbot [options] [config directory]"
|
108
|
+
puts " -h, --help this message"
|
109
|
+
puts " -v, --version version information"
|
110
|
+
puts " -d, --debug enable debug messages"
|
111
|
+
puts " -l, --loglevel sets the log level verbosity"
|
112
|
+
puts " -b, --background background (daemonize) the bot"
|
113
|
+
puts " -p, --pidfile write the bot pid to file"
|
114
|
+
puts "config directory defaults to ~/.rbot"
|
115
|
+
exit 0
|
116
|
+
end
|
117
|
+
|
118
|
+
if(bot = Irc::Bot.new(ARGV.shift, :argv => orig_opts))
|
119
|
+
# just run the bot
|
120
|
+
bot.mainloop
|
121
|
+
end
|
122
|
+
|
data/bin/rbot-remote
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
require 'drb'
|
3
|
+
require 'optparse'
|
4
|
+
|
5
|
+
#++
|
6
|
+
#
|
7
|
+
# :title: RemoteCtl example script
|
8
|
+
#
|
9
|
+
# Author:: jsn (dmitry kim) <dmitry dot kim at gmail dot org>
|
10
|
+
# Copyright:: (C) 2007 dmitry kim
|
11
|
+
# License:: in public domain
|
12
|
+
|
13
|
+
user = nil
|
14
|
+
pw = nil
|
15
|
+
dst = nil
|
16
|
+
uri = 'druby://localhost:7268'
|
17
|
+
|
18
|
+
opts = OptionParser.new
|
19
|
+
opts.on('-u', '--user <user>', "remote user (mandatory)") { |v| user = v }
|
20
|
+
opts.on('-p', '--password <pw>', "remote user password (mandatory)") { |v| pw = v }
|
21
|
+
opts.on('-d', '--destination <user or #channel>') { |v| dst = v }
|
22
|
+
opts.on('-r', '--uri <drb uri>', "rbot url (#{uri})") { |v| uri = v }
|
23
|
+
opts.on('-h', '--help', "this message") { |v| pw = nil } # sorry!
|
24
|
+
opts.on('-a', '--about', "what it's all about.") { |v|
|
25
|
+
puts <<EOF
|
26
|
+
This is just a proof-of-concept example for rbot druby-based api. This program
|
27
|
+
reads lines of text from the standard input and sends them to a specified irc
|
28
|
+
channel or user via rbot. Make sure you have remotectl.rb plugin loaded before
|
29
|
+
use.
|
30
|
+
|
31
|
+
The necessary setup is:
|
32
|
+
1) # create a new rbot user ("rmuser", in this example) with a password
|
33
|
+
# ("rmpw", in this example). in an open query to rbot:
|
34
|
+
|
35
|
+
<you> user create rmuser rmpw
|
36
|
+
<rbot> created botuser remote
|
37
|
+
|
38
|
+
2) # add a remotectl permission to your newly created remote user:
|
39
|
+
|
40
|
+
<you> permissions set +remotectl for rmuser
|
41
|
+
<rbot> okies!
|
42
|
+
|
43
|
+
3) # add specific permissions for the commands you want to allow via
|
44
|
+
# remote interface. for example, in this script we want 'say',
|
45
|
+
# 'action' and other basic commands to work:
|
46
|
+
|
47
|
+
<you> permissions set +basics::talk::do for rmuser
|
48
|
+
<rbot> alright
|
49
|
+
|
50
|
+
4) # run the #{$0} and type something. the message should
|
51
|
+
# show up on your channel / arrive as an irc private message.
|
52
|
+
|
53
|
+
[you@yourhost ~]$ ./bin/rbot-remote -u rmuser -p rmpw -d '#your-channel'
|
54
|
+
hello, world!
|
55
|
+
<Ctrl-D>
|
56
|
+
[you@yourhost ~]$
|
57
|
+
EOF
|
58
|
+
exit 0
|
59
|
+
}
|
60
|
+
opts.parse!
|
61
|
+
|
62
|
+
if !pw || !user || !dst
|
63
|
+
puts opts.to_s
|
64
|
+
exit 0
|
65
|
+
end
|
66
|
+
|
67
|
+
rbot = DRbObject.new_with_uri(uri)
|
68
|
+
id = rbot.delegate(nil, "remote login #{user} #{pw}")[:return]
|
69
|
+
puts "id is #{id.inspect}"
|
70
|
+
loop {
|
71
|
+
s = gets or break
|
72
|
+
s.chomp!
|
73
|
+
rv = rbot.delegate(id, "dispatch say #{dst} #{s}") or break
|
74
|
+
puts "rv is #{rv.inspect}"
|
75
|
+
}
|
76
|
+
|
metadata
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jsn-rbot
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.14
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tom Gilbert
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-03-21 00:00:00 -07:00
|
13
|
+
default_executable: rbot
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: A modular ruby IRC bot specifically designed for ease of extension via plugins.
|
17
|
+
email: tom@linuxbrit.co.uk
|
18
|
+
executables:
|
19
|
+
- rbot
|
20
|
+
- rbot-remote
|
21
|
+
extensions:
|
22
|
+
- Rakefile
|
23
|
+
extra_rdoc_files: []
|
24
|
+
|
25
|
+
files: []
|
26
|
+
|
27
|
+
has_rdoc: true
|
28
|
+
homepage: http://ruby-rbot.org
|
29
|
+
post_install_message:
|
30
|
+
rdoc_options:
|
31
|
+
- --exclude
|
32
|
+
- post-install.rb
|
33
|
+
- --title
|
34
|
+
- rbot API Documentation
|
35
|
+
- --main
|
36
|
+
- README
|
37
|
+
- README
|
38
|
+
require_paths:
|
39
|
+
- lib
|
40
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: "0"
|
51
|
+
version:
|
52
|
+
requirements:
|
53
|
+
- Ruby, version 1.8.0 (or newer)
|
54
|
+
rubyforge_project: rbot
|
55
|
+
rubygems_version: 1.2.0
|
56
|
+
signing_key:
|
57
|
+
specification_version: 2
|
58
|
+
summary: A modular ruby IRC bot.
|
59
|
+
test_files: []
|
60
|
+
|