27 July 2013

Lazos... en shell

Hace poco tuve que hacer unas modificaciones a varios archivos. Lo ideal habría sido crear un programita (en Delphi/Lazarus o en Python) y resolver el problema. Pero la verdad a veces con una simple instrucción en un shell se soluciona todo. Tuve que hacerlo en Windows, pero obviamente también se puede en Linux, aunque la sintaxis es diferente.

Veamos los requerimientos y cómo solucionarlos.

Primero vamos a copiar varios archivos de un lugar a otro. Se sabe el nombre del archivo, pero una copia con comodín en la extensión no va a servir pues no todas las extensiones se permiten. Digamos que los archivos a copiar llevan por nombre

Azul, Verde, Amarillo, Rojo, Naranja, Gris, Blanco y Negro

y las extensiones válidas son

txt, pas, py, pyc y gif

Pero existen también extensiones bak, ~old, dat, tmp y otras. Y esas no nos interesan. Por eso una copia con comodín no sirve. Sin embargo, es fácil con un lazo for. Si estamos en Windows la forma es:

for %%1 in (<lista de nombres>) do for %%2 in (<lista de extensiones>) do copy %%1.%%2 <dest>


Se usa un doble % si el comando está dentro de un .bat o .cmd (bat y cmd son lo mismo para el shell) y si lo ejecutamos directamente en una ventana cmd.exe entonces se usa un solo %

En nuestro caso el comando quedaría así:

for %%1 in (Azul, Verde, Amarillo, Rojo, Naranja, Gris, Blanco, Negro) do for %%2 in (txt, pas, py, pyc, gif) do copy F:\RutaFuente\%%1.%%2 G:\RutaDestino

Eso funciona bien porque ya sabíamos de antemano los nombres de los archivos a procesar, pero qué pasa si éste no es el caso? Supongamos que tenemos que eliminar todos los archivos '*.~bak' que haya en una determinada ruta recursivamente. Aún podemos seguir usando un lazo for:

for /f in "tokens=*" %%1 in ('dir H:\Ruta\*.~bak /s /b /n') do del /q "%%1"

El parámetro /f le dice al for que procese en determinada manera los argumentos in (..) del comando. Admite unas cuantas opciones interesantes, pero para este post con esta opción basta. El dir simplemente lista recursivamente los archivos a partir de la ruta dada; las opciones /b y /n son para simplificar la salida y que el lazo trabaje bien. El del al final simplemente borra sin preguntar (/q) lo que le envíe el for. Se usan comillas para encerrar al parámetro para contemplar nombres de rutas con espacios en ellas. Por la forma en que está hecho se reportarán intentos de borrado de archivos que ya fueron borrados, pero a fin de mantener la simplicidad no corregí este comportamiento. Igual cumple su cometido.

Para más información del for en Windows pueden consultar el help o esta página que hallé con I'm Felling Lucky en Google:


Muy simple. Ahora veamos cómo es en Linux. Los for del shell en Linux son mucho más complejos. En general el shell lo es. Uno puede escribir programas enteros e interactivos que corren como un script en algún shell de Linux (hay varios) Yo uso bash y mis ejemplos funcionarán con él.


for i in Azul Verde Amarillo Rojo Naranja Gris Blanco Negro; do for j in txt pas py pyc gif; do cp "/Source/$i.$j /Dest"; done; done

Los lazos acá son más parecidos a los de los lenguajes estructurados y eso se debe a que el shell lo es! Incluso se pueden crear funciones dentro de un shell!!!

Ahora veamos cómo sería la parte de borrar algo:

for i in /Path/*.~bak; do rm -f "$i"; done

Aunque para esto es innecesario ya que el comando rm puede borrar de forma recursiva. Pero sirve para comparar cómo operan ambas modalidades. Para saber más del uso del for pueden invocar man bash y leer la documentación.

18 July 2013

Usando RTMPDUMP

El programa rtmpdump permite capturar el código de un site que transmite un stream y luego invocarlo para ver ese stream sin un browser. Imaginemos que tenemos un canal de noticias el cual miramos con un browser. Pero la pantalla está limitada a lo que sale en la web. Sin mencionar las toneladas de publicidad en los frames que la rodean. No sería mejor ver sólo ese stream en un pantalla y ya?

Ahora bien, cómo hacemos que esto funcione? Lo primero es instalar el programa. Si usas Ubuntu y derivados la instrucción es simple:

sudo apt-get install rtmpdump


O busca rtmpdump en el Synaptic o en Ubuntu Software Center. Si no tienes Ubuntu o derivados tendrás que ver cómo se hace en tu distro. Pero Google es tu amigo :)

Si eres paranoico entonces instálalo desde las fuentes:

svn checkout svn://svn.mplayerhq.hu/rtmpdump/trunk rtmpdump
cd rtmpdump
make linux

Antes de correrlo es bueno cerrar todos los browsers. Es lo mejor.

Ahora viene la parte divertida. Abrimos un terminal y le decimos al firewall que dirija todo el tráfico RTMP localmente:

sudo iptables -t nat -A OUTPUT -p tcp --dport 1935 -j REDIRECT

A continuación invocamos el rtmpsrv (parte del paquete rtmpdump)  para que empiece a capturar data:

rtmpsrv

Abrimos el browser de nuestra elección y vamos a la página a capturar. Entonces veran que el video no se muestra pero la pantalla de terminal donde está corriendo el rtmpsrv se llena de data. Cuando vean en ese montón de texto algo que sea rtmp:// le dan a Ctrl-C en el terminal para parar el procesamiento.

No hay que olvidar volver a redireccionar el puerto en el firewall:

sudo iptables -t nat -D OUTPUT -p tcp --dport 1935 -j REDIRECT

Ahora tenemos el string del stream de video (si no lo pronuncian bien entonces es porque no hicieron el cursito de inglés "onlain")

Sólo queda reproducir esto sin un browser. Para ello lo mejor es usar el propio mplayer que viene con Linux.

Quieren ver cómo funciona? Pues veamos... el Cana Vasco, por ejemplo. En un terminal pongan:

rtmpdump -m 200 -r "rtmp://cp70268.live.edgefcs.net/live/" -a "live/" -f "LNX 11,2,202,251" -W "http://www.widih.com/player.swf" -p "http://www.widih.com/watch-tv/74/canal-vasco live tv streaming" -y "eitb-CanalVasco@5519" -v -q -o /tmp/0001.dat &

El programa comenzará a capturar data en background y enviarla a un archivo en /tmp llamado 0001.dat. Ahora en ese mismo terminal invocamos mplayer:

mplayer -really-quiet /tmp/0001.dat

Voilà! Ahora tienen mplayer mostrando el Canal Vasco.

No olviden, al finalizar de ver lo que estén mirando, matar el proceso de rtmpdump con un killall rtmpdump o de lo contrario se quedará capturando en background.

Para complementar esta info pueden visitar


y


Y si quieren usar una aplicación que ya tiene unos cuantos canales incorporados la pueden descargar en


De hecho, es la aplicación que usé al principio. La estudié. Vi cómo manejaba los rtmp. Estudié los rtmp y empecé a capturar mis propios streams. Entre ellos tengo un par de canales de Venezuela, algunos de películas (que lamentablemente cambian cada cierto tiempo) y unos cuantos no aptos para menores. También me hice un programita en Python que me muestra todos mis canales (tanto los de TVenLinux como los que yo agregué) pero aún está en estado alpha y por eso no la comparto. He aquí un pantallazo de mi applicación corriendo


15 July 2013

Creando segmentos de código en Blogger

  En Blogger los segmentos de código, esos que se hacen con el HTML Tag CODE o PRE no quedan bien. Y en el mejor de los casos van sin Syntax Highlight. Googleando un poquito encontré una solución. El truco lo consiguen en


pero para resumir (y añadir un par de cositas) deben editar el Template de su blog y justo antes de </head> ponen esto:

    
    
    
    
    
    
    
    
  Guardan y ya. Yo tuve que darle a Format template porque se negaba a salvar. Entonces para escribir un código cualquiera simplemente lo engloban entre <pre class="brush: python">  y </pre> remplazando donde dice python con el lenguaje adecuado. Hay varias opciones de lenguajes que pueden consultar en 


y como verán en las líneas que puse en mi template yo elegí muy pocos adrede. Básicamente los que uso. Eso mejora el tiempo de carga del blog. Uds. pongan los que más rabia les de.

Así un código en Python se vería así:

    def __init__(self, parent):

        self._init_ctrls(parent)
        
        self.ReadCFGFile()
        
        self.listCtrl1.InsertColumn(0, 'Channel', width=150)
        self.listCtrl1.InsertColumn(1, 'Category', width=150)
        self.listCtrl1.InsertColumn(2, 'Now broadcasting', width=230)
        self.listCtrl1.InsertColumn(3, 'Next program', width=230)

        self.gaugeBufferMB.SetValue(0)
        self.gaugeTimeout.SetValue(0)

        self.channels = {}
        self.actualDir = os.getcwd()
        self.channelsDir = self.actualDir + '/channels'
        self.tempFile = tempfile.mkstemp(suffix='.video', prefix='PyInTv-')[1]
        
        #Recorre los folders que existen 
        _sortedChannels = []
        for _dirs in os.walk(self.channelsDir):
            if _dirs[0] != self.channelsDir:
                self.channels[os.path.split(_dirs[0])[1]] = _dirs[0]
                _sortedChannels.append(os.path.split(_dirs[0])[1])
        _sortedChannels.sort()

Y un código en Pascal/Delphi/Lazarus así:

// Comment
procedure Algo;
var
  c : byte;
begin
  For c := 1 to 10 do begin
    WriteLn('Hello World.');
  end;
end;

Ahora ya pueden escribir segmentos de código acá y con syntax highlight

Dejando nanobits

  Desde hace algún tiempo creé una cuenta en Wikispaces para poner una que otra tontería. Lo usaba más que todo como un almacén de código y tips. Algo para no estar buscando a lo loco por Internet cosas que uso más o menos frecuentemente. El site se veía bien. nanobits.wikispaces.com (que es como se llama mi wiki) estaba bien.

  Pero de la noche a la mañana la gente de Wikispaces decidió que todas las cuentas debían ser verificadas. Incluso aquellas de hace tiempo y que, obviamente, no pertenecen a un robot. Pues bien, le doy a verificar. Por lo general esto implica responder un correo y ya. Pero no! Esta gente no quiere eso. Las formas de verificación implican DINERO. Para demostrar que NO eres un robot debes adquirir una membresía con ellos o bien hacerles un pago de USD $1. Si bien un dólar no es mucho al final es molesto que sólo puedas demostrar tu humanidad con dinero. Yo les escribí un mail en el mejor inglés que pude y les dije que no tenía dinero, ni tarjetas de crédito, ni ninguna forma de pago electrónico. La respuesta lacónica fue que ellos no tienen otra forma de verificar usuarios fuera de USA. Es decir, para ellos el que no vive en USA es un robot.

  Debido a esto tendré que migrar (poco a poco) mi contenido allí a este blog. Algo bien fastidioso de hacer pero ni modo.

  Gracias Wikispaces. Sólo me queda NO recomendarlos a cualquiera que me pregunte. De hecho les hablaré pestes de Uds.

06 September 2012

Operadores ternarios en Python



Aprendiendo Python una de las primeras cosas interesantes con las que me encontré es con operadores que toman 3 parámetros. Veamos (en inglés) un extracto de un tutorial en PDF:


The basic form of the operator is 
expression if condition else expression 

Python evaluates the condition – in the middle – first. If the condition is True, then the left-hand expression is evaluated, and that’s the value of the operation. If the condition is False, then the right-hand expression is evaluated, and that’s the value of the operation. Note that the condition is always evaluated. Only one of the other two expressions is evaluated, making this a kind of short-cut operator like and and or.
Here are a couple of examples.
average = sum/count if count != 0 else None
oddSum = oddSum + ( n if n % 2 == 1 else 0 )
The intent is to have an English-like reading of the statement. “The average is the sum divided by the count if the count is non-zero; else the average is None”.


Es una construcción algo rara pero simpática.

Primer post

Saludos programadores, curiosos y demás habitantes de la blogósfera:

  Decidí crear este blog como refuerzo a un grupo de FB en el que mis amigos, otrora ávidos de conocimientos informáticos, no aportan mucho. En principio hablaré de mis lenguajes de programación favoritos sin un orden específico, es decir que los posts irán apareciendo a medida que se me presenten situaciones frente al computador.

  Normalmente hablaría de Delphi/Lazarus (léase Pascal) pues es casi mi lenguaje nativo. Sin embargo, no estará restringido a esos. De hecho, es muy probable que los textos sobre Python los superen. La razón es que actualmente estoy de lleno con ese lenguaje y me tiene muy contento. Hablaré muy pero muy poco de C/C++/C# y sus variantes pues, reconozcámoslo, no me gusta el C. Y aunque Python está hecho en C no lleva la carga de complejidad del mismo.

  Mi visión de la programación es igual a la del LEGO. Buscas tus bloques y armas lo que quieres, y en el proceso te diviertes. Eso no implica que de vez en cuando no tengas que crear tus propias "fichas", pero de ahí a crear todo el set de juego hay demasiada diferencia. Me niego a reinventar la rueda. Recordando a Bernard de Chartres una frase mal atribuida a Isaac Newton que dice en latín:

"Nos esse quasi nanos, gigantium humeris insidentes, ut possimus plura eis et remotiora videre, non utique proprii visus acumine, aut eminentia corporis, sed quia in altum subvenimur et extollimur magnitudine gigantea"


  O como la conoce la mayoría:

"Si he logrado ver más lejos, ha sido porque he subido a hombros de gigantes"


  Con esto en mente es que yo programo.