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);
}

?>