X-Git-Url: https://git.camperquake.de/gitweb.cgi?p=videosite.git;a=blobdiff_plain;f=videosite-irssi.pl;h=aa838c0897430e1ea78aa78b1236890cbe405d57;hp=737ba823a771edc3a4acabbef840ea86ddf8106c;hb=HEAD;hpb=66b5d05437a3112f7a716e372205613fa8beaa67 diff --git a/videosite-irssi.pl b/videosite-irssi.pl index 737ba82..aa838c0 100644 --- a/videosite-irssi.pl +++ b/videosite-irssi.pl @@ -1,797 +1,298 @@ -# autodownload flash videos +# shim to connect libvideosite to irssi # # (c) 2007-2008 by Ralf Ertzinger # licensed under GNU GPL v2 -# -# Based on youtube.pl by Christian Garbs -# which in turn is -# based on trigger.pl by Wouter Coekaerts - - -BEGIN { - # Get rid of a (possibly old) version of BettIrssi - # This is a hack to prevent having to reload irssi just - # because BettIrssi.pm changed - - delete($INC{'BettIrssi.pm'}); -} - use strict; use Irssi 20020324 qw (command_bind command_runsub signal_add_first signal_add_last); use vars qw($VERSION %IRSSI); -use XML::Simple; -use Data::Dumper; use File::Spec; -use File::Temp qw(tempfile); -use BettIrssi 101 qw(_bcb _bcs); -use LWP::UserAgent; +use Module::Load; +use XML::Simple; use JSON -support_by_pp; +use Carp; -my @grabbers; -my @getters; -my $getter; -my $conf; -my $xmlconffile = File::Spec->catfile(Irssi::get_irssi_dir(), 'videosite.xml'); -my $conffile = File::Spec->catfile(Irssi::get_irssi_dir(), 'videosite.json'); -my $scriptdir = File::Spec->catfile(Irssi::get_irssi_dir(), 'scripts'); -my $plugindir = File::Spec->catfile($scriptdir, 'videosite'); -my @outputstack = (undef); - -my $PARAMS = { - 'getter' => '', - 'mode' => 'download', - 'connectorlist' => ['direct'], - 'connectors' => {}, -}; - - -# activate debug here -my $debug = 0; - -# "message public", SERVER_REC, char *msg, char *nick, char *address, char *target -signal_add_last(_bcs("message public" => sub {check_for_link(@_)})); -# "message own_public", SERVER_REC, char *msg, char *target -signal_add_last(_bcs("message own_public" => sub {check_for_link(@_)})); - -# "message private", SERVER_REC, char *msg, char *nick, char *address -signal_add_last(_bcs("message private" => sub {check_for_link(@_)})); -# "message own_private", SERVER_REC, char *msg, char *target, char *orig_target -signal_add_last(_bcs("message own_private" => sub {check_for_link(@_)})); - -# "message irc action", SERVER_REC, char *msg, char *nick, char *address, char *target -signal_add_last(_bcs("message irc action" => sub {check_for_link(@_)})); -# "message irc own_action", SERVER_REC, char *msg, char *target -signal_add_last(_bcs("message irc own_action" => sub {check_for_link(@_)})); - -# For tab completion -# This does not use BettIrssi (yet) -signal_add_first('complete word', \&sig_complete); - -sub push_output { - unshift(@outputstack, shift); -} - -sub pop_output { - shift(@outputstack); - - @outputstack = (undef) unless (@outputstack); -} - -my $videosite_commands = { - 'save' => sub { - cmd_save(); - }, - - 'set' => sub { - cmd_set(@_); - }, - - 'show' => sub { - cmd_show(@_); - }, - - 'help' => sub { - cmd_help(@_); - }, - - 'getter' => sub { - cmd_getter(@_); - }, - - 'enable' => sub { - cmd_enable(@_); - }, - - 'disable' => sub { - cmd_disable(@_); - }, - - 'reload' => sub { - init_videosite(0); - }, - - 'mode' => sub { - cmd_mode(@_); - }, - - 'connector' => sub { - cmd_connector(@_); - }, - - 'debug' => sub { - $debug = 1; - foreach (@grabbers, @getters) { - $_->setdebug(1); - } - write_irssi('Enabled debugging'); - }, - - 'nodebug' => sub { - $debug = 0; - foreach (@grabbers, @getters) { - $_->setdebug(0); - } - write_irssi('Disabled debugging'); - }, -}; - -sub write_irssi { - my @text = @_; - my $output = $outputstack[0]; - - my $format = "%%mvideosite: %%n" . shift(@text); - - # escape % in parameters from irssi - s/%/%%/g foreach @text; - - if (defined $output) { - $output->(sprintf($format, @text), MSGLEVEL_CLIENTCRAP); - } else { - Irssi::print(sprintf($format, @text)); - } - -} - -sub write_debug { - if ($debug) { - write_irssi(@_); - } -} - -sub expand_url_shortener { - my $s = shift; - my $os = ''; - my @urlshortener = ( - 'is\.gd/[[:alnum:]]+', - 'otf\.me/[[:alnum:]]+', - 'hel\.me/[[:alnum:]]+', - '7ax\.de/[[:alnum:]]+', - 'ow\.ly/[[:alnum:]]+', - 'j\.mp/[[:alnum:]]+', - 'bit\.ly/[[:alnum:]]+', - 'tinyurl\.com/[[:alnum:]]+', - 'pop\.is/[[:alnum:]]+', - 'post\.ly/[[:alnum:]]+', - '1\.ly/[[:alnum:]]+', - '2\.ly/[[:alnum:]]+', - 't\.co/[[:alnum:]]+', - 'shar\.es/[[:alnum:]]+', - 'goo\.gl/[[:alnum:]]+', - ); - my $ua = LWP::UserAgent->new(agent => 'Mozilla', max_redirect => 0, timeout => 5); - my $i = 10; - - OUTER: while (($os ne $s) and ($i > 0)) { - study($s); - $os = $s; - $i--; - - foreach my $pattern (@urlshortener) { - my $p = "https?:\/\/" . $pattern; - - write_debug("Matching %s against %s", $p, $s); - if ($s =~ m|($p)|) { - my $matched = $1; - my $res; - - write_debug("Found %s", $matched); - $res = $ua->head($matched); - if ($res->is_redirect()) { - my $new = $res->headers()->header("Location"); - - write_debug("Replacing %s with %s", $matched, $new); - $s =~ s/$matched/$new/; - next OUTER; - } else { - write_debug("Error resolving %s", $matched); - } - } - } - } - - if ($i == 0) { - write_debug("Loop terminated by counter"); - } - - write_debug("Final string: %s", $s); +$SIG{ __DIE__ } = sub { Carp::confess( @_ ) }; - return $s; -} +# +# List of foreground colors. This list is not complete, it just +# contains the colors needed by videosite. +# +# The % are doubled because these are used in sprintf. +# +my %foreground_colors = ( + 'magenta' => '%%m', + '*magenta' => '%%M', + '*yellow' => '%%Y', + '*green' => '%%G', + '*red' => '%%R', + 'default' => '%%n', +); -sub connectorlist { - my @c; +# +# This is a canary value used in the config system as the default +# value. As irssi does not have a way to test if a setting exists +# this is used instead. A config value is never expected to be set +# to this value and be valid. +# +my $config_canary = "\1"; - foreach (@{$conf->{'videosite'}->{'connectorlist'}}) { - push(@c, $conf->{'videosite'}->{'connectors'}->{$_}); +# +# Initialize the config subsystem. Called by the core. +# +# Due to historic reasons this has to deal with a number of possible config sources: +# * irssi internal config +# * JSON config, old format +# * XML config, old format +# +# JSON and XML configs are parsed, converted and moved to the irssi internal +# format. This happens only once, as the config search stops with the first +# format found +# +sub config_init { + my $xmlconffile = File::Spec->catfile(Irssi::get_irssi_dir(), 'videosite.xml'); + my $conffile = File::Spec->catfile(Irssi::get_irssi_dir(), 'videosite.json'); + my $conf; + + # Check for irssi internal config. If not found... + if (config_has(['config-version'])) { + # Configuration in irssi config file. We're done. + return; } - return @c; -} - - -sub check_for_link { - my $event = shift; - my $message = $event->message(); - my $witem = $event->channel(); - my $g; - my $m; - my $p; - - - # Look if we should ignore this line - if ($message =~ m,(?:\s|^)/nosave(?:\s|$),) { + # Try to find old config files and load them. + if (-r $conffile) { + Irssi::print("Converting configuration from videosite.json. This will happen only once."); + eval { + local $/; + open(CONF, '<', $conffile); + $conf = JSON->new->utf8->decode(); + close(CONF); + }; + } elsif (-r $xmlconffile) { + Irssi::print("Converting configuration from videosite.xml. This will happen only once."); + $conf = XML::Simple::XMLin($xmlconffile, ForceArray => ['config', 'option', 'connectorlist'], KeepRoot => 1, KeyAttr => {'connector' => '+name', 'config' => 'module', 'option' => 'key'}); + } else { + # No old config files around. Just exit. return; } - push_output($event->ewpf); - $message = expand_url_shortener($message); - - study($message); - - # Offer the message to all Grabbers in turn - GRABBER: foreach $g (@grabbers) { - ($m, $p) = $g->get($message); - while (defined($m)) { - write_debug('Metadata: %s', Dumper($m)); - if ('download' eq ($conf->{'videosite'}->{'mode'})) { - write_irssi('%%R>>> %%NSaving %%Y%s%%N %%G%s', $m->{'SOURCE'}, $m->{'TITLE'}); - unless($getter->get($m)) { - write_irssi('%%R>>> FAILED'); - } - } elsif ('display' eq ($conf->{'videosite'}->{'mode'})) { - write_irssi('%%M>>> %%NSaw %%Y%s%%N %%G%s', $m->{'SOURCE'}, $m->{'TITLE'}); - } else { - write_irssi('%%R>>> Invalid operation mode'); + # + # Configuration conversion: + # Replace this structure: + # + # key => { + # content => value + # } + # + # with this structure + # + # key => value + # + Irssi::print("Converting configuration, stage 1"); + + # Only the getter/grabbers have this, so just check that part of the config + foreach my $g (keys(%{$conf->{videosite}->{config}})) { + foreach (keys(%{$conf->{videosite}->{config}->{$g}->{option}})) { + if (exists($conf->{videosite}->{config}->{$g}->{option}->{$_}->{content})) { + $conf->{videosite}->{config}->{$g}->{option}->{$_} = $conf->{videosite}->{config}->{$g}->{option}->{$_}->{content}; } - - # Remove the matched part from the message and try again (there may be - # more!) - $message =~ s/$p//; - study($message); - last GRABBER if ($message =~ /^\s*$/); - - ($m, $p) = $g->get($message); } } - pop_output(); -} - -sub cmd_save { - - eval { - my ($tempfile, $tempfn) = tempfile("videosite.json.XXXXXX", dir => Irssi::get_irssi_dir()); - print $tempfile JSON->new->pretty->utf8->encode($conf); - close($tempfile); - rename($tempfn, $conffile); - }; - if ($@) { - write_irssi('Could not save config to %s: %s', ($conffile, $@)); - } else { - write_irssi('configuration saved to %s', $conffile); + # + # Walk the configuration hash, creating irssi config entries for + # each leaf node. + # + # Some config values changed, so not the entire config is copied over. + # There is a helper function for this in libvideosite that we're using. + # + Irssi::print("Converting configuration, stage 2"); + + # Copy the "basic" settings. + foreach (qw(getter mode)) { + config_set([$_], $conf->{videosite}->{$_}); } -} - -sub cmd_set { - my $target = shift; - my $key = shift; - my $val = shift; - my $p; - foreach $p (@getters, @grabbers) { - if ($p->{'NAME'} eq $target) { - $p->setval($key, $val); - return; + # Copy the per-getter/setter settings + foreach my $g (keys(%{$conf->{videosite}->{config}})) { + foreach (keys(%{$conf->{videosite}->{config}->{$g}->{option}})) { + config_set(['plugin', $g, $_], $conf->{videosite}->{config}->{$g}->{option}->{$_}); } } - write_irssi('No such module'); -} - -sub cmd_enable { - my $target = shift; - my $p; + # Copy the connectors. The connectors themselves are copied as-is, + # the list of active connectors is copied under a different name, + # and a list of all existing connectors is created + my @connectors; - foreach $p (@grabbers) { - if ($p->{'NAME'} eq $target) { - $p->enable(); - return; + foreach my $c (keys(%{$conf->{videosite}->{connectors}})) { + push(@connectors, $c); + config_set(['connectors', $c, 'name'], $conf->{videosite}->{connectors}->{$c}->{name}); + if (exists($conf->{videosite}->{connectors}->{$c}->{_immutable})) { + config_set(['connectors', $c, '_immutable'], $conf->{videosite}->{connectors}->{$c}->{_immutable}); } - } - write_irssi('No such module'); -} - - -sub cmd_disable { - my $target = shift; - my $p; - - foreach $p (@grabbers) { - if ($p->{'NAME'} eq $target) { - $p->disable(); - return; + foreach (qw(http https)) { + if (exists($conf->{videosite}->{connectors}->{$c}->{schemas}->{http})) { + config_set(['connectors', $c, 'schemas', $_], $conf->{videosite}->{connectors}->{$c}->{schemas_}->{$_}); + } } } - write_irssi('No such module'); + config_set(['active-connectors'], join(",", @{$conf->{videosite}->{connectorlist}})); + config_set(['defined-connectors'], join(",", @connectors)); + config_set(['config-version'], '2'); } +# +# Reading a configuration value. Called by the core +# +sub config_get { + my $path = shift; + my $item = join('.', 'videosite', @{$path}); + my $val; -sub cmd_show { - my $target = shift; - my $p; - my $e; - if (defined($target)) { - foreach $p (@getters, @grabbers) { - if ($p->{'NAME'} eq $target) { - write_irssi($p->getconfstr()); - return; - } - } - write_irssi('No such module'); - } else { - write_irssi('Loaded grabbers (* denotes enabled modules):'); - foreach $p (@grabbers) { - $e = $p->_getval('enabled'); - write_irssi(' %s%s', $p->{'NAME'}, $e?'*':''); - }; + Irssi::settings_add_str('videosite', $item, $config_canary); + $val = Irssi::settings_get_str($item); - write_irssi('Loaded getters:'); - foreach $p (@getters) { - write_irssi(' %s', $p->{'NAME'}); - }; - } + return ($val ne $config_canary)?$val:undef; } -sub cmd_help { - my $target = shift; - my $p; - - if (defined($target)) { - foreach $p (@getters, @grabbers) { - 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 [modulename]: display this help, or module specific help - show [modulename]: show loaded modules, or the current parameters of a module - set modulename parameter value: set a module parameter to a new value - getter [modulename]: display or set the getter to use - enable [modulename]: enable the usage of this module (grabbers only) - disable [modulename]: disable the usage of this module (grabbers only) - reload: reload all modules (this is somewhat experimental) - mode [modename]: display or set the operation mode (download/display) - connector [subcommand]: manage connectors (proxies) - debug: enable debugging messages - nodebug: disable debugging messages -EOT - } -} +# +# Returns a true value if the config item exists +# +sub config_has { + my $path = shift; + my $item = join('.', 'videosite', @{$path}); -sub cmd_getter { - my $target = shift; - my $p; - - if (defined($target)) { - foreach $p (@getters) { - if ($p->{'NAME'} eq $target) { - $getter = $p; - $conf->{'videosite'}->{'getter'} = $target; - write_irssi("Getter changed to %s", $target); - return; - } - } - write_irssi('No such getter'); - } else { - write_irssi('Current getter: %s', $conf->{'videosite'}->{'getter'}); - } + Irssi::settings_add_str('videosite', $item, $config_canary); + return Irssi::settings_get_str($item) ne $config_canary; } -sub cmd_mode { - my $mode = shift; +# +# Setting a configuration value. Called by the core +# +sub config_set { + my $path = shift; + my $value = shift; + my $item = join('.', 'videosite', @{$path}); - if (defined($mode)) { - $mode = lc($mode); - if (('download' eq $mode) or ('display' eq $mode)) { - $conf->{'videosite'}->{'mode'} = $mode; - write_irssi('Now using %s mode', $mode); - } else { - write_irssi('Invalid mode: %s', $mode); - } - } else { - write_irssi('Current mode: %s', $conf->{'videosite'}->{'mode'}); - } + Irssi::settings_add_str('videosite', $item, $config_canary); + Irssi::settings_set_str($item, $value); } -sub cmd_connector { - my $subcmd = shift; - my $connconf = $conf->{'videosite'}->{'connectors'}; - - unless(defined($subcmd)) { - $subcmd = "help"; - } - - $subcmd = lc($subcmd); - - if ($subcmd eq 'list') { - write_irssi("Defined connectors"); - foreach (keys(%{$connconf})) { - write_irssi($_); - my $schemas = $connconf->{$_}->{'schemas'}; - if (scalar(keys(%{$schemas})) == 0) { - write_irssi(" No schemas defined"); - } else { - foreach (keys(%{$schemas})) { - write_irssi(' %s: %s', $_, $schemas->{$_}); - } - } - } - - write_irssi(); - write_irssi("Selected connectors: %s", join(", ", @{$conf->{'videosite'}->{'connectorlist'}})); - } elsif ($subcmd eq 'add') { - my ($name) = @_; - - unless(defined($name)) { - write_irssi("No name given"); - return; - } - - $name = lc($name); - - if (exists($connconf->{$_})) { - write_irssi("Connector already exists"); - return; - } - - $connconf->{$name} = {'name' => $name, 'schemas' => {}}; - } elsif ($subcmd eq 'del') { - my ($name) = @_; - - unless(defined($name)) { - write_irssi("No name given"); - return; - } - - $name = lc($name); - - unless (exists($connconf->{$name})) { - write_irssi("Connector does not exist"); - return; - } - - if (exists($connconf->{$name}->{'_immutable'})) { - write_irssi("Connector cannot be removed"); - return; - } - - delete($connconf->{$name}); - - # Remove from list of active connectors - $conf->{'videosite'}->{'connectorlist'} = - [ grep { $_ ne $name } @{$conf->{'videosite'}->{'connectorlist'}} ]; - - if (scalar(@{$conf->{'videosite'}->{'connectorlist'}}) == 0) { - write_irssi("List of selected connectors is empty, resetting to direct"); - $conf->{'videosite'}->{'connectorlist'} = [ 'direct' ]; - } - } elsif ($subcmd eq 'addschema') { - my ($conn, $schema, $proxy) = @_; - - unless(defined($conn)) { - write_irssi("No connector name given"); - return; - } - - $conn = lc($conn); - - if (exists($connconf->{$conn}->{'_immutable'})) { - write_irssi("Connector cannot be modified"); - return; - } - - unless(defined($schema)) { - write_irssi("No schema given"); - return; - } - - $schema = lc($schema); - - unless(defined($proxy)) { - write_irssi("No proxy given"); - return; - } - - unless(exists($connconf->{$conn})) { - write_irssi("Connector does not exist"); - return; - } - - $connconf->{$conn}->{'schemas'}->{$schema} = $proxy; - } elsif ($subcmd eq 'delschema') { - my ($conn, $schema) = @_; - - unless(defined($conn)) { - write_irssi("No connector name given"); - return; - } - - $conn = lc($conn); - - if (exists($connconf->{$conn}->{'_immutable'})) { - write_irssi("Connector cannot be modified"); - return; - } - - unless(defined($schema)) { - write_irssi("No schema given"); - return; - } - - $schema = lc($schema); - - unless(exists($connconf->{$conn})) { - write_irssi("Connector does not exist"); - return; - } - - delete($connconf->{$conn}->{'schemas'}->{$schema}); - } elsif ($subcmd eq 'select') { - my @connlist = map { lc } @_; - - if (scalar(@connlist) == 0) { - write_irssi("No connectors given"); - return; - } - - foreach (@connlist) { - unless(exists($connconf->{$_})) { - write_irssi("Connector %s does not exist", $_); - return; - } - } +# +# Delete a configuration value. Called by the core. +# +# Now, according to the configuration Irssi::settings_remove() removes a +# config settings. This does not work in any irssi version available to me. +# So just set the key to the canary value. +# +sub config_del { + my $path = shift; - $conf->{'videosite'}->{'connectorlist'} = [ @connlist ]; - } else { - write_irssi("connector [list|add|del|addschema|delschema|help] "); - write_irssi(" help: Show this help"); - write_irssi(" list: List the defined connectors"); - write_irssi(" add : Add a connector with name "); - write_irssi(" del : Delete the connector with name "); - write_irssi(" addschema : Add proxy to connector for the given schema"); - write_irssi(" delschema : Remove the schema from the connector"); - write_irssi(" select [...]: Select the connectors to use"); - } + config_set($path, $config_canary); } +# +# Return a color code. Called by the core +# +# Does not handle background colors yet. +# +sub colorpair { + my ($fg, $bg) = @_; + $fg = exists($foreground_colors{$fg})?$foreground_colors{$fg}:''; + $bg = ''; - -# save on unload -sub sig_command_script_unload { - my $script = shift; - if ($script =~ /(.*\/)?videosite(\.pl)?$/) { - cmd_save(); - } + return $fg . $bg; } -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 $p:"); - $p =~ s/\.pm$//; - eval qq{ require videosite::$p; }; - if ($@) { - write_irssi("Failed to load plugin: $@"); - next; - } - - $g = eval qq{ videosite::$p->new(); }; - if ($@) { - write_irssi("Failed to instanciate: $@"); - delete($INC{$p}); - next; - } - - write_debug("found $g->{'TYPE'} $g->{'NAME'}"); - if ($type eq $g->{'TYPE'}) { - push(@g, $g); - $g->setio(\&write_irssi); - $g->setconn(\&connectorlist); - } else { - write_irssi('%s has wrong type (got %s, expected %s)', $p, $g->{'TYPE'}, $type); - delete($INC{$p}); - } - } +# +# Handle commands (/videosite ...) +# +sub videosite_hook { + my ($cmdline, $server, $witem) = @_; + my %event = ( + message => $cmdline, + io => sub { defined($witem)?$witem->print($_[0], MSGLEVEL_CLIENTCRAP):Irssi::print($_[0]) }, + window => defined($witem)?$witem->{server}->{real_address} . "/" . $witem->{name}:"", + ); + + libvideosite::handle_command(\%event); +} - write_debug("Loaded %d plugins", $#g+1); - - return @g; +# +# Handle a received message +# Create an event structure and hand it off to libvideosite +# +sub message_hook { + my ($server, $msg, $nick, $userhost, $channel) = @_; + my $witem = $server->window_item_find($channel); + my %event = ( + message => $msg, + io => sub { defined($witem)?$witem->print($_[0], MSGLEVEL_CLIENTCRAP):Irssi::print($_[0]) }, + window => defined($witem)?$witem->{server}->{real_address} . "/" . $witem->{name}:"", + ); + + libvideosite::check_for_link(\%event); } -sub _load_modules($) { +sub videosite_reset { + my $libpath; - my $path = shift; + # Find out the script directory, and add it to @INC. + # This is necessary to find libvideosite.pm + $libpath = File::Spec->catfile(Irssi::get_irssi_dir(), 'scripts'); + # If the library is already loaded unload it foreach (keys(%INC)) { - if ($INC{$_} =~ m|^$path|) { - write_debug("Removing %s from \$INC", $_); + if ($INC{$_} eq File::Spec->catfile($libpath, 'libvideosite.pm')) { delete($INC{$_}); } } - @grabbers = ploader($path, '.*Grabber\.pm$', 'grabber'); - @getters = ploader($path, '.*Getter\.pm$', 'getter'); -} - -sub init_videosite { - - my $bindings = shift; - my $p; - - if (-r $conffile) { - write_debug("Attempting JSON config load from %s", $conffile); - eval { - local $/; - open(CONF, '<', $conffile); - $conf = JSON->new->utf8->decode(); - close(CONF); - }; - } elsif (-r $xmlconffile) { - write_debug("Attempting XML config load from %s", $xmlconffile); - $conf = XML::Simple::XMLin($xmlconffile, ForceArray => ['config', 'option', 'connectorlist'], KeepRoot => 1, KeyAttr => {'connector' => '+name', 'config' => 'module', 'option' => 'key'}); - } - - unless(defined($conf)) { - # No config, start with an empty one - write_debug('No config found, using defaults'); - $conf = { 'videosite' => { }}; + push(@INC, $libpath); + load 'libvideosite'; + + unless(libvideosite::register_api({ + io => sub { Irssi::print($_[0]) }, + config_init => \&config_init, + config_get => \&config_get, + config_set => \&config_set, + config_has => \&config_has, + config_save => sub { 1 }, + config_del => \&config_del, + color => \&colorpair, + module_path => sub { return File::Spec->catfile(Irssi::get_irssi_dir(), 'scripts') }, + quote => sub { s/%/%%/g; return $_ }, + reload => \&videosite_reset, + # irssi needs this to prevent fork()ed child processes becoming zombies: + wait_for_child => sub { Irssi::pidwait_add($_[0]) }, + })) { + Irssi::print(sprintf("videosite API register failed: %s", $libvideosite::error)); + return 0; } - foreach (keys(%{$PARAMS})) { - unless (exists($conf->{'videosite'}->{$_})) { - $conf->{'videosite'}->{$_} = $PARAMS->{$_}; - } - } - - # Make sure there is a connector called 'direct', which defines no - # proxies - unless (exists($conf->{'videosite'}->{'connectors'}->{'direct'})) { - $conf->{'videosite'}->{'connectors'}->{'direct'} = { - 'name' => 'direct', - '_immutable' => '1', - 'schemas' => {}, - }; + unless(libvideosite::init()) { + Irssi::print(sprintf("videosite init failed: %s", $libvideosite::error)); + return 0; } - _load_modules($plugindir); - - unless (defined(@grabbers) && defined(@getters)) { - write_irssi('No grabbers or no getters found, can not proceed.'); - return; - } - - $getter = $getters[0]; - foreach $p (@getters) { - if ($conf->{'videosite'}->{'getter'} eq $p->{'NAME'}) { - $getter = $p; - } - } - write_debug('Selected %s as getter', $getter->{'NAME'}); - $conf->{'videosite'}->{'getter'} = $getter->{'NAME'}; - - # Loop through all plugins and load the config - foreach $p (@grabbers, @getters) { - $conf->{'videosite'}->{'config'}->{$p->{'NAME'}} = $p->mergeconfig($conf->{'videosite'}->{'config'}->{$p->{'NAME'}}); - } - - if ($bindings) { - - Irssi::signal_add_first('command script load', 'sig_command_script_unload'); - Irssi::signal_add_first('command script unload', 'sig_command_script_unload'); - Irssi::signal_add('setup saved', 'cmd_save'); - - - Irssi::command_bind(_bcb('videosite' => \&cmdhandler)); - } - - write_irssi('initialized successfully'); -} - -sub sig_complete { - my ($complist, $window, $word, $linestart, $want_space) = @_; - my @matches; - - if ($linestart !~ m|^/videosite\b|) { - return; - } - - if ('/videosite' eq $linestart) { - # No command enterd so far. Produce a list of possible follow-ups - @matches = grep {/^$word/} keys (%{$videosite_commands}); - } elsif ('/videosite set' eq $linestart) { - # 'set' command entered. Produce a list of modules - foreach (@grabbers, @getters) { - push(@matches, $_->{'NAME'}) if $_->{'NAME'} =~ m|^$word|; - }; - } elsif ($linestart =~ m|^/videosite set (\w+)$|) { - my $module = $1; - - foreach my $p (@getters, @grabbers) { - if ($p->{'NAME'} eq $module) { - @matches = $p->getparamlist($word); - last; - } - } - } elsif ($linestart =~ m|/videosite set (\w+) (\w+)$|) { - my $module = $1; - my $param = $2; - - foreach my $p (@getters, @grabbers) { - if ($p->{'NAME'} eq $module) { - @matches = $p->getparamvalues($param, $word); - last; - } - } - } - - - push(@{$complist}, sort @matches); - ${$want_space} = 0; - - Irssi::signal_stop(); + return 1; } -sub cmdhandler { - my $event = shift; - my ($cmd, @params) = split(/\s+/, $event->message()); +sub videosite_init { - push_output($event->ewpf); + if (videosite_reset()) { + signal_add_last("message public", sub { message_hook(@_) }); + signal_add_last("message own_public", sub { message_hook($_[0], $_[1], undef, undef, $_[2]) }); + signal_add_last("message private", sub { message_hook($_[0], $_[1], $_[2], $_[3], $_[2]) }); + signal_add_last("message own_private", sub { message_hook($_[0], $_[1], undef, undef, $_[2]) }); + signal_add_last("message irc action", sub { message_hook(@_) }); + signal_add_last("message irc own_action", sub { message_hook($_[0], $_[1], undef, undef, $_[2]) }); - if (exists($videosite_commands->{$cmd})) { - $videosite_commands->{$cmd}->(@params); + Irssi::command_bind('videosite', sub { videosite_hook(@_) }); } - - pop_output(); } -unshift(@INC, $scriptdir); -init_videosite(1); +videosite_init();