Leccion 8: Conexión y Descarga HTTP/*
+--------------------------------------------------------------------------
| La Biblia Enigma1 Tutorial
| ========================================
| Por: Bacicciosat aka Meo aka Luponero
| Traduccion: Nesi_tor
|
| Tutorial de entorno de la APIS de Enigma1 con codigo fuentes y comentarios
| (c) august 2006 by Meo
|
+---------------------------------------------------------------------------
*/
Leccion 8: Conexión y Descarga HTTP
Ok esta el la lección FINAL.
Vamos a crear una pequeña aplicación.
Este plugin conectara a la web de Wikipedia y descalrgara la pagina sobre el MKportal.
Si has seguido este tutorial eres capaz de entender el codigo y la API Enigma.
No lo explicare de nuevo.
Solo posteare aqui el codigo fuente comentado y completado.
Código:
--------------------------------------------------------------------------------
/*
+--------------------------------------------------------------------------
| La Biblia Enigma1 Tutorial
| ========================================
| Por: Bacicciosat aka Meo aka Luponero
| Traduccion: Nesi_tor
|
| Leccion 8: Conexión y Descarga HTTP
| (c) august 2006 by Meo
|
+---------------------------------------------------------------------------
*/
// incluimos los archivos que necesitaremos para nuestro codigo.
#include <stdio.h>
#include <stdlib.h>
#include <plugin.h>
#include <math.h>
#include <dirent.h>
#include <string.h>
#include <lib/gui/ewindow.h>
#include <lib/gui/ebutton.h>
#include <lib/gui/emessage.h>
#include <lib/gui/textinput.h>
#include <lib/gui/combobox.h>
#include <lib/gui/statusbar.h>
#include <lib/gui/eskin.h>
#include <lib/gdi/font.h>
#include <lib/gdi/epng.h>
#include <lib/gdi/gfbdc.h>
#include <lib/system/httpd.h>
#include <lib/gui/eprogress.h>
#include <upgrade.h>
#include <iostream>
#include <fstream>
#include <cstdio>
#include <lib/base/thread.h>
#include <lib/base/estring.h>
// La declaracion de la clase de nuestro sistema de conexión HTTP
class Fetcher : public Object
{
// El archivo temporal en el que guardaremos los datos descargados
eString tempPath;
// punteros y funciones internas de la conexion de descarga
eHTTPConnection * connectionP;
eHTTPDataSource * dataSinkP;
void transferDone(int err);
eHTTPDataSource * createDownloadSink(eHTTPConnection *conn);
public:
Signal1<void,int> downloadDone;
void fetch();
};
// La declaracion de clases de nuestra ventana principal
class eBibleMainWindow: public eWindow
{
// la etiqueta para mostrar el texto a mostrar
eLabel *label;
// el boton para iniciar la conexión
eButton *ok;
// el objeto de conexion
Fetcher theFetcher;
// un flag para indicar el estado de la descarga
int downloadDoneFlag;
int inDownloadFlag;
public:
// el constructor.
eBibleMainWindow();
// funcion a llamar cuando se pulse el boton
void Wconnect();
// funcion a llamar cuando la descarga se complete.
void downloadDone(int err);
// el destructor.
~eBibleMainWindow();
};
// La definición de la funcion C que usaremos para borrar las etiquetas HTML del texto descargado
eString removeTags(eString in);
// El punto de entrada del plugin, Aqui empezara la ejecución del codigo
extern "C" int plugin_exec( PluginParam *par )
{
// nuestra instancia del dialogo de demostracion.
eBibleMainWindow dlg;
// mostrar el dialogo...
dlg.show();
// dar el control al dialogo.. (el dialogo es modal!)
int result=dlg.exec();
// y despues de eso, esconderlo de nuevo.
dlg.hide();
return result;
}
eBibleMainWindow::eBibleMainWindow(): eWindow(1)
{
inDownloadFlag = 0;
// mover nuestro dialogo a 100.100...
cmove(ePoint(100, 70));
// ...darle dimensiones X e Y.
cresize(eSize(520, 436));
// fijar el titulo.
setText("Biblia Enigma Leccion 8: Conexión HTTP");
// crear una etiqueta para mostrar el texto.
label=new eLabel(this);
// darle una posición
label->move(ePoint(10, 0));
// fijar las dimensiones de la etiqueta
label->resize(eSize(490, 380));
// fijar el texto de la etiqueta
label->setText("Esta es una conexion HTTP de demostacion. Conectaremos con la Web de Wikipedia y descargaremos la pagina sobre Mkportal que es un escrito de CMS y distribuido por Meo aka Bacicciosat. Parsearemos la web de Wikipedia y mostraremos en esta ventana la definicion de MKPortal de la Wikipedia.");
// fijar el flag de estado a la etiqueta
label->setFlags(RS_WRAP);
// crear un boton y fijar las propiedades
ok = new eButton(this);
ok->setText("Conectar");
ok->move(ePoint((clientrect.width() - 150)/2, clientrect.height() - 60));
ok->resize(eSize(150, 40));
ok->setShortcut("green");
ok->setShortcutPixmap("green");
ok->loadDeco();
// funcion a llamar cuando se pulse el boton
CONNECT(ok->selected, eBibleMainWindow::Wconnect);
}
void eBibleMainWindow::Wconnect()
{
// Fijar el flag que indicara el estado de la descarga
if(!inDownloadFlag) {
inDownloadFlag = 1;
// Etiqueta oculta para cambiar el texto
label->hide();
// fijar nuevo texto para la etiqueta
label->setText("Espera por favor, conexión a la web de Wikipedia en progreso...");
// mostrar la etiqueta con el texto nuevo
label->show();
// Funcion a llamar cuando se complete la descarga
CONNECT(theFetcher.downloadDone, eBibleMainWindow::downloadDone);
// Fijar el flag que indicara que hay conexiones iniciadas
downloadDoneFlag = 0;
// Lamar a la funcion que iniciara la conexión HTTP
theFetcher.fetch();
}
}
void Fetcher::fetch()
{
// declarar una variable
eString url;
// asignar al la variable la URL a la que se quiere conectar
url = "
http://en.wikipedia.org/wiki/Mkportal";
// asignar a la clase variable el archivo temporal que se usara para guardar los datos descargados
tempPath = "/var/tmp/bdemo.tmp";
// inicializar el control del flag de error
int error = 0;
// iniciar conexion
connectionP = eHTTPConnection::doRequest(url.c_str(), eApp, &error);
// Mostrar un Messagebox en caso ce error de conexion
if(!connectionP || error)
{ eMessageBox msg("Error descargando " + url + "(" + eString().sprintf("%d", error) + ")", _("Detalles"), eMessageBox::btOK);
msg.show(); msg.exec(); msg.hide();
}
else
{
//si la conexion se ha establecido iniciar las funciones de descarga
CONNECT(connectionP->transferDone, Fetcher::transferDone);
CONNECT(connectionP->createDataSource, Fetcher::createDownloadSink);
// fijar el nombre de user-agent
connectionP->local_header["User-Agent"] = "PLBOT";
connectionP->start();
}
}
void Fetcher::transferDone(int err)
{
// Si no hay ningun error podemos llamar a la funcion de descarga completa
if(!err)
{ connectionP = NULL;
// Decir que la descarga esta preparada
/*emit*/ downloadDone(err);
}
else
{
//sino mostrar un Messagebox con la descripcion del error.
eString sMsg = "Error " + eString().sprintf("%d", err);
eMessageBox msg(sMsg, _("User Abort"), eMessageBox::iconWarning|eMessageBox::btOK);
msg.show(); msg.exec(); msg.hide();
}
}
// procedimiento de descarga interna (estandar)
eHTTPDataSource * Fetcher::createDownloadSink(eHTTPConnection *conn)
{ dataSinkP = new eHTTPDownload(connectionP, (char *)tempPath.c_str());
return(dataSinkP);
}
void eBibleMainWindow::downloadDone(int err)
{
// fijar el flag que indicara que la descarga se ha completado
if(!downloadDoneFlag)
{ downloadDoneFlag = 1;
// crear un buffer para leer el archivo temporal con los datos descargados.
char buf[512];
// declarar las variables que se usaran en esta funcion
eString strview, strview1;
// abrir el archivo temporal que contiene los datos descargados
FILE *f = fopen("/var/tmp/bdemo.tmp", "rt");
if (f)
{
//Añadir una introduccion de texto
strview = "Mkportal CMS. Autor Meo aka Bacicciosat aka Luponero.
www.mkportal.it\n\nWikipedia:\n";
// buscar la linea que se quiere (La definicion de Mkportal que hemos descargado de la web Wikipedia)
while (fgets(buf, 512, f))
{
if (strstr(buf, "is a free Portal"))
break;
}
// guardar esta linea en la variable
strview1 = eString(buf);
// borrar las etiquetas HTML
strview1 = removeTags(strview1);
// encadenar strings para componer nuestro texto de salida
strview += strview1;
// leer las siguientes lineas .....
while (fgets(buf, 512, f))
{
// si hemos encontrado las strings con el final de la definicion ya podemos leer el archivo
if (strstr(buf, "See also"))
break;
// sino guardar la linea en la variable
strview1 = eString(buf);
// borrar las etiquetas HTML
strview1 = removeTags(strview1);
// encadenar strings para componer nuestro texto de salida
strview += strview1;
}
// cerrar archivo
fclose(f);
}
//Borrar el archivo temporal que hemos usado para guardar los datos descargados
::unlink("/var/tmp/bdemo.tmp");
// Ocultar la etiqueta que cambia el texto
label->hide();
// Insertar en la etiqueta la salida que hemos guardad en la variable strview
label->setText(strview);
// Mostrar la etiqueta con el texto nuevo
label->show();
// ocultar el boton de conexion
ok->hide();
// fijar el flag que indica que no hay nada en el estado de descarga
inDownloadFlag = 0;
}
}
// Esta es una funcion normal en C++ para borrar las etiquetas HTML del strng.
// No comentare esto. Esto no es Enigma. Esto es programacion normal en C++.
eString removeTags(eString in)
{ eString out;
int startpos = 0; int length = 0;
for(unsigned int i = 0; i < in.length(); i++)
{ length++;
if(in.mid(i, 1) == "<")
{ out = out + in.mid(startpos, length - 1);
for(unsigned int j = i; j < in.length(); j++)
{ if(in.mid(j, 1) == ">")
{ i = j;
startpos = i + 1;
length = 0;
break;
}
}
}
}
if(out == "")
{ out = in;
}
return out;
}
eBibleMainWindow::~eBibleMainWindow()
{
// No tenemos que hacer nada mas aqui. todos los objetos seran borrados automaticamente
// Hasta un niño lo podria hacer. El eWidget-destructor lo hara por nosotros.
}
--------------------------------------------------------------------------------
Ya puedes practicar la compilacion de codigo fuente que podras encontrar en el paquete adjunto y modificarlo.
Ejercicios:
- Cambiar el codigo para que funcione con otra web.
Esto es todo, y esta es la captura de la aplicacion y el paquete completo.
Este tutorial acaba aquí.
Espero haberte ayudado.
Pasadlo bien.
Recuerdo de Meo aka bacicciosat.
Muchas Gracias Nesi-tor[archivo adjunto borrado por el administrador]