Skip to content

Iniciando el grupo de Coding Dojo en Cochabamba Bolivia

enero 27, 2010

Este año una de las metas propuestas es mejorar nuestro nivel de código, el anterior año estuvimos mas atentos a las practicas ágiles pero mas centrados en la parte del management, pero sin duda después de haberme iniciado como QA, luego hacer de developer y entrar al management, me doy cuenta que el management tienes mas allá de leer o tomar cursos es vivirlo y aplicarlo en casos reales y uno no puede enseñar buenas prácticas si nos la hace, en fin algo que siempre estuve buscando fue un grupo con el cual compartir y aprender experiencias y programar juntos, se que tuve un año muy flojo programando pero este año lo dedicaremos entero a mejorar nuestro código.

Aca les paso el resumen de nuestra primera reunión, cabe resaltar que el grupo fue iniciativa de rolando.

Bueno, nos reunimos entre antonio, rolando, jimmy y sergio (yo).

Hablamos de varias cosas y entre las que me acuerdo:

Se hablo sobre dos approaches para organizar el barcamp,
uno es “más ceremonial”, haciendo cartas para solicitar
ambientes, convocando estudiantes, poniendo fechas
con mucha anticipación etc.

Y la otra más espontánea, se propone una fecha, un problema
y nos juntamos para programar.

Se opto por la última, por que la primera require más organización,
etc. Que por ahora no es momento.

Bajo esa premisa se nos ocurrió realizar la primera sesión
aprovechando el Barcamp, este sábado 30 en la tarde
2-4pm

Hable con la organización y nos pueden habilitar un ambiente.
Nos encargamos de la portatil, y esta la opción de un data display.

Antonio va a realizar una charla pequeña en la mañana para explicar
de que trata el coding dojo e invitar a la gente.

Sobre el problema vamos a resolver este, que no es muy complicado
http://acm.uva.es/p/v101/10189.html

Sobre el lenguaje, se barajeo la opción de c, java pero se opto
por python, más que todo por los conocimientos frescos
sobre los unittest.

Para tomar en cuenta, al escoger el lenguaje hay que tomar en cuenta
que extrictamente se aplica TDD, ya sea con unittest u otro framework,
o puros asserts 😉

=== En resumen ===

Lugar:     Barcamp – Centro Manuela Gandarillas – Inmediaciones
América/Liberator
Fecha:    sábado 30/02
Hora:      14:00 – 16:00
Lenguage: python
Problema: http://acm.uva.es/p/v101/10189.html
Confirmados:
– Sergio
– Antonio
– Jimmy
– Rolando

=== /resumen ===

No hablamos sobre el estilo, pero supongo que aplicaremos randori
(rotación piloto/copiloto)

Luego tambien comentamos de ponernos más exquisitos y probar lenguajes nuevos:
clojure, erlang, scala, haskell, etc.

Y tambien de tratar hacer una sesión por semana, variando language/problema.

El lenguaje y problema pueden ser sometidos a votación, pero si entre dos o tres
se animan a convocar una sesión no hay problema, los demás apoyamos,
lo que menos queremos es burocracia 🙂

via: http://groups.google.com/group/dojo-cochabamba?hl=es

Instalación y configuración del Servidor y Cliente Git bajo ssh

marzo 23, 2009

Git es uno de los mejores versionadores distribuidos, si usas github pero quieres tener tu propio repositorio en tu casa o trabajo entonces esta es una simple solucion, que no te toma mas de unos minutos, esta misma configuracion la he probado en dreamhost y funciona de la misma manera, de echo deberia funcionar en cualquier host que tengas. Si quieres ademas poder publicarlo mediante http, entonces una muy buena opcion gitweb.  Gitosis es tambien otra opcion que tienes, que es muy parecido pero para algun proyecto simple creo que esto es suficiente.

1. Configuración del Servidor git

 

El único requisito es tener instalado git:

 

$ sudo apt-get install git-core

 

nota: El servidor esta configurado e instalado en django-server que tiene la IP 192.168.0.139, el usuario es django-server con password *****.

 

2. Configuración del Cliente git

 

Primero debemos generar el conjunto de llaves RSA:

 

$ ssh-keygen -t rsa

 

Luego debemos registrar nuestra llave publica en el servidor, dentro de las llaves autorizadas de ssh, como sigue:

 

$  cat .ssh/id_rsa.pub | ssh django-server@192.168.0.139 ‘cat >> .ssh/authorized_keys’

 

En caso de no tener git instalarlo:

 

