imaplib - Ejemplo muy básico

Estoy de vuelta con python, que desde antes de examenes no había tocado nada. Y como estoy llegando al final del Learning Python, donde he visto que existe la librería poplib, me ha dado por probar imaplib. Dejo aquí un sencillo ejemplo que muestra todos los mensajes de un buzón IMAP.
#!/usr/bin/python

import imaplib, getpass

if __name__ == '__main__':
	
	host = raw_input('Host: ')
	user = raw_input('User: ')
	passw = getpass.getpass('Password: ')
        
	mail = imaplib.IMAP4(host)
	mail.login(user,passw)
	mail.select()
	
	typ, data = mail.search(None, 'ALL')
	for num in data[0].split():
		typ, data = mail.fetch(num, '(RFC822)')
		print '\\n----------------------------------\\n',
		print 'Message %s' % num,
		print '\\n----------------------------------\\n',
		print '\\n%s\\n' % data[0][1]
		raw_input('Next message...')
		
	mail.close()
	mail.logout()

Mordiendo la manzana

Después de unos meses sin escribir nada, señal de que tengo poco que contar y que he estado bastante liado este último cuatrimestre, comunico que hace unos días (4) he adquirido un MacBook 13,3 (2.16GHz). La experiencia está siendo grata. Quizás demasiado pues de momento estoy tirando con MacOSX (ya me he flagelado por ello :P) que estoy de exámenes y no es plan de ponerme a trastear para meterle una Ubuntu. Sobre MacOSX, la verdad la impresión es bastante buena y lo sería aún más si no fuera por el "insignificante detalle" de que su escritorio es software propietario. Y poco más puedo decir que la mayoría de gente que pueda estar leyendo esto (osea nadie) no sepa sobre estos portátiles. Espero que este nuevo miembro de la familia se porte bien durante su estancia en Irlanda y que haga su papel en mi experiencia erasmus.

Argumentos mediante OptionParserArgument parsing with OptionParser

En la versión 2.3 de Python se añadió el módulo optparse a la librería estándar, el cual nos sirve para parsear las opciones y argumentos que se pasan a nuestros programas, haciendo fácil y cómodo el lidiar con ellos. Pondré un ejemplo: From Python 2.3 we've the module optparse on standard library, which serve us for parse options and arguments passed to our programs, doing it easy and handy. Here's an example:
from optparse import OptionParser

if __name__ == '__main__':
    usage = "%prog [options] arg1 arg2"

    parser = OptionParser(usage=usage, version="%prog 1.0")
    parser.add_option('-v','--verbose', action='store_true',
                      dest='verbose', help='shows detailed information')
    parser.add_option('-q','--quiet', action='store_false',
                      dest='verbose', help='hides detailed information')
    parser.add_option('-f','--filename', action='store',
                      dest='filename', help='name of the file to load')


    (options, args) = parser.parse_args()

    if options.verbose:
        print "Extra info enabled"
    else:
        print "Extra info disabled"
    if options.filename:
        print "I'll open", options.filename, "file."
    if args > 0:
        print "\nArguments:"
        for x in args:
            print "  ",x
Ahora veamos algunos resultados según los argumentos que pasemos: Let's see some results depending on arguments passed:
$ python option.py

Extra info disabled
$ python option.py -v

Extra info enabled
$ python option.py -h

usage: option.py [options] arg1 arg2

options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -v, --verbose         shows detailed information
  -q, --quiet           hides detailed information
  -f FILENAME, --filename=FILENAME
                        name of the file to load
$ python option.py -f fichero.txt "First" "Second" "Last argument"

Extra info disabled
I'll open fichero.txt file.

Arguments:
   First
   Second
   Last argument
Fijaos que distingue las opciones de los argumentos, como se puede ver en el último ejemplo. Notice it knows options from arguments, as you can see in the last example. Nota: He escrito los ejemplos en inglés para no desencajar, porque las cadenas que imprime el módulo están en inglés, aunque estaría bien que pudiera hacerlo en otros idiomas.

Parsear HTML con BeautifulSoupHTML parsing with BeautifulSoup

Voy a poner un ejemplo de uso de BeautifulSoup, un módulo para Python con el que podemos parsear HTML. I'm gonna put an example using BeautifulSoup, a Python module which we can parse HTML. Lo primero que tenemos que hacer es descargar la librería desde aquí. Una vez instalado vamos a ver un sencillo ejemplo: First we've to download the library from here. Once installed, let's see the simple example:
from BeautifulSoup import BeautifulSoup

html = '''Titulo de la pagina
  
  

Cabecera

Vamos a poner una lista. Lista:
  • Elemento 1
  • Elemento 2
  • Elemento 3
  • Elemento 4
''' soup = BeautifulSoup(html) # Mostramos el titulo de la pagina print soup.head.title.string # Mostramos la cabecera print soup.find("div",{"id":"cabecera"}).contents # Mostramos el contenido contenido = soup.find("div",{"id":"contenido"}) print contenido.contents # Ahora mostramos todos los elementos de lista1 lista = contenido.find("ul",{"id":"lista1"}) for x in lista: print x.string
Si en lugar de pasar una cadena con el código html quisieramos leer de una url lo podríamos hacer así: Instead of a string with html code we can read from an URL on this way:
...
import urllib2

sock = urllib2.urlopen("http://servidor/documento.html")
soup = BeautifulSoup(sock.read())
...
Esto es un ejemplo muy sencillo de lo que se puede hacer, para más detalles leer la documentación. It's a very simple sample, for details read the BeautifulSoup documentation.

Operador const de C++ (Resumen)

Variables constantes

  • const int entero; Entero constante, una vez inicializada la variable entero no podrá ser cambiado su valor.
  • const int * pentero; ó int const * pentero; Puntero a entero constante, el contenido del puntero pentero no se podrá cambiar.
  • int * const pentero; Puntero constante a entero, no se podrá cambiar el puntero.
Como regla general const afecta al elemento que está inmediatamente a su izquierda, si no hay nada al que está inmediatamente a su derecha.

Valores constantes de retorno de función

const char * Funcion()
{ return "Un texto";}

Funcion()[1] = 'a'; // Error
La variable devuelta no se puede modificar pues es constante.

Parámetros constantes

void mostrarPila(const Pila &p);
Como mostrarPila no debe modificar la pila pasamos el objeto pila a mostrar por referencia y constante. De esta manera no podremos modificar el objeto p, ni acceder a métodos de este que no se hayan declarado como const.

Métodos constantes

class Tipo {
...
	void imprime() const;
...
}
Evita que el método imprime pueda modificar los miembros del objeto.

Naudo

Samba pa ti (Santana) [youtube:http://www.youtube.com/watch?v=H1Lwc_l5xJQ] Every little thing she does is magic (Police) [youtube:http://www.youtube.com/watch?v=OqT_OMf-TwI]

Impresionantes las versiones de este guitarrista. Les da un toque muy personal. En youtube hay un buen puñado de videos de él.

Twitter Updater

A raíz de ver el script que se hizo felipe, para twittear los todos del basecamp, me he hecho yo uno (más sencillo aún) en Python para simplemente twittear desde consola. Así por ejemplo hago Alt+F2 en KDE o desde la consola escribo twupdater "Ya hemos acbado los examenes (ojala)" y ya está. Pues eso, nada existencial, pero me ha dado para un ratillo de frikeo, y de paso he toquiteado http desde python. Aquí dejo el script: twupdater_v02.tar.gz Actualización: El script ahora pide usuario y contraseña si no se configuran. Ultima actualizacion: Ahora además comprueba el usuario y contraseña antes de enviar el estado. After I saw the script made by felipe, for twitting basecamp TODOs, I made another one (more simpler) in Python, it's just for twitt from console. So, for instance, I just can do Alt+F2 in KDE (or directly in a console) and write twupdater "Exams are out!". Not an existential thing, but it has give me some phreak time. And while I had the chance to trying http in python. Here is: twupdater_v02.tar.gz Update: Now the script ask user and pass if them is not configured. Last update: Furthermore, now checks user and pass before send status.

Código fuente

Prueba Swing (Libros)

Reordenar PDFs

Buscando como unir PDFs he encontrado este post en kriptopolis, y he conocido la herramienta PDFTK que nos permite hacer cosas como unir, encriptar, descomprimir pdfs y más.

Pondré unos ejemplos:

  • pdftk 1.pdf 2.pdf 3.pdf cat output 123.pdf
    Une los tres ficheros (1.pdf, 2.pdf y 3.pdf) en uno solo (123.pdf).
  • pdftk A=1.pdf B=2.pdf cat A1-7 B1-5 A8 output combined.pdf
    Crea un nuevo pdf extrayendo páginas, en este caso el nuevo pdf se compondría de las paginas 1 a 7 de 1.pdf, luego 1 a 5 de 2.pdf y por último la 8 de 1.pdf
  • pdftk doc.pdf output doc_enc.pdf owner_pw contra
    Encripta el PDF con todos los permisos deshabilitados excepto ver el fichero
  • pdftk doc.pdf output doc_enc.pdf owner_pw contra user_pw contra2
    Igual que el anterior pero ahora pedirá password para abrirlo.

Existen más opciones que se pueden ver en la página del programa, para mí con los dos primeros ejemplos ya me es bastante útil.

Nuevo libro recibidoNew book received

Esta mañana estaba durmiendo como un lirón cuando han empezado a llamar al timbre, la verdad, un poco frenéticamente. Bastante mosqueado, pues me habían interrumpido el sueño me dirigo hacia el aparatito y cuando pregunto quien era: "Cartero, traigo un libro para Alvaro..." WOW. El Programming Python 3a Edición (Agosto 2006) que encargue el 13 de diciembre me ha llegado hoy. Menuda sorpesa pues lo esperaba para marzo, después de examenes. El libro ha llegado en bastante buen estado, aparte de un par de arañazos en las tapas todo perfecto (por si alguien no lo sabe, el libro es de segunda mano), por cierto es bastante tocho casi el doble que el Programming Perl. Al final de todo se puede decir que me han alegrado el día, si si un libro me alegra el día. En fin que el libro ya está aparcado junto con los demás, y no creo que lo toque demasiado hasta después de exámenes, aunque claro como decía en un post anterior cuando menos toca es cuando más frikeo. I was sleeping this morning when a ring has waked up me. It's made me quite angry, but all turned different when I've opened the door, "Hi I've a book for you" WOW. The Programming Python 3rd Edition book that I ordered on 13th december has arrived to me. I got really surprised. The book is on quite good state, only two small scratches. It's big, almost double size of Programming Perl. At all it has brigthen up me today.

Intentándolo con Gtkmm II

Algoritmos aritméticos

Primer postFirst post

No creo que nadie esté leyendo esto en los mismos instantes de publicar esta entrada, estareis todos emborrachandoos y deseando poder escaquearos de casa para salir a esparramarla un poquillo. Bueno la verdad, no penseis que lo primero de todo que haré en el 2007 será sentarme a postear, esto está programado. En fin, Feliz año 2007 I think nobody is reading this post at moment its published, you will be get drunk and desiring go out with friends. Really you don't think the first thing I will do on 2007 is sitting down to post, it's programmed. Well, Happy 2007

De vacaciones navideñas

Un año más, y si no el último casi, estoy en las vacaciones de navidad, si esa época en que te venden felicidad por todos los costados. Dejando aparte mi espíritu antinavideño (y anticristiano en general), lo importante es que no hay clases y que puedo dedicar mi tiempo en cosas útiles tales como estudiar, meterle más caña a Python, probar cosillas en el servidor, salir por ahí... Pero vaya contradicción ahora que tengo más tiempo es cuando menos hago, aún no me he sentado ni un sólo día a estudiar, Python desde de antes de nochebuena (creo) no he vuelto a leer ningún capítulo más del Learning Python, salir... si bueno algo salgo pero ya no como antes. La verdad es que siempre me pasa igual cuanto más agobiado estoy y más se supone que tengo que estudiar, en época de exámenes, es cuando más me paro a probar esto y lo otro. En fin que ya no se ni lo que escribo, lo que hay que hacer para rellenar el blog... Feliz falsedad a todos y próspero año nuevo.

Almacen 0.5 - Ventana entrada de producto

Almacen 0.5 - Ventana nuevo producto

Almacen 0.5 - Ventana principal

Mi primer programa

En septiembre comencé a desarrollar una sencilla aplicación de gestión de almacén para el gabinete de estética de mi prima. En un principio pensé en hacerlo en Java, pues era el lenguaje que estudié el año pasado. Pero el desarrollo de interfaces gráficas para este lenguaje no me resultaba demasiado cómodo. Así que decidí hacerlo con C++ utilizando Qt, retomando así un lenguaje y una librería que se me habían quedado un poco pendientes. El programa en sí es bastante sencillo (de momento), estará lleno de bugs, mal diseñado... también hay que tener en cuenta que es lo primero más o menos serio que hago en el campo de la programación. Como ya he dicho utilizo Qt (4.2) no solo para las interfaces sino en general. Utilizo las estructuras de datos que vienen con la librería, las clases de acceso a bases de datos... SQLite fue mi elección ya que como no va a ser una base de datos de tamaño excesivo pensé que estaría bien, además para las copias de seguridad basta con copiar el fichero de la base de datos a un lugar seguro. En fin, que ya tengo digamos una primera versión utilizable del programa, aunque no funciona como me gustaría si que por lo menos "funciona". La gestión de productos es un poco tediosa y tal. Pero bueno para empezar ya se puede manejar toda la información que creemos que es necesaria. El código del programa se puede obtener mediante subversion: Para la versión en desarrollo:
svn co http://svn.inbatu.com/almacen/trunk almacen
Para la primera versión que he considerado "estable" (más bien funcional):
svn co http://svn.inbatu.com/almacen/branches/almacen-0.5
Bueno y unas capturas de pantalla (un poco feas):
vprincipalAlmacen 0.5 - Ventana entrada de productoAlmacen 0.5 - Ventana nuevo producto
Ejem, quizá falte maquear un poco más las cosas. El pedazo de hueco blanco de la ventana principal es un textarea que puse para rellenar, más adelante quiero poner una lista de albaranes en su lugar.

Tengo un Slash en mi cuarto!

Esta tarde ni corto ni perezoso he visto un muñeco del Slash muy guapo, y bastante barato, no me he podido resistir y me lo he comprado. El nivel de detalles es impresionante, lleva la pua, una Gibson Les Paul, con las cuerdas de nilon, la marca Gibson en la pala, también cadenas, el pañuelo colgando, sus chapas... Ah y además lleva un Marshall :P Dejo unas fotillos, aunque no se aprecian muy bien los detalles.
Slash 1 Slash 2 Slash 3

GNU/Emacs - Comandos básicos I

Los comandos que pongo aquí son de la forma C-x, M-x, esto quiere decir, en el caso de C-x que debemos pulsar la tecla CONTROL y a la vez la tecla x. En el caso de M-x debemos pulsar la tecla META (ALT ó ESC) y a la vez la tecla x. Bueno, una vez aclarado esto paso a listar un resumen de los comandos básicos. Nota: Entre paréntesis pondré el nombre largo del comando por ejemplo find-file, que se corresponde con el atajo C-x C-f, con lo cual podremos ejecutar este comando o bien mediante el atajo o bien haciendo M-x find-file RETURN.

Abrir, insertar y guardar ficheros

  • C-x C-f (find-file): Abre un fichero existente o si no abre uno nuevo.
  • C-x C-v (find-alternate-file): Carga un fichero diferente en ese mismo buffer, nos sirve si por ejemplo queriamos abrir un fichero y nos hemos equivocado al escribir el nombre.
  • C-x i (insert-file): Inserta el contenido de un fichero dentro del buffer actual (en la posición del cursor).
  • C-x C-s (save-buffer): Guarda el contenido del buffer en el fichero asociado (y si no lo tiene pregunta el nombre de fichero con el que guardarlo).
  • C-x C-w (write-file): Guarda el contenido del buffer preguntando el nombre del fichero en el que guardar.
  • C-x C-c : Sale de emacs, preguntando si guardar los cambios o no en caso de que hayan buffers modificados sin guardar.

Ayuda

  • C-h ? (help): Muestra las opciones de ayuda de Emacs.
  • C-h t (help-with-tutorial): Inicia un tutorial de introducción a Emacs.
  • C-h k (describe-key): Muestra información sobre una combinación de teclas. Por ejemplo C-h k C-x i muestra una descripción del comando insert-file.
  • C-h f (describe-function): Muestra información sobre un comando. La información mostrada es la misma que en el anterior pero en lugar de pasarle una combinación de teclas le pasamos el comando directamente.

Moviéndonos por los ficheros

  • C-f (forward-char): Mueve el cursor un carácter hacia adelante.
  • C-b (backward-char): Mueve el cursor un carácter hacia atrás.
  • C-p (previous-line): Mueve el cursor a la línea anterior.
  • C-n (next-line): Mueve el cursor a la línea siguiente.
  • M-f (forward-word): Mueve el cursor una palabra hacia adelante.
  • M-b (backward-word): Mueve el cursor una palabra hacia atrás.
  • C-a (beginning-of-line): Mueve el cursor al principio de la línea.
  • C-e (end-of-line): Mueve el cursor al final de la línea.
  • M-a (backward-sentece): Mueve el cursor una frase hacia atrás.
  • M-e (forward-sentece): Mueve el cursor una frase hacia adelante.
  • M-{ (backward-paragraph): Mueve el cursor un párrafo hacia atrás.
  • M-} (forward-paragraph): Mueve el cursor un párrafo hacia adelante.
  • C-x [ (backward-page): Mueve el cursor una página hacia atrás.
  • C-x ] (forward-page): Mueve el cursor una página hacia adelante.

    Nota: Emacs se mueve entre páginas usando un delimitador de página (que se define mediante la variable page-delimiter). En el modo texto el delimitador de página (no imprimible) se puede insertar mediante C-q C-l (L minúscula), que insertará ^L que aunque parezcan dos carácteres es uno solo.

  • C-v (scroll-up): Avanza una pantalla hacia adelante, mostrando dos líneas de la pantalla anterior.
  • M-v (scroll-down): Avanza una pantalla hacia atrás
  • M-> (end-of-buffer): Lleva el cursor al final del fichero.
  • M-< (beginning-of-buffer): Lleva el cursor al principio del fichero.
  • M-x goto-line n RETURN: Mueve el cursor a la línea n del fichero.
  • M-x goto-char n RETURN: Mueve el cursor al carácter n del fichero.

Repetir comandos

  • M n (digit-argument): Repite el comando escrito a continuación n veces.
  • C-u n (universal-argument): Hace exactamente lo mismo que la anterior.
  • C-u: Este comando sin argumentos repite el comando escrito a continuación 4 veces. Si hacemos C-u C-u lo repetiría 16 veces, C-u C-u C-u 64 veces, etc.

Redibujar la pantalla

  • C-l (recenter): Redibuja la pantalla, poniendo la línea actual en el centro.

    Este comando es útil cuando por ejemplo estamos editando en consola y el kernel nos tira mensajes, con este comando emacs redibuja la pantalla con la información del buffer. También nos es útil si estamos editando una porción de texto que nos aparece al final del display, usamos este comando y nos centra la línea actual, así vemos lo que tenemos por encima y por debajo.

Haciendo amigos en C++

Mediante el uso de la palabra clave friend podemos permitir el acceso a miembros privados o protegidos de una clase a funciones que no pertenecen a esa clase o a permitir el acceso a otras clases. Veremos dos casos ejemplo, declarando una función como friend dentro de la interfaz pública de una clase y declarando una clase como amiga.

Funciones friend

Cuando declaramos una función como friend en una clase estamos indicando que esa función tendrá acceso a los miembros privados de la clase, pero la función en cuestión no forma parte del ámbito de la clase. Veamos un ejemplo: Supongamos que tenemos una clase que representa un número racional como un par de números enteros. Queremos que este tipo nuevo se pueda usar de igual forma que int, double,... así:
Racional r(2,3);
cout << r << endl;
Para poder hacer esto necesitamos sobrecargar el operador de inserción binario operator<<:
class Racional
{
     friend ostream &operator<<(ostream &out, const Racional &r);
     public:

     Racional(int numerador, int denominador);
     ~Racional();
     // ...
};
De esta manera la función friend obtiene acceso completo a los miembros de Racional. La implementación de esta función se haría, fijándonos en que no pertenece al ámbito de la clase:
ostream &operator<<(ostream &out, const Racional &r)
{
     // Acceso a los miembros privados de Racional para mostrar r.
     // ...

     return out;
}
Podríamos haber declarado la función como no friend, entonces tendríamos que usar métodos públicos get(), set() para obtener los valores, usando friend podemos acceder directamente a los miembros, y además la función forma parte de la interfaz pública de la clase Racional.

Clases friend

Además de declarar una función no miembro como friend, podemos declarar funciones miembro de otras clases como friend, así como otras clases como clases amigas. Las clases amigas se usan en casos donde una clase está íntimamente ligada a otra. Por ejemplo supongamos que tenemos una clase Punto que representa una coordenada, y una clase ColeccionPunto que guarda una lista de puntos. Como la colección quizá necesite manipular objetos Punto, podemos declarar ColeccionPunto como amiga de la clase Punto:
// Clase Punto
class Punto
{
     friend ColeccionPunto;

     public:
     Punto(double x, double y) :
     m_x(x),
     m_y(y)
     {
     }

     ~Punto();
     // ...

     private:
     double m_x;
     double m_y;
};
Como la clase ColeccionPunto esta declarada como friend, puede acceder a los datos internos de cualquier objeto Punto. Una cosa importante es que esta amistad no es mútua, aunque ColeccionPunto puede acceder a Punto no se da el caso inverso. Además la amistad no es heredable, las clases que deriven de ColeccionPunto no podrán acceder a Punto. El principio detrás de esto es que la amistad no se concede de forma implícita sino que cada clase debe especificar de forma explícita sus amigos.

Creación de un repositorio Debian (2ª parte)

Conforme terminamos lo explicado en la primera parte nuestro repositorio no utiliza firmas. Para ello deberemos firmar los Release con gpg, para lo cual necesitamos habernos creado una clave.

Generación de una clave

Simplemente hemos de ejecutar el siguiente comando: gpg --gen-key Nos hará una serie de preguntas, entre ellas nos pedira un passphrase, que sera la clave privada. Más adelante necesitaremos importar la clave pública para usar el repositorio, la exportamos con el siguiente comando: gpg -a --export > clave_publica.gpg

Firma de los Release

Ahora que ya poseemos una clave para firmar el repositorio tenemos que firmar los Release de cada uno de los directorios:
cd dists/sarge
gpg -bao Release.gpg Release

cd main/binary-i386
gpg -bao Release.gpg Release
Esto nos pide el passphrase que introdujimos al generar la clave, y nos genera un fichero Release.gpg. Pues bien una vez hemos firmado todos los ficheros Release ya tenemos firmado el repositorio.

Importando la clave pública

Ahora lo único que nos falta es importar la clave pública exportada anteriormente en cada una de las máquinas que utilizan el repositorio: apt-key add clave_publica.gpg Si no hacemos este último paso el apt de cada máquina no reconocerá como firmados los Release

Creación de un repositorio Debian automático

En este post voy a explicar cómo crear un repositorio para alojar nuestros propios paquetes .deb . Para ello necesitaremos tener instalado el paquete apt-utils que seguramente ya lo estará.

Preparando el repositorio

Antes que nada deberemos crear un directorio raíz donde se hallará el resto de directorios y ficheros. Por ejemplo creamos el directorio /var/repo. Una vez creado el raíz habrá que crear dentro de el la estructura de directorios, por ejemplo para la distribución sarge creamos la siguiente estructura:
/dists
/dists/sarge
/dists/sarge/contrib
/dists/sarge/contrib/binary-i386
/dists/sarge/contrib/source
/dists/sarge/main
/dists/sarge/main/binary-i386
/dists/sarge/main/source
/dists/sarge/non-free
/dists/sarge/non-free/binary-i386
/dists/sarge/non-free/source
Donde vemos que primero se crea el directorio dists, donde luego habrá un directorio por cada distribución (en nuestro caso solo sarge). Dentro de la distribución (sarge) tendremos las diferentes secciones, main para paquetes libres, non-free para paquetes no libres, y contrib para paquetes libres que dependen de otros paquetes que no lo son. Una vez creadas las secciones creamos un directorio para los binarios, binary-<arquitectura> en este caso como serán exclusivamente para arquitectura i386 solo necesitaremos binary-i386, y un directorio para los fuentes, source.

Llenando el repositorio

Una vez creada la estructura ya podemos alojar nuestros paquetes. Para ello tenemos que copiar los .deb correspondientes a paquetes binarios en los directorios binary-i386 de cada sección. Si además queremos distribuir los fuentes copiaremos los ficheros .dsc -diff.tar.gz .orig.tar.bz en los directorios source. En cada directorio binary-i386 y source necesitamos un fichero Release cuyo contenido sería el siguiente:
Archive: stable
Component: main
Origin: <Tu nombre u organizacion>
Label: <Una etiqueta descriptiva>
Architecture: <Arquitectura de tu procesador o "source" 
                        para los directorios de fuentes>

Ficheros de configuración

Necesitamos dos ficheros de configuración:
  • apt-sarge-release.conf
  • apt-ftparchive.conf
Ambos ficheros los pondremos en el directorio raíz del repositorio. Y su contenido sería el siguiente:

apt-sarge-release.conf

APT::FTPArchive::Release::Origin "Tu nombre u organizacion";
APT::FTPArchive::Release::Label "Etiqueta descriptiva";
APT::FTPArchive::Release::Suite "stable";
APT::FTPArchive::Release::Codename "sarge";
APT::FTPArchive::Release::Architectures "i386 source";
APT::FTPArchive::Release::Components "main contrib non-free";
APT::FTPArchive::Release::Description "Descripcion detallada";

apt-ftparchive.conf

Dir {
  ArchiveDir ".";
  CacheDir ".";
};

Default {
  Packages::Compress "gzip bzip2";
  Sources::Compress "gzip bzip2";
  Contents::Compress "gzip bzip2";
};

BinDirectory "dists/sarge/main/binary-i386" {
  Packages "dists/sarge/main/binary-i386/Packages";
  Contents "dists/sarge/Contents-i386";
  SrcPackages "dists/sarge/main/source/Sources";
};

BinDirectory "dists/sarge/contrib/binary-i386" {
  Packages "dists/sarge/contrib/binary-i386/Packages";
  Contents "dists/sarge/Contents-i386";
  SrcPackages "dists/sarge/contrib/source/Sources";
};

BinDirectory "dists/sarge/non-free/binary-i386" {
  Packages "dists/sarge/non-free/binary-i386/Packages";
  Contents "dists/sarge/Contents-i386";
  SrcPackages "dists/sarge/non-free/source/Sources";
};

Tree "dists/sarge" {
  Sections "main contrib non-free";
  Architectures "i386 source";
};

Default {
  Packages {
    Extensions ".deb";
  };
};
Una vez tenemos los ficheros de configuración adecuados a nuestras necesidades hemos de ejecutar un par de comandos, los cuales podemos meter en un script llamado por ejemplo update-archive.sh:
#!/bin/sh
apt-ftparchive generate apt-ftparchive.conf
apt-ftparchive -c apt-dapper-release.conf release dists/dapper/ 
               >dists/dapper/Release

Actualizando el repositorio

Una vez hemos puesto los paquetes dentro de los directorios correspondientes de su sección ejecutamos el script update-archive.sh, obteniendo una salida como la siguiente:
$ ./update-archive.sh
 dists/sarge/main/binary-i386: 21 files 42.7MB 2s
 dists/sarge/contrib/binary-i386: 0 files 0B 0s
 dists/sarge/non-free/binary-i386: 4 files 114MB 5s
 dists/sarge/main/binary-i386/: 21 files 42.7MB 0s
 dists/sarge/contrib/binary-i386/: 0 files 0B 0s
 dists/sarge/non-free/binary-i386/: 4 files 114MB 0s
 dists/sarge/main/source/: 2 pkgs in 0s
 dists/sarge/contrib/source/: 0 pkgs in 0s
 dists/sarge/non-free/source/: 0 pkgs in 0s
Done Packages, Starting contents.
Done. 314MB in 50 archives. Took 7s

Usando el repositorio

Después de los pasos anteriores ya podemos utilizar el repositorio modificando el fichero /etc/apt/sources.list:
  • Para acceso local deb file:///var/repo sarge main contrib non-free
  • Para acceso remoto (si por ejemplo hacemos un enlace simbólico a /var/svn dentro del direcorio de un servidor http): deb http://nuestro.servidor/repositorio sarge main contrib non-free

Nota

Este post es prácticamente una traducción de un howto cuyo link es este. En un próximo post pondré como añadir nuestra firma al repositorio con gpg.

Probando con Flock

Pues estoy probando el nuevo navegador este. Es un firefox (calcado) con algunas funcionalidades interesantes. Como esta que estoy gastando ahora mismo, posteando en el blog directamente desde el navegador (File -> New Blog post...), también se pueden subir fotos a Flickr y Photobucket, compartir los marcadores con del.icio.us, notificaciones de technorati, y un agregador de feeds. Muy chulo la verdad. Como curiosidad, lleva como buscador por defecto Yahoo! en lugar de Google.

technorati tags:, , ,

Blogged with Flock

Probando con Swing

Pues ya que lo estoy dando en clase, me ha dado por probar un poco con swing. El resultado es un pequeño, sencillo y poco usable programa que me he hecho para gestionar libros, mediante una base de datos mysql. En concreto usando JDBC con el driver de mysql. Tiene muchos fallos y no funciona demasiado bien, pero ahi esta. Código fuente

Por fin tengo un portátil

Pues sí, me salio una oferta y no la pude dejar pasar. El cacharro en cuestión es un HP Pavilion ze4930ea (1.5Ghz, 512 RAM, 40 Gb de disco, tarjeta wireless Intel PRO Wireless 2200...). Empecé poniendole una Ubuntu Breezy, pero la tarjeta inalámbrica me daba muchos fallos (kernel panic), despues probé una fedora core 5 y más de lo mismo. Compilando el driver a mano, con ndiswrapper y nada. Al final he puesto una Ubuntu Dapper y va a las mil maravillas.

Encontrar procesos zombi

Cuando tenemos una máquina que no funciona correctamente es posible que los procesos estén en estado zombi. Para poder ver los procesos en este estado usamos el comando siguiente:
ps -el | grep 'Z'
Con el comando ps -el se puede obtener una salida en la que la segunda columna indica el estado del proceso. Existen varios estados:
S : sleeping
R : running
D : waiting
T : gestopt (suspended)
Z : zombie (defunct)
Un ejemplo podría ser el siguiente:
# ps -el | grep 'Z'
F S   UID   PID  PPID  C PRI  NI ADDR    SZ WCHAN  TTY   TIME CMD
1 Z     0  1213   589  0  75   0    -     0 funct> ?    00:00:00 find 
Donde vemos que el proceso dovecot-auth está en estado zombi.

Creación de paquetes

Hoy he descubierto un programa bastante interesante para generar paquetes para las distribuciones más usadas, entre ellas como no Debian. El programa en cuestión es Checkinstall. Nos permite generarnos debs a partir del código fuente de forma tan fácil como: ./configure

make

checkinstall
Al ejecutar el checkinstall este nos pregunta acerca de la descripción que queremos poner al paquete, el tipo de paquete(RPM, DEB o SLACKWARE TGZ), así como el maintainer, version, licencia... Y después de indicárselo tendremos en el directorio nuestro programa en forma de paquete deb/rpm/tgz. Además el programa nos permite poner documentación que luego se instalará en /usr/share/doc, también podemos ejecutar scripts preinstall/postinstall y preremove/postremove y puede que más cosas que no he mirado.

Crear debs de Java

Existe una forma cómoda, fácil y rápida de tener java (ya sea jre o jsdk) en un deb, mediante el paquete java-package de debian. Los pasos son los siguientes:
  1. Instalar java-package (apt-get install java-package)
  2. Bajar de la web de sun el jsdk por ejemplo el jdk 5.0
  3. Ejecutar make-jpkg jdk-1_5_0-linux-i586.bin (lo que nos generará el .deb)
Ahora ya podremos hacer dpkg -i sun-j2sdk1.5_1.5.0_i386.deb , lo que nos instalará el entorno en /usr/lib/j2sdk1.5-sun.

Configurar Gateway

Lo que voy a explicar es una forma de hacer que una máquina (servidor) actúe como pasarela a internet, es decir compartir la conexión a internet entre varios equipos. Para ello nuestro servidor deberá constar de dos tarjetas de red. Una de ellas conectada a "internet" (modem) y la otra a otro equipo ya sea otro pc o un switch.

Bueno pues lo primero que necesitaremos que nuestro kernel debe soportar iptables (versiones 2.4 en adelante) así como realizar nat mediante este. Para ello tenemos que tener activados los modulos ip_tables e iptable_nat.

Una vez nos aseguramos de ello deberemos ejecutar lo siguiente:

iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

Donde 192.168.0.0/24 indica que redireccionaremos a toda la subred 192.168.0.0 (con máscara 255.255.255.0) y eth0 es la interfaz de red conectada a internet.

Después debemos activar el ip forwarding de la ejecutando lo siguiente:

echo "1" > /proc/sys/net/ipv4/ip_forward

Con esto ya tenemos a nuestra máquina haciendo funciones de pasarela. Pero en este punto si reiniciamos el ordenador se perderá la configuración y tendremos que volver a ejecutar los dos comandos anteriores. Para solucionar esto los metemos en un script, algo así como:

#! /bin/sh
echo -n "Iniciando Gateway... "
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j MASQUERADE

echo "1" > /proc/sys/net/ipv4/ip_forward
echo "Iniciado."

Guardamos este script como /etc/init.d/gateway, por ejemplo, le damos permisos de ejecución y creamos enlaces simbólicos a él para los runlevels que nos interesen, p. ej para el 2, como sigue:

ln -s /etc/init.d/gateway /etc/rc2.d/S99gateway

Solo resta configurar los clientes, utilizando como puerta de enlace la ip de nuestro servidor (p. ej. 192.168.0.1 en caso de que hayamos configurado esa ip en la segunda tarjeta de red de nuestro servidor) y para las DNS tenemos dos posibilidades:

  • Poner directamente las DNS de nuestro proveedor de servicios.
  • Instalar bind en nuestra máquina servidor (lo que se escapa de esta explicación).

Probando subversion

He estado trasteando un poco (bastante poco la verdad) con el tan resonado software de control de versiones Subversion y la verdad, creía que no me serviría hasta que fuera a hacer algo serio y tal, pero es muy útil y fácil de utilizar. Según he entendido, básicamente es un sistema de ficheros (o algo parecido) que guarda información en una base de datos acerca de todos los cambios que se realizan sobre los ficheros añadidos a los diferentes repositorios. Un repositorio (se pueden tener todos los que se quiera) no es más, a mi entender, que un contenedor de directorios y ficheros, en el que los usuarios van guardando archivos nuevos, actualizando existentes, eliminando... dando para cada una de estas acciones comentarios sobre lo que y porque lo hacen. De esta manera el sistema subversion guarda un historial de todos esos cambios referentes a cada acción, teniendo así un alto control del proyecto. Todos estos cambios se pueden extraer en un ChangeLog. Bueno esa es la visión global que he tenido en un ratito. Dejo aquí algunos comandos para ilustrar la facilidad de este sistema:
  • Crear un repositorio:

    svnadmin create /directorio/directorio

  • Importar un proyecto ya existente en un repositorio:

    svn import /directorio/dir http://server/dir -m "Comentario"

    Los repositorios se indican con URLs (file://, http://...)

  • Añadir un fichero al proyecto:

    svn add fichero
    svn commit fichero -m "comentario"

    Con add indicamos a subversion que vamos a controlar ese fichero y con commit subimos los cambios (la primera vez pues subimos el original)

  • Actualizar nuestra copia local de trabajo:

    svn update

    Desde el directorio que queremos actualizar.

Y bueno muchas más cosas interesantes. Será cuestión de intentar darle uso durante este curso, de hecho un amigo y yo ya hemos pensado usarlo para pasar a LaTeX los apuntes de matemáticas. Todo se andará. Salu2

De vuelta

Bueno, ya llegó septiembre. Después de todo el verano sin apenas acercarme a los pc's, ahora vuelta a la carga. De aquí a dos semanas empezaré segundo... este año tendre que meter caña. Y nada a ver si empiezo a poner más cosillas por aquí, supongo que proximámente pondré cosillas de java (como me toca estudiarlo este año), a ver si continúo con Qt que lo dejé bastante parado y claro ahora mismo ya casi no me acuerdo de nada. :P Salu2 (al Maca porque no se si lo leerá alguien más)

Me he pasado a Qt

Pues si, hace ya varias semanas que me dió por probar con qt, así esporádicamente y... me quedé. Quizá al principio me liaba un poco, debido a que había estado probando gtkmm, pero después ya me acostumbré. Como opinión propia (la de un novato en esto de la programación), me gusta más Qt pues quizá por las razones que daba la gente y por las cuales me empujé a probarla: la documentación es muchísimo mejor (muy completa), las interfaces (repito, en mi opinión) se construyen de forma más fácil e intuitiva (sobretodo gastando Qt Designer, una maravilla), y bueno también me gustó que las señales y los slots las maneja la propia librería (en gtkmm utiliza sigc). De momento estoy leyendo el libro "oficial" de Qt: C++ GUI Programming with Qt 3. Está bastante bien, claro que se suponen unos conocimientos de C++ tirando a avanzados. De momento lo estoy entendiendo, y me he hecho una calculadora (bastante simple y que no funciona de manera ideal).

Sarge ve la luz hoy

Pues si, si, no es una broma. Hoy por fín, y después de 3 años sin públicarse ninguna versión estable, se publica Sarge (versión 3.1rc0). En este momento aún no se puede ver en la web oficial ningún anuncio sobre esto, pero si que se ve como se están replicando los mirrors, llenándose con las isos para las diferentes arquitecturas soportadas. Supongo que una vez ya se han realizado las réplicas harán el anuncio oficial, y entonces ya de manera definitiva la versión estable será Sarge. Actualización: Confirmado aquí

Mundo conocido

Pues navegando, concretamente en la página de un desarrollador de kde, Scott Wheeler, me he encontrado con una web que entre otras cosas (yo solo he probado esta), puedes generar mapas con los paises que has visitado. Esta curioso. :P Así mi mapa de paises visitados actualmente es así: Mundo actual conocido Claro que por lo menos me gustaría que estuviera así: Mundo por conocer... Tampoco es mucho pedir, ¿no? Pues eso, una curiosidad.

Algoritmos de Aritmética de Computadores

Dejo aquí un pdf con los diagramas de los algoritmos aritméticos vistos en clase de computadores.

Paquetes en Debian (algunas utilidades)

Existen una serie de opciones en los comandos típicos de gestión de paquetes de Debian que son bastante útiles y/o curiosas, que quizá se desconocen (o yo por lo menos desconocía o no las había usado). Algunos de estos usos de los comandos son: dpkg --get-selections > fichero.txt Nos da una lista del estado de todos los paquetes de nuestro sistema. Otra forma de obtenerlo es mediante dpkg -l > fichero.txt que nos da ademas la version del paquete y la descripción. Este último se puede usar también para saber si tenemos un paquete instalado (dpkg -l <paquete>) dpkg --audit Nos muestra los paquetes que se han quedado a medio instalar o en los que halla fallado la configuración, y los que tengan cualquier estado de error. aptitude hold | unhold <paquete> Para bloquear o desbloquear la actualización de un paquete. aptitude -f --with-recommends dist-upgrade Se realizará una actualización completa del sistema, esto es, se instalarán las versiones más recientes de los paquetes y se resolverán todos los posibles cambios de dependencias entre los paquetes de diferentes versiones. Si fuera necesario, se instalarían paquetes nuevos (normalmente, versiones nuevas de las bibliotecas o paquetes que han cambiado de nombre), y se eliminarían los paquetes obsoletos conflictivos. Se puede utilizar aptitude facilmente (con comandos de consola) para instalar desinstalar programas, actualizar el sistema... de la misma manera que apt-get (claro que aptitude es un front-end de este), por ejemplo "aptitude install libncurses5-dev" , "aptitude purge libncurses5-dev". Aun más fácil es usarlo con su interfaz. Seguro que además de estas pocas hay muchísimas que desconozco (seguro que muchos también) y que si leemos atentamente los man seguro que las encontramos.

Intentándolo con Gtkmm II

Bueno, pues me puse con el tutorial, y empezé a probar más cosillas en el HolaMundo. Y nada, después de unas pocas (como unas 60 quizá) líneas de código más, tengo lo que ya no es un HolaMundo, sino lo que le llamo Intentando Gtkmm (voy por la version 0.3), jajaja, si me entra risa. Pues el programita en cuestión (si esque llega a programita) consta de un par de botones, unas cuantas etiquetas, tres RadioButton, dos CheckButton, un par de HScale, y la última adición una Entry. Con estos widgets, lo que he hecho no es otra cosa que mostrar de forma muy sencilla su funcionamiento básico. Aquí pongo una captura: Ejemplo intentándolo con gtkmm II Hacer click para ampliar Además de lo que es en sí la librería también estoy desarrollando mi ejercicio como si se tratase de un programa medio útil, es decir, utilizando un proyecto de Anjuta configurado con autotools/automake ... y me voy haciendo make distcheck y veo el resultado de instalarlo como si se tratase de un programa real, distribuido como código fuente. En resumen, que me está gustando bastante esto de programar con interfaz gráfica. Dudo que alguien lea esto pero si le apetece ver de lo que hablo bajaroslo de aquí. P.D: En vez de estar estudiando, pos no, programando en gtk!! :P

Intentándolo con Gtkmm

Ayer tarde decidí probar, ahora que tengo unas nociones un poco más amplias de C++ y de la programación en general (y orientada a objetos en particula), el uso de la librería Gtkmm. Por si alguien no sabe lo que es, es una interfaz de C++ para GTK+. Empezando con el tutorial que se encuentra en la web oficial del proyecto, he visto de forma escueta los principios muy muy básicos. Vamos el HolaMundo. Por ejemplo, añadiendo el include <gtkmm .h> y mediante el siguiente código creamos una ventana principal vacía y la mostramos: Gtk::Main kit(argc, argv[]); Gtk::Window w; Gtk::Main::run(w); Y bueno, el hola mundo, que simplemente consta de un botón que muestra una cadena en la consola, ya es un pelín más complicado. Resumiendo, que por ahora me voy enterando de lo que gasto, porque y, más o menos como funciona. Lo que no entiendo muy bien, porque aún no lo he estudiado/mirado, son temas como la herencia, los miembros virtual... Pero vamos que con las nociones básicas que tengo de las clases, ya comprendo mejor todo el tema. Asi es que seguiré en ello hasta por lo menos terminar este tutorial, espero llegar y haberlo comprendido. Saludos

Se abre el telón

Pues nada, que viendo que un colega había puesto un blog de estos, me he dicho: "voy a probarlo" y nada... Dudo que alguien aparte de mi lea esto pero bueno. Si acaso Saludos :-)

Sobre mí

I'm currently studying ITT. Telematica (focused on computer networks) at Universidad de Valencia (Spain). My principal interests are computer programming (lately with C++ with Qt, and Python), play the guitar, watch some tv series, spend my free time with friends, and over all break the rules.