cesnavarra 2008-boletín 12

98
Título Del oficio. Texto "El sector de la informática, tan vivaz e innovador en el trabajo pero tan dormido en la defensa de sus intereses..." (Little Bighorn y las ingenierías informáticas). Hace unas semanas recibí un correo diciendo que la carrera de informática, carrera docente se entiende, iba a desaparecer. Por ello se animaba a secundar las movilizaciones convocadas. El germen creo que estaba en la postura del PSOE a la hora de rechazar una iniciativa del PP respecto a una proposición no de ley en comisión parlamentaria. En ellas el PP insta a "crear las correspondientes fichas de grado y máster donde se reflejen las competencias de los titulados en ingeniería informática, dando así igual trato que al resto de las ingenierías". Más allá de lo que esto implique, tras ver los videos de la comisión lo único que me quedó claro es que nuestros representantes actúan y hablan de forma cuando menos curiosa. El diputado del BNG apoya al PP quizás porque, como indica él mismo, es paisano del diputado popular. Lo felicita y suscribe su iniciativa con el único argumento de que de seguir las cosas así la titulación desaparecería. No razona si esto es bueno o malo, parece dar por sentado que el que desaparezca una titulación es malo. En este caso coincido con él pero no parece razonar más su postura. Tras la renuncia de algunos grupos a intervenir, la diputada de CiU toma la palabra. Tras realizar un panegírico de la profesión informática empieza a hablar "En este marco del espacio europeo superior..." y a partir de ahí no entiendo ya casi nada salvo que es una especie de sí pero no y que el no es para lo que propone el PP: perdón, la abstención, porque como he dicho es un sí pero no. Finalmente habla el diputado del PSOE, flanqueado por una, supongo, compañera de partido que asiente su intervención en silencio y que, además, tiene problemas con su chaqueta. Dicho parlamentario también alaba al sector informático y luego empieza a citar ofertas de titulaciones o masters como el de "biología computacional" y otros. Tras varios minutos de conversación null, en mi opinión ni cierta ni falsa, da por cerrada su argumentación. Tras esto se vota y se rechaza la proposición no de ley. Esta claro que si hay un problema con el sector, en las Cortes no me lo han aclarado. Me llegó entonces un enlace de un blog en el que se trata la cuestión: ¿qué pasa con la ingeniería informática? Y leyéndolo es cuando empecé a tener una visión más clara del bosque formado por los árboles que arriba he descrito.

Upload: cein

Post on 05-Dec-2014

1.316 views

Category:

Documents


7 download

DESCRIPTION

Respuesta Digital

TRANSCRIPT

Page 1: Cesnavarra 2008-boletín 12

Título Del oficio.

Texto "El sector de la informática, tan vivaz e innovador en el

trabajo pero tan dormido en la defensa de sus intereses..." (Little Bighorn y las ingenierías informáticas). Hace unas semanas recibí un correo diciendo que la carrera de informática, carrera docente se entiende, iba a

desaparecer. Por ello se animaba a secundar las movilizaciones convocadas. El germen creo que estaba en la postura del PSOE a la hora de rechazar una iniciativa del PP respecto a una proposición

no de ley en comisión parlamentaria. En ellas el PP insta a "crear las correspondientes fichas de grado y máster donde se

reflejen las competencias de los titulados en ingeniería informática, dando así igual trato que al resto de las ingenierías". Más allá de lo que esto implique, tras ver los

videos de la comisión lo único que me quedó claro es que nuestros representantes actúan y hablan de forma cuando

menos curiosa. El diputado del BNG apoya al PP quizás porque, como indica él mismo, es paisano del diputado popular. Lo felicita y suscribe

su iniciativa con el único argumento de que de seguir las cosas así la titulación desaparecería. No razona si esto es

bueno o malo, parece dar por sentado que el que desaparezca una titulación es malo. En este caso coincido con él pero no

parece razonar más su postura. Tras la renuncia de algunos grupos a intervenir, la diputada de CiU toma la palabra. Tras realizar un panegírico de la

profesión informática empieza a hablar "En este marco del espacio europeo superior..." y a partir de ahí no entiendo ya

casi nada salvo que es una especie de sí pero no y que el no es para lo que propone el PP: perdón, la abstención, porque como he dicho es un sí pero no. Finalmente habla el diputado del PSOE, flanqueado por una, supongo, compañera de partido que asiente su intervención

en silencio y que, además, tiene problemas con su chaqueta. Dicho parlamentario también alaba al sector informático y luego empieza a citar ofertas de titulaciones o masters como

el de "biología computacional" y otros. Tras varios minutos de conversación null, en mi opinión ni cierta ni falsa, da por

cerrada su argumentación. Tras esto se vota y se rechaza la proposición no de ley. Esta claro que si hay un problema con el sector, en las Cortes no me lo han aclarado. Me llegó entonces un enlace de un

blog en el que se trata la cuestión: ¿qué pasa con la ingeniería informática? Y leyéndolo es cuando empecé a tener una visión más clara del bosque formado por los árboles que

arriba he descrito.

Page 2: Cesnavarra 2008-boletín 12

En todo esto el tema que más me interesa es el de si la profesión informática debe estar regulada o no. En mi opinión

no es ésta una pregunta a responder de forma aislada sino teniendo en cuenta el contexto laboral. Esto es: ¿por qué hay que regular unas profesiones y otras

no? ¿Por qué, de hecho, hay profesiones reguladas y otras no? Un argumento suele ser el que las profesiones que están reguladas se dedican a actividades que por su dificultad o implicación deben tener algún tipo de control o de garantía de

que quienes la realizan están capacitados para ello. Los ejemplos habituales son los siguientes: los planos de un

edificio deben estar firmados por un arquitecto para garantizar su seguridad, habitabilidad, etc. Una operación debe ser realizada por un médico para garantizar su éxito,

etc. ¿Y un proyecto informático no? Muchas personas en estos

casos realizan el siguiente razonamiento: programar es fácil, luego no hace falta regular dicha actividad. Aparte de que la realización de un proyecto informático no es sólo codificar,

podría decirse que sí que programar ciertas cosas, por ejemplo una macro de Word (y depende cuales, os lo

aseguro) es fácil pero también lo es aplicar mercromina a una herida y colocar encima de ella un apósito pero nadie llama a eso "intervención quirúrgica". Por otro lado es curioso como para realizar ciertas actividades que no considero triviales no se necesita más que pasar unas

pruebas o incluso sólo tener la intención de realizarlas: y si no piénsese en que para opositar a plazas de policía o alistarse en las fuerzas armadas se necesita acreditar pocas aptitudes.

Y no creo que estas profesiones sean menos críticas o más fáciles que desempeñar que todas las aquí descritas. Otro tema que ha salido a relucir con esta polémica es el del

intrusismo, que es la otra cara de la moneda de lo antes expuesto: puesto que no es necesario acreditarse de alguna forma para ejercitar la profesión de informático, cualquiera

puede hacerlo. A este respecto voy a contar mi experiencia: cuando

coordinaba un equipo de desarrolladores, solicitamos de una empresa de servicios un perfil de programador. Dicha empresa, que ya nos había proporcionado anteriormente

personas que cubrieron satisfactoriamente nuestras necesidades no envió el currículum de su candidato. El mismo

era licenciado en Farmacia y había realizado un curso de varios meses de programación en Java. Teníamos dos opciones: rechazarlo a priori o confiar en nuestro proveedor y

ver qué tal trabajaba esa persona. Resultó que era lo que necesitábamos: un programador que realizaba a conciencia su

trabajo. Acertamos: no nos importó el pedigrí del candidato sino sus resultados.

Page 3: Cesnavarra 2008-boletín 12

Meses más tarde mi rol cambió y era analista en un proyecto

internacional con tres equipos de desarrollo situados en España, Argentina y los Estados Unidos respectivamente.

El project leader del mismo era un estadounidense cuya formación era en... ¡música! El recuerdo que tengo es que sabía orquestar muy bien al equipo, combinando

idiosincrasias y manejando ritmos. En la actualidad me encuentro trabajando con colegas que en

su mayor parte son titulados en telecomunicaciones y sigo aplicando el mismo criterio: no me digas de dónde vienes sino vamos a ver cómo podemos trabajar juntos. Creo que uno de los problemas de la informática es la forma

en que se percibe: algo de lo que ya hemos tratado en estos artículos. Y otro el de la ignorancia de lo que un titulado en informática

tiene que estudiar para titularse, ya sea como ingeniero técnico o superior. Podríamos hacer un pequeño test: ¿cuáles de estas asignaturas aparecen en los planes de estudios de dichas carreras?

Álgebra Algoritmia Contabilidad Analítica Economía de la Empresa Estadística Estrategia y Política de Empresa Financiación e Inversión Inteligencia Artificial e Ingeniería del Conocimiento Introducción a la Mercadotecnia Organización de Empresas Planificación y Gestión de Proyectos Informáticos Robótica Industrial Simulación Informática Sistemas de Información Contable

La respuesta es: todas. Mi conclusión es la siguiente: la profesión informática está presente en todos los ámbitos de la vida actual. Aún así la

ignorancia acerca de los conocimientos que deben adquirirse para ser un titulado en la misma es más que notable. Y si uno ignora qué conocimientos tiene su empleado, difícilmente

podrá saber utilizar todo su potencial. Por otro lado no creo que haya que blindar el terreno profesional para que sólo los

que tengan carnet de socio puedan acceder al club de la informática. Pero esto debería ser una regla general a todo el

mercado laboral y no sólo a la informática: o todos o ninguno. Finalmente una pequeña autocrítica: los informáticos estamos

habituados a trabajar con máquinas que únicamente atienden a programas, que son la formalización unívoca de unos

Page 4: Cesnavarra 2008-boletín 12

requerimientos. E intentamos trasladar esa lógica del

verdadero/falso a las relaciones humanas, y por ende laborales, comerciales... En esto debemos aprender que las

cosas no son blanco o negro o que, si lo son, puede que no logremos convencer de ello a aquellos con quienes interactuamos. En esto seguimos siendo un poco utópicos: pensamos que "tenemos razón" y que con esto basta. Es similar a lo que aparecía en una escena del biopic "Pirates of Silicon Valley" en el que hay una escena con un supuesto

diálogo entre Steve Jobs y Bill Gates. En el mismo, Jobs intenta decir la última palabra exclamando algo así como:

"Somos mejores que tú... Tenemos productos mejores.", a lo que responde Gates: "¿No lo entiendes, Steve? Eso no importa."

Si quieres enviar algún comentario o sugerir temas a tratar en otros artículos, escribe a:

curtasun[simboloArroba]cein.es

Categorías General

Tema Varios

Autor Carlos Urtasun

Mes Diciembre

Año 2008

Boletín 12

Títu

lo

Proyecto piloto TDT: parte 4: fase 2

Tex

to

Esta segunda fase arrancó con el segundo comité. Comité en el cual

se presentaban los trabajos realizados hasta ese momento, es decir,

la primera fase completada, ya comentada en artículos anteriores, y

el planteamiento del proyecto desde ese momento hasta el final del

proyecto.

Este planteamiento consistía en establecer los trabajos a realizar por

parte del equipo local, número y planificación, junto con la

transferencia de conocimiento y papel que SiTVi debía ejercer durante

Page 5: Cesnavarra 2008-boletín 12

esta segunda fase. Para ello se partía del resultado del análisis de

servicios a adaptar a TDT realizados durante la primera fase, que

trajeron no pocos quebraderos de cabeza y de la finalización de la

preparación formal del equipo local.

Del análisis teníamos como resultado una lista de posibles servicios a

implementar en TDT, no obstante, no había identificados unas fuentes

fiables de información en ninguno de ellos y tampoco había asegurada

la incorporación de ningún servicio interactivo (con capacidad de

realizar peticiones mediante el uso del canal de retorno) dada la

imposibilidad de contar con una interacción con los sistemas de

Gobierno de Navarra (a través de servicios web) en la fecha presente.

Dado que había muchos flecos en prácticamente todos los servicios

que se irían aclarando con el estudio concreto de cada uno y dada la

existencia de un plan de modernización paralelo que iba afectar a los

sistemas de la información y por tanto, cambiar la situación actual, la

lista, prioridad y posición de cada servicio dentro de la misma podía

variar. De hecho, debía irse adaptando conforme se obtuviese más

información de los mismos a lo largo de los desarrollos de la segunda

fase. En resumen, había una gran indeterminación.

Servicio Prioridad Fuente

Meteorología Alta Extracción automatizada de la

información directamente de la fuente

Información

estática

Alta Inserción manual

Agenda de ocio y

cultura

Alta Extracción directa de BBDD

Farmacias de

guardia

Alta Extracción directa de BBDD

Centros de salud Alta Extracción directa de BBDD

Carreteras Alta Tempos21: analizar alternativas

Empleo público

(convocatorias)

Alta Tempos21: previo filtrado de la

información

Page 6: Cesnavarra 2008-boletín 12

Vivienda Alta-

Media

A determinar

BON Media Dentro del plan de modernización: a

determinar en octubre

Empleo privado Media Dentro del plan de modernización: a

determinar en otoño

Esto es, se habían identificado 10 posibles servicios, de los cuales, los

7 primeros eran informativos mientras que los 3 últimos podían

presentar algo de interactividad.

No obstante, existía una gran indeterminación en el posible uso de

estos 3 últimos puesto que en el momento del análisis, tal y como he

comentado, no existía ningún servicio web disponible para

implementar la interactividad en el servicio, circunstancia que podía

cambiar por el plan de modernización que afectaba directamente a

dos de estos servicios.

Entre los informativos, tras muchas averiguaciones se vio la dificultad

y riesgo de emplear el desarrollo de Tempos21 como fuente de

información ya procesada con lo que se planteó buscar la fuente de

datos original. Para los dos primeros ya se tenía detectada una

alternativa útil y por tanto podían implementarse en TDT, mientras

que en los restantes se sabía de la existencia de bases de datos que

almacenaban cierta información necesaria para cada uno de los

servicios pero se desconocía con certeza su naturaleza y por tanto, no

se podía asegurar en todos los casos su uso. De echo, para los

servicios de Carreteras y Empelo público, ni siquiera se tenía

constancia de la existencia de una base de datos, lo cual implicaría el

uso de Tempos21 como fuente de información ante la inexistencia de

una alternativa.

Por otro lado, el equipo local se encontraba “preparado”, había

recibido la formación adecuada relacionada con conceptos generales

de la TDT, el estándar MHP y el uso de la herramienta de autor a

emplear iDesginer. No obstante, como hemos adelantado, la

formación no terminaba ahí, esta tan solo había sido la parte teórica.

A continuación comenzaría la formación práctica basada en la

Page 7: Cesnavarra 2008-boletín 12

experimentación real con los trabajos a realizar, para lo cual se

definió junto con SiTVi un planteamiento de transferencia de

conocimiento: se identificaron una lista de habilidades a adquirir y

unos niveles para cada una de ellas, A, B y C, siendo A el nivel más

básico y C el más avanzado. Estas habilidades o conocimiento se

agruparon según su aplicación a las tareas de desarrollo, quedando el

siguiente planteamiento:

Niveles

A B C

Toma de requisitos

Ingeniería de software - Metodología de

desarrollo: toma de requisitos, análisis, diseño

aplicación.

X X X

Análisis funcional

Ingeniería de software - Metodología de

desarrollo: toma de requisitos, análisis, diseño

aplicación.

X X X

Diseño

Desarrollo MHP - Diseño y usabilidad. X X X

Integración y formateo de datos de entrada

Backend – Procesado de datos. X X X

Backend – Tratamiento de XML, XSLT. X X X

Conocimiento del entorno - Desarrollo con el

entorno de IDesigner.

X X X

Java – Desarrollo basado en Java (bajo nivel, sin uso de IDesigner).

X

Implementación del interfaz

Desarrollo MHP – Interfaz

gráfico (disposición/layout de componentes)

X X X

Java – Desarrollo de plugins (personalización

y creación de componentes gráficos para

X

Page 8: Cesnavarra 2008-boletín 12

IDesigner).

Java – Desarrollo basado en Java (bajo nivel, sin uso de IDesigner).

X

Conocimiento del entorno - Desarrollo con el entorno de IDesigner

X X X

Implementación de funcionalidades

Desarrollo MHP – Uso de formularios de entrada

(procesado de datos). X X X

Java – Desarrollo de plugins (personalización

y creación de componentes gráficos para IDesigner).

X

Java – Desarrollo basado en Java (bajo nivel, sin uso de IDesigner).

X

Conocimiento del entorno - Desarrollo con el entorno de IDesigner

X X X

Integración con servicios web

Desarrollo MHP - Canal de retorno. X

Backend - Interacción con servicios web:

post/xml, get/xml, soap.

X

Java – Desarrollo basado en Java (bajo nivel, sin uso de IDesigner).

X

Conocimiento del entorno - Desarrollo con el entorno de IDesigner

X X

Ejecución de pruebas

Conocimiento del entorno - Conocimiento de

puesta en producción de aplicaciones en el

laboratorio: encapsulador (iMux).

X

Conocimiento del entorno - Realización de pruebas

de aplicaciones. X X X

Backend - Parametrización de aplicaciones. X

Ingeniería de software - Metodología de

pruebas.

X X X

Puesta en emisión:

Backend - Parametrización de aplicaciones. X

Puesta en producción de aplicaciones: X X

Page 9: Cesnavarra 2008-boletín 12

comunicación con Abertis.

Dada la nula experiencia en TDT del equipo local se decidió comenzar

con un servicio sencillo de implementar en el que participasen todos

los miembros del equipo. Además, esto permitía arrancar la segunda

fase del proyecto con un servicio concreto y definido y así tener un

colchón suficiente para ir concretando el resto. Posteriormente, tras la

experiencia adquirida, se podían ir acometiendo más servicios en

paralelo mediante la distribución del trabajo entre los miembros del

equipos local. Se trabajaría con la lista identificada anterior como si

fuera un “pool” de servicios, decidiendo su incorporación al desarrollo

según la información recopilada en cada caso, la viabilidad y

evolución de las circunstancias:

Page 10: Cesnavarra 2008-boletín 12

Por tanto, este plan nos daba 5 servicios a incorporar de aquí al final

del proyecto, 4 informativos y un último interactivo aún por

determinar dependiendo del plan de modernización. Se decidió

comenzar por un servicio de modo que todo el equipo pudiera

participar e ir adaptándose al desarrollo de aplicaciones interactivas

con MHP para TDT de forma paulatina. De este modo, en este primer

servicio se podía hacer más hincapié en la labor de transferencia de

conocimiento que posteriormente se iría diluyendo a lo largo del

proyecto conforme el equipo adquiriese soltura y conocimientos y

convirtiéndose más bien en una labor de consultoría. Así pues, en los

servicios posteriores, tras esta toma de contacto y adaptación, podía

configurarse un equipo más eficiente de modo que se dividiesen los

trabajos y se pudiesen implementar y afrontar dos servicios en

paralelo cada vez. Dada la disponibilidad de 4 personas (se contaba

con 3 personas en el equipo local y un becario cedido por SiTVi como

refuerzo y apoyo), se podía dividir el equipo en 2 grupos de 2

personas cada uno. De modo que en los servicios informativos, una

persona del grupo pudiese dedicarse a las labores de extracción y

formateo de datos y la otra persona del grupo concentrarse en el

desarrollo MHP. En el caso del servicio interactivo, no existía

extracción y formateo de datos, pero la interacción complicaba el

desarrollo MHP que podía equilibrarse con la dedicación de dos

personas en este caso. Los roles y responsabilidades de cada

participante así como los propios grupos irían cambiando y rotando

con cada desarrollo de modo que todos los miembros del equipo local

experimentasen con todas las partes del desarrollo. La lista de

conocimientos y niveles antes citada encajaba dentro de este

planteamiento de la siguiente manera:

Page 11: Cesnavarra 2008-boletín 12

Esto es, los conocimientos de nivel A, se adquirirán con el desarrollo

del primer servicio. Durante el desarrollo del siguiente servicio, se

asimilarán los conocimientos de nivel B, consolidando, a su vez, los

de nivel A adquiridos en el desarrollo anterior. De igual modo,

durante el último servicio, se aprenderán los conocimientos de nivel

C, consolidando los de nivel B adquiridos en anteriores desarrollos y

asumiendo la completa responsabilidad de las tareas de nivel A.

Así pues, como se ha adelantado, se determinó comenzar con un

servicio, buscando el más sencillo y a la vez el que más garantías de

éxito pudiese ofrecer de la lista de servicios posibles. De entre todos

ellos, serios candidatos eran: Meteorología, Farmacias de Guardia,

Centros de Salud, Información Estática y Agenda de cultura y ocio.

Dado que de todos ellos, tan solo Meteorología teníamos realmente

identificada la fuente de información se decidió comenzar con el.

METEOROLOGÍA

Para profundizar en el análisis de la fuente de información y el

servicio, se organizó una reunión con el área de Meteorología

del Departamento de Agricultura, Ganadería y Alimentación del

Gobierno de Navarra, responsables del desarrollo de meteorología

para el portal web www.navarra.es.

Aunque se propuso un servicio muy interesante por el cual se

proporcionaba información en tiempo real de estaciones

meteorológicas, este hubiese requerido un análisis más profundo y

tratándose de un desarrollo más complejo hubiese retrasado el

desarrollo, por lo que fue descartado y se continuó con los planes

iniciales. Así pues, se determinó que el servicio a implantar en TDT

sería el de la predicción meteorológica. En concreto, las siguientes

predicciones:

Predicción meteorológica en Navarra para hoy.

Predicción meteorológica en Navarra para mañana.

Predicción meteorológica en Navarra para los próximos días.

Predicción meteorológica en el pirineo.

Page 12: Cesnavarra 2008-boletín 12

Predicción nivológica, sólo disponible en temporada de nieve.

Predicción avisos y alertas cuando los hubiere.

Imagen de radar.

Esta información, ofrecida en el portal web, se extraía del Instituto

Nacional de Meteorología (en adelante INM), ahora la actual Agencia

Estatal de Meteorología (AEMET). El formato de datos proporcionado

por el INM venía heredado de mucho tiempo atrás, cuando no se

empleaban los caracteres particulares del español como los acentos,

las eñes, etc. Esto unido al uso exclusivo de mayúsculas y a la

inexistencia de traducciones a diferentes idiomas (entre ellos el

Euskera) dificultaba las cosas. La aplicación a diseñar sería

multilingüe, como en todos los casos, aunque la disponibilidad de la

información estaría sujeta a su existencia. En este caso, la

información tan solo podía ser servida en español.

NOTA: posteriormente, a finales del 2007, los responsables del portal

realizaron un filtrado de la información de modo que esta se

visualizaba en minúsculas y realizaban correcciones ortográficas para

incluir los acentos y las eñes. No obstante, esta información contenía

tags html, con lo que requería un procesado previo antes de poder

ser incluida en TDT. Esta novedad no pudo ser incorporada finalmente

al proyecto por falta de tiempo y recursos.

Toda esta información era facilitada en forma de ficheros individuales

por cada una de las predicciones anteriores. Estos ficheros estaban

localizados en un servidor de FTP al que nos dieron acceso para la

conexión y descarga de la información.

La visualización de esta información, interfaz, presentó algunos

problemas en TDT. En el portal www.navarra.es, la información de

predicción correspondiente al día actual, el día siguiente y los

próximos días, eran visualizadas de forma conjunta. Esta información

consistía en un texto y en la imagen de un mapa de navarra

actualizados diariamente pero de forma independiente. La imagen del

mapa se correspondía con la predicción para el día siguiente, no

obstante, esta información se actualizaba en torno al medio día, con

lo que en las primeras horas del día el mapa se correspondía con la

Page 13: Cesnavarra 2008-boletín 12

predicción del día anterior, o visto de otra forma, la previsión del día

actual realizada el día anterior.

El interfaz en TDT impedía mostrar las 3 predicciones anteriores de

forma conjunta por problemas de espacio. Por esa razón se

implementaron de forma separada, lo cual, planteaba el problema de

donde ubicar el mapa de predicción común. Finalmente se decidió que

la predicción del día siguiente contendría el texto y la imagen del

mapa correspondiente, actualizado a medio día, momento en el cual,

la imagen del mapa anterior pasaría a la predicción del día actual.

Probablemente esta circunstancia podrí haberse resuelto de forma

más óptima de poder haber tenido más libertad sobre la disposición

de componentes en el interfaz, no obstante, la herencia de los

servicios en TDT anteriores marcaba una línea gráfica de la cual no

era posible salir.

Otro escollo asociado al interfaz en TDT resultaron ser las propias

imágenes por el origen de las mismas. Se trataba de imágenes con

tamaño y formato adaptado al entorno web, además de tratarse de

imágenes de calidad reducida, óptima para entorno web. Estas

debieron ser escaladas para adaptare al interfaz de TDT, acentuando

la mala calidad. Esto unido a la diferente visualización de los colores

en TDT dieron como resultado unas imágenes bastante pobres, no

obstante, no se contaba con otra fuente de datos alternativa.

A continuación se muestran unos bocetos del interfaz que indican la

ubicación de cada elemento gráfico:

Page 14: Cesnavarra 2008-boletín 12

Es decir, y como se ha mencionado, por coherencia se mantuvo el

Page 15: Cesnavarra 2008-boletín 12

diseño gráfico establecido en las aplicaciones anteriores:

Menú superior de acceso a otros servicios en TDT,

Menú inferior con los controles directos del mando de

televisión.

Menú propio del servicio actual situado a la izquierda.

La emisión del vídeo en la esquina inferior izquierda.

El espacio útil de visualización situado en el centro.

En este caso, el menú izquierdo se correspondía con cada una de las

predicciones a visualizar de forma independiente a modo de

secciones.

El área útil mostraba la información de predicción correspondiente a

la sección elegida. Para el caso de la predicción de hoy y mañana, se

desarrolló un componente que conmutaba entre la predicción de texto

y la predicción con la imagen, dado que las limitaciones del interfaz

en TDT impedían su visualización simultánea.

De igual modo, se mantuvo (como se verán en las imágenes de

resultado final) el estilo heredado de las aplicaciones anteriores en

cuanto a uso de colores, diseño de botones, etc.

En cuanto al proceso que recogía, procesaba y publicaba la

información en TDT, el sistema presentaba la siguiente arquitectura:

Esto es:

1. Proceso de adquisición de datos: se trataba de un sistema independiente que monitorizaba los ficheros determinados

ubicados en el servidor FTP. En caso de que hubiese cambios, los descargaba y procesaba para construir los ficheros XML que servirían como fuente de información a la aplicación MHP a

ejecutar en el televisor. Este proceso dejaba los ficheros XML generados en unas ubicaciones de carpetas preestablecidas en

un servidor local. 2. Proceso de publicación: se trataba de un sistema que

conjugaba los ficheros obtenidos y formateados en el proceso

Page 16: Cesnavarra 2008-boletín 12

anterior y los mezclaba con los fuentes de la aplicación para

generar el empaquetado compilado final. No obstante, no se enviaba a publicación el empaquetado completo, puesto que

sería requisito indispensable que la aplicación ya se encontrase disponible en el aire, por lo cual, tan solo se actualizaría la parte correspondiente a la información, manteniendo la

aplicación intacta. Tal y como se explicó en el artículo anterior, esto se hace así, puesto que cada actualización de la lógica

conlleva un proceso de validación previo por parte de Abertis que sería inmanejable en el día a día de una aplicación informativa de contenidos actualizables diariamente como es el

caso. La actualización se realiza de nuevo mediante un acceso por FTP a la información publicada en TDT proporcionada por

Abertis.

Esto es:

1. Proceso de adquisición de datos: se trataba de un sistema

independiente que monitorizaba los ficheros determinados ubicados en el servidor FTP. En caso de que hubiese cambios, los descargaba y procesaba para construir los ficheros XML que

servirían como fuente de información a la aplicación MHP a ejecutar en el televisor. Este proceso dejaba los ficheros XML

generados en unas ubicaciones de carpetas preestablecidas en un servidor local.

2. Proceso de publicación: se trataba de un sistema que conjugaba los ficheros obtenidos y formateados en el proceso anterior y los mezclaba con los fuentes de la aplicación para

generar el empaquetado compilado final. No obstante, no se enviaba a publicación el empaquetado completo, puesto que

sería requisito indispensable que la aplicación ya se encontrase disponible en el aire, por lo cual, tan solo se actualizaría la parte correspondiente a la información, manteniendo la

aplicación intacta. Tal y como se explicó en el artículo anterior, esto se hace así, puesto que cada actualización de la lógica

conlleva un proceso de validación previo por parte de Abertis que sería inmanejable en el día a día de una aplicación

Page 17: Cesnavarra 2008-boletín 12

informativa de contenidos actualizables diariamente como es el

caso. La actualización se realiza de nuevo mediante un acceso por FTP a la información publicada en TDT proporcionada por

Abertis. Aquí surgió por primera vez, el concepto de la plataforma de TDT.

Como era de esperar, esta consistía en una extracción de información

del back office y su procesado para emisión en TDT. Debía

establecerse un mecanismo que fuese común y reutilizable en todos

los servicios que independizasen información y presentación. Lógico,

pero muy difícil. Cada servicio requería procesos de extracción

diferentes, como posteriormente se vería, según la fuente de datos y

la propia información a extraer en cada caso. No obstante la filosofía

en todos los casos fue la misma, definiendo un formato de fichero

XML particular para cada aplicación que independizaba al menos la

información de la aplicación MHP, la lógica. El proceso, no obstante,

que si podía ser común o al menos reutilizado era el de publicación.

Una vez procesada la fuente de información y generado el XML base,

los pasos a partir de ahí eran los mismos en todos los casos,

compilar, empaquetar y enviar la información a Abertis para su

actualización en emisión.

En torno a esta cuestión, empezaron a tenerse las primeras reuniones

con sistemas de Gobierno de Navarra para definir esta plataforma de

extracción de datos y publicación en TDT, tanto a nivel hardware

como software. Para esto se redactaron una serie de documentos

solicitados por sistemas en los cuales se trataba de definir la

plataforma, pero de forma bastante abstracta puesto que no se

conocían las implicaciones ni requerimientos del resto de servicios por

desarrollar. De nuevo, todo se debía ir definiendo sobre la marcha. En

cualquier caso, sistemas estableció una serie de condicionantes que

aplicaban tanto a nivel hardware como software que daban una idea

de por donde debían ir las cosas. Se comenzó definiendo que estos

procesos podían ser aplicaciones Java que corriesen como demonios,

sin necesidad de ningún framework o requisito adicional que el propio

proceso, lo cual limitaba mucho las posibilidades. No obstante, como

se verá más adelante, estos requerimientos y condicionantes irían

cambiando a lo largo del proyecto.

La dificultad para ir definiendo todo esto, hizo que la plataforma

estuviese alojada de forma temporal en la infraestructura

proporcionada por los CES, hasta el momento en que fuera viable su

traspaso a sistemas de Gobierno, una vez definida por completo la

plataforma y disponible una infraestructura donde alojarla. No fue,

Page 18: Cesnavarra 2008-boletín 12

como se verá posteriormente, hasta el final del proyecto que pudo

hacerse esta migración.

Todos estos trabajos se planificaron de la siguiente manera:

Puede verse que para este servicio había un gran esfuerzo en lo que

era la parte de adquisición y formateo de los datos para construir los

Page 19: Cesnavarra 2008-boletín 12

ficheros XML base que alimentarían la aplicación MHP. También

existía una gran dependencia entre la aplicación cliente MHP y el

proceso de adquisición de datos debido al fichero XML que relacionaba

ambas aplicaciones. El diseño del interfaz marcaba la organización de

la información en el XML, el cual, a su vez, incidía directamente en el

proceso de adquisición de datos y obtención del XML. El publicador,

por el contrario, era un proceso que podía ser desarrollado de forma

independiente.

Finalmente, el equipo local estaba constituido por 3 personas (ante la

baja del miembro proporcionado por SiTVi, lo cual complicaría la

planificación acordad inicialmente) para tres desarrollos: proceso de

adquisición de datos, proceso de publicación y aplicación MHP. Las

responsabilidades de cada miembro, tal y como se ha dicho, iría

rotando en cada servicio para que todos los participasen en los

diferentes desarrollos y comprendiesen de esta forma el sistema

global.

Las pruebas del sistema completo, adquisición y publicación, eran

cruciales. Se realizaron una serie de pruebas del sistema completo en

un entorno de pre-producción habilitado en el laboratorio del CES

para asegurar el correcto flujo y procesado de la información, así

como una prueba del sistema completo en producción, pactado con

Abertis.

Previo a la emisión, se realizó una demostración de la aplicación al

área de Meteorología del Departamento de Agricultura, Ganadería y

Alimentación del Gobierno de Navarra para que solicitasen cambios y

diesen su aprobación final.

En dicha demostración, se detectó que se precisaba de la autorización

del INM para el empleo de sus datos en TDT, algo que, no obstante,

no supuso ningún impedimento ni inconveniente pudiéndose resolver

de forma satisfactoria a tiempo.

En cualquier caso, un retraso aproximadamente de una semana en

las pruebas y la coincidencia de las fiestas de San Fermin con la

emisión, pospusieron los planes, ante posibles eventualidades, hasta

Page 20: Cesnavarra 2008-boletín 12

finales de julio. Un retraso pequeño pero que unido a la baja de un

miembro del equipo, iría pesando a lo largo de los siguientes

desarrollos.

A continuación se muestran algunas imágenes de lo que fue e aspecto

final de la aplicación:

Page 21: Cesnavarra 2008-boletín 12
Page 22: Cesnavarra 2008-boletín 12

Catego

rías

CES OpenSouce/Java

Te

ma

Varios

Autor

Raúl Sanz de Acedo

Mes Diciembre

Año 2008

Bol

etín

12

Título Integración de jQuery con SharePoint (II)

Texto En el artículo anterior vimos como se crea un feature para

integrar la biblioteca jQuery en nuestro sitio SharePoint, sin

Page 23: Cesnavarra 2008-boletín 12

embargo no llegamos a ver sus funcionalidades. jQuery nos

permite, entre otras cosas, hacer consultas personalizadas

mediante código JavaScript.

Para ello es necesario descargarnos los archivos JavaScript que

nos permiten personalizar la consulta y que son modificables por

el desarrollador. También son necesarias las Web Parts que

alojan los contenidos y los resultados de la consulta, de una

manera similar a las búsquedas de SharePoint. Todo este

paquete está disponible para los suscriptores a las noticias

semanales de EndUserSharePoint un portal de usuarios de

SharePoint donde se recoge información sobre novedades,

actualizaciones y recursos interesantes. Un “precio” racionable si

se tiene en cuenta lo interesante de la información recibida.

Una vez que tenemos la biblioteca jQuery instalada y todos los

archivos JavaScript necesarios, iremos al Sitio donde queremos

emplearla y crearemos una biblioteca de documentos

llamada QueryResources, que será donde alojemos todos los

recursos necesarios para la personalización.

Para crear la biblioteca de documentos vamos a View All Site

Content> Create >Document Library. Una vez creada la biblioteca

cargamos los archivos medianteUpload>Upload Multiple Documents.

A continuación creamos una página de Web Parts (Web Part

Page 24: Cesnavarra 2008-boletín 12

Page) llamada SearchQuery.aspx, que guardaremos en la misma

biblioteca en la que tenemos nuestros recursos.

Una vez que hemos creado la página de Web Parts, el siguiente

paso es añadir las que nos permiten el empleo de jQuery. En

modo edición, utilizamos la opción Add Web Part y dentro de la

galería que nos aparece, seleccionamos Advanced Web Part

Gallery and Options que se encuentra en la parte inferior.

Al seleccionar dicha opción, nos aparece un cuadro de acciones que nos permite importar las Web Parts directamente del disco

Page 25: Cesnavarra 2008-boletín 12

duro. Para ello seleccionamos Browse> Import. A continuación

examinamos y cargamos, una a una, cada Web Part. Cuando nos aparece en la zona Uploaded Web Part, la arrastramos a la zona

de nuestra página donde deseamos implementarla.

En mi caso, he añadido jQuery_SearchBox-Top.dwp a la cabecera y jQuery_ContentOfPageToBeSearched-Center.dwp y jQuery_CallToScripts-Bottom.dwp al cuerpo. Y he

personalizado el texto de prueba.

De esta manera la página queda de la siguiente manera:

Page 26: Cesnavarra 2008-boletín 12

Finalmente, para comprobar que todo funciona correctamente, salimos del modo edición de nuestra página. Y comenzamos a escribir en el cuadro de texto…¡¡¡ Et Voilà!! A medida que vamos

escribiendo, las palabras que coinciden con la consulta se van pintando de amarillo.

Como hemos dicho al principio, está es sólo una de las múltiples funciones que tiene esta biblioteca. Ya que tenemos un amplio

abanico de posibilidades en el que poder trabajar. A continuación podemos ver algunos de los ejemplos:

Página oficial de

Page 27: Cesnavarra 2008-boletín 12

JQuery: http://dev.jquery.com/wiki/Demos

http://codylindley.com/blogstuff/js/jquery/

http://www.kelvinluck.com/assets/jquery/styleswitch/

http://iamzed.com/jquery/flashonetime.html

http://icant.co.uk/sandbox/jquerycodeview/

Categor

ías

CES Microsoft

Tema Desarrollo

Autor Goretti Ortigosa Rada

Mes Diciembre

Año 2008

Boletín 12

Título Introducción a Adobe Flex (y II).

Texto En este segundo artículo, vamos a ver un tutorial para la creación de un primer

proyecto con Adobe Flex. Crearemos una pequeña aplicación Java en el servidor y

un cliente realizado en Flex que accederá a ella a través de BlazeDS.

Descargas necesarias

A continuación se muestran las descargas necesarias para la realización del tutorial.

El sistema operativo utilizado es Windows XP.

Eclipse 3.3:

http://www.eclipse.org/downloads/download.php?file=/technology/epp/download

s/release/europa/winter/eclipse-jee-europa-winter-win32.zip

Apache Tomcat:

http://tomcat.apache.org/download-60.cgi

Page 28: Cesnavarra 2008-boletín 12

Flex Builder:

http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex3email

BlazeDS (Binary distribution):

http://opensource.adobe.com/wiki/display/blazeds/Release+Builds

Configuración del entorno de desarrollo

Se han instalado en la carpeta C:\FlexEclipse las herramientas que se utilizarán en

este tutorial. Se instala antes eclipse, ya que la instalación de FlexBuilder pide la ruta

donde está instalado eclipse. Por comodidad, colocamos el servidor Apache Tomcat

en la misma carpeta. Además, creamos una carpeta llamada FlexWS que servirá

como workspace de eclipse para el proyecto que crearemos.

Figura 1. Entorno de trabajo

Page 29: Cesnavarra 2008-boletín 12

Una vez instaladas las herramientas, arrancamos eclipse. Lo primero que debemos

hacer es registrar el servidor Apache Tomcat en eclipse. Para ello, vamos a Window -

> Preferences -> Server -> Installed Runtimes, y añadimos nuestro servidor Tomcat:

Figura 2. Servidor Apache Tomcat

Creación del proyecto de servidor

La descarga de BlazeDS consiste en una aplicación web (blazers.war), que

utilizaremos como base para nuestra aplicación de servidor. Para ello, desde eclipse,

vamos a File -> Import -> Web -> WAR File

Elegimos el fichero blazers.war, y ponemos el nombre de proyecto que queramos,

en este caso creamos un proyecto web llamado Coches.

Page 30: Cesnavarra 2008-boletín 12

Figura 3. Importación del archivo WAR de BlazeDS

En la siguiente pantalla, eclipse nos pregunta si queremos crear proyectos para las

librerías utilizadas en blazers.war. No seleccionamos ninguna, y finalizamos el

proceso de importación.

En este punto creamos las clases de la aplicación Java, que constará de dos clases:

Coche.java (Representa un coche con algunos atributos)

CocheService.java (Proporciona un método que devuelve una lista de coches)

Page 31: Cesnavarra 2008-boletín 12

Figura 4. Clases de la aplicación Coches

Para poder acceder a este servicio, debemos declarar la clase en el fichero remoting-

config.xml, de la siguiente forma

Page 32: Cesnavarra 2008-boletín 12

Figura 5. Configuración del acceso remoto a la aplicación

De esta forma, ya tenemos una pequeña aplicación Java en el servidor a la que

podremos acceder desde una aplicación Flex en el cliente, a través de BlazeDS. Para

publicar la aplicación en el servidor Tomcat, vamos a la pestaña de servidores, y

añadimos el proyecto Coches a las aplicaciones del servidor.

Creación del proyecto cliente

En este tutorial vamos a crear dos proyectos separados, uno para el servidor y otro

para el cliente. FlexBuilder nos permite crear la aplicación Java y el cliente Flex en un

mismo proyecto, pero en este caso se ha optado por separarlos para ganar en

claridad.

Antes de comenzar, debemos arrancar el servidor Tomcat, ya que en la creación del

cliente indicaremos donde encontrar la aplicación de servidor. Vamos a File -> New

Project -> FlexBuilder -> Flex Project y creamos el proyecto CochesClient:

Page 33: Cesnavarra 2008-boletín 12

Figura 6. Creación del proyecto cliente (I)

En la primera pantalla, introducimos el nombre del proyecto, CochesClient, y

dejamos el resto como se indica en la Figura 6. En la segunda pantalla, debemos

indicar la ruta y la URL del proyecto de servidor. La instalación por defecto de

Tomcat en eclipse no crea las aplicaciones en la carpeta del servidor

(C:\FlexEclipse\apache-tomcat-6.0.18), sino que las crea bajo la carpeta .metadata

del workspace. En la Figura 7 se muestra esta ruta para el entorno de trabajo

creado. Para comprobar que todo está bien, tenemos un botón llamado ‘Validate

Configuration'. Una vez que todo está bien, finalizamos el asistente.

Page 34: Cesnavarra 2008-boletín 12

Figura 7. Creación del proyecto cliente (II)

Al crear el proyecto se genera un fichero CochesClient.mxml, donde escribiremos la

parte de Flex que accederá a la aplicación. La aplicación cliente constará de un

botón y una tabla para mostrar los datos. Al pinchar en el botón ‘Obtener coches’,

se establecerá la conexión con el servidor a través de BlazeDS y se mostrará en la

tabla la información. A continuación se muestra el código:

<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"

layout="absolute">

<mx:Script>

import mx.rpc.events.ResultEvent;

import mx.rpc.events.FaultEvent;

import mx.controls.Alert;

import mx.utils.ObjectUtil;

Page 35: Cesnavarra 2008-boletín 12

public function resultListaCoches(event:ResultEvent

):void {

tablaCoches.dataProvider = event.result;

tablaCoches.visible = true;

}

private function faultListaCoches(event:FaultEvent)

:void{

Alert.show( ObjectUtil.toString(event.fault)

);

}

</mx:Script>

<mx:RemoteObject id="remoteCochesService"

destination="CocheServiceDestination" showBusyCursor="true">

<mx:method name="listaCoches"

result="resultListaCoches(event)"

fault="faultListaCoches(event)"/>

</mx:RemoteObject>

<mx:Button label="Obtener Lista"

click="remoteCochesService.listaCoches()"/>

<mx:DataGrid id="tablaCoches" x="10" y="63" width="574"

height="166" visible="false">

</mx:DataGrid>

</mx:Application>

En este código podemos ver:

Page 36: Cesnavarra 2008-boletín 12

- Un objeto RemoteObject que permite la conexión con el servidor.

- Un botón que realiza la llamada a través del RemoteObject.

- Un objeto DataGrid para mostrar los datos.

- Las funciones que gestionan el resultado de la petición. En caso de que vaya

bien, se pone el resultado de la petición como dataProvider del DataGrid, y

la información se muestra.

Figura 8. Aspecto de la aplicación Flex.

Código fuente

- Descargar

Referencias

- Adobe Flex

- BlazeDS

- Mihai Corlan Blog

Catego

rías

General

Tema Desarrollo

Autor Miguel Bacaicoa

Mes Diciembre

Page 37: Cesnavarra 2008-boletín 12

Año 2008

Boletín 12

Título Azure es un color… y más

Texto Siguiendo con la temática del artículo del mes anterior, vamos a volver

a hablar de Windows Azure, la plataforma de Microsoft para el

desarrollo de servicios disponibles en Internet e intercomunicables.

En este artículo vamos a llevar a cabo otro de los ejemplos disponiblres

en el Azure Services Training Kit y conseguir hacer disponible en

Internet un programa desarrollado en Silverlight. Para eso, nos

serviremos de los Live Services, que mediante Live Mesh nos permitirán

acceder a esta aplicación una vez la hayamos hecho disponible en la

plataforma Windows Azure.

Si empleamos como base el diagrama de la Plataforma de Servicios

Azure que mostrábamos el mes pasado, la representación de lo que

pretendemos hacer sería esta:

Aquí por simplificar hemos mostrado que nuestra aplicación sólo haría

uso de Live Services, pero nada nos impediría hacer uso de SQL

Page 38: Cesnavarra 2008-boletín 12

Services (para almacenar información en la “nube” y compartirla

mediante cualquiera de nuestros medios de acceso) , .NET Services

(para interactuar con otras infraestructuras de trabajo o ejecutar

Workflows por ejemplo) u otra aplicación alojada en Windows Azure a

la que tengamos acceso. ¡El poder de Azure!

Una vez conocido lo que vamos a hacer, al tajo. El ejemplo que vamos

a desarrollar consistirá en la publicación mediante Live Mesh de una

aplicación desarrollada en SilverLight (aunque podría tratarse de

cualquier aplicación soportada por Windows Azure). Para empezar, los

requisitos que necesitamos cumplir son:

- Microsoft Visual Studio 2008 (versión Estándar o superiores)

- Microsoft Visual Studio 2008 SP1 (descargable aquí)

- Microsoft Silverlight 2 Tools for Visual Studio 2008 (mejor no

usar las Betas anteriores por las diferencias entre Silverlight 2 y

sus antecesores): descargable aquí

- Microsoft Live Framework SDK (Descargable desde Microsoft

Connect)

- Microsoft Live Framework Tools for Visual Studio 1.0 CTP (como

el anterior también descargable desde Microsoft Connect)

Si tenemos la “sana” costumbre de instalar en nuestro PC todo aquello

Page 39: Cesnavarra 2008-boletín 12

con lo que podamos trastear (de alguna manera hay que probarlo,

¿no?), la instalación de los elementos listados arriba no va a ser todo lo

sencilla que podríamos desear. En concreto, la instalación de las

Silverlight Tools puede producir un error inesperado e “inexplicado”. En

este caso tendremos que hacer la instalación de manera manual de los

disitintos elementos del paquete. Para ello hay que lanzar la ejecución

y cuando nos muestre la pantalla de error no cerrarla. Entonces

buscaremos el directorio temporal de instalación que se habrá creado

automáticamente en nuestro disco duro C:\ (normalmente tendrá un

nombre compejo, enrevesado… informático vamos) y dentro de este

estarán entre otros los archivos a instalar:

- El Software Development Kit para Silverlight “silverlight_sdk.msi”

- Las Silverlight Tools para Visual Studio (aunque no usaremos estas

sino las indicadas anteriormente)

- Y dos parches de Visual Studio: VS90-KB951460.msp y VS90SP1-

KB955215.msp

Una vez realizada esta instalación ya estaremos en condiciones de

realizar desarrollos con Visual Studio 2008 y Silverlight para Windows

Azure.

En este ejemplo vamos a llevar a cabo el laboratorio para la creación

de una aplicación Live Mesh. Si seguimos el artículo del mes

pasado habremos instalado en nuestro PC el Microsoft Azure Services

Kit. Dentro de este se encuentra el Laboratorio denominado

“BuildingMeshEnabledWebApplications” que es el que nos interesa en

este caso. Si abrimos Visual Studio 2008 como Administradores

podremos abrir sin problemas la solución de ejemplo, “Begin.sln”,

ubicada en la carpeta “Ex01-UnderstandingTheApplication”. Se trata de

una aplicación completa basada en SilverLight para la gestión de

campeonatos de un deporte, donde podemos crear ligas, campos,

subir fotos de los campos, usar un sencillo tablón de mensajes, ver la

previsión del tiempo, etc.

Page 40: Cesnavarra 2008-boletín 12

Si miramos un poco el detalle de esta aplicación veremos que está

compuesta de 2 proyectos, uno que es la aplicación SilverLight en sí

para controlar el interfaz de usuario

(WLQuickApps.FieldManager.Silverlight) y otro con las clases

necesarias para que el anterior funcione (FieldManager.ObjectModel):

Page 41: Cesnavarra 2008-boletín 12

El proyecto FieldManager.ObjectModel representa un muy buen

ejemplo de organización de la estructura de un proyecto, con una

carpeta para la definición de los Objetos y otra para los Gestores

(Managers) de estos, de manera que su organización queda muy clara.

Antes de proceder con las modificaciones necesarias para publicar esta

aplicación en Live Mesh, habremos de conseguir el acceso a una

cuenta de Azure Services para desarrollo. Para ello, accedemos a Azure

Services Developer Portal mediante la

web http://lx.azure.microsoft.com y nuestro Windows Live ID. En el

caso de que se trate de la primera vez, habremos de dar de alta la

información precisa como cuenta de desarrollo:

Page 42: Cesnavarra 2008-boletín 12

Hecho esto, pasamos a la que será la pantalla principal en nuestras

próximas visitas, desde donde gestionaremos nuestros proyectos,

cuenta, etc.

Page 43: Cesnavarra 2008-boletín 12

Aquí tendremos que seleccionar el enlace “New Project” (a izquierda o

derecha, da igual) y pasamos a la pantalla desde la que definiremos el

nuevo proyecto a crear. Como veremos existen varios tipos

disponibles, agrupados en dos bloques:

- Windows Azure: este bloque nos permite definir aplicaciones

que se ejecutarán sobre Windows Azure, para lo que podemos

optar por crear almacenamiento mediante “Storage Account” o

nuestro propio servicio mediante “Hosted Services”.

- Azure Services Platform: en este caso haremos uso de la

plataforma de servicios de Azure ya existente, para lo que

tendremos a nuestra disposición el “Live Services: Live

Framework CTP” para el desarrollo de servicios que hagan uso

de cualquier Live Services existente, o “Live Services: Existing

Page 44: Cesnavarra 2008-boletín 12

APIs” para usar APIs de los Live Services desde cualquier

aplicación Web.

En nuestro caso, veremos más adelante que crearemos un proyecto

con el Live Framework CTP del Azure Services Platform, ya que lo que

queremos es publicar una aplicación que haga uso del Live Service

“Live Mesh” como plataforma de publicación.

Por ahora eso es todo en este portal, cancelamos las modificaciones y

regresaremos a Visual Studio y preparamos una solución para su

publicación. Para eso, cerramos la que tenemos abierta y abrimos la

solución “Begin.sln” que está localizada en la carpeta “Ex02-

DeployingIntoLiveMesh” que prepararemos para publicar mediante los

siguentes pasos:

1. Añadimos al

proyecto WLQuickApps.FieldManager.Silverlight tres

Page 45: Cesnavarra 2008-boletín 12

referencias (botón derecho sobre el nodo “References”, opción

“Add Reference…”) a los ensamblados de Live Framework que

encontraremos en “[LiveFxSDK]\Libraries\Silverlight”:

- Microsoft.LiveFX.Client.dll

- Microsoft.LiveFX.ResourceModel.dll

- Microsoft.Web.dll

2. Editamos el fichero App.xaml.cs

de WLQuickApps.FieldManager.Silverlight

E introduciremos los cambios siguientes mostrados en azul:

using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using System.Windows.Browser; using Microsoft.LiveFX.Client; namespace WLQuickApps.FieldManager.Silverlight { public partial class App : Application { public App() { this.Startup += this.Application_Startup; this.Exit += this.Application_Exit; this.UnhandledException += this.Application_UnhandledException; InitializeComponent(); } private void Application_Startup(object sender, StartupEventArgs e) {

Page 46: Cesnavarra 2008-boletín 12

MeshApplicationService meshApp =

Application.Current.GetMeshApplicationService(); meshApp.LoadCompleted += new EventHandler(this.App_Load); meshApp.Load(); } private void Application_Exit(object sender, EventArgs e) { } private void Application_UnhandledException(object sender,

ApplicationUnhandledExceptionEventArgs e) { // Commented out per security review. HtmlPage.Window.Invoke("alert", "DEBUG:\n" + e.ExceptionObject.Message); } // Evento de carga para Live Mesh public void App_Load(object sender, EventArgs e) { MeshApplicationService meshApp =

Application.Current.GetMeshApplicationService(); meshApp.Resource.Title = "App"; Mesh mesh = meshApp.LiveOperatingEnvironment.Mesh; this.RootVisual = new Page(); } } }

3. Añadiremos un nuevo proyecto a nuestra solución, que será el

encargado de prepararla como una aplicación Live Mesh. Al

haber instalado el Live Framework Tools tenemos disponible

entre las posibles plantillas de proyecto un nuevo nodo de

nombre “ Live Framework” que incluye el tipo que queremos

“Silverlight Mesh-enabled Web Application”.

Page 47: Cesnavarra 2008-boletín 12

Seleccionamos esta plantilla y le damos el nombre

“FieldManagerMeshApp”. Esto nos crear dos proyectos más en

nuestra solución, uno de los cuales hemos de borrar ya que no

nos hace falta. Se trata de “FieldManagerMeshAppSiverlight”

que es el esqueleto de proyecto que podríamos usar en caso de

que tuviéramos que crear una aplicación SilverLight desde cero,

que en nuestro caso está ya creada. Pincharemos con el botón

derecho del ratón sobre su nombre y seleccionaremos la opción

“Remove”

Para correguir este cambio en nuestra aplicación

“FieldManagerMeshApp” hemos de quitar la referencia a

“FieldManagerMeshAppSilverlight” y agregar la correcta a

nuestro proyecto “WLQuickApps.FieldManager.Silverlight”

Page 48: Cesnavarra 2008-boletín 12

Quitar Añadir

4. Cambiamos en el fichero Index.html del

proyecto FieldManagerMeshApp la referencia al paquete xap

del control de Silverlight modificando en la definición del

“silverlightControlHost” el valor del parámetro source como se

muestra a continuación:

<div id="silverlightControlHost"> <object data="data:application/x-silverlight," type="application/x-

silverlight-2" width="100%" height="100%"> <param name="source"

value="WLQuickApps.FieldManager.Silverlight.xap"/> <param name="onerror" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="2.0.30923.0" />

Page 49: Cesnavarra 2008-boletín 12

<param name="autoUpgrade" value="true" /> <param name="windowless" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=124807"

style="text-decoration: none;"> <img

src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft

Silverlight" style="border-style: none"/> </a> </object> <iframe style='visibility:hidden;height:0;width:0;border:0px'></iframe> </div>

5. Finalmente debemos modificar los valores del fichero

Manifest.xml del proyecto FieldManagerMeshApp para que la

publicación de nuestra aplicación tenga las propiedades que

nos interesen:

<?xml version="1.0" encoding="utf-8" ?> <Manifest xmlns="http://schemas.mesh.com/application/manifest/2008"> <Name>CES Field Manager</Name> <Description>Apliación de prueba de Silverlight en Live Mesh</Description> <PublisherName>User</PublisherName> <DisplayVersion>1.0</DisplayVersion> <MultiInstance>false</MultiInstance> <PrivacyPolicyLink>http://www.cesnavarra.net</PrivacyPolicyLink> <SupportLink>http://www.cesnavarra.net</SupportLink> <VendorLink>http://www.cesnavarra.net</VendorLink> <RequireDelegation>false</RequireDelegation> </Manifest>

6. Por último, establecemos el

proyecto FieldManagerMeshApp como proyecto de inicio,

pulsando con el botón derecho del ratón sobre su nombre y

seleccionando la opción “Establecer como proyecto de inicio”.

7. Ejecturaremos la aplicación sin debugging (Ctrl + F5) y nos

aparecerá la ventana de solicitud de nuestro Windows Live ID

para acceder a la plataforma Windows Azure.

Page 50: Cesnavarra 2008-boletín 12

8. Una vez hemos hecho esto, tendremos una nueva pantalla para

la definición del enlace la aplicación:

Lo primero a hacer ahora es pulsar el enlace “Navigate to the

Developer Portal” para definir la nueva aplicación Mesh en el

Azure Services Developer Portal. Como hemos dicho antes,

pulsaremos en “New Project” una vez en ese portal, y de las

opciones elegiremos “Live Services: Live Framework CTP” como

hemos comentado antes.

Page 51: Cesnavarra 2008-boletín 12

Esto nos pasa a otra pantalla donde introduciremos los datos de

la aplicación: su etiqueta y descripción. Aceptado esto,

tendremos la opción de elegir el tipo de aplicación, que en este

caso se trata de una Mesh-enabled Web application.

Seleecionaremos esta y pulsamos Create:

Tras esto habremos por fin creado nuestra aplicación Mesh (sin

contenido todavía, aún hemos de subirla) y se nos mostrará la

pantalla de propiedades de la misma:

Page 52: Cesnavarra 2008-boletín 12

Volvemos a Visual Studio y pulsamos el enlace “Copy full path of

FieldManagerMeshApp.zip to clipboard” en la ventana de

diálogo que teníamos abierta. Cambiamos de nuevo al

navegador, a Azure Services Developer Portal, y pulsamos el

botón “Upload Package”.

Page 53: Cesnavarra 2008-boletín 12

Pulsamos entonces el botón “Browse” para abrir la ventanda de

selección del paquete, pulsamos Ctrl+V para pegar el camino

del mismo y a continuación pulsamos Deploy, con lo que se

inicia la copia del paquete a Windows Azure.

Una vez completado, copiamos el “Application Self Link” que se

nos devuelve

Y de vuelta en Visual Studio lo introducimos en el 3er paso de la

ventana que tenemos activa:

Page 54: Cesnavarra 2008-boletín 12

Con esta información completa, una vez que pulsemos Ok se

produce la actualización final de la aplicación en Windows Live y

podremos ejecutarla (estos últimos pasos se simplifican en el

caso de que estemos actualizando una aplicación que ya exista

como Live Mesh application; en este ejemplo es más complejo

ya que hemos realizado a la vez la creación y definición de una

aplicación Live Mesh y la compilación y subida de una nueva

versión de la misma).

Para su ejecución, el mismo Visual Studio abrirá el Live Desktop

por nosotros. En caso de no ser así podemos acceder mediante

la webhttps://www.mesh.com/Welcome/Default.aspx

Page 55: Cesnavarra 2008-boletín 12

En definitiva, este ejemplo nos ha permitido ver cómo se pueden

desarrollar aplicaciones para Live Mesh, accesibles mediante cualquier

sistema que cuente con acceso a la web, desarrolladas desde nuestra

plataforma local y con todas las ventanas de los múltiples servicios que

Windows Azure pone a nuestra disposición:

- .NET Services para comunicación entre sistemas y

aplicaciones, workflows, etc.

- Storage Services para el almacenamiento de información

- Live Services para el uso del Live Framework y toda la

plataforma de servicios Live

Categorías

CES Microsoft

Tema Desarrollo

Autor Rafael Flores

Mes Diciembre

Año 2008

Boletín

12

Page 56: Cesnavarra 2008-boletín 12

Título Creación de un Gadget basado en una animación XAML

Texto Cada día los usuarios demandan el acceso a más información y que esta sea presentada de forma llamativa y eficiente. Una

de las novedades de Windows Vista ha sido Windows Sidebar.

Esta aplicación se nos presenta como una barra de herramientas formada por mini aplicaciones (Gadgets).Hay

diversos Gadgets, desde resultados deportivos, pasando por cotizaciones en bolsa y acabando por Radios o acceso al

Messenger.

En este artículo se pretende presentar nuestra información de la forma más llamativa posible, mediante un efecto 3D

realizado con nuestras fotos creado a partir de una animación XAML y la eficiente presentación de nuestras fotos en nuestra

Sidebar.

El primer paso que debemos seguir es crear la animación de XAML, en nuestro caso va ser un cubo en 3d que nos va

presentar nuestras seis fotos, una por cada cara del cubo, lo haremos con el siguiente código.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation

" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:SampleControls="SampleControls" WindowTitle="3D Rotation Example" Background="Black"> <Page.Resources> <!—Modelo 3D de cada una de las caras del cubo --> <MeshGeometry3D x:Key="CubeSide01" TriangleIndices="0,1,2 3,4,5 " Normals="-1,0,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 " TextureCoordinates="0,1 0,0 1,0 1,0 1,1 0,1 " Positions="-0.5,0.5,-0.5 -0.5,-0.5,-0.5 -0.5,-0.5,0.5 -0.5,-

0.5,0.5 -0.5,0.5,0.5 -0.5,0.5,-0.5 " /> <MeshGeometry3D x:Key="CubeSide02" TriangleIndices="0,1,2 3,4,5 "

<!—en la animación se reconocen las imágenes como triangulos

para recrear cada cara del cubo --> Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 "<!—vector

perpendicular a la superficie del plano --> TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 ""<!— aplicación de

la textura a cada triangulo--> Positions="-0.5,-0.5,0.5 0.5,-0.5,0.5 0.5,0.5,0.5 0.5,0.5,0.5 -

0.5,0.5,0.5 -0.5,-0.5,0.5 " />""<!— posicionamiento en las tres

dimensiones de los triangulos--> <MeshGeometry3D x:Key="CubeSide03" TriangleIndices="0,1,2 3,4,5 " Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 " TextureCoordinates="1,0 1,1 0,1 0,1 0,0 1,0 " Positions="0.5,-0.5,-0.5 0.5,0.5,-0.5 0.5,0.5,0.5 0.5,0.5,0.5

0.5,-0.5,0.5 0.5,-0.5,-0.5 " />

Page 57: Cesnavarra 2008-boletín 12

<MeshGeometry3D x:Key="CubeSide04" TriangleIndices="0,1,2 3,4,5 " Normals="1,0,0 1,0,0 1,0,0 1,0,0 1,0,0 1,0,0 " TextureCoordinates="1,0 1,1 0,1 0,1 0,0 1,0 " Positions="-0.5,-0.5,-0.5 -0.5,0.5,-0.5 0.5,0.5,-0.5 0.5,0.5,-

0.5 0.5,-0.5,-0.5 -0.5,-0.5,-0.5 " /> <MeshGeometry3D x:Key="CubeSide05" TriangleIndices="0,1,2 3,4,5 6,7,8 9,10,11 " Normals="0,-1,0 0,-1,0 0,-1,0 0,-1,0 0,-1,0 0,-1,0 0,1,0 0,1,0

0,1,0 0,1,0 0,1,0 0,1,0 " TextureCoordinates="0,0 1,0 1,1 1,1 0,1 0,0 1,1 0,1 0,0 0,0 1,0

1,1 " Positions="-0.5,-0.5,-0.5 -0.5,0.5,0.5 -0.5,-0.5,0.5 0.5,-

0.5,0.5 -0.5,-0.5,-0.5 -0.5,0.5,-0.5 0.5,0.5,-0.5 -0.5,0.5,-0.5 -0.5,0.5,0.5 -

0.5,0.5,0.5 0.5,0.5,0.5 0.5,0.5,-0.5 " /> <MeshGeometry3D x:Key="CubeSide06" TriangleIndices="0,1,2 3,4,5 6,7,8 9,10,11 " Normals="-1,0,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 -1,0,0 " TextureCoordinates="1,0 1,1 0,1 0,1 0,0 1,0 " Positions="-0.5,-0.5,0.5 -0.5,-0.5,-0.5 0.5,-0.5,-0.5 0.5,-

0.5,-0.5 0.5,-0.5,0.5 -0.5,-0.5,0.5" /> <!—Material 3D utilizado para cada cara del cubo --> <MaterialGroup x:Key="LeavesMaterial1"> <DiffuseMaterial> <DiffuseMaterial.Brush> <ImageBrush Stretch="UniformToFill" ImageSource="images\1.jp

g" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 1

1" AlignmentX="Left" AlignmentY="Top"Opacity="1.000000" /><!—Dibuja

una imagen a traves de un pincel definido --> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"><!—cantidad de luz que

incide sobre nuestro material --> <SpecularMaterial.Brush> <SolidColorBrush Color="#FFFFFF" Opacity="1.000000"/>"><!—

define el color y la opacidad del pincel --> </SpecularMaterial.Brush> </SpecularMaterial> </MaterialGroup> <MaterialGroup x:Key="RocksMaterial"> <DiffuseMaterial> <DiffuseMaterial.Brush> <ImageBrush Stretch="UniformToFill" ImageSource="images\2.jp

g" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 1

1" AlignmentX="Left" AlignmentY="Top"Opacity="1.000000" /> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"> <SpecularMaterial.Brush> <SolidColorBrush Color="#FFFFFF" Opacity="1.000000"/> </SpecularMaterial.Brush> </SpecularMaterial> </MaterialGroup> <MaterialGroup x:Key="BranchesMaterial"> <DiffuseMaterial> <DiffuseMaterial.Brush>

Page 58: Cesnavarra 2008-boletín 12

<ImageBrush Stretch="UniformToFill" ImageSource="images\3.jp

g" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 1

1" AlignmentX="Left" AlignmentY="Top"Opacity="1.000000" /> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"> <SpecularMaterial.Brush> <SolidColorBrush Color="#FFFFFF" Opacity="1.000000"/> </SpecularMaterial.Brush> </SpecularMaterial> </MaterialGroup> <MaterialGroup x:Key="BerriesMaterial"> <DiffuseMaterial> <DiffuseMaterial.Brush> <ImageBrush Stretch="UniformToFill" ImageSource="images\4.jp

g" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 1

1" AlignmentX="Left" AlignmentY="Top"Opacity="1.000000" /> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"> <SpecularMaterial.Brush> <SolidColorBrush Color="#FFFFFF" Opacity="1.000000"/> </SpecularMaterial.Brush> </SpecularMaterial> </MaterialGroup> <MaterialGroup x:Key="FlowersMaterial"> <DiffuseMaterial> <DiffuseMaterial.Brush> <ImageBrush Stretch="UniformToFill" ImageSource="images\5.jp

g" ViewportUnits="Absolute" Viewport="0 0 1

1" AlignmentX="Left" AlignmentY="Top" Opacity="1.000000" /> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"> <SpecularMaterial.Brush> <SolidColorBrush Color="#FFFFFF" Opacity="1.000000"/> </SpecularMaterial.Brush> </SpecularMaterial> </MaterialGroup> <MaterialGroup x:Key="SunsetMaterial"> <DiffuseMaterial> <DiffuseMaterial.Brush> <ImageBrush Stretch="UniformToFill" ImageSource="images\6.jp

g" ViewportUnits="Absolute" Viewport="0 0 1

1" AlignmentX="Left" AlignmentY="Top" Opacity="1.000000" /> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"> <SpecularMaterial.Brush> <SolidColorBrush Color="#FFFFFF" Opacity="1.000000"/> </SpecularMaterial.Brush> </SpecularMaterial> </MaterialGroup> <MaterialGroup x:Key="SolidColorMaterial"> <DiffuseMaterial> <DiffuseMaterial.Brush> <SolidColorBrush Color="Orange" Opacity="1.000000"/> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"> <SpecularMaterial.Brush> <SolidColorBrush Color="#FFFFFF" Opacity="1.000000"/> </SpecularMaterial.Brush> </SpecularMaterial> </MaterialGroup>

Page 59: Cesnavarra 2008-boletín 12

<!—Modelos visuales 3D --> <ModelVisual3D x:Key="PictureCubeModelVisual3DResource" > <ModelVisual3D.Children> <ModelVisual3D> <ModelVisual3D.Content> <AmbientLight Color="#333333" />

<!—el color que toma la textura según la incidencia de

la luz --> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content>

<DirectionalLight Color="#FFFFFF" Direction=

"-0.612372,-0.5,-0.612372" /><!—Dirección de la incidencia de

la luz sobre la textura --> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="0.612372,-

0.5,-0.612372" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide01}" Material="{StaticResource BranchesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide02}" Material="{StaticResource FlowersMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide03}" Material="{StaticResource BerriesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide04}" Material="{StaticResource LeavesMaterial1}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide05}" Material="{StaticResource RocksMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide06}" Material="{StaticResource SunsetMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> </ModelVisual3D.Children> </ModelVisual3D> </Page.Resources>

Page 60: Cesnavarra 2008-boletín 12

<DockPanel> <Viewbox> <!—La animación del cubo. --> <Viewport3D ClipToBounds="True" Width="400" Height="300"> <Viewport3D.Camera> <PerspectiveCamera x:Name="myPerspectiveCamera" LookDirection="0,0,-1" UpDirection="0,1,0" Position="0,0,2.1" FieldOfView="50" /> <!—dirección,prespectiva,pocición con la que la camara muestra el

cubo --> </Viewport3D.Camera> <ModelVisual3D> <ModelVisual3D.Children> <ModelVisual3D> <ModelVisual3D.Content> <AmbientLight Color="#333333" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="-

0.612372,-0.5,-0.612372" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <DirectionalLight Color="#FFFFFF" Direction="0.612372,

-0.5,-0.612372" /> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide01}" Material="{StaticResource BranchesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <!—material 3D que carga para cada cara del cubo --> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide02}" Material="{StaticResource FlowersMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide03}" Material="{StaticResource BerriesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide04}" Material="{StaticResource LeavesMaterial1}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

CubeSide05}" Material="{StaticResource RocksMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource

Page 61: Cesnavarra 2008-boletín 12

CubeSide06}" Material="{StaticResource SunsetMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> </ModelVisual3D.Children> <ModelVisual3D.Transform> <Transform3DGroup > <Transform3DGroup.Children> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D x:Name="myHorizontalRotation"

Angle="0" Axis="0 1 0" /> </RotateTransform3D.Rotation> </RotateTransform3D> <RotateTransform3D> <RotateTransform3D.Rotation> <AxisAngleRotation3D x:Name="myVerticalRotation" A

ngle="0" Axis="1 0 0" /><!—Angulo de rotación del Cubo --> </RotateTransform3D.Rotation> </RotateTransform3D> <TranslateTransform3D x:Name="myTranslateTransform" OffsetX="0" OffsetY="0" OffsetZ="0" />

<!—definicion de la translación del cubo --> </Transform3DGroup.Children> </Transform3DGroup> </ModelVisual3D.Transform> </ModelVisual3D> <Viewport3D.Triggers> <!—Animaciones del cubo despues de ser cargadas. --> <EventTrigger RoutedEvent="Viewport3D.Loaded"> <BeginStoryboard> <Storyboard> <DoubleAnimation Storyboard.TargetName="myVerticalRotation" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:10" RepeatBehavior="Forever" /> <!—Rotacion vertical de duración de 10 segundos --

> <DoubleAnimation Storyboard.TargetName="myHorizontalRotation" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:9" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard> </EventTrigger> </Viewport3D.Triggers> </Viewport3D> </Viewbox> </DockPanel> </Page>

Una vez creada la animación deberemos de ir a la carpeta que

contiene todos los Gadgets de la Sidebar. La ruta habitual donde la encontramos es la

siguiente C:\Users\usuario\AppData\Local\Microsoft\Win

dows Sidebar\Gadgets Dentro de dicha carpeta deberemos

de crear una con el siguiente formato: “Nombre

Gadget.gadget” en nuestro caso CUBO3D.gadget. En el

Page 62: Cesnavarra 2008-boletín 12

interior de esta carpeta colocaremos nuestro archivo XAML, y

también hemos de crear los archivos XML y HTML que definen las propiedades y el objeto del Gadget (en nuestro caso la

animación XAML), pero vamos por partes.

El siguiente paso es crear el archivo XML, que debe tener la siguiente estructura:

<?xml version="1.0" encoding="utf-8" ?> <gadget> <name>CUBO3D</name> <namespace>Cesnavarra</namespace> <version>1.0</version> <author name="Cesnavarra"> <info url="http://www.cesnavarra.net" /> </author> <copyright>2008</copyright> <description>Gadget animacion 3Da través de un XAML</description> <hosts> <host name="sidebar"> <base type="HTML" apiVersion="1.0.0" src="default.html" /> <permissions>full</permissions> <platform minPlatformVersion="0.3" /> </host> </hosts> </gadget>

El significado de cada etiqueta es el siguiente

<name></name>: En esta etiqueta colocaremos el nombre

de nuestro Gadget, en nuestro caso “CUBO3D”

<namespace></namespace>: Esta etiqueta define el grupo al que asociaremos nuestros Gadgets con lo que

podremos gestionarlos de manera agrupada. Es una etiqueta informativa y en nuestro caso lo haremos por ejemplo

mediante la agrupación “Cesnavarra”

<version></version>: La siguiente etiqueta nos indicara la versión de nuestro Gadget para posteriores actualizaciones.

<author name="">: Indica el nombre del autor de Gadget

<info url="" />: Nos ayudará a definir una página de

referencia de nuestro Gadget.

<copyright></copyright>: Esta etiqueta indica los

derechos reservados de autor de nuestro Gadget.

<description></description>: La siguiente Etiqueta nos ayudara a presentar información descriptiva sobre nuestro

Gadget.

La parte contenida en las etiquetas <hosts></hosts> no la vamos a modificar ya que está predeterminada para el

Windows SideBar. Lo único que puede interesarnos modificar

Page 63: Cesnavarra 2008-boletín 12

va a ser el origen donde obtendremos el contenido de nuestro

Gadget, que se obtiene a través de una página HTML. El nombre de este origen puede ser diferente al nombre del

Gadget. Ej. scr="default.html".

El archivo XML lo deberemos de nombrar Gadget.xml, ya que esta es la manera que la Sidebar reconoce nuestro Gadget.

El penúltimo paso será crear nuestra página web de

presentación de nuestro Gadget:

<html> <head> <title>CUBO 3D</title> <style> body { width:130; height:130; padding:5; margin:0; background:black; } </style> </head> <body> <iframe height="130" width="130" src="3d_animation.xaml" />

</body> </html>

Como se puede ver es una simple pagina en HTML donde lo más importante la definición de la carga de nuestra animación

mediante un iframe.

Por último una vez creados todos los elementos

procederemos a incluir nuestro Gadget en la Sidebar de Windows Vista de la siguiente manera:

En la Sidebar en la parte superior presionaremos la tecla más lo que nos presentara todos los Gadget que tenemos

instalados en nuestro sistema, entre ellos nuestro CUBO

3D.Realizaremos doble click sobre este Gadget y aparecerá en nuestra Sidebar.

Page 64: Cesnavarra 2008-boletín 12

Categ

orías

CES Microsoft

Tema Desarrollo

Autor Raúl Mayo González

Mes Diciembre

Año 2008

Boletín

12

Título Copias de seguridad de un repositorio subversion.

Texto Si repasáis los artículos de este año encontrareis 2 artículos interesantísimos

que no deberíais perderos sobre la instalación y despliegue del controlador

de versiones de código Subversión.

En este artículo vamos a tratar con un poco más de profundidad el hecho de

realizar copias de seguridad de un repositorio Subversión ( SVN ).

Copias de un repositorio de SVN. se pueden hacer de varias formas,

podríamos partir incluso de copias basadas en comandos del propio sistema

operativo, tar, cp, xcopy, zip etc., podríamos utilizar gestores de copias

completos tipo los comerciales Backup Exec de symantec (antiguamente de

Veritas.) o como los open source “Bacula backup” o el freeware Cobian

Backup (aunque este gestor tiene alguna versión opensource). Pero nosotros

Page 65: Cesnavarra 2008-boletín 12

nos vamos a centrar en las herramientas que distribuye el propio SVN.

El SVN tiene un funcionamiento transaccional. Deberíamos tener en cuenta

que mientras se hacen las copias se pueden estar haciendo modificaciones

en los ficheros bajo el control de SVN y que por lo tanto tendremos nuevas

revisiones. El árbol de directorios y ficheros está fuertemente relacionado a

través revisiones y Vds, etc. para dar consistencia a SVN. En una palabra: es

un sistema complejo.

Digamos que debido a esto y a toda esas psicosis que rodean las gestiones de

copias de seguridad nos vamos a centrar en los propios comandos del SVN.

Éstos nos dan un conocimiento más fino de las modificaciones existentes en

el repositorio y además están pensados para garantizar las interrelaciones y

consistencia entre ficheros revisiones directorios etc. del entramado SVN.

Subversión permite hacer copias de seguridad con las siguientes

herramientas:

svnadmin hotcopy: permite hacer copias completas del repositorio en

caliente. En realidad es tan trivial como hacer una llamada al cp/copy del

sistema dependiendo de si el sistema es Unix o Windows.

svnadmin dump: permite generar ficheros de exportación e importación

“dump” de un repositorio concreto; svnadmin dump permite exportaciones

parciales hasta una revisión concreta o un rango de revisiones. Con el

modifica “–incremental” se pueden hacer ficheros de parciales incrementales

sin incluir las revisiones anteriores a la especificadas.

tools/backup/ hot-backup.py: esta herramienta se distribuye y se localiza en

el directorio “tools/backup”. Si no podríamos localizarlo en la siguiente

dirección, http://svn.collab.net/repos/svn/trunk/tools/backup/hot-

backup.py.in

Hot-backup es un script que nos va a permitir hacer copias calientes de

repositorios de SVN. Automáticamente gestiona los nombres de los ficheros

de backup por cada repositorio cuando tienes múltiples repositorios y se

preocupará de evitar las colisiones con los backups previos. Los backups

antiguos los calificará de “rótate off” borrándolos y conservando solo las

versiones de copia más recientes. Podría ser interesante estudiar un modo

de realizar copias incrementales con la herramienta.

Bien, ya hemos visto que SVN se preocupa por la coherencia de sus

repositorios y por eso dispone de 3 herramientas de volcado de datos. Tanto

hotcopy como hot-backup.py son muy fáciles de usar para realizar copias de

seguridad completas, sobre todo hot-backup.py que además ofrece un nivel

más fino de generación y automatización de copias.

Sin embargo nosotros nos vamos a basar en el svnadmin dump. El método

Page 66: Cesnavarra 2008-boletín 12

puede ser más elaborado pero nos va a permitir hacer backups más

personalizados y afinados, como por ejemplo backups incrementales. Sobre

esto último ni que decir tiene que un backup completo es el backup más

seguro y coherente que se puede realizar. Sin embargo cuando nuestros

repositorios empiezan a crecer en cuestión de tamaño, podemos tener otros

problemas como la cantidad de tiempo en la generación de las copias o el

tamaño de los ficheros a distribuir a través de nuestros sistemas hasta llegar

al sistema de archivados de copias, trafico de red, etc.

Las copias incrementales nos van a permitir aligerar las cargas de tráfico y

volumen de datos pero nos van a exigir más control en la gestión de copias.

Vale, para empezar debemos conocer los siguientes 2 comandos y unos

modificadores en particular:

Svnlook: interesante herramienta que distribuye el subversion. Esta

herramienta con sus distintos comandos y modificadores tiene como

objetivo mostrarnos información del repositorio. Tiene muchas opciones

pero para nuestros intereses hemos seleccionado estas tres:

svnlook –info [path/repositorio]

svnlook –info [path/repositorio] –r [ nº revision]

svnlook youngest [path/repositorio]

Por ejemplo:

#svnlook info /opt/Repositorios/PruebaRepo01

Kikorro

2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)

57

¡¡¡ Esto martxaaaaaaaa : P !!! …… ¡¡¡ FIESTAAAAAAA !!!

Podemos observar por filas:

Nombre del usuario SVN: Kikorro

Fecha de la modificación : 2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)

Número de caracteres del mensaje de modificación :27

Mensaje sobre la modificación : ¡¡¡ Esto martxaaaaaaaa : P !!!!

#svnlook info –r 19 /opt/Repositorios/PruebaRepo01

Kikorro

Page 67: Cesnavarra 2008-boletín 12

2002-11-05 09:29:13 -0600 (Mon, 04 Nov 2002)

14

1..2..3...14!

Vemos que la salida es igual que en el ejemplo anterior, pero esta vez nos

esta mostrando un resumen de la información de la revisión 19 (también

podemos observar que al usuario Kikorro se le va mucho la “olla” y que

cuenta tan mal como “Bono”)

Dejando a un lado las bromas, estas instrucciones las vamos a usar para

comprobar que tanto el repositorio como la revisión existen. En caso de que

el repositorio o la revisión fuesen incorrectos se nos mostrarían sendos

mensajes de error, además de devolver el valor estándar de error $? = 1.

La opción “youngest” del comando svnadmin nos va a mostrar la ultima

revisión del repositorio indicado. Por ejemplo :

#svnlook youngest /opt1/Repositorios/PruebaRepo01

19

Svnadmin dump/load: hay que decir que estas opciones están orientadas a

la exportación y migración de repositorios pero perfectamente nos sirven

para hacer copias de seguridad.

La opción “dump” a secas nos generará un volcado binario del repositorio

especificado. Se pueden especificar volcados hasta una revisión, hasta un

rango de revisiones y volcados incrementales de rangos de revisiones.

#svnadmin dump /opt/Repositorios/PruebaRepo01 >

PruebaRepo01_full.dump

#svnadmin dump /opt/Repositorios/PruebaRepo01 –r 15 >

PruebaRepo01_r15.dump

#svnadmin dump /opt/Repositorios/PruebaRepo01 –r 10:15 >

PruebaRepo01_r10_15.dump

#svnadmin dump /opt/Repositorios/PruebaRepo01 –r 16:19 --

incremental > PruebaRepo01_inc_r16_19.dump

Vamos a tratar de explicar la diferencia entre la fila 3 y la 4: SVN tiene el

siguiente comportamiento por defecto para la opción “dump”. Cada revisión

volcada debe poder ser restaurada por sí misma. Si es una revisión nueva no

hay ningún problema pero si la revisión esta basada en otras anteriores,

entonces en el fichero “dump” deben de existir las revisiones necesarias

anteriores para poder restaurarse las revisiones especificadas en el rango.

Como mínimo va a existir un volcado completo de la primera revisión del

Page 68: Cesnavarra 2008-boletín 12

repositorio.

Especificando el modificador “–-incremental” se cambia el comportamiento

por defecto de SVN. Evitaremos un volcado completo de la primera revisión

del repositorio pero debemos ser muy cuidadosos con los “dump” parciales

ya sean completos o incrementales si luego queremos restauraciones

coherentes.

Muy bien: hasta aquí sabemos que podemos hacer copias completas de

nuestros repositorios preferidos y que incluso podríamos diseñar una política

de copias incrementales por si nuestros repositorios son muy grandes o

queremos aligerar la carga de red. Ahora lo que debemos saber es cómo

restaurar estas copias que nos hemos feriado.

La opción “load” del comando svnadmin es la que andábamos buscando. Un

ejemplo básico:

#svnadmin load /opt1/Repositorios/PruebaRepo01 <

pruebaRepo01_full.dump.

Claro, éste es el caso más sencillo: la restauración desde una copia completa.

Bien en el caso de tener ficheros “dump” parciales incrementales,

deberemos tener en cuenta la advertencia que hemos hecho anteriormente

sobre la restauración coherente de la revisiones: si una revisión se basa en

una anterior, ésta ha de existir, así que siempre ha de haber una copia

completa desde de la que deben ir partiendo las copias incrementales y por

lo tanto la restauración de dichas copias deberá seguir un orden lógico con

respecto a las copias generadas.

Por ejemplo: secuencia de dumps.

#svnadmin dump /opt1/Repositorios/PruebaRepo01 -r 0:10 >

dumpfile1

#svnadmin dump /opt1/Repositorios/PruebaRepo01 -r 11:14 -

-incremental > dumpfile2

#svnadmin dump /opt1/Repositorios/PruebaRepo01 -r 15:19 -

-incremental > dumpfile3

Secuencia de loads.

#svnadmin load /opt1/Repositorios/PruebaRepo01 <

dumpfile1

#svnadmin load /opt1/Repositorios/PruebaRepo01 <

dumpfile2

#svnadmin load /opt1/Repositorios/PruebaRepo01 <

dumpfile3

Page 69: Cesnavarra 2008-boletín 12

En el ejemplo anterior la primera instrucción equivale a una copia completa

hasta la revisión 10. También podríamos haberlo indicado de la siguiente

manera:

#svnadmin dump /opt1/Repositorios/PruebaRepo01 -r 10 >

dumpfile1.

Restaurar un repositorio; Para restaurar………en una noche de verano ….

¡¡CÓMO!! ¡¡QUEEEEEEE!! ¡¡Quée dice este ahora!! … ¿¿No bastaba sólo con el

load?? ….. ¡¡Por favor que acabe yaaaaaa!! (Los lectores digitales)

Queridos lectores: un poco de paciencia, que queda poco.

Para restaurar el repositorio, éste debe existir. “svnadmin load” no crea un

repositorio: carga un una copia generada con el comando svnadmin dump;

En caso de no existir el repositorio debemos recrearlo con la instrucción,

svnadmin create [repositorio].

Por ejemplo:

svnadmin create /opt1/Repositorios/PruebaRepo01

Si el repositorio está corrupto yo recomendaría eliminar el repositorio entero

y recrearlo desde nuestras propias copias. Como os dije en el primer párrafo

la creación y despliegue de un controlador de versiones SVN está detallado

en artículos anteriores así que ante la duda os emplazo a que les volváis a

echar un vistazo.

¡¡¡CONCLUSIONESSSS!!!.

Svnlook nos da mucha información del repositorio SVN, pero nos va permitir

verificar que existe un repositorio o determinada revisión. Además podemos

saber a que revisión corresponde la última modificación registrada en SVN.

Svnadmin dump/load nos permite hacer y recargar volcados a fichero de

nuestros repositorios SVN, además con control por revisiones, de forma

incremental, etc.

Vemos que tenemos un control muy fino de lo que queremos hacer. Sin

embargo se me antoja un poco complicado automatizar todo esto.

Vale, no os preocupéis le doy unas vueltas a todo esto: repasamos un poco

de shell script y nos montamos un “pseudo script” que haga uso de estos

Page 70: Cesnavarra 2008-boletín 12

comandos y pueda ser llamado desde un “cron” para automatizar el sistema.

Enlaces de interés:

http://benr75.com/2007/04/24/backing-up-subversion-using-hot-backup-py

http://svnbook.red-bean.com/en/1.1/ch05s03.html

http://svnbook.red-bean.com/en/1.1/ch05s02.html

Categorías CES OpenSouce/Java

Tema Varios

Autor Kike Muro Arbizu

Mes Diciembre

Año 2008

Boletín 12

Título Ontologías

Texto En el artículo XML, RDFS, Ontologías: Camino a la Web semántica, se comenzó a

dar una primera visión de las ontologías, sin embargo quedaron muchos cabos

sueltos y no se llegó a profundizar.

Actualmente, no es algo muy extendido, pero ya comienza a haber iniciativas

como la extensión de MediaWiki (la Wikipedia utiliza este

software)Extensions:Semantic MediaWiki, que pretende incluirlas en las páginas

de esta Wiki. Por otra parte, Swoogle, es un buscador de la Web semántica que

permite buscar entre otras cosas ontologías y recursos de la misma.

A continuación se intentará explicar los pasos necesarios para la creación de una

de ellas. Y se irán ilustrando mediante un ejemplo de creación de ontologías

muy sencillo empleando el lenguaje OWL y en formato XML. Una ontología en

OWL está formada por individuos (son instancias de clases), propiedades (al

darles valores se crean las individuos) y clases.

En términos prácticos, el desarrollo de una otología incluye:

Definir las clases de la ontología.

Page 71: Cesnavarra 2008-boletín 12

Ordenar las clases en una jerarquía taxonómica (subclase-

superclase).

Definir propiedades y describir los valores permitidos para

ellas.

Introducir valores en las propiedades para crear instancias.

Se puede crear entonces una base de conocimiento definiendo instancias

individuales de esas clases introduciendo en propiedades específicas información

de valor y restricciones adicionales de esas propiedades.

Como ayuda a la hora de crear ontologías uno debe recordar las siguientes

reglas, aunque parezcan un poco dogmáticas:

No hay una forma correcta de modelar un dominio – siempre hay alternativas viables. La mejor solución casi

siempre depende de la aplicación que se le vaya a dar y de las extensiones que se anticipan.

El desarrollo de ontologías es necesariamente un proceso iterativo.

Los conceptos de la ontología deberían ser cercanos a objetos (físicos o lógicos) y a relaciones en el dominio de

interés. Probablemente serán nombres (objetos) o verbos (relaciones) en frases que describan el dominio.

Al final, lo que guiará las decisiones de diseño serán las decisiones tomadas sobre

cómo de general o detallada va a ser la ontología y para qué se va a usar. Lo que

siempre se debe recordar durante este proceso es que una ontología es un

modelo de la realidad y que los conceptos en la ontología, deben reflejar esa

realidad. Así nunca se podría tener un concepto que fuera ent, elfo o hobbit a no

ser que se estuviera reflejando la realidad del mundo del Señor de los

Anillos. Una vez definida la ontología debe evaluarse y probablemente será

necesario revisarla y hacer cambios.

Se seguirán una serie de pasos para definir la ontología que vamos a hacer:

Paso 1. Determinar el dominio y el ámbito de la ontología.

Es conveniente comenzar el desarrollo de una ontología definiendo su dominio y

ámbito. Esto es, responder a varias cuestiones básicas:

¿Cuál es el dominio que cubrirá la ontología?

¿Para qué se va a usar?

¿A qué tipos de preguntas de información en la ontología se debería responder?

Page 72: Cesnavarra 2008-boletín 12

¿Quién usará y mantendrá la ontología?

En este caso se creará una ontología sobre personajes del Señor de los Anillos

que se usará como ejemplo y ofrecerá relaciones entre ellos.

Paso 2. Considere reutilizar ontologías existentes

Siempre suele ser conveniente pensar en lo que han hecho otras personas y

comprobar si se puede reutilizar extendiendo las fuentes y refinándolas para que

se adecuen a la tarea. Por ejemplo, utilizar ontologías como la Dublin core que

puede servir para clasificar información de películas, libros, etc., o lafoaf (Friend

of a friend) que puede servir para identificar personas a lo largo de internet.

Así en la cabecera de la ontología si se van a emplear los conceptos definidos

dentro de la ontología foaf, se tendría que declarar así:

<rdf:RDF

xmlns="http://www.servidor.de.ejemplo.es/ontologia_de_prueba.owl#"

xml:base="http://www.servidor.de.ejemplo.es/ontologia_de_prueba.owl"

xmlns:xsd="http://www.w3.org/2001/XMLSchema#"

xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"

xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"

xmlns:owl="http://www.w3.org/2002/07/owl#"

xmlns:foaf=“http://xmlns.com/foaf/0.1/”>

Luego para llamar a los conceptos, simplemente se utilizaría foaf:Person o

cualquier otro de ellos y se le daría el valor, al igual que se utiliza owl:Class para

definir una clase o rdfs:subClassOf para decir que una clase depende de otra.

Estas líneas lo que están definiendo es un namespace, es decir, un conjunto de

nombres en el cuál todos son únicos. Las dos primeras líneas de esa declaración

indican el espacio de nombres asociado a esa ontología. La primera lo declara

como el espacio de nombres por defecto, diciendo que los nombres cualificados

que no tengan ningún prefijo se refieren a la ontología actual. La segunda

identifica la URI base del documento. El resto de declaraciones indica que

aquellos nombres cualificados que empiecen por rdfs:, owl:, rdf: o fofa: se

referirán a conceptos definidos en esas ontologías.

Paso 3. Enumere los términos importantes en la ontología

Es útil escribir una lista de términos que se quieren explicar al usuario o de los

que se quieren hacer afirmaciones.

Page 73: Cesnavarra 2008-boletín 12

En la ontología que se está creando se definirán términos como Elfo, Ent, Enano,

Hobbit, Orco, Humano, Anillo, …

Paso4. Defina las clases y la jerarquía de clases

Hay varias opciones a la hora de desarrollar una jerarquía de clases:

Comenzar por los conceptos más generales e ir especializándolos.

Comenzar por los conceptos específicos e ir agrupándolos

en clases más generales.

una mezcla de ambas, definir los conceptos generales más

importantes y luego ir generalizándolos y especializándolos.

Por ejemplo, de la clase ser de esta ontología (clase general), tendremos las

especializaciones de orco, elfo, hobbit, ent, etc.

Paso 5. Defina las propiedades de las clases

Una vez que se tienen definidas algunas de las clases, se debe describir la

estructura interna de los conceptos.

En general, hay varios tipos de propiedades de objeto que pueden convertirse en

propiedades en una ontología:

“intrínsecas” como el sabor de un vino,

“extrínsecas” como el nombre de un vino,

relaciones con otros individuos, estas son las relaciones

entre instancias de clases y otros ítems.

En la ontología que se está definiendo se pueden considerar como propiedades

lleva, es_amigo_de, …

Paso 6. Defina los valores que pueden tomar las propiedades de las clases

Las propiedades pueden tener diferentes facetas describiendo el tipo de valor,

valores permitidos, el número de valores (cardinalidad), y otras características de

los valores que pueden tomar. Por ejemplo, el valor de una propiedad de

nombre (como por ejemplo “el nombre de un vino”) es una cadena de

caracteres.

Tipos de valores

Entre otros pueden ser (lo más comunes):

String: Es el tipo de valor más sencillo que se utiliza en

propiedades como un nombre: El valor es una cadena de

Page 74: Cesnavarra 2008-boletín 12

texto.

Number (a veces tipos más específicos como Float e Integer): describe propiedades con valores numéricos.

Boolean propiedades que simplemente son si o no,

verdadero/falso.

Enumeración: Lista de valores específicos permitidos para

la propiedad.

Tipo instancia: Permiten la definición de relaciones entre instancias de las clases. También deben definir una lista de clases permitidas de las que las instancias pueden

provenir.

Dominio y Rango de la propiedad

Las clases permitidas de tipo instancia son llamadas Rango de una

propiedad. Las clases a las que la propiedad está unida o las clases que la

propiedad describe se llaman dominio de la propiedad.

Paso 7. Cree instancias de las clases

El último paso es crear instancias individuales de las clases en la jerarquía. La

definición de una instancia individual de una clase requiere:

1. Elegir una clase.

2. Crear una instancia individual de la clase

3. Darle los valores apropiados a las propiedades.

A continuación, se mostrará el ejemplo de ontología que se ha propuesto

tomando como base el mundo del Señor de los Anillos. No hay relaciones

complicadas ni tampoco se expresa toda la potencia que las ontologías pueden

tener, pero a modo de ejemplo sirve. Esto viene escrito en notación XML, se

debería guardar en un archivo .owl para que fuera reconocible. Llamaremos a

esta ontología LordOfTheRings.owl y se podría acceder a ella en

http://www.servidor.de.ejemplo.es/.

<?xml version="1.0"?> <!DOCTYPE rdf:RDF [ <!ENTITY owl "http://www.w3.org/2002/07/owl#" > <!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" > <!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#"

> <!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-

ns#" > ]>

<!-- Declaración de espacios de nombres cualificados --> <rdf:RDF xmlns="http://www.servidor.de.ejemplo.es/LordOfTheRing

Page 75: Cesnavarra 2008-boletín 12

s.owl#" xml:base="http://www.servidor.de.ejemplo.es/LordOfTheRi

ngs.owl" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:owl="http://www.w3.org/2002/07/owl#" >

<!-- A continuación se define la ontología --> <!-- Se hacen una serie de afirmaciones explicándola --> <owl:Ontology rdf:about=""> <!-- Se le hace un comentario sobre ella explicándola

--> <rdfs:comment rdf:datatype="&xsd;string"> Ejemplo sencillo de ontología sobre personajes

del Señor de los Anillos. </rdfs:comment> </owl:Ontology>

<-- //////////// // Clases // //////////// --> <!-- A continuación se pasa a definir las clases de la

ontología --> <!-- La declaración de una clase se hace mediante la

sentencia --> <!-- owl:Class y su nombre se da con rdf:about =

#NombreClase --> <owl:Class rdf:about="#Cosa"> <rdfs:label>Cosa</rdfs:label> <rdfs:comment rdf:datatype="&xsd;string"> Clase superior de la ontología. Es buena cosa

que las clases de la ontología no dependan de la propia clase owl:Thing sino de

una clase que depende de ella. </rdfs:comment> </owl:Class> <owl:Class rdf:about="#Objeto"> <rdfs:label>Objeto</rdfs:label> <rdfs:comment rdf:datatype="&xsd;string"> Clase superior de las que describen las cosas

inanimadas. </rdfs:comment> <rdfs:subClassOf> <owl:Class rdf:about="#Cosa"/> </rdfs:subClassOf> </owl:Class> <!-- Con rdfs:subClassOf, lo que se hace es definir una

jerarquía --> <!-- de clases, después en el siguiente tag se dirá de que

clase --> <!-- hereda, en este caso es de la clase Objeto --> <owl:Class rdf:about="#Anillo"> <rdfs:label>Anillo</rdfs:label> <rdfs:subClassOf>

Page 76: Cesnavarra 2008-boletín 12

<owl:Class rdf:about="#Objeto"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Ser"> <rdfs:label>Ser</rdfs:label> <rdfs:comment rdf:datatype="&xsd;string"> Clase superior de las que describen las cosas

animadas, con vida. </rdfs:comment> <rdfs:subClassOf> <owl:Class rdf:about="#Cosa"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Elfo"> <rdfs:label>Elfo</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Ser"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Enano"> <rdfs:label>Enano</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Ser"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Humano"> <rdfs:label>Humano</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Ser"/> </rdfs:subClassOf> </owl:Class>

<owl:Class rdf:about="#Hobbit"> <rdfs:label>Hobbit</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Ser"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Orco"> <rdfs:label>Orco</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Ser"/> </rdfs:subClassOf> </owl:Class>

<owl:Class rdf:about="#Mago"> <rdfs:label>Mago</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Ser"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Ent"> <rdfs:label>Ent</rdfs:label>

Page 77: Cesnavarra 2008-boletín 12

<rdfs:subClassOf> <owl:Class rdf:about="#Ser"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Dunedain"> <rdfs:label>Dunedain</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Humano"/> </rdfs:subClassOf> </owl:Class> <owl:Class rdf:about="#Rohirrim"> <rdfs:label>Rohirrim</rdfs:label> <rdfs:subClassOf> <owl:Class rdf:about="#Humano"/> </rdfs:subClassOf> </owl:Class>

<!-- A continuación se creará una clase más compleja --> <!-- Será Portador del Anillo, y tendrá que heredar de ser

y --> <!-- además deberá tener la propiedad lleva --> <owl:Class rdf:about="#PortadorAnillo"> <rdfs:label>Portador del anillo</rdfs:label> <owl:intersectionOf rdf:parseType="Collection"> <owl:Class rdf:about="#Ser" /> <owl:Restriction> <owl:onProperty rdf:resource="#lleva" /> <owl:hasValue rdf:resource="#ElUnico" /> </owl:Restriction> </owl:intersectionOf> </owl:Class>

<!-- /////////////////////////// // Propiedades de objeto // /////////////////////////// -->

<!-- A continuación se definen las propiedades que pueden

tener --> <!-- las clases -->

<owl:ObjectProperty rdf:about="#es_amigo_de"> <!-- Con <rdf:type rdf:resource="&owl;SymmetricProperty"

/> se --> <!-- dice que la propiedad es simétrica, es decir, que si

A es --> <!-- amigo de B, B es amigo de A --> <rdf:type rdf:resource="&owl;SymmetricProperty" /> <!-- A continuación se define el rango y el dominio de la

--> <!-- propiedad --> <rdfs:domain> <owl:Class rdf:about="#Ser"/> </rdfs:domain> <rdfs:range> <owl:Class rdf:about="#Ser"/>

Page 78: Cesnavarra 2008-boletín 12

</rdfs:range> </owl:ObjectProperty> <owl:ObjectProperty rdf:about="#es_enemigo_de"> <rdf:type rdf:resource="&owl;SymmetricProperty" /> <rdfs:domain> <owl:Class rdf:about="#Ser"/> </rdfs:domain> <rdfs:range> <owl:Class rdf:about="#Ser"/> </rdfs:range> </owl:ObjectProperty> <owl:ObjectProperty rdf:about="#lleva"> <!-- Con la siguiente definición se especifica que son

inversas --> <!-- es decir, si A lleva a B, es porque B es llevado por

A --> <owl:inverseOf> <owl:ObjectProperty

rdf:about="#es_llevado_por"/> </owl:inverseOf> <rdfs:domain> <owl:Class rdf:about="#Ser"/> </rdfs:domain> <rdfs:range> <owl:Class rdf:about="#Objeto"/> </rdfs:range> </owl:ObjectProperty> <owl:ObjectProperty rdf:about="#es_llevado_por"> <owl:inverseOf> <owl:ObjectProperty rdf:about="#lleva"/> </owl:inverseOf> <rdfs:domain> <owl:Class rdf:about="#Objeto"/> </rdfs:domain> <rdfs:range> <owl:Class rdf:about="#Ser"/> </rdfs:range> </owl:ObjectProperty>

<!-- //////////////// // Instancias // //////////////// --> <!-- A continuación se definen las instancias de las

clases --> <Anillo rdf:about="#ElUnico"> <es_llevado_por rdfs:resource=#Frodo/> </Anillo> <Hobbit rdf:about="#Frodo"> <lleva rdfs:resource=#ElUnico/> <es_amigo_de rdfs:resource="#Trancos"/> <owl:sameAs rdf:resource="#FrodoPortador"/> <!-- Con esto se dice que las dos instancias son la misma

Page 79: Cesnavarra 2008-boletín 12

--> </Hobbit> <PortadorAnillo rdf:about="#FrodoPortador"> <es_amigo_de rdfs:resource="#Trancos"/> <owl:sameAs rdf:resource="#Frodo"/> <!-- Con esto se dice que las dos instancias son la misma

--> </PortadorAnillo>

<Dunedain rdf:about="#Aragorn"> <es_amigo_de rdfs:resource=#Frodo/> <es_enemigo_de rdfs:resource=#Saruman/> <owl:sameAs rdf:resource="#Trancos"/> <!-- Con esto se dice que las dos instancias son

la misma --> </Dunedain> <Dunedain rdf:about="#Trancos"> <es_amigo_de rdfs:resource=#Frodo/> <es_enemigo_de rdfs:resource=#Saruman/> <owl:sameAs rdf:resource="#Aragorn"/> </Dunedain> <Mago rdf:about="#Saruman"> <es_enemigo_de rdfs:resource=#Trancos/> </Mago>

<!-- ///////////// // Axiomas // ///////////// -->

<!-- Esta es la declaración de axiomas, define relaciones

entre --> <!-- clases. En owl, todas las clases están solapadas

salvo que --> <!-- se diga lo contrario con <owl:disjointWith> -->

<owl:Class rdf:about="#Objeto"> <owl:disjointWith> <owl:Class rdf:about="#Ser"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Ser"> <owl:disjointWith> <owl:Class rdf:about="#Objeto"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Elfo"> <owl:disjointWith> <owl:Class rdf:about="#Enano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Humano"/> </owl:disjointWith> <owl:disjointWith>

Page 80: Cesnavarra 2008-boletín 12

<owl:Class rdf:about="#Hobbit"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Orco"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Mago"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Ent"/> </owl:disjointWith> </owl:Class> <owl:Class rdf:about="#Enano"> <owl:disjointWith> <owl:Class rdf:about="#Elfo"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Humano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Hobbit"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Orco"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Mago"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Ent"/> </owl:disjointWith> </owl:Class> <owl:Class rdf:about="#Humano"> <owl:disjointWith> <owl:Class rdf:about="#Elfo"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Enano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Hobbit"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Orco"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Mago"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Ent"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Hobbit"> <owl:disjointWith> <owl:Class rdf:about="#Elfo"/> </owl:disjointWith> <owl:disjointWith>

Page 81: Cesnavarra 2008-boletín 12

<owl:Class rdf:about="#Enano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Humano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Orco"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Mago"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Ent"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Orco"> <owl:disjointWith> <owl:Class rdf:about="#Elfo"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Enano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Humano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Hobbit"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Mago"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Ent"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Mago"> <owl:disjointWith> <owl:Class rdf:about="#Elfo"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Enano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Humano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Hobbit"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Orco"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Ent"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Ent"> <owl:disjointWith>

Page 82: Cesnavarra 2008-boletín 12

<owl:Class rdf:about="#Elfo"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Enano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Humano"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Hobbit"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Orco"/> </owl:disjointWith> <owl:disjointWith> <owl:Class rdf:about="#Mago"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Dunedain"> <owl:disjointWith> <owl:Class rdf:about="#Rohirrim"/> </owl:disjointWith> </owl:Class>

<owl:Class rdf:about="#Rohirrim"> <owl:disjointWith> <owl:Class rdf:about="#Dunedain"/> </owl:disjointWith> </owl:Class> </rdf:RDF>

ENLACES DE INTERÉS:

ONTOLOGÍAS

http://www.ksl.stanford.edu/people/dlm/papers/ontology101/ontology101-noy-mcguinness.html

http://es.wikipedia.org/wiki/Ontolog%C3%ADa_(Inform%C3%A1tica)

http://www.wshoy.sidar.org/index.php?2005/12/09/30-ontologias-que-son-y-para-que-sirven

http://www.hipertexto.info/documentos/ontologias.htm

http://elies.rediris.es/elies18/index.html

http://www.ccs.neu.edu/course/isu300/readings/ontology.pdf

http://ksl.stanford.edu/people/dlm/papers/ontology-tutorial-noy-mcguinness.pdf

Page 83: Cesnavarra 2008-boletín 12

http://www.co-

ode.org/resources/tutorials/ProtegeOWLTutorial.pdf

http://www.cs.man.ac.uk/~horrocks/ISWC2003/Tutorial/

http://semanticweb.org/

http://www.w3.org/TR/owl-guide/

WEB SEMÁNTICA

http://es.wikipedia.org/wiki/Web_sem%C3%A1ntica

http://www.w3c.es/Divulgacion/Guiasbreves/WebSemanti

ca

http://www.hipertexto.info/documentos/web_semantica.htm

http://www.informandote.com/jornadasIngWEB/articulos/jiw02.pdf

http://www.w3.org/2001/sw/

http://www.w3.org/2008/Talks/1009-bratt-W3C-SemTech/Overview.html

http://swoogle.umbc.edu/

Categorías

CES OpenSouce/Java

Tema Varios

Autor Blanca Cubas Cruz

Mes Diciembre

Año 2008

Boletín 12

Título Automatización copias subversión

Texto Automatización de copias incrementales de repositorios

Subversión.

En mi anterior articulo Copias de seguridad de un repositorio Subversión,

explicamos como a través de los comandos que distribuye el

Page 84: Cesnavarra 2008-boletín 12

propio Subversión(SVN), podíamos realizar copias de seguridad con cierto grado

de control y nivel de personalización; Podíamos hacer copias completas, copias

de una revisión en concreto, copias de rangos de revisiones, copias incrementales

etc.

Concluimos que ese nivel de control y personalización añadía también cierta

complejidad para agruparlos y automatizar las copias con una entrada en el

“crontab” por ejemplo.

Sin embargo, lejos de amedrentarnos aceptamos el desafío de plantear un seudo

script que aunase la combinación de comandos de SVN y de esta manera, dicho

script pudiese programarse en el cron.

Vale, pues ha llegado el día de ser consecuente con las promesas hechas, (“ Alea

iacta est”).

Para ir empezando, vamos a ir planteando una posible solución.

Humm .. ¿Que queremos? ¡¡Ya esta!!, queremos una copia completa de los

repositorios el Lunes, y copias incrementales asta el viernes inclusive,¡!Ahh¡¡

entonces;

El lunes copia completa, “svnadmin dump [ repositorio ] > [

filename ]”

El martes, obtenemos la ultima revisión,

svnlook youngest [ repositorio ] > [ filename ] svnadmin dump [ repositorio ] –r x:y –incremental > [

filename ] así sucesivamente asta el viernes inclusive.

¡¡Ja!! ¿dudas?, yo si, tengo alguna, me tengo que guardar de alguna manera la ultima revisión incluida en cada copia ya sean

completas o parciales; me tengo que plantear algún criterio para nombrar los ficheros de las copias y que reflejen cierta

secuencialidad,

por ejemplo; file01, file02, file03, file14 … ¿otra vez?, en fin.

Después debería de borrar todos los ficheros para poder volver a

comenzar el ciclo…

Vale, creo que ya tenemos un plan y suficientes dudas para

comenzar a decidir cosas.

Como nombre de ficheros, os propongo lo siguiente.

#echo

$FECHA‖_‖$HOSTNAME‖_‖$REPOSITORIO‖_‖$TYPOBACKUP‖.dump$R1:$R2 20090108_KIRNIS_PruebaRepo01_full.dump0:10 #

Page 85: Cesnavarra 2008-boletín 12

Donde

FECHA=` date +%Y%m%d` HOSTNAME, es una variable de entorno shell. REPOSITORIO=”PruebaRepo01” TYPOBACKUP=”full” R1=0 R2=10

En el nombre, le estamos indicando la fecha en que se realizo, el host desde donde se realiza, el tipo de backup, y las revisiones; Tenemos mucho.

Por ejemplo

#pwd /opt1/backups #ls -t *PruebaRepo01* 20090108_KIRNIS_PruebaRepo01_inc.dump17:19 20090107_KIRNIS_PruebaRepo01_inc.dump11:16 20090105_KIRNIS_PruebaRepo01_full.dump0:10 # # FILE_BACKUPS=(`ls -tc *PruebaRepo01*`) # echo ${FILE_BACKUPS[*]} 20090108_KIRNIS_PruebaRepo01_inc.dump17:19 20090107_KIRNIS_PruebaRepo01_inc.dump11:16 20090105_KIRNIS_PruebaRepo01_full.dump0:10 # # echo ${FILE_BACKUPS[0]} 20090109_KIRNIS_PruebaRepo01_inc.dump17:19 # A ver, me explico, estamos colocados en el directorio donde se generan los

ficheros de backups, con el primer listado os quería mostrar que podemos

obtener la lista de ficheros del repositorio que nos interesa ordenados por la

fecha de creación mas actual; En la siguiente instrucción, “FILE_BACKUPS=(`ls -tc

*PruebaRepo01*`)”, estoy guardando la lista por columnas y ordenada por fecha

de creación mas actual en una array de shell.

“echo $,FILE_BACKUPS**+-”, nos muestra todo el contenido del array.

“echo $,FILE_BAKUPS*0+-, nos muestra el primer elemento del array, que en

nuestro caso es el ultimo fichero de backup generado o mas actual;

Asta ahí quería llegar yo, tenemos el fichero de backup más actual y gracias a su

nombre tenemos las revisiones que incluye. En este ejemplo, el fichero de

backup, corresponde al repositorio “PruebaRepo01”, es una copia incremental y

abarca desde la revisión 17 a la 19.

Si tuviéramos que hacer una nueva copia incremental, obtendríamos la última

revisión incluida en el fichero de backup más actual y luego preguntaríamos al

repositorio cual es la última revisión.

#REPOSITORIES_DIR=‖/opt1/Repositories‖ #REPOSITORY=‖PruebaRepo01‖ #FILE_BACKUPS=(`ls -tc *$REPOSITORY*`) #FILE_BACKUP=‖${FILE_BACKUPS[0]}‖

Page 86: Cesnavarra 2008-boletín 12

#echo ${FILE_BACKUP#*‖:‖} 19 #R1=`${FILE_BACKUP#*‖:‖} #R1=` exp. $R1 + 1 ` #echo $R1 20 #svnlook youngest $REPOSITORIES_DIR‖/‖$REPOSITORY 23 #R2=` svnlook youngest $REPOSITORIES_DIR‖/‖$REPOSITORY` #echo $R2 23 #FECHA=`date +%Y%m%d` #TYPEBACKUP=‖inc‖ #NEW_BACKUP_FILE=$FECHA‖_‖$HOSTNAME‖_‖$REPOSITORY‖_‖$TYPEBAC

KUP‖.dump‖$R1‖:‖$R2 # #snvdump $REPOSITORIES_DIR‖/‖$REPOSITORY –r $R1:$R2 >

$NEW_BACKUP_FILE * dumped revision 20 * dumped revision 21 * dumped revision 22 * dumped revision 23

#ls –t *$REPOSITORY* 20090109_KIRNIS_PruebaRepo01_inc.dump20:23 20090108_KIRNIS_PruebaRepo01_inc.dump17:19 20090107_KIRNIS_PruebaRepo01_inc.dump11:16 20090105_KIRNIS_PruebaRepo01_full.dump0:10 # La expresión $,FILE_BACKUP#*”:”-, es una expresión para obtener substrings de

“shell”, esta en concreto nos devuelve todos los caracteres a la derecha de el

símbolo “:”, que en este caso corresponde al valor numérico que representa a la

ultima revisión incluida en el fichero de backup correspondiente a ese nombre de

fichero, en este caso, si el nombre del fichero es

20090108_KIRNIS_PruebaRepo01_inc.dump17:19, la expresión devuelve 19,

ósea la revisión 19.

En la siguiente expresión “R1=` exp. $R1 + 1 `” incrementamos el valor de la

ultima revisión en 1 para que el la nueva copia incremental incluya solo

exclusivamente las nuevas revisiones.

Vale, esta es la secuencia de comandos para generar el nuevo fichero de backup

incremental en una Shell; esto es lo que deberíamos basar nuestro script a partir

de aquí podemos añadir lo que queramos.

El script, el script esta organizado así :

Zona de definición de variables, donde tenemos apartados dedicados a las

variables que intervienen en el script:

La generales como el, PATH, FECHA, HOME etc.

Variables que definen los directorios y tipos de backup;

Variables relacionadas con los repositorios de SVN,

Page 87: Cesnavarra 2008-boletín 12

directorios, repositorios etc.

La siguiente zona corresponde a la zona donde definimos las funciones del que

usamos en el script:

getParametros; recoge los parámetros que se pasan al script.

checkRepositorio; comprueba si el repositorio existe o es correcto

checkRevision; Comprueba si la revisión es correcta.

getUltimaRevisionBackup; Obtiene la última revisión indicada en el nombre del fichero de backup.

doDump(); Método que gestiona las llamadas al comando “svnadmin dump” según sean copias completas o

incrementales.

Y finalmente la zona “Cuerpo”, esta zona recorre la lista de repositorios y va

haciendo llamadas a doDump en función de si el tipo de copia pasado como

parámetro al script es de tipo completo o incremental.

Al final también hacemos una especie de control de errores consideramos que si

aunque solo una sola copia parcial de uno de los repositorios ha sido errónea la

salida de la ejecución de todo el script debe ser errónea.

#!/bin/sh

#### backup_svnDump.sh #####

## Actualizamos el acceso a las carpetas de ejecutables de este

script. PATH=/bin:/sbin:/usr/bin:/usr/sbin

## Nos guardamos la fecha en la que se lanza el backup. FECHA=`date +%Y%m%d`

## Establecemos el directorio home. export HOME="/opt1/home/backup"

## Directorios para el backup BACKUP_BIN_DIR=$HOME"/bin" BACKUP_DIR=$HOME"/backup" BACKUP_TYPE="" PATRON=".dump"

## Variables necesarias para la gestión de copias del SVN. REPOSITORIO_LIST=( "PruebaRepo01" "PruebaRepo02" "PruebaRepo03‖ ) REPOSITORIES_DIR="/opt1/Repositorio" REPOSITORY="" REVISION01="" REVISION02="" LAST_REVISION="" FILENAME=$BACKUP_DIR"/"

Page 88: Cesnavarra 2008-boletín 12

## Funciones

## getParametros; recogemos los parámetros que se pasan como getParametros() { for ARGUMENTO in $* do PARAMETRO=‖${ARGUMENTO%=*} VALOR=‖${ARGUMENTO#*=}‖ Case ―$PARAMETRO‖ in ―--repositories_dir‖) REPOSITORIES_DIR=$VALOR

;; ―—-backup_type‖) BACKUP_TYPE=$VALOR ;; Esac Done }

## checkRepositorio; comprueba si el repositorio existe o es

correcto. checkRepositorio () { REPOSITORIO="" REPOSITORIO=$1

if [ -s $REPOSITORIO ] then svnlook author $REPOSITORIO if [ $? = 1 ] then return 1 fi return 0 else return 1 fi }

## checkRevision; Comprueba si la revisión es correcta. checkRevision () { REVISION=‖‖ REVISION=$1 shift REPOSITORIO=$1 checkRepositorio $REPOSITORIO if [ $? = 1 ] then return 1 fi svnlook info -r $REVISION $REPOSITORIO if [ $? = 1 ] then return 1 fi }

## getUltimaRevisionBackup; Obtiene la ultima revisión indicada en

el nombre del fichero de backup. getUltimaRevisionBackup() { ## recogemos los parametros de entrada de las funciones. FILENAME=$1 Shift REPOSITORIO=$1

SEPARADORREVISION=‖:‖ REVISION=${FILENAME#*$SEPARADORREVISION}

Page 89: Cesnavarra 2008-boletín 12

CheckRevision $REVISION $REPOSITORIO if [ $? = 1 ] then return 1 fi R2=$REVISION }

doDump() {

BACKUP_TYPE=$1 shift REPOSITORIO=$1 shift FILENAME=$1 shift REVISION01=$1

checkRepositorio ―$REPOSITORIO‖

if [ $? = 1 ] then return 1

fi

REVISION02=`svnlook youngest ―$REPOSITORIO‖`

if [ "$BACKUP_TYPE" != "full" -a "$BACKUP_TYPE" != "inc" ] then return 1 fi

if [ $BACKUP_TYPE = "inc" ] then checkRevision ―$REVISION01‖ ―$REPOSITORIO‖ if [ $? = 1 ] then return 1 fi

#Si la revisión es mayor o igual que la ultima revisión del

repositorio, o hay algo incorrecto o no ha habido revisiones

nuevas. No hacemos nada. if [ REVISION01 –ge $REVISION02 ] then exit 1 fi

REVISION01=` expr REVISION01 + 1 ` else REVISION01=‖0‖ fi # Actualizamos el nombre del fichero con los números de las

revisiones. $FILENAME=$FILENAME$REVISION01‖:‖$REVISION02

if [ "$BACKUP_TYPE" = "full" ] then svnadmin dump $REPOSITORIO -r $REVISION01 :

$REVISION02 > $FILENAME elif [ "$BACKUP_TYPE" = "inc" ] then svnadmin dump $REPOSITORIO -r $REVISION01 :

$REVISION02 --incremental > $FILENAME

Page 90: Cesnavarra 2008-boletín 12

}

## Cuerpo del script ## 1 Obtenemos los parámetros de entrada. ## 2 Recorremos la lista de repositorios. ## 3 Creamos el nombre del fichero de backup, sin especificar el

numero de revisiones. ## 4 En función del tipo de backup full/inc se llama al método

DoDump especificando la revisión inicial o no. ## 5 control de la salida de ejecución de las instrucciones.

getParametros $*

cd $BACKUP_DIR ERROR=0

for REPOSITORY in ${REPOSITORIO_LIST[*]} do

FILENAME_BACKUP=$BACKUP_DIR‖/‖$FECHA‖_‖$HOSTNAME‖_‖$REPOSITO

RY‖_‖$BACKUPTYPE‖.dump‖$

if [ ―$BACKUP_TYPE‖ = ―inc‖ ] then

FILE_BACKUPS=(`ls -tc *$REPOSITORY*`) REVISION02=`svnlook youngest $REPOSITORIO` LAST_FILE_BACKUP=‖${FILE_BACKUPS[0]}‖ REVISION01=‖‖ getUltimaRevisionBackup $LAST_FILE_BACKUP

$REPOSITORIO doDump $BACKUPTYPE $REPOSITORIO $FILENAME_BACKUP

$REVISION01 else

doDump ―$BACKUPTYPE‖ ―$REPOSITORIO‖

―$FILENAME_BACKUP‖ fi

unset REVISION01 unset REVISION02 unset FILENAME_BACKUP

if [ $? = 1 ] then

ERROR=1 fi

done

if [ $ERROR = 1 ] then exit 1 fi

exit 0 Para finalizar; Esto es un “pseudo” script, lo que quiero decir es

que debéis tomarlo como un script de referencia, no me puedo asegurar que lo copiéis tal cual, lo ejecutéis y no os de errores;

Page 91: Cesnavarra 2008-boletín 12

Sin embargo la idea y la organización del mismo si que la he

probado y creo que os puede ser útil o por lo menos interesante.

Este script, por ejemplo lo podríamos copiar en una carpeta

relacionada con el ejemplo descrito: “/opt1/backup/bin”.

Después de darle los permisos pertinentes podríamos llamar al comando de las siguientes maneras.

Para las copias completas.

backup_svnDump.sh --repositories_dir=‖/opt1/Repositories‖ –

backup_type=‖full‖ Para las copias incrementales.

backup_svnDump.sh --repositories_dir=‖/opt1/Repositories‖ –

backup_type=‖inc‖ Automatización.

Ahora solo nos falta incluirlo en un fichero cron, con el comando “crontab –e” y dejar algo parecido a esto:

SHELL=/bin/bash PATH=/usr/bin:/usr/sbin:/bin:/sbin:/opt1/home/backup/bin 00 22 * * 1 backup_svnDump.sh --

repositories_dir=‖/opt1/Repositories‖ –backup_type=‖full‖ 00 22 * * 2-5 backup_svnDump.sh --

repositories_dir=‖/opt1/Repositories‖ –backup_type=‖inc‖ 00 22 * * 6 /opt1/home/cesbackup/bin/delete_files.sh --

backup_dir="/opt1/home/cesbackup" El lunes se llama al script para hacer una copia completa.

De martes a viernes, se llama al script para hacer una copia

incremental.

El Sábado se llama a método que borra los ficheros de la semana para reiniciar el ciclo de copias la semana siguiente.

Referencias:

Linux Shell Scripting with Bash, Sams publising, isbn: 0-672-

32642-6.

Copias de seguridad de un repositorio subversion.

Categorías

CES OpenSouce/Java

Tema Varios

Autor Kike Muro Arbizu

Mes Diciembre

Año 2008

Page 92: Cesnavarra 2008-boletín 12

Boletín 12

Título Collection: Extensión para Mediawiki

Texto Introducción

Mediawiki es un motor para wikis bajo licencia GPL y programado

en PHP, además también hace uso de MySQL sobre Apache.

Una de las principales ventajas de Mediawiki es el soporte de

extensiones, que permiten añadir funcionalidades que no vienen

dentro de Mediawiki o integrarlo con otros sistemas. Estas

extensiones dan la oportunidad al administrador y a los usuarios

finales de adaptar la wiki a sus necesidades específicas.

Las extensiones son compilaciones de código PHP que añaden o

mejoran las funcionalidades del núcleo principal de la Mediawiki.

Dependiendo del objetivo que se pretenda conseguir se pueden

utilizar distintos tipos de extensiones:

Extender los formatos que utiliza Mediawiki para editar los

artículos: mirar las categorías “Parser function extensions” y “Parser extensions”.

Presentación de informes y añadir nuevas capacidades administrativas, mirar la categoría “Special page

extensions”.

Cambiar el “look and feel” de Mediawiki, mirar las

categorías: “Galery of user styles” y “User interface extensions”.

Mejorar la seguridad a través de mecanismos de autentificación, mirar la categoría “Authentication and

authorization extensions”.

A la hora de buscar una extensión se puede buscar por

categorías o directamente en un listado de todas las extensiones

existentes. Si la extensión que necesitas no está escrita todavía,

la puedes escribir tu mismo y añadirla a la lista de las ya

existentes.

Comprobación de las extensiones instaladas

Solo si se tiene acceso como administrador al servidor se pueden

instalar extensiones para mediawiki, el resto de los usuarios solo

Page 93: Cesnavarra 2008-boletín 12

pueden chequear que extensiones están activas en una instancia

de Mediawiki.

Instalando una extensión

Mediawiki esta lista para aceptar extensiones nada más terminar

de instalarla.

En este caso vamos a ver el proceso de instalación de la

extensión Collection sobre Red Hat. Esta extensión nos permite

organizar una selección de páginas en una colección. Con esta

extensión también se puede:

editar y estructurar mediante capítulos

exportar como documento PDF

exportar como documento de texto ODF

exportar como DocBook XML

La extensión Collection ha sido desarrollada bajo la GNU General

Public License por PediaPress GMBH, en colaboración con

Wikimedia Foundation y la Commonwealth of Learning. Esta

extensión se ha testeado con Mediawiki 1.11 y posteriores, con

lo que no se asegura que vaya a funcionar para versiones

anteriores.

Para añadir una extensión se deben seguir los siguientes pasos:

1.- Antes de empezar:

Algunas extensiones de Mediawiki requieren la

instalación de un parche, aunque en nuestro caso no es

necesario. La mayoría de las extensiones ofrecen instrucciones

de instalación (usando comandos de Unix), en las cuales se suele

especificar si es necesaria la instalación de algún parche. Para

introducir estos comandos es necesario tener acceso a la Shell.

2.- Descargar e instalar ExtensionFunctions.php :

Algunas extensiones, especialmente las más nuevas,

necesitan este fichero de ayuda. El

fichero ExtensionFunctions contiene una serie de funciones que

permiten modularizar las extensiones separándolas del núcleo

básico de Mediawiki. La mejor forma de instalar este fichero es

descargando la última versión del repositorio. Una vez

descargado, se copia el fichero ExtensionFunctions.php en el

subdirectorio de Mediawiki $IP/extensions/.

Page 94: Cesnavarra 2008-boletín 12

Importante: Solo se debe instalar este fichero si se tiene algún

problema sin él, ya que muchas extensiones no lo necesitan.

3.- Descargar la extensión:

Las extensiones generalmente se distribuyen como

paquetes modulares y normalmente, van en el

subdirectorio $IP/extensions/. Se puede encontrar una lista de

todas las extensiones documentadas en la página de

MediaWiki.org en la sección extensión matrix, además en esta

misma página se tiene una lista de todas las extensiones

guardadas en el repositorio, desde donde se puede descargar la

última versión de ellas, el repositorio se encuentra

en svn:trunk/extensions

La versión actual de la extensión que vamos a instalar se obtiene

del repositorio de subversión oficial de Mediawiki, que se

encuentra enhttp://svn.wikimedia.org/svnroot/mediawiki/. Su

instalación se realiza mediante los siguientes comandos:

cd extensions/

svn con

http://svn.mediawiki.org/svnroot/mediawiki/trunk/extensions/Collectio

n

También se puede descargar desde:

http://www.mediawiki.org/wiki/Extension:Collection

4.- Instalar la extensión

Antes de empezar con la instalación y configuración de la

extensión se comprueba si se cumplen los prerrequisitos

necesarios para que funcione. En este caso es necesario tener

instalado PHP con soporte cURL. En este artículo no vamos a

meternos con la instalación de PHP, pero si se quiere más

información se puede consultar el manual de PHP.

También requiere tener htmldoc, gcc y gcc-c++. Primero nos

aseguramos de que esta, por ejemplo gcc-c++:

yum search gcc-cc++

Si no está instalado, se instala:

yum install gcc-cc++

Por otro lado, la generación de ficheros PDF y ZIP se hace a

Page 95: Cesnavarra 2008-boletín 12

través de un servidor que puede estar corriendo independiente

de la instalación de la Mediawiki y puede ser compartido por

varias wikis

Si se tiene poco tráfico en la Wiki se puede usar el servidor de

renderización público. Para ello, solo se debe mantener el valor

por defecto de la variable de

configuración $wgCollectionMWServeURL.

Una vez comprobado que se cumplen todos los prerrequisitos se

pasa a la instalación de la extensión propiamente dicha.

Generalmente, se añade al final del fichero LocalSettings.php la

siguiente sentencia:

require_once

"$IP/extensions/extension_name/extension_name.php";

Esta línea fuerza al interprete de PHP a leer el fichero de la

extensión, y así hacerlo accesible a Mediawiki.

En nuestro caso la sentencia quedaría:

require_once("$IP/extensions/Collection/Collection.php");

Después de esto se revisan las demás variables de configuración

del fichero. A continuación se comentan las más relevantes:

$wgCollectionMWServeURL (string)

Se le da la URL del servidor de renderización. Su valor por

defecto es "http://tools.pediapress.com/mw-serve/" que es un

servidor público para Mediawiki con poco tráfico.

Importante: Hay que tener en cuenta que la Mediawiki debe

ser accesible por el servidor, por tanto si se tiene la Mediawiki

detrás de un Firewall no se puede usar el servidor público que

se indica por defecto. En este caso lo que se hace es crear un

servidor de rederización y configurarlo. Para ello instalamos

las librerías mwlib y mwlib.rl. La mwlib es una librería hecha

en Python para parsear los artículos XML de la wiki, y la

mwlib.rl es también una librería hecha en Python que permite

escribir documentos PDF de los artículos de la wiki que han

sido parseados por la librería mwlib.

Para instalar mwlib se requiere tener instalado con

anterioridad: Python, Perl 5, setuptools, PIL (Python Image

Page 96: Cesnavarra 2008-boletín 12

Library), g++, odfpy 0.7.0.

Nos aseguramos de que tenemos todos los requisitos

instalados:

yum install g++ perl python python-dev python-setuptools

python-imaging

easy_install odfpy==0.7.0

Y después solo queda instalar mwlib:

easy_install mwlib && rehash

Para poder instalar mwlib.rl debe estar instalada ya la mwlib,

por eso se procede primero a instalar mwlib, y una vez está

instalada se pasa a realizar la instalación de mwlib.rl.

easy_install mwlib.rl

Con esto, ya estaría instalado y configurado el servidor de

renderización.

$wgCollectionFormats

En esta variable tenemos un array en el cual se mapean los

mwlib_writers con los nombres de los formatos de salida. Por

defecto solo esta habilitada la transformación a PDF:

array(

'rl' => 'PDF',

)

Por ejemplo, si se quiere añadir el paso a OpenDocument

Text, se debería añadir una línea más a la variable, quedando

de la siguiente manera:

$wgCollectionFormats = array(

'rl' => 'PDF',

'odf' => 'ODT',

);

En el servidor de renderización público tools.pediapress.com

están disponibles los siguientes writers:

- docbook: DocBook XML

Page 97: Cesnavarra 2008-boletín 12

- odf: OpenDocument Text

- rl: PDF

- xhtml: XHTML 1.0 Transitional

Si se está usando otro servidor propio, la lista de writers

disponibles se puede obtener con el siguiente comando de

mwlib:

mw-render --list-writers

Aunque se han comentado estas dos variables, el fichero

LocalSettings.php contiene otras muchas, así que para saber

más acerca de la configuración de estas variables se recomienda

leer el fichero Readme de la extensión.

Por último creamos un directorio llamado Collection en el

directorio extensions de la instalación de Mediawiki:

mkdir /opt2/mediawiki-xxx/extensions/Collection

Copiamos en el directorio Collection que acabamos de crear

estos 5 ficheros: Collection.php, Collection.body.php,

Collection.alias.php, Collection.i18n.php y Version.php.

Estos ficheros los tenemos en el paquete de la extensión que nos

hemos descargado.

También debemos dar permisos:

chown -R apache:apache /opt2/mediawiki-

xxx/extensions/Collection

Con esto ya tenemos instalada la extensión y lista para ser

usada.

Problemas que pueden surgir

Es posible que si se accede a la wiki desde una IP externa nos de

un error al redireccionar el fichero PDF. Para solucionar esto se

pone directamente en la línea de comandos la IP del servidor:

mw-serve -d -i "IP servidor"

El parámetro –d se pone para transformarlo en demonio, de esta

forma se ejecutara en un segundo plano y así poder atender las

peticiones.

Otro problema que nos podemos encontrar es que al cerrar la

ventana en la que se ven los logs nos de un error porque no

encuentra por donde sacarlos. Para solucionar esto añadimos un

Page 98: Cesnavarra 2008-boletín 12

parámetro más a la línea de comandos indicándoles la ruta del

fichero donde debe guardar estos logs:

mw-serve -d -i "IP servidor" -l /var/log/mw-serve.log

Nota: Tener en cuenta que los comandos facilitados en este

artículo son válidos para la instalación de la extensión sobre Red

Hat.

ENLACES DE INTERES:

http://www.mediawiki.org/wiki/Manual:LocalSettings.php

http://enciclopedia.us.es/index.php/MediaWiki

http://www.mediawiki.org/wiki/Manual:Extensions

http://en.wikipedia.org/wiki/Special:Version

http://www.wadooa.com/doku.php/wiki_en_las_empresas

http://www.siteground.com/mediawiki.htm

http://code.pediapress.com/wiki/wiki/mwlib-install

http://code.pediapress.com/wiki/wiki/mwlib.rl-install

http://code.pediapress.com/wiki/wiki

http://code.pediapress.com/wiki/wiki/mwlib

Categoría

s

CES OpenSouce/Java

Tema Desarrollo

Autor Elena Gadea Aransay

Mes Diciembre

Año 2008

Boletín 12