Merge branch 'master' into plugin
authorChristian Garbs <mitch@cgarbs.de>
Sun, 28 Dec 2008 12:47:03 +0000 (13:47 +0100)
committerChristian Garbs <mitch@cgarbs.de>
Sun, 28 Dec 2008 12:47:03 +0000 (13:47 +0100)
1  2 
xmlrtorrent.pl

diff --combined xmlrtorrent.pl
@@@ -13,12 -13,9 +13,12 @@@ use File::Spec
  use List::Util qw(max);
  use xmlrtorrent;
  
 +my @talkers;
 +my $talker;
  my $conf;
  my $conffile = File::Spec->catfile(Irssi::get_irssi_dir(), 'xmlrtorrent.xml');
  my $scriptdir = File::Spec->catfile(Irssi::get_irssi_dir(), 'scripts');
 +my $plugindir = File::Spec->catfile($scriptdir, 'xmlrtorrent');
  my %torrentlist = ();
  my $torrentindex = 1;
  my $rtorrent;
  my @outputstack = (undef);
  
  my $PARAMS = {
 -    'XMLURL' => 'http://localhost/RPC2',
 -    'USERNAME' => '',
 -    'PASSWORD' => '',
      '_QUEUE' => {},
  };
  
  # activate debug here
 -my $debug = 0;
 +my $debug = 1;
  
  # "message public", SERVER_REC, char *msg, char *nick, char *address, char *target
  signal_add_last("message public" => sub {check_for_link(\@_,1,4,2,0);});
