QPKG TelegramTorrent para descargar archivos Torrent/PDF vía Telegram v1.03
#2
Hola



Voy a describir como funciona internamente la aplicación con la idea de que sirva a otros para hacer las suyas o mejoras



El archivo TelegramTorrent.sh se basa en un archivo plantilla ya creado por defecto cuando creas un paquete desde la aplicación QDK.



Básicamente lo que hace es ejecutar unos comandos al activar la aplicación desde el app center y otros comandos cuando lo detenemos.



El código completo de TelegramTorrent.sh es:



Código:
#!/bin/sh
CONF=/etc/config/qpkg.conf
QPKG_NAME="TelegramTorrent"
QPKG_ROOT=`/sbin/getcfg $QPKG_NAME Install_Path -f ${CONF}`
APACHE_ROOT=`/sbin/getcfg SHARE_DEF defWeb -d Qweb -f /etc/config/def_share.info`
export QNAP_QPKG=$QPKG_NAME
directoriox="$(dirname -- $(readlink -fn -- "$0"; echo x))"
directorio="${directoriox%x}"
dirQPython=`getcfg QPython3 Install_Path -f /etc/config/qpkg.conf`
sisvol=`getcfg SHARE_DEF defVolMP -f /etc/config/def_share.info`
echo Donde estoy ahora $directorio
echo Ruta de QPython3 = $dirQPython
echo Volumen de sistema = $sisvol

case "$1" in
  start)
    ENABLED=$(/sbin/getcfg $QPKG_NAME Enable -u -d FALSE -f $CONF)
    if [ "$ENABLED" != "TRUE" ]; then
        echo "$QPKG_NAME ha sido desactivado."
        exit 1
    fi
    : ADD START ACTIONS HERE
    #compruebo si NO existe flag.txt es el primer arranque. No inicio bot por no tener configuracion correcta
    if [ ! -f $QPKG_ROOT/flag.txt ];
    then
        # creo el archivo flag para saber que
        touch $QPKG_ROOT/flag.txt
        #instalo pip
        sudo $dirQPython/bin/python3 $QPKG_ROOT/get-pip.py
        #instalo pyTelegramAPI
        sudo $dirQPython/bin/python3 -m pip install pyTelegramBotAPI
        #creo archivo flag2.txt como señal de futuros reinicios del servicio
        touch $QPKG_ROOT/flag2.txt
        #asigno permisos para que el usuario httpdusr pueda modificarlos
        chmod 666 $QPKG_ROOT/flag2.txt
        chmod 666 $QPKG_ROOT/botcfg.txt
        chmod 666 $QPKG_ROOT/BotTorrent.py
        chmod 666 $QPKG_ROOT/clave.md5
                # creo enlace simbolico a la página web
        ln -s $QPKG_ROOT/web /home/Qhttpd/Web/TelegramTorrent
    else
                  # creo enlace simbolico a la página web
        ln -s $QPKG_ROOT/web /home/Qhttpd/Web/TelegramTorrent
        #tarea de activar Telegram Torrent en segundo plano
        $dirQPython/bin/python3 $QPKG_ROOT/BotTorrent.py &
    fi
    
    #tarea de comprobacion de flag para reiniciar archivo
    echo -e "*/1 * * * * $QPKG_ROOT/comprobador.sh">> /mnt/HDA_ROOT/.config/crontab
    #tarea de activar crontab editado
    crontab  /etc/config/crontab
    /etc/init.d/crond.sh restart
    

    ;;

  stop)
    : ADD STOP ACTIONS HERE
        
    #eliminar lineas de tareas autorranque en crontab
        sed -i '/comprobador.sh/d' /etc/config/crontab
        #elimino el enlaces simbólicos para que no se pueda entrar en la web de configuración
    rm /home/Qhttpd/Web/TelegramTorrent
    #tarea de activar crontab editado
    crontab  /etc/config/crontab
    /etc/init.d/crond.sh restart
    
    #tarea de desactivación de Telegram Torrent
    ps | grep BotTorrent | grep -v grep | awk '{ print $1} ' | xargs kill
    ;;

  restart)
    $0 stop
    $0 start
    ;;

  *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
esac

exit 0




En nuestro caso además tenemos una dificultad añadida de que al efectuar la primera ejecución hay que hacer una primera ejecución de unos comandos para preparar python. Y ademas, no lanzaremos la escucha del bot ya que todavía no está configurado.



Para saber si es la primera ejecución compruebo la no existencia de un archivo "flag.txt". Si existe, es que ya hemos hecho la configuración de python.





En el primer arranque se hace las siguientes operaciones:


  • creo el archivo "flag.txt"
Código:
touch $QPKG_ROOT/flag.txt

  • instalo pip
Código:
sudo $dirQPython/bin/python3 $QPKG_ROOT/get-pip.py

  • instalo el api de Telegram
Código:
sudo $dirQPython/bin/python3 -m pip install pyTelegramBotAPI

  • creo y asigno permisos a "flag2.txt"
Código:
touch $QPKG_ROOT/flag2.txt
chmod 660 $QPKG_ROOT/flag2.txt

  • asigno permisos de escritura a "bootcfg.txt", a "BotTottent.py" y clave.md5 para que  pueda modificarlos el usuario httpdusr (el usuario de la web )
Código:
        chmod 666 $QPKG_ROOT/botcfg.txt
        chmod 666 $QPKG_ROOT/BotTorrent.py
        chmod 666 $QPKG_ROOT/clave.md5
  • añado enlace simbólico para poder acceder a la web de configuración
Código:
        ln -s $QPKG_ROOT/web /home/Qhttpd/Web/TelegramTorrent
  • añado y activo como tarea en crontab la ejecución del script "comprobador.sh"
Código:
    echo -e "*/1 * * * * $QPKG_ROOT/comprobador.sh">> /mnt/HDA_ROOT/.config/crontab
    crontab  /etc/config/crontab
    /etc/init.d/crond.sh restart




En el segundo arranque y posteriores se ejecutan estas operaciones:


  • activo la comunicación con Telegram con BotTottent.py
Código:
$dirQPython/bin/python3 $QPKG_ROOT/BotTorrent.py &
  • añado enlace simbólico para poder acceder a la web de configuración
Código:
        ln -s $QPKG_ROOT/web /home/Qhttpd/Web/TelegramTorrent

  • añado y activo como tarea en crontab la ejecución del script "comprobador.sh"
Código:
    echo -e "*/1 * * * * $QPKG_ROOT/comprobador.sh">> /mnt/HDA_ROOT/.config/crontab
    crontab  /etc/config/crontab
    /etc/init.d/crond.sh restart




En el caso de desactivación de la aplicación, las acciones que ejecutamos son:


  • elimino del crontab y desactivo como tarea en crontab la ejecución del script "comprobador.sh"
Código:
    sed -i '/comprobador.sh/d' /etc/config/crontab
    crontab  /etc/config/crontab
    /etc/init.d/crond.sh restart

  • desactivo el proceso mediante una búsqueda y filtrado (se encadenan varios comandos para matar únicamente a ese proceso)

Código:
    ps | grep BotTorrent | grep -v grep | awk '{ print $1} ' | xargs kill
  • elimino el enlace simbólico que permite el acceso a la web
Código:
    rm /home/Qhttpd/Web/TelegramTorrent




Bueno, ahora vamos con el mini script auxiliar "comprobador.sh".



Como desconozco como hacer que desde la web se pueda reiniciar la aplicación para aplicar la configuración, se me ocurrió el hacer una tarea programada que ejecuta ese "comprobador".



Lo que hace es comprobar el tamaño del archivo "flag2.txt", y si es distinto de cero ejecuta el reinicio (parada, vaciado de contenido de flag2.txt y arranque)



El código de este script es el siguiente:



Código:
#!/bin/sh
CONF=/etc/config/qpkg.conf
QPKG_NAME="TelegramTorrent"
QPKG_NAME2="QPython3"
QPKG_ROOT=`/sbin/getcfg $QPKG_NAME Install_Path -f ${CONF}`
Python_ROOT=`/sbin/getcfg $QPKG_NAME2 Install_Path -f ${CONF}`
    if [ -s $QPKG_ROOT/flag2.txt ];
    then
        echo "desactivo BOT"
        #tarea de desactivar Telegram Torrent
        ps | grep BotTorrent | grep -v grep | awk '{ print $1} ' | xargs kill
        
        echo "vacio archivo flag2.txt"
        #vacio archivo flag2.txt para no volver a entrar aqui y hacer reinicios del servicio
        cat /dev/null > $QPKG_ROOT/flag2.txt

        echo "Arranco Bot Python"
        #tarea de activar Telegram Torrent en segundo plano
        $Python_ROOT/bin/python3 $QPKG_ROOT/BotTorrent.py &
    fi




