martes, 27 de noviembre de 2007

Menu agregar/quitar

Hace ya algún tiempo que no posteo nada en el blog así que hoy he decidido dejar aquí un poco de los conocimientos adquiridos con este mensaje.
Mientras creaba el nuevo portal en el que estoy trabajando me ví en la necesidad de tener en uno de los formularios del sitio un menú de esos que permite incluir y/o excluir elemento de un listado, los típicos con un botón de agregar hacía uno y quitar hacía otro. Seguro que no es un misterio pero después de dar unas vueltas por la red no encontré ningún script que se adaptase a mis necesidades así que decidí crear uno. Bueno parte la obtuve de un sitio el cual ahora mismo no recuerdo pero como no pedía (que yo recuerde :P) conservar la nota legal (ni tenía, que yo recuerde de nuevo :P) lo utilizé sin más y modificandolo llegué a obtener el script que presento a continuación.
El script está compuesto por un par de funciones una para añadir / agregar y otra para eliminar / excluir. Se aplica a un par de elementos select y utilizando un par de elementos cualquiera se pueden crear los botones.
El script en ejecución tendría el siguiente aspecto.


<<>>


Para utilizarlo solo debemos crear el formulario, los botones y añadir las dos funciones javascript más abajo.

Lo único que deberas personalizar es la llamada a las funciones desde los botones, aquí se llaman desde el evento onClick del elemento <A> pero puedes utilizarlo de cualquier otro modo, solo debes llamar add_selected(nombreSelect1,nombreSelect2) y del_selected(nombreSelect1,nombreSelect2)


function add_selected(eout, ein){
var ob = document.getElementById(eout);
var oIn = document.getElementById(ein);
while (ob.selectedIndex != -1) {
var oSelected = ob.options[ob.selectedIndex];
var newOption = document.createElement('option');
newOption.setAttribute('value',oSelected.value);
newOption.innerHTML = oSelected.innerHTML;
oIn.appendChild(newOption);
newOption.selected = true;
ob.removeChild(oSelected);
}
}
function del_selected(eout,ein)
{
add_selected(ein,eout);
}

martes, 18 de septiembre de 2007

Como instalar Perl XML::DOM

Despues de haberme peleado para instalar XML::DOM en el servidor, queria dejar por si puede ayudar a alguien.
Al utilizar XML::DOM encontre dos problemas, el primero fue al instalarlo, cpan no podia instalar XML::DOM sin forzarlo, así que despues de buscar en el gugle encontré rapidamente la solucion. El problema era que faltaba las cabeceras de expat por instalar. Así que utilizando apt-get rapidamente instalé libexpat-dev como me aconsejaban un par de sitios enunciados por el buscador. Una vez instalado no hubo ningún problema para completar el comando de instalación de cpan XML::DOM
Seguidamente el problema que me encontré fue al utilizar el metodo parsefile de XML::DOM este provocaba problemas de codificacion de los archivos. Despues de otra pequeña inquisicion en gugle dí con que existe un problema interno no resuelto en XML::Parser, el cual impide tratar cualquier fichero que no sea unicode. Bien la solución con la que dí fue menos elegante pero eficaz, en lugar de utilizar el metodo para guardar la definicion de xml que generaba utilice la entrada directa a un archivo y opté por reescribir de nuevo el archivo. De esta manera podía dejar los archivos codificados en UTF-8 para que pudiesen ser leidos por xml_dom en php.

miércoles, 30 de mayo de 2007

Querido Newbie

Esta es la traducción de un artículo de acmqueue.com podeís encontrar la versión original en http://www.acmqueue.com/modules.php?name=Content&pa=showpage&pid=482. He intentado traducir fielmente el artículo aunque no siendo un profesional ni invirtiendo demasiado tiempo intento tener algo leible. Espero disfruteis con el artículo.


Estimado KV,
Soy nuevo a la programación y he justo comenzado a leer algunos libros acerca de la programación, particularmente de C++ y de Visual Basic. Disfruto de verdad el programar - hasta el punto que en el último par de meses nunca he faltado un día sin escribir un trozo código. Mi preocupación principal ahora es lo que sostiene el mundo para los programadores. ¿Si llaman a alguien programador (es decir, profesionalmente), qué programará realmente él o ella? ¿Inventará siempre nuevo software o qué, realmente? Esto está principalmente en el caso alguien que no trabajara para algún otro. ¿Mi otra pregunta es, puedes realmente hacerte una carrera como programador independiente, y qué programarás básicamente?
un programador Newbie


Estimado Newbie,
“Qué espera el mundo de los programadores?” Ésta es una pregunta tan interesante que no voy a darte ningún abuso para describirte como newbie ni para mencionar Visual Basic en cortés compañía. No que yo sea cortés compañía, pero puede haber niños alrededor de que podrían oírte. ¡Debemos cuidar a los niños!

Aunque escogiendo algunos libros en diversos lenguajes de programación, que es lo que has hecho ya, te enseñará que sobre esos lenguajes, no te enseñarán probablemente sobre programación sino solamente sobre la sintaxís del lenguaje que estás estudiando. Voy a jugarme un riñon aquí y a asumiré que lo qué realmente deseas ser no es tanto programador, un término realmente concreto, sino ingeniero.

En los viejos días cuando tenía el pelo y dientes, o, realmente más cercano a cuando nací y por lo tanto no tenía ni pelo ni diente alguno, un programador era la persona que entraba el programa en la computadora. Otra gente diseñaba el software y los sistemas, y entonces los programadores - había a menudo legiones de ellos - traducían estos diseños en software que la computadora podía entender.

Con la llegada de la programación interactiva, en comparación con la programación secuencial, la línea entre el programador y el ingeniero se difumina. Ahora un solo ingeniero puede ser el diseñador, el programador, el documentador, la garantía de calidad, el etc. No es que esto sea siempre la opción correcta, pero es cómo la industria se ha desarrollado. El número de gente que es terminantemente programadora, por lo tanto, es realmente pequeño.

Si deseas ser freelance - como dices, independiente - ingeniero, debes dejar esos libros de lenguajes de programación al azar y escoger algunos libros de cómo construir software. He dejado mi lista de lecturas recomendada en un artículo anterior (“Kode Vicious Bugs Out,” abril de 2006 de Kode) y así que no la repetiré aquí.

Lo que diré es que puedes tener ya una de las habilidades que necesitas a, que es lo que practicas diario. La informática es una ciencia y un arte. No sé porqué la gente siente la necesidad de hacer esa distinción tan a menudo, porque la mayoría de las ciencias son arte, en el sentido que para seguir siendo bueno en hacer ciencia necesitas practicar, apenas como con un arte. ¡El hecho de que dices, “… en el último par de meses nunca he faltado un día sin escribir un trozo código,” me conduce a creer que tienes una vida de servidumbre y de depresión en adelante! Oh, huh, que no es absolutamente lo que quería decir. Quería decir que ése practicar diario es un componente muy importante de ser buen ingeniero, o programador si tienes gusto.

No es suficiente escupir código, aunque, cualquier persona que ha oído al vecino trombonista autodidacta puede decirtelo. Después de años de tocar las mismas canciones, nunca las consigue tocar correctamente. Necesitas tomar medidas adicionales para anticiparte en tu arte. Lo primero es leer tanto código como escribes, probablemente más. El software es una forma de expresión, como prosa de la escritura, y como con cualquier tipo de expresión hay idiomas, frases, y los modos del pensamiento que conducen - o en nuestro caso, trabajando - a los diseños que satisfacen y a los que conducen al desastre. Los profesores de literatura són correctos en su aserción en que la “lectura de las obras clásicas” pueda ayudar con tu escritura.

En software hay un montón de obras clásicas a leer, y hay libros acerca de estas obras clásicas. Para el establecimiento de una red, uno de mis principales campos de interés, el sistema operativo de FreeBSD y su establecimiento de una red del TCP/IP. En el mundo de la base de datos hay MySQL, y para los servidores del Web, Apache. Estas bases de código son obras clásicas, y son Open Source así que són sistemas excelentes para estudiar.

Tener la historia completa del desarrollo, bajo la forma de revisionado del repositorio del código, es otra razón de trabajar con estos sistemas, puedes ver cómo se desarrollan en un cierto plazo, qué cambios ocurrieron, y por qué razón. Ninguno es perfecto, pero cada uno está bien documentado y és un ejemplo de un sistema vivo, con respiración. Si fueras arquitecto - de edificios, pues los arquitectos diseñan edificios y no software, aunque ese concepto es actualmente popular - desearías viajar por el mundo y estudiar varios pedazos de arquitectura. El software para aprende es mucho más barato, porque no necesitas un billete de avión - puedes permanecer en casa y estudiar los grandes trabajos de nuestra industria con una simple conexión de Internet.

El siguiente paso es conseguir que otros miren tu código. A menos que seas ese genio de los uno-décimo-de-uno-por ciento que puede hacer toda a la primer - y creo .1 por ciento es abundante - necesitas a gente para enseñarte y repasar la primera vez tu trabajo. Una vez más el Open Source puede ayudar aquí.

Enviar remiendos de tus programas preferidos, y aprender a trabajar con otros, esa es una de las grandes habilidades no enseñadas en cualquier departamento de la informática. Observar bien que un mentor es sólamente una guía y no debes crecer demasiado dependiente en él, o no aprenderás realmente nada. Un mentor es la persona a recurrir para el consejo cuando has llegado al final de tus ingenios, no cuando tienes una pregunta que puedes contestarte sin ser demasiado perezoso de trabajar en algo distinto. La holgazanería es una manera pobre de sentir bien a un buen ingeniero.

En cuanto a lo que puedes esperar del amplio mundo del software, bien, como el resto del mundo, 90 por ciento de él es una trampa. Si eres ingeniero freelance o trabajas para una gran compañía, vas raramente a escribir cantidades enormes de código definido por tí. Trabajarás definitivamente más a menudo en el código de otra gente que en tus diseños originales. Hay dos maneras de llevar esto: la primera es matar a cada uno de los ingenieros en la tierra, una tarea que podría tomarte un rato y resultando para tí en la perdida de tus privilegios de Internet; el segundo es cerciorarse siempre de tener cierto sistema en el cual seas tu quien conduce el trabajo. En realidad, así es cómo guardo los fragmentos restantes de mi cordura.

Sorprende a muchos de mis amigos no-frikis-computadoras que después de un día de trabajo, por las tardes y los fines de semana haría lo qué a ellos les parece la misma cosa, pero no es. Cuando trabajo en mis propios diseños y código, soy el amo, llamo la consonancia, y éso tiene más valor de lo que la mayoría de la gente puede imaginarse.

A tu pregunta final la respuesta es, programadores freelance puede llevarlo absolutamente bien. La gente freelance consigue a menudo algo menos del trabajo interesante, aunque, por lo menos con mi experiencia, porque consiguen la servidumbre que los lleno-contadores de tiempo no desean hacer. Eso no significa que no debas seguir esta trayectoria, pues puede ser absolutamente lucrativa y si está equilibrado bien puedes dejarte más tiempo para tus propios proyectos. Pero no debes engañarte en tus ideas de que entrarás como un freelance y diseñarás o construirás un gran sistema para un grupo o una compañía; eso es un acontecimiento muy raro. Lo que crearás depende exclusivamnte con quien trabajes. Podría ser sobre cualquier cosa, que es mitad de la diversión del trabajo en software.
Kilovoltio

lunes, 14 de mayo de 2007

MyRssScreenlet 1.0

De nuevo una pequeña creación que realicé el fin de semana pasado, un widget para el gestor de ventanas Compiz para gnome o kde que permite leer las noticias de un archivo de sindicación de noticias RSS, por el momento este solo acepta RSS, pero seguramente se añadirá atom proximamente.
MyRssScreenlet 1.0
Los screenlets de Compiz son scripts en python que permiten mostrar en el escritorio perqueño gadgets con especial hincapié estético. Si utilizais Compiz probadlo, darán un toque de diseño a vuestro escritorio.

martes, 24 de abril de 2007

El web2.0 ha entrado con fuerza y se esta consolidando como blogger o flickr, webs que integran las nuevas tecnologías que forman parte del web 2.0 como Ajax.

No solamente existe Ajax (Asynchronous Javascript and XML) también se ha consolidado la técnología para la sindicación de noticias RSS/Atom, protocolos que surgieron hace no muchos años y se han implantado como un sistema para agregar contenidos de una página web a otra.
La sindicación de contenidos permite rellenar las webs de hoy en día con contenido relevante en lugar de utilizar elementos esteticos para ello, o también puede servir para crear un recopilatorio de contenidos relevantes. Otra de las tecnologías que ha prevalecido ha sido PHP, implantandose como "middleware" entre los servidores de aplicaciones y los usuarios, los servicios en php permiten agilizar la integración sin tener que realizar un desarrollo muy elaborado y sirven de interfaz a otros sistemas que son más complicados a integrar en una web. De estos sistemas hay varios ejemplos, quizás ahora mismo no sepa citar ninguno, pero la mayoría de portales utilizan php solo como interfaz para luego interaccionar con un sistema más complejo basado en otras tecnologías.
Último citar Javascript y Flash dos tecnologías cliente que han adquirido fuerza con el tiempo y ahora son elemento imprescindible de las llamadas RIA's (Rich Internet Application), aunque Flash ya era desde un principio un sistema ideal para crear este tipo de sites no ha sido hasta la llegada de Ajax que Flash ha dado el salto y se erguido como un entorno de creación de este tipo de aplicaciones, la gente no estaba acostumbrada o Flash a llegado tarde, de cualquier modo Javascript sigue imponiendose y relega a Flash a una segunda posición.

miércoles, 11 de abril de 2007

rss4cvs en PHP

Hola a tod@s, he creado este nuevo blog para dejar huella de alguna manera con lo que voy haciendo al margen del trabajo. En este blog iré dejando consejos y programas que voy creando para facilitarme la vida así espero que también se la facilita a alguien más.
De momento mi primera aportación es un generador de noticias en RSS o atom que crea un feed de las entradas que se envian a un servidor CVS, este generador està creado con Zend_Feed. Es rapidamente integrado en el sistema ya que no hay más que incluirlo en el archivo loginfo en la carpeta CVSROOT dentro de la raiz del repositori, permitiendo así guardar todos los cambios y los mensajes de log.

Si teneis cualquier duda contactadme, estaré encantado de ayudar en lo que sea posible.

#!/usr/bin/php -q

# rss4cvs es un script para crear un feed de los envios al cvs
#
# --------------------------------------------------------
# $Id: rss4cvs.php,v 1.22 2007/04/08 12:14:09 iago Exp $
# --------------------------------------------------------
/**
* ______ ______ ______ _ _ _______ _ _ ______
* (_____ \ / _____) _____) | (_|_______|_) (_) _____)
* _____) | (____( (____ | |_____ _ _ ( (____
* | __ / \____ \\____ \|_____ | | | | | \____ \
* | | \ \ _____) )____) ) | | |_____ \ \ / /_____) )
* |_| |_(______(______/ |_|\______) \___/(______/
*
* rss4cvs $Revision: 1.22 $ , licencia GPLv2
* Este programa funciona con Zend_Framework, cvs 1.1.12.
* Utiliza la clase Zend_Feed para generar feed compatible con rss2.0 o atom, ver informacion sobre
* zend_feed para más.
*
* ==Instalacion==
*
* * copiar en cualquier lugar del sistema de archivos, hacerlo ejecutable.
* * Editar el archivo loginfo que se encuentra en la carpeta CVSROOT del reositorio, ver $CVSROOT.
* *Insertar :
* ALL /root/rss4cvs/rss4cvs.php %{sVv} %p "`(echo "";id;echo %s; date;cat)
*
*
*/
/**
* @todo dar opcion de formato destino.
* @todo mejorar la obtencion de archivos fuente (ahora mismo la fuente es un archivo local, el archivo destino)
*/
/**
* opciones de configuracion
*/
$output_dir = '/var/www/rss/';
$output_file = 'cvs.rss';
$use_cache_feed = true;
$feed_title = 'TITULO_FEED';
$feed_description = 'DESCRIPCION_FEED';
$feed_link = 'URL_DESTINO';
$feed_syndication_uri='URL_BASE';
$feed_dir = '/var/www/rss/';
$viewcvs_url="URL_DE_VIEWVC";
$rss4cvs_logo_url = "URL_DEL_LOGO";
$item_title="Nuevo cambio en %s";
$version = '0.9.1';
$max_entries = 50;
date_default_timezone_set('Europe/Madrid');
$feed_type='rss';
$charset = 'iso-8859-1';
$language = 'es';
$license = "GPLv2";
$generator = 'rss4cvs '.$version;

// Zend framework (http://framework.zend.com)
require_once 'Zend.php';
require_once 'Zend/Feed.php';

require_once 'Zend/Console/Getopt.php';
try {
$opts = new Zend_Console_Getopt(
array(
'commited_file|c=s' => 'Nombre del archivo que se ha cambiado',
'old_version|o=s' => 'Numero de version actual o NONE',
'new_version|n=s' => 'Numero de la nueva version recibida por el archivo',
'path_commit_file|p=s' => 'Ruta del modulo desde la raiz del repositorio',
'log_message|m=s' => 'Mensaje de log',
'verbose|v' => 'Mostrar mensajes de debug',
'help|h' => 'Mostrar este mensaje'
)
);

$opts->parse();
if(!$opts->getOption('c')||!$opts->getOption('o')||!$opts->getOption('n')||!$opts->getOption('p')||!$opts->getOption('m'))
{
usage();

}
$commited_file=$opts->c;
$old_version=$opts->o;
$new_version=$opts->n;
$path_commit_file=$opts->p;
$t_comment=htmlentities($opts->m);


$verbosity=false;
if($opts->getOption('v'))
{
echo "Verbosity : on\n";
$verbosity=true;
}
if($opts->getOption('h'))
{
usage();
}

}
catch (Zend_Console_Getopt_Exception $e) {
echo $e->getUsageMessage();
exit;
}
// fichero en que se han realizado los cambios
//$commited_file = (isset($argv[1]))?$argv[1]:usage();
//// version existente en el repositorio (NONE sino existe ninguna version)
//$old_version = (isset($argv[2]))?$argv[2]:usage();
//// version que se define al archivo
//$new_version = (isset($argv[3]))?$argv[3]:usage();
//// ruta relativa a la raiz del repositorio (sirve apra obtener el modulo)
//$path_commit_file = (isset($argv[4]))?$argv[4]:usage();
//// comentario añadido al commit
//$t_comment = (isset($argv[5]))? htmlentities($argv[5]):usage();
/**
* funcion devolviendo un mensaje de ayuda
*/
function usage()
{
global $opts;
echo "
______ ______ ______ _ _ _______ _ _ ______
(_____ \ / _____) _____) | (_|_______|_) (_) _____)
_____) | (____( (____ | |_____ _ _ ( (____
| __ / \____ \\____ \|_____ | | | | | \____ \
| | \ \ _____) )____) ) | | |_____ \ \ / /_____) )
|_| |_(______(______/ |_|\______) \___/(______/

rss4cvs $version, licencia GPLv2
Este programa funciona con Zend_Framework, cvs 1.1.12.
rss4cvs es un script para crear un feed de los envios al cvs\n
Utiliza la clase Zend_Feed para generar feed compatible con rss2.0 o atom, ver informacion sobre zend_feed para más.\n\n
";

echo $opts->getUsageMessage();
exit;
}
/**
* funcion escribiendo en el log los pasos que se dan
* @param string $message Mensaje de log
*/
function writelog($message)
{
global $verbosity;
$logfile = './rss4cvs.log';
$smessage = strftime("%d/%m/%y %H:%M",time())." -- ".$message."\n";
if($verbosity)
{
echo $smessage;
}
$fd = fopen($logfile,'a+');
if(!fwrite($fd,$smessage))
{
echo "rss4cvs Error : (No tiene permisos de escritura en $logfile) \tmessage :$message \n";

}
fclose($fd);
}

writelog("Buscando entradas antiguas en ".$feed_dir.$output_file);
//comprobamos si el archivo destino existe para recuperar antiguas entradas
if(file_exists($feed_dir.$output_file))
{
// Fetch the latest Slashdot headlines
try {
$feed = Zend_Feed::importFile($feed_dir.$output_file);
} catch (Zend_Feed_Exception $e) {
// feed import failed
$message = "Exception caught importing feed: ".$e->getMessage();
writelog($message);
exit;
}
}
// definimos datos del canal
/**
*@todo separar en canales los diferentes modulos
*/
$ftitle=((is_object($feed))||isset($feed->title))?$feed->title():$feed_title;
$flink=((is_object($feed))||isset($feed->link))?$feed->link():$feed_link;
$fdesc=((is_object($feed))||isset($feed->description))?$feed->description():$feed_description;
$channel = array(
'title' => $ftitle,//$feed->title(),
'link' => $flink,//$feed->link(),
'description' => $fdesc,//$feed->description(),
'entries' => array()
);
$existent_titles = array();
// Loop over each channel item and store relevant data
if(isset($feed))
{
foreach ($feed as $item) {
if(count($channel['entries'])<$max_entries)
{

if(!in_array($item->title(),$existent_titles))
{
$existent_titles[] = $item->title();
$title_verified = $item->title();
}
else
{
$existent_titles[] = $item->title()." ".strftime("%d/%m %H:%M:%S",time());
$title_verified = $item->title()." ".strftime("%d/%m %H:%M:%S",time());
}
$channel['entries'][] = array(
'title' => $title_verified,
'link' => $item->link(),
'description' => $item->description(),
'content' => $item->content(),
'lastUpdate' => $item->lastUpdate()
);
}
}
}
$comment_format = "Nuevo cambio en el archivo $commited_file
\n%s
\nViewvc : ".$viewcvs_url."/".$path_commit_file."";
$description_format = "%s";
$content=sprintf($comment_format,$t_comment);
$description=sprintf($description_format,$t_comment);


$possible_title = sprintf($item_title,$path_commit_file."/".$commited_file);

if(!in_array($possible_title,$existent_titles))
{
$existent_titles[] = $possible_title;
$title_verified = $possible_title;
}
else
{
$existent_titles[] = $possible_title." ".strftime("%d/%m %H:%M",time());
$title_verified = $possible_title." ".strftime("%d/%m %H:%M",time());
}
$channel['entries'][] = array(
'title' => $title_verified,
'link' => $viewcvs_url."/".$path_commit_file."/".$commited_file,
'description' => $description,
'content' => $content,
'lastUpdate' => time()
);
writelog("Nuevo cambio en $commited_file");
$channel['charset'] = $charset;
$channel['language'] = $language;
$channel['generator'] = $generator;
$channel['image'] = $rss4cvs_logo_url;
$channel['published'] = time();
$channel['copyright'] = $license;
// Fetch the latest Slashdot headlines
try {
$newfeed = Zend_Feed::importArray($channel,$feed_type);
} catch (Zend_Feed_Exception $e) {
// feed import failed
$message = "Exception caught importing feed: ".$e->getMessage();
writelog($message);
exit;
}

if(@file_put_contents($output_dir.$output_file,$newfeed->saveXML())!=0)
{
writelog("Nuevo feed creado ".$output_dir.$output_file . " con exito.");
}
else
{
writelog("Error creando ".$output_dir.$output_file);
}

?>