Sei sulla pagina 1di 160

Desarrollo de un Widget de Yahoo!

para TV para la solicitud de Cita Mdica


Proyecto Fin de Carrera Mara Len Bujes
Proyecto dirigido por Dr. Jos Ramn Cerquides Bueno

Departamento de Teora de la Seal y Comunicaciones Escuela Superior de Ingenieros de Sevilla Universidad de Sevilla Mayo 2012

A mis padres, Juan Antonio y Paqui.

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

ndice
1. 2. Objetivo del proyecto ......................................................................................................... 5 Connected TV: Concepto y plataformas ............................................................................. 6 2.1 2.2 2.3 3. Definicin de Connected TV ...................................................................................... 6 Principales plataformas de Connected TV ................................................................ 7 Las compaas de Internet a la conquista de la televisin ........................................ 8

Yahoo! Connected TV: descripcin de la plataforma ......................................................... 9 3.1 3.2 3.3 3.4 Interfaz de usuario .................................................................................................. 10 El mando a distancia como dispositivo de entrada ................................................. 12 Funcionamiento de la plataforma ........................................................................... 14 Perfiles de dispositivo.............................................................................................. 15

4.

Desarrollo de widgets de Yahoo! para TV ........................................................................ 16 4.1 Metodologa de desarrollo basada en Framework ................................................. 16 4.1.1 Introduccin al KONtx Framework .............................................................. 16 4.1.2 Vistas y clases de vista ................................................................................. 18 4.1.3 Gestin de eventos ...................................................................................... 20 4.2 Archivos de un widget ............................................................................................. 23 4.2.1 Estructura de carpetas................................................................................. 23 4.2.2 Archivo main.TV........................................................................................... 25 4.2.3 Archivo widget.xml ...................................................................................... 25 4.2.4 El archivo init.js ............................................................................................ 27 4.3 Widget Development Kit ......................................................................................... 29 4.3.1 Descarga e instalacin ................................................................................. 29 4.3.2 Primeros pasos con el simulador ................................................................. 30 4.3.3 Depuracin de cdigo con la consola del simulador ................................... 31 3

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

4.4 4.5 5.

Testeo de widgets en un televisor .......................................................................... 31 Publicacin en la Galera de TV Widgets de Yahoo! ............................................... 35

Tecnologas utilizadas en el desarrollo del Widget de Cita Mdica ................................. 36 5.1 5.2 5.3 Javascript ................................................................................................................. 36 PHP .......................................................................................................................... 37 XML y JSON .............................................................................................................. 38

6.

Desarrollo del Widget de Cita Mdica .............................................................................. 40 6.1 6.2 Esquema de funcionamiento de la aplicacin......................................................... 40 Cdigo del Widget de Cita Mdica (JavaScript) ...................................................... 40 6.2.1 Implementacin de las vistas ...................................................................... 40 6.2.2 Implementacin de dilogos ....................................................................... 45 6.2.3 Uso del objeto XMLHttpRequest de JavaScript ........................................... 48 6.2.4 Comprobacin del estado de la red antes de las peticiones XHR ............... 51 6.2.5 JSON Parser.................................................................................................. 56 6.2.6 Gestin de usuarios guardados y almacenamiento persistente ................. 58 6.3 Web API en el servidor intermedio (PHP) ............................................................... 64 6.3.1 Peticiones al servidor de InterS@S con libcurl ............................................ 64 6.3.2 Mantenimiento de la sesin ........................................................................ 66 6.3.3 Parseando la respuesta: HTML DOM parser ............................................... 67 6.3.4 Produccin de una cadena JSON: json_enconde() ...................................... 69

7. 8. 9.

Seguridad de los datos en el Widget de Cita Mdica ....................................................... 70 Posibles ampliaciones y mejoras ...................................................................................... 72 Bibliografa ........................................................................................................................ 73

Anexo I ..................................................................................................................................... 74 Anexo II .................................................................................................................................. 136

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

1. Objetivo del proyecto


El objetivo del proyecto propuesto es el desarrollo de un widget para la plataforma Yahoo! Connected TV que permita a los usuarios solicitar, consultar y cancelar cita con su mdico (o con el pediatra, si se gestiona para un menor) a travs de su televisor, usando el mando a distancia como dispositivo de entrada. El SAS ya permite realizar estos y otros trmites a travs de Internet por medio de InterS@S, una oficina virtual que proporciona a los andaluces servicios de informacin personal y tramitacin on-line en su relacin con la asistencia sanitaria. La filosofa de funcionamiento del widget cuyo desarrollo aborda el presente proyecto consiste en realizar peticiones a un servidor intermedio que, a su vez, interactuar con el servidor de InterS@S. El servidor intermedio se encargar de ofrecer las respuestas del servidor de InterS@S en formato JSON, el formato de datos ms adecuado para ser consumido por nuestro widget, widget que ser el que finalmente muestre al usuario el estado de su solicitud de cita en la pantalla del televisor, todo ello mientras disfruta de su programa de televisin favorito. Por tanto, el widget de peticin de cita mdica, en adelante Widget de Cita Mdica, pone a disposicin del usuario el servicio de peticin de cita ofertado por InterS@S pero a travs del televisor, es decir, ofrece una nueva forma de acceso distinta de la interfaz web que lleva tiempo funcionando. Se acerca as dicho servicio a un cierto tipo de usuario que estara ms predispuesto a aprender nuevas funcionalidades de un electrodomstico con el que est familiarizado y que utiliza cada da, como es el televisor, que a iniciarse en el uso de algo menos cotidiano para l, como puede ser un ordenador o un navegador web. Se consigue as reducir la brecha digital y hacer partcipes de la Sociedad de la Informacin a un mayor nmero de ciudadanos. Con este objetivo siempre presente, durante el desarrollo del Widget de Cita Mdica se ha dado especial importancia a la sencillez y facilidad de uso y a la claridad a la hora de presentar la informacin, con idea de favorecer la utilizacin de la aplicacin por parte de cualquier tipo de usuario, independientemente de su edad o grado familiaridad con el manejo de las TIC.

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

2. Connected TV: concepto y plataformas


2.1 Definicin de Connected TV Connected TV, Hybrid TV o Smart TV son trminos que hacen referencia a la tendencia actual de integracin de caractersticas de Internet y la Web 2.0 en los modernos aparatos de televisin y set top boxes, as como a la convergencia tecnolgica entre computadoras y estos nuevos aparatos de televisin/set top boxes. En estos nuevos dispositivos suelen tener una gran importancia los contenidos interactivos online, la Web TV o el over-the-top content1 as como el vdeostreaming bajo demanda, frente a generaciones anteriores de aparatos de televisin o set top boxes en los que casi de forma exclusiva primaba la difusin tradicional de contenidos audiovisuales. Pero adems, los Connected TV tambin proporcionan a los consumidores acceso a contenido generado por el propio usuario (ya sea almacenado en un disco duro externo, en su pc, o en la nube) y a una enorme variedad de servicios interactivos y aplicaciones de Internet. Esta evolucin est teniendo lugar de forma anloga a cmo Internet, los web widgets y las aplicaciones software se integraron en los modernos smartphones. De hecho, el trmino Smart TV se establece por analoga con el trmino Smart Phone. Por tanto, un dispositivo Smart TV o Connected TV es un aparato de televisin o un set top box para televisin que ofrece una mayor capacidad computacional y conectividad que un aparato de televisin bsico. De hecho, un Connected TV incorpora un Sistema Operativo completo y proporciona usualmente una plataforma para los desarrolladores de aplicaciones. Hay una gran variedad de sistemas operativos mviles disponibles en la actualidad y, aunque la mayora estn dirigidos a smartphones o tablets, algunos de ellos tambin se instalan en dispositivos Connected TV o incluso han sido diseados de manera especfica para su uso en estos dispositivos. Es interesante sealar tambin que la mayor parte de los sistemas operativos de los Connected TV (o Smart TV) estn basados en Linux, Android, y otras plataformas de cdigo abierto.

En los mbitos de la difusin y la entrega de contenidos, over-the-top content (OTT) hace referencia a la entrega de video y audio sin la implicacin del proveedor de servicios de Internet en el control o distribucin de dicho contenido.

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

2.2 Principales plataformas de Connected TV A continuacin se citarn algunas plataformas de Connected TV importantes, que son usadas como framework2 y middleware3 por los distintos fabricantes: Plataformas especficas del vendedor: o o o o o o o LG NetCast de LG Electronics. Panasonic Viera Connect de Panasonic. Philips NetTV de Philips, basada en los estndares del Open IPTV Forum. Samsung Smart TV de Samsung. Sharp Aquos Net+ de Sharp. Toshiba Places de Toshiba. Roku de Roku.

Plataformas disponibles para mltiples fabricantes: Manejadas por organizaciones de estandarizacin: o Ginga (SBTVD Middleware). o HbbTV, del Consorcio HbbTV. o Tru2way de CableLabs. Manejadas por editores especficos: o o o o o o o o o Google TV (plataforma basada en Android) de Google, Intel, Sony y Logitech. Boxee (popular fork4 del XBMC media). EMAGINE (plataforma popular en la regin asitica del Pacfico) de Select-TV. Mediaroom de Microsoft. MeeGo for Smart TV de Linux Foundation, Intel y AMD. Est basada en un fork de XBMC media center software. TVBLOB (usado en Tiscali TvBox, TELE System Electronic's Free-To-Air DVB Receiver, y en el propio BLOBbox de TVBLOB Srl). Ubuntu TV, de Canonical, basado en la interfaz de usuario Unity y el Sistema Operativo Ubuntu. XBMC Media Center, de la XBMC Foundation y su comunidad de cdigo abierto. Yahoo! Connected TV (anteriormente Yahoo! GoTV) de Yahoo!.

2 Framework: coleccin de libreras software que proporcionan una determinada Interfaz de Programacin de Aplicaciones (API). 3 Middleware: software que asiste a una aplicacin para interactuar o comunicarse con otras aplicaciones, software, redes, hardware y/o sistemas operativos. 4 Fork: desarrollo software independiente basado en una copia legal del cdigo fuente de un paquete software, que culmina con la creacin de una pieza de software diferente.

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Uno de los puntos crticos en el desarrollo de una plataforma de Connected TV es el diseo de una interfaz adecuada, algo que supone un desafo complejo desde el punto de vista del software. En efecto, la experiencia de usuario debe ser optimizada para que todas las fuentes de contenido se integren de forma eficiente y sean fcilmente accesibles a travs un nico EPG5, algo que requiere una programacin muy avanzada. 2.3 Las compaas de Internet a la conquista de la televisin El potencial de los Connected TV o televisores web-enabled es muy alto. Segn un estudio de la consultora iSuppli actualmente hay alrededor de 90 modelos de televisores webenabled y en el ao 2013 habr alrededor de entre 88 y 90 millones en los hogares, lo que supone alrededor del 40% del mercado mundial. A la luz de estos datos resulta evidente por qu las compaas de Internet se interesan por conquistar la plataforma de la televisin. En estos momentos se libra una reida lucha en la carrera por encontrar la mejor forma de llevar contenidos y servicios de Internet a las pantallas de televisin, algo que determinar qu plataforma acaba convirtindose en la opcin mayoritaria del mercado. En esta batalla, Yahoo! y Google, con sus respectivas propuestas (Yahoo! Connected TV y Google TV), se presentan como dos rivales bien posicionados y con gran proyeccin de futuro.

Ilustracin 1: Yahoo! y Google tratan de hacerse un hueco en el campo de las Connected TV.

5 EPG: Electronic Programme Guide.

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

3. Yahoo! Connected TV: descripcin de la plataforma


En la dura batalla por conquistar la plataforma de la televisin, Yahoo!, con su Yahoo! Connected TV, apuesta por una plataforma de pequeas aplicaciones (widgets) que adaptan servicios y contenidos de la Red al medio televisivo y que, como novedad en su ltima versin, incluye interactividad broadcast (la capacidad de reconocer el programa que el usuario est viendo y ofrecerle informacin o servicios complementarios), lo cual, entre otras posibilidades, abre el camino a la presentacin de publicidad personalizada, algo sumamente atractivo para los anunciantes. Firmas como Samsung, LG Electronics, Sony y Vizio ya han producido televisores de alta definicin compatibles con la plataforma de Yahoo!, y D-Link ya ha anunciado la prxima salida al mercado del primer set top box que incorporar Yahoo! Connected TV. Al tratarse de una plataforma abierta, Yahoo! Connected TV permite que cualquier desarrollador cree sus propios Widgets de TV, contando para ello con herramientas suministradas por la propia Yahoo!. Estas aplicaciones son luego puestas a disposicin del usuario, quien selecciona sus favoritas, y puede configurar su propia experiencia en el uso de las mismas gracias a la existencia de perfiles de usuario. Desde mediados de 2011, Yahoo! proporciona adems la oportunidad de desarrollar widgets de pago para venderlos posteriormente en la Yahoo! Connected TV Store, una iniciativa que forma parte de su programa para desarrolladores.

Ilustracin 2: Yahoo! Connected TV en el CES 2011 en Las Vegas (Nevada).

En 2009, la propuesta de Yahoo! fue una de las novedades del International Consumer Electronics Show (CES) y volvi a ser objeto de inters en el CES 2011 gracias a las nuevas caractersticas incluidas en la ltima versin de la plataforma, entre las que destacan dos: la interactividad broadcast, ya mencionada, y el nuevo protocolo de comunicacin de dispositivos que da soporte al paso de mensajes en formato JSON entre el Connected TV y otros dispositivos con acceso a Internet de la red domstica (smartphones, tablets, etc.). 9

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

3.1 Interfaz de usuario Los widgets de Yahoo! Connected TV despliegan su men principal en un lateral de la pantalla. De esta forma, el usuario puede acceder en cualquier momento a actualizaciones de noticias, vdeos, pronstico del tiempo, imgenes fotogrficas o redes sociales, entre otros servicios, sin necesidad de recurrir al ordenador y sin dejar de ver la televisin. Los widgets de Yahoo! Connected TV presentan tres vistas bsicas: 1. Snippet: Es la primera vista de un widget, la que el usuario ve en su dock o barra de widgets personal. Esta barra ocupa la parte inferior de la pantalla del televisor, superponindose al contenido de televisin en vivo.

Ilustracin 3: Barra de snippets (dock) en la plataforma de Yahoo! Connected TV.

Los Snippets son los bloques que forman este dock y dan acceso cada uno de ellos a la que podemos considerar la vista de barra lateral principal del widget, pero tambin pueden mostrar contenido dinmico, actualizado en tiempo real, proveniente de un servicio web. 2. Sidebar: La segunda vista, la que ms se usar, es la vista de barra lateral (sidebar view). Esta vista se lanza cuando se activa el snippet en el dock y normalmente proporciona la funcionalidad completa del widget. En esta vista se puede integrar casi cualquier fuente web (feed), incluyendo fotos, datos y vdeos. Se lanza cuando se activa el snippet en el dock. Los componentes principales de la vista lateral o sidebar view son: o El logo del widget o botn de ttulo en la parte superior de la vista lateral, el cual devolver el widget al men HOME si no nos encontrsemos en l. 10

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

o Contenido de la vista. Si estamos en la vista de barra lateral que se muestra inmediatamente despus de activar el snippet aqu se mostrar la pgina inicial de navegacin o men HOME. El men sirve para implementar la navegacin a otras pginas/vistas del widget. o La barra de herramientas global en la parte inferior de la vista lateral, que proporciona funciones globales, idnticas para todos los widgets.

Ilustracin 4: Vista lateral de un widget en la plataforma de Yahoo! Connected TV.

Ilustracin 5: Vista lateral y vista de Snippet del Widget de Cita Mdica.

3. Full screen: La tercera vista es la de pantalla completa. La pantalla completa ofrece, a su vez, dos formas, una en la que la vista del widget oculta el contenido de la TV (como ocurrira con un juego o un contenido de vdeo) y otra en que se superpone (mostrando, por ejemplo, el marcador de los deportes en streaming en vivo). 11

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Como se ha comentado antes, el dock es el componente de la interfaz de usuario que contiene los distintos snippets instalados organizados en una lista horizontal que ocupa la parte inferior de la pantalla del televisor.

Ilustracin 6: Barra de Snippets (dock).

Al dock se accede apretando un botn del mando a distancia y sus principales funciones son: o Presentacin de los snippets. o Navegacin entre snippets. o Organizacin de los widgets disponibles para cada usuario. o Lanzamiento de widgets sin interrupir el visionado del vdeo o del programa de televisin por parte del usuario. 3.2 El mando a distancia como dispositivo de entrada La plataforma Yahoo! Connected TV puede usarse con muchos tipos de mando a distancia, desde los ms bsicos hasta los que incorporan componentes de aceleracin, como por ejemplo un jog-wheell.

Ilustracin 7: Mando a distancia en modo Widgets.

Los mandos a distancia son modales en el sentido de que muchas de sus teclas pueden tener distintas funciones en modos distintos (por ejemplo modo TV, modo DVD, etc.). Para dar soporte a los widgets se incluye un "modo widget" en el mando a distancia. Cuando se 12

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

muestran los widgets, el "modo widget" est activo y el motor de widgets de Yahoo!, en adelante Widget Engine, controla (salvo excepciones) todas las teclas del mando a distancia. Las principales teclas implicadas en el uso de los widgets de Yahoo! para TV se indicarn con maysculas y son las siguientes: WIDGETS para activar y desactivar la plataforma y su interfaz de usuario. EXIT para cerrar el sidebar, el dock, y la vista fullscreen. UP ARROW para mover el foco arriba. RIGHT ARROW para mover el foco a la derecha. OK para seleccionar el elemento sobre el que se encuentra el foco. LEFT ARROW para mover el foco a la izquierda. DOWN ARROW para mover el foco hacia abajo. BACK para abandonar un dilogo modal, volver desde una vista lateral, vdeo o slideshow a la vista lateral previa, hasta detenerse en el men principal. Esta tecla no tiene efecto si se aprieta mientras se est mostrando el dock.

El mando a distancia tambin proporciona acceso a las funciones de la barra de herramientas global: Viewport (tecla AZUL), Add Snippet (tecla AMARILLA), Settings (tecla VERDE), y Close (tecla ROJA). Cada una de estas teclas se corresponde con un botn que sigue el mismo cdigo de color en la interfaz de usuario de los widgets. Los fabricantes de dispositivos pueden configurar las rdenes de las teclas usando los servicios de Yahoo!. Las teclas de los mandos a distancia usadas por los widgets se clasifican en tres categoras distintas: 1. Teclas dedicadas: son aquellas que deben ser aadidas al mando a distancia y no pueden ser sobrecargadas con otra funcionalidad. Estas teclas dedicadas son usadas por los widgets en todos los modos del mando a distancia. Una de estas teclas dedicadas es la tecla WIDGETS que adems debe ser fcil de encontrar. 2. Teclas necesarias: son teclas que ya existen en la mayora de los mandos a distancia y pueden ser sobrecargadas con funcionalidad adicional. Estas teclas usualmente realizan otras funciones en modos diferentes al "modo widget". 3. Teclas opcionales: son teclas que pueden existir en algunos mandos a distancia, y pueden ser sobrecargadas con funcionalidad adicional. Las teclas opcionales pueden proporcionar un acceso ms conveniente a funciones de los widgets.

13

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

3.3 Funcionamiento de la plataforma Los widgets de Yahoo! Connected TV se implementan usando nicamente JavaScript y XML. El empleo de JavaScript para el desarrollo de aplicaciones destinadas a Smart TVs puede sorprender en un primer momento pero, si lo pensamos, hace tiempo que JavaScript dej de usarse nicamente en navegadores. Por el contrario, podemos encontrarlo ya en aplicaciones para dispositivos mviles (smartphones, tablets, etc.) e incluso en servidores (Node.JS) y, ahora, tambin en televisores conectados. En sntesis, los principales elementos que intervienen en el funcionamiento de la plataforma de Yahoo! Connected TV son los siguientes: Los widgets de Yahoo! para TV, escritos usando JavaScript y XML. En informtica, un widget es una pequea aplicacin o programa, usualmente presentado en archivos o ficheros pequeos que son ejecutados por un motor de widgets o Widget Engine. El Yahoo! Widget Engine Toolbox Framework (KONtx Framework) . El KONtx Framework es el framework JavaScript en el que se basa el desarrollo de widgets de Yahoo! para TV. Se caracteriza por su orientacin a objetos y por presentar un modelo de clases similar al de MooTools. El motor de JavaScript SpyderMonkey, usado internamente por la plataforma. SpyderMonkey es el motor de JavaScript de Mozilla, usndose en varios de sus productos, incluido Firefox. Escrito en C/C++, est disponible bajo licencia GPL. El Motor de Widgets de Yahoo! Este motor de widgets se basa en Konfabulator y combina un entorno de ejecucin JavaScript (SpyderMonkey) y un intrprete XML para ejecutar los widgets. Un Sistema Operativo Linux embebido6 sobre el que corre el motor de widgets. Como ya se ha mencionado, la mayor parte de los sistemas operativos de los Smart TVs estn basados en Linux, Android, y otras plataformas de cdigo abierto y la plataforma de Yahoo! no es una excepcin.

Un sistema embebido o empotrado es un sistema o mdulo electrnico alojado dentro de un sistema de mayor entidad (host o anfitrin) y diseado para realizar una o varias funciones concretas. Al contrario de lo que ocurre con los ordenadores de propsito general que estn diseados para cubrir un amplio rango de necesidades, los sistemas embebidos se disean para cubrir necesidades especficas y para ello emplean uno o varios procesadores (CPUs) ya sea en formato microprocesador, microcontrolador o DSP.

14

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

3.4 Perfiles de dispositivo La siguiente tabla muestra los perfiles hardware y software de un dispositivo conectado ejecutando el motor de widgets de la plataforma Yahoo! Connected TV.

Tipo Perfil Software RAM Resolucin Media Player

Plataforma de Widgets para TV Yahoo! Widget Engine 128 MB (el motor de widgets requiere 10 MB y se necesitan otros 50 MB para el dock) 960 x 540 pixels Proporcionado por el fabricante del dispositivo Contenedor: MP4, Codec: H.264, Audio: AAC.

Codecs de Audio y Vdeo Contenedor: WMV9, Codec: VC-1, Audio: WMA. Audio multicanal Formatos de imagen Proporcionado por el fabricante del dispositivo JPG, PNG Proporcionado por el fabricante del dispositivo. El Motor de Widgets soporta Widevine DRM para implementacin especfica del fabricante. Proporcionados por el fabricante del dispositivo KON, JS, XML Proporcionado por el fabricante del dispositivo Flash Memory

DRM

Formatos Contenedor Lenguajes Acceso a Contenido Propio Almacenamiento

15

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

4. Desarrollo de widgets de Yahoo! para TV


4.1 Metodologa de desarrollo basada en Framework 4.1.1 Introduccin al KONtx Framework En el contexto del presente proyecto, los widgets pueden considerarse como RIAs (aplicaciones de Internet enriquecidas) que corren en dispositivos electrnicos Connected TV y que hacen uso de servicios de Internet para entregar contenido dinmico a la audiencia mientras ve un vdeo o un programa de televisin. Como ya se ha mencionado, la plataforma Yahoo! Connected TV basada en el Yahoo! Widget Engine permite a los desarrolladores programar widgets usando nicamente JavaScript y XML. Para el diseo e implementacin de estos Widgets de TV se utiliza una metodologa de desarrollo basada en framework (concretamente en el KONtx Framework). El Yahoo! Widget Engine Toolbox Framework (KONtx Framework), el cual est definido en el archivo JavaScript Framework/kontx/version/src/all.js, proporciona mltiples controles estndar (botones, elementos de texto, imgenes...), que permiten al desarrollador crear vistas personalizadas muy rpidamente. Un par de lneas de cdigo son suficientes para aadir un elemento de texto, una imagen, un grid o un botn. Adems, como se coment anteriormente, el KONtx Framework sigue un modelo de herencia clsico, similar al usado por el MOOtools browser JS framework7. Esto permite extender fcilmente los controles bsicos proporcionando funcionalidad adicional. En efecto, cada control presenta una estructura de eventos bien definida y consistente, que permite al desarrollador aadir su propia lgica con el mnimo esfuerzo. El uso del Yahoo! Widget Toolbox, implementado por el KONtx Framework, ofrece las siguientes ventajas: Ayuda a racionalizar el proceso de desarrollo de widgets. Proporciona encapsulacin de objetos primitivos para proveer funcionalidad extendida. Proporciona una interfaz de programacin normalizada consistente.

Moo Tools es un framework JavaScript orientado a objetos compacto y modular, diseado para el desarrollador JavaScript con un nivel de intermedio a avanzado. Permite escribir un cdigo potente, flexible y cross-browser con su coherente y bien documentada API.

16

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Facilita y promueve la adopcin de lneas de diseo comunes por parte de todos los desarrolladores.

Los estndares soportados en el Yahoo! Widget Toolbox son: Estructura de nodos DOM 2. Modelo de eventos DOM 2. XPath8. CSS Limitado: o No se admiten selectores CSS, los estilos se especifican inline. o No hay posicionamiento relativo. o Modelo de cajas (box model) limitado. Pero el KONtx Framework, adems de proporcionar componentes de interfaz de usuario pre-empaquetados y "bloques de construccin" para el desarrollador de widgets, es el encargado de encapsular todas las comunicaciones con el Yahoo! Widget Engine. El KONtx Framework escucha los eventos procedentes del Yahoo! Widget Engine que son pasados al widget a travs del widget Container. El Container es el software de encapsulamiento que maneja la comunicacin y la presentacin de los widgets en el dispositivo y est a cargo de todos esos elementos que estn fuera del control de los widgets individuales (por ejemplo, dock, barra lateral, barra de herramientas global, activacin de snippets, aadir y borrar widgets, y otras). Resumiendo, un Widget de TV, escrito usando la notacin literal de Objetos de JavaScript, hace llamadas al KONtx Framework que se comunica con el motor de widgets a travs del widget Container y la API del Container. El widget Container maneja el dock y todos los widgets que se ejecutan simultneamente en un perfil de usuario. La figura 6 ilustra la pila de llamadas que tiene lugar durante la ejecucin de un widget. El KONtx Framework simplifica el trabajo de desarrollo de widgets al liberar al programador de un gran nmero de tareas. Tambin contribuye a mejorar el rendimiento de los widgets y en consecuencia la experiencia de usuario, al maximizar el uso de la cach del motor de widgets.

XPath (XML Path Language): lenguaje que permite construir expresiones que recorren y procesan un documento XML.

17

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Ilustracin 8: Pila de llamadas en el desarrollo con el KONtx Framework.

4.1.2 Vistas y clases de vista Gracias al KONtx Framework, el cdigo de los widgets se estructura en torno a vistas y a clases base de vistas. Cada una de las vistas inicializadas por el manejador de aplicacin extiende alguna de las clases de vista base del KONtx Framework. As, los distintos tipos de vista de cualquier widget (snippet, sidebar y fullscreen) estn representadas por las siguientes clases base: KONtx.system.SnippetView Esta vista es una clase base abstracta para snippets. Para crear snippets deben usarse AnchorSnippetView y ProfileSnippetView en su lugar. Si se usa KONtx.system.SnippetView la clase que la extiende tiene que implementar sus mtodos abstractos. KONtx.system.AnchorSnippetView Estamos ante la vista principal del snippet. Esta vista no se borra al cambiar de perfil si los dos perfiles tienen el widget instalado. KONtx.system.ProfileSnippetView Vista de snippet especfica para un perfil determinado. Esta vista se borra cuando cambiamos de perfil (ingresamos bajo un perfil distinto). 18

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

KONtx.system.SidebarView Vista lateral.

KONtx.system.FullscreenView Vista a pantalla completa.

Para crear una vista de un widget basta extender la clase de vista base correspondiente, sobrescribiendo dos mtodos especficos de la misma: createView() y updateView(). Estos mtodos responden a los dos conceptos fundamentales en los cuales se basa la implementacin de las vistas: la creacin de componentes de interfaz de usuario y la actualizacin de contenido. El mtodo createView() es el encargado de crear los componentes bsicos de interfaz de usuario de la vista. El mtodo createView() se llama una nica vez y en el momento de hacerlo el contenido an no se ha incluido. Por su parte, el mtodo updateView() es el que se encarga de dotar de contenido a la vista. A diferencia del mtodo createView() el mtodo updateView() se llama cada vez que el usuario accede a la vista, o cuando los datos en la vista han sido actualizados. Los componentes de interfaz de usuario de la vista no necesitan ser renderizados de nuevo para actualizar los datos de la vista. El uso de los mtodos createView() y updateView() permiten al motor de widgets optimizar su renderizado de vistas. Una vez que createView() es llamado, el motor de widgets no necesita crear los elementos XML en la pantalla de nuevo. Llamar al mtodo updateView() es rpido porque en l se sustituye el contenido dentro de la vista sin tener que volver a generar el XML con la estructura de la misma. Cada widget tiene un ciclo de vida durante el cual va haciendo visibles las distintas vistas de su interfaz de usuario. Un ejemplo de ciclo de vida en un widget puede ser: activacin, ejecucin de operaciones y desactivacin. Cada vista a su vez tambin tiene un ciclo de vida. As, una vista es cargada, hecha visible y descargada. El siguiente diagrama resume el ciclo de vida de un widget, incluyendo los estados de las vistas y los mtodos llamados durante las transiciones entre estados.

19

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Ilustracin 9: Ciclo de vida de un widget.

La auto-reanudacin es el proceso por el cual una vista se oculta y vuelve a ser mostrada de nuevo, ya sea a travs del botn volver o por otros medios. Cuando la vista se oculta, se libera memoria gracias a la accin del garbage collector. Para ofrecer un contexto consistente al usuario, es posible que el desarrollador del widget desee que la vista se reanude con los mismos datos, foco y estado que mostraba cuando se mostr previamente. Para que un control sea reconocido como objeto de esta auto-reanudacin dentro de cada vista es necesario guardarlo en la estructura this.controls. Adems de this.controls existen otras estructuras muy tiles en el desarrollo de widgets. El siguiente listado resume las estructuras ms usadas en la creacin de vistas:
this.config Propiedades pasadas a la vista en la instanciacin de la misma. this.persist Almacenamiento persistente para cualquier cosa que se quiera

que permanezca cuando la vista se recargue tras la accin del garbage collector.
this.cache Estructuras para datos transitorios. this.controls Referencias a los controles de la vista.

4.1.3 Gestin de eventos La gestin de eventos permite a los widgets escuchar los input del usuario (por ejemplo cuando aprieta un botn del mando a distancia) y, en general, escuchar los eventos del Widget Engine as como disparar y enviar eventos a este ltimo. Como se mencion anteriormente, una de las funciones del KONtx Framework es encapsular las comunicaciones entre los widgets y el Yahoo! Widget Engine. 20

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Los

procedentes del Widget Engine son capturados por la clase KONtx.application y redifundidos a los widgets individuales como eventos del tipo KONtx.system.Event. Host Events son aquellos eventos del Host, procedentes del Widget Engine, a los que nuestro widget puede suscribirse.
Los

eventos

Para suscribir un widget a un evento del Host se hace uso del mtodo subscribeTo:
/*El mtodo subscribeTo() se aade a todas las instancias del objeto Function con la ayuda del objeto prototype de JavaScript*/ void Function.prototype.subscribeTo(Object publishingObject, StringOrArray eventTypes, Object bindingScope);

Al suscribir nuestro widget o una determinada vista a un evento del Host, dependiendo de dicho evento, la suscripcin se realiza a travs de KONtx.HostEventManager o bien a travs de KONtx.application. Esto se especifica en el parmetro publishingObject del mtodo subscribeTo() antes mencionado. Los dos ejemplos siguientes ilustran los mtodos de suscripcin a eventos a disposicin del desarrollador de widgets. Ejemplo de suscripcin a eventos por medio del KONtx.HostEventManager:
function hostEventViewSpecificDispatcher(event) { switch(event.type) { case 'onActivateAppButton': switch(event.payload.type) { case 'app-back': break; case 'app-home': case 'app-title': break; case 'app-settings': break; case 'app-fav-add': case 'app-fav-delete': break; } break; case 'onSelect': break; case 'onUnselect': break; } } hostEventViewSpecificDispatcher.subscribeTo(KONtx.HostEventManager, [ 'onActivateAppButton', 'onSelect', 'onUnselect' ]);

21

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Ejemplo de suscripcin a eventos a travs de KONtx.application:


var EventHandlers = { onApplicationStartup: function(event) { }, onCountryCodeChanged: function(event) { }, getProfileSnippetConfs: function(event) { }, onNetworkRestored: function(event) { } }; EventHandlers.onApplicationStartup.subscribeTo(KONtx.application, ['onApplicationStartup'], EventHandlers); EventHandlers.onCountryCodeChanged.subscribeTo(KONtx.application, ['onCountryCodeChanged'], EventHandlers); EventHandlers.getProfileSnippetConfs.subscribeTo(KONtx.application, ['getProfileSnippetConfs'], EventHandlers); EventHandlers.onNetworkRestored.subscribeTo(KONtx.application, ['onNetworkRestored','onNetworkConnectionReconnect'], EventHandlers);

El desarrollador tambin puede hacer que su widget se suscriba a eventos procedentes de otro publicador. Un ejemplo de publicador distinto es el KONtx message center que, adems de proporcionar una tabla que almacena pares clave-valor para almacenar mensajes accesibles desde las distintas vistas, genera eventos broadcast cuando se aaden nuevos datos o se actualizan los que ya existan. Ejemplo de suscripcin al evento de cambio en los mensajes del KONtx message center:
function logDatasetChange(event) { log("Data for key: " + event.payload.key + " changed value to: "+ event.payload.value); } logDatasetChange.subscribeTo(KONtx.messages, KONtx.messages.eventType); KONtx.messages.store("fibseq", [1,1,2,3,5,8,13,21]);

Por otra parte, un desarrollador tambin puede hacer que su widget dispare eventos y los enve al Widget Engine para que ste acte en consecuencia. Los Child Events, son aquellos eventos del Host que un widget individual puede disparar y enviar al Widget Engine usando el mtodo KONtx.HostEventManager.send(). Un ejemplo de Child Event puede ser el evento "Exit to Dock" que un widget puede disparar pasando "exitToDock" como parmetro en la llamada al mtodo send():
KONtx.HostEventManager.send("exitToDock");

Esta llamada tendra como resultado que el widget devuelve el control al Widget Engine, el cual muestra el dock en la pantalla. Un listado completo de los diferentes eventos puede encontrarse en la documentacin publicada por Yahoo! sobre la API del TV Widget KONtx Framework (ver bibliografa). 22

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Otro elemento importante de la gestin de eventos del KONtx Framework es la clase KONtx.system.Event. Esta clase es utilizada para gestionar y construir sistemas de eventos. En el siguiente ejemplo se muestra la forma de crear un nuevo evento a partir de un evento del host (hostEvent):
var event = new KONtx.system.Event(hostEvent.subject, JSON.parse(hostEvent.data), null,hostEvent);

De esta forma se definen los eventos personalizados. Despus se crea el suscriptor y los manejadores de eventos (event handlers) para configurar los disparadores de eventos y las acciones a realizar (callbacks) respectivamente. Cualquier vista puede suscribirse a un evento a travs de su publicador (publishing object). Cuando la memoria utilizada por la vista es liberada por el garbage collector, automticamente deja de estar suscrita a todos los eventos a los que estaba escuchando. Es posible sobrescribir los eventos existentes para las vistas, pero los mtodos createView() y updateView() estn pensados para evitar en gran medida la necesidad de utilizar los eventos onSelect, onLoad y onShow. 4.2 Archivos de un widget 4.2.1 Estructura de carpetas En un entorno de produccin, los widgets se almacenan en el directorio Widgets. Dentro de este directorio existe una carpeta por cada widget, que contiene los archivos que lo forman. Estas carpetas son fcilmente reconocibles porque presentan la extensin .widget en su nombre. Cuando se remite el widget a la Galera de Widgets de Yahoo! este directorio .widget debe comprimirse en un paquete zip cuyo nombre se construir de la siguiente forma:
widgetID-versionNumber.widget

En el caso del Widget de Cita Mdica el nombre elegido es:


es.us.widgets.tv.cita8-0.2.8.widget

Dentro de este paquete zip debe haber un directorio llamado Contents en el cual estarn los archivos main.TV y widget.xml.

23

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Tanto el widgetID como el nmero de versin en el nombre del paquete zip deben corresponder con los que aparezcan en el archivo widget.xml. En caso contrario la herramienta de publicacin de widgets en la galera muestra un mensaje de error y aborta la subida del widget. Otro detalle importante para evitar errores es comprimir la carpeta .widget y no la carpeta Contents que aloja en su interior y asegurarse de que el paquete zip resultante tenga la extensin .widget en lugar de .zip.

Ilustracin 10: Estructura de carpetas dentro del directorio Contents.

Dentro de la carpeta Contents, adems de los archivos main.TV y widget.xml (cuya utilidad se explica en los apartados 5.2.2 y 5.2.3) se pueden colocar otros archivos o carpetas cualesquiera. No obstante, en la documentacin de la plataforma se recomienda organizar los archivos en las carpetas Images, Javascript y Resources. Algunos fabricantes de televisores requieren que se guarde el icono del widget en la carpeta Contents/Images/960x540 de manera que pueda ser reutilizado para representar al widget en diferentes contextos. La utilidad de la carpeta Resources est relacionada con la posibilidad de que el widget pueda ser visto en varios idiomas. Para lograrlo se reemplazan todas las cadenas de texto en el widget por llamadas a una funcin que busca la cadena en el idioma adecuado, por ejemplo:
var localString = widget.getLocalizedString("video_error_dialog_title");

El motor de widgets buscar la traduccin de esta cadena en un archivo de idioma de nombre Localizable.strings. El motor de widgets espera encontrar estos archivos en una serie de directorios dentro de la carpeta Resources del widget. Los directorios dentro de la carpeta Resources deben nombrarse usando las etiquetas de idiomas IETF BCP 479.

La IETF (Internet Engineering Task Force) publica series numeradas de documentos BCP (Best Current Practice). La especificacin BCP 47 define la sintaxis de las etiquetas de idioma y puede consultarse de forma on-line en <http://tools.ietf.org/html/bcp47>.

24

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Por ejemplo, en el caso del espaol el motor de widgets busca el archivo en Resources/es/Localizable.strings. Para saber en qu carpeta debe buscar el archivo Localizable.strings el motor de widgets comprueba el valor de la variable de entorno KF_LANG. 4.2.2 Archivo main.TV El archivo main.TV es el primer archivo que el motor de widgets carga. Es un archivo XML que en la mayor parte de los casos es usado para cargar el cdigo JavaScript externo a travs de la etiqueta <script>. Sin embargo, en widgets muy sencillos puede incluir en s mismo el cdigo de dicho widget. En el Widget de Cita Mdica el contenido del archivo main.TV es el siguiente:
<?xml version="1.0" encoding="utf-8"?> <widget> <script src="Platform/platform.js"/> <script src="Javascript/init.js"/> </widget>

Es importante que la extensin de archivo .TV de main.TV est escrita con maysculas o el widget no cargar. Las rutas de los archivos en el motor de widgets son siempre relativas a la ubicacin de main.TV. Esto significa que la referencia a un archivo sin especificar ningn directorio, por ejemplo init.js, se buscar en el mismo directorio que main.TV, mientras que una referencia a un archivo con un directorio, por ejemplo Javascript/init.js, se buscar en el subdirectorio especificado dentro de Contents, en este caso el subdirectorio Javascript. En ningn caso deben usarse rutas absolutas, que son aquellas que empiezan con una barra (/). 4.2.3 Archivo w idget.xml Todos los metadatos de un widget se encuentran en el archivo widget.xml. este archivo debe ubicarse en el mismo directorio que main.TV. El archivo widget.xml incluye informacin como el nombre del widget, identificador nico, autor, descripcin e informacin de seguridad. El archivo widget.xml incluye un campo <identifier> el cual define el identificador nico del widget. Se puede usar cualquier valor para este identificador siempre que quede garantizada su unicidad, ya que no puede haber dos widgets con el mismo valor para el identificador de widget.

25

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Cuando se sube un widget a la galera de widgets de Yahoo! la API de subida comprobar que el identificador del widget es nico y devolver un error en caso contrario. El uso de un nombre de dominio inverso puede evitar duplicidades en los identificadores de nuestros widgets. Este tipo de nombres se construye de la siguiente forma:
<identifier>com.mycompany.widgets.mywidget</identifier>

Adems de los metadatos, en el archivo widget.xml tambin incluye la configuracin de seguridad del widget. El elemento <security> controla el acceso a recursos como pueden ser el sistema de archivos, http, comandos, etc... Esta configuracin de seguridad se define como en el siguiente ejemplo:
<security> <filesystem>full</filesystem> <command>true</command> <http>all</http> </security>

A continuacin se har un breve repaso por las principales etiquetas que suelen formar parte del archivo widget.xml:
<?xml version="1.0" encoding="utf-8"?>

Define la declaracin XML.


<metadata>

Indica el comienzo de los metadatos del widget.


<name>

Define el nombre del widget.


<version>

Define la versin del widget.


<identifier>

Define el identificador nico del widget.


<author>

Define el nombre del autor del widget, organizacin y URL de soporte.


<copyright>

Identifica la informacin de copyright.


<description>

Proporciona una descripcin para el widget.


<platform minVersion="5.0">

Define la versin mnima del motor de widgets requerida.

26

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

<security>

Define la seguridad para el sistema de archivos, los comandos de sistema, y http del widget.
<image usage="960x540.logo" src="Images/960x540/logo.png"/>

Define el logo de pantalla estndar para la parte de arriba de la barra lateral.


<image usage="960x540.icon" src="Images/960x540/icon.png"/>

Define el icono de pantalla estndar para la galera de widgets. Este icono es usado por varios fabricantes para representar al widget por lo que debe ser una imagen de 44x44 pixels y debe incluirse en el directorio Contents/Images/960x540/. 4.2.4 El archivo init.js Normalmente el primer archivo JavaScript que se carga es el archivo init.js cuyo cdigo realiza la inicializacin bsica del widget. La primera lnea del archivo init.js es la encargada de incluir el cdigo del KONtx Framework. Tras esto se incluyen otra serie de archivos que contienen el cdigo JavaScript del propio widget. Los archivos cargados desde la carpeta Javascript/views extienden alguna de las clases base del KONtx Framework relativas a los tres tipos de vistas existentes (snippet, barra lateral y pantalla completa), construyendo y definiendo el aspecto y funcionalidad de las distintas vistas del widget. A modo de ejemplo se citan a continuacin las primeras lneas del archivo init.js del Widget de Cita Mdica:
include("Framework/kontx/1.1/src/all.js"); include("Javascript/core/API.js"); include("Javascript/views/MainView.js"); include("Javascript/views/VistaSinUsuarios.js"); include("Javascript/views/VistaMostrarUsuarios.js"); include("Javascript/views/VistaBorrarUsuario.js"); include("Javascript/views/VistaIntroducirDatos.js"); include("Javascript/views/VistaEsperar.js"); include("Javascript/views/VistaMostrarDias.js"); include("Javascript/views/VistaMostrarHoras.js"); include("Javascript/views/VistaCitaAsignada.js"); include("Javascript/views/VistaInformacion.js"); include("Javascript/views/VistaInformacionError.js"); include("Javascript/views/VistaOtroDia.js"); include("Javascript/views/AboutView.js"); include("Javascript/views/SnippetView.js");

La inicializacin de las vistas tambin se realiza en el archivo init.js y es implementada llamando al mtodo KONtx.application.init (Object config). El objeto config incluye la propiedad views que consiste en un array con todas las vistas que se van a 27

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

inicializar, estando cada una definida por el id de la vista, una clase de vista, y un parmetro de datos opcional. A continuacin se comentarn una por una todas las propiedades del objeto config que deben especificarse en la inicializacin de las vistas: La matriz de vistas views, en la que cada vista se define por un Id, una clase de vista y un parmetro de datos opcional. El defaultViewId, que es el Id de la vista correspondiente al punto de inicio de la navegacin (HOME) del widget. El settingsViewId, que es el Id de la vista que se muestra al presionar la tecla verde del control remoto, correspondiente al About Box del widget y que puede asignarse a la vista por defecto KONtx.views.AboutBox. La propiedad widgetNeedsNetwork. Si el widget no requiere conexin de red se debe asignar el valor false a esta propiedad ya que el valor por defecto es true.

Tanto la matriz de vistas como la propiedad defaultViewId son obligatorias. En cambio, la propiedad settingsViewId es opcional, si bien se muestra un error por consola en caso de no asignarle un valor. En el caso del Widget de Cita Mdica la llamada a KONtx.application.init (Object config) queda de la siguiente forma:
KONtx.application.init({ views: [ { id: 'view-Main', viewClass: MainView }, { id: 'view-IntroducirDatos', viewClass: VistaIntroducirDatos }, { id: 'view-Esperar', viewClass: VistaEsperar }, { id: 'view-MostrarDias', viewClass: VistaMostrarDias }, { id: 'view-MostrarHoras', viewClass: VistaMostrarHoras }, { id: 'view-CitaAsignada', viewClass: VistaCitaAsignada }, { id: 'view-Informacion', viewClass: VistaInformacion }, { id: 'view-InformacionError', viewClass: VistaInformacionError }, { id: 'view-OtroDia', viewClass: VistaOtroDia }, { id: 'view-About', viewClass: AboutView }, { id: 'snippet-1', viewClass: SnippetView, data: { message1: "Versin 2.0", message2: "Cita Mdica" , message3: "Servicio Andaluz de Salud"} }, ], defaultViewId: 'view-Main', settingsViewId: 'view-About', });

Como el Widget de Cita Mdica requiere conexin no hemos tenido que asignar un valor a la propiedad widgetNeedsNetwork ya que por defecto su valor es true.

28

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Otra de las tareas que se realizan en el archivo init.js es la suscripcin de nuestro widget a eventos del host. Esta cuestin se analiza pormenorizadamente en el apartado 4.1.3 y en el 6.2.4 se explica su aplicacin en el Widget de Cita Mdica, por lo que no se profundizar en ella dentro de este apartado. 4.3 Widget Development Kit 4.3.1 Descarga e instalacin Durante el desarrollo de los widgets, estos se prueban usando el conjunto de simuladores (uno por fabricante) proporcionado con el Widget Development Kit (WDK). El simulador ofrece al desarrollador la posibilidad de ver cmo funcionan sus widgets y depurar su cdigo antes de probarlos en un dispositivo real. El Simulador est disponible a travs de un paquete Debian llamado Yahoo! Widget EngineWidget Development kit (YWE-WDK) el cual contiene la ltima versin del motor de widgets. El simulador slo ha sido testeado sobre la mquina virtual Ubuntu 10.04 distribuida por Yahoo! por lo que se descarg e instal el YWE-WDK dentro de ella. Para el desarrollo del Widget de Cita Mdica se ha utilizado VMware Player 3.0.0 como software de virtualizacin pero tambin se ha testeado la aplicacin con xito usando Virtual Box 4.1.10. Los pasos que se han seguido para la instalacin y puesta en marcha del Simulador son: 1. Instalar el software de Virtualizacin VMware Player. 2. Descargar y descomprimir la mquina virtual Linux Ubuntu 10.04 distribuida por Yahoo! Connected TV. 3. Abrir la mquina virtual distribuida por Yahoo! con VMware Player, e instalar el paquete Debian YWE-WDK dentro de la mquina virtual. 4. Arrancar el Simulador elegido de los nueve disponibles. Para arrancar el simulador de LG, por ejemplo, los pasos seran Applications>TV Widgets>LG>LG Simulator. El equipo utilizado es un porttil TOSHIBA con procesador Intel Core i5 y CPU M480 @ 2.67GHz., 4,00 GB de memoria RAM y S.O. Windows 7 de 64 bits. Algunas de las limitaciones conocidas del testeo de widgets en el simulador son: El rendimiento en la mquina virtual no es representativo del rendimiento en el dispositivo real. El manejo de memoria en el simulador no es representativo de las limitaciones de memoria en el dispositivo real. 29

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

El color en el monitor no es representativo del color en los televisores. La calidad del sonido no es representativa. La calidad de la reproduccin de vdeo en el simulador no es representativa de la reproduccin de vdeo en el televisor. En el simulador no estn presentes las tecnologas de DRM (Digital Rights Management).

4.3.2 Primeros pasos con el simulador Para determinar la versin del KONtx Framework presente en el simulador basta con lanzar alguno de los simuladores disponibles para, a continuacin, desde la ventana de consola que se abre, ir al widget principal (widget container) y tras esto imprimir la propiedad JavaScript platform.backend.devinfo.fwversion:
/widgets 1 print("KONtx Framework version: " + platform.backend.devinfo.fwversion);

En nuestro caso la versin del KONtx Framework es la 1.3.28 que es la que viene con la ltima versin del Yahoo! Widget Engine-Widget Development Kit (YWE-WDK 1.2.16). Para testear widgets en el simulador basta con colocarlos en la carpeta /devwidgets, resetear el simulador y lanzarlo. Una vez que el widget aparece en el dock no es necesario volver a resetear el simulador aunque se modifique el cdigo del mismo. Para ver los cambios guardados basta con cerrar y volver a lanzar el simulador. Eso s, en caso de aadir un nuevo widget a la carpeta /devwidgets habra que volver a resetear el simulador para cargar dicho widget en el dock. Si queremos probar en el simulador un idioma distinto al ingls, que es el idioma por defecto, hay que usar la variable de entorno KF_LANG. Para establecer el espaol como idioma de la plataforma basta abrir un terminal y escribir:
export KF_LANG = es

Una vez hecho esto, para lanzar el simulador Konfabulator Latest desde la consola de comandos se escribe:
/usr/local/bin/Konfabulator --Latest

Al hacer KF_LANG = es le estamos diciendo al motor de widgets que busque en Resources/es/Localizable.strings la traduccin de las distintas cadenas de texto.

30

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

4.3.3 Depuracin de cdigo con la consola del simulador La Consola del Simulador (que se ejecuta en una ventana de terminal que se abre cada vez que se lanza el simulador) permite inspeccionar los objetos tanto del motor de widgets como del KONtx Framework durante la ejecucin. Existen una serie de comandos que podemos escribir en la ventana de terminal que ejecuta la consola del simulador para facilitar la tarea de depuracin del cdigo. La lista de comandos completa puede obtenerse escribiendo:
/help

En el desarrollo del Widget de Cita Mdica result de gran utilidad restringir los mensajes de consola. Restringiendo los mensajes nicamente a aquellos relativos al widget cuyo cdigo estamos depurando es mucho ms fcil encontrar los mensajes que aportan informacin til. Para restringir los mensajes de consola se selecciona el elemento Simulator Settings del men Application>TV Widgets. Este elemento del men lanza una ventana del editor por defecto para revisar y editar el archivo Konfabulator.env que se encuentra en el directorio $HOME/TVWidgets. Este archivo controla las variables de entorno para todos los simuladores. Una de las lneas dentro de este archivo sirve para restringir los mensajes de consola a los del widget que se indique. Para facilitar el desarrollo del Widget de Cita Mdica esta lnea se modific de la siguiente forma:
restrict_console=es.us.tv.cita8

Donde es.us.tv.cita8 es el identificador de la ltima versin del Widget de Cita Mdica. 4.4 Testeo de widgets en un televisor Una vez hemos completado las pruebas en el simulador, es posible configurar un televisor en modo desarrollo para probar nuestro widget en un dispositivo real. Esto permite al desarrollador testear la experiencia de usuario con su widget antes de remitirlo a Yahoo! para su aprobacin. El Widget de Cita Mdica ha sido testeado con xito en un televisor Samsung modelo UE40B8000XW.

31

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Para saber la versin de los distintos componentes software de la plataforma instalados en el televisor, se accedi a la categora Settings>System Software del widget "Widget Gallery" (ver Ilustracin 12). As se comprob que la versin del Widget Application Framework instalada en el televisor es la 1.3.12.C, mientras que la versin del Yahoo! Widget Engine es la 5.0.0. Por su parte, la versin del Widget Container es la 1.2.66.C.

Ilustracin 11: Componentes software instalados en el televisor.

El primer paso para probar el funcionamiento del Widget de Cita Mdica en un dispositivo real consisti en la obtencin del cdigo de desarrollador del televisor en el que se iban a llevar a cabo las labores de testeo. Los pasos para la obtencin de este cdigo fueron los siguientes: 1. En el televisor se busca el Snippet del widget de nombre "Widget Gallery" y se selecciona para lanzarlo. 2. Se presiona el botn verde para lanzar la vista "Settings". 3. En la vista Settings se selecciona el botn "Developer Settings". 4. Se pone a "On" el botton "Show My Test Widgets". 5. A continuacin es necesario logarse con nuestro id de Yahoo!. 6. Se mostrar un cdigo de cuatro letras que es el "Developer Code". 32

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Ilustracin 12: Cdigo de Desarrollador del televisor en el que se han realizado las labores de testeo.

La herramienta de publicacin nos solicitar est cdigo en el momento de subir el widget a la galera. Para acceder a la herramienta de publicacin hay que identificarse con nuestro id de Yahoo! en <http://gallery.tv.widgets.yahoo.com/publisher/>

Ilustracin 13: Formulario previo a la subida del widget.

La herramienta permite, una vez subido el widget, aadir nuevos testers. Cada tester queda definido por el cdigo de desarrollador (Developer Code) y por su id de Yahoo!. 33

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Ilustracin 14: Datos requeridos para aadir un nuevo tester al widget.

Una vez subido, ya es posible ver el widget en el televisor de cualquiera de los testers aadidos. Estos son los pasos que debe realizar el tester para localizar el widget en su televisor: 1. Registrarse con su id de Yahoo!. 2. Abrir el widget de nombre "Widget Gallery". 3. Seleccionar "Categories" y navegar hasta la ltima pgina. 4. Seleccionar la categora "Test Widgets". 5. Seleccionar el widget que se quiere testear y aadirlo a su perfil. El widget aparecer entonces en el dock y se podr probar.

Ilustracin 15: Vista en la que se aade al perfil actual el Widget de Cita Mdica 0.2.8 para su testeo.

34

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

4.5 Publicacin en la Galera de TV Widgets de Yahoo! Para que nuestro widget est disponible para todos los usuarios en la Galera de Widgets de Yahoo!, previamente debe pasar por un proceso de validacin a cargo del equipo de Yahoo!. Tras superar este proceso, el widget "aprobado" podr ser descargado e instalado en cualquier dispositivo Yahoo! Connected TV. Para que el widget supere la QA y el proceso de aprobacin de Yahoo! el cdigo de dicho widget debe cumplir con una serie de condiciones entre las que destacan dos: No se realizarn llamadas sncronas, de forma que el usuario puede seguir interactuando con el widget mientras el servidor responde a una peticin XMLHttpRequest. El Widget debe manejar adecuadamente un fallo sbito de conexin de red. Debe indicar al usuario que dicho fallo se ha producido, mostrando un mensaje de alerta y unos iconos de advertencia, y volver a funcionar normalmente cuando la conexin se recupere. El testeo en el caso de estado de red "Desconectado" es parte de la QA 10 del widget y del proceso de aprobacin de Yahoo! previos a la inclusin de dicho widget en la Galera de Widgets en entornos de produccin.

Ilustracin 16: Portada del documento sobre Criterios de Aceptacin de Widgets para TV de Yahoo!

10

QA: Quality Assurance. En espaol puede traducirse como certificacin de la calidad.

35

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

5. Tecnologas utilizadas en el desarrollo del Widget de Cita Mdica


Aunque los lenguajes de programacin utilizados (JavaScript y PHP) son de sobra conocidos y estn ampliamente documentados, se incluir en este apartado una breve resea de cada uno de ellos, as como algunas caractersticas generales del formato de intercambio de datos utilizado, el formato JSON. 5.1 Javascript JavaScript es un lenguaje de programacin interpretado, es decir, diseado para ser ejecutado por un intrprete, por lo que no requiere compilacin. Es muy utilizado en pginas web, embebido en el cdigo HTML. En este caso son los navegadores los que interpretan los cdigos JavaScript incluidos en las pginas web. Es por ello que se considera un lenguaje del lado del cliente, si bien existe una forma de JavaScript del lado del servidor (Server-side JavaScript). Adems de en el mbito web, su uso tambin es significativo en aplicaciones de escritorio (widgets en su mayor parte). JavaScript es un lenguaje basado en prototipos, pues las nuevas clases se generan clonando las clases base (prototipos) y extendiendo sus funcionalidades. Tambin se define como orientado a objetos, imperativo, dbilmente tipado y dinmico. Creado por Brendan Eich de Netscape, aparece por primera vez en el navegador Netscape Navigator 2.0. Inicialmente se llam Mocha, luego LiveScript y finalmente vi la luz como JavaScript en un anuncio conjunto entre Sun Microsystems (creadores de JAVA) y Netscape el 4 de diciembre de 1995. El cambio de nombre gener confusin ya que daba pie a pensar que se trataba de una prolongacin de Java, cuando en realidad el cambio de nombre se debi a una estrategia de mercadotecnia de Netscape orientada a sacar partido de la popularidad de JAVA, que era la ltima novedad en ese momento. La existencia de distintas versiones de JavaScript incompatibles llev al World Wide Web Consortium (W3C) a disear un estndar llamado DOM (Document Object Model) que incopora Internet Explorer 6 en adelante, Opera versin 7 en adelante y Mozilla Firefox. En 1997 los autores propusieron JavaScript para que fuera adoptado como estndar de la European Computer Manufacturers Association (ECMA), que, a pesar de su nombre, no es europeo sino internacional, con sede en Ginebra. En junio de 1997 fue adoptado como un

36

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

estndar ECMA, con el nombre de ECMAScript11 y poco despus tambin como un estndar ISO. 5.2 PHP PHP es un lenguaje de programacin interpretado, diseado originalmente para la creacin de pginas web dinmicas. Se usa principalmente para la interpretacin del lado del servidor pero actualmente puede ser utilizado tambin desde una interfaz de lnea de comandos o para la creacin de otros tipos de programas incluyendo aplicaciones con interfaz grfica haciendo uso de las bibliotecas Qt o GTK+. Las siglas PHP corresponden a un acrnimo recursivo que significa PHP Hypertext Preprocessor. PHP fue creado originalmente por Rasmus Lerdorf en 1994; sin embargo la implementacin principal de PHP corre ahora a cargo de The PHP Group y sirve como el estndar de facto para PHP al no haber una especificacin formal. Publicado bajo la PHP License, la Free Software Foundation considera esta licencia como software libre. Puede ser desplegado en la mayora de los servidores web y en casi todos los sistemas operativos y plataformas sin costo alguno. El lenguaje PHP se encuentra instalado en ms de 20 millones de sitios web y en un milln de servidores. Es tambin el mdulo Apache ms popular entre las computadoras que utilizan Apache como servidor web. Cuando el cliente hace una peticin al servidor para que le enve una pgina web, el servidor ejecuta el intrprete de PHP. ste procesa el script solicitado que generar el contenido de manera dinmica (por ejemplo obteniendo informacin de una base de datos). El resultado es enviado por el intrprete al servidor, quien a su vez se lo enva al cliente. El gran parecido que posee PHP con los lenguajes ms comunes de programacin estructurada, como C y Perl, permiten a la mayora de los programadores crear aplicaciones complejas con una curva de aprendizaje muy corta. Tambin les permite involucrarse con aplicaciones de contenido dinmico sin tener que aprender todo un nuevo grupo de funciones. Permite la conexin a diferentes tipos de servidores de bases de datos tales como MySQL, PostgreSQL, Oracle, ODBC, DB2, Microsoft SQL Server, Firebird y SQLite.

11

Estndar ECMAScript: <http://www.ecma-international.org/publications/standards/Ecma-262.htm>

37

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

PHP tambin tiene la capacidad de ser ejecutado en la mayora de los sistemas operativos, tales como Unix (y de ese tipo, como Linux o Mac OS X) y Microsoft Windows, y puede interactuar con los servidores web ms populares ya que existe en versin CGI, mdulo para Apache, e ISAPI. PHP es una alternativa a las tecnologas de Microsoft ASP y ASP.NET (que utiliza C# y Visual Basic .NET como lenguajes), a ColdFusion de la empresa Adobe, a JSP/Java y a CGI/Perl. Comparndola con otras, PHP es, y probablemente seguir siendo, una tecnologa tremendamente abierta. A pesar de que el cdigo PHP se ejecuta en el servidor y permanece oculto para el usuario web, existe una enorme comunidad de desarrolladores dispuesta a compartir sus conocimientos y experiencias con el lenguaje. Basta con buscar un poco en la Web para encontrar multitud de ejemplos y tutoriales de PHP, desde los ms bsicos hasta algunos realmente complejos. 5.3 XML y JSON XML es un metalenguaje extensible de etiquetas utilizado para el intercambio de informacin estructurada. Desarrollado por la W3C, se defini con la intencin de convertirse en el estndar para el intercambio de datos entre diferentes plataformas. JSON por su parte es un subconjunto de la notacin literal de objetos de JavaScript y est adquiriendo cada vez una mayor notoriedad en la programacin web debido a las ventajas que ofrece sobre XML. Entre estas ventajas destaca que, el anlisis de una cadena JSON es algo inmediato usando la funcin eval() de JavaScript, en comparacin con la laboriosa tarea de recorrer un XML. Este es uno de los motivos por los cuales los desarrolladores estn volcando sus esfuerzos en esta herramienta de intercambio de datos. JSON se emplea habitualmente en entornos donde el tamao del flujo de datos entre cliente y servidor es de vital importancia. Sin embargo, la utilizacin de eval()para analizar JSON es algo delicado y puede atentar la seguridad del sitio si, en lugar de datos, la cadena contuviese cdigo malintencionado. Este inconveniente se soslaya en la plataforma de Yahoo! Connected TV poniendo a disposicin de los desarrolladores un analizador JSON que adems resulta ser entre 3 y 4 veces ms rpido que su versin JavaScript. En el apartado 6.2.5 se incluye una descripcin detallada del uso de este analizador JSON incluido en la plataforma en el desarrollo del Widget de Cita Mdica. Al estar escritos en JavaScript, JSON es el formato de transferencia de datos ms conveniente para los widgets de Yahoo! Connected TV. No obstante, XML tambin forma parte del desarrollo de cualquier widget, ya que se utiliza para definir el punto de inicio del

38

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

mismo. En efecto, el primer archivo que el motor de widgets carga es un archivo XML, concretamente el archivo main.TV, ya mencionado. Tambin se utiliza XML para definir los metadatos del widget. Estos metadatos se encuentran en el archivo widget.xml que, como tambin se ha comentado ya, contiene el nombre del widget, su identificador, su descripcin, la informacin de seguridad, etc.

39

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

6. Desarrollo del Widget de Cita Mdica


6.1 Esquema de funcionamiento de la aplicacin El widget de cita mdica basa su funcionamiento en la realizacin de peticiones por medio del objeto XMLHttpRequest de JavaScript a un servidor intermedio. Este servidor es el que, a su vez, se encarga de realizar peticiones al servidor de InterS@S haciendo uso de la librera libcurl de PHP. El servidor intermedio procesar la respuesta ofrecida por el servidor de InterS@S con ayuda de la clase Simple HTML DOM parser, obteniendo as los datos necesarios para el widget de cita mdica. Finalmente, el servidor intermedio se encargar de presentar estos datos en formato JSON, el formato de datos ms adecuado para ser consumido por los widgets de Yahoo! Connected TV.

Ilustracin 17: Esquema de funcionamiento de la aplicacin.

6.2 Cdigo del Widget de Cita Mdica (JavaScript) 6.2.1 Implementacin de las vistas Como ya se coment en el apartado 4.2.4, el cdigo de cada uno de los archivos cargados por init.js desde la carpeta Javascript/views/ extiende alguna de las clases base del KONtx Framework que implementan los distintos tipos de vistas existentes. Por tanto, es en estos archivos donde se construye y define el aspecto y funcionalidad de las distintas vistas del widget.

40

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

En efecto, en las primeras lneas del archivo init.js del Widget de Cita Mdica, adems de cargar el KONtx Framework y otros archivos necesarios para nuestro widget se cargan los catorce archivos contenidos en la carpeta JavaScript/views/ que corresponden a cada una de las vistas del Widget de Cita Mdica:
include("Framework/kontx/1.1/src/all.js"); include("Javascript/core/API.js"); include("Javascript/views/MainView.js"); include("Javascript/views/VistaSinUsuarios.js"); include("Javascript/views/VistaMostrarUsuarios.js"); include("Javascript/views/VistaBorrarUsuario.js"); include("Javascript/views/VistaIntroducirDatos.js"); include("Javascript/views/VistaEsperar.js"); include("Javascript/views/VistaMostrarDias.js"); include("Javascript/views/VistaMostrarHoras.js"); include("Javascript/views/VistaCitaAsignada.js"); include("Javascript/views/VistaInformacion.js"); include("Javascript/views/VistaInformacionError.js"); include("Javascript/views/VistaOtroDia.js"); include("Javascript/views/AboutView.js"); include("Javascript/views/SnippetView.js");

El Widget de Cita Mdica consta de catorce vistas, de las cuales trece son vistas de barra lateral por lo que en su definicin extienden la clase base KONtx.system.SidebarView. A continuacin y a modo de ejemplo se citan las primeras lneas del cdigo del archivo VistaCitaAsignada.js, en el que se define la clase VistaCitaAsignada.
var VistaCitaAsignada = new KONtx.Class({ ClassName: 'MiVistaCitaAsignada', Extends: KONtx.system.SidebarView, createView: function() { ...

La vista nmero catorce es la vista de Snippet del widget y extiende la clase base KONtx.system.SnippetView. En este caso, el archivo VistaSnippet.js empieza de la siguiente manera:
var VistaSnippet = new KONtx.Class({ ClassName: 'MiVistaSnippet', Extends: KONtx.system.SnippetView, ...

En la ilustracin 17 se muestran las doce vistas de barra lateral diseadas especficamente para el Widget de Cita Mdica. En ellas se contemplan todos los posibles casos que pueden darse durante el proceso de peticin de cita con el mdico a travs del widget. 41

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Ilustracin 18: Vistas del Widget de Cita Mdica.

La

implementada llamando al mtodo KONtx.application.init (Object config). El objeto config incluye la propiedad views que consiste en un array con todas las vistas que se van a inicializar, estando cada una definida por el id de la vista, una clase de vista, y un parmetro de datos opcional. 42

inicializacin

de

las

vistas

es

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA


//Inicializacin de las vistas KONtx.application.init({

Proyecto Fin de Carrera Mara Len Bujes

views: [ { id: 'view-Main', viewClass: MainView }, { id: 'view-IntroducirDatos', viewClass: VistaIntroducirDatos }, { id: 'view-Esperar', viewClass: VistaEsperar }, { id: 'view-MostrarDias', viewClass: VistaMostrarDias }, { id: 'view-MostrarHoras', viewClass: VistaMostrarHoras }, { id: 'view-CitaAsignada', viewClass: VistaCitaAsignada }, { id: 'view-Informacion', viewClass: VistaInformacion }, { id: 'view-InformacionError', viewClass: VistaInformacionError }, { id: 'view-OtroDia', viewClass: VistaOtroDia }, { id: 'view-About', viewClass: AboutView }, { id: 'snippet-1', viewClass: VistaSnippet, data: { message1: "Versin 2.7", message2: "Cita Mdica" , message3: "Servicio Andaluz de Salud"} }, ], defaultViewId: 'view-Main', settingsViewId: 'view-About', });

Dentro del objeto config tambin se especifica el id de la vista por defecto (la vista que se despliega al activar el Snippet) as como la vista que se mostrar al seleccionar el botn verde (Settings) ubicado en la barra de herramientas global que se encuentra en la parte inferior de las vistas de barra lateral del widget.

Ilustracin 19: Aspecto de la vista view-About.

Como ya se coment anteriormente, la forma de crear una nueva vista es extender la clase base correspondiente sobrescribiendo los mtodos createView() y updateView() de dicha clase. Es en el cdigo del mtodo createView() donde se aaden los controles que definen la estructura de la vista. En el Widget de Cita Mdica los controles aadidos a cada vista se guardan en la estructura this.controls (donde this representa a la vista en cuestin). 43

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Haciendo esto se consigue que, si la vista se oculta, cuando vuelva a mostrarse ofrezca un contexto consistente al usuario, reanudndose con los mismos datos, foco y estado que presentaba cuando se ocult. Un ejemplo del uso de la estructura this.controls en el Widget de Cita Mdica se encuentra en el siguiente fragmento de cdigo:
var VistaMostrarUsuarios = new KONtx.Class({ ClassName: 'MiVistaMostrarUsuarios', Extends: KONtx.system.SidebarView, createView: function() { this.controls.backButton = new KONtx.control.BackButton({ label:'Usuarios Guardados', guid: "back_button", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ data: "Escoja el usuario para el que desea pedir cita.", wrap:true, styles: { vOffset: this.controls.backButton.outerHeight+20, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.botonusuario1 = new KONtx.control.TextButton({ label: 'Usuario1', guid: "botonusuario1", styles: { vOffset: this.controls.texto0.outerHeight+20, }, events: { onSelect: function(event) { datosusuario1json=currentAppConfig.get('usuario1'); datosusuario1=JSON.parse(datosusuario1json); KONtx.messages.store('nuss', datosusuario1.nuss); KONtx.messages.store('dia', datosusuario1.dia); KONtx.messages.store('mes', datosusuario1.mes); KONtx.messages.store('anio', datosusuario1.anio); KONtx.messages.store('dni', datosusuario1.dni); KONtx.application.addViewConfig({ id: 'view-Esperar', viewClass: VistaEsperar }); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario1.hide(); ...

En aquellos casos en los que el widget ha requerido que los datos mostrados en la vista se actualicen cuando sta se cargue se ha implementado una llamada XMLHttpRequest en el mtodo updateView() de dicha vista y se ha usado la respuesta para actualizar los textos o datos mostrados. As ocurre en el mtodo updateView() de la clase VistaMostrarDias (el cdigo ntegro del archivo VistaMostrarDias.js puede consultarse en el Anexo I). 44

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

En este punto cabe preguntarse cmo se pueden recuperar datos presentes en una determinada vista cuando estamos en otra vista diferente. En el Widget de Cita Mdica este problema se soluciona recurriendo al Centro de Mensajes del KONtx Framework. El Centro de Mensajes del KONtx Framework proporciona una tabla basada en claves para el almacenamiento de mensajes, combinada con eventos broadcast que se disparan cuando se aaden datos nuevos o se actualizan los ya existentes en la tabla. Esta tabla puede describirse como un buzn de almacenamiento en el que se guardan los mensajes de un widget individual. Para realizar el paso de mensajes entre las diferentes vistas del Widget de Cita Mdica se utilizan los mtodos KONtx.messages.store(key, value), para almacenar el array, objeto o tipo primitivo value asociado a la clave key, y KONtx.messages.fetch(key) para recuperarlo posteriormente. 6.2.2 Implementacin de dilogos En el desarrollo del Widget de Cita Mdica se han utilizado distintos dilogos con objeto de ofrecer informacin al usuario durante el proceso de peticin de cita.

Ilustracin 20: Dilogo de alerta de dato no vlido y dilogo de confirmacin de cancelacin de cita.

En la vista en la que el usuario introduce sus datos se han implementado dilogos de alerta que se muestran si el nmero de la seguridad social, la fecha de nacimiento o el D.N.I. introducidos no superan la validacin pertinente, en cuyo caso no se llega a realizar la peticin al servidor intermedio y en consecuencia tampoco al servidor de InterS@S. La 45

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

validacin de los datos la realizan una serie de funciones incluidas en el archivo Javascript/core/API.js que devuelven un valor diferente segn se haya detectado o no un error. Si hay error se mostrar al usuario el dilogo que corresponda para facilitarle la correccin del mismo. A modo de ejemplo, a continuacin se cita un fragmento del cdigo de deteccin de errores incluido en el archivo API.js:
function mayor_edad(edad,dia1,mes1,anio1){ hoy=new Date(getRealTime()*1000); log(hoy); var dia=hoy.getDay(); var mes=hoy.getMonth()+1; var anio=hoy.getFullYear(); if ( (anio-anio1)>edad ) { return true; } if ( (anio-anio1)==edad && (mes-mes1)>0 ) { return true; } if ( (anio-anio1)==edad && (mes-mes1)==0 ){ if ((dia1-dia)<=0 ) /*Devolvemos true porque la fecha de nacimiento introducida corresponde con un usuario mayor de la edad pasada como parmetro y en la vista ViewIntroducirDatos se muestra un alert si no se ha introducido el dni*/ { return true; } } /*Devolvemos false en caso contrario y no se mostrar un alert aunque no se haya introducido dni ya que no es obligatiorio introducirlo en el caso de menores de edad*/ return(false); }

Por su parte, el cdigo incluido en el evento OnSelect del botn Solicitar/Consultar Cita de la vista en la que el usuario introduce sus datos es el encargado de comprobar los datos introducidos y de mostrar la alerta que corresponda:
this.controls.pedircita = new KONtx.control.TextButton({ label: 'Solicitar/Consultar Cita', guid: "pedircita", styles: { vOffset: this.height-this.controls.backButton.outerHeight, }, events: { onSelect: function(event) { KONtx.messages.store ('nuss', auxiliar2.controls.numeross.getValue()); KONtx.messages.store ('dia', auxiliar2.controls.dia.getValue()); KONtx.messages.store ('mes', auxiliar2.controls.mes.getValue()); KONtx.messages.store ('anio', auxiliar2.controls.anio.getValue()); KONtx.messages.store ('dni', auxiliar2.controls.dni.getValue()); var var var var var nuss=Quita_blancos(KONtx.messages.fetch('nuss')); dia1=Quita_blancos(KONtx.messages.fetch('dia')); mes1=Quita_blancos(KONtx.messages.fetch('mes')); anio1=Quita_blancos(KONtx.messages.fetch('anio')); dni=Quita_blancos(KONtx.messages.fetch('dni'));

//Si todos los campos se han rellenado se carga la vista MostrarDias if(nuss==''){alerta1_1.show();}

46

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

else{ if(dia1==''||mes1==''||anio1==''){alerta1_2.show();} else{ if (validar_ss(nuss)==false){alerta2.show();} //Nmero de la seguridad social incorrecto else{//Comprobamos la validez de la fecha de nacimiento contenido=dia1+'/'+mes1+'/'+anio1; switch (comprueba_fecha(contenido)){ /* case 1: alerta3.show();//Carcter no vlido en la fecha de nacimiento break; case 2: alerta4.show();//Fecha de nacimiento no vlida break; */ case 3: alerta5.show();//Ao incorrecto en la fecha de nacimiento break; case 4: alerta6.show();//Mes incorrecto en la fecha de nacimiento break; case 5: alerta7.show();//Da incorrecto en la fecha de nacimiento break; default: //La fecha es correcta. Comprobamos el dni. if((dni=='')&&(mayor_edad(14,dia1,mes1,anio1)==true)){ alerta8.show();//Debe introducir su dni } else{ /*Se ha introducido el dni. Comprobamos que es correcto. El widget slo admite el dni, si permitisemos otros documentos esta comprobacin se realizara slo para el dni.*/ if (((nif(dni)==false)&&(mayor_edad(14,dia1,mes1,anio1)==true))|| ((nif(dni)==false)&&(mayor_edad(14,dia1,mes1,anio1)==false)&&( dni!=''))){alerta9.show();}//El dni introducido no es vlido else{ KONtx.application.addViewConfig({ id: 'view-Esperar', viewClass: VistaEsperar }); KONtx.application.loadView('view-Esperar'); } } } } } } } } }).appendTo(this);

Cada una de las alertas se define indicando ttulo, texto, los botones que incluye y las funciones callback para cada uno de ellos. A modo de ejemplo se citar a continuacin el fragmento de cdigo que implementa el dilogo a desplegar en caso de que el nmero de la seguridad social introducido no sea vlido.
var alerta2= new KONtx.dialogs.Alert({ title: 'Dato no vlido', message: 'El nmero de la seguridad social introducido no es correcto.', focusOnCompletion: this.element.focusedView,

47

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA


buttons:[ { label: 'Aceptar'} ] });

Proyecto Fin de Carrera Mara Len Bujes

6.2.3 Uso del objeto XMLHttpRequest de JavaScript El Widget de Cita Mdica hace uso intensivo del objeto XMLHttpRequest (XHR) de JavaScript. El objeto XHR permite hacer peticiones HTTP y HTTPS a un servidor web y capturar su respuesta de forma similar a como lo haran un navegador o un cliente web de lnea de comandos. Para los datos transferidos puede utilizarse cualquier formato basado en texto, lo que incluye: texto plano, XML, JSON, HTML y codificaciones particulares especficas. El uso ms extendido del objeto XHR es entregar contenido dinmico, proporcionando actualizaciones asncronas de una pgina web en el navegador del usuario, mediante tecnologas construidas sobre l como por ejemplo AJAX. En este caso existe una limitacin importante (conocida como poltica del mismo origen o en ingls cross-domain restriction) por la cual los programas ejecutados desde un dominio no pueden afectar a los programas y datos de otro dominio. Es decir, el cdigo JavaScript debe residir en el mismo dominio que el recurso al que trata de acceder. Esta restriccin evidentemente no existe en la plataforma Yahoo! Connected TV que permite que el cdigo JavaScript de los widgets que reside en el televisor del usuario acceda mediante el objeto XMLHttpRequest a contenido web almacenado en cualquier servidor. Con un objeto XMLHttpRequest se puede hacer una peticin a una URL pero lo que reside en esa URL no tiene que ser en principio algo demasiado til para nuestros propsitos. As, si necesitamos unos datos especficos, qu sentido tendra obtener una pgina de HTML entera que despus nuestro cdigo tendra que analizar hasta obtener el dato que necesitamos? Resulta evidente que, en este caso, la respuesta debera ser pequea y fcilmente analizable12. Podemos referirnos a este tipo de recursos, que tienen una entrada y salida relativamente simple y que funcionan ms como la llamada a una funcin que como una aplicacin web convencional, como servicios web o simplemente servicios. Hay muchas formas de implementar servicios web pero atendiendo a la definicin propuesta, basada en lo que es en esencia un servicio web, se puede considerar que el servidor intermedio del esquema del apartado 6.1 (ilustracin 16) aloja una coleccin de servicios web relacionados

12

Esta caracterstica del recurso adquiere especial relevancia en el caso de desarrollo de aplicaciones para dispositivos con recursos limitados como ocurre en el desarrollo del Widget de Cita Mdica, ya que en estos casos interesa liberar al dispositivo de toda la carga computacional que sea posible.

48

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

(una web API) que se encarga de proporcionar contenido a las distintas vistas del Widget de Cita Mdica a lo largo del proceso de peticin de cita en InterS@S. La forma de realizar una peticin a un recurso web con el objeto XMLHttpRequest puede resumirse en los siguientes pasos: 1. Se crea una nueva instancia de XMLHttpRequest.
var xhr = new XMLHttpRequest();

2. Se prepara la llamada al recurso web con el mtodo open.


xhr.open("POST", url, true);

El primer parmetro es el mtodo que se usar en la peticin, que puede ser GET o POST. En el mtodo GET los parmetros de la peticin se pasan en la URL de la peticin mientras que en el mtodo POST se incluyen en el cuerpo de la misma. Por motivos de seguridad, en el Widget de Cita Mdica todas las llamadas se realizan con el mtodo POST. De esta forma los parmetros de la peticin no viajarn expuestos en la url. El segundo parmetro es una cadena con la URL del recurso al que estamos llamando (en el Widget de Cita Mdica sera la url del archivo php alojado en el servidor intermedio que contiene el cdigo del servicio web correspondiente). La opcin "true" indica que la llamada es asncrona y que, por tanto, el cdigo del widget seguir ejecutndose mientras no llegue la respuesta. Un valor "false" en este tercer parmetro, que recibe el nombre de asynchronous flag, se correspondera con una llamada sncrona, en la que el cdigo deja de ejecutarse al enviar la llamada, quedando a la espera de una respuesta. Para validar un widget y hacerlo pblico en su Galera de widgets, Yahoo! exige que todas las llamadas que se realicen sean asncronas, directriz que se ha seguido en el desarrollo del Widget de Cita Mdica. 3. Se programa la captura de la respuesta:
xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { log("!!!!!!!!!!La peticin xhr se complet http: "+xhr.status); var respuesta=xhr.responseText; ... KONtx.application.setNetworkRequestFailed(false); } else { log("!!!!!!!!!!La peticin xhr fall http: "+xhr.status); KONtx.application.setNetworkRequestFailed(true); } } };

49

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Para saber si la respuesta est lista, el cdigo anterior comprueba la propiedad readyState del objeto xhr, la cual refleja en todo momento en qu punto de su ciclo de vida se encuentra la llamada. Tras instanciar el objeto XHR su valor es 0. Despus de llamar al mtodo open pasa a ser 1. El ciclo de vida de la llamada contina hasta que la respuesta del servidor es recibida completamente, momento en el cual el valor de la propiedad readyState pasa a ser 4. Hay que esperar a tener un readyState de 4 para obtener la respuesta del servidor, algo que se comprueba cada vez que se produce el evento readystatechange (cada vez que readyState cambia de valor). Es posible, tal como se hace en el cdigo de ejemplo, declarar una funcin callback en la propiedad onreadystatechange de XMLHttpRequest. Esta funcin se encargar bsicamente de comprobar que la respuesta ha llegado completamente (readyState=4) y que el cdigo HTTP de la misma es 200 (respuesta estndar para peticiones HTTP exitosas). De esta forma no slo nos aseguramos de que se ha recibido completamente la respuesta sino que adems tenemos constancia de que el servidor ha logrado procesar correctamente la peticin. En caso de que la comprobacin sea positiva, se recupera la respuesta del servidor con ayuda de la propiedad responseText y se realizan las acciones oportunas. 4. Se enva la peticin al servidor llamando al mtodo send() de XHR.
xhr.send(params);

El argumento que se pasa al mtodo send() es un string con los parmetros que se enviarn por POST. En caso de que la llamada se realizase por el mtodo GET se pasara el objeto null como argumento. Una posible inicializacin de la variable params antes de llamar al mtodo send() podra ser:
var params="param1=1&param2=2"

Es posible realizar las llamadas escribiendo las lneas de cdigo descritas cada vez que lo necesitemos, no obstante, en el Widget de Cita Mdica se ha optado por implementar una funcin que encapsula estos pasos y algunos otros relacionados con el manejo de los estados de red y que se describen en el siguiente apartado.

50

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

6.2.4 Comprobacin del estado de la red antes de las peticiones XHR Los widgets de TV deben detectar los cambios producidos en la disponibilidad de la red y dar soporte tanto al funcionamiento en modo online como en modo offline de forma adecuada. Para conseguirlo es necesario realizar una comprobacin del estado de red antes de cada llamada a un recurso web basada en el objeto XMLHttpRequest. Un widget no debe nunca iniciar una peticin XHR cuando la red fsica est cada. En el Widget de Cita Mdica se ha cumplimentado este requisito por medio del mtodo KONtx.application.isPhysicalNetworkDown(). Dentro del archivo Content>Javascript>core>API.js del Widget de Cita Mdica se encuentra la siguiente funcin encargada de implementar las peticiones al servidor intermedio a travs del objeto XMLHttpRequest:
function funcion_xmlhttprequest(o){ if (KONtx.application.isPhysicalNetworkDown()) { KONtx.utility.WaitIndicator.off(); log("Network down, no se permiten peticiones xhr!"); return; } var xhr = new XMLHttpRequest(); xhr.autoRedirect = true; xhr.open(o.metodo, o.url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { log("!!!!!!!!!!!!!!La peticin xhr tuvo xito http: "+xhr.status); o.success(xhr); KONtx.application.setNetworkRequestFailed(false); } else { log("!!!!!!!!!!!!!!La peticin xhr fall http: "+xhr.status); o.error(); KONtx.application.setNetworkRequestFailed(true); } } }; xhr.send(o.params); }

Si se revisa el cdigo de la funcin anterior comprobamos que, antes de crear el nuevo objeto XMLHttpRequest y para comprobar que la red fsica est funcionando, se llama al mtodo KONtx.application.isPhysicalNetworkDown(). Esto plantea una dificultad, y es que esta funcin no est presente en versiones antiguas del KONtx Framework. Para que el Widget de Cita Mdica mantenga compatibilidad hacia atrs se ha incluido el siguiente parche en el archivo init.js: 51

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

//En primer lugar comprobamos que existe la funcin y si no es as la definimos if (typeof KONtx.application.isPhysicalNetworkDown === "undefined") { (function () { var original = KONtx.application.setNetworkRequestFailed, setDownByUser = false; delete KONtx.application.setNetworkRequestFailed; KONtx.application.setNetworkRequestFailed = function (status) { original(status); setDownByUser = status; }; KONtx.application.isPhysicalNetworkDown = function () { if (KONtx.application.getNetworkDownStatus) { return !setDownByUser; } return false; }; }()); }

El archivo API.js se incluye en el cdigo del widget con la siguiente lnea de cdigo del archivo init.js:
include("Javascript/core/API.js");

De esta forma, cada vez que desde el widget se realiza una peticin al servidor intermedio se instancia un objeto usando notacin literal de objetos. Este objeto contiene las propiedades de la peticin y se pasa como parmetro a la funcin funcion_xmlhttprequest(o). A continuacin se cita un ejemplo extrado del Widget de Cita Mdica:
peticion1={ metodo:"POST", url:'http://www.s414468704.mialojamiento.es/proyecto/servidor_intermedio5.php', params:'id_us='+nuss+'&dia='+dia+'&mes='+mes+'&anio='+anio+'&dni='+dni+'&origen= 1', success: function(requestObj){ /*al no usar var delante de datosjson2 nos estamos refiriendo a la variable global datosjson2*/ datosjson_web=requestObj.responseText; datosjson=datosjson_web.split("SEPARADOR"); /*En el primer JSON van los datos de la cita existente previamente o los que hay que pasar a la siguiente llamada, adems de los das, para obtener las horas disponibles. Lo guardamos en Objeto0.*/ Objeto0 = JSON.parse(datosjson[0]); Objeto1 = JSON.parse(datosjson[1]); /*Comprobamos que no hay una cita ya asignada*/ if (Objeto0.enlace_cancelar=="no hay cita que cancelar"){ /*Comprobamos que hemos conseguido ingresar a InterS@S*/ if (Objeto0.comprueba_acceso=="ok"){ KONtx.messages.store ('cookies_sesion', Objeto0.sesion); KONtx.messages.store ('tipocita', Objeto0.tipocita); KONtx.messages.store ('actividad_agenda', Objeto0.actividad_agenda); KONtx.messages.store ('modalidad_agenda', Objeto0.modalidad_agenda);

52

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

KONtx.messages.store ('codigo_agenda', Objeto0.codigo_agenda); KONtx.messages.store ('codigo_profesional', Objeto0.codigo_profesional ); KONtx.messages.store ('domicilio_usuario', Objeto0.domicilio_usuario); KONtx.messages.store ('nuss_usuario', Objeto0.nuss_usuario); KONtx.messages.store ('nombre_usuario', Objeto0.nombre_usuario); KONtx.messages.store ('telefonos_usuario', Objeto0.telefonos_usuario); KONtx.messages.store ('desplazado', Objeto0.desplazado); KONtx.messages.store ('tarea_desc', Objeto0.tarea_desc); KONtx.messages.store ('centro_desc', Objeto0.centro_desc); KONtx.messages.store ('centro_codigo', Objeto0.centro_codigo); KONtx.messages.store ('nombre_profesional', Objeto0.nombre_profesional); KONtx.messages.store ('Objeto0', Objeto0); KONtx.messages.store ('Objeto1', Objeto1); /*Ponemos flag a 1 para que en la vista mostrarDias se busquen las horas disponibles.*/ KONtx.messages.store ('flag', '1'); KONtx.application.loadView('view-MostrarDias',null,false); } else{ KONtx.utility.WaitIndicator.off(); KONtx.messages.store ('informacion', Objeto0.comprueba_acceso); /*El tercer parmetro del mtodo loadView() es "Boolean noSaveCurrentViewInHistory". Si no se pone el tercer parmetro por defecto es false. Si lo ponemos a true no se guardar la vista actual en la historia (No volvemos a esta vista al seleccionar el backbutton en la vista que estamos cargando).*/ KONtx.application.loadView('view-InformacionError',null,true); } } //Por el contrario, si hay una cita asignada previamente else{ KONtx.utility.WaitIndicator.off(); KONtx.messages.store ('cookies_sesion', Objeto0.sesion); KONtx.messages.store ('enlace_cancelar', Objeto0.enlace_cancelar); KONtx.messages.store('fecha_cita',Objeto0.fecha_cita); KONtx.messages.store('hora_cita',Objeto0.hora_cita); KONtx.messages.store('orden',Objeto0.orden); KONtx.messages.store('centro',Objeto0.centro); KONtx.messages.store('direccion',Objeto0.direccion); KONtx.messages.store('ubicacion',Objeto0.ubicacion); KONtx.messages.store('profesional',Objeto0.profesional); KONtx.messages.store('nombre_usuario',Objeto0.nombre_usuario); KONtx.messages.store('fecha_solicitud',Objeto0.fecha_solicitud); KONtx.application.loadView('view-CitaAsignada'); } }, error: function(){ KONtx.utility.WaitIndicator.off(); log("Error en la conexin"); } }

Una vez definido el objeto peticion1 ya slo hay que pasarlo como parmetro de la funcin funcion_xmlhttprequest(o), la cual se encargar de la instanciacin del objeto xhr y de comprobar el estado de la red antes de realizar la llamada.
funcion_xmlhttprequest(peticion1); KONtx.utility.WaitIndicator.up();

53

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Tras llamar a la funcin se llama al mtodo KONtx.utility.WaitIndicator.up()que se encarga de mostrar la animacin de espera, la cual se mantendr hasta que se reciba la respuesta del servidor y se realicen las acciones oportunas segn dicha respuesta. Es la funcin funcion_xmlhttprequest(o) la que se encarga de gestionar los estados de la red en cada llamada por lo que, una vez definida dicha funcin, basta con llamarla cada vez que se quiera hacer una peticin al servidor intermedio. Cuando la peticin falla es el propio cdigo de funcion_xmlhttprequest(o) el que llama al mtodo KONtx.application.setNetworkRequestFailed (true), mtodo que se encarga de mostrar un dilogo de alerta y sacar al widget de la vista lateral en la que nos encontremos para volver al dock, adems de mostrar iconos informativos de NoNetwork.

Ilustracin 21: Dilogo de alerta e icono informativo del estado NoNetwork.

En el caso del Widget de Cita Mdica, no obstante, se planteaba el problema de que, una vez que una peticin fallaba y desde funcion_xmlhttprequest(o) se llamaba a KONtx.application.setNetworkRequestFailed (true), an en el caso de que hubiese desaparecido la causa que en un principio haba provocado el fracaso en la peticin, el widget no consegua recuperarse del estado de NoNetwork. La causa es que el Widget de Cita Mdica no realiza ninguna peticin XMLHttpRequest en su vista principal (la que se carga al lanzar el widget desde su Snippet en el dock) ya que el usuario debe primero introducir sus datos o elegir un usuario de la vista de Usuarios Guardados, por lo que no exista llamada a KONtx.application.setNetworkRequestFailed(false) y nunca se llegaba a salir del estado de NoNetwork. En consecuencia, al lanzar el widget desde el 54

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

dock se desplegaba la vista lateral principal pero inmediatamente se mostraba el dilogo de alerta para volver al dock tras seleccionar el botn aceptar. Para solucionar este inconveniente se ha optado por realizar llamadas XHR a un archivo php de contenido trivial al dispararse los eventos OnApplicationStartup y OnActivateSnippet, con la finalidad de comprobar el estado de la red cuando se inicia la plataforma y cuando se activa el Snippet. La forma de conseguir esto es suscribir el widget a dichos eventos del Host haciendo uso del mtodo subscribeTo(), adems de definir los manejadores de eventos asociados a los mismos. El cdigo utilizado, que se encuentra en el archivo init.js, es el siguiente:
//Definimos el objeto peticion0 peticion0={ metodo:"POST", url:'http://www.s414468704.mialojamiento.es/proyecto/holamundo.php', params:"param1=1&param2=2", success: function(requestObj){ var datosjson =requestObj.responseText; log(datosjson); var Objeto = JSON.parse(datosjson); log ("Comprobando red en onApplicationStartup: "+Objeto.mensaje); }, error: function(){ log("Error en la conexin"); } }; var EventHandlers = (function () { return { //Definicin de la funcin callback para el evento OnApplicationStartup onApplicationStartup: function () { //Peticin al servidor intermedio para comprobar el estado de la conexin funcion_xmlhttprequest(peticion0); }, onActivateSnippet:function () { funcion_xmlhttprequest(peticion0); } } }()); EventHandlers.onApplicationStartup.subscribeTo(KONtx.application, "onApplicationStartup", EventHandlers); EventHandlers.onActivateSnippet.subscribeTo(KONtx.application, "onActivateSnippet", EventHandlers);

55

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

El testeo en el caso de estado de red "desconectado" es parte del QA13 del widget y del proceso de aprobacin de Yahoo! previo a la inclusin de dicho widget en la Galera de Widgets en entornos de produccin. En este sentido, hay que asegurarse de que el widget se comporta adecuadamente en los siguientes estados de "desconexin": 1. Prdida de conectividad manteniendo la direccin IP. Para probar esta situacin basta con desconectar el cable WAN del router, testear el comportamiento del widget, volver a conectar el cable y testear de nuevo. 2. Prdida de conectividad y prdida de la direccin IP. Para probar esta situacin basta con desconectar el cable LAN del router, testear el comportamiento del widget, volver a conectar el cable y testear de nuevo. Durante la fase de desarrollo del Widget de Cita Mdica se teste el comportamiento del widget deteniendo y reiniciando un servidor proxy instalado para este propsito en la mquina virtual que alberga al simulador. El servidor proxy elegido fue Polipo. Para instalar Polipo se abri una ventana de consola y se escribi:
sudo apt-get install polipo

A continuacin se especific el valor de la variable de entorno KF_PROXY en el archivo $HOME/TVWidgets/Konfabulator.env incluyendo la siguiente lnea:
KF_PROXY=http://localhost:8123 Konfabulator

De esta forma, cada vez que se lanzaba el simulador ste se conectaba a la red travs de Polipo. Para iniciar y detener Polipo durante las pruebas se utilizaron los siguientes comandos:
sudo /etc/init.d/polipo start sudo /etc/init.d/polipo stop

6.2.5 JSON Parser La respuesta del servidor intermedio es siempre un string que contiene datos en formato JSON. Como ya se ha comentado, el formato JSON es muy adecuado para ser consumido por una aplicacin JavaScript.

13

QA: Quality Assurance. En espaol puede traducirse como certificacin de la calidad.

56

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Al ser JSON un subconjunto de la notacin literal de objetos de JavaScript los datos en este formato pueden convertirse en objetos JavaScript simplemente pasndolos como argumento a la funcin eval(). La funcin eval() de JavaScript es muy rpida, pero puede compilar y ejecutar cualquier programa JavaScript, lo que acarrea problemas de seguridad. Para defenderse de posibles amenazas se debe usar un analizador JSON en lugar de eval(). El Widget Engine de Yahoo! Connected TV pone a disposicin del desarrollador de widgets un analizador JSON. Este analizador JSON es entre tres y cuatro veces ms rpido que la versin JavaScript y est presente en todos los widgets por defecto, por lo que no es necesario ningn paso previo para utilizarlo. La interfaz JSON del Widget Engine es la siguiente:
interface JSON { variant parse( string inString ); string stringify( variant inValue ); };

Los mtodos son los mismos que los del analizador JavaScript, excepto que no existen parmetros adicionales. Otra diferencia respecto al analizador JavaScript es que el analizador JSON del Widget Engine no utiliza la funcin toJSON(). Existe una instancia global de la clase llamada JSON, por lo que su uso es igual que el del analizador JavaScript. Por ejemplo:
var v = JSON.parse(inString); var s = JSON.stringify(inValue);

El analizador es estricto, no usa expresiones regulares y respeta la gramtica de JSON descrita en <http://www.json.org/> con la salvedad de que acepta comillas simples o dobles tal como ocurre en el estndar JavaScript. En el Widget de Cita Mdica se usa el analizador JSON del Widget Engine en mltiples ocasiones para convertir en objetos JavaScript los datos en formato JSON procedentes del servidor intermedio. Un ejemplo puede ser el siguiente fragmento de cdigo extraido de CitaAsignada.js, archivo en el que se implementa la clase VistaCitaAsignada:
var datosjson=requestObj.responseText; /*Usamos el analizador JSON sobre los datos obtenidos*/ var Objeto = JSON.parse(datosjson); KONtx.messages.store('informacion',Objeto.informacion); KONtx.application.setNetworkRequestFailed(false); /*Para que una vez borrada la cita no podamos volver a esta vista con el backButton, pasamos el valor true en el tercer parmetro del mtodo loadView()*/

57

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA


KONtx.application.loadView('view-Informacion',null,true);

Proyecto Fin de Carrera Mara Len Bujes

6.2.6 Gestin de usuarios guardados y almacenamiento persistente Hay tres tipos de almacenamiento disponibles para perfiles y widgets:
Store currentAppConfig: Almacena datos para el widget nicamente. Los datos

almacenados no cambian si se cambia de perfil, pero son diferentes en cada widget.


Store currentAppData: Almacena datos asociados con el widget y el perfil. Los

datos almacenados aqu son diferentes en cada perfil y en cada widget.


Store currentProfileData: Almacena datos para un perfil nicamente. Los

datos son privados para un perfil, pero estn disponibles para todos los widgets y pueden ser sobrescritos por otro widget si se utiliza la misma clave. Los widgets y los perfiles pueden almacenar cadenas JSON. Por tanto, si se quiere almacenar un objeto JavaScript se pasa antes como parmetro del mtodo JSON.stringify(). Si por el contrario lo que se quiere es recuperar un valor almacenado habr que hacer uso del mtodo JSON.parse() para obtener de nuevo el objeto JavaScript. La informacin almacenada en el objeto persistente se mantiene despus de salir del widget, lanzar otro widget o cambiar de perfil ya que el almacenamiento es independiente del ciclo de vida del widget. Slo la desistalacin del widget borra todos los datos asociados al widget. De igual forma borrar un perfil elimina todos los datos asociados a dicho perfil. Cada elemento en el objeto Store es un par clave-valor. Cada instancia del objeto Store es un conjunto de pares clave-valor con una estructura open-ended, es decir, que permite su extensin en cualquier momento sin modificar los datos existentes. El modelo de datos puede describirse como una coleccin de pares "clave,valor" en formato texto. Las claves son nicas slo en cada objeto Store. Los mtodos disponibles son los mismos para los tres tipos de almacenamiento: Boolean delete (String key) Borra el par clave-valor especificado por key. El parmetro key es una cadena de texto que identifica de manera nica el par que debe borrarse. Devuelve true si la operacin se completa con xito o si no se encuentra la clave key. String get (String key) Devuelve el valor del par clave-valor cuya clave es key. Devuelve null si la clave no existe en el objeto Store.

58

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Array getIDs() Devuelve un array de cadenas que contiene todas las claves existentes para el objeto. Si no existe ninguna clave, el mtodo devuelve un array vaco.

Boolean set (String key, String value) Establece un valor asociado con una clave nica. El parmetro key es la cadena que servir de clave nica y que se asociar a la cadena value, el valor almacenado. Como se mencion anteriormente, si el valor es un objeto JavaScript antes de usar el mtodo set() previamente habra que llamar a JSON.stringify() para convertirlo en una cadena JSON.

Este almacenamiento persistente ofrecido por la plataforma es la base del cdigo que permite al usuario del Widget de Cita Mdica ingresar al sistema seleccionando su nombre de la lista de usuarios guardados que ofrece la vista correspondiente.

Ilustracin 22: Vista view-MostrarUsuarios.

Los datos de un usuario se almacenan en el objeto currentAppConfig en el momento en el que dicho usuario ha completado con xito una consulta o una peticin de cita. As se evita la posibilidad de almacenar en el widget datos errneos. Para evitar duplicidades, antes de almacenar los datos del usuario se comprueba si dichos datos ya se guardaron en una ocasin anterior. Asimismo, el ltimo usuario que completa con xito una peticin o consulta de cita aparecer automticamente en el lugar ms alto en la vista de usuarios guardados. El fragmento de cdigo que se cita a continuacin, y que forma parte del mtodo updateview() de la clase VistaCitaAsignada (definida en el archivo 59

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

VistaCitaAsignada.js) del Widget de Cita Mdica, implementa toda la funcionalidad descrita anteriormente.
//Guardamos el usuario para el que se ha pedido o consultado cita con xito. var matrizclaves=currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; log(numerousuarios); var coincidencia=0; if (numerousuarios>0){ for (i=1;i<=numerousuarios;i++){ eval("var datosusuario"+i+"=currentAppConfig.get('usuario"+i+"');"); eval("var auxiliar=JSON.parse(datosusuario"+i+");"); if (auxiliar.nuss==KONtx.messages.fetch('nuss')){ coincidencia=i;} } if (coincidencia>0){ /*Este switch podra sustituirse por una expresin ms compacta usando otro bucle for y el valor de la variable coincidencia*/ log("HAY COINCIDENCIA!!"); switch (coincidencia){ case 1: break; case 2: currentAppConfig.set('usuario2',datosusuario1); break; case 3: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); break; case 4: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); break; case 5: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); currentAppConfig.set('usuario5',datosusuario4); break; case 6: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); currentAppConfig.set('usuario5',datosusuario4); currentAppConfig.set('usuario6',datosusuario5); break; case 7: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); currentAppConfig.set('usuario5',datosusuario4); currentAppConfig.set('usuario6',datosusuario5); currentAppConfig.set('usuario7',datosusuario6); break; default: /*Esto no ocurrir nunca porque ya hemos comprobado que hay coincidencia (coincidencia>0)*/ } }

60

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

/*Si el usuario no ha sido guardado previamente se desplazan todas las cadenas json guardadas (datos de usuarios previos) una posicin dentro de los datos persistentes.*/ else{ for (i=numerousuarios;i>0;i--){ j=i+1; eval("currentAppConfig.set('usuario"+j+"',datosusuario"+i+");"); } if (numerousuarios==7){ currentAppConfig.delete('usuario8'); } } } /*Creamos el objeto datosusuarionuevo. Con dos replace y dos expresiones regulares eliminamos los espacios del principio y del final de la cadena.*/ var nombre = KONtx.messages.fetch('nombre_usuario').replace(/^\s+/g,'').replace(/\s+$/g,''); /*Almacenamos los datos del nuevo usuario asociados a la clave 'usuario1'*/ var usuariojson="{'nombre' : '"+nombre+"', 'nuss': '" +KONtx.messages.fetch('nuss')+ "', 'dia': '" +KONtx.messages.fetch('dia')+ "', 'mes': '" +KONtx.messages.fetch('mes')+ "', 'anio': '" +KONtx.messages.fetch('anio')+ "', 'dni': '" +KONtx.messages.fetch('dni')+ "'}"; log(usuariojson); //comprobamos que estamos obteniendo la cadena esperada /*Guardamos los datos del usuario en formato json asociados a la clave "usuario1" (el ltimo usuario ser el que aparezca en el primer botn de usuarios guardados). currentAppConfig.set() devuelve true si se consigue realizar la operacin con xito.*/ funciona=currentAppConfig.set("usuario1", usuariojson); /*Si el mtodo set se ejecut con xito la siguiente lnea muestra FUNCIONA=true en la consola de comandos.*/ log("FUNCIONA="+funciona); /*Las siguientes lneas muestran en consola el string en formato json que guardamos en usuariojson. As comprobamos que se almacenan los datos que necesitamos.*/ prueba2=currentAppConfig.get("usuario1"); log(prueba2); /*Borramos la "ViewHistory" para que si se pulsa el botn volver vayamos a la vista principal que es lo que nos interesa*/ KONtx.application.clearViewHistory();

Al usar el objeto currentAppConfig los usuarios guardados se asocian al widget pero son independientes del perfil. Para que los usuarios guardados fuesen diferentes en funcin del perfil bastara con sustituir currentAppConfig por currentAppData. Se ha explicado cmo se guarda un usuario en el almacenamiento persistente del widget, pero tambin es necesario algo de cdigo para extraer los datos almacenados y mostrar el nombre de cada usuario guardado en la vista view-MostrarUsuarios. Desde esta vista el usuario puede seleccionar uno de los usuarios guardados, evitndose as la molestia de 61

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

tener que volver a introducir todos sus datos de nuevo para pedir una cita. El fragmento de cdigo que se cita a continuacin es el encargado de esta funcionalidad del widget y se encuentra en el archivo VistaMostrarUsuarios.js, en la definicin del mtodo updateview() de la clase VistaMostrarUsuarios.
updateView: function() { this.controls.botonusuario1.hide(); this.controls.botonusuario2.hide(); this.controls.botonusuario3.hide(); this.controls.botonusuario4.hide(); this.controls.botonusuario5.hide(); this.controls.botonusuario6.hide(); this.controls.botonusuario7.hide(); var matrizclaves = currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; for (i=numerousuarios;i>0;i--){ eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); datosusuario=JSON.parse(datosusuariojson); eval("this.controls.botonusuario"+i+".setText(datosusuario.nombre);"); eval("this.controls.botonusuario"+i+".show();"); } }

Como puede apreciarse, en un primer momento y haciendo uso del mtodo hide(), se ocultan todos los botones que se haban incluido en la vista en la llamada al mtodo createview(). Tras esto se entra en un bucle for que en cada iteracin extrae del objeto currentAppConfig los datos (en formato JSON) del usuario correspondiente, los convierte en objeto JavaScript con ayuda de JSON.parse(), escribe el nombre del usuario en el botn adecuado y, finalmente, muestra dicho botn usando el mtodo show(). Esto ocurre hasta que el contador, inicializado con el nmero de usuarios, alcanza el valor 0. De esta forma se consigue que el usuario vea tantos botones en la vista como usuarios hay guardados en currentAppConfig. La vista view-MostrarUsuarios incluye, adems, un botn para gestionar usuarios guardados que, al ser seleccionado, hace que se cargue la vista view-BorrarUsuario. Esta vista muestra de nuevo los usuarios guardados pero al seleccionar uno de ellos lo que hacemos en este caso es borrar sus datos de currentAppConfig. El cdigo encargado de esta accin es el que se encuentra en la funcin callback del evento onSelect de cada botn. A modo de ejemplo, se incluye a continuacin el cdigo del botn correspondiente al usuario1 almacenado en currentAppConfig.
this.controls.botonusuario1 = new KONtx.control.TextButton({ label: 'Usuario1', guid: "botonusuario1", styles: { vOffset: this.controls.texto0.outerHeight+20, },

62

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA


events: { onSelect: function(event) { var matrizclaves = currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; if (numerousuarios>1){

Proyecto Fin de Carrera Mara Len Bujes

for (i=2;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView();//auxiliar representa a la vista actual } else{ eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); KONtx.application.addViewConfig({ id: 'view-SinUsuarios', viewClass: VistaSinUsuarios }); KONtx.application.loadView('view-SinUsuarios'); } } } }).appendTo(this);

Ilustracin 23: Vista view-BorrarUsuario.

63

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

6.3 Web API en el servidor intermedio (PHP) 6.3.1 Peticiones al servidor de InterS@S con libcurl Libcurl es una librera creada por Daniel Stenberg que permite conectar y comunicarse con servidores utilizando diferentes tipos de protocolos. Actualmente libcurl soporta los protocolos HTTP, HTTPS, FTP, FTPS, Gopher, Telnet, DICT, FILE, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet y TFTP. Libcurl tambin soporta certificados SSL, HTTP POST, HTTP PUT, subida de ficheros usando FTP (tambin se puede hacer con la extensin FTP de PHP), formularios HTTP, proxies, cookies, y autenticaciones usuario+contrasea. A continuacin se describir la forma en que la librera se utiliza en la web API a la que realiza sus peticiones el Widget de Cita Mdica. PHP incorpora libcurl a partir de su versin 4.0.2. Por ello, el cdigo de la web API funcionar en cualquier servidor con una versin de PHP instalada igual o posterior. La inicializacin de una sesin cURL se realiza de la siguiente forma:
$curl = curl_init();

Tras la inicializacin ya podemos especificar todas las opciones de la sesin cURL. La primera opcin de la sesin especifica la url de destino:
curl_setopt ($curl, CURLOPT_URL, $url);

Para obtener el resultado en una cadena de texto se asigna un 1 en la opcin CURLOPT_RETURNTRANSFER de libcurl.
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);

Tambin es necesario especificar el contenido de la cabecera "User-Agent: " que se utilizar en la peticin HTTP:
curl_setopt ($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1');

Si queremos que la respuesta incluya la cabecera HTTP:


curl_setopt ($curl, CURLOPT_HEADER, 1);

Aunque normalmente libcurl detecta de forma automtica la versin SSL instalada en el servidor al que se realiza la peticin, en el caso del servidor de InterS@S result

64

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

imprescindible especificar dicha versin como SSL 3.0 para que la peticin se completara con xito.
curl_setopt ($curl, CURLOPT_SSLVERSION, 3);

Con la siguiente opcin se comprueba que el certificado de servidor es vlido. Esto equivale a comprobar que la CA (Autoridad Certificadora) que lo firma est entre la CA reconocidas.
curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, true);

Para que la comprobacin del certificado que hace libcurl fuera positiva hubo que seguir una serie de pasos. Como el certificado de servidor de InterS@S est firmado por la Fbrica Nacional de Moneda y Timbre fue necesario descargarse su certificado raiz (FNMTClase2CA-FNMT.crt), exportarlo como certificado X.509 con cadena (PEM), y subirlo al servidor intermedio. A continuacin se especific la ruta de este certificado raiz en la siguiente opcin de libcurl que sirve para especificar el certificado raiz de la CA que firma el certificado de servidor al que estamos tratando de acceder va HTTPS.
curl_setopt ($curl, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt');

Con la siguiente opcin se especifica que hay que comprobar el common name (CN) del certificado de servidor:
curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, 2);

Habilitamos el paso de parmetros por POST:


curl_setopt ($curl, CURLOPT_POST, 1);

La variable $campos es la que contiene los parmetros de la peticin a InterS@S que son enviados haciendo uso del mtodo POST:
curl_setopt ($curl, CURLOPT_POSTFIELDS, $campos);

Una vez especificadas todas las opciones de libcurl que necesitamos, podemos ejecutar la sesin CURL.
$codigofuente = curl_exec ($curl);

En el ejemplo la respuesta se almacena en la variable $codigofuente, tras lo cual se procedera a su anlisis. En todo momento, antes de abrir una sesin cURL nueva se ha tomado la precaucin de cerrar la sesin anterior.
curl_close ($curl);

65

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

6.3.2 Mantenimiento de la ses in Uno de los puntos ms delicados a la hora implementar con xito el Widget de Cita Mdica era el mantenimiento de la sesin en el servidor de InterS@S en las sucesivas peticiones que se le haran desde el servidor intermedio. La solucin pasa por extraer la cookie de sesin de la cabecera de la primera respuesta del servidor de InterS@S y enviarla al widget como un dato ms dentro de la estructura de datos JSON. Este dato deber ser reenviado por el widget en cada una de las peticiones al servidor intermedio de tal modo que con dicho dato pueda especificarse la opcin CURLOPT_COOKIE de la peticin de libcurl al servidor de InterS@S.
curl_setopt($curl3, CURLOPT_COOKIE, $cookies_sesion);

La variable $cookies_sesion contendr las cookies obtenidas tras el anlisis de la cabecera HTTP de la peticin libcurl anterior o bien es uno de los parmetros pasados por POST desde el widget. Una cookie, tambin llamada HTTP cookie, web cookie, o browser cookie, sirve para el envo de informacin de estado desde un servidor al navegador del usuario y para devolver la informacin de estado al servidor original. La informacin de estado puede ser usada para autenticacin, identificacin de una sesin de usuario, preferencias de usuario, contenidos de un carrito de la compra y, en definitiva, para cualquier cosa que pueda lograrse a travs del almacenamiento de datos en formato texto en la computadora del usuario. Las cookies forman parte de la cabecera HTTP enviadas al cliente por el servidor web precediendo al contenido de la pgina solicitada. Las cookies dentro de la cabecera HTTP van precedidas de la directiva Set-Cookie. A continuacin aparece el name=value de la cookie que el servidor quiere que almacene el navegador. Tras un ";" pueden aparecer una serie de atributos de la cookie. Segn se ha explicado, la cabecera HTTP enviada por un servidor cualquiera tiene una estructura similar a la del siguiente ejemplo:
HTTP/1.1 200 OK Set-Cookie: name=value Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT Content-type: text/html; charset=UTF-8 (contenido de la pgina)

Lo que interesa para poder establecer la opcin CURLOPT_COOKIE de la siguiente peticin CURL que se realice, y mantener de esta forma la sesin, son los pares name=value de dicha cabecera.

66

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

El cdigo empleado en el archivo servidorintermedio5.php de la web API del Widget de Cita Mdica para obtener las cookies de sesin a partir de la respuesta en formato texto del servidor es el que se cita a continuacin. En l se analiza $codigofuente2 (respuesta del servidor de InterS@S tras ejecutar las sesin $curl2) para quedarnos con las cookies que aparecen en su cabecera HTTP.
$start = strpos($codigofuente2, "Set-Cookie"); $end = strpos($codigofuente2, "Content-Type"); $parts = split("Set-Cookie: ",substr($codigofuente2, $start, $end-$start)); $cookies = array(); foreach ($parts as $co){ $cd = split(";",$co); if (!empty($cd[0])) /*Se aade un elemento a la matriz de tamao indeterminado $cookies[]*/ $cookies[] = $cd[0]; } $cookies_sesion=implode(";",$cookies);

Finalmente, como ya se ha comentado, una vez que tenemos $cookies_sesion slo resta especificar la opcin CURLOPT_COOKIE en la siguiente sesin CURL ($curl3):
curl_setopt($curl3, CURLOPT_COOKIE, $cookies_sesion);

Cabe sealar que libcurl tiene una opcin que permite guardar de forma automtica las cookies enviadas en respuesta a una peticin en un archivo del servidor creado a tal efecto, pero no se logr que esta tcnica funcionase en el hosting en el que se encuentra la web API del Widget de Cita Mdica, por lo que se decidi implementar esta solucin alternativa. 6.3.3 Parseando la respuesta: HTML DOM parser De todo el documento HTML que obtenemos al ejecutar una sesin CURL en el servidor intermedio, slo nos van a interesar ciertos datos, que sern los que finalmente se codificarn en formato JSON para ser consumidos por el Widget de Cita Mdica. Existen varias formas de realizar este anlisis de la respuesta del servidor de InterS@S. Se pueden usar expresiones regulares combinadas con funciones PHP de manipulacin de cadenas (como explode, implode, y otras) pero todas estas soluciones requieren mucho cdigo para obtener un simple dato y son susceptibles de presentar problemas con determinados carcteres. Para evitar estos inconvenientes, en el Widget de Cita Mdica se opt por recurrir a una librera PHP que permite manipular HTML de manera muy sencilla y que result ser la solucin ideal. El nombre de la librera en cuestin es Simple HTML Dom parser, y con ella se pueden buscar etiquetas usando selectores como en jQuery y extraer su contenido.

67

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Simple HTML DOM parser est escrita en PHP 5+ y para usarla simplemente hay que descargarla de <http://sourceforge.net/projects/simplehtmldom/files/> y despus incluirla en nuestro desarrollo, tal como se hace con cualquier otra librera. No est limitada nicamente a HTML vlido, en el sentido de que puede trabajar con cdigo HTML que no ha pasado la validacin W3C, y con ella es posible encontrar elementos por ids, classes, etiquetas, etc. Una vez incluida, ya es posible crear un nuevo objeto DOM:
$html = new simple_html_dom();

Tras esto, ya es posible cargar HTML en dicho objeto, ya sea desde una URL, desde una cadena, o desde un archivo. En el caso que nos ocupa la carga se ha realizado siempre desde la cadena de texto obtenida al ejecutar una sesin CURL.
$html->load($codigofuente);

A continuacin podemos buscar el contenido o las propiedades de las etiquetas que nos interesen. El siguiente es un ejemplo extrado de servidorintemedio5.php:
$matrizdatos['enlace_cancelar']=$html->find('a[class=enlace_cancelar_cita]',0)>href;

Como puede apreciarse es posible encontrar elementos utilizando selectores y elegir el atributo de ese elemento que nos interesa. Adems de los atributos normales, como podra ser el caso del atributo href de un ancla, existen cuatro atributos especiales que seran: tag: devuelve el nombre de la etiqueta. innertext: devuelve el contenido HTML de un elemento. outertext: devuelve el HTML exterior a un elemento. plaintext: devuelve texto plano (sin etiquetas HTML).

En servidorintermedio5.php se utiliza el atributo especial innertext. A continuacin se cita un ejemplo de este uso:
$matrizdatos['fecha_solicitud']=utf8_encode($html>find('span[class=letra_pequena_fecha]',0)->innertext);

Simple HTML DOM parser es una poderosa herramienta. No obstante, a la hora de usarla, hay que tener cuidado con cierto derroche de memoria que puede producir en el servidor y 68

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

que puede ocasionar que se ralentice, o incluso que deje de funcionar unos minutos, si se cargan demasiados objetos DOM simultneamente. Es por ello que al escribir el cdigo de la web API alojada en el servidor intermedio se ha tenido especial cuidado en eliminar cada objeto DOM antes de cargar uno nuevo, haciendo uso del mtodo clear():
$html->clear();

6.3.4 Produccin de una cadena JSON : json_enconde() En el apartado 6.3 se explicaron las bondades del formato JSON a la hora de ser consumido por una aplicacin escrita en JavaScript. Para crear una cadena que exprese un objeto u otro tipo de variable en formato JSON, en PHP se dispone de una funcin nativa llamada json_encode(), que recibe lo que deseamos convertir en notacin JSON y devuelve una cadena de texto con el JSON producido. La funcin json_encode() permite convertir a JSON cualquier cosa que necesitemos, ya sea una cadena, una variable numrica, un array -normal o asociativo- u objetos con todo tipo de datos dentro. Centrndonos en el caso de la web API alojada en el servidor intermedio a la que realiza peticiones el Widget de Cita Mdica, la produccin de la cadena JSON se realiza a partir de los datos obtenidos de InterS@S y es implementada de la siguiente forma: 1. Los datos que nos interesan (extraidos de la respuesta del servidor de InterS@S con ayuda de la librera Simple HTML DOM parser) son almacenados en un array asociativo. 2. El array asociativo resultante se pasa como parmetro a la funcin json_encode(). 3. Se ejecuta print($json) donde $json es el valor devuelto por la funcin json_encode($array) en el paso anterior. Hay ejemplos del proceso anterior en prcticamente todos los archivos de la web API alojada en el servidor intermedio (ver Anexo II).

69

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

7. Seguridad de los datos en el Widget de Cita Mdica


Una modificacin que habra que realizar de forma obligada en el Widget de Cita Mdica, antes de su uso en entornos de produccin, es la ubicacin de la web API en un servidor con certificado SSL y la realizacin de todas las peticiones del widget usando el protocolo HTTPS. El protocolo criptogrfico SSL se utiliza en todas las comunicaciones entre el servidor intermedio y el servidor de InterS@S, pero slo con esto no se garantiza la confidencialidad de los datos que maneja el widget. En efecto, el protocolo SSL tambin debe utilizarse en las comunicaciones entre el Widget de Cita Mdica y el servidor intermedio. Para poder realizar desde un widget peticiones HTTPS, en las que el contenido viaje por Internet debidamente encriptado, es necesario que el servidor al que se conecta (en este caso el servidor intermedio) cuente con un certificado de servidor firmado por una CA cuyo certificado raz se encuentre incluido en la lista de certificados raz del televisor. Esta lista se mantiene en el firmware del televisor por lo que no se actualiza frecuentemente. Por tanto, el servidor intermedio (que aloja los servicios web consumidos por el Widget de Cita Mdica) debe tener un certificado de servidor firmado por una de las autoridades certificadoras incluidas por defecto en la mayor parte de los navegadores (autoridades entre las que, de hecho, no se encuentra la Fabrica Nacional de Moneda y Timbre) ya que son las que, en definitiva, con mayor probabilidad, tendrn su certificado raz incluido en el firmware de los televisores. La imposibilidad de usar un certificado autofirmado ha provocado que durante la fase de desarrollo del Widget de Cita Mdica no se use el protocolo HTTPS en las comunicaciones entre el widget y el servidor intermedio. No obstante, y por razones obvias, al enviarse informacin sensible a dicho servidor desde el widget, en un entorno de produccin sera imprescindible contar con un certificado firmado por una autoridad de certificacin cuyo certificado raz est presente en el firmware de la mayor parte de los televisores Connected TV a los que estara destinado el Widget de Cita Mdica. Sera necesario, por tanto, un certificado de servidor firmado por una CA como Geotrust, VeriSign, RSA Secure Server AC, AT&T, Thawte, etc. Gracias al sistema de clave pblica y privada proporcionado por el certificado de servidor la clave simetrica con la que se encripta el todo el trfico es intercambiada con una altsima garanta de confidencialidad. De esta forma se garantiza que la informacin que viaja entre el widget y el servidor intermedio lo hace codificada con una clave simtrica compartida nicamente por cliente y servidor.

70

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Otra opcin posible para mejorar la confidencialidad de las comunicaciones con coste cero (sin pagar por un certificado de servidor) es encriptar la informacin intercambiada usando una clave simtrica, alojada tanto en el servidor como en el widget. Pero el nivel de seguridad de este sistema ser siempre muy inferior al que se obtiene por medio del protocolo SSL, en el cual cliente y servidor intercambian en cada nueva sesin una clave simtrica generada de forma aleatoria.

71

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

8. Posibles ampliaciones y mejoras


Entre las posibles mejoras del Widget de Cita Mdica hay una bastante sencilla de implementar que consiste en permitir al usuario identificarse con un documento identificativo distinto al D.N.I., una posibilidad que contempla la aplicacin de InterS@S. Para lograrlo bastara con modificar la vista en la que el usuario introduce sus datos incluyendo un men desplegable con los distintos tipos de documentos con los que es posible identificarse (D.N.I., pasaporte, tarjeta de extranjero y otros) y pasar el par nombre/valor correspondiente (type=1, type=2, type=3 o type=4) como un parmetro ms enviado por POST en la peticin a servidorintemedio5.php. Evidentemente tambin habra que hacer los cambios pertinentes en las funciones de validacin de los datos introducidos. Otra posible mejora estara relacionada con el mantenimiento de la aplicacin. En efecto, una hipottica modificacin realizada ahora mismo en la aplicacin web que gestiona la peticin de cita mdica en InterS@S podra afectar al funcionamiento del Widget de Cita Mdica, por lo que cualquier accin en este sentido debera acompaarse de una actualizacin de los servicios web alojados en el servidor intermedio, de forma que las modificaciones en InterS@S no afectasen al correcto funcionamiento del widget instalado en los televisores. Esta dependencia podra eliminarse programando los servicios web alojados en el servidor intermedio para que atacasen directamente a las bases de datos de la aplicacin de InterS@S, en lugar de limitarse a realizar peticiones a la aplicacin web y a analizar el HTML obtenido como respuesta. No obstante, el desarrollo de este servicio web exigira tener acceso a las bases de datos del SAS y escapaba al mbito del presente proyecto, por lo que no se contempl como una opcin posible. Por ltimo tamben sera interesante implementar un recordatorio de "cita prxima". Este recordatorio podra mostrarse en el snippet del widget el da anterior a la fecha en la que el usuario tiene una cita asignada.

72

DESARROLLO DE UN WIDGET DE YAHOO! PARA TV PARA LA SOLICITUD DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

9. Bibliografa
BABIN, Lee. Introduccin a AJAX con PHP. Madrid: Anaya Multimedia, D.L. 2007. SUEHRING, Steve. JavaScript: paso a paso. Madrid : Anaya Multimedia, 2008. OPPLIGER, Rolf. SSL and TLS: theory and practice. Boston: Artech House, c2009. Yahoo! Developer Network. Yahoo! Widget Engine TV Widgets Release Notes. 2011. Disponible en: <http://developer.yahoo.com/connectedtv/releasenotes/> Yahoo! Developer Network. Yahoo! Connected TV Installation Guide. 2012. Disponible en: <http://developer.yahoo.com/connectedtv/installguide/> Yahoo! Developer Network. Yahoo! Connected TV Quick Start. 2011. Disponible en: <http://developer.yahoo.com/connectedtv/quickstart/> Yahoo! Developer Network. Yahoo! Connected TV Developer Guide. 2011. Disponible en: <http://developer.yahoo.com/connectedtv/devguide/ > Yahoo! Developer Network. Yahoo! Connected TV KONtx Framework API Reference. 2010. Disponible en: <http://developer.yahoo.com/connectedtv/kontxapi/> BEDA, Benito. Apuntes de Sistemas embebidos. 2009. Disponible en: <http://ocw.um.es/ingenierias/sistemas-embebidos/material-de-clase-1/ssee-t01.pdf> CHEN, S.C. PHP Simple HTML DOM Parser. Manual. Disponible en: <http://simplehtmldom.sourceforge.net/manual.htm/> cURL. libcurl - the multiprotocol file transfer library. 2011. Disponible en: <http://curl.haxx.se/libcurl/> PHP Team. cURL Functions. 2011. Disponible en: <http://es2.php.net/manual/en/ref.curl.php> IETF. Best Current Practice 47. Tags for Identifying Languages. 2009. Disponible en: <http://tools.ietf.org/html/bcp47> ECMA. Standard ECMA-262. ECMAScript Language Specification. 2011. Disponible en: <http://www.ecma-international.org/publications/standards/Ecma-262.htm>

73

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Anexo I
A continuacin se reproduce ntegramente el cdigo JavaScript y XML incluido en los distintos archivos creados durante el desarrollo del Widget de Cita Mdica. Archivo MainView.js:
var MainView = new KONtx.Class({ ClassName: 'MyCustomMainView', Extends: KONtx.system.SidebarView, createView: function() { var cabecera = new KONtx.control.Header({ label: "Acceso al sistema", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ data: "Bienvenido al widget de peticin de Cita Mdica en el SAS.", wrap:true, styles: { vOffset: cabecera.outerHeight+20, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto1 = new KONtx.element.Text({ data: "Tiene dos formas para ingresar al sistema:", wrap:true, styles: { vOffset: this.controls.texto0.outerHeight+10, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto2 = new KONtx.element.Text({ data: "1) Introduciendo todos los datos requeridos (nmero de la SS, fecha de nacimiento y DNI).", wrap:true, styles: { vOffset: this.controls.texto1.outerHeight+10, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto3 = new KONtx.element.Text({

74

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


data: "2) Escogiendo alguno de los usuarios guardados.", wrap:true, styles: { vOffset: this.controls.texto2.outerHeight+10, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.button1 = new KONtx.control.TextButton({ label: 'Introducir datos', guid: "button0", styles: { vOffset: this.controls.texto3.outerHeight+20, }, events: { onSelect: function(event) { KONtx.application.loadView('view-IntroducirDatos'); } } }).appendTo(this); this.controls.button2 = new KONtx.control.TextButton({

Proyecto Fin de Carrera Mara Len Bujes

label: 'Usuarios guardados', guid: "button1", styles: { vOffset: this.controls.button1.outerHeight, }, events: { onSelect: function(event) { var datosguardados =currentAppConfig.getIDs(); if (datosguardados.length>0){ KONtx.application.addViewConfig({ id: 'view-MostrarUsuarios', viewClass: VistaMostrarUsuarios }); KONtx.application.loadView('view-MostrarUsuarios'); } else{ KONtx.application.addViewConfig({ id: 'view-SinUsuarios', viewClass: VistaSinUsuarios }); KONtx.application.loadView('view-SinUsuarios'); } } } }).appendTo(this); var emptySpaceTop = new KONtx.control.EmptySpace({ styles: { vOffset: this.controls.button2.outerHeight, //height: KONtx.utility.scale(15), height: this.height-this.controls.button2.outerHeight } }).appendTo(this); }, updateView: function() { } });

75

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo SnippetView.js:
var SnippetView = new KONtx.Class({ ClassName: 'MyCustomSnippetView', Extends: KONtx.system.SnippetView, createView: function() { this.controls.anchor_image = new KONtx.element.Image({ src:"image/960x540/snippet-main-540.png" }).appendTo(this); /***********************************/ this.controls.apptitle = new KONtx.element.Text({ label: this.config.data.message1, styles: { hOffset: KONtx.utility.scale(10), vOffset: KONtx.utility.scale(16), fontSize: KONtx.utility.scale(12), color: '#AAAAAA' } }).appendTo(this); /************************************/ this.controls.message2 = new KONtx.element.Text({ label: this.config.data.message2, styles: { hOffset: KONtx.utility.scale(18), vOffset: KONtx.utility.scale(30), fontSize: KONtx.utility.scale(18), color: '#FFFFFF' } }).appendTo(this); this.controls.message3 = new KONtx.element.Text({ label: this.config.data.message3, styles: { hOffset: KONtx.utility.scale(18), vOffset: KONtx.utility.scale(55), fontSize: KONtx.utility.scale(11), color: '#FFFFFF' } }).appendTo(this); }, updateView: function() { } });

76

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaBorrarUsuario.js:
var VistaBorrarUsuario = new KONtx.Class({ ClassName: 'MiVistaBorrarUsuario', Extends: KONtx.system.SidebarView, createView: function() { auxiliar=this; this.controls.backButton = new KONtx.control.BackButton({ label:'Borrar usuario guardado', guid: "back_button", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ data: "Escoja el usuario que desee BORRAR. El usuario seleccionado desaparecer de la lista de usuarios guardados.", wrap:true, styles: { vOffset: this.controls.backButton.outerHeight+20, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.botonusuario1 = new KONtx.control.TextButton({ label: 'Usuario1', guid: "botonusuario1", styles: { vOffset: this.controls.texto0.outerHeight+20, }, events: { onSelect: function(event) { var matrizclaves = currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; if (numerousuarios>1){ for (i=2;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } else{

77

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); KONtx.application.addViewConfig({ id: 'view-SinUsuarios', viewClass: VistaSinUsuarios }); KONtx.application.loadView('view-SinUsuarios'); } } } }).appendTo(this); this.controls.botonusuario1.hide(); this.controls.botonusuario2 = new KONtx.control.TextButton({ label: 'Usuario2', guid: "botonusuario2", styles: { vOffset: this.controls.botonusuario1.outerHeight, }, events: { onSelect: function(event) { var matrizclaves = currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; if (numerousuarios>2){ for (i=3;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } else{ eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } } } }).appendTo(this); this.controls.botonusuario2.hide(); this.controls.botonusuario3 = new KONtx.control.TextButton({ label: 'Usuario3', guid: "botonusuario3", styles: { vOffset: this.controls.botonusuario2.outerHeight, }, events: { onSelect: function(event) { var matrizclaves = currentAppConfig.getIDs();

78

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


var numerousuarios=matrizclaves.length; if (numerousuarios>3){

Proyecto Fin de Carrera Mara Len Bujes

for (i=4;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } else{ eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } } } }).appendTo(this); this.controls.botonusuario3.hide(); this.controls.botonusuario4 = new KONtx.control.TextButton({ label: 'Usuario4', guid: "botonusuario4", styles: { vOffset: this.controls.botonusuario3.outerHeight, }, events: { onSelect: function(event) { var matrizclaves = currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; if (numerousuarios>4){ for (i=5;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } else{ eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } } } }).appendTo(this); this.controls.botonusuario4.hide();

79

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

this.controls.botonusuario5 = new KONtx.control.TextButton({ label: 'Usuario5', guid: "botonusuario5", styles: { vOffset: this.controls.botonusuario4.outerHeight, }, events: { onSelect: function(event) { if (numerousuarios>5){ for (i=6;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } else{ eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } } } }).appendTo(this); this.controls.botonusuario5.hide(); this.controls.botonusuario6 = new KONtx.control.TextButton({ label: 'Usuario6', guid: "botonusuario6", styles: { vOffset: this.controls.botonusuario5.outerHeight, }, events: { onSelect: function(event) { if (numerousuarios>6){ for (i=7;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } else{

80

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } } } }).appendTo(this); this.controls.botonusuario6.hide(); this.controls.botonusuario7 = new KONtx.control.TextButton({ label: 'Usuario7', guid: "botonusuario7", styles: { vOffset: this.controls.botonusuario6.outerHeight, }, events: { onSelect: function(event) { if (numerousuarios>7){ for (i=8;i<=numerousuarios;i++){ var datosusuariojson; log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log (datosusuariojson); var j=i-1; log("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); eval("currentAppConfig.set('usuario"+j+"',datosusuariojson);"); } log("currentAppConfig.delete('usuario"+numerousuarios+"');"); eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } else{ eval("currentAppConfig.delete('usuario"+numerousuarios+"');"); auxiliar.updateView(); } } } }).appendTo(this); this.controls.botonusuario7.hide(); var botonterminar = new KONtx.control.TextButton({ label: 'Terminar', guid: "botonterminar", styles: { vOffset: this.controls.botonusuario7.outerHeight+40, }, events: { onSelect: function(event) { KONtx.application.loadView('view-Main'); } } }).appendTo(this); }, updateView: function() {

81

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


this.controls.botonusuario1.hide(); this.controls.botonusuario2.hide(); this.controls.botonusuario3.hide(); this.controls.botonusuario4.hide(); this.controls.botonusuario5.hide(); this.controls.botonusuario6.hide(); this.controls.botonusuario7.hide(); var matrizclaves = currentAppConfig.getIDs();

Proyecto Fin de Carrera Mara Len Bujes

var numerousuarios=matrizclaves.length; log(numerousuarios); for (i=numerousuarios;i>0;i--){ log("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); log(datosusuariojson); //convertimos en objeto el json guardado en 'usuarioi' datosusuario=JSON.parse(datosusuariojson); //comprobamos: log(datosusuario.dni);//Muestra el nmero del dni correspondiente por consola eval("this.controls.botonusuario"+i+".setText(datosusuario.nombre);"); eval("this.controls.botonusuario"+i+".show();"); } } });

82

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaCitaAsignada.js
var VistaCitaAsignada = new KONtx.Class({ ClassName: 'MiVistaCitaAsignada', Extends: KONtx.system.SidebarView, createView: function() { function acciones_cancelar() { if (requestObj.readyState == 4) { if (requestObj.status==200) { KONtx.utility.WaitIndicator.off(); //dentro de la funcin onreadyStateChange this representa a requestObj (instancia del objeto XMLHttprequest) log("requestObj.readyState: " +this.readyState+" requestObj.status: "+this.status); datosjson=requestObj.responseText; log(datosjson); Objeto = JSON.parse(datosjson); KONtx.messages.store('informacion',Objeto.informacion); KONtx.application.setNetworkRequestFailed(false); //Para que una vez borrada la cita no podamos volver a esta vista con el backButton, establecemos a true el tercer parmetro del mtodo loadView() KONtx.application.loadView('view-Informacion',null,true); } else{ KONtx.utility.WaitIndicator.off(); log("La peticin xmlhttprequest ha fallado."); /*Dilogo de NoNetwork, exit al dock y se muestran los iconos de noNetwork.*/ KONtx.application.setNetworkRequestFailed(true); } } } //Creamos el botn volver this.controls.backButton = new KONtx.control.BackButton({ label:'Cita Asignada', guid: "back_button", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ label: "Usuario: ", truncation:'center', styles: { vOffset: this.controls.backButton.outerHeight+20, vAlign: 'top', fontSize: KONtx.utility.scale(16), width: this.width, color: '#FFFFFF' } }).appendTo(this); this.controls.texto1 = new KONtx.element.Text({

83

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


label: "Da: ", styles: { vOffset: this.controls.texto0.outerHeight, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto2 = new KONtx.element.Text({ label: "Hora: ", styles: { vOffset: this.controls.texto1.outerHeight, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto3 = new KONtx.element.Text({ label: "Orden: ", styles: { vOffset: this.controls.texto2.outerHeight, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto4 = new KONtx.element.Text({ label: "Doctor/a: ", truncation:"center", styles: { vOffset: this.controls.texto3.outerHeight+10, vAlign: 'top', width:this.width, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto5 = new KONtx.element.Text({ label: "Ubicacin: ", truncation:"center", styles: { vOffset: this.controls.texto4.outerHeight, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto6 = new KONtx.element.Text({ data: "Centro: ",

Proyecto Fin de Carrera Mara Len Bujes

84

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


truncation:"center", styles: { vOffset: this.controls.texto5.outerHeight, width:this.width, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.texto7 = new KONtx.element.Text({ data: "Fecha de solicitud: ", styles: { vOffset: this.controls.texto6.outerHeight+20, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.terminar = new KONtx.control.TextButton({ label: 'Terminar', guid: "botoncancelar", styles: { vOffset: this.controls.texto7.outerHeight+20, }, events: { onSelect: function(event) { KONtx.application.loadView('view-Main'); } } }).appendTo(this); var alerta= new KONtx.dialogs.Alert({ title: 'Confirme la cancelacin', message: 'Va usted a cancelar la cita. Est seguro?', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'S. Cancelar la cita', callback: function(){ KONtx.utility.WaitIndicator.on(); if (KONtx.application.isPhysicalNetworkDown()) {

Proyecto Fin de Carrera Mara Len Bujes

KONtx.utility.WaitIndicator.off(); log("Network down, no se permiten peticiones xhr!"); return; } requestObj = new XMLHttpRequest(); var urlcancelar='http:// www.s414468704.mialojamiento.es/proyecto/cancelacion_de_cita.php'; var enlace_cancelar=KONtx.messages.fetch('enlace_cancelar'); var matriz_enlacecancelar=enlace_cancelar.split("&amp;"); var params = 'cookies_sesion='+KONtx.messages.fetch('cookies_sesion')+'&enlace_can celar0='+matriz_enlacecancelar[0]+'&hora_inicio='+KONtx.messages.fetc h('hora_cita')+'&fecha='+KONtx.messages.fetch('fecha_cita')+'&nombre_ usuario='+KONtx.messages.fetch('nombre_usuario'); requestObj.autoRedirect = true; requestObj.onreadystatechange = acciones_cancelar; requestObj.open('POST',urlcancelar,true); requestObj.send(params); } },

85

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


{ ] }); this.controls.botoncancelar = new KONtx.control.TextButton({ label: 'Cancelar la cita', guid: "botoncancelar", styles: { vOffset: this.controls.terminar.outerHeight, }, events: { onSelect: function(event) { alerta.show(); } } }).appendTo(this); }, updateView: function() { // cdigo de actualizacin de la vista: label: 'No. Volver atrs.'}

Proyecto Fin de Carrera Mara Len Bujes

var fecha_solicitud=KONtx.messages.fetch('fecha_solicitud'); fecha_solicitud=fecha_solicitud.replace("&nbsp;",""); var fecha_solicitud_final=fecha_solicitud.replace("a travs de InterS@S",""); this.controls.texto0.setText("Usuario: "+KONtx.messages.fetch('nombre_usuario')); this.controls.texto1.setText("Da: "+KONtx.messages.fetch('fecha_cita')); this.controls.texto2.setText("Hora: "+KONtx.messages.fetch('hora_cita')); this.controls.texto3.setText("Orden: "+KONtx.messages.fetch('orden')); this.controls.texto4.setText("Doctor/a: "+KONtx.messages.fetch('profesional')); this.controls.texto5.setText("Ubicacin: "+KONtx.messages.fetch('ubicacion')); this.controls.texto6.setText("Centro: "+KONtx.messages.fetch('centro')); this.controls.texto7.setText(fecha_solicitud_final); //Guardamos el usuario para el que se ha pedido o consultado cita con xito var matrizclaves=currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; log(numerousuarios); var coincidencia=0; if (numerousuarios>0){ for (i=1;i<=numerousuarios;i++){ eval("var datosusuario"+i+"=currentAppConfig.get('usuario"+i+"');"); eval("var auxiliar=JSON.parse(datosusuario"+i+");"); log(auxiliar.nuss); if (auxiliar.nuss==KONtx.messages.fetch('nuss')){ coincidencia=i; } } if (coincidencia>0){ //Este switch podra sustituirse por una expresin ms compacta usando otro bucle for y el valor de la variable coincidencia log("HAY COINCIDENCIAAAAAAAAAAA!!"); switch (coincidencia){ case 1: break; case 2: currentAppConfig.set('usuario2',datosusuario1); break; case 3: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2);

86

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

break; case 4: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); break; case 5: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); currentAppConfig.set('usuario5',datosusuario4); break; case 6: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); currentAppConfig.set('usuario5',datosusuario4); currentAppConfig.set('usuario6',datosusuario5); break; case 7: currentAppConfig.set('usuario2',datosusuario1); currentAppConfig.set('usuario3',datosusuario2); currentAppConfig.set('usuario4',datosusuario3); currentAppConfig.set('usuario5',datosusuario4); currentAppConfig.set('usuario6',datosusuario5); currentAppConfig.set('usuario7',datosusuario6); break; default: /*Esto no ocurrir nunca porque ya hemos comprobado que hay coincidencia (coincidencia>0)*/ } } //Si el usuario no ha sido guardado previamente se desplazan todos json guardados (datos de usuarios previos) una posicin dentro de los datos persistentes. else{ for (i=numerousuarios;i>0;i--){ j=i+1; eval("currentAppConfig.set('usuario"+j+"',datosusuario"+i+");"); } if (numerousuarios==7){ currentAppConfig.delete('usuario8'); } } } //creamos el objeto datosusuarionuevo var nombre = KONtx.messages.fetch('nombre_usuario').replace(/^\s+/g,'').replace(/\s+$/g,''); //con los dos replace y las expresiones regulares eliminamos los espacios del principio y del final de la cadena. /* var nuss = KONtx.messages.fetch('nuss'); var dia = KONtx.messages.fetch('dia'); var mes = KONtx.messages.fetch('mes'); var anio = KONtx.messages.fetch('anio'); var dni = KONtx.messages.fetch('dni');*/ //Almacenamos los datos del nuevo usuario en formato json asociados a la clave 'usuario1' var usuariojson="{'nombre' : '"+nombre+"', 'nuss': '"+KONtx.messages.fetch('nuss')+"', 'dia': '"+KONtx.messages.fetch('dia')+"', 'mes': '"+KONtx.messages.fetch('mes')+"', 'anio': '"+KONtx.messages.fetch('anio')+"', 'dni': '"+KONtx.messages.fetch('dni')+"'}";

87

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


log(usuariojson);

Proyecto Fin de Carrera Mara Len Bujes

/*Guardamos los datos del usuario (en formato json) asociados a la clave "usuario1" (el ltimo usuario ser el que aparezca en el primer botn de usuarios guardados). El mtodo currentAppConfig.set() devuelve true si se consigue realizar la operacin con xito.*/ funciona=currentAppConfig.set("usuario1", usuariojson); /*El siguiente log muestra FFFFUNCIONA=true en la consola de comandos si el mtodo set se ejecuto con xito.*/ log("FFFFUNCIONA="+funciona); prueba2=currentAppConfig.get("usuario1"); /*El siguiente log muestra el string json que guardamos en usuariojson. As comprobamos que se almacena lo que queremos.*/ log(prueba2); //Borramos la historia de las vistas KONtx.application.clearViewHistory(); } });

88

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaEsperar.js
var VistaEsperar = new KONtx.Class({ ClassName: 'MiVistaEsperar', Extends: KONtx.system.SidebarView, createView: function() { /*Cargamos todos los datos que necesitamos y que almacenamos en la vista MostrarHoras dentro del cdigo correspondiente al evento OnSelect para cada uno de los botones*/ //Creamos el botn volver: this.controls.backButton = new KONtx.control.BackButton({ label:'Espere', guid: "back_button", }).appendTo(this); var contenedor= new KONtx.element.Container ({ styles: { width: this.width, height: this.height-this.controls.backButton.outerHeight, vOffset: this.controls.backButton.outerHeight, hAlign: 'center', //backgroundColor: 'red' } }).appendTo(this); this.controls.texto1 = new KONtx.element.Text({ data: "Buscando citas disponibles...", styles: { vOffset: this.controls.backButton.outerHeight*6, vAlign: 'top', hAlign: 'center', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(contenedor); this.controls.texto2 = new KONtx.element.Text({ data: "Espere, por favor", styles: { vOffset: this.controls.texto1.outerHeight, vAlign: 'top', hAlign: 'center', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(contenedor); }, updateView: function() { var auxiliar=this; //Recogemos los valores introducidos en la vista IntroducirDatos var nuss=KONtx.messages.fetch('nuss'); var dia=KONtx.messages.fetch('dia');

89

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


var mes=KONtx.messages.fetch('mes'); var anio=KONtx.messages.fetch('anio'); var dni=KONtx.messages.fetch('dni');

Proyecto Fin de Carrera Mara Len Bujes

/*Definimos el objeto peticion usando notacin literal de objetos y llamamos a funcion_xmlhttprequest() pasndole como argumento ese objeto peticion.*/ peticion1={ metodo:"POST", url:'http:// www.s414468704.mialojamiento.es/proyecto/servidor_intermedio5.php', params:'id_us='+nuss+'&dia='+dia+'&mes='+mes+'&anio='+anio+'&dni='+dni+'&orig en=1', success: function(requestObj){ log("requestObj.readyState: "+requestObj.readyState+" requestObj.status: "+this.status); datosjson_web=requestObj.responseText; log (datosjson_web); datosjson=datosjson_web.split("SEPARADOR"); /*En el primer JSON van los datos de la cita existente previamente o los que hay que pasar a la siguiente llamada, junto con los das, para obtener las horas disponibles. Lo guardamos en Objeto0.*/ Objeto0 = JSON.parse(datosjson[0]); Objeto1 = JSON.parse(datosjson[1]); if (Objeto0.enlace_cancelar=="no hay cita que cancelar"){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan para obtener las horas disponibles cada da.*/ if (Objeto0.comprueba_acceso=="ok"){ KONtx.messages.store ('cookies_sesion', Objeto0.sesion); KONtx.messages.store ('tipocita', Objeto0.tipocita); KONtx.messages.store ('actividad_agenda', Objeto0.actividad_agenda); KONtx.messages.store ('modalidad_agenda', Objeto0.modalidad_agenda); KONtx.messages.store ('codigo_agenda', Objeto0.codigo_agenda); KONtx.messages.store ('codigo_profesional', Objeto0.codigo_profesional); KONtx.messages.store ('domicilio_usuario', Objeto0.domicilio_usuario); KONtx.messages.store ('nuss_usuario', Objeto0.nuss_usuario); KONtx.messages.store ('nombre_usuario', Objeto0.nombre_usuario); KONtx.messages.store ('telefonos_usuario', Objeto0.telefonos_usuario); KONtx.messages.store ('desplazado', Objeto0.desplazado); KONtx.messages.store ('tarea_desc', Objeto0.tarea_desc); KONtx.messages.store ('centro_desc', Objeto0.centro_desc); KONtx.messages.store ('centro_codigo', Objeto0.centro_codigo); KONtx.messages.store ('nombre_profesional', Objeto0.nombre_profesional); KONtx.messages.store ('Objeto0', Objeto0); KONtx.messages.store ('Objeto1', Objeto1); /*Ponemos flag a 1 para que en la vista mostrarDias se busquen las horas disponibles.*/ KONtx.messages.store ('flag', '1'); KONtx.application.loadView('view-MostrarDias',null,false); }

90

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

else{ KONtx.utility.WaitIndicator.off(); KONtx.messages.store ('informacion', Objeto0.comprueba_acceso); /*El tercer parmetro del mtodo loadView() es "Boolean noSaveCurrentViewInHistory". Si no se pone el tercer parmetro por defecto es false. Si lo ponemos a true no se guardar la vista actual en la historia (No volvemos a esta vista al seleccionar el backbutton en la vista que estamos cargando).*/ KONtx.application.loadView('view-InformacionError',null,true); } } //Por el contrario, si hay una cita asignada previamente else{ KONtx.utility.WaitIndicator.off(); KONtx.messages.store ('cookies_sesion', Objeto0.sesion); KONtx.messages.store ('enlace_cancelar', Objeto0.enlace_cancelar); KONtx.messages.store('fecha_cita',Objeto0.fecha_cita); KONtx.messages.store('hora_cita',Objeto0.hora_cita); KONtx.messages.store('orden',Objeto0.orden); KONtx.messages.store('centro',Objeto0.centro); KONtx.messages.store('direccion',Objeto0.direccion); KONtx.messages.store('ubicacion',Objeto0.ubicacion); KONtx.messages.store('profesional',Objeto0.profesional); KONtx.messages.store('nombre_usuario',Objeto0.nombre_usuario); KONtx.messages.store('fecha_solicitud',Objeto0.fecha_solicitud); KONtx.application.loadView('view-CitaAsignada'); } }, error: function(){ KONtx.utility.WaitIndicator.off(); log("Error en la conexin"); } } funcion_xmlhttprequest(peticion1); KONtx.utility.WaitIndicator.up(); } });

91

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaInformacion.js
var VistaInformacion = new KONtx.Class({ ClassName: 'MiVistaInformacion', Extends: KONtx.system.SidebarView, createView: function() { this.controls.backButton = new KONtx.control.BackButton({ label:'Informacin', guid: "back_button", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ totalLines:2, wrap:true, styles: { vOffset: this.controls.backButton.outerHeight+20, hOffset: 5, vAlign: 'top', width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.botonotracita = new KONtx.control.TextButton({ label: 'Solicitar una nueva cita', guid: "botonotracita", styles: { vOffset: this.controls.texto0.outerHeight+40, }, events: { onSelect: function(event) { KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonotrousuario = new KONtx.control.TextButton({ label: 'Identificarse como un usuario diferente', guid: "botonotrousuario", styles: { vOffset: this.controls.botonotracita.outerHeight, }, events: { onSelect: function(event) { KONtx.application.loadView('view-Main'); } } }).appendTo(this); }, updateView: function() { //Cdigo de actualizacin de los contenidos de la vista. var informacion=KONtx.messages.fetch('informacion'); this.controls.texto0.setText(informacion); } });

92

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaInformacionError.js
var VistaInformacionError = new KONtx.Class({ ClassName: 'MiVistaInformacionError', Extends: KONtx.system.SidebarView, createView: function() { //Creamos el botn volver this.controls.backButton = new KONtx.control.BackButton({ label:'Informacin', guid: "back_button", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ totalLines:2, wrap:true, styles: { vOffset: this.controls.backButton.outerHeight+20, hOffset: 5, vAlign: 'top', width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.botonotrousuario = new KONtx.control.TextButton({ label: 'Identificarse de nuevo', guid: "botonotrousuario", styles: { vOffset: this.controls.texto0.outerHeight+40, }, events: { onSelect: function(event) { KONtx.application.loadView('view-Main'); } } }).appendTo(this); }, updateView: function() { //Cdigo de actualizacin de los contenidos de la vista. var informacion=KONtx.messages.fetch('informacion'); this.controls.texto0.setText(informacion); } });

93

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaIntroducirDatos.js
var VistaIntroducirDatos = new KONtx.Class({ ClassName: 'MiVistaIntroducirDatos', Extends: KONtx.system.SidebarView, createView: function() { var auxiliar2=this; this.controls.backButton = new KONtx.control.BackButton({ label:'Introduzca sus datos', guid: "back_button", }).appendTo(this); this.controls.numerodelass = new KONtx.element.Text({ label: 'Nmero de la Seguridad Social:', styles: { /*Ojo a los estilos, es muy importante que los elementos no se solapen. El elemento Text no se puede superponer al botn BackButton, o dar error.*/ vOffset: this.controls.backButton.outerHeight+20, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.numeross = new KONtx.control.TextEntryButton({ guid: 'nuss', label: 'Nmero ss', styles: { vOffset: this.controls.numerodelass.outerHeight }, keyboard: { controlSize: 'small', maxLength: 12, }, events: { onSubmit: function(event) { }, onCancel: function(event) { } } }).appendTo(this); this.controls.fecha = new KONtx.element.Text({ label: 'Fecha de nacimiento:', styles: { vOffset: this.controls.numeross.outerHeight+10, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.dia = new KONtx.control.TextEntryButton({ guid: 'dia', label: 'Da de nacimiento (Ejemplo: 4)', styles: { vOffset: this.controls.fecha.outerHeight },

94

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


keyboard:{ layout: 'pinentry', controlSize: 'small', maxLength: 2, }, events: { onSubmit: function(event) { }, onCancel: function(event) { } } }).appendTo(this); this.controls.mes = new KONtx.control.TextEntryButton({ guid: 'mes', label: 'Mes de nacimiento (Ejemplo: 12)', styles: { vOffset: this.controls.dia.outerHeight }, keyboard:{ layout: 'pinentry', controlSize: 'small', maxLength: 2, }, events: { onSubmit: function(event) { }, onCancel: function(event) { }, } }).appendTo(this); this.controls.anio = new KONtx.control.TextEntryButton({ guid: 'anio', label: 'Ao de nacimiento (Ejemplo:1983)', styles: { vOffset: this.controls.mes.outerHeight }, keyboard:{ layout: 'pinentry', controlSize: 'small', maxLength: 4, }, events: { onSubmit: function(event) { }, onCancel: function(event) { }, } }).appendTo(this); this.controls.numerodni = new KONtx.element.Text({ label: 'Nmero DNI (con la letra):', styles: { vOffset: this.controls.anio.outerHeight+10, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this);

Proyecto Fin de Carrera Mara Len Bujes

95

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


this.controls.dni = new KONtx.control.TextEntryButton({

Proyecto Fin de Carrera Mara Len Bujes

guid: 'dni', label: 'Nmero DNI (Ejemplo:28799995d)', styles: { vOffset: this.controls.numerodni.outerHeight }, keyboard:{ /* en este caso no especificamos layout: 'pinentry', ya que en este caso vamos a necesitar tambin letras para introducir el dni.*/ controlSize: 'small', maxLength: 9, }, events: { onSubmit: function(event) { }, onCancel: function(event) { }, } }).appendTo(this); this.controls.pedircita = new KONtx.control.TextButton({ label: 'Solicitar/Consultar Cita', guid: "pedircita", styles: { vOffset: this.height-this.controls.backButton.outerHeight, }, events: { onSelect: function(event) { minusculas=auxiliar2.controls.numeross.getValue(); KONtx.messages.store ('nuss', minusculas.toUpperCase()); KONtx.messages.store ('dia', auxiliar2.controls.dia.getValue()); KONtx.messages.store ('mes', auxiliar2.controls.mes.getValue()); KONtx.messages.store ('anio', auxiliar2.controls.anio.getValue()); KONtx.messages.store ('dni', auxiliar2.controls.dni.getValue()); /*A continuacin comprobamos que todos los campos (excepto el dni para menores de 14 aos) se han completado con valores vlidos y se muestra la alerta correspondiente en caso contrario.*/ var nuss=Quita_blancos(KONtx.messages.fetch('nuss')); var dia1=Quita_blancos(KONtx.messages.fetch('dia')); var mes1=Quita_blancos(KONtx.messages.fetch('mes')); var anio1=Quita_blancos(KONtx.messages.fetch('anio')); var dni=Quita_blancos(KONtx.messages.fetch('dni')); //Si todos los campos se han rellenado se carga la vista MostrarDias if(nuss==''){alerta1_1.show();} else{ if(dia1==''||mes1==''||anio1==''){alerta1_2.show();} else{ switch (validar_ss(nuss)){ case 1: alerta1_1.show();//Debe introducir nmero tarjeta sanitaria break; case 2: /*El nmero de la tarjeta sanitaria debe tener 12 dgitos*/ alerta2_1.show(); break; case 3: alerta2_2.show();//El nmero de la tarjeta sanitaria no es vlido break;

96

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


default:{ contenido=dia1+'/'+mes1+'/'+anio1; switch (comprueba_fecha(contenido)){

Proyecto Fin de Carrera Mara Len Bujes

case 1: //Carcter no vlido en la fecha de nacimiento alerta3.show(); break; case 2: //Fecha de nacimiento no vlida alerta4.show(); break; case 3: //Ao incorrecto en la fecha de nacimiento alerta5.show(); break; case 4: //Mes incorrecto en la fecha de nacimiento alerta6.show(); break; case 5: //Da incorrecto en la fecha de nacimiento alerta7.show(); break; default: //La fecha es correcta. Comprobamos el dni. if((dni=='')&&(mayor_edad(14,dia1,mes1,anio1)==true)) { alerta8.show();//Debe introducir su dni } else{ /*Se ha introducido el dni. Comprobamos que es correcto. El widget slo admite el dni, si permitisemos otros documentos esta comprobacin se realizara slo para el dni.*/ if (((nif(dni)==false)&&(mayor_edad(14,dia1,mes1,anio 1)==true))||((nif(dni)==false)&&(mayor_edad(14,dia 1,mes1,anio1)==false)&&(dni!=''))){ alerta9.show();//El dni introducido no es vlido } else{ KONtx.application.addViewConfig({ id: 'viewEsperar', viewClass: VistaEsperar }); KONtx.application.loadView('view-Esperar'); } } } } } } } } } }).appendTo(this); var alerta1_1= new KONtx.dialogs.Alert({ title: 'Datos incompletos', message: 'Debe introducir su nmero de la tarjeta sanitaria.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] });

97

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


var alerta1_2= new KONtx.dialogs.Alert({ title: 'Datos incompletos', message: 'Debe introducir su fecha de nacimiento.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] });

Proyecto Fin de Carrera Mara Len Bujes

var alerta2_1= new KONtx.dialogs.Alert({ title: 'Dato no vlido', message: 'El nmero de la tarjeta sanitaria debe tener 12 dgitos.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); var alerta2_2= new KONtx.dialogs.Alert({ title: 'Dato no vlido', message: 'El nmero de la tarjeta sanitaria no es vlido.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); var alerta2_3= new KONtx.dialogs.Alert({ title: 'Dato no vlido', message: 'El nmero de la tarjeta sanitaria no es vlido.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); /* Cambiando el layout del keyboard a 'pinentry' en los correspondientes TextEntrybutton evitamos que el usuario introduzca carcteres no vlidos en la fecha de nacimiento. No obstante, mantengo los dos alerts correspondientes a este caso.*/ var alerta3= new KONtx.dialogs.Alert({ title: 'Dato no vlido', message: 'Ha introducido un carcter no vlido en la fecha de nacimiento', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); var alerta4= new KONtx.dialogs.Alert({ title: 'Dato no vlido', message: 'Fecha de nacimiento no vlida.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); var alerta5= new KONtx.dialogs.Alert({ title: 'Datos no vlido', message: 'Ao incorrecto en la fecha de nacimiento.', focusOnCompletion: this.element.focusedView, buttons:[

98

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


{ ] }); var alerta6= new KONtx.dialogs.Alert({ title: 'Dato no vlido', message: 'Mes incorrecto en la fecha de nacimiento.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); var alerta7= new KONtx.dialogs.Alert({ title: 'Datos no vlido', message: 'Da incorrecto en la fecha de nacimiento.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); var alerta8= new KONtx.dialogs.Alert({ title: 'Datos incompletos', message: 'Debe introducir su DNI.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); var alerta9= new KONtx.dialogs.Alert({ title: 'Datos no vlido', message: 'El DNI introducido no es correcto.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] }); }, updateView: function() { label: 'Aceptar'}

Proyecto Fin de Carrera Mara Len Bujes

/* El siguiente fragmento de cdigo sirve para que aparezcan los campos rellenos con los datos del ltimo usuario para el que se pidi/consult cita. Est comentado porque finalmente incorpor una vista de usuarios guardados que permite tener a todos los usuarios (hasta un mximo de 7) almacenados de forma persistente. var matrizclaves = currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; if (numerousuarios>0){ var datosusuariojson=currentAppConfig.get('usuario1'); var datosusuario=JSON.parse(datosusuariojson); this.controls.numeross.setValue(datosusuario.nuss); this.controls.dia.setValue(datosusuario.dia); this.controls.mes.setValue(datosusuario.mes); this.controls.anio.setValue(datosusuario.anio); this.controls.dni.setValue(datosusuario.dni); } */ } });

99

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaMostrarDias.js
var VistaMostrarDias = new KONtx.Class({ ClassName: 'MiVistaMostrarDias', Extends: KONtx.system.SidebarView, createView: function() { //Creamos el botn volver this.controls.backButton = new KONtx.control.BackButton({ // label: this.config.data.mode == "edit" ? $_('edit_mode') : $_('insert_mode'), label:'Elija da', guid: "back_button", }).appendTo(this); //Lnea en blanco. this.controls.texto = new KONtx.element.Text({ data: " ", styles: { vOffset: this.controls.backButton.outerHeight, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); //Creamos los botones que representan cada uno de los das disponibles this.controls.botondia0 = new KONtx.control.TextButton({ label: Objeto1.dia0.cadena, guid: "dia0", styles: { vOffset: this.controls.texto.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_0.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita.*/ KONtx.messages.store ('numerohoras', Objeto3_0.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_0.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_0.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_0.profesional_agenda); Objeto4_0=KONtx.messages.fetch('Objeto4_0'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_0.numerohoras;i ++){ eval ('cadenahora = Objeto4_0.hora'+i+'.cadena'); eval ('valuehora = Objeto4_0.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); }

100

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

//Cargamos la vista Mostrarhoras KONtx.messages.store ('dia_elegido', Objeto1.dia0.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras0', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras0'); } //Si no hay citas disponibles para ese da se carga la vista viewOtroDia else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia1 = new KONtx.control.TextButton({ label: Objeto1.dia1.cadena, guid: "dia1", styles: { vOffset: this.controls.botondia0.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_1.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita*/ KONtx.messages.store ('numerohoras', Objeto3_1.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_1.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_1.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_1.profesional_agenda); Objeto4_1=KONtx.messages.fetch('Objeto4_1'); //Se guardan las horas en el centro de mensajes //for ( $i = 0 ; $i <= 66 ; $i ++) { for (i=0;i<Objeto3_1.numerohoras;i ++){ eval ('cadenahora = Objeto4_1.hora'+i+'.cadena'); eval ('valuehora = Objeto4_1.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia1.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras1', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras1'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this);

101

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


this.controls.botondia2 = new KONtx.control.TextButton({ label: Objeto1.dia2.cadena, guid: "dia2", styles: { vOffset: this.controls.botondia1.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{

Proyecto Fin de Carrera Mara Len Bujes

if (Objeto3_2.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita*/ KONtx.messages.store ('numerohoras', Objeto3_2.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_2.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_2.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_2.profesional_agenda); Objeto4_2=KONtx.messages.fetch('Objeto4_2'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_2.numerohoras;i ++){ eval ('cadenahora = Objeto4_2.hora'+i+'.cadena'); eval ('valuehora = Objeto4_2.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia2.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras2', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras2'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia3 = new KONtx.control.TextButton({ label: Objeto1.dia3.cadena, guid: "dia3", styles: { vOffset: this.controls.botondia2.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_3.numerohoras>0){

102

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

/*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita.*/ KONtx.messages.store ('numerohoras', Objeto3_3.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_3.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_3.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_3.profesional_agenda); Objeto4_3=KONtx.messages.fetch('Objeto4_3'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_3.numerohoras;i ++){ eval ('cadenahora = Objeto4_3.hora'+i+'.cadena'); eval ('valuehora = Objeto4_3.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia3.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras3', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras3'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia4 = new KONtx.control.TextButton({ label: Objeto1.dia4.cadena, guid: "dia4", styles: { vOffset: this.controls.botondia3.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_4.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita*/ KONtx.messages.store ('numerohoras', Objeto3_4.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_4.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_4.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_4.profesional_agenda); Objeto4_4=KONtx.messages.fetch('Objeto4_4'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_4.numerohoras;i ++){ eval ('cadenahora = Objeto4_4.hora'+i+'.cadena'); eval ('valuehora = Objeto4_4.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); }

103

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

//Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia4.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras4', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras4'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia5 = new KONtx.control.TextButton({ label: Objeto1.dia5.cadena, guid: "dia5", styles: { vOffset: this.controls.botondia4.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_5.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita*/ KONtx.messages.store ('numerohoras', Objeto3_5.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_5.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_5.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_5.profesional_agenda); Objeto4_5=KONtx.messages.fetch('Objeto4_5'); //Se guardan las horas en el centro de mensajes //for ( $i = 0 ; $i <= 66 ; $i ++) { for (i=0;i<Objeto3_5.numerohoras;i ++){ eval ('cadenahora = Objeto4_5.hora'+i+'.cadena'); eval ('valuehora = Objeto4_5.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia5.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras5', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras5'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia6 = new KONtx.control.TextButton({

104

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


label: Objeto1.dia6.cadena, guid: "dia6", styles: { vOffset: this.controls.botondia5.outerHeight, }, events: { onSelect: function(event) {

Proyecto Fin de Carrera Mara Len Bujes

if(flag2>0){ alerta.show(); } else{ if (Objeto3_6.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita*/ KONtx.messages.store ('numerohoras', Objeto3_6.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_6.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_6.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_6.profesional_agenda); Objeto4_6=KONtx.messages.fetch('Objeto4_6'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_6.numerohoras;i ++){ eval ('cadenahora = Objeto4_6.hora'+i+'.cadena'); eval ('valuehora = Objeto4_6.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia6.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras6', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras6'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia7 = new KONtx.control.TextButton({ label: Objeto1.dia7.cadena, guid: "dia7", styles: { vOffset: this.controls.botondia6.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_7.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita.*/ KONtx.messages.store ('numerohoras', Objeto3_7.numerohoras);

105

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_7.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_7.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_7.profesional_agenda); Objeto4_7=KONtx.messages.fetch('Objeto4_7'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_7.numerohoras;i ++){ eval ('cadenahora = Objeto4_7.hora'+i+'.cadena'); eval ('valuehora = Objeto4_7.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia7.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras7', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras7'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia8 = new KONtx.control.TextButton({ label: Objeto1.dia8.cadena, guid: "dia8", styles: { vOffset: this.controls.botondia7.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_8.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita.*/ KONtx.messages.store ('numerohoras', Objeto3_8.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_8.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_8.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_8.profesional_agenda); Objeto4_8=KONtx.messages.fetch('Objeto4_8'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_8.numerohoras;i ++){ eval ('cadenahora = Objeto4_8.hora'+i+'.cadena'); eval ('valuehora = Objeto4_8.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); }

106

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

//Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia8.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras8', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras8'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia9 = new KONtx.control.TextButton({ label: Objeto1.dia9.cadena, guid: "dia9", styles: { vOffset: this.controls.botondia8.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_9.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita*/ KONtx.messages.store ('numerohoras', Objeto3_9.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_9.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_9.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_9.profesional_agenda); Objeto4_9=KONtx.messages.fetch('Objeto4_9'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_9.numerohoras;i ++){ eval ('cadenahora = Objeto4_9.hora'+i+'.cadena'); eval ('valuehora = Objeto4_9.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia9.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras9', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras9'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia10 = new KONtx.control.TextButton({ label: Objeto1.dia10.cadena, guid: "dia10",

107

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


styles: { vOffset: this.controls.botondia9.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_10.numerohoras>0){

Proyecto Fin de Carrera Mara Len Bujes

KONtx.messages.store ('numerohoras', Objeto3_10.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_10.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_10.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_10.profesional_agenda); Objeto4_10=KONtx.messages.fetch('Objeto4_10'); //Se guardan las horas en el centro de mensajes //for ( $i = 0 ; $i <= 66 ; $i ++) { for (i=0;i<Objeto3_10.numerohoras;i ++){ eval ('cadenahora = Objeto4_10.hora'+i+'.cadena'); eval ('valuehora = Objeto4_10.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia10.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras10', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras10'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia11 = new KONtx.control.TextButton({ label: Objeto1.dia11.cadena, guid: "dia11", styles: { vOffset: this.controls.botondia10.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_11.numerohoras>0){ /*Guardamos en el centro de mensajes los inputs ocultos que se envan junto con valuehora para asignar la cita.*/ KONtx.messages.store ('numerohoras', Objeto3_11.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_11.centro_ubicacion_agenda);

108

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


KONtx.messages.store ('codigo_tarea_agenda', Objeto3_11.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_11.profesional_agenda); Objeto4_11=KONtx.messages.fetch('Objeto4_11');

Proyecto Fin de Carrera Mara Len Bujes

//Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_11.numerohoras;i ++){ eval ('cadenahora = Objeto4_11.hora'+i+'.cadena'); eval ('valuehora = Objeto4_11.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia11.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras11', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras11'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia12 = new KONtx.control.TextButton({ label: Objeto1.dia12.cadena, guid: "dia12", styles: { vOffset: this.controls.botondia11.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_12.numerohoras>0){ KONtx.messages.store ('numerohoras', Objeto3_12.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_12.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_12.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_12.profesional_agenda); Objeto4_12=KONtx.messages.fetch('Objeto4_12'); //Se guardan las horas en el centro de mensajes //for ( $i = 0 ; $i <= 66 ; $i ++) { for (i=0;i<Objeto3_12.numerohoras;i ++){ eval ('cadenahora = Objeto4_12.hora'+i+'.cadena'); eval ('valuehora = Objeto4_12.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia12.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras12', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras12'); }

109

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); this.controls.botondia13 = new KONtx.control.TextButton({ label: Objeto1.dia13.cadena, guid: "dia13", styles: { vOffset: this.controls.botondia12.outerHeight, }, events: { onSelect: function(event) { if(flag2>0){ alerta.show(); } else{ if (Objeto3_13.numerohoras>0){

Proyecto Fin de Carrera Mara Len Bujes

KONtx.messages.store ('numerohoras', Objeto3_13.numerohoras); KONtx.messages.store ('centro_ubicacion_agenda', Objeto3_13.centro_ubicacion_agenda); KONtx.messages.store ('codigo_tarea_agenda', Objeto3_13.codigo_tarea_agenda); KONtx.messages.store ('profesional_agenda', Objeto3_13.profesional_agenda); Objeto4_13=KONtx.messages.fetch('Objeto4_13'); //Se guardan las horas en el centro de mensajes for (i=0;i<Objeto3_13.numerohoras;i ++){ eval ('cadenahora = Objeto4_13.hora'+i+'.cadena'); eval ('valuehora = Objeto4_13.hora'+i+'.value'); KONtx.messages.store ('cadenahora'+i, cadenahora); KONtx.messages.store ('valuehora'+i, valuehora); } //Cargamos la vista Mostrar horas KONtx.messages.store ('dia_elegido', Objeto1.dia13.cadena); KONtx.application.addViewConfig({ id: 'view-MostrarHoras13', viewClass: VistaMostrarHoras }); KONtx.application.loadView('view-MostrarHoras13'); } else{ KONtx.application.loadView('view-OtroDia'); } } } } }).appendTo(this); var alerta= new KONtx.dialogs.Alert({ title: 'Obteniendo citas', message: 'Espere hasta que aparezca el nmero de citas disponibles para este da.', focusOnCompletion: this.element.focusedView, buttons:[ { label: 'Aceptar'} ] });

110

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


this.controls.terminar = new KONtx.control.TextButton({ label: 'Salir sin pedir cita', guid: "botonsalir", styles: { vOffset: this.controls.botondia13.outerHeight+30, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.off(); KONtx.application.loadView('view-Main'); } } }).appendTo(this); }, updateView: function() { flag2=0; if (KONtx.messages.fetch('flag')=='1'){ flag2=1; //this.controls.botondia0.setDisabled(true); var Objeto0=KONtx.messages.fetch('Objeto0'); var Objeto1=KONtx.messages.fetch('Objeto1');

Proyecto Fin de Carrera Mara Len Bujes

var cadenaparams='diacita0='+Objeto1.dia0.value+'&diacita1='+Objeto1.dia1.value+' &diacita2='+Objeto1.dia2.value+'&diacita3='+Objeto1.dia3.value+'&diacita4='+O bjeto1.dia4.value+'&diacita5='+Objeto1.dia5.value+'&diacita6='+Objeto1.dia6.v alue+'&diacita7='+Objeto1.dia7.value+'&diacita8='+Objeto1.dia8.value+'&diacit a9='+Objeto1.dia9.value+'&diacita10='+Objeto1.dia10.value+'&diacita11='+Objet o1.dia11.value+'&diacita12='+Objeto1.dia12.value+'&diacita13='+Objeto1.dia13. value+'&cookies_sesion='+Objeto0.sesion+'&tipocita='+Objeto0.tipocita+'&activ idad_agenda='+Objeto0.actividad_agenda+'&modalidad_agenda='+Objeto0.modalidad _agenda+'&codigo_agenda='+Objeto0.codigo_agenda+'&codigo_profesional='+Objeto 0.codigo_profesional+'&domicilio_usuario='+Objeto0.domicilio_usuario+'&nuss_u suario='+Objeto0.nuss_usuario+'&nombre_usuario='+Objeto0.nombre_usuario+'&tel efonos_usuario='+Objeto0.telefonos_usuario+'&desplazado='+Objeto0.desplazado+ '&tarea_desc='+Objeto0.tarea_desc+'&centro_desc='+Objeto0.centro_desc+'&centr o_codigo='+Objeto0.centro_codigo+'&nombre_profesional='+Objeto0.nombre_profes ional; log("!!!!!!!!!!!!!!!!!!!!!!!!!!!"+cadenaparams); this.controls.botondia0.setText(Objeto1.dia0.cadena+" (cargando...)"); this.controls.botondia1.setText(Objeto1.dia1.cadena+" (cargando...)"); this.controls.botondia2.setText(Objeto1.dia2.cadena+" (cargando...)"); this.controls.botondia3.setText(Objeto1.dia3.cadena+" (cargando...)"); this.controls.botondia4.setText(Objeto1.dia4.cadena+" (cargando...)"); this.controls.botondia5.setText(Objeto1.dia5.cadena+" (cargando...)"); this.controls.botondia6.setText(Objeto1.dia6.cadena+" (cargando...)"); this.controls.botondia7.setText(Objeto1.dia7.cadena+" (cargando...)"); this.controls.botondia8.setText(Objeto1.dia8.cadena+" (cargando...)"); this.controls.botondia9.setText(Objeto1.dia9.cadena+" (cargando...)"); this.controls.botondia10.setText(Objeto1.dia10.cadena+" (cargando...)"); this.controls.botondia11.setText(Objeto1.dia11.cadena+" (cargando...)"); this.controls.botondia12.setText(Objeto1.dia12.cadena+" (cargando...)"); this.controls.botondia13.setText(Objeto1.dia13.cadena+" (cargando...)");

111

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


auxiliar3=this; peticion2={ metodo:"POST",

Proyecto Fin de Carrera Mara Len Bujes

url:'http:// www.s414468704.mialojamiento.es/proyecto/seleccion_de_cita2.php', params: cadenaparams, success: function(requestObj2){ KONtx.utility.WaitIndicator.off(); flag2=0; log("requestObj2.readyState: " +requestObj2.readyState+" requestObj2.status: "+requestObj2.status); datosjson_web2=requestObj2.responseText; log (datosjson_web2); datosjson2=datosjson_web2.split("SEPARADOR"); //Datos da 0, da 1, da 2... Objeto3_0 = JSON.parse(datosjson2[0]); Objeto3_1 = JSON.parse(datosjson2[2]); Objeto3_2 = JSON.parse(datosjson2[4]); Objeto3_3 = JSON.parse(datosjson2[6]); Objeto3_4 = JSON.parse(datosjson2[8]); Objeto3_5 = JSON.parse(datosjson2[10]); Objeto3_6 = JSON.parse(datosjson2[12]); Objeto3_7 = JSON.parse(datosjson2[14]); Objeto3_8 = JSON.parse(datosjson2[16]); Objeto3_9 = JSON.parse(datosjson2[18]); Objeto3_10 = JSON.parse(datosjson2[20]); Objeto3_11 = JSON.parse(datosjson2[22]); Objeto3_12 = JSON.parse(datosjson2[24]); Objeto3_13 = JSON.parse(datosjson2[26]); if (Objeto3_0.numerohoras>0){ Objeto4_0 = JSON.parse(datosjson2[1]); KONtx.messages.store ('Objeto4_0', Objeto4_0); } else{} if (Objeto3_1.numerohoras>0){ Objeto4_1 = JSON.parse(datosjson2[3]); KONtx.messages.store ('Objeto4_1', Objeto4_1); } else{} if (Objeto3_2.numerohoras>0){ Objeto4_2 = JSON.parse(datosjson2[5]); KONtx.messages.store ('Objeto4_2', Objeto4_2); } else{} if (Objeto3_3.numerohoras>0){ Objeto4_3 = JSON.parse(datosjson2[7]); KONtx.messages.store ('Objeto4_3', Objeto4_3); } else{} if (Objeto3_4.numerohoras>0){ Objeto4_4 = JSON.parse(datosjson2[9]); KONtx.messages.store ('Objeto4_4', Objeto4_4); }

112

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


else{} if (Objeto3_5.numerohoras>0){ Objeto4_5 = JSON.parse(datosjson2[11]); KONtx.messages.store ('Objeto4_5', Objeto4_5); } else{} if (Objeto3_6.numerohoras>0){ Objeto4_6 = JSON.parse(datosjson2[13]); KONtx.messages.store ('Objeto4_6', Objeto4_6); } else{} if (Objeto3_7.numerohoras>0){ Objeto4_7 = JSON.parse(datosjson2[15]); KONtx.messages.store ('Objeto4_7', Objeto4_7); } else{} if (Objeto3_8.numerohoras>0){ Objeto4_8 = JSON.parse(datosjson2[17]); KONtx.messages.store ('Objeto4_8', Objeto4_8); } else{} if (Objeto3_9.numerohoras>0){ Objeto4_9 = JSON.parse(datosjson2[19]); KONtx.messages.store ('Objeto4_9', Objeto4_9); } else{} if (Objeto3_10.numerohoras>0){ Objeto4_10 = JSON.parse(datosjson2[21]); KONtx.messages.store ('Objeto4_10', Objeto4_10); } else{} if (Objeto3_11.numerohoras>0){ Objeto4_11 = JSON.parse(datosjson2[23]); KONtx.messages.store ('Objeto4_11', Objeto4_11); } else{} if (Objeto3_12.numerohoras>0){ Objeto4_12 = JSON.parse(datosjson2[25]); KONtx.messages.store ('Objeto4_12', Objeto4_12); } else{} if (Objeto3_13.numerohoras>0){ Objeto4_13 = JSON.parse(datosjson2[27]); KONtx.messages.store ('Objeto4_13', Objeto4_13); } else{}

Proyecto Fin de Carrera Mara Len Bujes

auxiliar3.controls.botondia0.setText(Objeto1.dia0.cadena+" ("+Objeto3_0.numerohoras+" citas)"); auxiliar3.controls.botondia1.setText(Objeto1.dia1.cadena+" ("+Objeto3_1.numerohoras+" citas)"); auxiliar3.controls.botondia2.setText(Objeto1.dia2.cadena+" ("+Objeto3_2.numerohoras+" citas)"); auxiliar3.controls.botondia3.setText(Objeto1.dia3.cadena+" ("+Objeto3_3.numerohoras+" citas)");

113

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

auxiliar3.controls.botondia4.setText(Objeto1.dia4.cadena+" ("+Objeto3_4.numerohoras+" citas)"); auxiliar3.controls.botondia5.setText(Objeto1.dia5.cadena+" ("+Objeto3_5.numerohoras+" citas)"); auxiliar3.controls.botondia6.setText(Objeto1.dia6.cadena+" ("+Objeto3_6.numerohoras+" citas)"); auxiliar3.controls.botondia7.setText(Objeto1.dia7.cadena+" ("+Objeto3_7.numerohoras+" citas)"); auxiliar3.controls.botondia8.setText(Objeto1.dia8.cadena+" ("+Objeto3_8.numerohoras+" citas)"); auxiliar3.controls.botondia9.setText(Objeto1.dia9.cadena+" ("+Objeto3_9.numerohoras+" citas)"); auxiliar3.controls.botondia10.setText(Objeto1.dia10.cadena+" ("+Objeto3_10.numerohoras+" citas)"); auxiliar3.controls.botondia11.setText(Objeto1.dia11.cadena+" ("+Objeto3_11.numerohoras+" citas)"); auxiliar3.controls.botondia12.setText(Objeto1.dia12.cadena+" ("+Objeto3_12.numerohoras+" citas)"); auxiliar3.controls.botondia13.setText(Objeto1.dia13.cadena+" ("+Objeto3_13.numerohoras+" citas)"); }, error: function(){ KONtx.utility.WaitIndicator.off(); log("Error en la conexin"); } } funcion_xmlhttprequest(peticion2); } //cerramos el if } });

114

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaMostrarHoras.js
var VistaMostrarHoras = new KONtx.Class({ ClassName: 'MiVistaMostrarHoras', Extends: KONtx.system.SidebarView, createView: function() { auxiliar3=this; /*Creamos el objeto asignarcita mediante la notacin literal de objetos de JavaScript.*/ var asignarcita={ metodo:"POST", url:"http://www.s414468704.mialojamiento.es/proyecto/cita_asignada.php", params:"", success:function(requestObj3){ KONtx.utility.WaitIndicator.off(); log("requestObj3.readyState: " +this.readyState+" requestObj3.status: "+this.status); datosjson_web3=requestObj3.responseText; log ("!!!!!!!!!!!!!!!!!!!!!!! datosjson_web3:"+datosjson_web3); var Objeto5 = JSON.parse(datosjson_web3); if (Objeto5.comprueba_sesion=="ok"){ KONtx.messages.store ('enlace_cancelar', Objeto5.enlace_cancelar); KONtx.messages.store('fecha_cita',Objeto5.fecha_cita); KONtx.messages.store('hora_cita',Objeto5.hora_cita); KONtx.messages.store('orden',Objeto5.orden); KONtx.messages.store('centro',Objeto5.centro); KONtx.messages.store('direccion',Objeto5.direccion); KONtx.messages.store('ubicacion',Objeto5.ubicacion.replace("&nbsp;","") ); KONtx.messages.store('profesional',Objeto5.profesional); KONtx.messages.store('nombre_usuario',Objeto5.nombre_usuario.replace("& nbsp;","")); KONtx.messages.store('fecha_solicitud',Objeto5.fecha_solicitud.replace( "&nbsp;","")); KONtx.application.loadView('view-CitaAsignada'); } else{ KONtx.messages.store ('informacion', Objeto5.comprueba_sesion); KONtx.application.loadView('view-InformacionError'); } }, error:function(){ KONtx.utility.WaitIndicator.off(); log("Error en la peticin de cita"); } }; //Creamos el botn volver this.controls.backButton = new KONtx.control.BackButton({ label:'Elija hora', guid: "back_button", }).appendTo(this);

115

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


var contenedor= new KONtx.element.Container ({

Proyecto Fin de Carrera Mara Len Bujes

styles: { width: this.width, height: this.height-2*this.controls.backButton.outerHeight, vOffset: this.controls.backButton.outerHeight, } }).appendTo(this); this.controls.texto = new KONtx.element.Text({ data: "Citas para el (da elegido):", styles: { vAlign: 'top', fontSize: KONtx.utility.scale(16), vOffset: 10, hOffset: 5, color: '#FFFFFF' } }).appendTo(contenedor); this.controls.botonhora0 = new KONtx.control.TextButton({ label: "Hora 0", guid: "botonhora0", styles: { vOffset: this.controls.texto.outerHeight+10, }, events: { onSelect: function(event) { //Iniciamos la animacin de indicacin de espera KONtx.utility.WaitIndicator.on(); log("!!!!!!!!!!params_nocambian:"+params_nocambian); /*modificamos la propiedad params del objeto asignarcita para que el parmetro horacita que pasamos por POST sea el adecuado:*/ asignarcita.params='horacita='+KONtx.messages.fetch('valuehora0')+param s_nocambian; /*Llamamos a la funcin funcion_xmlhttprequest pasndole como parmetro el objeto asignarcita:*/ funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora1 = new KONtx.control.TextButton({ label:"Hora 1", guid: "botonhora1", styles: { vOffset: this.controls.botonhora0.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora1') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor);

116

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

/* el botn se har visible por medio del mtodo show() cuando se ejecute el mtodo updateView() */ this.controls.botonhora1.hide(); this.controls.botonhora2 = new KONtx.control.TextButton({ label:"Hora 2", guid: "botonhora2", styles: { vOffset: this.controls.botonhora1.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora2') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora2.hide(); this.controls.botonhora3 = new KONtx.control.TextButton({ label:"Hora 3", guid: "botonhora3", styles: { vOffset: this.controls.botonhora2.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora3') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora3.hide(); this.controls.botonhora4 = new KONtx.control.TextButton({ label: "Hora 4", guid: "botonhora4", styles: { vOffset: this.controls.botonhora3.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora4') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora4.hide(); this.controls.botonhora5 = new KONtx.control.TextButton({ label: "Hora 5", guid: "botonhora5",

117

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


styles: { vOffset: this.controls.botonhora4.outerHeight, }, events: {

Proyecto Fin de Carrera Mara Len Bujes

onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora5') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora5.hide(); this.controls.botonhora6 = new KONtx.control.TextButton({ label: "Hora 6", guid: "botonhora6", styles: { vOffset: this.controls.botonhora5.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora6') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora6.hide(); this.controls.botonhora7 = new KONtx.control.TextButton({ label: "Hora 7", guid: "botonhora7", styles: { vOffset: this.controls.botonhora6.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora7') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora7.hide(); this.controls.botonhora8 = new KONtx.control.TextButton({ label: "Hora 8", guid: "botonhora8", styles: { vOffset: this.controls.botonhora7.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on();

118

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

asignarcita.params='horacita='+KONtx.messages.fetch('valuehora8')+param s_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora8.hide(); this.controls.botonhora9 = new KONtx.control.TextButton({ label: "Hora 9", guid: "botonhora9", styles: { vOffset: this.controls.botonhora8.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora9') + params_nocambian; funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora9.hide(); this.controls.botonhora10 = new KONtx.control.TextButton({ label: "Hora 10", guid: "botonhora10", styles: { vOffset: this.controls.botonhora9.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora10') + params_nocambian; log(asignarcita.params); funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora10.hide(); this.controls.botonhora11 = new KONtx.control.TextButton({ label: "Hora 11", guid: "botonhora11", styles: { vOffset: this.controls.botonhora10.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora11') + params_nocambian; log(asignarcita.params); funcion_xmlhttprequest(asignarcita); } }

119

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


}).appendTo(contenedor); this.controls.botonhora11.hide(); this.controls.botonhora12 = new KONtx.control.TextButton({ label: "Hora 12", guid: "botonhora12",

Proyecto Fin de Carrera Mara Len Bujes

styles: { vOffset: this.controls.botonhora11.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora12') + params_nocambian; log(asignarcita.params); funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora12.hide(); this.controls.botonhora13 = new KONtx.control.TextButton({ label: "Hora 13", guid: "botonhora13", styles: { vOffset: this.controls.botonhora12.outerHeight, }, events: { onSelect: function(event) { KONtx.utility.WaitIndicator.on(); asignarcita.params='horacita=' + KONtx.messages.fetch('valuehora13') + params_nocambian; log(asignarcita.params); funcion_xmlhttprequest(asignarcita); } } }).appendTo(contenedor); this.controls.botonhora13.hide(); this.controls.botonotrodia = new KONtx.control.TextButton({ label: 'Seleccionar otro da', guid: "botonotrodia", styles: { vOffset: contenedor.outerHeight, }, events: { onSelect: function(event) { //Si seleccionamos el botn cargamos la VistaMostrarDias KONtx.application.loadView('view-MostrarDias'); } } }).appendTo(this); }, updateView: function() { this.controls.botonhora1.hide(); this.controls.botonhora2.hide();

120

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


this.controls.botonhora3.hide(); this.controls.botonhora4.hide(); this.controls.botonhora5.hide(); this.controls.botonhora6.hide(); this.controls.botonhora7.hide(); this.controls.botonhora8.hide(); this.controls.botonhora9.hide(); this.controls.botonhora10.hide(); this.controls.botonhora11.hide(); this.controls.botonhora12.hide(); this.controls.botonhora13.hide();

Proyecto Fin de Carrera Mara Len Bujes

params_nocambian='&cookies_sesion='+KONtx.messages.fetch('cookies_sesion')+'&ac tividad_agenda='+KONtx.messages.fetch('actividad_agenda')+'&modalidad_agenda='+ KONtx.messages.fetch('modalidad_agenda')+'&codigo_agenda='+KONtx.messages.fetch ('codigo_agenda')+'&profesional_agenda='+KONtx.messages.fetch('profesional_agen da')+'&domicilio_usuario='+KONtx.messages.fetch('domicilio_usuario')+'&nuss_usu ario='+KONtx.messages.fetch('nuss_usuario')+'&nombre_usuario='+KONtx.messages.f etch('nombre_usuario')+'&telefonos_usuario='+KONtx.messages.fetch('telefonos_us uario')+'&codigo_tarea_agenda='+KONtx.messages.fetch('codigo_tarea_agenda')+'&c entro_ubicacion_agenda='+KONtx.messages.fetch('centro_ubicacion_agenda'); this.controls.texto.setText("Citas para el"+KONtx.messages.fetch('dia_elegido') +":"); this.controls.botonhora0.setText(KONtx.messages.fetch('cadenahora0')); /*las siguientes lneas se podran expresar de forma ms compacta usando la funcin eval() en el siguiente bucle for.*/ this.controls.botonhora1.setText(KONtx.messages.fetch('cadenahora1')); this.controls.botonhora2.setText(KONtx.messages.fetch('cadenahora2')); this.controls.botonhora3.setText(KONtx.messages.fetch('cadenahora3')); this.controls.botonhora4.setText(KONtx.messages.fetch('cadenahora4')); this.controls.botonhora5.setText(KONtx.messages.fetch('cadenahora5')); this.controls.botonhora6.setText(KONtx.messages.fetch('cadenahora6')); this.controls.botonhora7.setText(KONtx.messages.fetch('cadenahora7')); this.controls.botonhora8.setText(KONtx.messages.fetch('cadenahora8')); this.controls.botonhora9.setText(KONtx.messages.fetch('cadenahora9')); this.controls.botonhora10.setText(KONtx.messages.fetch('cadenahora10')); this.controls.botonhora11.setText(KONtx.messages.fetch('cadenahora11')); this.controls.botonhora12.setText(KONtx.messages.fetch('cadenahora12')); this.controls.botonhora13.setText(KONtx.messages.fetch('cadenahora13')); KONtx.messages.store ('flag', 0); var numerohoras=KONtx.messages.fetch('numerohoras'); //Mostramos tantos botones como horas disponibles hay. for (i=numerohoras-1;i>0;i--){ eval("this.controls.botonhora"+i+".show()"); } } });

121

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaMostrarUsuarios.js
var VistaMostrarUsuarios = new KONtx.Class({ ClassName: 'MiVistaMostrarUsuarios', Extends: KONtx.system.SidebarView, createView: function() { this.controls.backButton = new KONtx.control.BackButton({ label:'Usuarios Guardados', guid: "back_button", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ data: "Escoja el usuario para el que desea pedir cita.", wrap:true, styles: { vOffset: this.controls.backButton.outerHeight+20, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.botonusuario1 = new KONtx.control.TextButton({ label: 'Usuario1', guid: "botonusuario1", styles: { vOffset: this.controls.texto0.outerHeight+20, }, events: { onSelect: function(event) { datosusuario1json=currentAppConfig.get('usuario1'); datosusuario1=JSON.parse(datosusuario1json); KONtx.messages.store('nuss', datosusuario1.nuss); KONtx.messages.store('dia', datosusuario1.dia); KONtx.messages.store('mes', datosusuario1.mes); KONtx.messages.store('anio', datosusuario1.anio); KONtx.messages.store('dni', datosusuario1.dni); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario1.hide(); this.controls.botonusuario2 = new KONtx.control.TextButton({ label: 'Usuario2', guid: "botonusuario2", styles: { vOffset: this.controls.botonusuario1.outerHeight, }, events: { onSelect: function(event) { datosusuario2json=currentAppConfig.get('usuario2'); log("datosusuario2json="+datosusuario2json); datosusuario2=JSON.parse(datosusuario2json); KONtx.messages.store('nuss', datosusuario2.nuss); KONtx.messages.store('dia', datosusuario2.dia);

122

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


KONtx.messages.store('mes', datosusuario2.mes); KONtx.messages.store('anio', datosusuario2.anio); KONtx.messages.store('dni', datosusuario2.dni); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario2.hide(); this.controls.botonusuario3 = new KONtx.control.TextButton({ label: 'Usuario3', guid: "botonusuario3", styles: { vOffset: this.controls.botonusuario2.outerHeight, }, events: { onSelect: function(event) { datosusuario3json=currentAppConfig.get('usuario3'); datosusuario3=JSON.parse(datosusuario3json); KONtx.messages.store('nuss', datosusuario3.nuss); KONtx.messages.store('dia', datosusuario3.dia); KONtx.messages.store('mes', datosusuario3.mes); KONtx.messages.store('anio', datosusuario3.anio); KONtx.messages.store('dni', datosusuario3.dni); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario3.hide(); this.controls.botonusuario4 = new KONtx.control.TextButton({

Proyecto Fin de Carrera Mara Len Bujes

label: 'Usuario4', guid: "botonusuario4", styles: { vOffset: this.controls.botonusuario3.outerHeight, }, events: { onSelect: function(event) { datosusuario4json=currentAppConfig.get('usuario4'); datosusuario4=JSON.parse(datosusuario4json); KONtx.messages.store('nuss', datosusuario4.nuss); KONtx.messages.store('dia', datosusuario4.dia); KONtx.messages.store('mes', datosusuario4.mes); KONtx.messages.store('anio', datosusuario4.anio); KONtx.messages.store('dni', datosusuario4.dni); KONtx.application.addViewConfig({ id: 'view-Esperar', viewClass: VistaEsperar }); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario4.hide(); this.controls.botonusuario5 = new KONtx.control.TextButton({ label: 'Usuario5', guid: "botonusuario5", styles: { vOffset: this.controls.botonusuario4.outerHeight, },

123

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


events: { onSelect: function(event) { datosusuario5json=currentAppConfig.get('usuario5'); datosusuario5=JSON.parse(datosusuario5json); KONtx.messages.store('nuss', datosusuario5.nuss); KONtx.messages.store('dia', datosusuario5.dia); KONtx.messages.store('mes', datosusuario5.mes); KONtx.messages.store('anio', datosusuario5.anio); KONtx.messages.store('dni', datosusuario5.dni); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario5.hide(); this.controls.botonusuario6 = new KONtx.control.TextButton({ label: 'Usuario6', guid: "botonusuario6", styles: { vOffset: this.controls.botonusuario5.outerHeight, }, events: { onSelect: function(event) { datosusuario6json=currentAppConfig.get('usuario6'); datosusuario6=JSON.parse(datosusuario6json); KONtx.messages.store('nuss', datosusuario6.nuss); KONtx.messages.store('dia', datosusuario6.dia); KONtx.messages.store('mes', datosusuario6.mes); KONtx.messages.store('anio', datosusuario6.anio); KONtx.messages.store('dni', datosusuario6.dni); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario6.hide(); this.controls.botonusuario7 = new KONtx.control.TextButton({ label: 'Usuario7', guid: "botonusuario7", styles: { vOffset: this.controls.botonusuario6.outerHeight, }, events: { onSelect: function(event) { datosusuario7json=currentAppConfig.get('usuario7'); datosusuario7=JSON.parse(datosusuario7json); KONtx.messages.store('nuss', datosusuario7.nuss); KONtx.messages.store('dia', datosusuario7.dia); KONtx.messages.store('mes', datosusuario7.mes); KONtx.messages.store('anio', datosusuario7.anio); KONtx.messages.store('dni', datosusuario7.dni); KONtx.application.loadView('view-Esperar'); } } }).appendTo(this); this.controls.botonusuario6.hide(); var botonformulario = new KONtx.control.TextButton({ label: 'Pedir cita para un usuario diferente',

Proyecto Fin de Carrera Mara Len Bujes

124

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


guid: "botonformulario", styles: { vOffset: this.controls.botonusuario7.outerHeight+30, }, events: { onSelect: function(event) { KONtx.application.loadView('view-IntroducirDatos'); } } }).appendTo(this); var botongestion = new KONtx.control.TextButton({

Proyecto Fin de Carrera Mara Len Bujes

label: 'Gestionar usuarios guardados', guid: "botongestion", styles: { vOffset: botonformulario.outerHeight, }, events: { onSelect: function(event) { KONtx.application.addViewConfig({ id: 'view-BorrarUsuario', viewClass: VistaBorrarUsuario }); KONtx.application.loadView('view-BorrarUsuario'); } } }).appendTo(this); }, updateView: function() { this.controls.botonusuario1.hide(); this.controls.botonusuario2.hide(); this.controls.botonusuario3.hide(); this.controls.botonusuario4.hide(); this.controls.botonusuario5.hide(); this.controls.botonusuario6.hide(); this.controls.botonusuario7.hide(); var matrizclaves = currentAppConfig.getIDs(); var numerousuarios=matrizclaves.length; for (i=numerousuarios;i>0;i--){ eval("datosusuariojson=currentAppConfig.get('usuario"+i+"');"); datosusuario=JSON.parse(datosusuariojson); eval("this.controls.botonusuario"+i+".setText(datosusuario.nombre);"); eval("this.controls.botonusuario"+i+".show();"); } } });

125

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaOtroDia.js
var VistaOtroDia = new KONtx.Class({ ClassName: 'MiVistaOtroDia', Extends: KONtx.system.SidebarView, createView: function() { //Creamos el botn volver this.controls.backButton = new KONtx.control.BackButton({ label:'No hay citas disponibles', guid: "back_button", }).appendTo(this); this.controls.texto = new KONtx.element.Text({ data: "No quedan citas para este da.", styles: { vOffset: this.controls.backButton.outerHeight+10, hOffset: 5, vAlign: 'top', fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.botonotrodia = new KONtx.control.TextButton({ label: 'Seleccionar otro da', guid: "botonotrodia", styles: { vOffset: this.controls.texto.outerHeight+10, }, events: { onSelect: function(event) { //Si seleccionamos el botn cargar la VistaMostrarDias KONtx.application.loadView('view-MostrarDias'); } } }).appendTo(this); }, updateView: function() { KONtx.messages.store ('flag', 0); } });

126

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo VistaSinUsuarios.js
var VistaSinUsuarios = new KONtx.Class({ ClassName: 'MiVistaSinUsuarios', Extends: KONtx.system.SidebarView, createView: function() { this.controls.backButton = new KONtx.control.BackButton({ label:'Usuarios Guardados', guid: "back_button", }).appendTo(this); this.controls.texto0 = new KONtx.element.Text({ data: "Los usuarios se guardan de forma automtica al pedir/consultar cita por primera vez. Sin embargo, no exite actualmente ningn usuario guardado. Para pedir cita deber introducir los datos del usuario en el siguiente formulario.", wrap:true, styles: { vOffset:this.controls.backButton.outerHeight+20, hOffset: 5, width: this.width-5, fontSize: KONtx.utility.scale(16), color: '#FFFFFF' } }).appendTo(this); this.controls.button1 = new KONtx.control.TextButton({ label: 'Introducir datos', guid: "button0", styles: { vOffset: this.controls.texto0.outerHeight+30, }, events: { onSelect: function(event) { KONtx.application.loadView('view-IntroducirDatos'); } } }).appendTo(this); /* var emptySpaceTop = new KONtx.control.EmptySpace({ styles: { height: KONtx.utility.scale(15), } }).appendTo(this); */ }, updateView: function() { KONtx.application.clearViewHistory(); } });

127

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo API.js
/**** XMLHttpRequest API ****/ function funcion_xmlhttprequest(o){ if (KONtx.application.isPhysicalNetworkDown()) { KONtx.utility.WaitIndicator.off(); log("Network down, no se permiten peticiones xhr!"); return; } var xhr = new XMLHttpRequest(); xhr.autoRedirect = true; xhr.open(o.metodo, o.url, true); xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { log("!!!!!!!!!!!!!!La peticin xhr tuvo xito http: "+xhr.status); o.success(xhr); KONtx.application.setNetworkRequestFailed(false); } else { log("!!!!!!!!!!!!!!La peticin xhr fall http: "+xhr.status); o.error(); KONtx.application.setNetworkRequestFailed(true); } } }; xhr.send(o.params); } /**** Validacin formulario ****/ function Quita_blancos(valor){ if (typeof valor == "undefined"){ return(""); } else{ var no_espacios; var longitud=valor.length; for (i=0;i<longitud;i++){ //Espacio blanco y tabulador if (valor.charAt(i)!=" " && valor.charAt(i)!="\t"){ if ( (i==0) || (typeof no_espacios == "undefined" )){ no_espacios=valor.charAt(i); } else{ no_espacios=no_espacios + valor.charAt(i); } } } if (typeof no_espacios == "undefined"){ return(""); } else{ return (no_espacios); } } } /********************************************************/

128

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


function comprueba_fecha(contenido){

Proyecto Fin de Carrera Mara Len Bujes

var separador_fecha="/"; var numero_separadores=0; if ((contenido.length==0)){ alert("Debe indicar la fecha de nacimiento"); return(false); } //Comprobacion de la sintaxis de la fecha: for (var t=0; t<contenido.length; t++){ var caracter=contenido.charAt(t); if (!es_numero(caracter) && caracter !=separador_fecha ){ return(1); //alerta3.show() Carcter no vlido en la fecha de nacimiento } if (caracter==separador_fecha){ numero_separadores++; } } if (numero_separadores!=2){ return(2); //alerta4.show(). Fecha de nacimiento no vlida } //Comprobacion de la semantica de la fecha: var posicion_separador_1=contenido.indexOf(separador_fecha); var dia=contenido.substring(0,posicion_separador_1); var posicion_separador_2= contenido.indexOf(separador_fecha,posicion_separador_1+1); var mes=contenido.substring(posicion_separador_1+1,posicion_separador_2); var anio=contenido.substring(posicion_separador_2+1,10); if (anio.length!=4){ return(3); //alerta5.show(). Ao incorrecto en la fecha de nacimiento } if (mes<1 || mes>12){ return(4); //alerta6.show(). Mes incorrecto en la fecha de nacimiento } if (( dia<1 || dia>31) || (mes==4 && dia>30) || (mes==6 && dia>30) || (mes==9 && dia>30) || (mes==11 && dia>30) || (mes==2 && es_bisiesto(anio) && dia>29) || (mes==2 && !es_bisiesto(anio) && dia>28)){ return(5); //alerta7.show() Da incorrecto en la fecha de nacimiento } return (6); } function es_numero(car){ var NUMEROS="0123456789"; return NUMEROS.indexOf(car)>=0; } function es_bisiesto(anio){ if ((( anio % 4==0) && anio % 100 !=0 ) || anio % 400 == 0){ return true; } return false; } /********************************************************/ function mayor_edad(edad,dia1,mes1,anio1){ hoy=new Date(getRealTime()*1000); log("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); log(hoy); var dia=hoy.getDay(); var mes=hoy.getMonth()+1; var anio=hoy.getFullYear();

129

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

if ( (anio-anio1)>edad ){ return true; } if ( (anio-anio1)==edad && (mes-mes1)>0 ){ return true; } if ( (anio-anio1)==edad && (mes-mes1)==0 ){ if ((dia1-dia)<=0 ){ /*En este caso devolvemos true porque la fecha de nacimiento introducida corresponde con un usuario mayor de la edad pasada como parmetro.*/ return true; } } /*Devolvemos false en caso contrario y no se muestra un alert aunque no se haya introducido dni (no es obligatiorio).*/ return(false); } /********************************************************/ function validar_ss(nuss){ if (nuss.length!=12||nuss==" ") { if (nuss.length==0){ return(1); //Introduzca el nmero de la tarjeta sanitaria } else{ return(2); //El Nmero de la Tarjeta Sanitaria debe tener 12 dgitos } } // Controlamos la Fecha de Nacimiento: var id1=nuss.substr(0,2); var id2=nuss.substr(2,8); var id3=nuss.substr(10,2); if(id1){ if((!id1.match(/^(\s)*$/)) && (!id1.match(/^(\s)*$/)) && (!id1.match(/^(\s)*$/))){ if(!(id1=="\0")){ if( (id1>0) || (String(id1).toUpperCase()=="AN") ){ if(String(id2).length<8){ for(i=String(id2).length;i<8;i++){ id2e= "0" + id2.value; } } if((id2).charAt(0)=="0"){ if (String(id1).toUpperCase()=="AN"){ provincia=60 * 10000000; } else{ provincia=id1 * 10000000; } } else{ if (String(id1).toUpperCase()=="AN"){ provincia=60 * 100000000; } else{ provincia=id1 * 100000000 ; } } dividendo=Number(provincia) + Number(id2); divisor=97; resto=dividendo%divisor; if(resto <10){

130

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

resto="0" + resto; } if(id3.match(/^(\s)*$/)){ id3=resto; } else{ if(id3!=resto){ /*alert("El nmero de la Tarjeta Sanitaria introducido no es correcto");*/ return(3); } } return(7);//correcto } else{ return(3);//alert("El nmero de la Tarjeta Sanitaria introducido no es correcto"); } } else{ return(3);//alert("El nmero de la Tarjeta Sanitaria introducido no es correcto"); } } else{ return(7); //correcto } } else{ return(7); //correcto } } /********************************************************/ function nif(dni) { numero = dni.substr(0,dni.length-1); let = dni.substr(dni.length-1,1); numero = numero % 23; letra1='TRWAGMYFPDXBNJZSQVHLCKET'; letra2='trwagmyfpdwbnjzsqvhlcket'; letra1=letra1.substring(numero,numero+1); letra2=letra2.substring(numero,numero+1); if ((letra1!=let)&&(letra2!=let)) { return (false); } else{ return (true); } } /****************************************************************/ function Es_Natural(valor){ resultado=true; for(i=0;i<valor.length && resultado==true;i++){ car=valor.substr(i,1); if(car!="0" && car!="1" && car!="2" && car!="3" && car!="4" && car!="5" &&car!="6" && car!="7" && car!="8" && car!="9"){ resultado=false; } } return(resultado); }

131

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo init.js
include("Framework/kontx/1.1/src/all.js"); include("Javascript/core/API.js"); include("Javascript/views/MainView.js"); include("Javascript/views/VistaSinUsuarios.js"); include("Javascript/views/VistaMostrarUsuarios.js"); include("Javascript/views/VistaBorrarUsuario.js"); include("Javascript/views/VistaIntroducirDatos.js"); include("Javascript/views/VistaEsperar.js"); include("Javascript/views/VistaMostrarDias.js"); include("Javascript/views/VistaMostrarHoras.js"); include("Javascript/views/VistaCitaAsignada.js"); include("Javascript/views/VistaInformacion.js"); include("Javascript/views/VistaInformacionError.js"); include("Javascript/views/VistaOtroDia.js"); include("Javascript/views/AboutView.js"); include("Javascript/views/SnippetView.js"); /*Para mantener la compatibilidad del widget con versiones antiguas del Framework comprobamos que existe la funcin KONtx.application.isPhysicalNetworkDown() y si no existe la definimos*/ if (typeof KONtx.application.isPhysicalNetworkDown === "undefined") { (function () { //Antes de borrar la funcin original la guardamos en una variable var original = KONtx.application.setNetworkRequestFailed, setDownByUser = false; delete KONtx.application.setNetworkRequestFailed; KONtx.application.setNetworkRequestFailed = function (status) { original(status); setDownByUser = status; }; KONtx.application.isPhysicalNetworkDown = function () { if (KONtx.application.getNetworkDownStatus) { return !setDownByUser; } return false; }; }()); } //Inicializacin de las vistas KONtx.application.init({ views: [ { id: 'view-Main', viewClass: MainView }, { id: 'view-IntroducirDatos', viewClass: VistaIntroducirDatos }, { id: 'view-Esperar', viewClass: VistaEsperar }, { id: 'view-MostrarDias', viewClass: VistaMostrarDias }, { id: 'view-MostrarHoras', viewClass: VistaMostrarHoras }, { id: 'view-CitaAsignada', viewClass: VistaCitaAsignada }, { id: 'view-Informacion', viewClass: VistaInformacion }, { id: 'view-InformacionError', viewClass: VistaInformacionError }, { id: 'view-OtroDia', viewClass: VistaOtroDia }, { id: 'view-About', viewClass: AboutView }, { id: 'snippet-1', viewClass: SnippetView, data: { message1: "Versin 2.8", message2: "Cita Mdica" , message3: "Servicio Andaluz de Salud"} }, ],

132

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA


defaultViewId: 'view-Main', settingsViewId: 'view-About', }); peticion0={

Proyecto Fin de Carrera Mara Len Bujes

metodo:"POST", url:'http://www.s414468704.mialojamiento.es/proyecto/holamundo.php', params:"param1=1&param2=2", success: function(requestObj){ var datosjson =requestObj.responseText; log(datosjson); var Objeto = JSON.parse(datosjson); log ("Comprobando red en onApplicationStartup: "+Objeto.mensaje); }, error: function(){ log("Error en la conexin"); } }; var EventHandlers = (function () { return { onApplicationStartup: function () { //Peticin al servidor intermedio para comprobar el estado de la conexin funcion_xmlhttprequest(peticion0); }, onActivateSnippet:function () { funcion_xmlhttprequest(peticion0); } } }()); EventHandlers.onApplicationStartup.subscribeTo(KONtx.application, "onApplicationStartup", EventHandlers); EventHandlers.onActivateSnippet.subscribeTo(KONtx.application, "onActivateSnippet", EventHandlers);

133

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

A continuacin se reproducir el contenido que, en el caso del Widget de Cita Mdica, presentan los archivos widget.xml y main.TV, presentes en cualquier implementacin de un widget. Archivo widget.xml
<?xml version="1.0" encoding="utf-8"?> <metadata> <name>Widget Cita Mdica</name> <version>0.2.8</version> <identifier>es.us.widgets.tv.cita8</identifier> <debug>on</debug> <author name="Maria Leon" organization="Universidad de Sevilla" href="http://www.us.es" /> <copyright>Universidad de Sevilla 2012</copyright> <description>Widget para solicitud de cita mdica.</description> <platform minVersion="4.6.1" /> <settings> <setting name="debug" value="on" /> <setting name="allowCustomObjectAttributes" value="true" /> </settings> <security> <http>all</http> </security> <image usage="1920x1080.icon" src="image/1920x1080/application-icon.png"/> <image usage="1920x1080.logo" src="image/1920x1080/application-logo.png"/> <image usage="1920x1080.loading.snippet" src="image/1920x1080/applicationloader.png"/> <image usage="1920x1080.anchor" src="image/1920x1080/snippet-main-1080.png" />

<image usage="960x540.icon" src="image/960x540/application-icon.png"/> <image usage="960x540.logo" src="image/960x540/application-logo.png"/> <image usage="960x540.loading.snippet" src="image/960x540/applicationloader.png"/> <image usage="960x540.anchor" </metadata> src="image/960x540/snippet-main-540.png" />

134

ANEXO I: ARCHIVOS CREADOS PARA IMPLEMENTAR EL WIDGET DE CITA MDICA

Proyecto Fin de Carrera Mara Len Bujes

Archivo main.TV
<?xml version="1.0" encoding="utf-8"?> <widget> <script src="Platform/platform.js"/> <script src="Javascript/init.js"/> </widget>

135

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

Anexo II
En el presente anexo se incluye el cdigo PHP de la web API almacenada en el servidor intermedio. En este caso, el orden de los archivos persigue favorecer la comprensin del cdigo, por lo que no se ha realizado una ordenacin alfabtica de los mismos. Archivo servidor_intermedio5.php
<?php //Incluimos la librera para parsear html include_once('simple_html_dom.php'); function loginintersas ($url, $agente) { foreach($_POST as $nombre_campo => $valor){ $asignacion = "$" . $nombre_campo . "='" . $valor . "';"; eval($asignacion); } //$ckfile = tempnam ("/tmp", "CURLCOOKIE"); $curl = curl_init(); //Nueva sesion CURL $campos = "id_us=" . $id_us . "&dia=" . $dia . "&mes=" . $mes . "&anio=" . $anio . "&dni=" . $dni . "&origen=1"; curl_setopt ($curl, CURLOPT_URL, $url); //Direccion de destino curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1); //Resultado en una cadena de texto curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl, CURLOPT_USERAGENT, $agente); curl_setopt ($curl, CURLOPT_HEADER, 1); //devuelve encabezado http // Especificamos la versin de SSL para poder conectar con el servidor de InterS@S curl_setopt ($curl, CURLOPT_SSLVERSION, 3); /* Se comprobar que el certificado del servidor es vlido verificando que la CA (Autoridad Certificadora) que lo expidi est entre las CA reconocidas.*/ curl_setopt ($curl, CURLOPT_SSL_VERIFYPEER, true); /* Tambin se comprobar que el common name (CN) del certificado de servidor se corresponde con el dominio al que nos estamos conectando.*/ curl_setopt ($curl, CURLOPT_SSL_VERIFYHOST, 2); /* Con la siguiente opcin le indicamos a cURL que confe en los certificados de servidor firmados por una CA cuyo certificado raiz es FNMTClase2CA-FNMT.crt. Este es el certificado raiz de la FNMT que es la autoridad certificadora que expide el certificado de servidor del servidor al que estamos intentando acceder va https (el servidor de InterS@S). El certificado se ha obtenido exportndolo desde Firefox como certificado X.509 con cadena (PEM). Es fundamental que se exporte en este formato para que sea compatible con Curl. Por otra parte getcwd() es una funcin de php que devuelve el directorio actual.*/ curl_setopt ($curl, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl, CURLOPT_POST, 1); curl_setopt ($curl, CURLOPT_POSTFIELDS, $campos); $codigofuente = curl_exec ($curl); //Ejecutamos sesion CURL /* Comprobamos que los datos se han introducido correctamente (comprobamos que no hemos obtenido la pgina advirtiendo de la no coincidencia entre los datos introducidos y los almacenados en la base de datos de InterS@S). */

136

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


$html = new simple_html_dom(); $html->load($codigofuente);

Proyecto Fin de Carrera Mara Len Bujes

$compruebaerrordatos=$html->find('span[class=letra_general]',0)->innertext; if ($compruebaerrordatos=="Se ha producido un error al introducir los datos."){ $json2='{"enlace_cancelar":"no hay cita que cancelar","comprueba_acceso":"'.$compruebaerrordatos.'"}'; curl_close ($curl); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html para no malgastar memoria print (utf8_encode($json2)); print("SEPARADOR"); print ('{"segundoJSON":"RELLENO"}'); } else{ /* Queremos obtener la direccin para pedir cita con el mdico, la cual es generada dinmicamente. Para ello analizaremos el contenido de $codigofuente, que no es ms que una cadena de texto, haciendo uso de algunas funciones de php de manipulacin de cadenas: */ $primerpaso=explode('href="/citaInternet/inicio_citamedico.jsp?id=',$codigofuen te); $segundopaso=$primerpaso[1]; $tercerpaso=explode('" target="_blank" onclick="completa_url(this.href);',$segundopaso); $idprimero=$tercerpaso[0]; // La url para pedir cita $url2 = "https://ws003.juntadeandalucia.es/citaInternet/inicio_citamedico.jsp?id=" . $idprimero; curl_close ($curl); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html para ahorrar recursos del servidor. $curl2 = curl_init(); //Nueva sesion CURL curl_setopt ($curl2, CURLOPT_URL, $url2); //Direccion de destino curl_setopt($curl2, CURLOPT_AUTOREFERER, 1); // Queremos la respuesta en una cadena de texto curl_setopt ($curl2, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl2, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl2, CURLOPT_USERAGENT, $agente); /* Especificamos la versin de ssl para que funcione con el servidor de InterS@S */ curl_setopt ($curl2, CURLOPT_SSLVERSION, 3); /* Igual que antes, se comprobar que el certificado del servidor es vlido comprobando que la CA (Autoridad Certificadora) que lo expidi est entre las CA reconocidas. */ curl_setopt ($curl2, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl2, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt ($curl2, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); /* Las siguientes tres lneas para almacenar las cookies de esta peticin no funcionan en el hosting a pesar de haber dado permisos de escritura. $ckfile = "/proyecto/tmp".time(); curl_setopt($curl2, CURLOPT_COOKIEFILE, $ckfile); curl_setopt($curl2, CURLOPT_COOKIEJAR, $ckfile);

137

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

Finalmente opto por obtener las cookies parseando la cabecera http de la peticin. Para que la cabecera http est incluida en la respuesta que se obtiene establecemos a uno la opcin CURLOPT_HEADER de la sesin cURL */ //Se incluye la cabecera http en la respuesta. curl_setopt ($curl2, CURLOPT_HEADER, 1); //Ejecutamos sesion CURL esta vez sin paso de parmetros por POST $codigofuente2 = curl_exec ($curl2); /* Parseamos $cdigofuente2 para quedarnos con las cookies que aparecen en la cabecera http (http response). La cabecera http que precede a la pgina solicitada incluye una serie de lneas que comienzan con la directiva Set-Cookie. A continuacin aparece el name=value de la cookie que el servidor quiere que almacene el navegador. Tras un ; pueden aparecer una serie de atributos de la cookie. Lo que nos interesa a nosotros es este name=value que es lo que incluiremos (utilizando la opcin CURL_COOKIE) en la cabecera de la siguiente peticin que establezcamos. La cabecera http enviada por el servidor tiene la siguiente estructura: HTTP/1.1 200 OK Set-Cookie: name=value Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT Content-type: text/html (content of page) */ $start = strpos($codigofuente2, "Set-Cookie"); $end = strpos($codigofuente2, "Content-Type"); $parts = split("Set-Cookie: ",substr($codigofuente2, $start, $end-$start)); $cookies = array(); foreach ($parts as $co){ $cd = split(";",$co); if (!empty($cd[0])) /* cada vez que se recorre el bucle se aade un elemento a la matriz de tamao indeterminado $cookies[] */ $cookies[] = $cd[0]; } $cookies_sesion=implode(";",$cookies); curl_close ($curl2); //Cerramos sesion CURL $curl3 = curl_init(); //Nueva sesion CURL $url3='https://ws003.juntadeandalucia.es/citaInternet/inicio_peticion_cita.jsp' ; curl_setopt ($curl3, CURLOPT_URL, $url3); //Direccion de destino /* Establecemos el valor de las cookies en la nueva peticin. Las cookies las hemos obtenido parseando la cabecera http (http header de la enterior peticin) */ curl_setopt($curl3, CURLOPT_COOKIE, $cookies_sesion); //Resultado en una cadena de texto curl_setopt ($curl3, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl3, CURLOPT_FOLLOWLOCATION, 0);

138

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt ($curl3, CURLOPT_USERAGENT, $agente); curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt ($curl3, ($curl3, ($curl3, ($curl3, ($curl3, ($curl3,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_HEADER, 0); //Oculta encabezado CURLOPT_SSLVERSION, 3); CURLOPT_SSL_VERIFYPEER, true); CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); CURLOPT_POST, 0);

//Ejecutamos sesion CURL $codigofuente3 = curl_exec ($curl3); /* Hay que obtener una matriz y despus un JSON con los das de cita disponibles */ $html = new simple_html_dom(); $html->load($codigofuente3); /*Comprobamos si hay cita pedida. Si la hay se genera un json con los datos de la cita.*/ $compruebacita=$html->find('a[class=enlace_cancelar_cita]',0)->href; if ($compruebacita!=null){ $matrizdatos['sesion']=$cookies_sesion; $matrizdatos['comprueba_acceso']="ok"; $matrizdatos['enlace_cancelar']=$html>find('a[class=enlace_cancelar_cita]',0)->href; $matrizdatos['fecha_solicitud']=utf8_encode($html>find('span[class=letra_pequena_fecha]',0)->innertext); $matrizdatos['fecha_cita']=utf8_encode($html>find('strong[class=letra_justificante_cita_negrita_big]',0)->innertext); $matrizdatos['hora_cita']=utf8_encode($html>find('strong[class=letra_justificante_cita_negrita_big]',1)->innertext); $matrizdatos['orden']=utf8_encode($html>find('strong[class=letra_justificante_cita_negrita_big]',2)->innertext); $matrizdatos['centro']=utf8_encode($html>find('td[class=letra_justificante_cita_negrita]',0)->innertext); $matrizdatos['direccion']=utf8_encode($html>find('td[class=letra_justificante_cita_negrita]',2)->innertext); $matrizdatos['ubicacion']=trim(utf8_encode(html_entity_decode($html>find('td[class=letra_justificante_cita_negrita]',3)->innertext))); $matrizdatos['profesional']=utf8_encode($html>find('td[class=letra_justificante_cita_negrita]',4)->innertext); $matrizdatos['nombre_usuario']=trim(utf8_encode(html_entity_decode($html>find('span[class=letra_justificante_cita_negrita]',0)->innertext))); $matrizdatos['fecha_solicitud']=trim(utf8_encode(html_entity_decode($html>find('span[class=letra_justificante_cita]',4)->innertext))); curl_close ($curl3); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html para no malgastar memoria $json=json_encode($matrizdatos); print (utf8_encode($json)); print ($json); print("SEPARADOR"); print ('{"segundoJSON":"RELLENO"}'); } /* Si $compruebacita=null es que no hay cita asignada todava */ else{ for ( $i = 0 ; $i <= 13 ; $i ++) { $matrizdias['dia'.$i]['value']=$html->find('input[id=dia'.$i.']',0)>value;

139

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


$matrizdias['dia'.$i]['cadena']=utf8_encode($html>find('label[for=dia'.$i.']',0)->innertext); }

Proyecto Fin de Carrera Mara Len Bujes

/* Array asociativo de datos. Como no hay cita asignada, al elemento "enlace_cancelar" le asignamos la cadena "no hay cita que cancelar". Este valor ser el que utilice el widget para saber si debe ir a la vista MostrarDias o la la vista CitaAsignada: */ $matrizdatos['sesion']=$cookies_sesion; $matrizdatos['comprueba_acceso']="ok"; $matrizdatos['enlace_cancelar']="no hay cita que cancelar"; $matrizdatos['tipocita']=$html->find('input[name=tipocita]',0)->value; $matrizdatos['actividad_agenda']=$html>find('input[name=actividad_agenda]',0)->value; $matrizdatos['modalidad_agenda']=$html>find('input[name=modalidad_agenda]',0)->value; $matrizdatos['codigo_agenda']=$html->find('input[name=codigo_agenda]',0)>value; $matrizdatos['codigo_profesional']=$html>find('input[name=codigo_profesional]',0)->value; $matrizdatos['domicilio_usuario']=$html>find('input[name=domicilio_usuario]',0)->value; $matrizdatos['nuss_usuario']=trim($html->find('input[name=nuss_usuario]',0)>value); $matrizdatos['nombre_usuario']=trim($html>find('input[name=nombre_usuario]',0)->value); $matrizdatos['telefonos_usuario']=$html>find('input[name=telefonos_usuario]',0)->value; $matrizdatos['desplazado']=$html->find('input[name=desplazado]',0)->value; $matrizdatos['tarea_desc']=$html->find('input[name=tarea_desc]',0)->value; $matrizdatos['centro_desc']=$html->find('input[name=centro_desc]',0)->value; $matrizdatos['centro_codigo']=$html->find('input[name=centro_codigo]',0)>value; $matrizdatos['nombre_profesional']=$html>find('input[name=nombre_profesional]',0)->value; curl_close ($curl3); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html para no malgastar memoria $json2=json_encode($matrizdatos); print (utf8_encode($json2)); print("SEPARADOR"); $json=json_encode($matrizdias); print (utf8_encode($json)); } } } //Hacemos la llamada a la funcin loginintersas $codigofuente3 = loginintersas ('https://ws003.juntadeandalucia.es/pls/intersas/servicios.localizar_usuario', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1'); ?>

140

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

Archivo seleccion_de_cita2.php
<?php //Incluimos la librera para parsear html include_once('simple_html_dom.php'); function selecciondecita ($url, $agente) { foreach($_POST as $nombre_campo => $valor){ $asignacion = "$" . $nombre_campo . "='" . $valor . "';"; eval($asignacion); } $camposfijos = '&cookies_sesion='.$cookies_sesion.'&tipocita='.$tipocita.'&actividad_agenda='.$ac tividad_agenda.'&modalidad_agenda='.$modalidad_agenda.'&codigo_agenda='.$codigo_ag enda.'&codigo_profesional='.$codigo_profesional.'&domicilio_usuario='.$domicilio_u suario.'&nuss_usuario='.$nuss_usuario.'&nombre_usuario='.$nombre_usuario.'&telefon os_usuario='.$telefonos_usuario.'&desplazado='.$desplazado.'&tarea_desc='.$tarea_d esc.'&centro_desc='.$centro_desc.'&centro_codigo='.$centro_codigo.'&nombre_profesi onal='.$nombre_profesional; $campos = 'diacita='.$diacita0.$camposfijos; /*****************************************************************************/ $curl0 = curl_init(); //Nueva sesion CURL curl_setopt ($curl0, CURLOPT_URL, $url); //Direccion de destino /* Establecemos el valor de las cookies en la nueva peticin. Las cookies se han enviado desde el Widget de Cita Mdica por POST. */ curl_setopt($curl0, CURLOPT_COOKIE, $cookies_sesion); // Para que curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt el resultado de la peticin se almacene en una cadena de texto: ($curl0, CURLOPT_RETURNTRANSFER, 1); ($curl0, CURLOPT_FOLLOWLOCATION, 0); ($curl0, CURLOPT_USERAGENT, $agente); ($curl0, CURLOPT_HEADER, 0); //Oculta encabezado ($curl0, CURLOPT_SSLVERSION, 3); //Especificamos la versin de ssl

/* Para que curl compruebe que el certificado del servidor es vlido (que verifique que la CA o Autoridad Certificadora que lo expidi est entre las CA reconocidas) se asigna el valor true a la opcin CURLOPT_SSL_VERIFYPEER. */ curl_setopt ($curl0, CURLOPT_SSL_VERIFYPEER, true); /* Comprueba que el common name (CN) del certificado de servidor se corresponde con el dominio al que nos estamos conectando. */ curl_setopt ($curl0, CURLOPT_SSL_VERIFYHOST, 2); /* Con la siguiente opcin le indicamos a cURL que confe en los certificados de servidor firmados por una CA cuyo certificado raiz es FNMTClase2CA-FNMT.crt. Este es el certificado raiz de la FNMT que es la autoridad certificadora que expide el certificado de servidor del servidor al que estamos intentando acceder va https (el servidor de InterS@S). El certificado se ha obtenido exportndolo desde Firefox como certificado X.509 con cadena (PEM). Es fundamental que se exporte en este formato para que sea compatible con Curl. Por otra parte getcwd() es una funcin de php que devuelve el directorio actual.*/ curl_setopt ($curl0, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl0, CURLOPT_POST, 1); curl_setopt ($curl0, CURLOPT_POSTFIELDS, $campos); //Ejecutamos sesion CURL $codigofuente0 = curl_exec ($curl0);

141

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

// Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente0); //$html = str_get_html($codigofuente0); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras0['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras0['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos0['numerohoras']=$numerohoras; $matrizdatos0['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos0['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos0['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos0['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos0['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos0['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos0); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras0); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl0); //Cerramos sesion CURL $html->clear(); /*****************************************************************************/ $curl1 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita1.$camposfijos; curl_setopt ($curl1, CURLOPT_URL, $url); curl_setopt($curl1, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl1, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl1, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl1, CURLOPT_USERAGENT, $agente); curl_setopt ($curl1, CURLOPT_HEADER, 0); curl_setopt ($curl1, CURLOPT_SSLVERSION, 3); curl_setopt ($curl1, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl1, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt ($curl1, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl1, CURLOPT_POST, 1);

142

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt ($curl1, CURLOPT_POSTFIELDS, $campos); //Ejecutamos sesion CURL $codigofuente1 = curl_exec ($curl1);

Proyecto Fin de Carrera Mara Len Bujes

// Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente1); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras1['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras1['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos1['numerohoras']=$numerohoras; $matrizdatos1['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos1['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos1['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos1['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos1['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos1['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos1); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras1); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl1); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html para evitar falta de memoria /*****************************************************************************/ $curl2 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita2.$camposfijos; curl_setopt ($curl2, CURLOPT_URL, $url); curl_setopt($curl2, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl2, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl2, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl2, CURLOPT_USERAGENT, $agente); curl_setopt ($curl2, CURLOPT_HEADER, 0); curl_setopt ($curl2, CURLOPT_SSLVERSION, 3); curl_setopt ($curl2, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl2, CURLOPT_SSL_VERIFYHOST, 2);

143

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

curl_setopt ($curl2, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl2, CURLOPT_POST, 1); curl_setopt ($curl2, CURLOPT_POSTFIELDS, $campos); $codigofuente2 = curl_exec ($curl2); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente2); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras2['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras2['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos2['numerohoras']=$numerohoras; $matrizdatos2['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos2['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos2['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos2['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos2['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos2['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos2); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras2); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl2); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl3 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita3.$camposfijos; curl_setopt ($curl3, CURLOPT_URL, $url); curl_setopt($curl3, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl3, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl3, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl3, CURLOPT_USERAGENT, $agente); curl_setopt ($curl3, CURLOPT_HEADER, 0); curl_setopt ($curl3, CURLOPT_SSLVERSION, 3); curl_setopt ($curl3, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl3, CURLOPT_SSL_VERIFYHOST, 2);

144

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

curl_setopt ($curl3, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl3, CURLOPT_POST, 1); curl_setopt ($curl3, CURLOPT_POSTFIELDS, $campos); $codigofuente3 = curl_exec ($curl3); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente3); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras3['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras3['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos3['numerohoras']=$numerohoras; $matrizdatos3['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos3['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos3['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos3['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos3['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos3['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos3); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras3); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl3); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl4 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita4.$camposfijos; curl_setopt ($curl4, CURLOPT_URL, $url); curl_setopt($curl4, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl4, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl4, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl4, CURLOPT_USERAGENT, $agente); curl_setopt ($curl4, CURLOPT_HEADER, 0); curl_setopt ($curl4, CURLOPT_SSLVERSION, 3); curl_setopt ($curl4, CURLOPT_SSL_VERIFYPEER, true);

145

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt curl_setopt curl_setopt curl_setopt ($curl4, ($curl4, ($curl4, ($curl4,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); CURLOPT_POST, 1); CURLOPT_POSTFIELDS, $campos);

$codigofuente4 = curl_exec ($curl4); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente4); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras4['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras4['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos4['numerohoras']=$numerohoras; $matrizdatos4['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos4['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos4['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos4['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos4['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos4['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos4); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras4); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl4); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl5 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita5.$camposfijos; curl_setopt ($curl5, CURLOPT_URL, $url); //Direccion de destino curl_setopt($curl5, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl5, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl5, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl5, CURLOPT_USERAGENT, $agente); curl_setopt ($curl5, CURLOPT_HEADER, 0); curl_setopt ($curl5, CURLOPT_SSLVERSION, 3); curl_setopt ($curl5, CURLOPT_SSL_VERIFYPEER, true);

146

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt curl_setopt curl_setopt curl_setopt ($curl5, ($curl5, ($curl5, ($curl5,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); CURLOPT_POST, 1); CURLOPT_POSTFIELDS, $campos);

$codigofuente5 = curl_exec ($curl5); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente5); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras5['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras5['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos5['numerohoras']=$numerohoras; $matrizdatos5['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos5['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos5['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos5['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos5['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos5['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos5); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras5); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl5); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl6 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita6.$camposfijos; curl_setopt ($curl6, CURLOPT_URL, $url); curl_setopt($curl6, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl6, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl6, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl6, CURLOPT_USERAGENT, $agente); curl_setopt ($curl6, CURLOPT_HEADER, 0); curl_setopt ($curl6, CURLOPT_SSLVERSION, 3); curl_setopt ($curl6, CURLOPT_SSL_VERIFYPEER, true);

147

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt curl_setopt curl_setopt curl_setopt ($curl6, ($curl6, ($curl6, ($curl6,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); CURLOPT_POST, 1); CURLOPT_POSTFIELDS, $campos);

$codigofuente6 = curl_exec ($curl6); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente6); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras6['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras6['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos6['numerohoras']=$numerohoras; $matrizdatos6['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos6['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos6['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos6['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos6['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos6['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos6); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras6); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl6); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl7 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita7.$camposfijos; curl_setopt ($curl7, CURLOPT_URL, $url); curl_setopt($curl7, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl7, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl7, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl7, CURLOPT_USERAGENT, $agente); curl_setopt ($curl7, CURLOPT_HEADER, 0); curl_setopt ($curl7, CURLOPT_SSLVERSION, 3);

148

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt curl_setopt curl_setopt curl_setopt ($curl7, ($curl7, ($curl7, ($curl7,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_SSL_VERIFYPEER, true); CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); CURLOPT_POST, 1);

curl_setopt ($curl7, CURLOPT_POSTFIELDS, $campos); $codigofuente7 = curl_exec ($curl7); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente7); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras7['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras7['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos7['numerohoras']=$numerohoras; $matrizdatos7['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos7['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos7['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos7['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos7['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos7['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos7); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras7); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl7); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl8 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita8.$camposfijos; curl_setopt ($curl8, CURLOPT_URL, $url); curl_setopt($curl8, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl8, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl8, CURLOPT_FOLLOWLOCATION, 0);

149

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt ($curl8, ($curl8, ($curl8, ($curl8, ($curl8, ($curl8, ($curl8, ($curl8,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_USERAGENT, $agente); CURLOPT_HEADER, 0); CURLOPT_SSLVERSION, 3); CURLOPT_SSL_VERIFYPEER, true); CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); CURLOPT_POST, 1); CURLOPT_POSTFIELDS, $campos);

$codigofuente8 = curl_exec ($curl8); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente8); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras8['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras8['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos8['numerohoras']=$numerohoras; $matrizdatos8['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos8['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos8['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos8['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos8['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos8['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos8); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras8); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl8); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl9 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita9.$camposfijos; curl_setopt ($curl9, CURLOPT_URL, $url); curl_setopt($curl9, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl9, CURLOPT_RETURNTRANSFER, 1);

150

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt ($curl9, ($curl9, ($curl9, ($curl9, ($curl9, ($curl9, ($curl9, ($curl9, ($curl9,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_FOLLOWLOCATION, 0); CURLOPT_USERAGENT, $agente); CURLOPT_HEADER, 0); CURLOPT_SSLVERSION, 3); CURLOPT_SSL_VERIFYPEER, true); CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); CURLOPT_POST, 1); CURLOPT_POSTFIELDS, $campos);

$codigofuente9 = curl_exec ($curl9); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente9); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras9['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras9['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos9['numerohoras']=$numerohoras; $matrizdatos9['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos9['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos9['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos9['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos9['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos9['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos9); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras9); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl9); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl10 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita10.$camposfijos; curl_setopt ($curl10, CURLOPT_URL, $url); curl_setopt($curl10, CURLOPT_COOKIE, $cookies_sesion);

151

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt curl_setopt ($curl10, ($curl10, ($curl10, ($curl10, ($curl10, ($curl10, ($curl10, ($curl10,

Proyecto Fin de Carrera Mara Len Bujes

CURLOPT_RETURNTRANSFER, 1); CURLOPT_FOLLOWLOCATION, 0); CURLOPT_USERAGENT, $agente); CURLOPT_HEADER, 0); CURLOPT_SSLVERSION, 3); CURLOPT_SSL_VERIFYPEER, true); CURLOPT_SSL_VERIFYHOST, 2); CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt');

curl_setopt ($curl10, CURLOPT_POST, 1); curl_setopt ($curl10, CURLOPT_POSTFIELDS, $campos); $codigofuente10 = curl_exec ($curl10); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente10); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras10['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras10['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos10['numerohoras']=$numerohoras; $matrizdatos10['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos10['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos10['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos10['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos10['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos10['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos10); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras10); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl10); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl11 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita11.$camposfijos;

152

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

curl_setopt ($curl11, CURLOPT_URL, $url); curl_setopt($curl11, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl11, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl11, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl11, CURLOPT_USERAGENT, $agente); curl_setopt ($curl11, CURLOPT_HEADER, 0); curl_setopt ($curl11, CURLOPT_SSLVERSION, 3); curl_setopt ($curl11, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl11, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt ($curl11, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl11, CURLOPT_POST, 1); curl_setopt ($curl11, CURLOPT_POSTFIELDS, $campos); $codigofuente11 = curl_exec ($curl11); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente11); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras11['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras11['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos11['numerohoras']=$numerohoras; $matrizdatos11['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos11['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos11['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos11['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos11['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos11['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos11); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras11); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl11); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/ $curl12 = curl_init(); //Nueva sesion CURL

153

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

$campos = 'diacita='.$diacita12.$camposfijos; curl_setopt ($curl12, CURLOPT_URL, $url); curl_setopt($curl12, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl12, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl12, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl12, CURLOPT_USERAGENT, $agente); curl_setopt ($curl12, CURLOPT_HEADER, 0); curl_setopt ($curl12, CURLOPT_SSLVERSION, 3); curl_setopt ($curl12, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl12, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt ($curl12, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl12, CURLOPT_POST, 1); curl_setopt ($curl12, CURLOPT_POSTFIELDS, $campos); $codigofuente12 = curl_exec ($curl12); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente12); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras12['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras12['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos12['numerohoras']=$numerohoras; $matrizdatos12['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos12['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos12['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos12['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos12['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos12['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos12); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras12); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl12); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html /*****************************************************************************/

154

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

$curl13 = curl_init(); //Nueva sesion CURL $campos = 'diacita='.$diacita13.$camposfijos; curl_setopt ($curl13, CURLOPT_URL, $url); curl_setopt($curl13, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl13, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl13, CURLOPT_FOLLOWLOCATION, 0); curl_setopt ($curl13, CURLOPT_USERAGENT, $agente); curl_setopt ($curl13, CURLOPT_HEADER, 0); curl_setopt ($curl13, CURLOPT_SSLVERSION, 3); curl_setopt ($curl13, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl13, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt ($curl13, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl13, CURLOPT_POST, 1); curl_setopt ($curl13, CURLOPT_POSTFIELDS, $campos); $codigofuente13 = curl_exec ($curl13); //Ejecutamos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente13); $numerohoras=0; $hora=""; for ( $i = 0 ; $i <= 66 ; $i ++) { $hora=$html->find('input[id=hora'.$i.']',0)->value; if ($hora!=""){ $matrizhoras13['hora'.$numerohoras]['value']=utf8_encode($html>find('input[id=hora'.$i.']',0)->value); $matrizhoras13['hora'.$numerohoras]['cadena']=utf8_encode($html>find('label[for=hora'.$i.']',0)->innertext); $numerohoras=$numerohoras+1; } } $matrizdatos13['numerohoras']=$numerohoras; $matrizdatos13['codigo_agenda']=utf8_encode($html>find('input[name=codigo_agenda]',0)->value); $matrizdatos13['modalidad_agenda']=utf8_encode($html>find('input[name=modalidad_agenda]',0)->value); $matrizdatos13['actividad_agenda']=utf8_encode($html>find('input[name=actividad_agenda]',0)->value); $matrizdatos13['centro_ubicacion_agenda']=utf8_encode($html>find('input[name=centro_ubicacion_agenda]',0)->value); $matrizdatos13['codigo_tarea_agenda']=utf8_encode($html>find('input[name=codigo_tarea_agenda]',0)->value); $matrizdatos13['profesional_agenda']=utf8_encode($html>find('input[name=profesional_agenda]',0)->value); $json=json_encode($matrizdatos13); print ($json); print("SEPARADOR"); if ($numerohoras>0){ $json2=json_encode($matrizhoras13); print ($json2); } else{ print ("SIN CITAS"); } print("SEPARADOR"); curl_close ($curl13); //Cerramos sesion CURL $html->clear();//Eliminamos el objeto html }

155

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


//Hacemos la llamada a la funcin selecciondecita()

Proyecto Fin de Carrera Mara Len Bujes

$codigofuente4 = selecciondecita ('https://ws003.juntadeandalucia.es/citaInternet/seleccion_de_cita.jsp', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1'); ?>

156

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

Archivo cita_asignada.php
<?php //Incluimos la librera para parsear html include_once('simple_html_dom.php'); function citaasignada ($url, $agente) { foreach($_POST as $nombre_campo => $valor){ $asignacion = "$" . $nombre_campo . "='" . $valor . "';"; eval($asignacion); } $curl5 = curl_init(); //Nueva sesion CURL $campos = 'horacita='.$horacita.'&cookies_sesion='.$cookies_sesion.'&codigo_agenda='.$codigo _agenda.'&actividad_agenda='.$actividad_agenda.'&modalidad_agenda='.$modalidad_age nda.'&centro_ubicacion_agenda='.$centro_ubicacion_agenda.'&codigo_tarea_agenda='.$ codigo_tarea_agenda.'&profesional_agenda='.$profesional_agenda.'&nombre_usuario='. $nombre_usuario.'&domicilio_usuario='.$domicilio_usuario.'&telefonos_usuario='.$te lefonos_usuario.'&nuss_usuario='.$nuss_usuario; curl_setopt ($curl5, CURLOPT_URL, $url); //Direccion de destino //Establecemos el valor de las cookies en la nueva peticin. curl_setopt($curl5, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl5, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl5, CURLOPT_FOLLOWLOCATION, 1); curl_setopt ($curl5, CURLOPT_USERAGENT, $agente); curl_setopt ($curl5, CURLOPT_HEADER, 1); //Se incluye el encabezado en la salida curl_setopt ($curl5, CURLOPT_SSLVERSION, 3); /* Para que se compruebe que el certificado del servidor es vlido verificando que la CA (Autoridad Certificadora) que lo expidi est entre las CA reconocidas ponemos la opcin CURLOPT_SSL_VERIFYPEER a true. */ curl_setopt ($curl5, CURLOPT_SSL_VERIFYPEER, true); curl_setopt ($curl5, CURLOPT_SSL_VERIFYHOST, 2); // Para que la FNMT sea reconocida como autoridad certificadora: curl_setopt ($curl5, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl5, CURLOPT_POST, 1); curl_setopt ($curl5, CURLOPT_POSTFIELDS, $campos); $codigofuente5 = curl_exec ($curl5); //Ejecutamos sesion CURL $html = new simple_html_dom(); $html->load($codigofuente5); /* Comprobamos que la sesin no ha caducado. Si hubiese caducado lo que obtenemos, en lugar de los datos de la cita, es un mensaje de sesin caducada: */ $comprueba_sesion=trim($html->find('span[class=letra_contenido_info]',0)>innertext); if ($comprueba_sesion=="En estos momentos no podemos ofrecerle este servicio a travs de Inters@s."||$comprueba_sesion=="Su tiempo de sesin ha caducado. Por favor, identifquese de nuevo en InterS@S."){ $json2='{"comprueba_sesion":"'.$comprueba_sesion.'"}'; print (utf8_encode($json2)); } else{

157

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

/* Hay que obtener una matriz y despus un JSON con los datos que se mostrarn en la vista correspondiente (los datos de la cita). */ $matrizdatos['comprueba_sesion']="ok"; $matrizdatos['enlace_cancelar']=utf8_encode($html>find('a[class=enlace_cancelar_cita]',0)->href); $matrizdatos['fecha_solicitud']=utf8_encode($html>find('span[class=letra_pequena_fecha]',0)->innertext); $matrizdatos['fecha_cita']=utf8_encode($html>find('strong[class=letra_justificante_cita_negrita_big]',0)->innertext); $matrizdatos['hora_cita']=utf8_encode($html>find('strong[class=letra_justificante_cita_negrita_big]',1)->innertext); $matrizdatos['orden']=utf8_encode($html>find('strong[class=letra_justificante_cita_negrita_big]',2)->innertext); $matrizdatos['centro']=utf8_encode($html>find('td[class=letra_justificante_cita_negrita]',0)->innertext); $matrizdatos['direccion']=utf8_encode($html>find('td[class=letra_justificante_cita_negrita]',2)->innertext); $matrizdatos['ubicacion']=utf8_encode(trim(html_entity_decode($html>find('td[class=letra_justificante_cita_negrita]',3)->innertext))); $matrizdatos['profesional']=utf8_encode($html>find('td[class=letra_justificante_cita_negrita]',4)->innertext); $matrizdatos['nombre_usuario']=trim(utf8_encode(html_entity_decode($html>find('span[class=letra_justificante_cita_negrita]',0)->innertext))); $matrizdatos['fecha_solicitud']=trim(utf8_encode(html_entity_decode($html>find('span[class=letra_justificante_cita]',4)->innertext))); $json=json_encode($matrizdatos); print ($json); } curl_close ($curl5); //Cerramos sesion CURL $html->clear(); } //Hacemos la llamada a la funcin selecciondecita() $codigofuente5 = citaasignada ('https://ws003.juntadeandalucia.es/citaInternet/cita_asignada.jsp', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1'); ?>

158

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR

Proyecto Fin de Carrera Mara Len Bujes

Archivo cancelacion_de_cita.php
<?php //Incluimos la librera para parsear html include_once('simple_html_dom.php'); function cancelaciondecita ($url, $agente) { foreach($_POST as $nombre_campo => $valor){ $asignacion = "$" . $nombre_campo . "='" . $valor . "';"; eval($asignacion); } /********************************************************************************/ $curl0 = curl_init(); //Nueva sesion CURL $enlace_cancelar_completo="https://ws003.juntadeandalucia.es/citaInternet/".$enlac e_cancelar0."&hora_inicio=".urlencode($hora_inicio)."&fecha=".urlencode($fecha)."& nombre_usuario=".urlencode($nombre_usuario); curl_setopt ($curl0, CURLOPT_URL, $enlace_cancelar_completo); /* Establecemos el valor de las cookies en la nueva peticin. Las cookies se han pasado por POST desde el widget con el nombre cookies_sesion y en el bucle for del inicio de la funcin se han guardado en la variable $cookies_sesion. */ curl_setopt($curl0, CURLOPT_COOKIE, $cookies_sesion); curl_setopt ($curl0, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($curl0, CURLOPT_FOLLOWLOCATION, 1); curl_setopt ($curl0, CURLOPT_USERAGENT, $agente); curl_setopt ($curl0, CURLOPT_HEADER, 0); //Oculta encabezado // Se especifica la versin de SSL del servidor de InterS@S: curl_setopt ($curl0, CURLOPT_SSLVERSION, 3); /* Con la siguiente opcin se exige la comprobacin del certificado del servidor para lo cual se verificar que la CA (Autoridad Certificadora) que lo expidi est entre las CA reconocidas. */ curl_setopt ($curl0, CURLOPT_SSL_VERIFYPEER, true); /* Se comprueba que el common name (CN) del certificado de servidor se corresponde con el dominio al que nos estamos conectando. */ curl_setopt ($curl0, CURLOPT_SSL_VERIFYHOST, 2); /* En esta opcin de cURL se especifica el certificado raiz de la FNMT (CA que expide el certificado del servidor al que estamos intentando acceder va https). Con esto le decimos a cURL que es una CA reconocida. El certificado se obtiene de exportndolo desde Firefox como certificado X.509 con cadena (PEM). Es fundamental que est en este formato para que sea compatible con Curl. Por otra parte getcwd() es una funcin de php que obtiene el directorio actual. */ curl_setopt ($curl0, CURLOPT_CAINFO, getcwd().'/FNMTClase2CA-FNMT.crt'); curl_setopt ($curl0, CURLOPT_POST, 0); //curl_setopt ($curl0, CURLOPT_POSTFIELDS, $campos); $codigofuente0 = curl_exec ($curl0); //Ejecutamos sesion CURL curl_close ($curl0); //Cerramos sesion CURL // Hay que obtener una matriz y despus un JSON con los das de cita disponibles $html = new simple_html_dom(); $html->load($codigofuente0); /* trim() elimina los espacios del inicio y del final de la cadena, utf8_encode() pasa la codificacin de ISO-8859-1 a utf8, html_entity_decode() convierte las entidades html que haya en la cadena (como &iacute;) a su correspondiente carcter ( en este caso): */

159

ANEXO II: ARCHIVOS CREADOS PARA IMPLEMENTAR LA WEB API EN EL SERVIDOR


$matriz['informacion']=trim(utf8_encode(html_entity_decode($html>find('span[class=letra_contenido_info]',0)->innertext)));

Proyecto Fin de Carrera Mara Len Bujes

/* Con la funcin json_encode() de PHP obtenermos una cadena en formato json a partir de la matriz asociativa $matriz */ $json=json_encode($matriz); print ($json); $html->clear(); } //Hacemos la llamada a la funcin selecciondecita() $codigofuente4 = cancelaciondecita ('https://ws003.juntadeandalucia.es/citaInternet/seleccion_de_cita.jsp', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1'); ?>

160

Potrebbero piacerti anche