[LUG.ro Mix] Gripe, encierro y rapidshare (entre otras cosas)
Emiliano
emilianogavilan en gmail.com
Jue Jul 23 17:40:05 ART 2009
Buenas
Me sucedió que, como a varios, después de varias semanas de gripe H1N1
empecé a sentir esa inflamación testicular de tanto estar al pedo
y encerrado, además de tener que soportar el encierro con mi hija de
tres que hace que la paciencia se vaya rápidamente por el caño.
Entonces, para contrarrestar esa sensación de "en cualquier momento mato
a alguien con una sobredosis de alcohol en gel" decidí que era buen
momento para que la internet me alegre el momento con alguna buena
colección de wallpapers de megan fox y/o alguna peli de las que ya no
se consiguen, como ser Citizen Kane, Dr. Strangelove y Metrópolis de
Fritz Lang.
Al encontrar enterradas en la red algunas cosas que despertaron mi
interés, resultó que la gran mayoría de esas joyas estaban tras varias
capas de cerradura en la forma de sitios como rapidshare y megaupload,
diseñados específicamente para que nadie los use a no ser que sea
un usuario premium (lo que sea que eso signifique).
Una corta búsqueda me llevó a un programa que automatiza las descargas
con el nombre de JDownloader. La "J" al principio fué un fuerte indicio
de que el programa estaba escrito en java, y la intuición femenina no
me falló; efectivamente terminé bajando un archivo zip de unos 13 megas
que al descomprimirlo ocupan:
emiliano en merlot:~/src$ du -sm JDownloader\ 0.6.193/
25 JDownloader 0.6.193/
25 megas!!! Es más que algunas de las cosas que quería bajar,
pero bueno, como a caballo regalado no se le miran los dientes
le dí una oportunidad. Para empezar, no arrancaba, me tirababa
algún "fatal exception" o algo asi, por lo que tuve que averiguar
la línea de comandos completa (que llevaba algunos switches
para la jvm) y finalmente, andando !!!!
Sin embargo, algo no andaba bien: tarda como veinte segundos en lanzarse
(algo así como el OpenOffice) y además es bastante molesto su
funcionamiento; "intrusivo" sería una descripción adecuada. Al ver todas
estas "funcionalidades" se me ocurrió hacer una simple prueba:
emiliano en merlot:~$ pmap `pgrep -f JDownloader` | grep total
total 690892K
Holy shit!!! casi 700 megas de memoria se chupa esa porquería !!!
Los que me conocen saben de mi gusto por las cosas pequeñas y que
funcionen (será que me siento identificado por algo??), y si bien
esto funciona, no tiene nada ni de pequeño, ni de eficiente (en términos
de memoria consumida y micro) para una tarea aparentemente tan sencilla
como automatizar unas descargas molestas.
Entonces, no me pude resistir, y tras un monólogo que recuerda la famosa
escena de "300" (This is madness!! - Madness?? This ... is ... UNIX!!!)
por lo que le dí una patada al mensajero^WJDownloader y me preparé para
la batalla.
Al cabo de un par de horas de tirar algunas líneas y ver las basuras que
esos sitios mandan en las paginas, termine con el script que finaliza
este mail. Solamente trabaja con el sitio rapidshare.com, pero es mas
que suficiente para mis necesidades. Tras probarlo un par de veces y
comprobar su utilidad decidí que a alguien más podría serle útil, así
que ése es el motivo del presente delirio.
Un par de notas por si alguien decide probarlo:
* le dí el nombre súper-sofisticado de rsdownload
* está escrito en Tcl; si alguien quiere pasarlo a otro lenguaje solo
tiene que mirar el copyright, sobre todo la parte de la cerveza ;-)
* el script acepta tanto una lista de URLs de rapidshare.com como el
nombre de un archivo que contiene URLs de rapidshare.com
* hay que ajustar el nombre del interprete Tcl en la primera línea; esto
es especialmente importante si deciden probarlo siguiendo las
instrucciones del PD2 abajo.
* la finalidad del script cumple con los requisitos iniciales: bajo
consumo de memoria y ser no intrusivo. Acá esta la comparación de la
memoria consumida
emiliano en merlot:~$ pmap `pgrep -f rsdownload` | grep total
total 4440K
si las matemáticas no fallan, es el 0,64% del JDownloader.
PD1: también tengo andando uno para megaupload, pero en este caso no es
tan útil ya que en cada nueva descarga pide que ingrese el código de la
imagen, por lo cual no es tan automático.
PD2: si no tienen instalado Tcl, una forma rápida es bajar un binario
autocontenido desde http://patthoyts.tk/tclkit/linux-ix86/
Los recomendados son
http://patthoyts.tk/tclkit/linux-ix86/tclkit%2dgui%2d8.5.7.gz
con Tk incluído o
http://patthoyts.tk/tclkit/linux-ix86/tclkit%2dcli%2d8.5.7.gz
sin Tk (es suficiente para este script en particular)
8<------8<------8<------8<------8<------8<------8<------8<------8<------8<------
#!/usr/bin/env tclsh8.5
# ajustar el nombre del interprete arriba
# Primero, el copyright de rigor, sacado literal de otro proyecto
# Copyright (c) 2009 by Emiliano Gavilán.
# The authors hereby grant permission to use, copy, modify, distribute,
# and license this software and its documentation for any purpose, provided
# that existing copyright notices are retained in all copies and that this
# notice is included verbatim in any distributions. No written agreement,
# license, or royalty fee is required for any of the authorized uses.
# Modifications to this software may be copyrighted by their authors
# and need not follow the licensing terms described here, provided that
# the new terms are clearly indicated on the first page of each file where
# they apply.
# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
# MODIFICATIONS.
# Por supuesto, si esto te sirve cualquier pago en forma de cerveza y pizzas
# será bienvenido :^)
package require http
namespace eval rapidshare.com {
variable regxp
# ponemos las definiciones de las expresiones regulares aca
# esto nos va a facilitar el mantenimiento en caso que algo cambie
# el valor de "dling" es una expresion para string match, no para regexp
array set regxp {
main {action=\"(http://[[:alnum:]]+\.rapidshare\.com[^\"]*)\"}
wait {([[:digit:]]+) minutes}
dling {*already downloading*}
rurl {var tt.*action=\"(http://[[:alnum:]]+\.rapidshare\.com[^\"]*)\"}
delay {var c=([[:digit:]]+);}
}
}
proc rapidshare.com::main {url} {
variable regxp
chan puts "\nPidiendo\n$url"
set tok [http::geturl $url]
set data [http::data $tok]
http::cleanup $tok
if {![regexp -- $regxp(main) $data -> rurl]} {
chan puts "No se encontro la url\n$url"
set ::urldone 1
return
}
chan puts "redireccionando a\n$rurl"
firstredirect $rurl
}
proc rapidshare.com::firstredirect {url {wait 0}} {
variable regxp
set tok [http::geturl $url -query dl.start=Free]
set data [http::data $tok]
http::cleanup $tok
if {[regexp -- $regxp(wait) $data -> min]} {
# el servidor nos pide que esperemos unos minutos
cntdown_min $min $url
return
}
# si el flag wait vale uno, venimos de la espera, y necesitamos un \n
if $wait {chan puts stdout ""}
# usamos string match dado lo simple de la expresion
if {[string match $regxp(dling) $data]} {
# hay una descarga en curso, abort, abort !!! :^P
chan puts "hay descargas en curso, saliendo ..."
exit
}
if {[regexp -- $regxp(rurl) $data -> rurl]} {
chan puts "la url real es\n$rurl"
} else {
chan puts "no se pudo resolver la url real :^("
set ::urldone 1
return
}
if {[regexp -- $regxp(delay) $data -> secs]} {
cntdown_sec $secs $rurl
} else {
chan puts "algo salio mal determinando el retardo :^("
set ::urldone 1
return
}
}
proc rapidshare.com::cntdown_min {n url} {
set msg [format "\rel servidor pide que intentemos en %2d minuto" $n]
if {$n > 1} {append msg "s"} {append msg " "}
chan puts -nonewline $msg
chan flush stdout
# Intentamos igual cada minuto ya que a veces nos autoriza antes
# lo peor que puede pasar es que terminemos aca de nuevo
after 60000 [list [namespace which firstredirect] $url 1]
}
proc rapidshare.com::cntdown_sec {n url} {
if {$n > 0} {
set msg [format "\rla descarga comenzara en %3d segundo" $n]
if {$n > 1} {append msg "s"} {append msg " "}
chan puts -nonewline $msg
chan flush stdout
incr n -1
after 1000 [list [namespace which cntdown_sec] $n $url]
} else {
chan puts "\nempezando descarga"
download $url
}
}
proc rapidshare.com::download {url} {
set filename [file tail $url]
chan puts "descargando $filename desde $url"
set fd [open $filename w]
chan configure $fd -encoding binary -translation binary
http::geturl $url \
-channel $fd \
-progress [namespace which httpCallback] \
-command [list [namespace which httpDone] $fd]
}
proc rapidshare.com::httpDone {fd tok} {
chan close $fd
http::cleanup $tok
set ::urldone 1
chan puts "\nlisto !!!"
}
proc rapidshare.com::httpCallback {tok total current} {
if {$total != 0} {
set p [expr {$current * 100.0 / $total}]
set w [string length $total]
chan puts -nonewline [format \
"\rtransferidos %*d bytes de %*d (%5.1f%%)" \
$w $current $w $total $p]
} else {
chan puts -nonewline "\rtransferidos $current bytes"
}
chan flush stdout
}
proc usage {} {
set name [file tail $::argv0]
set msg "$name es un script para automatizar la descarga "
append msg "de archivos desde el sitio\nrapidshare.com\n"
append msg "Uso:\n\n"
append msg "\t$name FILENAME\n\n"
append msg "o\n\n"
append msg "\t$name URL \[URL\]\n\n"
append msg "FILENAME debe contener una lista de links separados "
append msg "con espacios, tabulaciones\no retornos de linea"
chan puts $msg
}
################################################################################
#
#
if {$argc == 0} {
usage
exit
}
if {$argc == 1 && [file exists [set f [lindex $argv 0]]]} {
set fd [open $f]
set urllist [split [read $fd]]
chan close $fd
} else {
set urllist $argv
}
set urllist [lsearch -all -inline $urllist "http://rapidshare.com*"]
if {![llength $urllist]} {
chan puts "No se han encontrado links a http:://rapidshare.com"
exit
}
foreach url $urllist {
after idle [list rapidshare.com::main $url]
set urldone 0
vwait urldone
}
Más información sobre la lista de distribución Lugro-mix