From 762f732c33432c9a6f488dd5618e19b26fe47609 Mon Sep 17 00:00:00 2001 From: piernov Date: Thu, 2 Jun 2011 15:08:03 +0200 Subject: Réécrit entièrement. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LISEZMOI | 28 ++++--- config.xml | 25 ++++++ modules/aide.rb | 6 ++ modules/bdg.rb | 35 ++++++++ modules/date.rb | 6 ++ modules/google.rb | 20 +++++ modules/ping.rb | 6 ++ modules/pjp.rb | 28 +++++++ modules/ports.rb | 60 ++++++++++++++ modules/ports/drivers/git | 28 +++++++ modules/ports/drivers/hg | 27 +++++++ modules/ports/drivers/httpup | 27 +++++++ modules/ports/drivers/rsync | 143 ++++++++++++++++++++++++++++++++ modules/ports/ports | 188 +++++++++++++++++++++++++++++++++++++++++++ modules/ports/recipes.git | 2 + modules/version.rb | 6 ++ modules/vote.rb | 89 ++++++++++++++++++++ modules/wikipedia.rb | 23 ++++++ rbjbbot.rb | 158 +++++++++++++++++++++++++++--------- rbjbbot.sh | 3 +- vote.json | 11 +++ 21 files changed, 868 insertions(+), 51 deletions(-) create mode 100644 config.xml create mode 100644 modules/aide.rb create mode 100644 modules/bdg.rb create mode 100644 modules/date.rb create mode 100644 modules/google.rb create mode 100644 modules/ping.rb create mode 100644 modules/pjp.rb create mode 100644 modules/ports.rb create mode 100755 modules/ports/drivers/git create mode 100755 modules/ports/drivers/hg create mode 100755 modules/ports/drivers/httpup create mode 100755 modules/ports/drivers/rsync create mode 100755 modules/ports/ports create mode 100644 modules/ports/recipes.git create mode 100644 modules/version.rb create mode 100644 modules/vote.rb create mode 100644 modules/wikipedia.rb create mode 100644 vote.json diff --git a/LISEZMOI b/LISEZMOI index 7aa1e22..c8e6baa 100644 --- a/LISEZMOI +++ b/LISEZMOI @@ -1,15 +1,19 @@ -rbjbbot est un bot Jabber simple en Ruby. +RbJbBot est un bot Jabber simpliste et modulaire en Ruby. -Dépendances : - - Ruby - - RubyGems - - XMPP4R - - dtach +== Dépendances == + - Ruby + - RubyGems + → XMPP4R + → XML-Simple + → JSON (optionnel, pour "vote") + → DBI / DBD-MySQL (optionnel, pour "bdg") + → htmlentities (optionnel, pour "bdg" et "pjp") + - dtach (optionnel, pour détacher le processus Ruby) -Configurez le bot en remplissant les champs approprié dans rbjbbot.rb -Pour le lancer, il vous suffit de lancer rbjbbot.sh. -Vous devez vous trouvez dans le même répertoire que rbjbbot.rb. -Pour le passer en tache de fond, appuyez sur les touches Ctrl + G. -Pour le remettre au premier plan, réexécutez rbjbbot.sh. -Si vous ne voulez pas utiliser dtach, lancez tout simplement rbjbbot.rb. +== Configuration == + Remplissez les champs dans config.xml +== Lancement == + Déplacez vous dans le répertoire de RbJbBot puis exécutez rbjbbot.sh. + Pour le passer en tache de fond, appuyez sur les touches Ctrl + G. + Pour le remettre au premier plan, réexécutez rbjbbot.sh. diff --git a/config.xml b/config.xml new file mode 100644 index 0000000..847906f --- /dev/null +++ b/config.xml @@ -0,0 +1,25 @@ + + + + RubyJabberBot + 0.2.99 + Linux + Net/HTTP RubyJabberBot (Linux x86; fr; 0.2.99) + RubyJabberBot + + + + + + ping + version + google + wikipedia + vote + date + ports + aide + pjp + bdg + + diff --git a/modules/aide.rb b/modules/aide.rb new file mode 100644 index 0000000..17c4e16 --- /dev/null +++ b/modules/aide.rb @@ -0,0 +1,6 @@ +def module_aide(msg_body, sender_nick, config) + if msg_body =~ /^!aide/ + answer = sender_nick + ', commandes valides : "!ping", "!aide", "!date", "!google", "!wiki", "!ports", "!vote", "!version", "!pirate", "!bdg".' + return answer + end +end \ No newline at end of file diff --git a/modules/bdg.rb b/modules/bdg.rb new file mode 100644 index 0000000..5acd832 --- /dev/null +++ b/modules/bdg.rb @@ -0,0 +1,35 @@ +def module_bdg(msg_body, sender_nick, config) + + require 'dbi' + require 'htmlentities' + require 'iconv' + + @mysql_config = { "host" => "localhost", + "db" => "bdg", + "user" => "bdg_ro", + "passwd" => "vinblanc_ro" + } + + def bdg(bdg_number) + begin + db = DBI.connect("DBI:Mysql:" + @mysql_config["db"] + ":" + @mysql_config["host"], @mysql_config["user"], @mysql_config["passwd"]) + st = db.execute('select id,titre,blague,auteur,date_post from blague where id=' + bdg_number) + row = st.fetch + answer = "\##{row[0]} - #{row[1]} \n #{row[2]} \n par #{row[3]} le #{row[4]} " + answer = HTMLEntities.new.decode(answer) + answer = Iconv.new('utf-8', 'iso-8859-1').iconv(answer) + return answer + rescue + answer = "BDG introuvable" + return answer + end + end + + if msg_body =~ /^!bdg(\s|)\d+$/ + answer = bdg(msg_body.gsub(/!bdg(\s|)/, '')) + return answer + elsif msg_body =~ /^!bdg+/ + answer = "Veuillez entrer un numéro de BDG." + return answer + end +end diff --git a/modules/date.rb b/modules/date.rb new file mode 100644 index 0000000..44c8ff9 --- /dev/null +++ b/modules/date.rb @@ -0,0 +1,6 @@ +def module_date(msg_body, sender_nick, config) + if msg_body =~ /^!date/ + answer = `date "+%A %-d %B %Y à %HH %Mm %Ss et %Nns"`.chomp.capitalize + return answer + end +end \ No newline at end of file diff --git a/modules/google.rb b/modules/google.rb new file mode 100644 index 0000000..2dff668 --- /dev/null +++ b/modules/google.rb @@ -0,0 +1,20 @@ +def module_google(msg_body, sender_nick, config) + def google(phrase) + response = Net::HTTP::get_response('www.google.fr', "/m/search?hl=fr&q=#{CGI::escape(phrase)}") + result = [] + html = Iconv.new('utf-8', 'utf-8').iconv(response.body) + html.scan(/(.+?)<\/a> <\/div>/) { |useless,url,title| + result.push("#{CGI::escapeHTML(title)}") + } + result + end + + if msg_body == "!google" + answer = "Veuillez entrer une recherche à effectuer." + return answer + elsif msg_body =~ /^!google+/ + searchresult = google(msg_body.gsub("!google ","")) + answer = searchresult[0..2].join("\n") + return answer + end +end \ No newline at end of file diff --git a/modules/ping.rb b/modules/ping.rb new file mode 100644 index 0000000..9069de1 --- /dev/null +++ b/modules/ping.rb @@ -0,0 +1,6 @@ +def module_ping(msg_body, sender_nick, config) + if msg_body =~ /^!.+ing/ + answer = sender_nick + ", " + msg_body.gsub("ing","ong") + "." + return answer + end +end \ No newline at end of file diff --git a/modules/pjp.rb b/modules/pjp.rb new file mode 100644 index 0000000..ce2276f --- /dev/null +++ b/modules/pjp.rb @@ -0,0 +1,28 @@ +def module_pjp(msg_body, sender_nick, config) + + require 'rubygems' + require 'net/http' + require 'cgi' + require 'iconv' + require 'open-uri' + require 'htmlentities' + + def pjp(pjp_number) + if pjp_number =~ /^\d/ + response = Net::HTTP::get_response('pourquoijepirate.fr', "/index.php?id=#{pjp_number}") + else + response = Net::HTTP::get_response('pourquoijepirate.fr', "/index.php") + end + html = response.body + html.scan(/
(.+?)

/m) { |content| + if content != "" + return HTMLEntities.new.decode(content) + end + } + end + + if msg_body =~ /^!pirate/ + answer = "Pourquoi je pirate ?" + pjp(msg_body.gsub(/!pirate(\s|)/, '')) + return answer + end +end \ No newline at end of file diff --git a/modules/ports.rb b/modules/ports.rb new file mode 100644 index 0000000..34c1edc --- /dev/null +++ b/modules/ports.rb @@ -0,0 +1,60 @@ +def module_ports(msg_body, sender_nick, config) + def ports(cmd) + case cmd + when /^maj(|\s)$/ + answer= 'Usage: "!ports maj all" ; "!ports maj (repo)' + when /^maj/ + if cmd =~ /^maj all(|\s)$/ + answer= `cd modules/ports && ./ports -u`.chomp + else + repo=cmd.gsub("maj","") + answer= `cd modules/ports && ./ports -u #{repo}`.chomp + end + when /^query(|\s)$/ + answer='Usage: "!ports query (search string)"' + when /^query\s[a-z0-9_-]*$/i + package=cmd.gsub(/^query\s/,"") + repo=[] + for driver in `ls modules/ports/drivers/` + suffix=`basename #{driver}` + for file in `ls modules/ports/*.#{suffix}`.chomp + repo << `basename #{file} .#{suffix}`.chomp + end + end + pkg={} + for cur_repo in repo + pkg[cur_repo] = Array.new() + for port in `find modules/ports/#{cur_repo} -maxdepth 1 -name "*#{package}*"`.chomp + begin + name = `basename #{port}`.chomp + pkgfile=`cat modules/ports/#{repo}/#{name}/Pkgfile` + pkg[cur_repo] << {"name" => name, + "version" => pkgfile.grep(/version=/)[0].gsub("version=","").chomp, + "release" => pkgfile.grep(/release=/)[0].gsub("release=","").chomp, + "packager" => pkgfile.grep(/packager=/)[0].gsub("packager=","").chomp, + "maintainer" => pkgfile.grep(/maintainer=/)[0].gsub("maintainer=","").chomp + } + rescue + end + end + end + list_port="" + list_repo="" + for repo in pkg + for port in repo[1] + list_port="Name: #{port['name']} | Version: #{port['version']} | Release: #{port['release']} | Packager: #{port['packager']} | Maintainer: #{port['maintainer']}" + "\n" + list_port + end + list_repo= "Dans " + repo[0] + " => " + list_port.chomp + "\n" + list_repo + end + return list_repo.chomp + end + return answer + end + + if msg_body =~ /^!ports (maj|query)/ + answer = ports(msg_body.gsub("!ports ","")) + return answer + elsif /^!ports/ + answer = '"!ports maj" ; "!ports query"' + end +end diff --git a/modules/ports/drivers/git b/modules/ports/drivers/git new file mode 100755 index 0000000..e4b301b --- /dev/null +++ b/modules/ports/drivers/git @@ -0,0 +1,28 @@ +#!/bin/sh +# +# /etc/ports/drivers/git: git driver script for ports(8) +# + +if [ $# -ne 1 ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +. $1 + +if [ -z "$ROOT_DIR" ]; then + echo "ROOT_DIR not set in '$1'" >&2 + exit 2 +fi +if [ -z "$URL" ]; then + echo "URL not set in '$1'" >&2 + exit 2 +fi + +if [ -d $ROOT_DIR ]; then + cd $ROOT_DIR + git pull +else + git clone $URL $ROOT_DIR +fi +# End of file. diff --git a/modules/ports/drivers/hg b/modules/ports/drivers/hg new file mode 100755 index 0000000..776cb89 --- /dev/null +++ b/modules/ports/drivers/hg @@ -0,0 +1,27 @@ +#!/bin/sh +# +# /etc/ports/drivers/hg: mercurial driver script for ports(8) +# + +if [ $# -ne 1 ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +. $1 + +if [ -z "$ROOT_DIR" ]; then + echo "ROOT_DIR not set in '$1'" >&2 + exit 2 +fi +if [ -z "$URL" ]; then + echo "URL not set in '$1'" >&2 + exit 2 +fi + +for REPO in $URL; do + PORT=`echo $REPO | sed -n '/#.*$/s|^.*#||p'` + hg -v clone $REPO $ROOT_DIR/$PORT +done + +# End of file. diff --git a/modules/ports/drivers/httpup b/modules/ports/drivers/httpup new file mode 100755 index 0000000..5c8db84 --- /dev/null +++ b/modules/ports/drivers/httpup @@ -0,0 +1,27 @@ +#!/bin/sh +# +# /etc/ports/drivers/httpup: httpup driver script for ports(8) +# + +if [ $# -ne 1 ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +. $1 + +if [ -z "$ROOT_DIR" ]; then + echo "ROOT_DIR not set in '$1'" >&2 + exit 2 +fi +if [ -z "$URL" ]; then + echo "URL not set in '$1'" >&2 + exit 2 +fi + +for REPO in $URL; do + PORT=`echo $REPO | sed -n '/#.*$/s|^.*#||p'` + httpup sync $REPO $ROOT_DIR/$PORT +done + +# End of file. diff --git a/modules/ports/drivers/rsync b/modules/ports/drivers/rsync new file mode 100755 index 0000000..0908632 --- /dev/null +++ b/modules/ports/drivers/rsync @@ -0,0 +1,143 @@ +#!/usr/bin/perl +# +# /etc/ports/drivers/rsync: rsync(1) driver script for ports(8) +# + +use warnings; +use strict; +use File::Basename; + +my $host = ''; +my $collection = ''; +my $destination = ''; +my %new_checkouts; +my %old_checkouts; + +sub error +{ + my $message = shift; + print "Error: $message ($!)\nUpdating failed\n"; + exit 1; +} + +sub warning +{ + my $message = shift; + print "Warning: $message ($!)\n"; +} + +if ($#ARGV < 0) +{ + print "Usage: $0 \n"; + exit 1; +} + +open(FILE, $ARGV[0]) or error("Couldn't open $ARGV[0]"); +while () +{ + chomp; + if (/^host=(.*)/) { $host = $1; } + elsif (/^collection=(.*)/) { $collection = $1; } + elsif (/^destination=(.*)/) { $destination = $1; } +} +close(FILE); + +if ($host eq '') { error("Host field not set in $ARGV[0]"); } +if ($collection eq '') { error("Collection field not set in $ARGV[0]"); } +if ($destination eq '') { error("Destination field not set in $ARGV[0]"); } + +if (-e "$destination/.checkouts") +{ + # read the old .checkouts file into memory + open(FILE, "$destination/.checkouts") or error("Couldn't read checkouts from $destination/.checkouts"); + while () + { + chomp; + $old_checkouts{$_} = 1; + } + close(FILE); +} + +print "Updating file list from " . $host . "::$collection\n"; + +# get the remote file list (new .checkouts) +open(PIPE, 'rsync -crz rsync://' . $host . '/' . $collection . '|') or error("Couldn't open pipe to rsync"); +while () +{ + chomp; + + next if /^MOTD:/; # ignore MOTD lines + s/^(.{43})//; # ignore the first 43 characters (mode, date etc...) + next if /^.$/; # ignore the . directory + + $new_checkouts{$_} = 1; +} +close(PIPE); +error("Running rsync failed") unless $? == 0; + +print "Updating collection " . basename($destination) . "\n"; + +# now really run rsync +open(PIPE, 'rsync -crz --exclude=.footprint.x86_64 --exclude=.md5sum.x86_64 --log-format "%o %n" rsync://' . $host . "/$collection $destination|") or error("Couldn't open pipe to rsync"); +while () +{ + chomp; + + if (/^recv (.*)/) + { + if ($old_checkouts{$1}) + { + s/^recv/ Edit/; + } + else + { + s/^recv/ Checkout/; + } + } + + print $_ . "\n"; +} +close(PIPE); +error("Running rsync failed") unless $? == 0; + +# save new checkouts into .checkouts +open(FILE, ">$destination/.checkouts") or error("Couldn't save checkouts to $destination/.checkouts"); +foreach my $checkout (sort keys %new_checkouts) +{ + print FILE "$checkout\n"; +} +close(FILE); + +# use chroot as an additional safety measure when removing files +chroot($destination) or error("Couldn't chroot into $destination"); +chdir('/'); + +# iterate through old checkouts, remove obsolete files +foreach my $checkout (sort keys %old_checkouts) +{ + if (!$new_checkouts{$checkout}) + { + if (-f $checkout) + { + print " Delete $checkout\n"; + unlink($checkout) or warning("Couldn't delete $checkout"); + } + } +} + +# iterate through old checkouts, remove obsolete directories +foreach my $checkout (sort keys %old_checkouts) +{ + if (!$new_checkouts{$checkout}) + { + if (-d $checkout) + { + print " Delete $checkout\n"; + rmdir($checkout) or warning("Couldn't delete $checkout"); + } + } +} + +print "Finished successfully\n"; + +# End of file diff --git a/modules/ports/ports b/modules/ports/ports new file mode 100755 index 0000000..ab44353 --- /dev/null +++ b/modules/ports/ports @@ -0,0 +1,188 @@ +#!/bin/bash +# +# ports +# +# Copyright (c) 2002-2004 Per Liden +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. +# + +VERSION="1.9-rbjbbot" +PORTS_DIR="./" + +check_ports_dir() { + if [ ! -d "$PORTS_DIR" ]; then + echo "$COMMAND: directory '$PORTS_DIR' not found" + exit 1 + fi +} + +update_ports() { + #if [ "`id -u`" != "0" ]; then + #echo "$COMMAND: only root can update ports" + #exit 1 + #fi + + shopt -s nullglob + export PORTS_DIR + + if [ "$OPT_COLLECTIONS" ]; then + # Update selected collections + for collection in $OPT_COLLECTIONS; do + collection_exists=no + for file in ./$collection.*; do + collection_exists=yes + done + if [ "$collection_exists" = "yes" ]; then + for driver in ./drivers/*; do + if [ -x $driver ]; then + suffix=`basename $driver` + file=./$collection.$suffix + if [ -f $file ]; then + $driver $file + fi + fi + done + else + echo "$COMMAND: collection '$collection' not found" + fi + done + else + # Update all collections + for driver in ./drivers/*; do + if [ -x $driver ]; then + suffix=`basename $driver` + for file in ./*.$suffix; do + $driver $file + done + fi + done + + if [ ! "$driver" ]; then + echo "$COMMAND: no driver(s) installed" + fi + fi +} + +list_ports() { + cd $PORTS_DIR && find . -name Pkgfile -follow -printf "%h\n" | sed 's|^./||g' | sort +} + +list_differences_at_exit() { + rm $installed_list $ports_list $output $output_sorted &> /dev/null +} + +list_differences() { + installed_list=`mktemp` || exit 1 + ports_list=`mktemp` || exit 1 + output=`mktemp` || exit 1 + output_sorted=`mktemp` || exit 1 + found_diff="no" + + trap list_differences_at_exit EXIT + + pkginfo -i >> $installed_list + ports -l >> $ports_list + + for package in `cat $installed_list | gawk '{ print $1 }'`; do + installed_version=`cat $installed_list | grep "^$package " | gawk '{ print $2 }'` + port_list=`cat $ports_list | grep "/$package\$"` + for port in $port_list; do + port_version=`cd $PORTS_DIR/$port; . Pkgfile; echo $version-$release` + if [ "$installed_version" != "$port_version" ]; then + echo "${port%/*} $package $port_version $installed_version" >> $output + found_diff="yes" + fi + done + done + + if [ "$found_diff" = "yes" ]; then + echo "Collection Name Port Installed" >> $output_sorted + sort $output >> $output_sorted + column -t $output_sorted + else + echo "No differences found" + fi +} + +print_try_help() { + echo "Try '$COMMAND --help' for more information." +} + +print_help() { + echo "usage: $COMMAND [options] [collection ...]" + echo "options:" + echo " -u, --update update ports" + echo " -l, --list list ports" + echo " -d, --diff list version differences" + echo " -v, --version print version and exit" + echo " -h, --help print help and exit" +} + +parse_options() { + OPT_MODE="" + OPT_COLLECTIONS="" + + for OPT in "$@"; do + case $OPT in + -u|--update) + OPT_MODE="update" ;; + -l|--list) + OPT_MODE="list" ;; + -d|--diff) + OPT_MODE="diff" ;; + -v|--version) + echo "$COMMAND $VERSION" + exit 0 ;; + -h|--help) + print_help + exit 0 ;; + -*) + echo "$COMMAND: invalid option $OPT" + print_try_help + exit 1 ;; + *) + OPT_COLLECTIONS="$OPT_COLLECTIONS $OPT" ;; + esac + done +} + +main() { + parse_options "$@" + + if [ "$OPT_MODE" = "update" ]; then + check_ports_dir + update_ports + elif [ "$OPT_MODE" = "list" ]; then + check_ports_dir + list_ports + elif [ "$OPT_MODE" = "diff" ]; then + check_ports_dir + list_differences + else + echo "$COMMAND: option missing" + print_try_help + exit 1 + fi + + exit 0 +} + +COMMAND=`basename $0` + +main "$@" + +# End of file diff --git a/modules/ports/recipes.git b/modules/ports/recipes.git new file mode 100644 index 0000000..2f9bf42 --- /dev/null +++ b/modules/ports/recipes.git @@ -0,0 +1,2 @@ +ROOT_DIR=./recipes +URL=git://upyum.com/recipes.git diff --git a/modules/version.rb b/modules/version.rb new file mode 100644 index 0000000..9ef8908 --- /dev/null +++ b/modules/version.rb @@ -0,0 +1,6 @@ +def module_version(msg_body, sender_nick, config) + if msg_body =~ /^!version/ + answer = "#{config['bot'][0]['NAME'][0]} #{config['bot'][0]['VERSION'][0]} -> #{config['bot'][0]['DISTRIB'][0]}" + return answer + end +end \ No newline at end of file diff --git a/modules/vote.rb b/modules/vote.rb new file mode 100644 index 0000000..169ad20 --- /dev/null +++ b/modules/vote.rb @@ -0,0 +1,89 @@ +def module_vote(msg_body, sender_nick, config) + def vote(cmd,sender_nick) + def vote_commit(current_vote) + vote_db = File.open("vote.json", "w") + vote_json = JSON.pretty_generate(current_vote) + vote_db.write(vote_json) + vote_db.close + end + vote_db_file = File.open("vote.json", "r") + vote_db_text = "" + vote_db_file.each { |line| vote_db_text = "#{vote_db_text}\n#{line}" } + p vote_db_text + @vote = JSON.parse(vote_db_text) + vote_db_file.close + case cmd + when "" + answer = "'!vote #n [titre]' pour ajouter un vote, '!vote #[numéro]' pour afficher un vote." + when /^#\d+ (pour|contre|blanc)$/i + number = cmd.gsub(/\s(pour|contre|blanc)$/i,"").gsub("#","").to_i + vote_type = cmd.scan(/^#\d (.+?)$/)[0][0] + if @vote[number]['voté'][sender_nick] == nil + p cmd + p vote_type + @vote[number][vote_type] = @vote[number][vote_type] + 1 + @vote[number]['voté'][sender_nick] = vote_type + answer = "#{sender_nick} a voté #{vote_type}." + else + old_vote = @vote[number]['voté'][sender_nick] + p @vote[number] + p old_vote + p @vote[number]['voté'][sender_nick] + @vote[number][old_vote] = @vote[number][old_vote] -1 + @vote[number]['voté'][sender_nick] = vote_type + @vote[number][vote_type] = @vote[number][vote_type] +1 + answer = "#{sender_nick} a modifié son vote (#{old_vote}) en #{vote_type}." + end + vote_commit(@vote) + + when /^#\d+$/ + begin + number = cmd.gsub("#","").to_i + voted = "" + @vote[number]['voté'].keys.each do |nick| voted = "#{voted} #{nick}" end + voted = (voted != "" ? voted : "Personne") + answer = "Vote ##{number} par #{@vote[number]['auteur']} : #{@vote[number]['titre']} → Pour : #{@vote[number]['pour'].to_s}, Contre : #{@vote[number]['contre'].to_s}, Blanc : #{@vote[number]['blanc'].to_s}, Déjà voté : #{voted}" + rescue + answer = "Vote inexistant !" + end + + when /^#\d+ ràz$/i + number = cmd.gsub(/\sràz$/i,"").gsub("#","").to_i + if @vote[number] != nil + if @vote[number]['auteur'] == sender_nick + ["pour","contre","blanc"].each do |s| @vote[number][s] = 0 end + @vote[number]["voté"] = {} + answer = "Vote ##{number} : #{@vote[number]['titre']} → Remis à zéro" + else + answer = "L'auteur (#{@vote[number]['auteur']}) du vote #{number} ne correspond pas à vous !" + end + vote_commit(@vote) + else + answer = "Vote inexistant !" + end + + when /^#n (.+?)$/ + number = @vote.length + titre = cmd.scan(/^#n (.+?)$/)[0][0] + if @vote == nil + @vote = Array.new + end + @vote[number] = { + 'titre' => titre, + 'auteur' => sender_nick, + 'pour' => 0, + 'contre' => 0, + 'blanc' => 0, + 'voté' => { } + } + answer = "Vote ##{number.to_s} ajouté par #{@vote[number]['auteur']}: #{@vote[number]['titre']}" + vote_commit(@vote) + end + return answer + end + + if msg_body =~ /^!vote(\s|\s(.+?)|$)/ + answer = vote(msg_body.gsub(/^!vote(\s|)/,""),sender_nick) + return answer + end +end \ No newline at end of file diff --git a/modules/wikipedia.rb b/modules/wikipedia.rb new file mode 100644 index 0000000..68e7280 --- /dev/null +++ b/modules/wikipedia.rb @@ -0,0 +1,23 @@ +def module_wikipedia(msg_body, sender_nick, config) + def wikipedia(wikisearch, config) + http = Net::HTTP.new("fr.wikipedia.org", 80) + http.start do |http| + req = Net::HTTP::Get.new("/w/api.php?action=opensearch&limit=3&format=xml&search=#{CGI::escape(wikisearch)}", {"User-Agent" => config['bot'][0]['USERAGENT'][0]}) + $resp = http.request(req).body + end + data = XmlSimple.xml_in($resp, { 'KeyAttr' => 'name','ContentKey' => '-content'}) + unless data['Section'][0] == {} then + return data['Section'][0]['Item'][0]['Description'][0]['content'] + else + return "Aucun résultat, veuillez reformuler votre recherche" + end + end + + if msg_body == "!wiki" + answer = "Veuillez entrer une recherche à effectuer." + return answer + elsif msg_body =~ /^!wiki+/ + answer = wikipedia(msg_body.gsub("!wiki ",""), config).chomp + return answer + end +end diff --git a/rbjbbot.rb b/rbjbbot.rb index 05268cd..4aa848c 100755 --- a/rbjbbot.rb +++ b/rbjbbot.rb @@ -1,48 +1,130 @@ -#! /usr/bin/ruby +#!/usr/bin/env ruby require 'rubygems' require 'xmpp4r' -require 'xmpp4r/muc/helper/simplemucclient' +require 'xmpp4r/version' +require 'xmpp4r/muc' +require 'xmpp4r/delay/x/delay' +require 'xmpp4r/pubsub' +require 'xmpp4r/pubsub/helper/servicehelper.rb' +require 'xmpp4r/pubsub/helper/nodebrowser.rb' +require 'xmpp4r/pubsub/helper/nodehelper.rb' +require 'xmpp4r/muc/helper/mucbrowser' +require 'net/http' +require 'cgi' +require 'iconv' +require 'xmlsimple' +require 'open-uri' +require 'json' + include Jabber +Jabber::debug = true + + def count_users() + jid, password, muc_jid = Jabber::JID.new($botjid), $botpass, Jabber::JID.new($mucjid) + + cl = Jabber::Client.new(jid) + cl.connect + cl.auth(password) + + browser = Jabber::MUC::MUCBrowser.new(cl) + + print "Querying #{muc_jid} for identity..."; $stdout.flush + name = browser.muc_name(muc_jid) + + if name.nil? + puts " Sorry, but the queried MUC component doesn't seem to support MUC or Groupchat." + else + puts " #{name}" + + print "Querying #{muc_jid} for its rooms..."; $stdout.flush + rooms = browser.muc_rooms(muc_jid) + puts " #{rooms.size} rooms found" -############## Configuration du bot ################# - # -mucjid = "" # JID du salon où connecter le bot # -mucpass = "" # Mot de passe du salon # -botnick = "" # Pseudo du bot # -botjid = "" # JID du bot # -botpass = "" # Mot de passe du bot # - # -##################################################### + max_room_length = 0 + rooms.each_key { |jid| max_room_length = jid.to_s.size if jid.to_s.size > max_room_length } + rooms.each { |jid,name| + puts "#{jid.to_s.ljust(max_room_length)} #{name}" + } + end + return rooms.size + cl.close + end + def time(stan) + time = nil + stan.each_element('x') { |x| + if x.kind_of?(Delay::XDelay) + time = x.stamp + end + } + return time + end + + def send_response(answer,msg_body) + if answer != nil + response = Jabber::Message.new() + response.type = :chat + response.body = answer + if msg_body != nil + case msg_body + when /^!google+/ + response.add_element(prepare_html(response.body)) + responsenohtml = [] + response.body.scan(/(.+?)<\/a>/) { |url,title| + responsenohtml.push("#{title} -> #{url}") + } + response.body = responsenohtml.join("\n").gsub(/<.*?>/, '') + end + return response + end + end + end + + def prepare_html(text) + h = REXML::Element::new("html") + h.add_namespace('http://jabber.org/protocol/xhtml-im') + b = REXML::Element::new("body") + b.add_namespace('http://www.w3.org/1999/xhtml') + t = REXML::Text.new(text.gsub("\n","
"), false, nil, true, nil, %r/.^/ ) + b.add(t) + h.add(b) + h + end + + +class RbJbBot begin + config = XmlSimple.xml_in('config.xml', { 'KeyAttr' => 'name' }) + p config['bot'][0]['botjid'][0] + client = Jabber::Client.new(Jabber::JID.new("#{config['bot'][0]['botjid'][0]}/#{config['bot'][0]['botnick'][0]}")) + client.connect + client.auth(config['bot'][0]['botpass'][0]) + Jabber::Version::SimpleResponder.new(client, config['bot'][0]['NAME'][0], config['bot'][0]['VERSION'][0], config['bot'][0]['DISTRIB'][0]) + muc = Jabber::MUC::MUCClient.new(client) + muc.join(Jabber::JID.new(config['bot'][0]['mucjid'][0] + '/' + config['bot'][0]['botnick'][0]), config['bot'][0]['mucpass'][0]) + + module_list = config['bot'][0]['module'] + module_list.each do |mod| require "modules/#{mod}" end + -xmpp = Client.new(JID::new(botjid)) -xmpp.connect -xmpp.auth(botpass) - -muc = Jabber::MUC::SimpleMUCClient.new(xmpp) -muc.join(Jabber::JID.new(mucjid + '/' + botnick),mucpass) - loop do - muc.on_message { |time,nick,text| - if nick != botnick - case text - when "!ping" - msg = nick + ', pong.' - when "!aide" - msg = nick + ', commandes valides : "!ping", "!aide", "!kick" + pseudo à kicker.' - when "!kick moi" - muc.kick nick, 'Tu me le demande si gentiment :D' - when /!kick+/ - nickkick = text.gsub(/!kick /, "") - muc.kick nickkick, 'Demandé par ' + nick - when /Xtn-RubyBot+/ - msg = nick + ', je ne te comprends pas, écris "!aide" pour avoir une liste des commandes valides.' - end - muc.say(msg) - end - } - sleep 1 - end + muc.add_message_callback { |msg| + sender_nick = msg.from.resource + unless time(msg) + if sender_nick != $botnick + answer = nil + + module_list.each do |mod| answer_tmp = eval "module_#{mod}(msg.body, sender_nick, config)"; if answer_tmp != nil and answer != ""; answer=answer_tmp; end; end + + if answer != nil and answer != "" + muc.send(send_response(answer,msg.body)) + end + end + end + } end +RbJbBot.new +Thread.stop +client.close +end diff --git a/rbjbbot.sh b/rbjbbot.sh index 17c45e0..5f32d14 100755 --- a/rbjbbot.sh +++ b/rbjbbot.sh @@ -1 +1,2 @@ - dtach -A ./rbjbbot.dtach -e ^G ruby ./rbjbbot.rb +#!/bin/sh +exec dtach -A ./rbjbbot.dtach -e ^G ruby ./rbjbbot.rb diff --git a/vote.json b/vote.json new file mode 100644 index 0000000..3f51fdf --- /dev/null +++ b/vote.json @@ -0,0 +1,11 @@ +[ + { + "voté": { + }, + "auteur": "", + "blanc": 0, + "contre": 0, + "titre": "", + "pour": 0 + } +] -- cgit v1.2.3-54-g00ecf