@@@ -75,10 -75,6 +75,10 @@@ my $xmlrtorrent_commands = 
          cmd_remote(@_);
      },
  
 +    'talker' => sub {
 +      cmd_talker(@_);
 +    },
 +
      'debug' => sub {
          $debug = 1;
          write_irssi('Enabled debugging');
@@@ -97,7 -93,7 +97,7 @@@ sub write_irssi 
      my $format = '%%mxmlrtorrent: %%n' . shift(@text);
  
      # escape % in parameters from irssi
-     @text = grep { s/%/%%/g } @text;
+     s/%/%%/g foreach @text;
  
      if (defined($output) and ref($output)) {
          $output->print(sprintf($format, @text), MSGLEVEL_CLIENTCRAP);
@@@ -121,6 -117,35 +121,6 @@@ sub write_debug 
      }
  }
  
 -# This is shamelessly stolen from pythons urlgrabber
 -sub format_number {
 -    my $number = shift;
 -    my $SI = shift || 0;
 -    my @symbols = ('', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y');
 -    my $step = $SI?1000:1024;
 -    my $thresh = 999;
 -    my $depth = 0;
 -    my $max_depth = $#symbols;
 -    my $format;
 -
 -    while (($number > $thresh) and ($depth < $max_depth)) {
 -        $depth += 1;
 -        $number /= $step;
 -    }
 -
 -    if ($number =~ /^[+-]?\d+$/) {
 -        # Integer.
 -        $format = '%i%s';
 -    } elsif ($number < 9.95) {
 -        $format = '%.1f%s';
 -    } else {
 -        $format = '%.0f%s';
 -    }
 -    return sprintf($format, $number, $symbols[$depth]);
 -}
 -
 -
 -
  sub check_for_link {
      my ($signal,$parammessage,$paramchannel,$paramnick,$paramserver) = @_;
      my $server = $signal->[$paramserver];
@@@ -171,7 -196,7 +171,7 @@@ sub cmd_queue 
          $u = $torrentlist{$id}->{'URL'};
  
          write_debug('Sending %s to rtorrent', $u);
 -        unless(defined($rtorrent->load_start($u))) {
 +        unless(defined($rtorrent->load_start($talker, $u))) {
              write_irssi('%%RError sending URL %s: %s', $u, $rtorrent->errstr());
          } else {
              write_irssi('%s enqueued', $u);
@@@ -206,23 -231,24 +206,23 @@@ sub cmd_remote 
      my $rqueue;
  
      if (('list' eq $subcmd) or !defined($subcmd)) {
 -        unless(defined($rqueue = $rtorrent->download_list())) {
 +        unless(defined($rqueue = $rtorrent->download_list($talker))) {
              write_irssi('Error getting list of downloads: %s', $rtorrent->errstr());
              return;
          }
  
 -        write_irssi('List of rempote torrents');
 +        write_irssi('List of remote torrents');
          if (0 == scalar(@{$rqueue})) {
              write_irssi('  (no torrents in remote queue)');
          } else {
              foreach (@{$rqueue}) {
                  write_irssi('  %s%s: %sB/%sB done (%d%%), %sB/s up, %sB/s down',
 -                        $_->[6]?'*':' ',
 -                        $_->[0],
 -                        format_number($_->[2]),
 -                        format_number($_->[1]),
 -                        ($_->[2]*100)/$_->[1],
 -                        format_number($_->[3]),
 -                        format_number($_->[4]));
 +                          $_->{'ACTIVE'}?'*':' ',
 +                          $_->{'NAME'},
 +                          $_->{'BYTES_DONE'},
 +                          $_->{'SIZE_BYTES'},
 +                          $_->{'UP_RATE'},
 +                          $_->{'DOWN_RATE'});
              }
          }
      }
@@@ -254,84 -280,46 +254,84 @@@ sub cmd_set 
      my $target = shift;
      my $key = shift;
      my $val = shift;
 +    my $p;
  
 -    if ('global' eq $target) {
 -        if(exists($PARAMS->{$key})) {
 -            $conf->{'xmlrtorrent'}->{$key} = $val;
 -            if ('XMLURL' eq $key) {
 -                unless(defined($rtorrent = xmlrtorrent->new(
 -                        'XMLURL' => $conf->{'xmlrtorrent'}->{'XMLURL'},
 -                        'USERNAME' => $conf->{'xmlrtorrent'}->{'USERNAME'},
 -                        'USERNAME' => $conf->{'xmlrtorrent'}->{'PASSWORD'}))) {
 -                    write_irssi('Could not initialize XMLRPC instance');
 -                    return;
 -                }
 -            }
 -        } else {
 -            write_irssi('Key %s does not exist', $key);
 +    foreach $p (@talkers) {
 +        if ($p->{'NAME'} eq $target) {
 +            $p->setval($key, $val);
 +            return;
          }
      }
 +    write_irssi(undef, 'No such module');
  }
  
 -
  sub cmd_show {
      my $target = shift;
      my $p;
      my $e;
 +
 +    if (defined($target)) {
 +        foreach $p (@talkers) {
 +            if ($p->{'NAME'} eq $target) {
 +                write_irssi($p->getconfstr());
 +                return;
 +            }
 +        }
 +        write_irssi('No such module');
 +    } else {
 +        write_irssi('Loaded talkers:');
 +        foreach $p (@talkers) {
 +            write_irssi(' %s', $p->{'NAME'});
 +        };
 +    }
  }
  
  sub cmd_help {
      my $target = shift;
      my $p;
  
 -    write_irssi(<<'EOT');
 +    if (defined($target)) {
 +        foreach $p (@talkers) {
 +            if ($p->{'NAME'} eq $target) {
 +                write_irssi($p->gethelpstr());
 +                return;
 +            }
 +        }
 +        write_irssi('No such module');
 +    } else {
 +      write_irssi(<<'EOT');
  Supported commands:
 - save: Save the current configuration
 - help: Display this help
 + save: save the current configuration
 + help [modulename]: display this help or module specific help
 + show [modulename]: show loaded modules or the current parameters of a module
 + talker [modulename]: display or set the talker to use
   debug: enable debugging messages
   nodebug: disable debugging messages
  EOT
 +;
 +    }
 +}
 +
 +sub cmd_talker {
 +    my $target = shift;
 +    my $p;
 +
 +    if (defined($target)) {
 +        foreach $p (@talkers) {
 +            if (($p->{'NAME'} eq $target) && ($p->{'TYPE'} eq 'talker')) {
 +                $talker = $p;
 +                $conf->{'videosite'}->{'talker'} = $target;
 +                return;
 +            }
 +        }
 +        write_irssi('No such talker');
 +    } else {
 +        write_irssi('Current talker: %s', $conf->{'videosite'}->{'talker'});
 +    }
  }
  
  
 +
  # save on unload
  sub sig_command_script_unload {
      my $script = shift;
      }
  }
  
 +sub ploader {
 +
 +    my $dir = shift;
 +    my $pattern = shift;
 +    my $type = shift;
 +    my @list;
 +    my $p;
 +    my $g;
 +    my @g = ();
 +
 +    opendir(D, $dir) || return ();
 +    @list = grep {/$pattern/ && -f File::Spec->catfile($dir, $_) } readdir(D);
 +    closedir(D);
 +
 +    foreach $p (@list) {
 +        write_debug('Trying to load %s:', $p);
 +        $p =~ s/\.pm$//;
 +        eval qq{ require xmlrtorrent::$p; };
 +        if ($@) {
 +            write_irssi('Failed to load plugin: %s', "$@");
 +            next;
 +        }
 +
 +        $g = eval qq{ xmlrtorrent::$p->new(); };
 +        if ($@) {
 +            write_irssi('Failed to instanciate: %s', "$@");
 +            delete($INC{$p});
 +            next;
 +        }
 +
 +        write_debug('found %s %s', $g->{'TYPE'}, $g->{'NAME'});
 +        if ($type eq $g->{'TYPE'}) {
 +            push(@g, $g);
 +            $g->setio(sub {Irssi::print(shift)});
 +        } else {
 +            write_irssi('%s has wrong type (got %s, expected %s)', $p, $g->{'TYPE'}, $type);
 +            delete($INC{$p});
 +        }
 +    }
 +
 +    write_debug('Loaded %d plugins', $#g+1);
 +    
 +    return @g;
 +}
 +
 +sub _load_modules($) {
 +
 +    my $path = shift;
 +
 +    foreach (keys(%INC)) {
 +        if ($INC{$_} =~ m|^$path|) {
 +            write_debug('Removing %s from $INC', $_);
 +            delete($INC{$_});
 +        }
 +    }
 +    @talkers = ploader($path, '.*Talker\.pm$', 'talker');
 +}
 +
  sub init_xmlrtorrent {
  
      my $bindings = shift;
          }
      }
  
 +    _load_modules($plugindir);
 +
 +    unless (defined(@talkers)) {
 +        write_irssi('No talkers found, can not proceed.');
 +        return;
 +    }
 +
 +    $talker = $talkers[0];
 +    foreach $p (@talkers) {
 +        if ($conf->{'xmlrtorrent'}->{'talker'} eq $p->{'NAME'}) {
 +            $talker = $p;
 +        }
 +    }
 +    write_debug(undef, 'Selected %s as talker', $talker->{'NAME'});
 +    $conf->{'videosite'}->{'talker'} = $talker->{'NAME'};
 +
 +
      # Restore the queue
      %torrentlist = %{$conf->{'xmlrtorrent'}->{'_QUEUE'}};
      %torrentlist = map { my $a = substr($_, 1); ("$a" => $torrentlist{$_}) } keys(%torrentlist);
      $torrentindex = max(keys(%torrentlist)) + 1;
  
 -    unless(defined($rtorrent = xmlrtorrent->new(
 -            'XMLURL' => $conf->{'xmlrtorrent'}->{'XMLURL'},
 -            'USERNAME' => $conf->{'xmlrtorrent'}->{'USERNAME'},
 -            'USERNAME' => $conf->{'xmlrtorrent'}->{'PASSWORD'}))) {
 +    unless(defined($rtorrent = xmlrtorrent->new())) {
          write_irssi('Could not initialize XMLRPC instance');
          return;
      }