summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Rakefile2
-rwxr-xr-xbin/rbot-remote76
-rw-r--r--data/rbot/plugins/remotectl.rb29
-rw-r--r--lib/rbot/core/remote.rb401
-rw-r--r--man/rbot-remote.xml217
-rw-r--r--rbot.gemspec5
6 files changed, 3 insertions, 727 deletions
diff --git a/Rakefile b/Rakefile
index 97b3e1f3..7bf643e3 100644
--- a/Rakefile
+++ b/Rakefile
@@ -7,7 +7,7 @@ rule '.1' => ['.xml'] do |t|
sh "xsltproc -nonet -o #{t.name} /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl #{t.source}"
end
-task :manpages => ['man/rbot.1', 'man/rbot-remote.1']
+task :manpages => ['man/rbot.1']
SPECFILE = 'rbot.gemspec'
# The Rakefile is also used after installing the gem, to build
diff --git a/bin/rbot-remote b/bin/rbot-remote
deleted file mode 100755
index 353bb06d..00000000
--- a/bin/rbot-remote
+++ /dev/null
@@ -1,76 +0,0 @@
-#! /usr/bin/ruby
-require 'drb'
-require 'optparse'
-
-#++
-#
-# :title: RemoteCtl example script
-#
-# Author:: jsn (dmitry kim) <dmitry dot kim at gmail dot org>
-# Copyright:: (C) 2007 dmitry kim
-# License:: in public domain
-
-user = nil
-pw = nil
-dst = nil
-uri = 'druby://localhost:7268'
-
-opts = OptionParser.new
-opts.on('-u', '--user <user>', "remote user (mandatory)") { |v| user = v }
-opts.on('-p', '--password <pw>', "remote user password (mandatory)") { |v| pw = v }
-opts.on('-d', '--destination <user or #channel>') { |v| dst = v }
-opts.on('-r', '--uri <drb uri>', "rbot url (#{uri})") { |v| uri = v }
-opts.on('-h', '--help', "this message") { |v| pw = nil } # sorry!
-opts.on('-a', '--about', "what it's all about.") { |v|
- puts <<EOF
-This is just a proof-of-concept example for rbot druby-based api. This program
-reads lines of text from the standard input and sends them to a specified irc
-channel or user via rbot. Make sure you have remotectl.rb plugin loaded before
-use.
-
-The necessary setup is:
- 1) # create a new rbot user ("rmuser", in this example) with a password
- # ("rmpw", in this example). in an open query to rbot:
-
- <you> user create rmuser rmpw
- <rbot> created botuser remote
-
- 2) # add a remotectl permission to your newly created remote user:
-
- <you> permissions set +remotectl for rmuser
- <rbot> okies!
-
- 3) # add specific permissions for the commands you want to allow via
- # remote interface. for example, in this script we want 'say',
- # 'action' and other basic commands to work:
-
- <you> permissions set +basics::talk::do for rmuser
- <rbot> alright
-
- 4) # run the #{$0} and type something. the message should
- # show up on your channel / arrive as an irc private message.
-
- [you@yourhost ~]$ ./bin/rbot-remote -u rmuser -p rmpw -d '#your-channel'
- hello, world!
- <Ctrl-D>
- [you@yourhost ~]$
-EOF
- exit 0
-}
-opts.parse!
-
-if !pw || !user || !dst
- puts opts.to_s
- exit 0
-end
-
-rbot = DRbObject.new_with_uri(uri)
-id = rbot.delegate(nil, "remote login #{user} #{pw}")[:return]
-puts "id is #{id.inspect}"
-loop {
- s = gets or break
- s.chomp!
- rv = rbot.delegate(id, "dispatch say #{dst} #{s}") or break
- puts "rv is #{rv.inspect}"
-}
-
diff --git a/data/rbot/plugins/remotectl.rb b/data/rbot/plugins/remotectl.rb
deleted file mode 100644
index 31d48fe3..00000000
--- a/data/rbot/plugins/remotectl.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-#-- vim:sw=4:et
-#++
-#
-# :title: RemoteCtl plugin
-#
-# Author:: jsn (dmitry kim) <dmitry dot kim at gmail dot org>
-# Copyright:: (C) 2007 dmitry kim
-# License:: in public domain
-#
-# Adds druby remote command execution to rbot. See 'bin/rbot-remote' for
-# example usage.
-
-class RemoteCtlPlugin < Plugin
- include RemotePlugin
-
- def remote_command(m, params)
- s = params[:string].to_s
- u = @bot.server.user("remote:#{m.source.username}")
- @bot.auth.login(u, m.source.username, m.source.password)
- fake_message(s, :source => u)
- end
-end
-
-me = RemoteCtlPlugin.new
-
-me.remote_map 'dispatch *string',
- :action => 'remote_command'
-
-me.default_auth('*', false)
diff --git a/lib/rbot/core/remote.rb b/lib/rbot/core/remote.rb
deleted file mode 100644
index d8d43533..00000000
--- a/lib/rbot/core/remote.rb
+++ /dev/null
@@ -1,401 +0,0 @@
-#-- vim:sw=2:et
-#++
-#
-# :title: Remote service provider for rbot
-#
-# Author:: Giuseppe Bilotta (giuseppe.bilotta@gmail.com)
-#
-# From an idea by halorgium <rbot@spork.in>.
-#
-# TODO find a way to manage session id (logging out, manually and/or
-# automatically)
-
-require 'drb/drb'
-
-module ::Irc
-class Bot
-
- module Auth
-
- # We extend the BotUser class to handle remote logins
- #
- class BotUser
-
- # A rather simple method to handle remote logins. Nothing special, just a
- # password check.
- #
- def remote_login(password)
- if password == @password
- debug "remote login for #{self.inspect} succeeded"
- return true
- else
- return false
- end
- end
- end
-
- # We extend the ManagerClass to handle remote logins
- #
- class ManagerClass
-
- MAX_SESSION_ID = 2**128 - 1
-
- # Creates a session id when the given password matches the given
- # botusername
- #
- def remote_login(botusername, pwd)
- @remote_users = Hash.new unless defined? @remote_users
- n = BotUser.sanitize_username(botusername)
- k = n.to_sym
- raise "No such BotUser #{n}" unless include?(k)
- bu = @allbotusers[k]
- if bu.remote_login(pwd)
- raise "ran out of session ids!" if @remote_users.length == MAX_SESSION_ID
- session_id = rand(MAX_SESSION_ID)
- while @remote_users.has_key?(session_id)
- session_id = rand(MAX_SESSION_ID)
- end
- @remote_users[session_id] = bu
- return session_id
- end
- return false
- end
-
- # Returns the botuser associated with the given session id
- def remote_user(session_id)
- return everyone unless session_id
- return nil unless defined? @remote_users
- if @remote_users.has_key?(session_id)
- return @remote_users[session_id]
- else
- return nil
- end
- end
- end
-
- end
-
-
- # A RemoteMessage is similar to a BasicUserMessage
- #
- class RemoteMessage
- # associated bot
- attr_reader :bot
-
- # when the message was received
- attr_reader :time
-
- # remote client that originated the message
- attr_reader :source
-
- # contents of the message
- attr_accessor :message
-
- def initialize(bot, source, message)
- @bot = bot
- @source = source
- @message = message
- @time = Time.now
- end
-
- # The target of a RemoteMessage
- def target
- @bot
- end
-
- # Remote messages are always 'private'
- def private?
- true
- end
- end
-
- # The RemoteDispatcher is a kind of MessageMapper, tuned to handle
- # RemoteMessages
- #
- class RemoteDispatcher < MessageMapper
-
- # It is initialized by passing it the bot instance
- #
- def initialize(bot)
- super
- end
-
- # The map method for the RemoteDispatcher returns the index of the inserted
- # template
- #
- def map(botmodule, *args)
- super
- return @templates.length - 1
- end
-
- # The unmap method for the RemoteDispatcher nils the template at the given index,
- # therefore effectively removing the mapping
- #
- def unmap(botmodule, handle)
- tmpl = @templates[handle]
- raise "Botmodule #{botmodule.name} tried to unmap #{tmpl.inspect} that was handled by #{tmpl.botmodule}" unless tmpl.botmodule == botmodule.name
- debug "Unmapping #{tmpl.inspect}"
- @templates[handle] = nil
- @templates.clear unless @templates.compact.size > 0
- end
-
- # We redefine the handle() method from MessageMapper, taking into account
- # that @parent is a bot, and that we don't handle fallbacks.
- #
- # On failure to dispatch anything, the method returns false. If dispatching
- # is successfull, the method returns a Hash.
- #
- # Presently, the hash returned on success has only one key, :return, whose
- # value is the actual return value of the successfull dispatch.
- #
- # TODO this same kind of mechanism could actually be used in MessageMapper
- # itself to be able to handle the case of multiple plugins having the same
- # 'first word' ...
- #
- #
- def handle(m)
- return false if @templates.empty?
- failures = []
- @templates.each do |tmpl|
- # Skip this element if it was unmapped
- next unless tmpl
- botmodule = @parent.plugins[tmpl.botmodule]
- options = tmpl.recognize(m)
- if options.kind_of? Failure
- failures << options
- else
- action = tmpl.options[:action]
- unless botmodule.respond_to?(action)
- failures << NoActionFailure.new(tmpl, m)
- next
- end
- auth = tmpl.options[:full_auth_path]
- debug "checking auth for #{auth}"
- # We check for private permission
- if m.bot.auth.permit?(m.source, auth, '?')
- debug "template match found and auth'd: #{action.inspect} #{options.inspect}"
- return :return => botmodule.send(action, m, options)
- end
- debug "auth failed for #{auth}"
- # if it's just an auth failure but otherwise the match is good,
- # don't try any more handlers
- return false
- end
- end
- failures.each {|r|
- debug "#{r.template.inspect} => #{r}"
- }
- debug "no handler found"
- return false
- end
-
- end
-
- # The Irc::Bot::RemoteObject class represents and object that will take care
- # of interfacing with remote clients
- #
- # Example client session:
- #
- # require 'drb'
- # rbot = DRbObject.new_with_uri('druby://localhost:7268')
- # id = rbot.delegate(nil, 'remote login someuser somepass')[:return]
- # rbot.delegate(id, 'some secret command')
- #
- # Of course, the remote login is only neede for commands which may not be available
- # to everyone
- #
- class RemoteObject
-
- # We don't want this object to be copied clientside, so we make it undumpable
- include DRbUndumped
-
- # Initialization is simple
- def initialize(bot)
- @bot = bot
- end
-
- # The delegate method. This is the main method used by remote clients to send
- # commands to the bot. Most of the time, the method will be called with only
- # two parameters (session id and a String), but we allow more parameters
- # for future expansions.
- #
- # The session_id can be nil, meaning that the remote client wants to work as
- # an anoynomus botuser.
- #
- def delegate(session_id, *pars)
- warn "Ignoring extra parameters" if pars.length > 1
- cmd = pars.first
- client = @bot.auth.remote_user(session_id)
- raise "No such session id #{session_id}" unless client
- debug "Trying to dispatch command #{cmd.inspect} from #{client.inspect} authorized by #{session_id.inspect}"
- m = RemoteMessage.new(@bot, client, cmd)
- @bot.remote_dispatcher.handle(m)
- end
-
- private :instance_variables, :instance_variable_get, :instance_variable_set
- end
-
- # The bot also manages a single (for the moment) remote dispatcher. This method
- # makes it accessible to the outside world, creating it if necessary.
- #
- def remote_dispatcher
- if defined? @remote_dispatcher
- @remote_dispatcher
- else
- @remote_dispatcher = RemoteDispatcher.new(self)
- end
- end
-
- # The bot also manages a single (for the moment) remote object. This method
- # makes it accessible to the outside world, creating it if necessary.
- #
- def remote_object
- if defined? @remote_object
- @remote_object
- else
- @remote_object = RemoteObject.new(self)
- end
- end
-
- module Plugins
-
- # We create a new Ruby module that can be included by BotModules that want to
- # provide remote interfaces
- #
- module RemoteBotModule
-
- # The remote_map acts just like the BotModule#map method, except that
- # the map is registered to the @bot's remote_dispatcher. Also, the remote map handle
- # is handled for the cleanup management
- #
- def remote_map(*args)
- @remote_maps = Array.new unless defined? @remote_maps
- @remote_maps << @bot.remote_dispatcher.map(self, *args)
- end
-
- # Unregister the remote maps.
- #
- def remote_cleanup
- return unless defined? @remote_maps
- @remote_maps.each { |h|
- @bot.remote_dispatcher.unmap(self, h)
- }
- @remote_maps.clear
- end
-
- # Redefine the default cleanup method.
- #
- def cleanup
- super
- remote_cleanup
- end
- end
-
- # And just because I like consistency:
- #
- module RemoteCoreBotModule
- include RemoteBotModule
- end
-
- module RemotePlugin
- include RemoteBotModule
- end
-
- end
-
-end
-end
-
-class RemoteModule < CoreBotModule
-
- include RemoteCoreBotModule
-
- Config.register Config::BooleanValue.new('remote.autostart',
- :default => false,
- :requires_rescan => true,
- :desc => "Whether the remote service provider should be started automatically")
-
- Config.register Config::IntegerValue.new('remote.port',
- :default => 7268, # that's 'rbot'
- :requires_rescan => true,
- :desc => "Port on which the remote interface will be presented")
-
- Config.register Config::StringValue.new('remote.host',
- :default => '127.0.0.1',
- :requires_rescan => true,
- :desc => "Host on which the remote interface will be presented")
-
- def initialize
- super
- @port = @bot.config['remote.port']
- @host = @bot.config['remote.host']
- @drb = nil
- begin
- start_service if @bot.config['remote.autostart']
- rescue => e
- error "couldn't start remote service provider: #{e.inspect}"
- end
- end
-
- def start_service
- raise "Remote service provider already running" if @drb
- @drb = DRb.start_service("druby://#{@host}:#{@port}", @bot.remote_object)
- end
-
- def stop_service
- @drb.stop_service if @drb
- @drb = nil
- end
-
- def cleanup
- stop_service
- super
- end
-
- def handle_start(m, params)
- if @drb
- rep = "remote service provider already running"
- rep << " on port #{@port}" if m.private?
- else
- begin
- start_service(@port)
- rep = "remote service provider started"
- rep << " on port #{@port}" if m.private?
- rescue
- rep = "couldn't start remote service provider"
- end
- end
- m.reply rep
- end
-
- def remote_test(m, params)
- @bot.say params[:channel], "This is a remote test"
- end
-
- def remote_login(m, params)
- id = @bot.auth.remote_login(params[:botuser], params[:password])
- raise "login failed" unless id
- return id
- end
-
-end
-
-remote = RemoteModule.new
-
-remote.map "remote start",
- :action => 'handle_start',
- :auth_path => ':manage:'
-
-remote.map "remote stop",
- :action => 'handle_stop',
- :auth_path => ':manage:'
-
-remote.default_auth('*', false)
-
-remote.remote_map "remote test :channel",
- :action => 'remote_test'
-
-remote.remote_map "remote login :botuser :password",
- :action => 'remote_login'
-
-remote.default_auth('login', true)
diff --git a/man/rbot-remote.xml b/man/rbot-remote.xml
deleted file mode 100644
index b68b4ef0..00000000
--- a/man/rbot-remote.xml
+++ /dev/null
@@ -1,217 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
-
-<!--
-
-Process this file with an XSLT processor: `xsltproc \
--''-nonet /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
-manpages/docbook.xsl manpage.dbk'. A manual page
-<package>.<section> will be generated. You may view the
-manual page with: nroff -man <package>.<section> | less'. A
-typical entry in a Makefile or Makefile.am is:
-
-DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
-manpages/docbook.xsl
-XP=xsltproc -''-nonet
-
-manpage.1: manpage.dbk
- $(XP) $(DB2MAN) $<
-
-The xsltproc binary is found in the xsltproc package. The
-XSL files are in docbook-xsl. Please remember that if you
-create the nroff version in one of the debian/rules file
-targets (such as build), you will need to include xsltproc
-and docbook-xsl in your Build-Depends control field.
-
--->
-
- <!-- Fill in your name for FIRSTNAME and SURNAME. -->
- <!ENTITY dhfirstname "<firstname>Marc</firstname>">
- <!ENTITY dhsurname "<surname>Dequènes</surname>">
- <!ENTITY gbgname "<firstname>Giuseppe</firstname>">
- <!ENTITY gbfname "<surname>Bilotta</surname>">
- <!-- Please adjust the date whenever revising the manpage. -->
- <!ENTITY dhdate "<date>20100701</date>">
- <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
- allowed: see man(7), man(1). -->
- <!ENTITY dhsection "<manvolnum>1</manvolnum>">
- <!ENTITY dhemail "<email>Duck@DuckCorp.org</email>">
- <!ENTITY gbemail "<email>giuseppe.bilotta@gmail.com</email>">
- <!ENTITY dhusername "Marc Dequènes (Duck)">
- <!ENTITY gbusername "Giuseppe Bilotta">
- <!ENTITY dhucapp "<refentrytitle>RBOT-REMOTE</refentrytitle>">
- <!ENTITY dhapp "rbot-remote">
- <!ENTITY dhpackage "rbot">
- <!ENTITY dhpackageversion "0.9.15">
-
- <!ENTITY debian "<productname>Debian</productname>">
- <!ENTITY gnu "<acronym>GNU</acronym>">
- <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
-]>
-
-<refentry id="&dhapp;.1">
-
- <refentryinfo>
- <productname>&dhapp;</productname>
- <authorgroup>
- <author>
- &dhfirstname;
- &dhsurname;
- &dhemail;
- <contrib>&debian; package maintainer</contrib>
- </author>
- <author>
- &gbgname;
- &gbfname;
- &gbemail;
- <contrib>&dhapp; maintainer</contrib>
- </author>
- </authorgroup>
- <copyright>
- <year>2004-2009</year>
- <holder>&dhusername;</holder>
- </copyright>
- <copyright>
- <year>2010</year>
- <holder>&gbusername;</holder>
- </copyright>
- &dhdate;
- </refentryinfo>
-
- <refmeta>
- &dhucapp;
- &dhsection;
- <refmiscinfo class="manual">&dhapp; man page</refmiscinfo>
- <refmiscinfo class="source">&dhpackage;</refmiscinfo>
- <refmiscinfo class="version">&dhpackageversion;</refmiscinfo>
- </refmeta>
-
- <refnamediv>
- <refname>&dhapp;</refname>
-
- <refpurpose>IRC bot written in ruby</refpurpose>
- </refnamediv>
-
- <refsynopsisdiv>
- <cmdsynopsis>
- <command>&dhapp;</command>
-
- <group choice="req">
- <group choice="req">
- <arg><option>-u USER</option></arg>
- <arg><option>--user USER</option></arg>
- </group>
- <group choice="req">
- <arg><option>-p PASSWORD</option></arg>
- <arg><option>--password PASSWORD</option></arg>
- </group>
- </group>
- <group choice="opt">
- <group choice="req">
- <arg><option>-d DEST</option></arg>
- <arg><option>--destination DEST</option></arg>
- </group>
- <group choice="req">
- <arg><option>-r DRB_URI</option></arg>
- <arg><option>--uri DRB_URI</option></arg>
- </group>
- <group choice="req">
- <arg><option>-h</option></arg>
- <arg><option>--help</option></arg>
- </group>
- <group choice="req">
- <arg><option>-a</option></arg>
- <arg><option>--about</option></arg>
- </group>
- </group>
-
- </cmdsynopsis>
- </refsynopsisdiv>
- <refsect1>
- <title>DESCRIPTION</title>
-
- <para><command>&dhapp;</command> is a proof-of-concept example for
- rbot druby-based api. This program reads lines of text from the standard
- input and sends them to a specified irc channel or user via rbot.
- </para>
-
- <para>Make sure you have the remotectl plugin loaded and assigned the needed
- rights to the user before use.
- </para>
-
- </refsect1>
- <refsect1>
- <title>OPTIONS</title>
-
- <para>This program follow the usual &gnu; command line syntax,
- with long options starting with two dashes (`-'). A summary of
- options is included below.</para>
-
- <variablelist>
- <varlistentry>
- <term><option>-u <parameter>USER</parameter></option></term>
- <term><option>--user <parameter>USER</parameter></option></term>
- <listitem>
- <para>Remote user.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-p <parameter>PASSWORD</parameter></option></term>
- <term><option>--password <parameter>PASSWORD</parameter></option></term>
- <listitem>
- <para>Remote user password.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-d <parameter>DEST</parameter></option></term>
- <term><option>--destination <parameter>DEST</parameter></option></term>
- <listitem>
- <para>Destination for message (user or channel).</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-r <parameter>DRB_URI</parameter></option></term>
- <term><option>--uri <parameter>DRB_URI</parameter></option></term>
- <listitem>
- <para>Rbot url.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-h</option></term>
- <term><option>--help</option></term>
- <listitem>
- <para>Show summary of options.</para>
- </listitem>
- </varlistentry>
-
- <varlistentry>
- <term><option>-a</option></term>
- <term><option>--about</option></term>
- <listitem>
- <para>Tell what it's all about.</para>
- </listitem>
- </varlistentry>
- </variablelist>
- </refsect1>
- <refsect1>
- <title>VERSION</title>
-
- <para>This manual page was written by &dhusername; &dhemail; for
- the &debian; system (but may be used by others). Permission is
- granted to copy, distribute and/or modify this document under
- the terms of the &gnu; General Public License, Version 3 or
- any later version published by the Free Software Foundation.
- </para>
- <para>
- On Debian systems, the complete text of the GNU General Public
- License can be found in /usr/share/common-licenses/GPL.
- </para>
-
- </refsect1>
-</refentry>
-
diff --git a/rbot.gemspec b/rbot.gemspec
index 5d563b53..29d88c1f 100644
--- a/rbot.gemspec
+++ b/rbot.gemspec
@@ -7,7 +7,7 @@ Gem::Specification.new do |s|
s.description = <<-EOF
A modular ruby IRC bot specifically designed for ease of extension via plugins.
EOF
- s.requirements << 'Ruby, version 1.8.0 (or newer)'
+ s.requirements << 'Ruby, version 1.9.3 (or newer)'
s.files = FileList[
'lib/**/*.rb',
@@ -24,7 +24,6 @@ Gem::Specification.new do |s|
'INSTALL',
'Usage_en.txt',
'man/rbot.1',
- 'man/rbot-remote.1',
'setup.rb',
'launch_here.rb',
'po/*.pot',
@@ -32,7 +31,7 @@ Gem::Specification.new do |s|
]
s.bindir = 'bin'
- s.executables = ['rbot', 'rbot-remote']
+ s.executables = ['rbot', 'rbotdb']
s.default_executable = 'rbot'
s.extensions = 'Rakefile'