Archivo de la categoría: Prácticas con Web

Importar contenidos a WordPress a partir de un RSS implementado en ASP.NET

Este post pretende dar una idea de las posibilidades de los sistemas RSS para guardar y recuperar toda la información contenida en una página web, un blog, o simplemente en una base de datos.

Es ya muy conocida la utilidad de esta tecnología para recibir información de interés, mediante los lectores RSS, previa suscripción a un canal, sin necesidad de visitar una a una las páginas web de las que deseas obtener dicha información.

Pues bien, WordPress.org incorpora la posibilidad de importar un fichero RSS, de tal manera que toda la información contenida en ese fichero será reconocida. Como el RSS tiene un formato XML estándar, hay garantías de que no se perderá información durante el camino.

Si tenemos la información en otro blog o página web, sólo debemos exportar el fichero con el código fuente del feed e importarlo directamente en WordPress.org. La mayoría de las páginas web cuentan hoy día con la posibilidad de obtener un feed de manera muy sencilla. Generalmente sólo hay que hacer click a un icono, generalmente con este aspecto:

La importación a WordPress.org es igualmente sencilla desde el panel de administrador de nuestro blog. En la parte izquierda, hacemos click en el menú desplegable Herramientas y podremos ver la opción Importar. Si al enlazar dicha opción no vemos la opción RSS, podemos instalar cualquiera de los plugins que se nos ofrece. Aquí teneís el más famoso: http://wordpress.org/extend/plugins/rss-import/

Si sois expertos en código php + WordPress o queréis adentraros en ese mundo, podéis intentar conseguir la importación del RSS sin plugins siguiendo este tutorial (está en inglés): http://perishablepress.com/press/2009/04/26/import-and-display-rss-feeds-in-wordpress/

Estructura de un RSS

<?xml version="1.0" encoding="ISO-8859-1" ?>
<rss version="2.0">
<channel>
<title>WebNet Architect</title>
<link>https://webnetarchitect.wordpress.com</link&gt;
<description>Tutorial para importar RSS mediante ASP.NET</description>
<item>
<title>Estructura de un RSS</title>
<link>http://wp.me/p1w1Ur-6G</link>
<description>Ejemplo de la estructura de un RSS básico</description>
</item>
</channel>
</rss>

La primera línea del documento es la declaración de XML que define la versión XML y la codificación de caracteres utilizados en el documento. En este caso, el documento se ajusta a la 1.0 especificación de XML y utiliza el conjunto de caracteres utf-8 .
La siguiente línea es la declaración RSS, que identifica que trata, de hecho, un documento RSS (más concretamente, RSS versión 2.0).

La siguiente línea contiene el elemento <channel> . Este elemento se utiliza para describir la fuente RSS. El elemento <channel> define tres elementos requeridos:

  • <title> : define el título del canal (por ejemplo, el nombre de su sitio Web)
  • <link> : define el hipervínculo al canal (por ejemplo, https://webnetarchitect.wordpress.com)
  • <description> : describe el canal (por ejemplo Tutorial para importar…)

Cada elemento de <channel> puede tener uno o más elementos de <item> . Cada elemento de <item> define un artículo dentro de la RSS feed.

El elemento <item> requiere tres elementos secundarios:

  • <title> : define el título del tema (por ejemplo, primer artículo)
  • <link> : define el hipervínculo al elemento (por ejemplo, http://wp.me/p1w1Ur-6G)
  • <description> – describe el elemento (por ejemplo, la descripción del primer artículo)

Primer paso: Comprobar tipos de datos en la tabla correspondiente de la base de datos.

En este ejemplo vamos a trabajar con la base de datos del Docu de la Universidad Cardenal Herrera CEU. Al trabajar con ASP.NET, lo normal es que las noticias se almacenen en la base de datos de Microsoft SQL Server. En nuestro caso, los artículos se almacenan en una tabla denominada DOCU_NOTICIA, que contiene los campos siguientes:

  • DNOT_Id : un campo de número entero de clave principal de incremento automático identificar de forma única cada artículo
  • DNOT_Titulo : un nvarchar(256), especifica el título del artículo.
  • DNOT_Autor : un nvarchar(50), especifica al autor del artículo.
  • DNOT_Cabecera : un nvarchar(500), proporcionando una descripción más detallada del artículo.
  • DNOT_Categoría: nvarchar(50), especifica la categoría del artículo.
  • DNOT_Texto: un ntext con el texto de la noticia.
  • DNOT_Imagen: un nvarchar(50), especifica la url de la imagen alojada en el servidor.
  • DNOT_Fecha – un datetime, indicando la fecha que publicó el artículo.

Nos hemos dejado otros campos de la tabla, pero los mencionados son los únicos que estamos interesados para utilizar en nuestro feed.

Segundo paso: Creación de un procedimiento almacenado para consultas a la tabla.

 Si no existe ya el procedimiento almacenado que realice las consultas a los campos de la tabla que necesitamos para generar nuestro RSS, tenemos que crearlo.

Para ello recomiendo instalar el SQL Server Management Studio Express 2008, que se puede descargar aquí.

 Para crear el procedimiento almacenado sp_obtener_DOCU_NOTICIA_todosRSS escribimos el siguiente código:

CREATE PROCEDURE [dbo].[sp_obtener_DOCU_NOTICIA_todosRSS]
AS
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SELECT
[DNOT_Id] as [id],
[DNOT_Titulo] as [title],
[DNOT_Cabecera] as [header],
[DNOT_Texto] as [description],
[DNOT_Fecha] as [pubDate],
[DNOT_Categoria] as [category],
[DNOT_Imagen] as [image],
[DNOT_Autor] as [author]
FROM
[dbo].[DOCU_NOTICIA]
ORDER BY [DNOT_Fecha] DESC


Tercer paso: Creación de un ConnectionString en el web.config

En nuestro proyecto en ASP.NET depositamos la información de configuración de todos nuestros proyectos, incluidos los parámetros de conexión con nuestra base de datos, en una clase llamada Conexiones. Al guardar la información de la cadena de conexión, vamos a evitar tener que codificar en el archivo de código subyacente. Esto simplifica las cosas, si cambia la información de la cadena de conexión en el futuro. El método de esa clase que contiene la información es en concreto el siguiente (oculto id de usuario y contraseña por razones obvias):

public static System.Data.SqlClient.SqlConnection Conectar()
{
SqlConnection sqlConn = new SqlConnection();
sqlConn.ConnectionString = "Server=webnet;Database=WEB;" +
"User ID=******;Password=******;" +
"Trusted_Connection=False";
return sqlConn;
}

Cuarto paso: Creación de una página rss.aspx

 El siguiente paso es crear una página Web en ASP.NET (rss.aspx) que mostrará una lista de las noticias más recientes como un documento con formato correcto de RSS 2.0. En el Solution Explorer, hay que hacer clic en el nombre del proyecto y, a continuación, hacer clic en Add New Item. Posteriormente en el cuadro de diálogo templates, hay que hacer clic en Web Form.

En el cuadro Name , escribimos un nombre para la nueva página Web (rss.aspx) y, a continuación, hacmos clic en Add.

Lo primero que debemos hacer en la página es quitar todos los controles de marcado o web HTML  y, a continuación, establecer la propiedad ContentType de la directiva @pagetext/xml“.

Después de borrar todo el marcado HTML, agregamos el nombre del método que programaremos posteriormente en el fichero rss.aspx.cs que también se ha creado. Éste es es aspecto de la página rss.aspx , después de haber hecho algunos cambios:

<%@ Page Language="C#" ContentType="text/xml" AutoEventWireup="true" CodeBehind="rss.aspx.cs" Inherits="rss" %>
<% = obtenerNoticiaRSS() %>

En el fichero rss.aspx.cs implementamos en C# el método que hemos invocado en el formulario. En primer lugar debemos recuperar los datos de la base de datos, llamando al procedimiento almacenado que hemos creado anteriormente. Éste es el código que abre la conexión a la base de datos e introduce los datos en un contenedor de datos.
public static void obtenerNoticiaRSS()
{

Llamamos aquí al método Conectar de la clase Conexiones que hemos visto antes.

SqlConnection connWebceuWeb = Conexiones.Conectar();

El fichero se guardará en la carpeta RssDocu y en la subcarpeta de la fecha actual.

String fechaDir = DateTime.Now.Day.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Year.ToString();
String path = @"C:\temp\";
DirectoryInfo di = Directory.CreateDirectory(path + @"\RssDocu\" + fechaDir);
String ruta = path + @"\RssDocu\" + fechaDir;
FileInfo fichero = new FileInfo(ruta + @"\" + "RssDocu.xml");
StreamWriter sr = fichero.CreateText();
try
{
SqlCommand cmdObtenerNoticias = new SqlCommand();
cmdObtenerNoticias = new System.Data.SqlClient.SqlCommand();
cmdObtenerNoticias.CommandText = "dbo.[sp_obtener_DOCU_NOTICIA_todosRSS]";
cmdObtenerNoticias.CommandType = System.Data.CommandType.StoredProcedure;
cmdObtenerNoticias.Connection = connWebceuWeb;
SqlDataAdapter da = new SqlDataAdapter();
if (connWebceuWeb.State == ConnectionState.Closed) {
connWebceuWeb.Open();
}
da.SelectCommand = new SqlCommand();
da.SelectCommand = cmdObtenerNoticias;
DataSet ds = new DataSet();
da.Fill(ds);
DataView dv = ds.Tables[0].DefaultView;

A continuación hay que incluir el código que nos muestre el contenido de las etiquetas que forman la estructura xml del RSS. Además de mostrarlo en el formulario lo guardaremos en un fichero de texto, que será el que podremos importar posteriormente. Utilizaremos un objeto de C# StreamWriter, que hemos instanciado previamente llamándolo sr.
sr.Write("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
sr.Write("<rss version=\"2.0\" xmlns:blogChannel=\"http://www.uchceu.es\" ");

Añadimos todos los espacios de nombres que consideramos interesantes.
sr.Write("xmlns:content=\"http://purl.org/rss/1.0/modules/content/\"\n");
sr.Write("xmlns:wfw=\"http://wellformedweb.org/CommentAPI/\"\n");
sr.Write("xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n");
sr.Write("xmlns:atom=\"http://www.w3.org/2005/Atom\"\n");
sr.Write("xmlns:sy=\"http://purl.org/rss/1.0/modules/syndication/\"\n");
sr.Write("xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\">\n");
sr.Write("<channel>\n");
sr.Write("<title>Docu. La revista de la Universidad CEU Cardenal Herrera.</title>\n");

El espacio de nombres atom:link incluye el link a la página del rss
sr.Write("<atom:link href=\"http://blog.uchceu.es/docu/rss.aspx\" rel=\"self\" type=\"application/rss+xml\" />\n");
sr.Write("<link>http://www.uch.ceu.es/principal/docu</link&gt;\n");
sr.Write("<description>");
sr.Write("Este RSS sirve para suscribirse a las noticias del DOCU de la Universidad CEU Cardenal Herrera.");
sr.Write("</description>\n");

La etiqueta LastBuildLate sirve para ver si se puede incluir dinámicamente, pero en este caso la hemos dejado vacía.
sr.Write("<lastBuildLate>");
sr.Write("");
sr.Write("</lastBuildLate>\n");

Indicamos lengua en que está escrita la información.
sr.Write("<language>");
sr.Write("es");
sr.Write("</language>\n");

Añadimos modulo “syndication”.
sr.Write("<sy:updatePeriod>");
sr.Write("hourly");
sr.Write("</sy:updatePeriod>\n");
sr.Write("<sy:updateFrequency>");
sr.Write("1");
sr.Write("</sy:updateFrequency>\n");

También el módulo generador.
sr.Write("<generator>");
sr.Write("http://wordpress.org/?v=3.1");
sr.Write("</generator>\n");

Abrimos un bucle que recorre la tabla.
for (int i = 0; i < dv.Table.Rows.Count; i++)
{
sr.Write("<item>\n");
sr.Write("<title><![CDATA[ ");
string tituloNot = dv.Table.Rows[i]["title"].ToString();
tituloNot = tituloNot.Replace("<b>", "");
tituloNot = tituloNot.Replace("</b>", "");
sr.Write(tituloNot);
sr.Write("]]></title>\n");

A continuación escribimos la etiqueta <link> pero la dejamos vacía porque no podemos clasificar segun el id de las noticias, ya que las va a clasificar wordpress según sus algoritmos.
sr.Write("<link>");
sr.Write("</link>\n");

Añadimos la fecha de publicacion, la convertimos a string, y obtenemos subcadenas para obtener día, més y año. También podríamos haber recurrido a métodos del objeto string.
DateTime fecha = DateTime.Parse(dv.Table.Rows[i]["pubdate"].ToString()).
string strDia = fecha.Date.DayOfWeek.ToString();
strDia = strDia.Substring(0, 3);
string strMes = devolverMes(fecha.Month);
string strFecha = strDia + ", " + fecha.Date.Day.ToString() + " " + strMes + " " + fecha.Date.Year.ToString() + " " +   fecha.Date.TimeOfDay.ToString() + " GMT";
sr.Write("<pubDate>" + strFecha + "</pubDate>\n");

Añadimos el autor  mediante el espacio de nombres de Dublin Core.
sr.Write("<dc:creator><![CDATA[");
if (dv.Table.Rows[i]["author"].ToString() != "")
sr.Write(dv.Table.Rows[i]["author"].ToString());
else sr.Write("Administrador");
sr.Write("]]></dc:creator>\n");
sr.Write("<category>");
sr.Write(dv.Table.Rows[i]["category"].ToString());
sr.Write("</category>\n");

De nuevo, ponemos <guid> en blanco porque no podemos clasificar segun el id
sr.Write("<guid isPermaLink=\"false\">");
sr.Write("");
sr.Write("</guid>\n");

Añadimos el texto de las noticias.
sr.Write("<description>");
sr.Write(dv.Table.Rows[i]["header"].ToString() + "\n");
sr.Write("</description>\n");

Añadimos la etiqueta content:encoded,que incluye las imágenes y los vídeos. Es importante reemplazar algunos caracteres que influirán negativamente en la visión de la noticia importada.
string cabecera = dv.Table.Rows[i]["header"].ToString();
cabecera = cabecera.Replace("  ", "");
cabecera = cabecera.Replace("\n", "");
cabecera = cabecera.Replace("\r", "");
string descripcion = dv.Table.Rows[i]["description"].ToString();
descripcion = descripcion.Replace("\n", "");
descripcion = descripcion.Replace("\r", "");
sr.Write("<content:encoded>");
sr.Write("<![CDATA[");
if (dv.Table.Rows[i]["image"].ToString() != "")
{

En nuestra base de datos se han colado etiquetas innecesarias. por ejemplo la eqtiqueta <b> de los alt de las imagenes. Si os ocurre algo similar en vuestras bases de datos, tendréis que reemplazarlos como hacemos aquí.
string titulo = dv.Table.Rows[i]["imageTitle"].ToString();
titulo = titulo.Replace("<b>", "");
titulo = titulo.Replace("</b>", "");

Es muy importante cambiar las rutas de las imagenes si las vamos a subir al servidor de WordPress.
string urlImagen = dv.Table.Rows[i]["image"].ToString();
urlImagen = urlImagen.Replace("archivos_subidos/imagenes/", "/wp-content/uploads/docu/");
sr.Write(cabecera);
sr.Write("<p><img alt='" + titulo + "' src='" + urlImagen + "'/></p>");
sr.Write("<p>" + dv.Table.Rows[i]["imageDesc"].ToString()  + "</p>");
sr.Write(descripcion);
sr.Write("]]></content:encoded>\n");
}
else
{
sr.Write(cabecera);
sr.Write(descripcion);
sr.Write("]]></content:encoded>\n");  }
if (dv.Table.Rows[i]["file"].ToString() != "")
{
sr.Write("http://blog.uchceu.es/wp-content/uploads/docu/" + dv.Table.Rows[i]["file"].ToString();
}
sr.Write("</item>\n");
}
sr.Write("</channel>\n");
sr.Write("</rss>\n");
}
catch (Exception ex)
{
Utilidades.Utilidades.mandarMail("desarrolloweb@uch.ceu.es", "anonimo@uch.ceu.es", "No se puede escribir RSS : " + ruta, ex.Message);
}
finally
{
if (connWebceuWeb.State == ConnectionState.Open)
{
connWebceuWeb.Close();
}
if (sr != null)
{
sr.Close();
}
}
}

Resultados:

Este ejemplo pertenece al Docu de la Universidad Cardenal Herrera CEU. Tras aplicar el código para importar el RSS en la plataforma WordPress que creamos y diseñarlo a nuestro gusto se han obtenido los resultados que podéis ver en la Página del Docu.

También se ha aplicado el mismo método para importar el contenido de la página SalaPrensa, y próximamente se aplicará a todos los blogs antiguos de la Universidad Cardenal Herrera CEU.

Un saludo.

Analizadores de log. ¿Analog o Webalizer?

En esta entrada quiero compartir un pequeño análisis, en base a mi experiencia, sobre dos de los analizadores de logs más famosos utilizados para obtener las estadísticas de nuestro sitio web. Analog vs Webalizer.

1. Aspectos generales.

Tanto Analog como Webalizer son analizadores de logs simples pero bastante completos para realizar registros de accesos generados por servidores Apache e IIS. Ambos son completamente gratuitos. Desde la web de Analog es posible obtener el código fuente, mientras que Webalizer está programado en C, teniendo el usuario acceso a los ficheros .c y .h en el directorio en el que ha sido descargado.

Una de las características principales de ambos es que funcionan en cualquier plataforma o sistema operativo, son escalables y altamente configurables, pudiendo realizar reportes con los datos en mas de 32 lenguajes incluido el Español, son rápidos y ofrecen estadísticas detalladas sobre el uso de su servidor web.
Entre los datos estadísticos ambos nos permiten obtener : Cantidad de páginas vistas, indicando las más populares, la procedencia de cada visita (páginas de donde llegan los visitantes), códigos de respuesta de errores del servidor, información de archivos, actividad del sitio cada cierto tiempo, uso del tráfico…
Analog no contiene una interfaz gráfica o GUI como suele llamarse, si no que consta de un archivo ejecutable (analog.exe) , y este funciona desde la línea de comandos mediante el paso de parámetros para configurarlo y poder crear los reportes y listados con la información.
Además contiene una página html (anglform.html, ubicado tanto en la carpeta principal, aunque podemos encontrar en la carpeta Lang el mismo fichero en español, con nombre esform.html) que sirve como interfaz para realizar algunas configuraciones y ajustar algunas opciones, como por ejemplo: Indicar si el programa debe realizar un sumario general, un sumario de datos mensual, semanal…, así como otros detalles para los reportes. El hecho de incluir estas opciones fuera del fichero de configuración analog.conf (que se encarga de indicar el fichero html en el que se generará el reporte, el fichero de log a analizar, así como los tipos de páginas y de ficheros que se encuentran en el servidor), le otorga un carácter más amigable y más fácil de usar.
Webalizer consta de una serie de ficheros programados en c que deben ser compilados y ejecutados para funcionar, por tanto, según la plataforma en la que trabajemos se instalará de una forma u otra, pudiendo ser necesaria la instalación de librerías (como gdlib) u otros componentes. A favor, podemos encontrar en el fichero README una guía completísima para instalar y configurar el programa. Una vez instalado, enontramos en el directorio principal el fichero de configuración, webalizer.conf, que concentra todos los parámetros de configuración que podemos encontrar, como indicar el fichero de log, el directorio de salida en el que se mostrará el reporte, la dirección de la web y otros parámetros que identificaremos con más detalle a continuación.

2. Ficheros de configuración.

Como hemos comentado anteriormente, el fichero de configuración analog.conf contiene las etiquetas de configuración del programa Analog, aunque sólo las más básicas. Existe otro fichero de configuración más extenso en la carpeta examples, llamado big.conf, si se desea una configuración más específica, algo que, en principio, puede ser ventajoso para principiantes, aunque para configuraciones poco más complejas requiere una lectura detenida del fichero README.

A priori, con conocer unas pocas etiquetas podemos obtener un informe considerablemente completo. Con la etiqueta LOGFILE elegimos el fichero de log a analizar, su formato es reconocido automáticamente. Indicamos el nombre del fichero html de salida mediante la etiqueta OUTFILE. Por otra parte, con otras etiquetas la configuración por defecto suele ajustarse a las necesidades de los usuarios, por ejemplo en las siguientes. Indicamos que los reportes incluyan links en html mediante LINKINCLUDE. Con PAGEINCLUDE o PAGEEXCLUDE indicamos qué tipos cuentan como páginas (por defecto .html, .htm y directorios), con TYPEALIAS se reconocen los tipos de ficheros válidos, etc. Hay que tener cuidado con la etiqueta SEARCHENGINE, que nos indica los buscadores que tiene en cuenta leyendo las cadenas de los referentes, ya que, aunque parece haberse actualizado desde 2005, puede precisar de nuevas actualizaciones con el paso del tiempo.

Sin embargo, para indicar otras configuraciones básicas, como el lenguaje de la salida mediante LANGUAGE, la resolución de las ip’s a dominios con DNS WRITE o la generación del reporte con los requisitos fallidos mediante FAILURE ON, tenemos que acudir al fichero big.conf, por lo que podemos concluir que, en cuanto nos hagamos un poco con la herramienta, debemos acudir directamente a este fichero de configuración.

Debo romper una lanza en favor de la Interfaz de Formularios de Analog, en todos los idiomas disponibles, que nos permite indicar de forma sencilla los informes que deseamos ver (general, mensual, semanal, diario o por horas, por dominios, organizaciones , directorios, navegadores o SO, por tamaño o tipo de archivo…). También podemos ordenar la búsqueda para cada informe,
según número de peticiones o según el tráfico y limitar el análisis por fechas o indicar de forma explícita los archivos a incluir. Por último, nos ofrece un par de opciones relacionadas con la presentación. Todo de forma clara, sencilla y bastante amigable.
En cuanto a Webalizer, como ya hemos dicho todos los aspectos relacionados con la configuración se controlan desde el fichero webalizer.conf, por lo que nos encontramos con un fichero mucho más extenso, que contiene algunas opciones por defecto poco eficientes.

Comenzamos hablando de los referrers, es decir, los enlaces a la web y desde donde se reciben las visitas. La etiqueta Hidereferrer oculta nuestros propios referrers y deja que se vean mejor los externos. Indicando un dominio se podrían ver con claridad las visitas externas.

Continuamos con el tiempo de visita. La etiqueta VisitTimeout indica el tiempo entre dos peticiones desde una IP, a partir del cual se considera que se trata de dos visitas distintas. El valor por defecto es media hora (1800 segundos). Este es un aspecto a tener en cuenta, ya que según el tiempo de visita indicado, los resultados de los análisis de los logs serán diferentes.

Y finalizamos con el problema de los informes incompletos. Las etiquetas AllReferrers o DumpReferrers (entre otras), disponibles en html y texto sin formato con separadores de campo proporcionan informes completos si están habilitadas, pero por defecto no lo están por lo que se puede perder bastante información. La razón por la que no se generan es la cantidad de espacio en el disco que pueden ocupar.

Aunque existen versiones actualizadas, conviene comprobar las cadenas de buscadores, igual que en Analog, por si acaso están obsoletas ante la aparición de nuevos buscadores. Otros parámetros a tener en cuenta, en muchos casos con funcionalidades similares a las obtenidas con Analog mediante sus ficheros de configuración y sus formularios, son PageType, que indica los archivos que cuentan como páginas para las visitas (el formato .php suele estar comentado), los valores por defecto que muestra el informe de estadística (TopSites, TopURLs, TopAgents), IndexAlias, que permite comprobar si la página principal de la web y la dirección absoluta de la misma tienen diferentes nombres (está deshabilitado por defecto), o las etiquetas Ignore para no mostrar determinadas páginas.

En definitiva, ambos poseen muchas opciones de configuración que hay que conocer y tener en cuenta para realizar las modificaciones necesarias. Webalizer las engloba en un sólo fichero, lo que simplifica el trabajo a alguien que sabe manejarse a través del fichero. Analog lo divide en varios ficheros, e incluye el famoso formulario, algo que puede resultar más engorroso para
alguien experto, pero que puede ayudar a usuarios menos familiarizados con la herramienta o que requieran configuraciones más sencillas.

3. Estadísticas.

Analog ofrece sus estadísticas en un fichero html con el nombre que le hemos indicado en el fichero de log. Si seleccionamos en el formulario la realización de un informe completo, podemos ver algo así.
Al principio vemos un resumen general, que contiene estadísticas globales, como el número de peticiones exitosas o fallidas o los datos transferidos. A continuación vemos un informe mensual mostrado con un sencillísimo gráfico de barras cuyas alturas representan las peticiones por página. Lo mismo ocurre con el posterior resumen diario, que lista la actividad total por cada día de la semana, sumados por todas las semanas en el informe, y en el resumen horario, que muestra la actividad total por cada hora del día.

Los posteriores informes se representan mediante un, también muy sencillo, gráfico circular. En el informe de dominio vemos el porcentaje de tráfico proveniente de los países de los hosts que pidieron ficheros, mientras que en el informe de la Organización podemos listar las organizaciones de los hosts que pidieron ficheros, ordenadas por número de solicitudes y su porcentaje. Podemos encontrar un informe de búsqueda por palabras utilizadas en motores de búsqueda, ordenados por el número de solicitudes, un informe sobre el sistema operativo utilizado por los visitantes, ordenado por el número de peticiones de páginas, un informe que enlista los códigos de estado HTTP de todas las solicitudes, por orden numérico, un informe que enlista los tamaños de los ficheros en grupos de tamaños definidos, un informe que agrupe las peticiones según las extensiones de los ficheros con un mínimo de, por ejemplo, un 0,1% del tráfico, ordenados por la cantidad de tráfico, un informe que muestre los directorios desde los cuáles fueron pedidos los ficheros (siempre que ocupen, por ejemplo, un 0,01% del tráfico), ordenados por la cantidad de tráfico o un informe que proporcione un listado de los archivos con, por ejemplo, al menos 20 peticiones, ordenados por el número de peticiones.

Es en el apartado de resultados donde Webalizer demuestra ser un analizador más sofisticado o
al menos, pensado para análisis más complejos y completos.
Webalizer muestra al principio dos páginas de información, con un gráfico y una tabla resumen
de los últimos 12 meses (mostrando los totales mensuales y la media diaria). Agrupa los
resultados según:

  • Accesos: Número de veces que se hace un acceso al servidor por cada elemento de las páginas. Cada vez que un navegador solicita una página web, o ejecuta un programa, hace una búsqueda en una base de datos, accede a una imagen u otro tipo de archivo.
  • Archivos: Número de veces que el servidor envía un archivo al usuario/cliente. Por ejemplo: si un usuario entra en una página html, el servidor le enviará a parte del fichero html, los gráficos y otros elementos de la página.
  • Páginas: Número de archivos que se consideran páginas web. Por ejemplo: htm, html, asp, php…Este dato es importante para conocer el número de páginas visitadas.
  • Visitas: Una visita es una petición al servidor Web para consultar una página. Si se realizan varias peticiones desde una misma IP es un corto espacio de tiempo solo se contabiliza una visita.
  • Kbytes: Cantidad de datos medidos en KBytes que el servidor envía a los usuarios de la web y
  • Clientes: Los clientes son las diferentes direcciones IP desde las cuales se accede al dominio.

A continuación se muestra el resumen de las estadísticas del mes analizado, incluyendo la media y el valor máximo del mes, así como los Accesos por código de respuesta del servidor. Por supuesto, tenemos también las estadísticas diarias, detalladas por cada día del mes de la misma forma que los anteriores.

Así pues, posteriormente podemos ver un análisis de los accesos realizados a la web por horas. Se pueden ver gráficos que contienen las horas en las cuales los usuarios visitan el sitio web. Esto puede ser útil en muchos casos, por ejemplo para elegir el momento del día para hacer alguna modificación importante en la web.

Por otra parte, Webalizer informa de las páginas más consultadas por los usuarios, lo que puede servirnos para ver qué páginas son las que necesitamos favorecer para que sean más visitadas (facilitando su acceso) y qué productos/servicios necesitamos promocionar.

Vemos también completas estadísticas por páginas de entrada y salida, indicando su URL, estadísticas por clientes, indicando el nombre de la máquina, estadísticas por enlaces desde los cuales se ha accedido a nuestra web, estadísticas por cadena de búsqueda que nos informa de las palabras introducidas en los buscadores desde donde los usuarios han accedido a la página web, tablas con los primeros navegadores utilizados y/o gráficos circulares con estadísticas por países (similar al de Analog en este caso).

4. Conclusión.

Tengo la sensación de que Analog es un programa más sencillo de utilizar, tanto a nivel de instalación y puesta en marcha, como a nivel de configuración de los parámetros de entrada para la realización de los informes. En consecuencia, los resultados obtenidos son más simples e incompletos que los que ofrece Webalizer, y también es cierto que el fichero de salida de Analog es menos atractivo que el de Webalizer.

De todas formas, mi conclusión es que Analog es el mejor programa para realizar informes sencillos, interesante para principiantes, mientras que Webalizer es más adecuado para consultas más complejas y usuarios más expertos.

Control editor de texto open-source: TinyMCE + NetImageBrowser

En ocasiones un cliente puede desear encargarse él mismo del mantenimiento de la página web que se le ha diseñado sin tener que retocar directamente el código fuente.

Para ello se suelen programar aplicaciones web desde las cuales se puede actualizar una página web,  utilizando un recurso bastante común, el uso de controles llamados WYSIWYG (What You See Is What You Get).

Un control WYSIWYG es un editor de texto que permite modificar el contenido de una página web asociada, colocando los elementos tal y como queremos que se visualicen (como si escribiéramos un documento de MSWord).

Existen varios controles editores de texto conocidos, algunos de ellos gratuitos, los cuales dejan bastante que desear en algunos aspectos. Es el caso del control FreeTextBox para ASP.NET, que entre otros problemas, escribía gran cantidad de código basura cuando se hacía copy/paste desde un documento de Word, ya que, al hacer la conversión interna de los estilos de Word a HTML en el editor, incluía muchas etiquetas innecesarias. Esto puede parecer una tontería, que se solucionaría convirtiendo el contenido a texto plano e introduciendo nuestros propios estilos manualmente, pero implica una pérdida de tiempo que el cliente prefiere no asumir.

Estuve buscando otros editores gratuitos que solucionaran este problema y que añadieran otras funcionalidades, pero ninguno satisfacía por sí solo todas las necesidades. El que más me convenció fue TinyMCE, un control basado en html y javascript, lo que permite su integración de forma muy sencilla en cualquier plataforma, incluido ASP.NET.

Podemos probar cómo funciona desde la página oficial. Aquí.

Como he dicho antes, la integración es muy sencilla. Vamos a ver cómo.

–          En primer lugar abrimos nuestro Visual Studio (en este ejemplo uso 2008), hacemos clic en File>Website y elegimos ASP.NET Website si queremos empezar un nuevo sitio web.

–          Nos descargamos la última versión disponible del tinyMCE desde aquí.

–          Descomprimimos el fichero y copiamos la carpeta TinyMCE en nuestra solución de Visual Studio, como se muestra abajo.

–          Ahora arrastramos un control de cuadro de texto ASP.Net en nuestra página aspx y establecemos la propiedad TextMode a Multiline.

–          Para utilizar las características de TinyMCE con el cuadro de texto Multiline, necesitamos incluir el fichero Tiny_MCE.js, que se encuentra en la carpeta tinymce/jscripts/tiny_mce/ del paquete, en nuestra página web.

<script type="text/javascript"
src="tinymce/jscripts/tiny_mce/tiny_mce.js"></script>

–          A continuación tenemos que llamar al API javascript de tinyMCE para convertir el cuadro de texto Multiline a una instancia del editor, tal y como se muestra abajo.

<head runat="server">
<script type="text/javascript"
src="tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" language="javascript">
   tinyMCE.init({
       mode: "textareas"
   });
</script>
  <title></title>
</head>

–          ¡Y ya está! Ejecutamos la página y podemos ver nuestro control. Por defecto, el editor TinyMCE incluirá una barra de herramientas de configuración simple con algunas herramientas básicas. Así:

–          El código final nos quedaría así:

<head runat="server">
<script type="text/javascript"
src="tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" language="javascript">
    tinyMCE.init({
        mode: "textareas"
    });
</script>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:TextBox ID="TextBox1" TextMode="MultiLine"
runat="server"></asp:TextBox>   
    </div>
    </form>
</body>
</html>

Dentro del código javascript podemos incluir todas las herramientas que incluye la versión gratuita, en la columna que deseamos que se sitúe. Sustituyamos en el código anterior, la parte comprendida entre las líneas <script type=”text/javascript” src=”tinymce/jscripts/tiny_mce/tiny_mce.js”></script>  y </script> (ambas incluidas) por el siguiente código:

<script type="text/javascript"
src="tinymce/jscripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" language="javascript">
    tinyMCE.init({
        // General options
        mode: "textareas",
        theme: "advanced",
        plugins: "safari,pagebreak,style,layer,table,save,advhr,
advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,
preview,media,searchreplace,print,contextmenu,
 paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,
 xhtmlxtras,template,wordcount",
        // Theme options
        theme_advanced_buttons1: "save,newdocument,|,bold,italic,
underline,strikethrough,|,justifyleft,justifycenter,justifyright,
justifyfull,styleselect,formatselect,fontselect,fontsizeselect",
        theme_advanced_buttons2: "cut,copy,paste,pastetext,pasteword,
|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,
undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,
inserttime,preview,|,forecolor,backcolor",
        theme_advanced_buttons3:  "tablecontrols,|,hr,removeformat,
visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,
|,ltr,rtl,|,fullscreen",
        theme_advanced_buttons4: "insertlayer,moveforward,movebackward,
absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,
nonbreaking,template,pagebreak",
        theme_advanced_toolbar_location: "top",
        theme_advanced_toolbar_align: "left",
        theme_advanced_statusbar_location: "bottom",
        theme_advanced_resizing: true,
        // Drop lists for link/image/media/template dialogs
        template_external_list_url : "lists/template_list.js",
        external_link_list_url : "lists/link_list.js",
        external_image_list_url : "lists/image_list.js",
        media_external_list_url : "lists/media_list.js"
        }
    });
</script>

Al ejecutar de nuevo la página podemos ver el resultado:

Sin embargo, esta versión tiene un importante déficit respecto de la que hemos visto en el ejemplo de la página oficial, y es que no permite incluir imágenes descargadas desde el propio pc o servidor. Para eso hay que pagar.

Aunque también podemos programar nosotros mismos el plugin…o buscar en internet por si alguien ya lo ha hecho, como es el caso :D.

El plugin que encontré, en concreto, se llama netImageBrowser y podemos descargarlo desde aquí. El autor tiene como nombre de usuario, Ilyax.

Incluir este plugin en nuestro proyecto es tan sencillo como copiar la carpeta netImageBrowser que hemos descargado en el directorio tinyMCE/plugins/, y añadir la nueva herramienta en el código javascript. Por ejemplo en la tercera columna, quedando así:

        theme_advanced_buttons3: "tablecontrols,|,hr,removeformat,
visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,
|,ltr,rtl,|,fullscreen",
        theme_advanced_buttons4: "insertlayer,moveforward,
movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,
ins,attribs,|,visualchars,nonbreaking,template,pagebreak
,netImageBrowser",

Con este nuevo control podemos subir imágenes desde nuestro pc a nuestro servidor, cuya dirección debemos especificar en el fichero up.aspx, modificando en las siguientes líneas:

private string path =
        HttpContext.Current.Server.MapPath("../../../images");
private string imgPath = "../../../images";

los paths en negrita por los paths de nuestro servidor. Una vez hemos subido los ficheros ya pueden ser incluidos en nuestro editor de texto. En este enlace podemos ver un ejemplo de cómo funciona este control. Es el icono con forma de carpeta que aparece en la primera columna del editor.

Ya he incluido este control en alguna aplicación, en concreto la de la página del Observatorio de la Universidad Cardenal Herrera – CEU, cuya página principal (y casi todas las demás también) pueden ser modificadas por el usuario a través del control situado en la aplicación.

A continuación vemos una captura de pantalla del editor utilizado en la aplicación para actualizar la página principal:

Y el resultado final se ve enlazando con la página web. (El contenido puede ser distinto del de la foto de arriba si el usuario ha decidido modificarlo desde el editor para actualizar su web…¡Ese es el objetivo! ).

Eso es todo. Un saludo.

A %d blogueros les gusta esto: