viernes, 29 de mayo de 2009

Practica 6

¿Qué hace esta aplicación?



Esta aplicación carga una base de datos rss y muestra una lista con los títulos de las noticias, libros o lo que contenga el rss, de forma que la pinchar sobre ellos nos muestra la noticia al completo y si pinchas sobre el título (que aparece en la parte superior) pasa a la siguiente noticia.



En mi caso lo he hecho para una base de libros formada como un rss (para que pudiera también abrir los rss de noticias de la práctica anterior). La página principal tiene 3 casillas desplegables: en la primera seleccionamos si cargamos la base de libros o las noticias; en la segunda seleccionamos el número de noticias a mostrar en la lista (he puesto un máximo de 10 porque algunos rss de noticias no tenían más y tampoco lo consideraba necesario); en la tercera seleccionamos el género del libro haciendo una especie de filtrado (esta solo funciona con "Mi biblioteca").



Ejemplo: si nosotros seleccionamos la biblioteca en la primera casilla, con solo detectar el cambio ya se carga la lista igual que cuando se modifica cualquiera de las otras casillas, se nos cargan (por defecto) 10 libros. Si cambiamos la segunda casilla aparecerán los primeros x libros que le indiques. Y si variamos la tercera casilla solo se te muestran los primeros x libros del género que selecciones (hay muy pocos libros así que si marcas más de los que tiene solo te muestra los que tiene valga la redundancia). Si una vez tengamos la lista deseada pinchamos sobre un título (esto también funciona para las noticias), vemos el resumen del libro (en caso de noticias la noticia seleccionada), y si pinchamos sobre el título pasamos al libro (o noticia) siguiente, de forma que si tenemos seleccionado género el siguiente del género. Si pinchamos sobre "El Señor de los Anillos" y tenemos marcado el género "Fantástico" y luego pinchamos sobre el título pasamos a "El Hobbit" (puesto que es el siguiente del género), en lugar de "La Isla del Tesoro" que sería el siguiente libro (si tenemos ninguno en género pasa a este), y si no hay ninguno detrás de este vuelve al primero.


Esta aplicación está orientada para una librería pero pongo lo de las noticias por ver que usos, además de para los que se ha propuesto, tiene, como, por ejemplo un gestor de noticias.


Aplicación servidor



El servidor es muy parecido al de la práctica anterior y se encarga de recibir la url de donde se encuentra el rss en cuestión y crear un rss de salida que lo tomará el cliente con los x primeros elementos o items, donde x será un parámetro que también se le pasa. El servidor está escrito en perl y su código es el siguiente:


#!/usr/bin/perl

use CGI qw(:standard);
use XML::RSS;
use LWP::Simple qw(get);

my $numero_elementos = param('num_elementos');
my $url = param('url');
#Baja fichero
my $rdf = get($url);
my $rss = new XML::RSS;
$rss->parse($rdf);
my $rss_salida = new XML::RSS;
$rss_salida->channel( title => 'Resumen feed',
link => $url,
description => 'Resumiendo el feed' );
print header( -type => 'application/xhtml+xml' );

for (my $i = 0; $i < $numero_elementos;$i ++ ) {
$rss_salida->add_item( title => $rss->{'items'}[$i]->{'title'},
link => $rss->{'items'}[$i]->{'link'},
pubDate => $rss->{'items'}[$i]->{'pubDate'},
description => $rss->{'items'}[$i]->{'description'},
category => $rss->{'items'}[$i]->{'category'} );
}
print $rss_salida->as_string;

Aplicación cliente



El cliente se encarga de ver que hay en los valores de las casillas y pedir al servidor lo necesario, y una vez que tiene los datos llama a las funciones necesarias para mostrar, en la parte de abajo donde en el html tenemos con un div con id=RSS, lo mencionado anteriormente.


var request;
var variable;
var html="<hr>";
var items;

Esta función es la que se encarga de llamar al servidor, pasandole la dircción de la fuente, y obtener los datos necesarios para trabajar con ellos en la funcion escribe_RSS


function pide_RSS() {
html="<hr>";
request = new XMLHttpRequest();
var url=document.getElementById('feed').value;
//var cuantos=document.getElementById('cuantos').value;
var peticion_str = 'cgi-bin/XMLvar_2.cgi?url='+encodeURIComponent(url)+'&num_elementos='+10;
request.open('GET', peticion_str , true);
request.onreadystatechange= escribe_RSS;
request.send(null);
}

