jsn-rbot 0.9.14
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.
- 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
|
+
|