Difference between revisions of "Amulet pl src"
From AMule Project FAQ
Line 1: | Line 1: | ||
− | + | = aMulet.pl source = | |
+ | <pre><nowiki> | ||
+ | #!/usr/bin/perl -w | ||
+ | # | ||
+ | # file aMulet.pl | ||
+ | # Copyright by AnimAlf | ||
+ | # | ||
+ | # This lines are under the GNU General Public License. | ||
+ | # http://www.gnu.org/copyleft/gpl.html | ||
+ | # | ||
+ | # aMulet - la t final en catalán le indica diminutivo | ||
+ | # También se traduce como amuleto | ||
+ | |||
+ | use strict; | ||
+ | |||
+ | my $binaMuled = 'amuled -f'; | ||
+ | my $apppid = "$ENV{HOME}/.tx2z.pid"; | ||
+ | my $logMode = "warning"; # debug warning msg | ||
+ | my $verbose = 1; # true false | ||
+ | |||
+ | if (!defined($ENV{'DISPLAY'})){ | ||
+ | print &appRel . "\nATENCIÓN: Este script necesita ser ejecutado bajo las X Window\n"; | ||
+ | exit -1; | ||
+ | } | ||
+ | |||
+ | eval "use Gtk2::TrayIcon;"; | ||
+ | if ($@) { | ||
+ | print &appRel; | ||
+ | print "\n\nATENCIÓN: Este script necesita el módulo Gtk2::TrayIcon\n\n"; | ||
+ | print "Puede instalarlo a través de CPAN del siguiente modo:\n\n"; | ||
+ | print "\t\tperl -MCPAN -e shell\n"; | ||
+ | print "\t\tinstall Gtk2::TrayIcon\n\n"; | ||
+ | print "bye\n"; | ||
+ | exit -1; | ||
+ | } | ||
+ | |||
+ | my $modUniCode; | ||
+ | eval "use Unicode::MapUTF8 qw(from_utf8);"; | ||
+ | $modUniCode = !$@; | ||
+ | |||
+ | my $config = {}; | ||
+ | my @appList = ( 'aMuleGui', 'wxCas', 'aLinkCreator'); | ||
+ | |||
+ | # Los procesos hijo envían esta señal al padre cuando terminan y ésta | ||
+ | # debe ser atendida, si no se quedan zombies hasta que termine el padre. | ||
+ | $SIG{CHLD} = \&finalHijo; | ||
+ | |||
+ | # Si se recibe cualquier señal que pueda provocar la interrupción del | ||
+ | # normal funcionamiento, entonces nos encargamos de finalizar correctamente. | ||
+ | $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = \&finalizar; | ||
+ | |||
+ | # Iniciando Gtk2 | ||
+ | Gtk2->init; | ||
+ | |||
+ | # Comprobaciones iniciales. Cargar configuración. | ||
+ | if (!&inicializar){ | ||
+ | logsys ("msg", &appRel ." ha abortado el arranque."); | ||
+ | unlink $apppid or die "No puedo eliminar el archivo de bloqueo"; | ||
+ | exit -1; | ||
+ | } | ||
+ | logsys ("msg", &appRel ." iniciado"); | ||
+ | |||
+ | # Formas Gtk2 | ||
+ | my $menu = Gtk2::Menu->new(); | ||
+ | my $menu_opciones = Gtk2::MenuItem->new("opciones"); | ||
+ | my $menu_aLinkCreator = Gtk2::MenuItem->new("aLinkCreator"); | ||
+ | my $menu_wxCas = Gtk2::MenuItem->new("wxCas"); | ||
+ | my $menu_aMuleGui = Gtk2::MenuItem->new("aMuleGui"); | ||
+ | my $menu_verLog = Gtk2::MenuItem->new("aMule log"); | ||
+ | my $menuSalir = Gtk2::MenuItem->new("Salir"); | ||
+ | my $pic; | ||
+ | eval {$pic = Gtk2::Gdk::Pixbuf->new_from_file ($config->{'iconPath'});}; | ||
+ | if ($@){ | ||
+ | my @aMulet_xpm = ('18 24 17 1', ' c None', '. c #312A28', '+ c #524842', | ||
+ | '@ c #D42238', '# c #835128', '$ c #985A20', '% c #6A6B6A', | ||
+ | '& c #AA7B50', '* c #EC5867', '= c #BF7B3F', '- c #C9792F', | ||
+ | '; c #898989', '> c #E39854', ', c #CB9D83', '" c #A9AAAA', | ||
+ | ') c #CDCBC9', '! c #F4F5F3', ' ', | ||
+ | ' $ ', | ||
+ | ' !> ', | ||
+ | ' #! )$$ ', | ||
+ | ' ## #-$ ', | ||
+ | ' )##$ -,# ', | ||
+ | ' .+##)$,) ', | ||
+ | ' ...$,!" ', | ||
+ | ' ".$=-$" ', | ||
+ | ' ;==-!= ', | ||
+ | ' " >! " ', | ||
+ | ' ; !& ; ', | ||
+ | ' " !)))" ', | ||
+ | ' """"""! ', | ||
+ | ' %!.""""); ', | ||
+ | ' ;))";;;"%;;) ', | ||
+ | ' ">-)";;;;"->"" ', | ||
+ | ' )-=$,;;%@,->$) ', | ||
+ | ' ;%--#=>>**+%%; ', | ||
+ | ' +....&=>>>>#!))! ', | ||
+ | '%"-=##$>>>>=&$--;;', | ||
+ | '+)-=##&=>>>=#=->)+', | ||
+ | '%;;=$+.+>>++$->,;%', ' " . '); | ||
+ | $pic = Gtk2::Gdk::Pixbuf->new_from_xpm_data (@aMulet_xpm); | ||
+ | logsys ("warning", "Error al cargar el icono: " . $config->{'iconPath'}); | ||
+ | logsys ("msg", "Se procede a cargar el icono interno."); | ||
+ | } | ||
+ | my $img= Gtk2::Image->new_from_pixbuf($pic->scale_simple(18, 24, "tiles")); | ||
+ | my $tray= Gtk2::TrayIcon->new("trayicon"); | ||
+ | my $paraEvent = Gtk2::EventBox->new; | ||
+ | my $trayTooltip = Gtk2::Tooltips->new; | ||
+ | my $SeparadorMenu1 = Gtk2::SeparatorMenuItem->new; | ||
+ | my $SeparadorMenu2 = Gtk2::SeparatorMenuItem->new; | ||
+ | my $SeparadorMenu3 = Gtk2::SeparatorMenuItem->new; | ||
+ | |||
+ | $menu->append($menu_verLog); | ||
+ | $menu->append($SeparadorMenu1); | ||
+ | $menu->append($menu_opciones); | ||
+ | $menu->append($SeparadorMenu2); | ||
+ | $menu->append($menu_aLinkCreator); | ||
+ | $menu->append($menu_wxCas); | ||
+ | $menu->append($menu_aMuleGui); | ||
+ | $menu->append($SeparadorMenu3); | ||
+ | $menu->append($menuSalir); | ||
+ | |||
+ | $paraEvent->add($img); | ||
+ | $tray->add($paraEvent); | ||
+ | &statusText; | ||
+ | |||
+ | # Tratamiento de señales | ||
+ | logsys ("debug", "Asignación de señales"); | ||
+ | $tray->signal_connect ('button-press-event' => \&ClickOnIcon); | ||
+ | $menu_opciones->signal_connect('activate' => \&opcionesGui); | ||
+ | $menu_verLog->signal_connect('activate' => \&visorTexto); | ||
+ | $menu_aLinkCreator->signal_connect('activate' => sub {&extAppStatus('aLinkCreator')}); | ||
+ | $menu_wxCas->signal_connect('activate' => sub {&extAppStatus('wxCas')}); | ||
+ | $menu_aMuleGui->signal_connect('activate' => sub {&extAppStatus('aMuleGui')}); | ||
+ | $menuSalir->signal_connect('activate' => \&finalizar); | ||
+ | Glib::Timeout->add($config->{'signOnTime'}*1000, \&statusText) if $config->{'signOn'}; | ||
+ | |||
+ | # show sobre los witgets para que sean visibles | ||
+ | logsys ("debug", "Show sobre los witgets"); | ||
+ | $menu->show_all; | ||
+ | $tray->show_all; | ||
+ | &popUpsAct; | ||
+ | # iniciando bucle de mensajes | ||
+ | logsys ("debug", "Inicio del bucle de mensajes"); | ||
+ | Gtk2->main; | ||
+ | # Fin. Aquí termina el flujo. | ||
+ | |||
+ | ############# | ||
+ | # Funciones # | ||
+ | ############# | ||
+ | # statusText Establece el texto del toolTip | ||
+ | sub statusText{ | ||
+ | my $tmpStr = &appRel ." - Click derecho para opciones"; | ||
+ | if ($config->{'signOn'}){ | ||
+ | &onlineInfo; | ||
+ | # my $tmpStr; | ||
+ | if ($config->{'ConectStatus'}){ | ||
+ | if ($config->{'typeId'}eq"H"){$tmpStr = "[ID alta]"} | ||
+ | elsif ($config->{'typeId'}eq"L"){$tmpStr = "[ID baja]"} | ||
+ | else {$tmpStr = "[Conectando]"} | ||
+ | $tmpStr .= " Down:" . $config->{'downSpeed'}; | ||
+ | $tmpStr .= " kb/s Up:" . $config->{'upSpeed'} ." Kb/s "; | ||
+ | if ($config->{'kadStatus'}==2) {$tmpStr .= "[kad ok]"; | ||
+ | } elsif ($config->{'kadStatus'}==1) {$tmpStr .= "[kad firewalled]"; | ||
+ | } else {$tmpStr .= "[kad off]"}; | ||
+ | } else {$tmpStr = &appRel . " [aMuled No Conectado]"} | ||
+ | |||
+ | } | ||
+ | $trayTooltip->set_tip($tray, $tmpStr); | ||
+ | $tray->send_message($config->{'signOnTime'}*1000, "[AnimAlf dice] No entiendo"); | ||
+ | } | ||
+ | |||
+ | # signatureOn Comprueba OnlineSignature en amule.conf | ||
+ | sub readSignatureConf { | ||
+ | $config->{'signOn'} = 0; | ||
+ | $config->{'signOnTime'} = 0; | ||
+ | if (-f $config->{'aMuleDir'} . "/amule.conf"){ | ||
+ | if ( open( CONFIGFILE, $config->{'aMuleDir'} . "/amule.conf" ) ) { | ||
+ | while (<CONFIGFILE>) { | ||
+ | if ( $_ =~ /^OnlineSignature=(.+)/ ) { $config->{'signOn'} = $1 } | ||
+ | if ( $_ =~ /^OnlineSignatureUpdate=(.+)/ ) { $config->{'signOnTime'} = $1 } | ||
+ | } | ||
+ | close CONFIGFILE; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # onlineInfo Recoge la información de amulesig.dat | ||
+ | sub onlineInfo { | ||
+ | if ( open( SIGNFILE, $config->{'aMuleDir'} . "/amulesig.dat" ) ) { | ||
+ | my @signFile; | ||
+ | while (<SIGNFILE>) { | ||
+ | $_ =~ /(.+)\n$/; push (@signFile, $1) | ||
+ | } | ||
+ | close SIGNFILE; | ||
+ | $config->{'ConectStatus'} = $signFile[0]; | ||
+ | $config->{'nameServ'} = $signFile[1]; | ||
+ | $config->{'ipServ'} = $signFile[2]; | ||
+ | $config->{'portServ'} = $signFile[3]; | ||
+ | $config->{'typeId'} = $signFile[4]; | ||
+ | $config->{'kadStatus'} = $signFile[5]; | ||
+ | $config->{'downSpeed'} = $signFile[6]; | ||
+ | $config->{'upSpeed'} = $signFile[7]; | ||
+ | $config->{'colaCli'} = $signFile[8]; | ||
+ | $config->{'filesShared'} = $signFile[9]; | ||
+ | $config->{'nickName'} = $signFile[10]; | ||
+ | $config->{'totalDown'} = $signFile[11]; | ||
+ | $config->{'totalUp'} = $signFile[12]; | ||
+ | $config->{'aMuleVer'} = $signFile[13]; | ||
+ | $config->{'SessionDown'} = $signFile[14]; | ||
+ | $config->{'SessionUp'} = $signFile[15]; | ||
+ | $config->{'TimeRun'} = $signFile[16]; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # finalHijo atender la señal de los hijos (cuando terminan la mandan) | ||
+ | sub finalHijo { | ||
+ | $SIG{CHLD} = \&finalHijo; | ||
+ | my $pid = wait; | ||
+ | return unless $config->{$pid}; # El system() realiza un fork() también. | ||
+ | logsys ("msg", "Acaba de finalizar: " . $config->{$pid} . | ||
+ | " [" . $config->{$config->{$pid} . 'Pid'} . "]"); | ||
+ | undef $config->{$config->{$pid} . 'Pid'}; | ||
+ | undef $config->{$pid}; | ||
+ | } | ||
+ | |||
+ | # finalizar correctamente y eliminar bloqueo | ||
+ | sub finalizar { | ||
+ | $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = \&finalizar; | ||
+ | logsys ("msg", "Finalizando ..."); | ||
+ | #Finalizar el bucle de mensajes | ||
+ | Gtk2->main_quit; | ||
+ | #Comprobar que no quede ninguna aplicación hijo en funcionamiento | ||
+ | #y si existe eliminarlas antes de finalizar no vayan a quedar zombies. | ||
+ | logsys ("msg", "Finalizando posibles hijos"); | ||
+ | # Ahora la señal de retorno del hijo la trataremos aquí. | ||
+ | $SIG{CHLD} = 'DEFAULT'; | ||
+ | foreach my $app (@appList) { | ||
+ | if (defined $config->{$app . "Pid"}){ | ||
+ | logsys ("msg", "[$app] está en marcha. Finalizándolo ..."); | ||
+ | kill ('SIGTERM', $config->{$app . "Pid"}); | ||
+ | waitpid($config->{$app . "Pid"}, 0); | ||
+ | } | ||
+ | } | ||
+ | logsys ("msg", "No quedan procesos hijo de " . &appRel . " en el sistema"); | ||
+ | #TODO Si archivo de bloqueo es usado para log volcar a otro sitio. | ||
+ | logsys ("warning", "TODO: volcar archivo log a log final [si se le ordena]"); | ||
+ | logsys ("msg", "Terminada la ejecución"); | ||
+ | logsys ("msg", "bye ;-)\n\n".&appRel."\n"); | ||
+ | # borrar archivo de bloqueo | ||
+ | unlink $apppid or die "No puedo eliminar el archivo de bloqueo $apppid"; | ||
+ | } | ||
+ | |||
+ | # flushChars transforma utf8 a iso-8859-1 | ||
+ | sub flushChars { | ||
+ | my ($tmpStr) = @_; | ||
+ | $tmpStr =~ s/([\200-\377]+)/from_utf8({ -string => $1, -charset => 'ISO-8859-1'})/eg | ||
+ | if $modUniCode; | ||
+ | return $tmpStr; | ||
+ | } | ||
+ | |||
+ | #logsys Mini sistema de logs. | ||
+ | sub logsys { | ||
+ | my ($mode, $text) = @_; | ||
+ | my $tmpStr; | ||
+ | if (open LOG, ">>$apppid") { | ||
+ | if (($logMode eq "debug" && ($mode eq "debug" or $mode eq "warning")) || | ||
+ | ($logMode eq "warning" && ($mode eq "warning" or $mode eq "msg")) || | ||
+ | ($logMode eq "msg" && $mode eq "msg")){ | ||
+ | my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime (time); | ||
+ | $year += 1900; $mon ++; | ||
+ | $tmpStr="[" . uc($mode) . "] " . sprintf("%02d",$mday) . "-" . | ||
+ | sprintf("%02d",$mon) . "-$year " . sprintf("%02d",$hour) . ":" . | ||
+ | sprintf("%02d",$min) . ":" . sprintf("%02d",$sec) . " $text\n"; | ||
+ | print LOG $tmpStr; print $tmpStr if $verbose; | ||
+ | } | ||
+ | close LOG; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # ClickOnIcon se lanzará tras un click en el TrayIcon. | ||
+ | # Para diferenciar el botón del ratón que se pulsó. | ||
+ | sub ClickOnIcon { | ||
+ | logsys ("debug", "sub: ClickOnIcon start"); | ||
+ | my ($widget, $event) = @_; | ||
+ | return 1 if $event->button == 2; | ||
+ | $menu->popup(undef, undef, undef, undef, $event->button,$event->time) if $event->button == 3; | ||
+ | &extAppStatus($config->{'appOnClick'}) if $event->button == 1; | ||
+ | } | ||
+ | |||
+ | # extAppStatus lanzará una instancia de la aplicación si no existe | ||
+ | sub extAppStatus { | ||
+ | logsys ("debug", "sub: extAppStatus start"); | ||
+ | my ($refApp) = @_; | ||
+ | $config->{ $refApp . 'Pid'} = fork() | ||
+ | unless ($config->{ $refApp . 'Pid'}); # Crea un proceso hijo | ||
+ | die "error al hacer fork: $!" if !defined($config->{$refApp . 'Pid'}); | ||
+ | if ( $config->{$refApp . 'Pid'} == 0) { # Si se trata del proceso hijo | ||
+ | logsys ("msg", "Iniciando proceso hijo con [$refApp]"); | ||
+ | if ($config->{$refApp . 'Ok'}) { | ||
+ | $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = 'DEFAULT'; | ||
+ | logsys ("warning", "Redirección de STDOUT para $refApp a $apppid"); | ||
+ | open STDOUT, ">>$apppid"; | ||
+ | exec ($config->{$refApp . 'App'}) || | ||
+ | die "ATENCIÓN: Falló la ejecución de $refApp"; | ||
+ | } else {exit -1} | ||
+ | } else { # Circuito del proceso padre | ||
+ | logsys ("msg", "Circuito del proceso padre [hijo=>$refApp pid:" | ||
+ | . $config->{$refApp . 'Pid'} . "]"); | ||
+ | # Asigno una clave en la configuración con el valor de la pid con el padre | ||
+ | $config->{$config->{$refApp . 'Pid'}} = $refApp | ||
+ | unless $config->{$config->{$refApp . 'Pid'}}; | ||
+ | # a ejecutar por el proceso padre | ||
+ | # TODO: Enviar setFocus a la aplicación | ||
+ | # | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # appRel nombre y versión del script | ||
+ | sub appRel { | ||
+ | $0=~/.*\/(.*)$/; | ||
+ | my $fileRun = $1; | ||
+ | $fileRun = $0 unless $fileRun; | ||
+ | $fileRun = "aMulet.pl [$1]" if $fileRun ne 'aMulet.pl'; | ||
+ | return $fileRun . " v.1.2 beta"; | ||
+ | } | ||
+ | |||
+ | # popUpsAct des/activar apartados del menú | ||
+ | sub popUpsAct { | ||
+ | $menu_aLinkCreator->set_sensitive($config->{'aLinkCreatorOk'}); | ||
+ | $menu_wxCas->set_sensitive($config->{'wxCasOk'}); | ||
+ | $menu_aMuleGui->set_sensitive($config->{'aMuleGuiOk'}); | ||
+ | } | ||
+ | |||
+ | # pathsVerify comprobar la ruta de las aplicaciones | ||
+ | sub pathsVerify{ | ||
+ | foreach my $app (@appList) { | ||
+ | $config->{$app . 'Ok'} = (-x $config->{$app . 'App'}); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | # inicializar comprobaciones iniciales | ||
+ | sub inicializar { | ||
+ | my $tmpStr; | ||
+ | my $runDaemon; | ||
+ | |||
+ | # Comprobar si ya estamos en marcha | ||
+ | if (-f $apppid){ | ||
+ | my $appVerify=0; | ||
+ | # Comprobar si realmente la aplicación está en marcha. | ||
+ | if (open(APPPID, $apppid)){ | ||
+ | my $line; | ||
+ | while ($line = <APPPID>) { | ||
+ | chop($line); last; | ||
+ | } | ||
+ | close(APPPID); | ||
+ | $appVerify=&isRunProcess($line); | ||
+ | } | ||
+ | if ($appVerify){ | ||
+ | $tmpStr = "<b>" .appRel . "</b> ya está funcionando!\n\n"; | ||
+ | $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = 'DEFAULT'; | ||
+ | &showMessage( 'error', flushChars($tmpStr), 'ok'); | ||
+ | exit -1; | ||
+ | } else {unlink $apppid} | ||
+ | } | ||
+ | |||
+ | # Iniciar Bloqueo | ||
+ | logsys ("msg", "Iniciando archivo de bloqueo"); | ||
+ | if (open LOG, ">$apppid"){print LOG "$$\n"} | ||
+ | # Cargar la configuración | ||
+ | logsys ("msg", "Cargando la configuración"); | ||
+ | &loadConfig; | ||
+ | readSignatureConf; | ||
+ | |||
+ | # Comprobar el estado del aMule como servicio | ||
+ | if ($config->{'aMuledOn'}){ | ||
+ | logsys ("msg", "Iniciando la verificación de la existencia de amuled"); | ||
+ | if (open(PROCESOS,"ps -A |")){ | ||
+ | while (<PROCESOS>){ | ||
+ | $runDaemon = 1 if ($_ =~ /amuled/); | ||
+ | } | ||
+ | close PROCESOS; | ||
+ | } | ||
+ | if (!$runDaemon) { $runDaemon = 1; | ||
+ | logsys ("msg", "No se detecta. Iniciando amuled ..."); | ||
+ | if (open(AMULED,"$binaMuled |")){ | ||
+ | my $aMuleRun; | ||
+ | while (<AMULED>){ | ||
+ | logsys ("msg", $_); | ||
+ | logsys ("msg", "ATENCIÓN: Cambie la orden [$binaMuled] bajo su responsabilidad") if $_ =~ /binary requires/; | ||
+ | undef $runDaemon if $_ =~ /binary requires/; | ||
+ | $aMuleRun = 1 if $_ =~ /Raising current running instance/; | ||
+ | } | ||
+ | close AMULED; | ||
+ | if ($aMuleRun){ | ||
+ | logsys ("msg", "*"x56 ); | ||
+ | logsys ("msg", "*"x5 ." Se ha detectado que el aMule está en marcha " ."*"x6 ); | ||
+ | logsys ("msg", "*"x56 ); | ||
+ | logsys ("msg", "aMulet.pl se diseñó pensando en las herramientas remotas" ); | ||
+ | logsys ("msg", "*"x56 ); | ||
+ | logsys ("msg", "* FUNCIONARÍA, pero no veo la necesidad de ello. STOP!!" ); | ||
+ | logsys ("msg", "*"x56 ); | ||
+ | undef $runDaemon; | ||
+ | }; | ||
+ | logsys ("msg", "El amuled ha sido puesto en marcha.") if $runDaemon; | ||
+ | } else { | ||
+ | undef $runDaemon; | ||
+ | logsys ("msg", "No se ha podido ejecutar el amuled!"); | ||
+ | logsys ("msg", "Se puede indicar en la configuración que se salte este paso"); | ||
+ | $tmpStr = "<u><b>No se ha podido ejecutar aMuled</b></u>.\n\n"; | ||
+ | $tmpStr .= "¿Desactivo la opción de arrancar el amuled en la configuración?\n\n"; | ||
+ | $tmpStr .= "Desactive esta opción si el aMuled está residente en otra máquina de su red."; | ||
+ | $tmpStr .= "\n\nNo he detectado el aMuleGui." unless $config->{'aMuleGuiOk'}; | ||
+ | $tmpStr .= "\nDeberá indicar donde está situado éste en la configuración" unless $config->{'aMuleGuiOk'}; | ||
+ | my $confirmacion= &showMessage( 'question', flushChars($tmpStr), 'yes-no'); | ||
+ | if ($confirmacion eq 'yes'){ | ||
+ | $config->{'aMuledOn'}=0; | ||
+ | &saveConfig; | ||
+ | $runDaemon = 1; | ||
+ | }; | ||
+ | } | ||
+ | } else {logsys ("msg", "El aMuled ha sido detectado :))");} | ||
+ | } else { | ||
+ | $runDaemon = 1; | ||
+ | logsys ("msg", "ATENCIÓN No se detectará ni arrancará el aMuled"); | ||
+ | logsys ("msg", " Se puede modificar esto en la configuración"); | ||
+ | } | ||
+ | |||
+ | # Comprobar que la aplicación que arranca tras el click en el icono existe. | ||
+ | # Esto no afectará al retorno de esta función. | ||
+ | if ($runDaemon){ | ||
+ | logsys ("msg", "Verificando la aplicación que responde al click del icono."); | ||
+ | if (!$config->{$config->{'appOnClick'} . 'Ok'}){ | ||
+ | $tmpStr = "Debe indicar en la configuración dónde residen el ejecutable\n"; | ||
+ | $tmpStr .= "de la aplicación <b>$config->{'appOnClick'}</b> o escoger otra\n"; | ||
+ | $tmpStr .= "aplicación que responda al click en el icono"; | ||
+ | &showMessage( 'warning', flushChars($tmpStr), 'ok'); | ||
+ | &opcionesGui; | ||
+ | } | ||
+ | } # TODO: Intentar mostrarlo como modal y esperar respuesta. | ||
+ | return $runDaemon; | ||
+ | } | ||
+ | |||
+ | # visorTexto Crea una ventana Gtk en la que muestra el logfile del aMule | ||
+ | sub visorTexto { | ||
+ | logsys ("debug", "sub: visorTexto start"); | ||
+ | my ($widget, $event) = @_; | ||
+ | logsys ("debug", "Deshabilitando la llamada en el menú"); | ||
+ | $widget->set_sensitive(0); | ||
+ | my $visorTextWin = Gtk2::Window->new("toplevel"); | ||
+ | my $vbox = Gtk2::VBox->new; | ||
+ | my $scrolledwindow = Gtk2::ScrolledWindow->new; | ||
+ | my $textBuffer = Gtk2::TextBuffer->new; | ||
+ | my $ok = Gtk2::Button->new_from_stock("gtk-close"); | ||
+ | my $textView = Gtk2::TextView->new_with_buffer($textBuffer); | ||
+ | my $LineaLog; | ||
+ | |||
+ | $visorTextWin->set_title('Visor de Texto'); | ||
+ | $visorTextWin->set_position('center'); | ||
+ | $visorTextWin->set_default_size(640, 300); | ||
+ | logsys ("debug", "Leyendo " . $config->{'aMuleDir'} . "/logfile"); | ||
+ | open (LOGFILE, $config->{'aMuleDir'} . "/logfile") || logsys ("warning", $config->{'aMuleDir'} . "/logfile: $!"); | ||
+ | while (<LOGFILE>) {$LineaLog .= $_;} | ||
+ | close LOGFILE; | ||
+ | $textView->set_editable(0); | ||
+ | $textView->set_cursor_visible(0); | ||
+ | $textBuffer->set_text($LineaLog); | ||
+ | $scrolledwindow->set_policy('automatic', 'automatic'); | ||
+ | |||
+ | $scrolledwindow->add($textView); | ||
+ | $vbox->add($scrolledwindow ); | ||
+ | $vbox->pack_end($ok, 0, 0, 3); | ||
+ | $visorTextWin->add($vbox); | ||
+ | |||
+ | $ok->signal_connect("clicked", sub { $visorTextWin->destroy; } ); | ||
+ | $visorTextWin->signal_connect('destroy' => sub { $widget->set_sensitive(1); }); | ||
+ | logsys ("msg", "Mostrando la ventana de logs"); | ||
+ | $visorTextWin->show_all; | ||
+ | } | ||
+ | |||
+ | # isRunProcess comprobará si un proceso está en ejecución | ||
+ | sub isRunProcess { | ||
+ | my ($proceso) = @_; | ||
+ | my $runDaemon = 0; | ||
+ | if (open(PROCESOS,"ps -A |")){ | ||
+ | while (<PROCESOS>){$runDaemon = 1 if $_ =~ /^$proceso\s/;} | ||
+ | close PROCESOS; | ||
+ | } | ||
+ | return $runDaemon; | ||
+ | } | ||
+ | |||
+ | sub infoOnLine { | ||
+ | my $tmpStr = ''; | ||
+ | &onlineInfo if $config->{'signOn'}; | ||
+ | if ($config->{'signOn'} && $config->{'ConectStatus'}==1){ | ||
+ | $tmpStr = "\n\n<b>" . $config->{'nickName'} . "</b> con <b>aMule</b> [<i>"; | ||
+ | $tmpStr .= $config->{'aMuleVer'} . "</i>]\n"; | ||
+ | $tmpStr .= "está conectado al puerto <b>" . $config->{'portServ'}; | ||
+ | $tmpStr .= "</b> de <b>" . $config->{'nameServ'} . "</b>\ncon <b>ID "; | ||
+ | $tmpStr .= $config->{'typeId'}eq"H"?"alta</b>":"baja</b>"; | ||
+ | $tmpStr .= " y la <b>red kad "; | ||
+ | if ($config->{'kadStatus'}==2) {$tmpStr .= "bien conectada</b>\n"; | ||
+ | } elsif ($config->{'kadStatus'}==1) {$tmpStr .= "en firewalled</b>\n"; | ||
+ | } else {$tmpStr .= "desconectada</b>\n"}; | ||
+ | $tmpStr .= "lleva "; | ||
+ | my $tmpStr2 = $config->{'TimeRun'} % 60 . " segundos"; | ||
+ | my $tiempo = sprintf("%d",$config->{'TimeRun'} / 60); | ||
+ | $tmpStr2 = $tiempo % 60 . " minutos y $tmpStr2" if $tiempo; | ||
+ | $tiempo = sprintf("%d",$tiempo / 60) if $tiempo; | ||
+ | $tmpStr2 = $tiempo % 24 . " horas $tmpStr2" if $tiempo; | ||
+ | $tiempo = sprintf("%d",$tiempo / 24) if $tiempo; | ||
+ | $tmpStr2 = $tiempo . " dias $tmpStr2" if $tiempo; | ||
+ | $tmpStr .= $tmpStr2 . " conectado\n"; | ||
+ | $tmpStr .= "y en este tiempo ha descargado: <b>"; | ||
+ | $tmpStr .= sprintf("%.2f",$config->{'SessionDown'}/1048576) . " Mb</b>\n"; | ||
+ | $tmpStr .= "con lo que tiene un total descagado de "; | ||
+ | $tmpStr .= sprintf("%.2f",$config->{'totalDown'}/1048576) . " Mb\n"; | ||
+ | $tmpStr .= "Además comparte <b>" . $config->{'filesShared'} . "</b> archivos y en esta sesión\n"; | ||
+ | $tmpStr .= "se han subido <b>" . sprintf("%.2f",$config->{'SessionUp'}/1048576); | ||
+ | $tmpStr .= " Mb</b> obteniendo un\ntotal de " . sprintf("%.2f",$config->{'totalUp'}/1048576); | ||
+ | $tmpStr .= " Mb subidos a la Red,\nen cola tiene ahora mismo "; | ||
+ | $tmpStr .= $config->{'colaCli'} . " clientes"; | ||
+ | } | ||
+ | return flushChars($tmpStr); | ||
+ | } | ||
+ | |||
+ | # opcionesGui muestra la ventana de opciones | ||
+ | sub opcionesGui { | ||
+ | my ($widget, $event) = @_; | ||
+ | logsys ("debug", "Deshabilitando la llamada en el menú"); | ||
+ | $widget->set_sensitive(0) if defined $widget; | ||
+ | my $guiOpciones = Gtk2::Window->new; | ||
+ | my $vboxPrincipal = Gtk2::VBox->new; | ||
+ | my $notebook = Gtk2::Notebook->new; | ||
+ | my $select_aMuleGui = Gtk2::RadioButton->new('appOnClick', 'aMuleGui'); | ||
+ | my @grupo = $select_aMuleGui->get_group; | ||
+ | my $select_alc = Gtk2::RadioButton->new_with_label(@grupo, 'aLinkCreator'); | ||
+ | my $select_wxcas = Gtk2::RadioButton->new_with_label(@grupo, 'wxCas'); | ||
+ | my $check_aMuled_on = new Gtk2::CheckButton->new(flushChars('Arrancar aMule como servicio al principio (si no lo está)')); | ||
+ | my $vBoxTabRutas = Gtk2::VBox->new; | ||
+ | my $vBoxTabAbout = Gtk2::VBox->new; | ||
+ | my $hboxPrincipal = Gtk2::HBox->new; | ||
+ | my $hBoxTabRutas1 = Gtk2::HBox->new; | ||
+ | my $hBoxTabRutas2 = Gtk2::HBox->new; | ||
+ | my $hBoxTabRutas3 = Gtk2::HBox->new(1); | ||
+ | my $hseparator1 = Gtk2::HSeparator->new; | ||
+ | my $hseparator2 = Gtk2::HSeparator->new; | ||
+ | my $hseparator3 = Gtk2::HSeparator->new; | ||
+ | my $labelTabRutas = Gtk2::Label->new('General'); | ||
+ | my $labelTabAbout = Gtk2::Label->new('About'); | ||
+ | my $labelTabRut1 = Gtk2::Label->new('Relacionado con el Servicio amuled'); | ||
+ | my $labelTabRut2 = Gtk2::Label->new('aMule Home Dir'); | ||
+ | my $labelTabRut3 = Gtk2::Label->new('Ruta a las aplicaciones'); | ||
+ | my $labelTabRut4 = Gtk2::Label->new('aMuleGui: '); | ||
+ | my $labelTabRut5 = Gtk2::Label->new('wxCas: '); | ||
+ | my $labelTabRut6 = Gtk2::Label->new('aLinkCreator: '); | ||
+ | my $labelTabRut7 = Gtk2::Label->new(flushChars('Icono que se mostrará en la barra')); | ||
+ | my $labelTabRut8 = Gtk2::Label->new('Icono:'); | ||
+ | my $labelTabRut9 = Gtk2::Label->new(flushChars('¿Qué aplicación arrancará tras hacer click en el icono?')); | ||
+ | my $labelAbout1 = Gtk2::Label->new('aMulet.pl'); | ||
+ | my $labelAbout2 = Gtk2::Label->new('by AnimAlf - AnimAlf@engendro.sytes.net'); | ||
+ | my $labelAbout3 = Gtk2::Label->new('una idea de tx2z en http://forum.amule.org'); | ||
+ | my $labelAbout4 = Gtk2::Label->new('Distribuido bajo la licencia GPL'); | ||
+ | my $labelAbout5 = Gtk2::Label->new('http://www.gnu.org/copyleft/gpl.html'); | ||
+ | my $labelAbout6 = Gtk2::Label->new; | ||
+ | my $edit_home_aMule = Gtk2::Entry->new; | ||
+ | my $edit_aMuleGui_path = Gtk2::Entry->new; | ||
+ | my $edit_wxcas_path = Gtk2::Entry->new; | ||
+ | my $edit_alc_path = Gtk2::Entry->new; | ||
+ | my $edit_icon_path = Gtk2::Entry->new; | ||
+ | my $btnOk = Gtk2::Button->new_from_stock("gtk-apply"); | ||
+ | my $btnCancel = Gtk2::Button->new_from_stock("gtk-cancel"); | ||
+ | my $btnRutas1 = Gtk2::Button->new('...'); | ||
+ | my $btnRutas2 = Gtk2::Button->new('...'); | ||
+ | my $btnRutas3 = Gtk2::Button->new('...'); | ||
+ | my $btnRutas4 = Gtk2::Button->new('...'); | ||
+ | my $btnRutas5 = Gtk2::Button->new('Selecciona'); | ||
+ | my $tableTabRutas = Gtk2::Table->new(3, 3, 0 ); | ||
+ | |||
+ | # Posicionando en la ventana principal | ||
+ | $guiOpciones->add($vboxPrincipal); | ||
+ | # Posicionando en el notebook (contenedor de pestañas) | ||
+ | $vboxPrincipal->add($notebook); | ||
+ | |||
+ | # primera pestaña | ||
+ | $notebook->append_page($vBoxTabRutas, $labelTabRutas); | ||
+ | |||
+ | $vBoxTabRutas->pack_start($labelTabRut1, 0, 0, 3); | ||
+ | $vBoxTabRutas->pack_start($hBoxTabRutas1, 0, 0, 3); | ||
+ | |||
+ | $hBoxTabRutas1->pack_start($labelTabRut2, 0, 0, 3); | ||
+ | $hBoxTabRutas1->add($edit_home_aMule); | ||
+ | $hBoxTabRutas1->pack_end($btnRutas1, 0, 0, 3); | ||
+ | $vBoxTabRutas->pack_start($check_aMuled_on, 0, 0, 3); | ||
+ | |||
+ | $vBoxTabRutas->pack_start($hseparator2, 0, 0, 3); | ||
+ | $vBoxTabRutas->pack_start($labelTabRut3, 0, 0, 3); | ||
+ | $vBoxTabRutas->pack_start($tableTabRutas, 0, 0, 3); | ||
+ | |||
+ | $tableTabRutas->attach($labelTabRut4, 0, 1, 0, 1, ['fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($edit_aMuleGui_path, 1, 2, 0, 1, ['expand', 'fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($btnRutas2, 2, 3, 0, 1, ['fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($labelTabRut5, 0, 1, 1, 2, ['fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($edit_wxcas_path, 1, 2, 1, 2, ['expand', 'fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($btnRutas3, 2, 3, 1, 2, ['fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($labelTabRut6, 0, 1, 2, 3, ['fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($edit_alc_path, 1, 2, 2, 3, ['expand', 'fill'], [], 0, 0 ); | ||
+ | $tableTabRutas->attach($btnRutas4, 2, 3, 2, 3, ['fill'], [], 0, 0 ); | ||
+ | |||
+ | $vBoxTabRutas->pack_start($hseparator1, 0, 0, 3); | ||
+ | $vBoxTabRutas->pack_start($labelTabRut9, 0, 0, 3); | ||
+ | $vBoxTabRutas->pack_start($hBoxTabRutas3, 0, 0, 3); | ||
+ | $hBoxTabRutas3->pack_start($select_aMuleGui, 0, 0, 3); | ||
+ | $hBoxTabRutas3->pack_start($select_alc, 0, 0, 3); | ||
+ | $hBoxTabRutas3->pack_start($select_wxcas, 0, 0, 3); | ||
+ | |||
+ | $vBoxTabRutas->pack_end($hBoxTabRutas2, 0, 0, 3); | ||
+ | |||
+ | $hBoxTabRutas2->pack_start($labelTabRut8, 0, 0, 3); | ||
+ | $hBoxTabRutas2->add($edit_icon_path); | ||
+ | $hBoxTabRutas2->pack_end($btnRutas5, 0, 0, 3); | ||
+ | |||
+ | $vBoxTabRutas->pack_end($labelTabRut7, 0, 0, 3); | ||
+ | $vBoxTabRutas->pack_end($hseparator3, 0, 0, 3); | ||
+ | |||
+ | # Segunda pestaña | ||
+ | $notebook->append_page($vBoxTabAbout, $labelTabAbout); | ||
+ | $vBoxTabAbout->pack_start($labelAbout1, 0, 0, 3); | ||
+ | $vBoxTabAbout->pack_start($labelAbout2, 0, 0, 3); | ||
+ | $vBoxTabAbout->pack_start($labelAbout3, 0, 0, 3); | ||
+ | $vBoxTabAbout->pack_start($labelAbout4, 0, 0, 3); | ||
+ | $vBoxTabAbout->pack_start($labelAbout5, 0, 0, 3); | ||
+ | $vBoxTabAbout->pack_start($labelAbout6, 0, 0, 3); | ||
+ | |||
+ | # Posicionando en la parte inferior de la ventana principal | ||
+ | $vboxPrincipal->pack_end($hboxPrincipal, 0, 0, 3); | ||
+ | $hboxPrincipal->pack_start($btnOk, 0, 0, 3); | ||
+ | $hboxPrincipal->pack_end($btnCancel, 0, 0, 3); | ||
+ | |||
+ | $labelAbout1->set_markup('<span foreground="DarkRed" size="x-large"><b>' . appRel . ' </b></span>'); | ||
+ | #TODO: Intentar conseguir una UrlLabel, fácil con gnome-open (pero y si no existe gnome?) | ||
+ | #http://forum.amule.org/thread.php?threadid=9751 | ||
+ | $labelAbout3->set_markup('<span>Una idea de <b>tx2z</b> en http://forum.amule.org</span>'); | ||
+ | #Añado un mini resumen de la información disponible en amulesig.dat | ||
+ | $labelAbout6->set_markup(infoOnLine); | ||
+ | if ($config->{'signOn'}){ | ||
+ | Glib::Timeout->add($config->{'signOnTime'}*1000, sub { | ||
+ | $labelAbout6->set_markup(infoOnLine); | ||
+ | $tray->send_message($config->{'signOnTime'}*1000, "[AnimAlf dice] No entiendo");}); | ||
+ | } | ||
+ | |||
+ | # Propiedades de la ventana principal | ||
+ | $guiOpciones->set_title('Opciones aMulet.pl'); | ||
+ | $guiOpciones->set_position('center'); | ||
+ | #TODO: Intentar que actuase como una ventana modal, como el showMessage | ||
+ | # y el punto de la llamada esperase la respuesta ok-cancel | ||
+ | logsys ("msg", "Mostrando la ventana de opciones"); | ||
+ | logsys ("warning", "*"x36) unless $widget; | ||
+ | logsys ("warning", "TODO: Que sea modal tipo showMessage") unless $widget; | ||
+ | logsys ("warning", "*"x36) unless $widget; | ||
+ | |||
+ | # Propiedades del notebook | ||
+ | $notebook->set_tab_pos('top'); | ||
+ | $notebook->set_show_tabs (1); | ||
+ | $notebook->set_show_border(1); | ||
+ | $notebook->set_scrollable (0); | ||
+ | $notebook->set_tab_hborder(2); | ||
+ | $notebook->set_tab_vborder(2); | ||
+ | |||
+ | # alineando de algunas etiquetas | ||
+ | $labelTabRut4->set_alignment(1,0.5); | ||
+ | $labelTabRut5->set_alignment(1,0.5); | ||
+ | $labelTabRut6->set_alignment(1,0.5); | ||
+ | |||
+ | # Asignando la configuración. | ||
+ | $edit_home_aMule->set_text($config->{'aMuleDir'}); | ||
+ | $edit_aMuleGui_path->set_text($config->{'aMuleGuiApp'}); | ||
+ | $edit_wxcas_path->set_text($config->{'wxCasApp'}); | ||
+ | $edit_alc_path->set_text($config->{'aLinkCreatorApp'}); | ||
+ | $edit_icon_path->set_text($config->{'iconPath'}); | ||
+ | |||
+ | $check_aMuled_on->set_active($config->{'aMuledOn'}); | ||
+ | |||
+ | $select_wxcas->set_active($config->{'appOnClick'} eq 'wxCas'); | ||
+ | $select_alc->set_active($config->{'appOnClick'} eq 'aLinkCreator'); | ||
+ | $select_aMuleGui->set_active($config->{'appOnClick'} eq 'aMuleGui'); | ||
+ | |||
+ | $select_wxcas->set_sensitive($config->{'wxCasOk'}); | ||
+ | $select_alc->set_sensitive($config->{'aLinkCreatorOk'}); | ||
+ | $select_aMuleGui->set_sensitive($config->{'aMuleGuiOk'}); | ||
+ | |||
+ | # Lo mostramos todo | ||
+ | $guiOpciones->show_all; | ||
+ | # La asignación de señales | ||
+ | $btnOk->signal_connect("clicked", sub { | ||
+ | my ($tmpStr, $tmpStr1); | ||
+ | |||
+ | $tmpStr1 = 'wxCas' if $select_wxcas->get_active; | ||
+ | $tmpStr1 = 'aLinkCreator' if $select_alc->get_active; | ||
+ | $tmpStr1 = 'aMuleGui' if $select_aMuleGui->get_active; | ||
+ | |||
+ | $tmpStr .= $edit_home_aMule->get_text . ": No es un directorio\n" | ||
+ | if !(-d $edit_home_aMule->get_text); | ||
+ | $tmpStr .= $edit_aMuleGui_path->get_text . ": <b>No es un ejecutable</b> (o no existe)\n" | ||
+ | if !(-x $edit_aMuleGui_path->get_text); | ||
+ | $tmpStr .= $edit_wxcas_path->get_text . ": <b>No es un ejecutable</b> (o no existe)\n" | ||
+ | if !(-x $edit_wxcas_path->get_text); | ||
+ | $tmpStr .= $edit_alc_path->get_text . ": <b>No es un ejecutable</b> (o no existe)\n" | ||
+ | if !(-x $edit_alc_path->get_text); | ||
+ | $tmpStr .= $edit_icon_path->get_text . ": <b>No parece que exista</b>\n" | ||
+ | if !(-e $edit_icon_path->get_text); | ||
+ | |||
+ | if (defined $tmpStr){ | ||
+ | $tmpStr = "<b>Se ha detectado lo siguiente:</b>\n\n$tmpStr\n\n" . flushChars("¿Desea continuar de todos modos?"); | ||
+ | my $confirmacion= &showMessage( 'question', $tmpStr, 'yes-no'); | ||
+ | return if ($confirmacion eq 'no'); | ||
+ | } | ||
+ | |||
+ | $config->{'appOnClick'} = 'wxCas' if $select_wxcas->get_active; | ||
+ | $config->{'appOnClick'} = 'aLinkCreator' if $select_alc->get_active; | ||
+ | $config->{'appOnClick'} = 'aMuleGui' if $select_aMuleGui->get_active; | ||
+ | |||
+ | $config->{'aMuleDir'} = $edit_home_aMule->get_text; | ||
+ | $config->{'aMuleGuiApp'} = $edit_aMuleGui_path->get_text; | ||
+ | $config->{'wxCasApp'} = $edit_wxcas_path->get_text; | ||
+ | $config->{'aLinkCreatorApp'} = $edit_alc_path->get_text; | ||
+ | &showMessage( 'info', flushChars("El icono cambiará cuando reinicie la aplicación."), 'ok') | ||
+ | if $config->{'iconPath'} ne $edit_icon_path->get_text; | ||
+ | $config->{'iconPath'} = $edit_icon_path->get_text; | ||
+ | |||
+ | $config->{'aMuledOn'} = $check_aMuled_on->get_active; | ||
+ | |||
+ | &saveConfig; pathsVerify; popUpsAct; readSignatureConf; | ||
+ | $guiOpciones->destroy; | ||
+ | } | ||
+ | ); | ||
+ | $btnCancel->signal_connect("clicked", sub { $guiOpciones->destroy; } ); | ||
+ | $guiOpciones->signal_connect('destroy' => sub {$widget->set_sensitive(1) if defined $widget;}); | ||
+ | $btnRutas1->signal_connect('clicked' => sub { dialogOpen($edit_home_aMule, | ||
+ | 'Seleccione el directorio home de aMule', 'select-folder'); }); | ||
+ | $btnRutas2->signal_connect('clicked' => sub { dialogOpen($edit_aMuleGui_path, | ||
+ | flushChars('Seleccione la aplicación aMuleGui'), 'open'); }); | ||
+ | $btnRutas3->signal_connect('clicked' => sub { dialogOpen($edit_wxcas_path, | ||
+ | flushChars('Seleccione la aplicación wxCas'), 'open'); }); | ||
+ | $btnRutas4->signal_connect('clicked' => sub { dialogOpen($edit_alc_path, | ||
+ | flushChars('Seleccione la aplicación aLinCreator'), 'open'); }); | ||
+ | $btnRutas5->signal_connect('clicked' => sub { dialogOpen($edit_icon_path, | ||
+ | flushChars('Seleccione el icono que utilizará aMulet'), 'open'); }); | ||
+ | } | ||
+ | |||
+ | # loadConfig carga la configuración o la crea si no existe | ||
+ | sub loadConfig { | ||
+ | if ( open( CONFIGFILE, "$ENV{HOME}/.aMule/amulet.rc" ) ) { | ||
+ | while (<CONFIGFILE>) { | ||
+ | if ( $_ =~ /(\w+)\s=\s(.+)/ ) { $config->{$1} = $2 } | ||
+ | } | ||
+ | close CONFIGFILE; | ||
+ | } else { | ||
+ | # es la primera vez. | ||
+ | mkdir "$ENV{HOME}/.aMule" unless (-d "$ENV{HOME}/.aMule"); | ||
+ | $config = { # Por defecto | ||
+ | 'aMuleDir' => "$ENV{'HOME'}/.aMule", | ||
+ | 'aMuleGuiApp' => 'amulegui', | ||
+ | 'wxCasApp' => 'wxcas', | ||
+ | 'aLinkCreatorApp' => 'alc', | ||
+ | 'iconPath' => '/usr/share/pixmaps/amule.xpm', | ||
+ | 'appOnClick' => 'aMuleGui', | ||
+ | 'aMuledOn' => 1 | ||
+ | }; | ||
+ | foreach my $app (@appList) { | ||
+ | $config->{$app . 'App'} = which($config->{$app . 'App'}); | ||
+ | } | ||
+ | pathsVerify; | ||
+ | &saveConfig; | ||
+ | } | ||
+ | pathsVerify; | ||
+ | } | ||
+ | |||
+ | # saveConfig guarda la configuración en un archivo | ||
+ | sub saveConfig { | ||
+ | my @keyList = ('aMuleDir', 'aMuleGuiApp', 'wxCasApp', | ||
+ | 'aLinkCreatorApp', 'iconPath', 'appOnClick', 'aMuledOn'); | ||
+ | if ( open( CONFIGFILE, '>', "$ENV{HOME}/.aMule/amulet.rc" ) ) { | ||
+ | foreach my $key (@keyList) { | ||
+ | print CONFIGFILE "$key = $config->{$key}\n" if $config->{$key} ne ''; | ||
+ | } | ||
+ | close CONFIGFILE; | ||
+ | }else {logSys("warning", "No se puede escribir en el archivo de configuración!");} | ||
+ | }; | ||
+ | |||
+ | # showMessage Muestra una ventana con un mensaje, y espera respuesta. | ||
+ | sub showMessage { | ||
+ | #$icon info warning error question | ||
+ | #$type none ok close cancel yes-no ok-cancel | ||
+ | my ($icon,$text,$type) = @_; | ||
+ | my $dialog = Gtk2::MessageDialog->new_with_markup (undef, | ||
+ | [qw/modal destroy-with-parent/], $icon, $type, sprintf "$text"); | ||
+ | my $retval = $dialog->run; | ||
+ | $dialog->destroy; | ||
+ | return $retval; | ||
+ | } | ||
+ | |||
+ | # which Devuelve el path completo a la aplicación. | ||
+ | sub which { | ||
+ | my $appFile = shift; | ||
+ | foreach (split(':', $ENV{PATH})) { | ||
+ | my $tmpStr = "$_/$appFile"; | ||
+ | if (-x $tmpStr) { | ||
+ | $appFile = $tmpStr; | ||
+ | last; | ||
+ | } | ||
+ | } | ||
+ | return $appFile; | ||
+ | } | ||
+ | |||
+ | # dialogOpen ventana de selección de archivos o directorios y escribe | ||
+ | # el resultado en en el entry que debe ser el primer parámetro. | ||
+ | sub dialogOpen { | ||
+ | # $widget debe ser un entry | ||
+ | # $type open save select-folder create-folder | ||
+ | my($widget,$caption,$type) =@_; | ||
+ | my $chooserDialog = Gtk2::FileChooserDialog->new ($caption, undef, $type, | ||
+ | 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok'); | ||
+ | my $filename = $chooserDialog->get_filename if 'ok' eq $chooserDialog->run; | ||
+ | $widget->set_text ($filename) if defined $filename; | ||
+ | $chooserDialog->destroy; | ||
+ | return; | ||
+ | } | ||
+ | </nowiki></pre> |
Revision as of 00:20, 7 December 2006
aMulet.pl source
#!/usr/bin/perl -w # # file aMulet.pl # Copyright by AnimAlf # # This lines are under the GNU General Public License. # http://www.gnu.org/copyleft/gpl.html # # aMulet - la t final en catalán le indica diminutivo # También se traduce como amuleto use strict; my $binaMuled = 'amuled -f'; my $apppid = "$ENV{HOME}/.tx2z.pid"; my $logMode = "warning"; # debug warning msg my $verbose = 1; # true false if (!defined($ENV{'DISPLAY'})){ print &appRel . "\nATENCIÓN: Este script necesita ser ejecutado bajo las X Window\n"; exit -1; } eval "use Gtk2::TrayIcon;"; if ($@) { print &appRel; print "\n\nATENCIÓN: Este script necesita el módulo Gtk2::TrayIcon\n\n"; print "Puede instalarlo a través de CPAN del siguiente modo:\n\n"; print "\t\tperl -MCPAN -e shell\n"; print "\t\tinstall Gtk2::TrayIcon\n\n"; print "bye\n"; exit -1; } my $modUniCode; eval "use Unicode::MapUTF8 qw(from_utf8);"; $modUniCode = !$@; my $config = {}; my @appList = ( 'aMuleGui', 'wxCas', 'aLinkCreator'); # Los procesos hijo envían esta señal al padre cuando terminan y ésta # debe ser atendida, si no se quedan zombies hasta que termine el padre. $SIG{CHLD} = \&finalHijo; # Si se recibe cualquier señal que pueda provocar la interrupción del # normal funcionamiento, entonces nos encargamos de finalizar correctamente. $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = \&finalizar; # Iniciando Gtk2 Gtk2->init; # Comprobaciones iniciales. Cargar configuración. if (!&inicializar){ logsys ("msg", &appRel ." ha abortado el arranque."); unlink $apppid or die "No puedo eliminar el archivo de bloqueo"; exit -1; } logsys ("msg", &appRel ." iniciado"); # Formas Gtk2 my $menu = Gtk2::Menu->new(); my $menu_opciones = Gtk2::MenuItem->new("opciones"); my $menu_aLinkCreator = Gtk2::MenuItem->new("aLinkCreator"); my $menu_wxCas = Gtk2::MenuItem->new("wxCas"); my $menu_aMuleGui = Gtk2::MenuItem->new("aMuleGui"); my $menu_verLog = Gtk2::MenuItem->new("aMule log"); my $menuSalir = Gtk2::MenuItem->new("Salir"); my $pic; eval {$pic = Gtk2::Gdk::Pixbuf->new_from_file ($config->{'iconPath'});}; if ($@){ my @aMulet_xpm = ('18 24 17 1', ' c None', '. c #312A28', '+ c #524842', '@ c #D42238', '# c #835128', '$ c #985A20', '% c #6A6B6A', '& c #AA7B50', '* c #EC5867', '= c #BF7B3F', '- c #C9792F', '; c #898989', '> c #E39854', ', c #CB9D83', '" c #A9AAAA', ') c #CDCBC9', '! c #F4F5F3', ' ', ' $ ', ' !> ', ' #! )$$ ', ' ## #-$ ', ' )##$ -,# ', ' .+##)$,) ', ' ...$,!" ', ' ".$=-$" ', ' ;==-!= ', ' " >! " ', ' ; !& ; ', ' " !)))" ', ' """"""! ', ' %!.""""); ', ' ;))";;;"%;;) ', ' ">-)";;;;"->"" ', ' )-=$,;;%@,->$) ', ' ;%--#=>>**+%%; ', ' +....&=>>>>#!))! ', '%"-=##$>>>>=&$--;;', '+)-=##&=>>>=#=->)+', '%;;=$+.+>>++$->,;%', ' " . '); $pic = Gtk2::Gdk::Pixbuf->new_from_xpm_data (@aMulet_xpm); logsys ("warning", "Error al cargar el icono: " . $config->{'iconPath'}); logsys ("msg", "Se procede a cargar el icono interno."); } my $img= Gtk2::Image->new_from_pixbuf($pic->scale_simple(18, 24, "tiles")); my $tray= Gtk2::TrayIcon->new("trayicon"); my $paraEvent = Gtk2::EventBox->new; my $trayTooltip = Gtk2::Tooltips->new; my $SeparadorMenu1 = Gtk2::SeparatorMenuItem->new; my $SeparadorMenu2 = Gtk2::SeparatorMenuItem->new; my $SeparadorMenu3 = Gtk2::SeparatorMenuItem->new; $menu->append($menu_verLog); $menu->append($SeparadorMenu1); $menu->append($menu_opciones); $menu->append($SeparadorMenu2); $menu->append($menu_aLinkCreator); $menu->append($menu_wxCas); $menu->append($menu_aMuleGui); $menu->append($SeparadorMenu3); $menu->append($menuSalir); $paraEvent->add($img); $tray->add($paraEvent); &statusText; # Tratamiento de señales logsys ("debug", "Asignación de señales"); $tray->signal_connect ('button-press-event' => \&ClickOnIcon); $menu_opciones->signal_connect('activate' => \&opcionesGui); $menu_verLog->signal_connect('activate' => \&visorTexto); $menu_aLinkCreator->signal_connect('activate' => sub {&extAppStatus('aLinkCreator')}); $menu_wxCas->signal_connect('activate' => sub {&extAppStatus('wxCas')}); $menu_aMuleGui->signal_connect('activate' => sub {&extAppStatus('aMuleGui')}); $menuSalir->signal_connect('activate' => \&finalizar); Glib::Timeout->add($config->{'signOnTime'}*1000, \&statusText) if $config->{'signOn'}; # show sobre los witgets para que sean visibles logsys ("debug", "Show sobre los witgets"); $menu->show_all; $tray->show_all; &popUpsAct; # iniciando bucle de mensajes logsys ("debug", "Inicio del bucle de mensajes"); Gtk2->main; # Fin. Aquí termina el flujo. ############# # Funciones # ############# # statusText Establece el texto del toolTip sub statusText{ my $tmpStr = &appRel ." - Click derecho para opciones"; if ($config->{'signOn'}){ &onlineInfo; # my $tmpStr; if ($config->{'ConectStatus'}){ if ($config->{'typeId'}eq"H"){$tmpStr = "[ID alta]"} elsif ($config->{'typeId'}eq"L"){$tmpStr = "[ID baja]"} else {$tmpStr = "[Conectando]"} $tmpStr .= " Down:" . $config->{'downSpeed'}; $tmpStr .= " kb/s Up:" . $config->{'upSpeed'} ." Kb/s "; if ($config->{'kadStatus'}==2) {$tmpStr .= "[kad ok]"; } elsif ($config->{'kadStatus'}==1) {$tmpStr .= "[kad firewalled]"; } else {$tmpStr .= "[kad off]"}; } else {$tmpStr = &appRel . " [aMuled No Conectado]"} } $trayTooltip->set_tip($tray, $tmpStr); $tray->send_message($config->{'signOnTime'}*1000, "[AnimAlf dice] No entiendo"); } # signatureOn Comprueba OnlineSignature en amule.conf sub readSignatureConf { $config->{'signOn'} = 0; $config->{'signOnTime'} = 0; if (-f $config->{'aMuleDir'} . "/amule.conf"){ if ( open( CONFIGFILE, $config->{'aMuleDir'} . "/amule.conf" ) ) { while (<CONFIGFILE>) { if ( $_ =~ /^OnlineSignature=(.+)/ ) { $config->{'signOn'} = $1 } if ( $_ =~ /^OnlineSignatureUpdate=(.+)/ ) { $config->{'signOnTime'} = $1 } } close CONFIGFILE; } } } # onlineInfo Recoge la información de amulesig.dat sub onlineInfo { if ( open( SIGNFILE, $config->{'aMuleDir'} . "/amulesig.dat" ) ) { my @signFile; while (<SIGNFILE>) { $_ =~ /(.+)\n$/; push (@signFile, $1) } close SIGNFILE; $config->{'ConectStatus'} = $signFile[0]; $config->{'nameServ'} = $signFile[1]; $config->{'ipServ'} = $signFile[2]; $config->{'portServ'} = $signFile[3]; $config->{'typeId'} = $signFile[4]; $config->{'kadStatus'} = $signFile[5]; $config->{'downSpeed'} = $signFile[6]; $config->{'upSpeed'} = $signFile[7]; $config->{'colaCli'} = $signFile[8]; $config->{'filesShared'} = $signFile[9]; $config->{'nickName'} = $signFile[10]; $config->{'totalDown'} = $signFile[11]; $config->{'totalUp'} = $signFile[12]; $config->{'aMuleVer'} = $signFile[13]; $config->{'SessionDown'} = $signFile[14]; $config->{'SessionUp'} = $signFile[15]; $config->{'TimeRun'} = $signFile[16]; } } # finalHijo atender la señal de los hijos (cuando terminan la mandan) sub finalHijo { $SIG{CHLD} = \&finalHijo; my $pid = wait; return unless $config->{$pid}; # El system() realiza un fork() también. logsys ("msg", "Acaba de finalizar: " . $config->{$pid} . " [" . $config->{$config->{$pid} . 'Pid'} . "]"); undef $config->{$config->{$pid} . 'Pid'}; undef $config->{$pid}; } # finalizar correctamente y eliminar bloqueo sub finalizar { $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = \&finalizar; logsys ("msg", "Finalizando ..."); #Finalizar el bucle de mensajes Gtk2->main_quit; #Comprobar que no quede ninguna aplicación hijo en funcionamiento #y si existe eliminarlas antes de finalizar no vayan a quedar zombies. logsys ("msg", "Finalizando posibles hijos"); # Ahora la señal de retorno del hijo la trataremos aquí. $SIG{CHLD} = 'DEFAULT'; foreach my $app (@appList) { if (defined $config->{$app . "Pid"}){ logsys ("msg", "[$app] está en marcha. Finalizándolo ..."); kill ('SIGTERM', $config->{$app . "Pid"}); waitpid($config->{$app . "Pid"}, 0); } } logsys ("msg", "No quedan procesos hijo de " . &appRel . " en el sistema"); #TODO Si archivo de bloqueo es usado para log volcar a otro sitio. logsys ("warning", "TODO: volcar archivo log a log final [si se le ordena]"); logsys ("msg", "Terminada la ejecución"); logsys ("msg", "bye ;-)\n\n".&appRel."\n"); # borrar archivo de bloqueo unlink $apppid or die "No puedo eliminar el archivo de bloqueo $apppid"; } # flushChars transforma utf8 a iso-8859-1 sub flushChars { my ($tmpStr) = @_; $tmpStr =~ s/([\200-\377]+)/from_utf8({ -string => $1, -charset => 'ISO-8859-1'})/eg if $modUniCode; return $tmpStr; } #logsys Mini sistema de logs. sub logsys { my ($mode, $text) = @_; my $tmpStr; if (open LOG, ">>$apppid") { if (($logMode eq "debug" && ($mode eq "debug" or $mode eq "warning")) || ($logMode eq "warning" && ($mode eq "warning" or $mode eq "msg")) || ($logMode eq "msg" && $mode eq "msg")){ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime (time); $year += 1900; $mon ++; $tmpStr="[" . uc($mode) . "] " . sprintf("%02d",$mday) . "-" . sprintf("%02d",$mon) . "-$year " . sprintf("%02d",$hour) . ":" . sprintf("%02d",$min) . ":" . sprintf("%02d",$sec) . " $text\n"; print LOG $tmpStr; print $tmpStr if $verbose; } close LOG; } } # ClickOnIcon se lanzará tras un click en el TrayIcon. # Para diferenciar el botón del ratón que se pulsó. sub ClickOnIcon { logsys ("debug", "sub: ClickOnIcon start"); my ($widget, $event) = @_; return 1 if $event->button == 2; $menu->popup(undef, undef, undef, undef, $event->button,$event->time) if $event->button == 3; &extAppStatus($config->{'appOnClick'}) if $event->button == 1; } # extAppStatus lanzará una instancia de la aplicación si no existe sub extAppStatus { logsys ("debug", "sub: extAppStatus start"); my ($refApp) = @_; $config->{ $refApp . 'Pid'} = fork() unless ($config->{ $refApp . 'Pid'}); # Crea un proceso hijo die "error al hacer fork: $!" if !defined($config->{$refApp . 'Pid'}); if ( $config->{$refApp . 'Pid'} == 0) { # Si se trata del proceso hijo logsys ("msg", "Iniciando proceso hijo con [$refApp]"); if ($config->{$refApp . 'Ok'}) { $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = 'DEFAULT'; logsys ("warning", "Redirección de STDOUT para $refApp a $apppid"); open STDOUT, ">>$apppid"; exec ($config->{$refApp . 'App'}) || die "ATENCIÓN: Falló la ejecución de $refApp"; } else {exit -1} } else { # Circuito del proceso padre logsys ("msg", "Circuito del proceso padre [hijo=>$refApp pid:" . $config->{$refApp . 'Pid'} . "]"); # Asigno una clave en la configuración con el valor de la pid con el padre $config->{$config->{$refApp . 'Pid'}} = $refApp unless $config->{$config->{$refApp . 'Pid'}}; # a ejecutar por el proceso padre # TODO: Enviar setFocus a la aplicación # } } # appRel nombre y versión del script sub appRel { $0=~/.*\/(.*)$/; my $fileRun = $1; $fileRun = $0 unless $fileRun; $fileRun = "aMulet.pl [$1]" if $fileRun ne 'aMulet.pl'; return $fileRun . " v.1.2 beta"; } # popUpsAct des/activar apartados del menú sub popUpsAct { $menu_aLinkCreator->set_sensitive($config->{'aLinkCreatorOk'}); $menu_wxCas->set_sensitive($config->{'wxCasOk'}); $menu_aMuleGui->set_sensitive($config->{'aMuleGuiOk'}); } # pathsVerify comprobar la ruta de las aplicaciones sub pathsVerify{ foreach my $app (@appList) { $config->{$app . 'Ok'} = (-x $config->{$app . 'App'}); } } # inicializar comprobaciones iniciales sub inicializar { my $tmpStr; my $runDaemon; # Comprobar si ya estamos en marcha if (-f $apppid){ my $appVerify=0; # Comprobar si realmente la aplicación está en marcha. if (open(APPPID, $apppid)){ my $line; while ($line = <APPPID>) { chop($line); last; } close(APPPID); $appVerify=&isRunProcess($line); } if ($appVerify){ $tmpStr = "<b>" .appRel . "</b> ya está funcionando!\n\n"; $SIG{TERM} = $SIG{QUIT} = $SIG{HUP} = $SIG{INT} = 'DEFAULT'; &showMessage( 'error', flushChars($tmpStr), 'ok'); exit -1; } else {unlink $apppid} } # Iniciar Bloqueo logsys ("msg", "Iniciando archivo de bloqueo"); if (open LOG, ">$apppid"){print LOG "$$\n"} # Cargar la configuración logsys ("msg", "Cargando la configuración"); &loadConfig; readSignatureConf; # Comprobar el estado del aMule como servicio if ($config->{'aMuledOn'}){ logsys ("msg", "Iniciando la verificación de la existencia de amuled"); if (open(PROCESOS,"ps -A |")){ while (<PROCESOS>){ $runDaemon = 1 if ($_ =~ /amuled/); } close PROCESOS; } if (!$runDaemon) { $runDaemon = 1; logsys ("msg", "No se detecta. Iniciando amuled ..."); if (open(AMULED,"$binaMuled |")){ my $aMuleRun; while (<AMULED>){ logsys ("msg", $_); logsys ("msg", "ATENCIÓN: Cambie la orden [$binaMuled] bajo su responsabilidad") if $_ =~ /binary requires/; undef $runDaemon if $_ =~ /binary requires/; $aMuleRun = 1 if $_ =~ /Raising current running instance/; } close AMULED; if ($aMuleRun){ logsys ("msg", "*"x56 ); logsys ("msg", "*"x5 ." Se ha detectado que el aMule está en marcha " ."*"x6 ); logsys ("msg", "*"x56 ); logsys ("msg", "aMulet.pl se diseñó pensando en las herramientas remotas" ); logsys ("msg", "*"x56 ); logsys ("msg", "* FUNCIONARÍA, pero no veo la necesidad de ello. STOP!!" ); logsys ("msg", "*"x56 ); undef $runDaemon; }; logsys ("msg", "El amuled ha sido puesto en marcha.") if $runDaemon; } else { undef $runDaemon; logsys ("msg", "No se ha podido ejecutar el amuled!"); logsys ("msg", "Se puede indicar en la configuración que se salte este paso"); $tmpStr = "<u><b>No se ha podido ejecutar aMuled</b></u>.\n\n"; $tmpStr .= "¿Desactivo la opción de arrancar el amuled en la configuración?\n\n"; $tmpStr .= "Desactive esta opción si el aMuled está residente en otra máquina de su red."; $tmpStr .= "\n\nNo he detectado el aMuleGui." unless $config->{'aMuleGuiOk'}; $tmpStr .= "\nDeberá indicar donde está situado éste en la configuración" unless $config->{'aMuleGuiOk'}; my $confirmacion= &showMessage( 'question', flushChars($tmpStr), 'yes-no'); if ($confirmacion eq 'yes'){ $config->{'aMuledOn'}=0; &saveConfig; $runDaemon = 1; }; } } else {logsys ("msg", "El aMuled ha sido detectado :))");} } else { $runDaemon = 1; logsys ("msg", "ATENCIÓN No se detectará ni arrancará el aMuled"); logsys ("msg", " Se puede modificar esto en la configuración"); } # Comprobar que la aplicación que arranca tras el click en el icono existe. # Esto no afectará al retorno de esta función. if ($runDaemon){ logsys ("msg", "Verificando la aplicación que responde al click del icono."); if (!$config->{$config->{'appOnClick'} . 'Ok'}){ $tmpStr = "Debe indicar en la configuración dónde residen el ejecutable\n"; $tmpStr .= "de la aplicación <b>$config->{'appOnClick'}</b> o escoger otra\n"; $tmpStr .= "aplicación que responda al click en el icono"; &showMessage( 'warning', flushChars($tmpStr), 'ok'); &opcionesGui; } } # TODO: Intentar mostrarlo como modal y esperar respuesta. return $runDaemon; } # visorTexto Crea una ventana Gtk en la que muestra el logfile del aMule sub visorTexto { logsys ("debug", "sub: visorTexto start"); my ($widget, $event) = @_; logsys ("debug", "Deshabilitando la llamada en el menú"); $widget->set_sensitive(0); my $visorTextWin = Gtk2::Window->new("toplevel"); my $vbox = Gtk2::VBox->new; my $scrolledwindow = Gtk2::ScrolledWindow->new; my $textBuffer = Gtk2::TextBuffer->new; my $ok = Gtk2::Button->new_from_stock("gtk-close"); my $textView = Gtk2::TextView->new_with_buffer($textBuffer); my $LineaLog; $visorTextWin->set_title('Visor de Texto'); $visorTextWin->set_position('center'); $visorTextWin->set_default_size(640, 300); logsys ("debug", "Leyendo " . $config->{'aMuleDir'} . "/logfile"); open (LOGFILE, $config->{'aMuleDir'} . "/logfile") || logsys ("warning", $config->{'aMuleDir'} . "/logfile: $!"); while (<LOGFILE>) {$LineaLog .= $_;} close LOGFILE; $textView->set_editable(0); $textView->set_cursor_visible(0); $textBuffer->set_text($LineaLog); $scrolledwindow->set_policy('automatic', 'automatic'); $scrolledwindow->add($textView); $vbox->add($scrolledwindow ); $vbox->pack_end($ok, 0, 0, 3); $visorTextWin->add($vbox); $ok->signal_connect("clicked", sub { $visorTextWin->destroy; } ); $visorTextWin->signal_connect('destroy' => sub { $widget->set_sensitive(1); }); logsys ("msg", "Mostrando la ventana de logs"); $visorTextWin->show_all; } # isRunProcess comprobará si un proceso está en ejecución sub isRunProcess { my ($proceso) = @_; my $runDaemon = 0; if (open(PROCESOS,"ps -A |")){ while (<PROCESOS>){$runDaemon = 1 if $_ =~ /^$proceso\s/;} close PROCESOS; } return $runDaemon; } sub infoOnLine { my $tmpStr = ''; &onlineInfo if $config->{'signOn'}; if ($config->{'signOn'} && $config->{'ConectStatus'}==1){ $tmpStr = "\n\n<b>" . $config->{'nickName'} . "</b> con <b>aMule</b> [<i>"; $tmpStr .= $config->{'aMuleVer'} . "</i>]\n"; $tmpStr .= "está conectado al puerto <b>" . $config->{'portServ'}; $tmpStr .= "</b> de <b>" . $config->{'nameServ'} . "</b>\ncon <b>ID "; $tmpStr .= $config->{'typeId'}eq"H"?"alta</b>":"baja</b>"; $tmpStr .= " y la <b>red kad "; if ($config->{'kadStatus'}==2) {$tmpStr .= "bien conectada</b>\n"; } elsif ($config->{'kadStatus'}==1) {$tmpStr .= "en firewalled</b>\n"; } else {$tmpStr .= "desconectada</b>\n"}; $tmpStr .= "lleva "; my $tmpStr2 = $config->{'TimeRun'} % 60 . " segundos"; my $tiempo = sprintf("%d",$config->{'TimeRun'} / 60); $tmpStr2 = $tiempo % 60 . " minutos y $tmpStr2" if $tiempo; $tiempo = sprintf("%d",$tiempo / 60) if $tiempo; $tmpStr2 = $tiempo % 24 . " horas $tmpStr2" if $tiempo; $tiempo = sprintf("%d",$tiempo / 24) if $tiempo; $tmpStr2 = $tiempo . " dias $tmpStr2" if $tiempo; $tmpStr .= $tmpStr2 . " conectado\n"; $tmpStr .= "y en este tiempo ha descargado: <b>"; $tmpStr .= sprintf("%.2f",$config->{'SessionDown'}/1048576) . " Mb</b>\n"; $tmpStr .= "con lo que tiene un total descagado de "; $tmpStr .= sprintf("%.2f",$config->{'totalDown'}/1048576) . " Mb\n"; $tmpStr .= "Además comparte <b>" . $config->{'filesShared'} . "</b> archivos y en esta sesión\n"; $tmpStr .= "se han subido <b>" . sprintf("%.2f",$config->{'SessionUp'}/1048576); $tmpStr .= " Mb</b> obteniendo un\ntotal de " . sprintf("%.2f",$config->{'totalUp'}/1048576); $tmpStr .= " Mb subidos a la Red,\nen cola tiene ahora mismo "; $tmpStr .= $config->{'colaCli'} . " clientes"; } return flushChars($tmpStr); } # opcionesGui muestra la ventana de opciones sub opcionesGui { my ($widget, $event) = @_; logsys ("debug", "Deshabilitando la llamada en el menú"); $widget->set_sensitive(0) if defined $widget; my $guiOpciones = Gtk2::Window->new; my $vboxPrincipal = Gtk2::VBox->new; my $notebook = Gtk2::Notebook->new; my $select_aMuleGui = Gtk2::RadioButton->new('appOnClick', 'aMuleGui'); my @grupo = $select_aMuleGui->get_group; my $select_alc = Gtk2::RadioButton->new_with_label(@grupo, 'aLinkCreator'); my $select_wxcas = Gtk2::RadioButton->new_with_label(@grupo, 'wxCas'); my $check_aMuled_on = new Gtk2::CheckButton->new(flushChars('Arrancar aMule como servicio al principio (si no lo está)')); my $vBoxTabRutas = Gtk2::VBox->new; my $vBoxTabAbout = Gtk2::VBox->new; my $hboxPrincipal = Gtk2::HBox->new; my $hBoxTabRutas1 = Gtk2::HBox->new; my $hBoxTabRutas2 = Gtk2::HBox->new; my $hBoxTabRutas3 = Gtk2::HBox->new(1); my $hseparator1 = Gtk2::HSeparator->new; my $hseparator2 = Gtk2::HSeparator->new; my $hseparator3 = Gtk2::HSeparator->new; my $labelTabRutas = Gtk2::Label->new('General'); my $labelTabAbout = Gtk2::Label->new('About'); my $labelTabRut1 = Gtk2::Label->new('Relacionado con el Servicio amuled'); my $labelTabRut2 = Gtk2::Label->new('aMule Home Dir'); my $labelTabRut3 = Gtk2::Label->new('Ruta a las aplicaciones'); my $labelTabRut4 = Gtk2::Label->new('aMuleGui: '); my $labelTabRut5 = Gtk2::Label->new('wxCas: '); my $labelTabRut6 = Gtk2::Label->new('aLinkCreator: '); my $labelTabRut7 = Gtk2::Label->new(flushChars('Icono que se mostrará en la barra')); my $labelTabRut8 = Gtk2::Label->new('Icono:'); my $labelTabRut9 = Gtk2::Label->new(flushChars('¿Qué aplicación arrancará tras hacer click en el icono?')); my $labelAbout1 = Gtk2::Label->new('aMulet.pl'); my $labelAbout2 = Gtk2::Label->new('by AnimAlf - AnimAlf@engendro.sytes.net'); my $labelAbout3 = Gtk2::Label->new('una idea de tx2z en http://forum.amule.org'); my $labelAbout4 = Gtk2::Label->new('Distribuido bajo la licencia GPL'); my $labelAbout5 = Gtk2::Label->new('http://www.gnu.org/copyleft/gpl.html'); my $labelAbout6 = Gtk2::Label->new; my $edit_home_aMule = Gtk2::Entry->new; my $edit_aMuleGui_path = Gtk2::Entry->new; my $edit_wxcas_path = Gtk2::Entry->new; my $edit_alc_path = Gtk2::Entry->new; my $edit_icon_path = Gtk2::Entry->new; my $btnOk = Gtk2::Button->new_from_stock("gtk-apply"); my $btnCancel = Gtk2::Button->new_from_stock("gtk-cancel"); my $btnRutas1 = Gtk2::Button->new('...'); my $btnRutas2 = Gtk2::Button->new('...'); my $btnRutas3 = Gtk2::Button->new('...'); my $btnRutas4 = Gtk2::Button->new('...'); my $btnRutas5 = Gtk2::Button->new('Selecciona'); my $tableTabRutas = Gtk2::Table->new(3, 3, 0 ); # Posicionando en la ventana principal $guiOpciones->add($vboxPrincipal); # Posicionando en el notebook (contenedor de pestañas) $vboxPrincipal->add($notebook); # primera pestaña $notebook->append_page($vBoxTabRutas, $labelTabRutas); $vBoxTabRutas->pack_start($labelTabRut1, 0, 0, 3); $vBoxTabRutas->pack_start($hBoxTabRutas1, 0, 0, 3); $hBoxTabRutas1->pack_start($labelTabRut2, 0, 0, 3); $hBoxTabRutas1->add($edit_home_aMule); $hBoxTabRutas1->pack_end($btnRutas1, 0, 0, 3); $vBoxTabRutas->pack_start($check_aMuled_on, 0, 0, 3); $vBoxTabRutas->pack_start($hseparator2, 0, 0, 3); $vBoxTabRutas->pack_start($labelTabRut3, 0, 0, 3); $vBoxTabRutas->pack_start($tableTabRutas, 0, 0, 3); $tableTabRutas->attach($labelTabRut4, 0, 1, 0, 1, ['fill'], [], 0, 0 ); $tableTabRutas->attach($edit_aMuleGui_path, 1, 2, 0, 1, ['expand', 'fill'], [], 0, 0 ); $tableTabRutas->attach($btnRutas2, 2, 3, 0, 1, ['fill'], [], 0, 0 ); $tableTabRutas->attach($labelTabRut5, 0, 1, 1, 2, ['fill'], [], 0, 0 ); $tableTabRutas->attach($edit_wxcas_path, 1, 2, 1, 2, ['expand', 'fill'], [], 0, 0 ); $tableTabRutas->attach($btnRutas3, 2, 3, 1, 2, ['fill'], [], 0, 0 ); $tableTabRutas->attach($labelTabRut6, 0, 1, 2, 3, ['fill'], [], 0, 0 ); $tableTabRutas->attach($edit_alc_path, 1, 2, 2, 3, ['expand', 'fill'], [], 0, 0 ); $tableTabRutas->attach($btnRutas4, 2, 3, 2, 3, ['fill'], [], 0, 0 ); $vBoxTabRutas->pack_start($hseparator1, 0, 0, 3); $vBoxTabRutas->pack_start($labelTabRut9, 0, 0, 3); $vBoxTabRutas->pack_start($hBoxTabRutas3, 0, 0, 3); $hBoxTabRutas3->pack_start($select_aMuleGui, 0, 0, 3); $hBoxTabRutas3->pack_start($select_alc, 0, 0, 3); $hBoxTabRutas3->pack_start($select_wxcas, 0, 0, 3); $vBoxTabRutas->pack_end($hBoxTabRutas2, 0, 0, 3); $hBoxTabRutas2->pack_start($labelTabRut8, 0, 0, 3); $hBoxTabRutas2->add($edit_icon_path); $hBoxTabRutas2->pack_end($btnRutas5, 0, 0, 3); $vBoxTabRutas->pack_end($labelTabRut7, 0, 0, 3); $vBoxTabRutas->pack_end($hseparator3, 0, 0, 3); # Segunda pestaña $notebook->append_page($vBoxTabAbout, $labelTabAbout); $vBoxTabAbout->pack_start($labelAbout1, 0, 0, 3); $vBoxTabAbout->pack_start($labelAbout2, 0, 0, 3); $vBoxTabAbout->pack_start($labelAbout3, 0, 0, 3); $vBoxTabAbout->pack_start($labelAbout4, 0, 0, 3); $vBoxTabAbout->pack_start($labelAbout5, 0, 0, 3); $vBoxTabAbout->pack_start($labelAbout6, 0, 0, 3); # Posicionando en la parte inferior de la ventana principal $vboxPrincipal->pack_end($hboxPrincipal, 0, 0, 3); $hboxPrincipal->pack_start($btnOk, 0, 0, 3); $hboxPrincipal->pack_end($btnCancel, 0, 0, 3); $labelAbout1->set_markup('<span foreground="DarkRed" size="x-large"><b>' . appRel . ' </b></span>'); #TODO: Intentar conseguir una UrlLabel, fácil con gnome-open (pero y si no existe gnome?) #http://forum.amule.org/thread.php?threadid=9751 $labelAbout3->set_markup('<span>Una idea de <b>tx2z</b> en http://forum.amule.org</span>'); #Añado un mini resumen de la información disponible en amulesig.dat $labelAbout6->set_markup(infoOnLine); if ($config->{'signOn'}){ Glib::Timeout->add($config->{'signOnTime'}*1000, sub { $labelAbout6->set_markup(infoOnLine); $tray->send_message($config->{'signOnTime'}*1000, "[AnimAlf dice] No entiendo");}); } # Propiedades de la ventana principal $guiOpciones->set_title('Opciones aMulet.pl'); $guiOpciones->set_position('center'); #TODO: Intentar que actuase como una ventana modal, como el showMessage # y el punto de la llamada esperase la respuesta ok-cancel logsys ("msg", "Mostrando la ventana de opciones"); logsys ("warning", "*"x36) unless $widget; logsys ("warning", "TODO: Que sea modal tipo showMessage") unless $widget; logsys ("warning", "*"x36) unless $widget; # Propiedades del notebook $notebook->set_tab_pos('top'); $notebook->set_show_tabs (1); $notebook->set_show_border(1); $notebook->set_scrollable (0); $notebook->set_tab_hborder(2); $notebook->set_tab_vborder(2); # alineando de algunas etiquetas $labelTabRut4->set_alignment(1,0.5); $labelTabRut5->set_alignment(1,0.5); $labelTabRut6->set_alignment(1,0.5); # Asignando la configuración. $edit_home_aMule->set_text($config->{'aMuleDir'}); $edit_aMuleGui_path->set_text($config->{'aMuleGuiApp'}); $edit_wxcas_path->set_text($config->{'wxCasApp'}); $edit_alc_path->set_text($config->{'aLinkCreatorApp'}); $edit_icon_path->set_text($config->{'iconPath'}); $check_aMuled_on->set_active($config->{'aMuledOn'}); $select_wxcas->set_active($config->{'appOnClick'} eq 'wxCas'); $select_alc->set_active($config->{'appOnClick'} eq 'aLinkCreator'); $select_aMuleGui->set_active($config->{'appOnClick'} eq 'aMuleGui'); $select_wxcas->set_sensitive($config->{'wxCasOk'}); $select_alc->set_sensitive($config->{'aLinkCreatorOk'}); $select_aMuleGui->set_sensitive($config->{'aMuleGuiOk'}); # Lo mostramos todo $guiOpciones->show_all; # La asignación de señales $btnOk->signal_connect("clicked", sub { my ($tmpStr, $tmpStr1); $tmpStr1 = 'wxCas' if $select_wxcas->get_active; $tmpStr1 = 'aLinkCreator' if $select_alc->get_active; $tmpStr1 = 'aMuleGui' if $select_aMuleGui->get_active; $tmpStr .= $edit_home_aMule->get_text . ": No es un directorio\n" if !(-d $edit_home_aMule->get_text); $tmpStr .= $edit_aMuleGui_path->get_text . ": <b>No es un ejecutable</b> (o no existe)\n" if !(-x $edit_aMuleGui_path->get_text); $tmpStr .= $edit_wxcas_path->get_text . ": <b>No es un ejecutable</b> (o no existe)\n" if !(-x $edit_wxcas_path->get_text); $tmpStr .= $edit_alc_path->get_text . ": <b>No es un ejecutable</b> (o no existe)\n" if !(-x $edit_alc_path->get_text); $tmpStr .= $edit_icon_path->get_text . ": <b>No parece que exista</b>\n" if !(-e $edit_icon_path->get_text); if (defined $tmpStr){ $tmpStr = "<b>Se ha detectado lo siguiente:</b>\n\n$tmpStr\n\n" . flushChars("¿Desea continuar de todos modos?"); my $confirmacion= &showMessage( 'question', $tmpStr, 'yes-no'); return if ($confirmacion eq 'no'); } $config->{'appOnClick'} = 'wxCas' if $select_wxcas->get_active; $config->{'appOnClick'} = 'aLinkCreator' if $select_alc->get_active; $config->{'appOnClick'} = 'aMuleGui' if $select_aMuleGui->get_active; $config->{'aMuleDir'} = $edit_home_aMule->get_text; $config->{'aMuleGuiApp'} = $edit_aMuleGui_path->get_text; $config->{'wxCasApp'} = $edit_wxcas_path->get_text; $config->{'aLinkCreatorApp'} = $edit_alc_path->get_text; &showMessage( 'info', flushChars("El icono cambiará cuando reinicie la aplicación."), 'ok') if $config->{'iconPath'} ne $edit_icon_path->get_text; $config->{'iconPath'} = $edit_icon_path->get_text; $config->{'aMuledOn'} = $check_aMuled_on->get_active; &saveConfig; pathsVerify; popUpsAct; readSignatureConf; $guiOpciones->destroy; } ); $btnCancel->signal_connect("clicked", sub { $guiOpciones->destroy; } ); $guiOpciones->signal_connect('destroy' => sub {$widget->set_sensitive(1) if defined $widget;}); $btnRutas1->signal_connect('clicked' => sub { dialogOpen($edit_home_aMule, 'Seleccione el directorio home de aMule', 'select-folder'); }); $btnRutas2->signal_connect('clicked' => sub { dialogOpen($edit_aMuleGui_path, flushChars('Seleccione la aplicación aMuleGui'), 'open'); }); $btnRutas3->signal_connect('clicked' => sub { dialogOpen($edit_wxcas_path, flushChars('Seleccione la aplicación wxCas'), 'open'); }); $btnRutas4->signal_connect('clicked' => sub { dialogOpen($edit_alc_path, flushChars('Seleccione la aplicación aLinCreator'), 'open'); }); $btnRutas5->signal_connect('clicked' => sub { dialogOpen($edit_icon_path, flushChars('Seleccione el icono que utilizará aMulet'), 'open'); }); } # loadConfig carga la configuración o la crea si no existe sub loadConfig { if ( open( CONFIGFILE, "$ENV{HOME}/.aMule/amulet.rc" ) ) { while (<CONFIGFILE>) { if ( $_ =~ /(\w+)\s=\s(.+)/ ) { $config->{$1} = $2 } } close CONFIGFILE; } else { # es la primera vez. mkdir "$ENV{HOME}/.aMule" unless (-d "$ENV{HOME}/.aMule"); $config = { # Por defecto 'aMuleDir' => "$ENV{'HOME'}/.aMule", 'aMuleGuiApp' => 'amulegui', 'wxCasApp' => 'wxcas', 'aLinkCreatorApp' => 'alc', 'iconPath' => '/usr/share/pixmaps/amule.xpm', 'appOnClick' => 'aMuleGui', 'aMuledOn' => 1 }; foreach my $app (@appList) { $config->{$app . 'App'} = which($config->{$app . 'App'}); } pathsVerify; &saveConfig; } pathsVerify; } # saveConfig guarda la configuración en un archivo sub saveConfig { my @keyList = ('aMuleDir', 'aMuleGuiApp', 'wxCasApp', 'aLinkCreatorApp', 'iconPath', 'appOnClick', 'aMuledOn'); if ( open( CONFIGFILE, '>', "$ENV{HOME}/.aMule/amulet.rc" ) ) { foreach my $key (@keyList) { print CONFIGFILE "$key = $config->{$key}\n" if $config->{$key} ne ''; } close CONFIGFILE; }else {logSys("warning", "No se puede escribir en el archivo de configuración!");} }; # showMessage Muestra una ventana con un mensaje, y espera respuesta. sub showMessage { #$icon info warning error question #$type none ok close cancel yes-no ok-cancel my ($icon,$text,$type) = @_; my $dialog = Gtk2::MessageDialog->new_with_markup (undef, [qw/modal destroy-with-parent/], $icon, $type, sprintf "$text"); my $retval = $dialog->run; $dialog->destroy; return $retval; } # which Devuelve el path completo a la aplicación. sub which { my $appFile = shift; foreach (split(':', $ENV{PATH})) { my $tmpStr = "$_/$appFile"; if (-x $tmpStr) { $appFile = $tmpStr; last; } } return $appFile; } # dialogOpen ventana de selección de archivos o directorios y escribe # el resultado en en el entry que debe ser el primer parámetro. sub dialogOpen { # $widget debe ser un entry # $type open save select-folder create-folder my($widget,$caption,$type) =@_; my $chooserDialog = Gtk2::FileChooserDialog->new ($caption, undef, $type, 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok'); my $filename = $chooserDialog->get_filename if 'ok' eq $chooserDialog->run; $widget->set_text ($filename) if defined $filename; $chooserDialog->destroy; return; }