Con esto soluciono el tema de aplicación de cambios de configuración. 

No se aplican instantáneamente y se hacen a intervalos de un minuto.



Podemos aumentar el tiempo modificando la línea de crontab en el archivo "TorrentTelegram.sh", 5 o 10 minutos también serían correctos.



Todo lo anterior es referente a la aplicación archivos bash en la nas.



Ahora describo como es el funcionamiento de los archivos php de la web.



Como mis conocimiento son muy básicos la web tiene esa apariencia tan pobre, pero nos sirve.



Como función primordial lo que hace es recomponer el archivo "BotTorrent.py".



Y digo recomponer porque mas o menos a mitad de su contenido es donde están los 4 parámetros que queremos modificar.



Así que lo que hago es regenerar por concatenación el archivo "BotTorrent.py" partiendo de:


  • un archivo "botini.txt" que contiene el comienzo de "BotTorrent.py"
  • un archivo botcfg.txt que contiene definición de las variables obtenidas por la web
  • un archivo "botfin.txt" que contiene la parte final de "BotTorrent.py"



Si tenéis conocimientos de python, podemos modificarlos para bajar mas tipos de archivos, y seguramente podemos jugar con el máximo tamaño del archivo a descargar.



La función secundaria es el permitir cambiar la clave de acceso.



Esto se ha hecho para aumentar la seguridad de acceso.

Y es que al tener activada la aplicación web, ésta también está disponible si escribimos http://ip_nas/TelegramTorrent.

Es decir estaría accesible desde el exterior y si la tenemos accesible desde el exterior no queremos que nadie nos manipule el la aplicación  Dodgy 

En versiones anteriores tenias varios archivos ditintos en la web, pero he modificado el codigo php fusionando varios archivo y moviendo otros para evitar que sean accesibles.



El código del index.php es el siguiente:



Código PHP:
<?php 
session_start
();
$archivo="../clave.md5";
$filesize filesize($archivo);
$password "";
if (
$filesize == 0){
    $password "7eae385761fcdc3b6ee6e1682efed2b2";
    } else {
    
$file fopen($archivo,"r");
    
$password fgets($file);
    
fclose($file);    
    }

if(
$_POST['password']){
    if(md5($_POST['password']) == $password){
        $_SESSION['password'] = "alm";
    }else{
        echo 
"<span style='color:red;font-weight:bold;'>La contraseña $password es incorrecta</span>";
    }}
    
