jueves, 28 de julio de 2011

Decoradores en python (I)

Llevo poco tiempo programando en python, y una de las cosas que más me ha sorpendido es el tema de los decoradores. Estan basado en el patron decorador, y existen tambien en otros lenguajes, pero en python esta muy bien integrado. Los decoradores nos sirven para añadir nuevas funcionalidades a codigo ya existente, o reutilizar código de forma más eficiente, y sobre todo tambien, para que quede el codigo más legible. En está pagina podemos ver que lo utiliza para evitar la repetición de código, y para que quede más clara. A continuación voy a poner un ejemplo muy simple de decorador, que simplemente nos dice cuando se ejecuta la parte perteneciente al decorador con un print: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 # Nuestro decorador def saluda_antes(funcion): print "Codigo antes de decorar la funcion" def nueva_funcion(*args, **kwargs): print "Ejecuto la funcion decorada" return funcion(*args, **kwargs) print "Codigo despues de decorar la funcion" return nueva_funcion # Nuestra funcion def sumar(a, b): print "Ejecutando suma" return a+b # Main if __name__ == '__main__': sol = sumar(2, 3) print "Solucion {0}\n".format(sol) print "Decoramos la funcion_______________" sumar = saluda_antes(sumar) print "Funcion ya decorada________________\n" sol = sumar(2, 3) print "Solucion {0}".format(sol) Que nos genera la siguiente salida: Ejecutando suma Solucion 5 Decoramos la funcion_______________ Codigo antes de decorar la funcion Codigo despues de decorar la funcion Funcion ya decorada________________ Ejecuto la funcion decorada Ejecutando suma Solucion 5 En el primer bloque vemos la funcion sumar a secas. En el segundo la salida que nos muestra es la que obtenemos mientras se aplica el decorador. Y por ultimo tenemos el resultado de lanzar la funcion con el decorador aplicado. Otra manera de lanzar el decorador es poniendo la @nombre_decorador encima de la función. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # Nuestro decorador def saluda_antes(funcion): print "Codigo antes de decorar la funcion" def nueva_funcion(*args, **kwargs): print "Ejecuto la funcion decorada" return funcion(*args, **kwargs) print "Codigo despues de decorar la funcion" return nueva_funcion # Nuestra funcion @saluda_antes def sumar(a, b): print "Ejecutando suma" return a+b # Main if __name__ == '__main__': sol = sumar(2, 3) print "Solucion {0}".format(sol) Que genera una salida ligeramente diferente: Codigo antes de decorar la funcion Codigo despues de decorar la funcion Ejecuto la funcion decorada Ejecutando suma Solucion 5 Podemos ver que lo primero que se ejecuta es el código que hay al decorar la funcion, seguido por el código del decorador, y por último el de la funcion. Creo que queda claro, pero solo quiero aclarar que el codigo que se ejecuta al decorar la funcion (al principio), sólo se ejecuta una única vez. Si hicieramos 4 llamadas seguidas, tendriamos algo tal que así: Codigo antes de decorar la funcion Codigo despues de decorar la funcion Ejecuto la funcion decorada Ejecutando suma Solucion 5 Ejecuto la funcion decorada Ejecutando suma Solucion 5 Ejecuto la funcion decorada Ejecutando suma Solucion 5 Ejecuto la funcion decorada Ejecutando suma Solucion 5 Y hasta aquí lo que se daba. Volvere con más operadores cuando aprenda un poco más sobre ellos (paso de parametros, autocreacion de decoradores, etc).

viernes, 3 de junio de 2011

Instalación de Redmine sobre Debian Squeeze

La versión de Redmine que vamos a instalar es la 1.2.

Instalamos dependencias:
sudo aptitude install mysql-server
sudo aptitude install apache2
sudo aptitude install ruby
sudo aptitude install rails
sudo aptitude install rake rubygems
sudo aptitude install libmysql-ruby libopenssl-ruby
sudo gem install rails -v=2.1.2
sudo aptitude install g++ make ruby-dev apache2-dev
sudo aptitude install libcurl4-openssl-dev
sudo aptitude install subversion

Configuración MySQL
mysql -u root -p

create database redmine character set utf8;
grant all on redmine.* to ‘redmine’ identified by ‘*****’;

Si queremos que se utilice como motor de búsqueda InnoDB, creamos el fichero innodb.cnf:
sudo vi /etc/mysql/conf.d/innodb.cnf

Con la siguiente información:
[mysqld]
default-storage-engine = InnoDB

