Leyéndome los logs de las asambleas por irc se me ha ocurrido que el papel del
moderador es bastante fácil de suplir con un bot. Para lo que he escrito el bot
que va adjunto a este email.

El bot se encarga de recoger las peticiones de palabra (/me pide palabra) y
asignar palabras en orden esperando a que termine de hablar (indicado con un
".") el interlocutor. Ademas le he añadido, no se si de verdad es útil, la
opción de pedir frases, que te dan voz mas prioritaria, pero para decir un
único mensaje.

Sería fácil de adaptarlo para que quitara y diera voz a los que tienen la 
palabra, pero he pensado que mientras las asambleas no sean un caos con todo el
mundo teniendo voz es mejor que no lo haga.

Este bot solo se encarga del moderador, todavía sería necesario el dinamizador y
alguien que guarde el log. Pero si se le da uso lo puedo ampliar para que cumpla
alguna de estas funciones.

Perdonad los que sepáis de perl y os parezca guarro, llevo pocas horas de rodaje
en perl.


-- 
Rubén Pollán  | jabber:mes...@jabber.org
       http://vagamundo.cauterized.net/
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Lo hago para no volverme loco cuando noto
que solo me queda un demonio en un hombro
por que se ha cortado las venas
el ángel que había en el otro.
#!/usr/bin/perl
# Este es un Bot de IRC preparado para hacer de moderador en asambleas

use warnings;
use strict;
use POE;
use POE::Component::IRC;
use Getopt::Long;


# información de conexion
my $nickname = 'moderador';
my $username = 'moderador';
my $ircname  = 'El sumo moderador';
my $server   = 'irc.freenode.net';
my $port     = '6667';
my $channel  = '#hackmeeting';

# textos
my $welcome = "<</me pide la palabra>> para esperar turno para hablar
<</me pide frase>> para pedir frase
tu turno de palabra termina cuando escribes un mensaje con <<.>>
tu turno de frase te permite enviar un solo mensage, pero tienes prioridad.";
my $msg      = '';
my $help;

# orden de palabras y frases pedidas
my @palabras = ();
my @frases = ();
my $fue_frase = 2; # bool indica si la última peticion era frase, 2 indica que nadie esta hablando

# regexp de los comandos
my $palabra = '.*palabr.';
my $fin_escritura = '^\.$';
my $frase = '.*frase.*';


# parsear los parametros
usage() if ( ! GetOptions('help|h'      => \$help,
		                  'nick|n=s'    => \$nickname,
						  'user|u=s'    => \$username,
						  'irc|i=s'     => \$ircname,
						  'server|s=s'  => \$server,
						  'port|p=s'    => \$port,
						  'channel|c=s' => \$channel,
						  'msg|m=s'     => \$msg)
			or defined $help );
sub usage {
	print "usage: moderador [--nick|-n nickname] [--user|-u username] [--irc|-i ircname] [--server|-s server] [--port|-p port] [--channel|-c channel] [--msg|-m mensage] [--help|-h]\n";
	exit;
}

print "Iniciando conexión......\n";

# Crea el componente de IRC
my ($irc) = POE::Component::IRC->spawn();

# Crea la sesión, indicandole los eventos que queremos que atienda
POE::Session->create(
  inline_states => {
    _start     => \&bot_start,
    irc_001    => \&on_connect,
    irc_public => \&on_public,
	irc_join   => \&on_join,
	irc_nick   => \&on_nick,
	irc_part   => \&on_part,
	irc_quit   => \&on_part,
	irc_ctcp_action   => \&on_me,
  },
);


# Al iniciar la sesion, conectarse al servidor
sub bot_start {
  $irc->yield(register => "all");
  $irc->yield(
    connect => {
      Nick     => $nickname,
      Username => $username,
      Ircname  => $ircname,
      Server   => $server,
      Port     => $port,
    }
  );
  print "Conectado a: $server\n";
}

# Una vez este conectado al servidor conectarse al canal y enviar mensaje
sub on_connect {
	$irc->yield(join => $channel);

	envia_texto($channel, $welcome);
	if ($msg)
	{
		envia_texto($channel, $msg);
	}
	print "Conectado a: $channel\n";
}

# Interpretar los mensajes de los usuarios
sub on_public {
  my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2];
  my $nick    = (split /!/, $who)[0];

  if ($fue_frase == 1) {
	  if ($nick eq $frases[0]) {
		  shift(@frases);
		  asignar_voz();
	  }
  } elsif ($fue_frase == 0) {
	  if (($msg =~ /$fin_escritura/) and ($nick eq $palabras[0])) {
		  shift(@palabras);
		  asignar_voz();
	  }
  }
}

# Enviar mensage de info cuando se conecte alguien nuevo
sub on_join {
    my ($kernel, $who, $where) = @_[KERNEL, ARG0, ARG1];
    my $nick    = (split /!/, $who)[0];

	envia_texto($nick, $welcome);
	if ($msg)
	{
		envia_texto($nick, $msg);
	}
}

# Cuando alguien cambia de nick hay que actualizar
sub on_nick {
  my ($kernel, $prev, $now) = @_[KERNEL, ARG0, ARG1];
  my $prev_nick    = (split /!/, $prev)[0];
  my $now_nick    = (split /!/, $now)[0];

  for (my $i = 0; $i < @palabras; $i++) {
	  if ($palabras[$i] eq $prev_nick) {
		  $palabras[$i] = $now_nick;
	  }
  }
  for (my $i = 0; $i < @frases; $i++) {
	  if ($frases[$i] eq $prev_nick) {
		  $frases[$i] = $now_nick;
	  }
  }
}

# Si se va pierde sus palabras
# FIXME: si me caigo y me reconecto también las pierdo
sub on_part {
  my ($kernel, $who) = @_[KERNEL, ARG0];
  my $nick    = (split /!/, $who)[0];

  my $tengo_que_asignar = 0;
  if (@frases > 0) {
	  if ($frases[0] eq $nick) {
		  $tengo_que_asignar = 1;
	  }
  } elsif ((@palabras > 0) and ($palabras[0] eq $nick)) {
	  $tengo_que_asignar = 1;
  }

  my $j = 0;
  for (my $i = 0; $i < @palabras; $i++) {
	  # Deslizar para eliminar el nick
	  if ($j != $i) {
		  $palabras[$j] = $palabras[$i];
	  }
	  if ($palabras[$i] ne $nick) {
		  $j++;
	  }
  }
  while ($#palabras >= $j) {
	  pop(@palabras);
  }

  $j = 0;
  for (my $i = 0; $i < @frases; $i++) {
	  # Deslizar para eliminar el nick
	  if ($j != $i) {
		  $frases[$j] = $frases[$i];
	  }
	  if ($frases[$i] ne $nick) {
		  $j++;
	  }
  }
  while ($#frases >= $j) {
	  pop(@frases);
  }

  if ($tengo_que_asignar) {
	  asignar_voz();
  }
}

# /me para pedir palabra
sub on_me {
  my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2];
  my $nick    = (split /!/, $who)[0];

  if ($msg =~ /$palabra/)
  {
	  push(@palabras, $nick);
	  print "$nick ha pedido palabra\n";
  }
  if ($msg =~ /$frase/)
  {
	  push(@frases, $nick);
	  print "$nick ha pedido frase\n";
  }
  print "frases: " . join(", ", @frases) . ".\n";
  print "palabras: " . join(", ", @palabras) . ".\n";

  if ($fue_frase == 2)
  {
	  asignar_voz();
  }
}

sub asignar_voz {
	my $str = "";

	if (@frases > 0) {
		$str = "da frase a $frases[0]";
	    if (@frases > 1) {
			$str .= " otras frases pedidas: " . 
					join(', ', @frases[1..$#frases]) . ".";
		}
		$fue_frase = 1;
	} elsif (@palabras > 0) {
		$str = "da la palabra a $palabras[0].";
	    if (@palabras > 1) {
			$str .= " otras palabras pedidas: " . 
					join(', ', @palabras[1..$#palabras]) . ".";
		}
		$fue_frase = 0;
	} else {
		$fue_frase = 2;
	}

	if ($str ne "") {
	   	$irc->yield(ctcp => $channel => "ACTION $str");
	}
}

sub envia_texto {
	my ($who, $txt) = @_[0, 1];

	foreach (split("\n", $txt)) {
		$irc->yield(privmsg => $who, $_);
	}
}

# Ejecutar el bot hasta que termine
$poe_kernel->run();
exit 0;

Attachment: signature.asc
Description: Digital signature

_______________________________________________
HackMeeting mailing list
HackMeeting@listas.sindominio.net
https://listas.sindominio.net/mailman/listinfo/hackmeeting

Responder a