$ sudo apt-get install git-core

 

Crear el archivo initrepo con el siguiente contenido:

 

$ vim initrepo

 

DOMAIN=django-server@192.168.0.139

ssh $DOMAIN ‘mkdir -p ~/git/’$1′.git && cd ~/git/’$1′.git && git –bare init’

mkdir $1

cd $1

git init

git remote add origin ssh://$DOMAIN/~/git/$1.git

touch .gitignore

git add .

git commit -m ‘Created new repo’

git push origin master

echo “

[branch \”master\”]

  remote = origin

  merge = refs/heads/master” >>.git/config

echo “Your new git repo ‘$1’ is ready and initialized at $DOMAIN/~/git/$1.git”

 

Asignarle los permisos:

 

$ sudo chmod a+x initrepo

 

Para iniciar un repositorio nuevo en la maquina remota solo es necesario ejecutar initrepo y pasarle como parámetro el nombre del repositorio:

 

$ ./initrepo test01

 

Inmediatamente veras una salida como esta:

 

Reinitialized existing Git repository in /home/django-server/git/test01.git/

mkdir: cannot create directory `test01′: File exists

Initialized empty Git repository in .git/

Created initial commit cccf28a: Created new repo

 0 files changed, 0 insertions(+), 0 deletions(-)

 create mode 100644 .gitignore

Counting objects: 3, done.

Writing objects: 100% (3/3), 219 bytes, done.

Total 3 (delta 0), reused 0 (delta 0)

To ssh://django-server@192.168.0.139/~/git/test01.git

 * [new branch]      master -> master

Your new git repo ‘test01’ is ready and initialized at django-server@192.168.0.139/~/git/test01.git

 

Veras que en tu propia maquina tendrás la carpeta test01, ingresa y ya puedes empezar a hacer cambios y propagarlos en el servidor haciendo git push.

 

3. Obtener una copia de un repositorio remoto git y trabajar sobre el mismo

 

Para poder obtener una copia de un repositorio remoto primero deberá registrar su llave publica en el servidor remoto.

 

git clone ssh://django-server@192.168.0.139/~/git/test01.git

 

Luego puedes hacer cambios y replicarlos en el repositorio remoto con git push.

 

Referencias:

 

http://autopragmatic.com/2008/01/26/hosting-a-git-repository-on-dreamhost/

http://casperfabricius.com/site/2008/09/21/keeping-git-repositories-on-dreamhost-using-ssh/

http://madduck.net/blog/2007.07.11:publishing-git-repositories/

http://batterypowered.wordpress.com/2008/07/04/deploying-a-git-repository-server-in-ubuntu/

http://www.urbanpuddle.com/articles/2008/07/11/installing-git-on-a-server-ubuntu-or-debian

http://mechanicalrobotfish.com/posts/119-installing-git-server-using-gitosis

Instalando mod_wsgi, nginx y cmemcache en Ubuntu Intrepid para Django

marzo 21, 2009

Es un resumen breve para configurar nuestro servidor apache con mod_wsgi, memcache y nginx, el cual lo he recopilado de varios sitios, el cual espero pueda ser de ayuda y tambien pueda permitirnos a abrir debatos en lo que se refiere a las mejores practicas para configurar tus host para aplicaciones django.

Por que mod_wsgi y no mod_apache, puedes encontrar en este resumen mas detalles en los siguientes links:

Primero instalamos todos los paquetes requeridos:

$ sudo apt-get install subversion gcc curl
$ sudo apt-get install build-essential python-dev python-setuptools
$ sudo apt-get install python-egenix-mxdatetime memcached postfix

Para configurar memcache, necesitamos realizar dos pasos, el primero será inicializar memcache:

$ sudo memcached -u www-data -p 11211 -m 32 -d

(Inicializa memcached bajo el usuario www-data con 32 megabytes de ram)
Ahora necesitaremos construir el cmemcache, para ello obtenemos la siguiente librería:

$ sudo apt-get install libmemcache-dev

Ahora obtenemos el cmemcache y haremos un build del mismo:

$ wget http://gijsbert.org/downloads/cmemcache/cmemcache-0.95.tar.bz2
$ tar -xjvf cmemcache-0.95.tar.bz2
$ cd cmemcache-0.95
$ sudo python setup.py install

Instalación y configuración de Nginx

Primero debemos instalar nginx:

$ sudo apt-get install nginx

Luego inicializar nginx:

$ sudo /etc/init.d/nginx start

Podemos probarlo realizando curl 127.0.0.1 que nos devolverá una pagina html con titulo: Welcome to nginx!!

A continuación editamos la configuración básica de nginx, actualizando los siguientes datos:

$ sudo vim /etc/nginx/nginx.conf

worker_processes 4;  #4 indica que el servidor usa 4 procesadores
tcp_nopush on;       # activar esta línea
keepalive_timeout  2;
gzip  on;
gzip_comp_level 2;
gzip_proxied any;
gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

Luego debemos añadir un nuevo archivo de configuración llamado proxy.conf que deberá contener lo siguiente:

$ sudo vim /etc/nginx/proxy.conf

proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size           4k;
proxy_buffers               4 32k;
proxy_busy_buffers_size     64k;
proxy_temp_file_write_size  64k;

Puesto que nginx usa el Puerto 80 debemos cambiar la configuración de nuestro apache para que use el puerto 8080, para ello modificamos el archivo /etc/apache2/ports.conf y remplazamos el 80 por 8080.

Puesto que nginx no soporta la opción keepAlive debemos desactivar la misma en nuestro apache, para ello editamos el archivo /etc/apache2/apache2.conf y ponemos: KeepAlive off.

Ahora nos toca crear la estructura de directorios para nuestro dominio:

$ mkdir –p /home/<username>/webapps/<midominio>/{public,private,log,backup}

Para habilitar nginx en nuestro dominio debemos añadir nuestro dominio a los sitios habilitados y disponibles en nginx, para ello debemos añadir el siguiente archivo:

$ sudo vim /etc/nginx/sites-available/<midominio>

Cuyo contenido debería tener algo parecido a:

server {
listen 80;
server_name <midominio> http://www.<midominio>;
access_log /home/<username>/webapps/<midominio>/log/access.log;
error_log /home/<username>/webapps/<midominio>/log/error.log;

# main
location / {
proxy_pass              http://127.0.0.1:8080/;
proxy_redirect          off;
proxy_set_header        Host            $host;
proxy_set_header        X-Real_IP       $remote_addr;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size    10m;
client_body_buffer_size 128k;
proxy_connect_timeout   90;
proxy_send_timeout      90;
proxy_read_timeout      90;
proxy_buffer_size       4k;
proxy_buffers           4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
location /media/ {
root    /home/<username>/webapps/<midominio>/public/;
}
}

Luego debemos crear un link del mismo archivo a sites-enabled:

$ sudo ln -s /etc/nginx/sites-available/<midominio> /etc/nginx/sites-enabled/<midominio>
$ sudo /etc/init.d/nginx restart

Para probar nginx, primero añadimos nuestro dominio al archivo de host usando nuestra ip.

$ sudo vim /etc/hosts

Dicho archivo debería verse algo asi:

127.0.0.1      localhost
<mi ip>       http://www.<midominio&gt;

Luego en un browser ingresar a tu dominio y debera aparecer la pagina de error de nginx.

Instalar y Configurar mod_wsgi, con apache, nginx

Obtenemos mod_wsgi para nuestro servidor apache:

sudo apt-get install libapache2-mod-wsgi apache2-mpm-worker apache2-threaded-dev

En primera instancia debemos deshabilitar los sitios por defecto de apache:

$ sudo a2dissite 000-default

Asignamos los permisos correctamente:

$ sudo usermod -a -G www-data <username>

– Aseguramos que el directorio /home/<username>/webapps sea de <username> y que además este en el grupo www-data:

$ sudo chgrp -R www-data /home/<username>/

Nos aseguramos que todos los archivos nuevos de nuestro directorio webapps, heredaran los permisos:

$ sudo chmod -R 2750 /home/<username>/webapps

Otorgar permisos de escritura al usuario apache en el directorio privado de nuestro dominio:

$ sudo chmod -R 2770 /home/<username>/webapps/<midominio>/private

Obtener tu proyecto django y colocarlo dentro del directorio /home/<username>/webapps/<midominio>/

A continuación creamos el archivo wsgi:

vim /home/<username>/webapps/<midominio>/miproyecto.wsgi

El cual tendrá el siguiente contenido:

import os, sys
sys.stdout = sys.stderr

if ‘/home/<username>/webapps/<midominio>’ not in sys.path:
sys.path.append(‘/home/<username>/webapps/<midominio>’)
if ‘/home/<username>/webapps/<midominio>/<miproyecto>’ not in sys.path:
sys.path.append(‘/home/<username>/webapps/<midominio>/<miproyecto>’)
os.environ[‘DJANGO_SETTINGS_MODULE’] = ‘<miproyecto>.settings’

import django.core.handlers.wsgi

application = django.core.handlers.wsgi.WSGIHandler()

Por ultimo lo que nos toca es configurar el virtual host en el apache.
$ sudo vim /etc/apache2/sites-available/<midominio>

<VirtualHost *:8080>
ServerName http://www.<midominio&gt;
ServerAlias <midominio>

<Directory /home/<username>/webapps/<midominio>/<miproyecto>/>
Order deny,allow
Allow from all
</Directory>

LogLevel warn
ErrorLog   /home/<username>/webapps/<midominio>/log/apache_error.log
CustomLog  /home/<username>/webapps/<midominio>/log/apache_access.log combined

WSGIDaemonProcess <midominio> user=www-data group=www-data threads=25
WSGIProcessGroup <midominio>
WSGIScriptAlias /  /home/<username>/webapps/<midominio>/<miproyecto>/<miproyecto>.wsgi
</VirtualHost>

Creamos un link del archivo para colocarlo entre los sitios habilitados de apache:

Ln –s /etc/apache2/sites-available/<midominio> /etc/apache2/sites-enable/<midominio>

Por ultimo le decimos a apache que agregue nuestro dominio:

$ sudo a2ensite <midominio>
$ sudo /etc/init.d/apache2 reload

Reiniciamos nuestro apache y listo!! Tenemos nuestro dominio en http://www.<midominio&gt;

Referencias:
http://articles.slicehost.com/2008/5/16/ubuntu-hardy-nginx-virtual-hosts
http://www.meppum.com/2009/jan/17/installing-django-ubuntu-intrepid/
http://lethain.com/entry/2007/jul/17/dreamier-dream-server-nginx/
http://lethain.com/entry/2009/feb/13/the-django-and-ubuntu-intrepid-almanac/

Django – Managers que sobreescriben el get_query_set

enero 30, 2009

Los managers son una interfaz por encima de los modelos de django, que nos permiten realizar consultas sql relacionadas al modelo al cual están relacionados.

Django nos provee para todos los modelos un manager por defecto (objects), el cual nos provee una buena cantidad de consultas en forma de funciones (all, filter, exclude, etc)

Los managers los usamos en dos formas, una para sobreescribir el queryset que viene dado por defecto, y el otro para extender funcionalidad o extender nuestra gama de consultas que podemos realizar al modelo.

Sobreescribiendo el queryset

Cuando? si necesitas que ciertas instancias (tuplas de datos en la BD) no sean mostradas, entonces reducimos los resultados mostrados por el queryset que viene por defecto.

A continuacion escribimos un manager propio, en el cual sobreescribimos el queryset par devolver uno filtrado, que solo me muestre objetos que esten activos.

class CustomManager(models.Manager):
def get_query_set(self):
return super(CustomManager, self).get_query_set().filter(activo=True)

Class Empleado(models.Model):
nombre_completo = models.CharField(max_lenght=100)
activo = models.BooleanField(default=True)

A continuacion existen dos alternativas, la primera es sobreescribir el manager que viene por defecto y es accesido usando el nombre de objects, tambien puedes designarle un otro nombre, pero ya no podras llamar al atributo objects ya que al definir uno propio como se llame, objects ya no es mas disponible a menos que lo definamos explicitamente.

objects = CustomManager()

En el caso definido arriba, objects solo maneja los objetos empleado activos (activo=True), por lo cual:

Empleado.objects.all()

listara todos los empleados activos.

Por otro lado si se desea mantener objects, entonces debemos:

objects = models.Manager()
activos = CustomManager()

De esta manera tenemos:

Empleado.objects.all() que nos lista todos los empleados
Empleado.activos.all() que nos lista todos los empleados activos

El orden como se los define es importante, ya que el default manager, que es invocado por el admin, sera el que primero sea definido.

Django Forms – Sobreescribiendo los valores iniciales de un formulario dinámicamente.

enero 26, 2009
tags: ,

Lo que se quiere:

Mantener el ítem seleccionado dentro de un dropdown list, después de que el usuario realice un submit, se requiere que el campo seleccionado por el usuario se mantenga seleccionado.

Lo que se nos provee por defecto:

Una vez que el cliente presiona submit, los valores de nuestro formulario son restablecidos a los por defecto (campos en blanco y sin selección).

Solución 1:

Guardar el ítem seleccionado en la sesión del usuario (para mayor seguridad), luego; cada vez que se cree el formulario, verificar si existe en la sesión el ítem seleccionado, si existe: entonces pasarlo dentro de los valores iniciales que tomara nuestro formulario.

Ejemplo:

Usaremos un formulario que permita seleccionar un usuario e ingresar/guardar sus horas de trabajo semanales, y que tambien pueda navegar a través de las semanas pasadas y posteriores, para dicha navegación requeriremos que el empleado seleccionado se mantenga seleccionado.

Dentro de nuestro ModelForm sobreescribimos nuestro init:

def __init__( self, request, *args, **kwargs ):
report = None
if ‘do’ in request.POST:
start_date = parsedate(request.POST[‘hidden_start_date’])
else:
if request.session.__contains__(‘employee’):

# En esta sección verifico si esta guardado nuestro empleado seleccionado en la sesión, si es así, obtengo el empleado seleccionado.

employee=request.session.get(‘employee’)
report = TimeReport.objects.extra(where=[‘employee_id=%s’, ‘company_id=%s’, ‘start_week_date=%s’], params=[employee, request.user.client.pk, start_date])

# A continuación sobreescribiremos los valores iniciales de nuestro formulario y le agregaremos como valor inicial que este seleccionado el empleado que sacamos de la sesión.

initial = {‘employee’: employee }
initial.update(kwargs.get(‘initial’, dict()))
kwargs[‘initial’] = initial
super( TimeReportForm, self ).__init__( *args, **kwargs )

Solución 2:

En la vista, verificar si el usuario ha seleccionado un cliente, si es así, crear el formulario y pasarle los valores iniciales (el empleado seleccionado):

if ‘employee’ in request.POST:
form = TimeReportForm(request)
form.initial = {‘employee’: request.POST[‘employee’] }

En esta segunda solución tan simple, existiría varias ventajas y solo una desventaja,

Ventajas:

Menos código, ya no es necesario guardar y recuperar una variable de sesión y tampoco sera necesario realizar operaciones extras.

Desventaja:

La selección del empleado no se recordara durante la vida de la sesión del usuario como ocurre en la primera solución.

DRY – Dont Repeat Yourself, Django esta pensado en facilitarte muchas necesidades muy comunes.

DRY – Filtrando elementos en un campo de tipo ModelChoiceField

enero 13, 2009
tags: ,

Muchas veces descuidamos algunos detalles al leer la documentacion o simplemente no la entendemos, Dont Repeat Your Self es algo que debemos aplicar en todo momento, mas aun cuando usamos frameworks como Django, donde siempre existe una forma mas sencilla de hacer las cosas.

En el ejemplo siguiente, sobreescribo la manera de construir un formulario, especificamente: De lo aplicantes quiero que solo se muestren los que han sido seleccionados como empleados, en el campo employee:

class PayRollForm(forms.ModelForm):
def __init__( self, *args, **kwargs ):
super( PayRollForm, self ).__init__( *args, **kwargs )
self.fields[‘employee’] = forms.ModelChoiceField(queryset = Applicant.employees.all(), label=_(‘Employee’))
class Meta:
model = PayRoll

En la ultima linea sobreescribo el queryset, pasandole un nuevo queryset pero que solo contiene la lista de empleados.

Es asi fue como resolvi la primera vez que empezaba a jugar con django. Despues de leer detenidamente la documentacion y tratando de no perder detalles, encontre que la solucion a mi problema, era tan simple como:

Model PayRoll(models.Model):
employee = models.ForeignKey(Applicant, verbose_name =_(‘Employee’), related_name=’employee_payroll’, limit_choices_to = {‘is_employee’: True})

El atributo limit_choices_to nos permite filtrar los datos a ser mostrados en un campo que recibe llaves extranjeras.

Basto con una linea para resolver mi problema, lo bueno fue que aprendi a sobreescribir mis formularios y a prestar mayor atencion a a los detalles en la documentacion de Django.

Anuncio del lanzamiento de la Segunda Version del Libro Oficial de Django (para la version de Django 1.0)

enero 9, 2009
tags:

Adrian Holovaty nos anuncia en su blog del lanzamiento de la Segunda Version del Libro Oficial de Django, el cual ahora no contiene incompatibilidades con la actual version de Django 1.0.

Durante este periodo fue realmente una tragedia para muchos que se iniciaban en Django al no tener a la mano Libros que esten totalmente actualizados de acuerdo al a Version 1.0.

Enlaces de interes:

Adrian en Twitter, nos mantendra informados de los avances.
Los borradores del libro que son gratis y estan en linea.