Y reiniciamos el servidor:
sudo /etc/init.d/mysql restart

Instalamos passenger
Version instalada: 3.0.9
sudo gem install passenger
cd /var/lib/gems/1.8/gems/passenger-3.0.9/bin/
sudo ./passenger-install-apache2-module
sudo ln -s /var/lib/gems/1.8/gems/passenger-3.0.9/ /usr/lib/passenger

Configuración de Apache para Passenger
En la ruta /etc/apache2/mods-available/ creamos los ficheros passenger.load y passenger.conf, con la siguiente informacion:

PASSENGER.LOAD
sudo vi /etc/apache2/mods-available/passenger.load

LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-3.0.7/ext/apache2/mod_passenger.so

PASSENGER.CONF
sudo vi /etc/apache2/mods-available/passenger.conf
PassengerRoot /usr/lib/passenger
PassengerRuby /usr/bin/ruby1.8
PassengerDefaultUser www-data

Y ahora los habilitamos:
cd /etc/apache2/mods-enabled/
sudo ln -s ../mods-available/passenger.load
sudo ln -s ../mods-available/passenger.conf

Y reiniciamos apache:
sudo /etc/init.d/apache2 reload

Instalamos RedMine
Descargamos RedMine (Version instalada 1.2)
cd /usr/local/lib
sudo svn co http://redmine.rubyforge.org/svn/branches/1.2-stable redmine-1.2

Instalamos dependencias
sudo gem install -v=0.4.2 i18n
sudo gem install -v=2.3.11 rails
sudo gem install rake -v'0.8.7'
sudo gem uninstall rake -v'0.9.0'

Configuramos fichero enviroment:
sudo nano redmine-1.2/config/environment.rb

y añadimos la siguiente línea:
config.action_controller.session = { :key => "_myapp_session", :secret => "tengoqueponeraqui30caracteresynosequecojonesponer" }

Instalamos la base de datos de RedMine:
cd /usr/local/lib/redmine-1.2/
sudo cp config/database.yml.example config/database.yml
sudo rake db:migrate RAILS_ENV="production"

Terminamos de configurar el RedMine:
cd /usr/local/lib/redmine-1.2/
sudo mkdir tmp public/public_assets
sudo chown -R www-data:www-data files log tmp public/public_assets
sudo chmod -R 755 files log tmp public/public_assets

Configuracion de Apache para soportar Redmine
cd /etc/apache2/sites-enabled
sudo rm 000-default

Creamos el fichero /etc/apache2/sites-available/redmine
sudo nano /etc/apache2/sites-available/redmine

Con la siguiente información:
<VirtualHost *:80>
  DocumentRoot /usr/local/lib/redmine-1.2/public
  <Directory /usr/local/lib/redmine-1.2/public>
     AllowOverride None
  </Directory>
</VirtualHost>

Y lo habilitamos:
cd /etc/apache2/sites-enabled
sudo ln -s ../sites-available/redmine 000-default

Y por ultimo reiniciamos apache:
sudo /etc/init.d/apache2 reload

Con esto ya debería estar funcionando.
Por lo menos así fue en mi caso, problem?

viernes, 25 de marzo de 2011

Mantener programas activos al cerrar el terminal

Muchas veces hemos abierto programas desde una terminal y queremos dejarlos activos al cerrar.
O bien si queremos dejar abierto algo en una maquina remota, también podemos hacerlo.

Para ello segun se esta ejecutando el programa presionamos Ctrl + z y después escribimos:
bg
disown


Ahora ya podemos cerrar el terminal sin problemas.

Borrar una palabra en un terminal

Es un poco chorra crear una entrada para esto, pero bueno, a mi me vale.

Podemos cortar una palabra entera cuando estemos con el terminal si hacemos Ctrl + w, o presionamos Esc y luego (no a la vez) backspace (la de borrar).

Se comporta de igual manera a cuando hacemos Ctrl + backspace en un editor de textos.

Relacionadas:
Terminal: buscar un comando ejecutado antes
Corta y pega en bash

lunes, 21 de marzo de 2011

Ejemplo /etc/network/interfaces

Para configurar dinámicamente la ip:
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp


Para configurar estáticamente la ip:
# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet static
address 192.168.1.128
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1


La verdad es que las opciones de network y broadcast nunca las había configurado antes, pero en este caso (en Debian 6), no se porque pero me iba demasiado lenta la configuración si no ponía estos parámetros (quizás tenga otra cosa mal :?).

Pidgin - Esperando la conexión a la red

Esto me ocurrió en Debian 6 "escuiss".
Este es un problema que me daba el Pidgin, me aparecía el mensaje "Esperando la conexión a la red".

Todo porque el network manager me dejo de funcionar al configurar estáticamente la dirección IP.

Así que lo solucioné desinstalando el network manager (pa lo que sirve):
sudo aptitude remove network-manager network-manager-gnome

No lo he probado pero recomiendan por ahí wicd para la gestión de la red (sobretodo en portátiles, para el wifi).

Saludos varios (pa cuando me autolea :()

viernes, 11 de marzo de 2011

Script para convertir ficheros en linux (ffmpeg)

Este es un pequeño script para convertir ficheros con ffmpeg.

No tiene casi opciones, y las opciones de video puestas son que mantenga la misma calidad de entrada que de salida. Y en el audio esta puesto para que codifique a mp3 sin mas.
Lo único que se puede elegir es el tipo de fichero de salida (con -f) y el número de threads (con -t) con el que lo vamos a convertir.

Yo lo utilizo para pasar los vídeos flv a avi, sin tener que andar tocando mucho, y después me los puedo pasar al móvil.

El tamaño de salida no lo he tocado porque mi móvil se come todos los vídeos, pero podéis modificarlo y dejadlo al gusto.

Aquí esta, creáis un fichero con éste contenido, le dais permisos de ejecucion (chmod +x archivo) y ya lo tenéis.
Ej: Yo lo he llamado conv, así que quedaría: conv -t 4 jl.flv

#!/bin/bash
# Default values
THREADS="1"
VFORMAT="avi"

# Parse options
while (($#))
do
case $1 in
-t)
shift
THREADS=$1
echo "Number of threads $THREADS"
;;
-f)
shift
VFORMAT=$1
echo "Video Format = $VFORMAT"
;;
-h)
echo "Usage: $0 [-t threads] [-f format] [-h help] file"
echo " by default threads=2, format=avi"
exit
;;
*)
FICHERO_IN=$1
FICHERO_IN_TRUNK=${FICHERO_IN%.*}
echo "Fichero entrada: $FICHERO_IN"

FICHERO_OUT="$FICHERO_IN_TRUNK.${VFORMAT}"
echo "Fichero salida: $FICHERO_OUT"
;;
esac
shift
done

ffmpeg -threads $THREADS -sameq -i $FICHERO_IN -acodec libmp3lame $FICHERO_OUT

martes, 8 de marzo de 2011

Crear enlaces simbólicos en ntfs

Es posible crear enlaces simbólicos en ntfs utilizando junction, que podéis descargar aquí.
Una vez descargado, se descomprime en la carpeta de System32, dentro de Windows, para poder utilizarlo y así ademas no tenemos que andar tocando el PATH.

Después para utilizarlo es necesario abrir un terminal (Símbolo de Sistema en Windows 7) y desde alli crear el enlace.

Creamos un enlace de la siguiente manera:

junction enlace_simbolico ruta_hacia_datos

Como nota añadir que se permite los enlaces simbólicos entre diferentes unidades del sistema.

Por ejemplo Si tenemos la carpeta G:\Datos\Descargas y queremos que en C:\ haya una carpeta llamada Datos que enlace a la otra sería de la siguiente manera.

cd C:
junction
Descargas G:\Datos\Descargas

o bien

junction C:\Descargas G:\Datos\Descargas

Con eso ya tendríamos nuestro enlace.

Hay que tener cuidado a la hora de borrar ya que si borramos el conteido del enlace perderemos los datos.
Si lo que queremos es desacer el enlace lo haremos de la siguiente manera:

junction -d C:\Descargas

Y con eso ya desharíamos el enlace.

sábado, 5 de marzo de 2011

"Device is busy"...., problem?

Cuando nos encontremos con este problema podemos hacer varias cosas para librarnos de él.
Hay dos fases, primero encontrar al cuplable, y después .... (que parezca un accidente).

Finding a culpable


Con fuser ejecutamos:
fuser -m /dev/sde1
/dev/sde1: 5884


Ya tenemos ahí al culpable: 5884.

Una vez que tenemos el culpable ya podemos acabar con él.
Aunque sólo sea por curiosidad no estaría de mas ver la cara del culpable, para ello nos basta hacer:
ps auxw | grep 5884
jewi 5884 0.0 0.1 25828 4848 pts/2 Ss 19:54 0:00 /bin/bash


Y como podemos observar en este caso soy un poco corki, me deje en un terminal un directorio abierto en el que teníamos montado el dispositivo.

Yo en mi caso salí de ese directorio y ya pude cerrarlo. Pero si no es el caso tenemos cosas con las que acabar con el proceso.

kill -9 5884

And it is all.

jueves, 3 de marzo de 2011

Corta y pega en bash

En bash tenemos algunos comandos que nos pueden servir de utilidad a la hora de copiar y pegar comandos.

  • C^a : Va al principio de la linea
  • C^e : Va al final de la linea
  • C^k : corta lo que hay en la linea a partir de la posición actual y lo guarda en un buffer.
  • C^y : pega el contenido del buffer a partir de la posición actual.
Nota: C^ significa pulsar la tecla Ctrl y la que indiquemos a continuación.

miércoles, 2 de febrero de 2011

GIT: Ver la rama en la que estas en el promp

Si trabajamos con terminales y git nos puede venir bien este pequeño truco para no despistarnos.

De una forma sencilla podemos ver en el promp la rama en la que estamos, quedaría de la siguiente manera:

|rama_actual|jou-tu@r2d2:$

Para verlo así tenemos que editar la variable PS1 dentro del fichero .bashrc (en linux mint es el fichero /etc/bash.bashrc), y añadirle esto al principio de la variable:
$(__git_ps1 "|%s|")

justo despues del primer ' (o donde querramos ponerlo)

Yo lo tengo así, pase de tener esto:
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '

a esto:
PS1='$(__git_ps1 "|%s|")${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
Si aparte queremos tener más información de la rama (si hay cambios sin subir, etc) podemos añadir la siguiente linea al ~/.bashrc:
export GIT_PS1_SHOWDIRTYSTATE=1


Con esto nos saldra al final del nombre de la rama:
  • * - si tenemos cambios pendientes que no han sido añadido para hacer el commit.
  • + - si tenemos cambios para hacer el commit, pero este aun no se ha realizado.

viernes, 28 de enero de 2011

Terminal: buscar un comando ejecutado antes

Hay muchas veces en las que queremos ejecutar un comando que hemos puesto previamente, pero por vaguería, por ser muy largo o porque no nos acordamos exactamente de como era, no queremos volver a escribir.

Lo tipico que hacía era mostrar el contenido del ~/.bash_history:
cat .bash_history

o buscar en ese fichero algo del comando que nos suene (ej: checkout):
$ cat .bash_history | grep checkout
git checkout new_domain
$

Pero se puede hacer de manera más fácil. Dentro del terminal pulsamos ^r (Ctrl + r), nos aparecerá lo siguiente:
(reverse-i-search)`':

Ahora solo tenemos que escribir lo que buscamos. Nos aparecerá el último comando ejecutado que contenga esos caracteres. Si queremos alguno anterior a ese solo tenemos que volver a dar a ^r.
Por ejemplo, buscando check:
(reverse-i-search)`check': git checkout integration

Si queremos ejecutar el comando pulsamos enter, y si queremos movernos por él con las teclas de dirección.

P.D: Ya no se ni como pongo los formatos.

jueves, 27 de enero de 2011

GIT: Crear un proyecto y subirlo a un servidor

El proceso inicial es bastante raro, aviso.
Se supone que hemos estado trabajando con nuestro repositorio local, pero ahora queremos subirlo a nuestro repositorio central para compartirlo con mas gente.

Para ello vamos a crear la carpeta en el servidor, vamos a configurarla y después uniremos el trabajo realizado en local con la carpeta en el servidor.

Se supone que ya tenemos nuestra carpeta creada localmente (git init, git add, git commit, etc), pero para que no haya lios vamos a mostrar el proceso entero.
En local creamos la carpeta ejemplo, e inicializamos el proyecto ahí:
LOCAL
mkdir ejemplo
cd ejemplo
git init

Si intentamos sincronizar el proyecto vacío nos devolverá error (No refs in common and none specified; doing nothing.), así que añadimos nuestros archivos del proyecto y realizamos un commit (pondré algo a modo de ejemplo, pero podéis poner el vuestro proyecto directamente).
LOCAL
echo ejemplo > ejemplo.txt
git add .
git commit

Ahora vamos a crear la carpeta en el servidor, donde vamos a guardar el proyecto.

El directorio raíz de todos los proyectos lo vamos a situar en /var/git (se puede cambiar).
No hay ningún problema en ponerlo en otro sitio.

Por estándar el nombre de la carpeta del proyecto es el mismo que el del proyecto local, pero terminado en .git, si nuestro proyecto se llama ejemplo, pues usaremos “ejemplo.git”.

Nos situamos en /var/git, creamos la carpeta ejemplo.git y entramos en ella:
SERVIDOR
mkdir ejemplo.git
cd ejemplo.git

Una vez creada la carpeta se inicializará el respositorio con este comando (desde la carpeta):
SERVIDOR
git init --bare --shared=group

Asignarle el bit s a la carpeta creada
SERVIDOR
cd ..
chmod -R g+s ‘ejemplo.git’

Tener cuidado de asignar la carpeta al grupo que queramos (en este caso utilizamos el grupo git):
SERVIDOR
chgrp -R git ejemplo.git

Ya hemos terminado el trabajo en el servidor, ahora solo quería sincronizar el proyecto desde donde tengamos nuestro repositorio local, si estamos en nuestra maquina en la carpeta ejemplo hacemos:
LOCAL
git push --all ssh://’user’@’server’/var/git/ejemplo.git

Una vez hecho esto ya esta en el servidor.

Para que queden bien todas las referencias dentro del proyecto lo mas sencillo es borrarlo del repositorio local, y clonarlo desde el servidor, así no habrá problemas:
LOCAL
rm -rf ejemplo
git clone ssh://’user’@’server’/var/git/ejemplo.git

Debemos asegurarnos que ‘user’ pertenece al mismo grupo al que pertenece la carpeta que queremos bajar(en este caso git).

Podemos editar el fichero /etc/group y añadirnos:
git:x:1005:user1,user2,user3,...

miércoles, 26 de enero de 2011

Screen manejador de ventanas en linux

Screen es un manejador de ventanas que multiplexa un terminal en varios procesos.

Con esto podemos tener un único terminal abierto en el que podemos tener varias sesiones.
También podemos dejar abiertas esas sesiones y cerrar el terminal original para despues recuperarlas más tarde. Y los procesos que se ejecutan en ellas no se quedan en background, sino que están en ejecución.

El control no es demasiado intuitivo, pero puede que quizás te valga la pena.

Para ejecutarlo solo tenemos que invocar el comando screen.

Parecerá que no hace nada pero ya tenemos una sesion screen abierta.
Para ver los comandos debemos hacer ^A (Ctrl + A) y después ?, veremos la siguiente ventana.


Tenemos algunos comandos útiles, y todos se invocan pulsando primero ^A y después las letras que salen en el menú.

^A A: renombramos el titulo de la sesion de screen actual.
^A c: multiplexa una nueva sesión dentro de screen.
^A ": muestra la lista de sesiones disponibles
^A ^A: cambia entre las ultimas sesiones de screen vistas.
^A ^D: "liberas" la sesion actual. Vuelves a tu terminal normal, pero la sesion de screen sigue activa, y puedes volver a abrirla.

Una vez "liberada" la sesión podemos volver a abrirla de la siguiente manera.
con screen -ls vemos las sesiones de screen abiertas, y con screen -x abrimos la última sesion abierta.
Para cerrar screen definitivamente sólo tenemos que salir de todas las sesiones abiertas dentro de screen con exit.

Configuración basica de ssh en linux

No es que vaya a salvar la vida a nadie esta ayuda, pero puede ser útil cuando trabajamos mucho con sesiones ssh, o cuando no nos apetece tener que aprendernos las direcciones ip, o simplemente queremos escribir menos.

Si accedemos de la siguiente manera:
  • ssh usuarioP@192.168.1.14
Podemos configurar el fichero ~/.ssh/config para no tener que escribir todo el tiempo el usuario con el que vamos a entrar y la dirección:
Host ejemplo
Hostname 192.168.1.14
User usuarioP

A partir de entonces nos bastará con:
  • ssh ejemplo

martes, 25 de enero de 2011

Varias sesiones por un mismo socket

Esto nos sirve para cuando tenemos que abrir varias sesiones hacia una maquina (por ssh).

En vez de tener que logearnos una vez por cada sesión sólo (con acento ¬¬) nos logearemos una vez para todas las sesiones, y estas sesiones compartiran el socket entre ellas.

Para conseguir esto tenemos que escribir lo siguiente en el fichero ~/.ssh/config :
Host *
ControlMaster auto
ControlPath ~/.ssh/socks/%r@%h:%p
Y ya esta listo.