Esta función trata con los datos que recibimos del servidor y mostramos las listas de elementos, estas listan tendrán el tamaño que aparece en segundo seleccionable del html. Si tenemos algún género seleccionado nos muestra solo los libros de este género.


function escribe_RSS(){
if ( request.readyState == 4 ) {
if ( request.status == 200 ) {
// alert(request.responseText);
var doc = request.responseXML;
var root=doc.documentElement;
var cuantos=document.getElementById('cuantos').value;
var quegenero=document.getElementById('genero').value;
var k = 0;
items=root.getElementsByTagName('item');
for ( var i = 0; i < items.length; i ++ ){

var title = items[i].getElementsByTagName('title')[0];
var genero = items[i].getElementsByTagName('link')[0];
if (quegenero == 'Ninguno'){
k++;
html += "<dt><button onClick='prueba"+i+"()'>"+title.firstChild.data+ "</button></dt>";
if (k == cuantos){
i=items.length;
}
}
else if (quegenero == genero.firstChild.data){
k++;
html += "<dt><button onClick='prueba"+i+"()'>"+title.firstChild.data+ "</button></dt>";
if (k == cuantos){
i=items.length;
}
}
}
html += "";
document.getElementById('RSS').innerHTML=html;
}
}
}

Esta función es casi igual que la primera, es decir, que llama al servidor con la url y el número de elementos necesarios para trabajar en este caso con escribe_otro. Al volver a llamar al servidor estamos recargando continuamente la los datos, de forma que estos son siempre los más actuales respecto a la base de datos, de forma que si se cambia algo en la base de datos aparece incluso en cuanto pinchamos en un título.


function prueba(){

request = new XMLHttpRequest();
var url=document.getElementById('feed').value;
var cuantos=document.getElementById('cuantos').value;
var peticion_str = 'cgi-bin/XMLvar_2.cgi?url='+encodeURIComponent(url)+'&num_elementos='+cuantos;
request.open('GET', peticion_str , true);
request.onreadystatechange= escribe_otro;
request.send(null);

}

Esta función toma el item que se ha pinchado y muestra este con su descripción, y nos crea el trozo de la página en el que se nos muestra el título junto con su resumen o noticia, de forma que al pinchar sobre este pasamos al siguiente título del género.


function escribe_otro(){
if ( request.readyState == 4 ) {
if ( request.status == 200 ) {
// alert(request.responseText);
var quegenero=document.getElementById('genero').value;

html = "<hr>";
var title = items[variable].getElementsByTagName('title')[0];
var description = items[variable].getElementsByTagName('description')[0];
var genero = items[variable].getElementsByTagName('link')[0];
variable = variable + 1;
if (variable == items.length){
variable = 0;
}
if (quegenero == genero.firstChild.data || quegenero == 'Ninguno'){
html += "<dt><button onClick='prueba"+variable+"()'><font size='+3'>"+title.firstChild.data+ "</font></button><p>"+description.firstChild.data+"</p></dt>";
}
else{
for (var n=variable;n<items.length;n++){
var genero = items[n].getElementsByTagName('link')[0];
if (quegenero == genero.firstChild.data){
var title = items[n].getElementsByTagName('title')[0];
var description = items[n].getElementsByTagName('description')[0];
variable = n+1;
html += "<dt><button onClick='prueba"+variable+"()'><font size='+3'>"+title.firstChild.data+ "</font></button><p>"+description.firstChild.data+"</p></dt>";
n=items.length
}
if (n == (items.length-1)){
n=-1;
}
}
}


html += "";
document.getElementById('RSS').innerHTML=html;
}
}
}




Estas funciones se encargan de indicarnos qué título se ha pinchado y llamar a la función prueba para que cargue la página



function prueba0(){
variable = 0;
prueba();
}
function prueba1(){
variable = 1;
prueba();
}
function prueba2(){
variable = 2;
prueba();
}
function prueba3(){
variable = 3;
prueba();
}
function prueba4(){
variable = 4;
prueba();
}
function prueba5(){
variable = 5;
prueba();
}
function prueba6(){
variable = 6;
prueba();
}
function prueba7(){
variable = 7;
prueba();
}
function prueba8(){
variable = 8;
prueba();
}
function prueba9(){
variable = 9;
prueba();
}

El documento HTML que he usado para llamar a las funciones anteriores es:


&#60!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&#62
&#60html&#62
&#60head&#62
&#60title&#62BIBLIOTECA dinámica&#60/title&#62
&#60script type='application/javascript' src='peticion.js' &#62&#60/script&#62
&#60/head&#62

&#60body&#62
&#60h1&#62BIBLIOTECA&#60/h1&#62
&#60p&#62Busca el libro que deseas y mira de que trata, y si te gusta, pues a comprarlo :-)&#60/p&#62
&#60p&#62También puedes ver algunas noticias interesantes, para ello asegúrate de que el seleccionable de género está puesto en ninguno
&#60div id='formulario'&#62


&#60select name="feed" id='feed' size="1" onChange='pide_RSS()'&#62
&#60option&#62 Elegir feed
&#60option value="http://www.fileden.com/files/2007/11/7/1570028/biblioteca.xml"&#62 Mi biblioteca
&#60option value="http://www.ideal.es/granada/rss/feeds/ultima.xml"&#62 Ideal
&#60option value="http://rss.marca.com/rss/descarga.htm?data2=385"&#62 Marca
&#60option value="http://feeds.weblogssl.com/xataka2.xml"&#62 Xataka
&#60option value="http://feeds.feedburner.com/NoPuedoCreerQueLoHayanInventado.xml"&#62Nolopuedocreer
&#60/select&#62
&#60select name="cuantos" id='cuantos' size="1" onChange='pide_RSS()'&#62
&#60option value="10"&#62 10
&#60option value="9"&#62 9
&#60option value="8"&#62 8
&#60option value="7"&#62 7
&#60option value="6"&#62 6
&#60option value="5"&#62 5
&#60option value="4"&#62 4
&#60option value="3"&#62 3
&#60option value="2"&#62 2
&#60option value="1"&#62 1
&#60/select&#62
&#60select name="genero" id='genero' size="1" onChange='pide_RSS()'&#62
&#60option value="Ninguno"&#62 Ninguno
&#60option value="Aventuras"&#62 Aventuras
&#60option value="Ficcion"&#62 Ficción
&#60option value="Intriga"&#62 Intriga
&#60/select&#62


&#60div id='RSS'&#62 &#60/div&#62

&#60hr&#62
&#60p&#62&#60font size='-1' color='red'&#62&#60b&#62Ejemplo de uso:&#60/b&#62 si nosotros seleccionamos la biblioteca en la primera casilla, con solo detectar el cambio ya se carga la lista igual que cuando se modifica cualquiera de las otras casillas, se nos cargan (por defecto) 10 libros. Si cambiamos la segunda casilla aparecerán los primeros x libros que le indiques. Y si variamos la tercera casilla solo se te muestran los primeros x libros del género que selecciones (hay muy pocos libros así que si marcas más de los que tiene solo te muestra los que tiene valga la redundancia). Si una vez tengamos la lista deseada pinchamos sobre un título (esto también funciona para las noticias), vemos el resumen del libro (en caso de noticias la noticia seleccionada), y si pinchamos sobre el título pasamos al libro (o noticia) siguiente, de forma que si tenemos seleccionado género el siguiente del género. Si pinchamos sobre "El Señor de los Anillos" y tenemos marcado el género "Fantástico" y luego pinchamos sobre el título pasamos a "El Hobbit" (puesto que es el siguiente del género), en lugar de "La Isla del Tesoro" que sería el siguiente libro (si tenemos ninguno en género pasa a este), y si no hay ninguno detrás de este vuelve al primero.&#60/font&#62&#60/p&#62
&#60/body&#62
&#60/html&#62

Y funciona perfectamente


El funciona bien para lo que lo he probado pero he de reconocer que no he trabajado con un biblioteca muy grande, pero el adaptar el programa a los problemas que pueda tener creo que sería más bien de diseño web y trabajar con lo que te imprime el cliente, con lo que sería, principio sencillo, pero a mi pesar (ya que me gustaría ver si podría hacer una base de datos de los libros de mi casa y con esto puedo verlos desde cualquier sitio y de forma sencilla), a las alturas de curso que estamos y todas las entregas de prácticas y los examenes aquí mismo no puedo entretenerme mucho con ninguna práctica. En definitivamente el programa me ha funcionado bien aunque puede que en algún sitio se pueda optimizar algo, como siempre.


Puedes ver como funciona aquí

No hay comentarios: