Trac con Bazaar en Ubuntu

18 05 2009

Unas de las cosas que hacen a un buen programador, es el orden que lleve con los proyectos y su documentación, por lo que se me ocurrió intentar utilizar Trac, si me preguntan porque, por mera casualidad estaba buscando un paquete en el repositorio de Ubuntu y me encontré con el paquete de trac-bzr, me llamó la antención y decidí instarlo:

sudo aptitude install trac trac-bzr

luego crear el contenedor de los proyectos, en mi caso yo suelo utilizar mi home, pero se puede utilizar cualquiera:

mkdir ~/Trac
mkdir ~/Trac/proyecto
trac-admin ~/Trac/proyecto initenv

Seleccionamos todas las optiones a gusto a excepción del tipo de repositorio

Repository type [svn]> bzr

Hay que habilitar el plugin de bazaar o va a mostrar un error en la pagina del proyecto acerca de que no puede leer el repositorio, para esto hay que ir al archivo de configuración del proyecto:

vim ~/Trac/proyecto/conf/track.ini

y al final agregarle las lineas

[components]
tracbzr.* = enabled

Con eso ya esta habilitado el plugin, si se quisiera agregar más plugins se hace de la misma manera.

Con eso ya tenemos la instalación básica, ahora es necesario configurar el apache para que nos muestre las paginas de proyectos de trac

sudo apt-get install libapache2-mod-python

ahora es necesario editar el archivo de virtualhost de apache

sudo vim /etc/apache2/sites-available/default

agregamos la seccion debado de algun “location”

<Location /projects> #set up Trac handling
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /home/<tu_usuario>/Trac
PythonOption TracUriRoot /projects
</Location>

Cambiamos los permisos para que apache pueda leer nuestro trac

sudo chown www-data -R ~/Trac

Luego reiniciamos el apache

sudo /etc/init.d/apache2 restart

Seguidamente hay que agregar autenticación al sitio, para la parte del flujo de los ticketes y demás, primero hay que crear un archivo de password para apache

htpasswd -c ~/Trac/.htpasswd admin

Se llenan los password y luego hay que hacer la referencia en el location de apache, quedando de ésta manera

<Location /projects>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracEnvParentDir /home/edder/Trac
PythonOption TracUriRoot /projects
#authentication scheme
AuthType Basic
AuthName "Trac Projects"
AuthUserFile /home/<tu_usuario>/Trac/.htpasswd
Require valid-user
</Location>

Reiniciamos apache y ya con eso estamos :P

Nota: Funciona para Intrepid como para Jaunty.





Una clase php para hacer archivos log

4 05 2009

Actualmente estoy trabajando en un sistema legacy de PHP,  en algunas partes del código quiero saber que hay en las variables, si trato de hacer un var_dump / print_r no sale nunca en pantalla, me dirán “pero existe xdebug”, en efecto existe pero algunas veces si hay mod_rewrite no funciona bien por lo que no sirve de nada.

Para eso me cree una clase pequeña, que permite crear un archivo de log a el cual le agrega la hora y fecha además si es una arreglo lo muestra formateado, a éste archivo de log se le dice el path y el te va a decir si puede crearlo o no, además va a agregar linea tras linea, asi que cuidado de dejarlo habilitado porque despues de más 1.000.000 puede hacerse grande el archivo :P .

El codigo de archivo:

< ?php

	/**
	 * myLogger
	 * @author Edder Rojas Douglas
	 * @version 0.2
	 */

	class myLogger  {

		protected $_path;
		protected $_fileName = 'myLogger.log';

		/**
		 * @param string $path can be a directory o a file path
		 */
		public function __construct($path) {
			if (empty($path)){
				Throw new Exception("Path must be filled");
			}
			if (!file_exists($path)) {
				Throw new Exception("The Path doesn't exists.");
			}
			if (!is_writeable($path)) {
				Throw new Exception("You can write on the give path");
			}
			$this->_path = $this->_parsePath($path);
		}	

		/**
		 * Validate the path the add the filename to the path
		 * @param String $path
		 * @return String
		 */
		protected function _parsePath($path) {
			$strLenght = strlen($path);
        	$lastChar = substr($path, $strLenght - 1, $strLenght);
        	$path = $lastChar != "/" ? $path . "/" : $path;

        	if ( is_dir($path) ) {
        		return $path . $this->_fileName;
        	} else {
        		return $path;
        	}
		}

		/**
		 * Will save the path on the give path
		 * @param String $line
		 */
		protected function _save($line) {
			$fhandle = fopen($this->_path, "a+");
			fwrite($fhandle, $line);
			fclose($fhandle);
		}

		/**
		 * main function to add lines to the logging file
		 * @param String $line
		 */
		public function addLine($line){
			$line = is_array($line) ? print_r($line, true) : $line;
			$line = date("d-m-Y h:i:s") . ": $line\n";
			$this->_save($line);
		}
	}

Su utilización es sencilla:

// cargar la clasesita
require_once('myLogger.php');

$log = new myLogger(dirname(__FILE__) . "/tmp");
$log->addLine(array("testing", "my", 'data'));
// si en éste punto no muestra errores, todo bien =D

Actualización: Hice unas pequeñas modificaciones para mostrar mejor los resultados si lo que se loguea es un objecto.





Como ver los índices en Postgres y MySQL

10 03 2009

Unos de los problemas de rendimiento se deben a las base de datos, un ejemplo sería tratar de traerse datos cuando no hay indices que definan la tabla, eso provocaría que el gestor de base de datos valla registro por registro aplicando las condiciones, y en donde la base de datos en grande podría generar problemas de rendimiento.

Unas de las formas de mejorar el problema de rendiemiento relacionados a las Bases de datos es crear índices, pero en mi caso es ver si una base de datos existente hay indices definidos, por lo que en mysql se podrían ver así:

show create table <tu_tabla>;

Y por otro lado en postgres es:

select * from pg_indexes where tablename = '</tu_tabla>';

Nota: cambiar <tu_tabla> por el nombre de la tabla que se quiere inspeccionar.

Con ése queda el truquito para encontrar cuellos de botellas en las base de datos :)





Recomendaciones al crear una Clase en Orientación a Objetos

7 03 2009

Cuando se crea una clase en la programación orientada a objectos, la responsabilidad de ésa nueva clase dería ser descrita en menos de 25 palabras sin usar las palabras “y”, “o”, además de tratar de mantener ésa clase los más simple y enfocada posible en su responsabilidad.

Si alguna vez esa clase contiene más de una resposabilidad, es bueno ir pensando en crear más clases para abarcar esas otras responsabilidades.





Iniciando con Dojo Toolkit

4 12 2008

Dojo toolkit

Dojo Toolkit es una framework javascript para desarrollar aplicaciones ricas en Interfaces de usuarios y funcionalidades, muy a lo Web 2.0.

Mi idea no es hacerle propaganda, más bien es contar mi punto de vista de lo que he visto hasta ahora, ya que no he me adentrado mucho en esta herramienta que a primera vista me encanta, de hecho me encanta Javascript :D , bueno, volviendo al punto, he utilizado recientemente Extjs lo cual es otro buen Framework Javascript pero no destaca por su velocidad, si no, por su interface de usuario y todo los widgets que viene por defecto.

Lo primero que me ha llamado la antención es, que solo es una liberia “dojo.js” a la hora de inicializar y las demas llamadas se hacen por medio de dojo.require(“nombre_libreria_dojo”) que realmente es un XHR; esto me gusta a medias, por un lado esta muy bien hecho de tal manera que para el desarrollador es muy sencillo segmentar el codigo y trabajar las dependecias si tener que cargar todo el framework cada vez que se refresque la pagina y por otro lado eso le da carga al servidor por cada request, pero para eso digamos que tiene una solución: creando un paquete comprimido con las dependecias del modulo o pagina que se requiera y así solo hace una llamada.

Otra cosa que me gusto bastante es lo sencillo que es comprender como funciona, lo digo porque cuando trate de aprender a usar Extjs es más complicado seguir los tutoriales y ver el codigo fuente ya que no se usa un patrón determinado y todo está estrechamente relacionado, en el dojo solamente creas tu objeto e interactúas.

La documentación no es muy elaborada como la de Extjs, pero se comprende y trae por lo menos un ejemplo de cada cosa, además que es más facil encontrar como se hacen más cosas específicas por medio de Google que Extjs.

Bueno me regreso a programar que tengo seguir leyendo sobre Dojo ;)





Script que te lee lo que selecciones con el mouse

18 11 2008

Algo que me sucede muy a menudo, es que si hay mucho ruido no puedo concentrarme, tengo grandes problemas para mantener la concentración, más aún si estoy leyendo, ésto se hace un gran problema cuando tengo que leer documentación o manuales, una solución que me ayuda bastante es leerlo en voz alta, el cual no se puede en un entorno de trabajo compartido, porque molestarías a los compañeros, otra solución usando sintetizadores de voces para que te lean por ti, por lo que me di la tarea de hacer una pequeña investigación al respecto, y me encontré que espeak está instalado por defecto, lo cual hace mucho más facil el desarrollo del script, en ésta pagina hay buena información al respecto.

Linux por defecto tiene dos clipboard (cuando copias se almacena ahi), uno es cuando le das copiar o cortar y otro es cuando con el mouse seleccionas un texto, éste ultimo se pega cuando das click en el botón central de mouse. Para obtener el clipboard de seleccion del mouse y tener acceso de esa información desde la consola (o script) se necesita una utilidad que está en los repositorios de Ubuntu:

sudo aptitude install xclip

y con esa utilidad tenemos el texto seleccionado que nos va alimentar a espeak, para que nos hable; el siguiente script solo habla en inglés, pero se puede modificar para hable español (lo dejo de tarea para después :P ), ademas si se vuelve a llamar a el script se va a detener de seguir hablando:

#!/bin/bash
VOICE=`pgrep espeak`
if [ $VOICE ]; then
        killall espeak
        exit
else
        xclip -selection primary -out | espeak
        exit
fi




Organizando ideas nuevas

16 11 2008

Cuando programo me suele suceder que no me organizo en mis ideas, más que todo cuando las ideas que quiero plasmar son nuevas o bien el algo nuevo para mi, por lo que me di la tarea de buscar algún método que me ayudara a organizar las ideas.

Primero intenté utilizando notas, el problema de las notas es que no tienes relaciones por lo que a veces la nota se hace dificil de seguir.

Luego intenté usando diagramas de flujo o de casos de uso; no me gusto mucho ésta idea porque se me hacía difícil una herramienta que lo hiciera y correctamente.

Por último opté utilizando herramientas para lluvia de ideas y me recordé de un programa que me habían recomendado que se llama freemind.

Éste programa es sumamente sencillo de utiilzar, es más, se necesita aproximadamente 20 minutos para comprender la funcionalidad básica, bueno, eso me tomó a mi, que a veces soy durito :P

La metodología que utilizo junto con freemind es de crear los pasos que sigue la herramienta o bien donde quiero que valla, además agrego bifurcaciones o varios nodos para entender que hace el codigo en cada momento de una manera visual.





Porque complicarse?

12 11 2008

En el trabajo me tocó modificar el comportamiento de un sistema que doy matenimiento el cual después habló de él.

Me toco crear un pequeño sistema que mandaba por correo un link que éste a su vez mandaba a un formulario especial, para ser aprobado o no, el cual todo funcionaba bien, pero me di cuenta que uno de los parametros mandaba el valor anterior y no el actual, rebusque dentro del arbol de archivos revise código para que ese parametró fuera pasado, al final era más sencillo obtener el parametro, dentro del formulario especial obtener el parametro para luego ser procesado.

Eso deja como anecdota, así como a mi, muchos programadores buscan de primero la via más dificil i/o complicada :P

Como decía un profesor, los estudiantes siempre busca complicarse primero para entender…





Compresión en la lectura

30 10 2008

Unos de los problemas que más me molestan es el asunto que tengo problemas para concentrarme y la dislexia, que para un programador es algo duro de manejar, porque se está leyendo todo el día una y otra vez y muchas veces me ha pasado que por un punto y coma el programa no me corre, por eso me di la tarea de buscar técnicas de compresión de lectura y me encontré un buen artículo que da las primeras pautas para lograrlo:

  1. Predecir: Hacerse preguntas sobre lo que lees. Buenos lectores hacen predicciones sobre pensamientos, eventos, resultados y conclusiones.
  2. Imagenes: Formular imagenes mentales. Formularse imagenes mentales de lo que se lee o crear una especie de pelicula de lo que se lee es un buena practica
  3. Relate: Dibujar comparaciones mentales. Hacer relaciones con tu existente conocimiento con la nueva información y lo haces parte de tus ideas y mejoras la comprensión.
  4. Monitorea: comprueba tu comprensión. Comprueba tu conocimiento, realiza estadísticas de tu entendimiento y que tanto has mejorado, si mantienes una mejora lograras hacer el texto parte de tus ideas.
  5. Arregla lagunas de comprendimiento: No aceptes lagunas en tu comprensión de lectura, si encuentras que una palabra, terminó o frase no es de tu entendimiento trata de devolverte y releer o bien buscar el significado para que toda la frase tenga significado.

Al final son buenas prácticas aplicar estos 5 conocimientos para hacer el día a día más eficiente.

Original | http://academic.cuesta.edu/acasupp/AS/302.HTM





Script en python para hacer respaldos

5 10 2008

Ultimamente me ha interesado bastante python tanto asi, que me di la tarea de ir haciendo programitas (scripts) que hagan cosas automaticamente por mi.

Unas de las ideas que se me presentó es hacer un respaldo, ya que en la computadora que tengo en el trabajo ultimamente me ha dado problemas, creo que es el disco duro que está en las últimas, por dicha nos van a cambiar la maquinas :D

Bueno volviendo al tema, me dieron acceso (ssh) a otro maquina para que subiera mis respaldos, como un respaldo es algo que se hace monotonamente todo el tiempo decidi hacer el script pero en python, normalmente estos tipos de scripts se hacen en shell (bash, sh, awk, perl, etc), personalmente me gusta bastante python, por lo que investigue como hacer llamadas al sistema y éste es el resultado:

import os

# Definicion de la variables que para preconfigurar
backupDir = '/home/edder/Backups/'
backupUser = 'backup'
backupPass = '*******'
summary = ""
backupDest = 'edder@192.168.0.x:/home/edder/backups/'
webroot = '/var/www/'

#funcion que ejecuta un comando y devuelve el resultado
def run_command(command, message):
	results = os.system(command)

	if results == 0:
		return message + '\n'
	else:
		return str(results) + "\n"

# comando y mensaje que hace un respaldo de mysql
command = 'mysqldump -u ' + backupUser + ' -p'+ backupPass + ' website > ' + backupDir + 'website.sql'
message = "Backup completed of the database\n"
summary += run_command(command, message)

#comando que respalda un website (apache) en un tar.gz
command = 'tar -pzcf ' + backupDir + '/website.tar.gz ' + webroot+ 'website'
message = "Backup of page website completed\n"
summary += run_command(command, message)

# comando que copia los respaldos via ssh a otra maquina via rsync
command = 'rsync -avz ' + backupDir + ' ' + backupDest
message = "Backup stored in the remote computer\n"
summary += run_command(command, message)

# los resultados obtenidos
print summary

Al script le falta pulir pero se entiene la esencia de lo que hace ;)