if(!
$_SESSION['password']){
?>
<center>
<h2><br /><br />Acceso configuraci&oacute;n de Telegram Torrent</h2>
<br />
<form style="margin:12px;" name="form1" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<input type="password" name="password">
<input type="submit" name="Submit" value="Entrar"></form>
</center>

<?php 
}else{
    if($_GET['acabar']){
        session_destroy();
        exit(
"<span style='color:blue;font-weight:bold;'>Te has desconectado, ya puedes cerrar esta ventana</span>");
    }
?>    

<?php
if(isset($_POST['Guardar'])){
 
$nombre "";
  if (!empty($_REQUEST['name'])){
   $nombre $_REQUEST['name'];
}
$post "";
if (!empty(
$_REQUEST['token'])){
 
$post $_REQUEST['token'];
}
$torrent "";
if (!empty(
$_REQUEST['torrent'])){
 
$torrent $_REQUEST['torrent'];
}
$pdf "";
if (!empty(
$_REQUEST['pdf'])){
 
$pdf $_REQUEST['pdf'];
}
$usuarios "";
if (!empty(
$_REQUEST['usuarios'])){
 
$usuarios $_REQUEST['usuarios'];
}
$archivo "../botcfg.txt";
$file fopen($archivo,"w");
fwrite($file,"TOKEN = '".$post."'\n"."ruta = '".$torrent."'\n"."rutaPDF = '".$pdf."'\n"."usuarios = {".$usuarios."}\n");
fclose($file);
}
$archivo "../flag2.txt";
$file fopen($archivo,"w");
fwrite($file,"escribo algo de contenido para reiniciar TelegramTorrent");
fclose($file);


$out fopen("../BotTorrent.py""w");
          $in fopen("../botini.txt""r");
          while ($line fgets($in)){
                /*print $file;*/
               fwrite($out$line);
          }
          $in fopen("../botcfg.txt""r");
          while ($line fgets($in)){
                /*print $file;*/
               fwrite($out$line);
          }
          fclose($in);
        
  $in fopen("../botfin.txt""r");
          while ($line fgets($in)){
                /*print $file;*/
               fwrite($out$line);
          }
        
  fclose($in);
        
fclose($out);


$ar fopen("../botcfg.txt","r") or die("No se pudo abrir el archivo");
$i=0;
while (!
feof($ar)){
 
$linea fgets($ar);
 
$i $i ;
 
/*$lineasalto = nl2br($linea);
 echo $lineasalto; */
 
if ($i == 1$valor1 $linea ;
 if (
$i == 2$valor2 $linea ;
 if (
$i == 3$valor3 $linea ;
 if (
$i == 4$valor4 $linea ;
}
fclose($ar);
$valor1 substr($valor19);
$valor1 substr($valor10, -2);
$valor2 substr($valor28);
$valor2 substr($valor20, -2);
$valor3 substr($valor311);
$valor3 substr($valor30, -2);
$valor4 substr($valor412);
$valor4 substr($valor40, -2);
?>

<form method="post" action="">
<center><br /><h3> Definición de  las variables y rutas del Telegram Torrent.</h3>
<br />Token de Telegram:
<br />
<input type="text" name="token" size="60" value="<?php echo $valor1?>" />
<br />
<br />Ruta de descarga de archivos .torrent: 
<div style="font-size:14px"> ejemplo:/share/MD0_DATA/Download/Torrents/ </div>
<input type="text" name="torrent" size="60" value="<?php echo $valor2?>" />
<br />
<br />Ruta de descarga de archivos .pdf 
<div style="font-size:14px"> ejemplo:/share/MD0_DATA/Download/pdf/</div>
<input type="text" name="pdf" size="60" value="<?php echo $valor3?>" />
<br />
<br />Usuarios permitidos:<br />
<div style="font-size:14px"> ejemplo 555666677 : 'usuario1', '12345678' : 'usuario2' </div> 
<input type="text" name="usuarios" size="60" value="<?php echo $valor4?>" />
<br/>
<br/>
<input type="submit" name="Guardar" value="Guardar"> 
<br/>
<br/>
<center><h3> Cambio de la clave de acceso.</h3>
<input type="text" name="clave" size="20">
<input type="submit" name="Actualizar" value="Actualizar"> 
<br/>
<a href="<?php echo $_SERVER['PHP_SELF']; ?>?acabar=si">Desconectar</a>
<br />
</center>
</form>

<?php     
}
?>
<?php
if(isset($_POST['Actualizar'])){
 
$nombre "";
  if (!empty($_REQUEST['clave'])){
   $clave $_REQUEST['clave'];
}
$clave=md5($clave);
$archivo "../clave.md5";
$file fopen($archivo,"w+");
fwrite($file,$clave);
fclose($file);
}
?>




Se agradecerían mejoras en él para optimizarlo.





Por ejemplo para los que sepan, se puede ver que leo las líneas del archivo botcfg.txt de forma secuencial (y als voy contando) y no creo un array de 4 elementos.



Hay muchas cosas que se podrían mejorar, incluso la estética



Y creo que eso es todo lo que puedo contar acerca del código.



Si hago (o hacemos) alguna mejora, la pondré por aquí a disposición de todos.



He actualizado este mensaje un par de veces, según he ido añadiendo mejoras de seguridad y de estructura.
Un saludo

Agur eta ondo ibili

Ganekogorta (TS-469Pro, TVS-673e, QBoat Sunny, TS-453Be, TR-002 y QHora-301w) Ʀɐɯ0η
  Responder


Mensajes en este tema
QPKG TelegramTorrent para descargar archivos Torrent/PDF vía Telegram v1.02 - por Ganekogorta - 03-04-2021, 07:36 PM



Usuarios navegando en este tema: 1 invitado(s)