Your SlideShare is downloading. ×
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Cesnavarra 2008-boletín 12
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Cesnavarra 2008-boletín 12

1,027

Published on

Respuesta Digital

Respuesta Digital

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,027
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. 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.
  • 2. En todo esto el tema que más me interesa es el de si laprofesión informática debe estar regulada o no. En mi opiniónno es ésta una pregunta a responder de forma aislada sinoteniendo en cuenta el contexto laboral.Esto es: ¿por qué hay que regular unas profesiones y otrasno? ¿Por qué, de hecho, hay profesiones reguladas y otrasno?Un argumento suele ser el que las profesiones que estánreguladas se dedican a actividades que por su dificultad oimplicación deben tener algún tipo de control o de garantía deque quienes la realizan están capacitados para ello. Losejemplos habituales son los siguientes: los planos de unedificio deben estar firmados por un arquitecto paragarantizar su seguridad, habitabilidad, etc. Una operacióndebe ser realizada por un médico para garantizar su éxito,etc.¿Y un proyecto informático no? Muchas personas en estoscasos realizan el siguiente razonamiento: programar es fácil,luego no hace falta regular dicha actividad. Aparte de que larealización de un proyecto informático no es sólo codificar,podría decirse que sí que programar ciertas cosas, porejemplo una macro de Word (y depende cuales, os loaseguro) es fácil pero también lo es aplicar mercromina a unaherida y colocar encima de ella un apósito pero nadie llama aeso "intervención quirúrgica".Por otro lado es curioso como para realizar ciertas actividadesque no considero triviales no se necesita más que pasar unaspruebas o incluso sólo tener la intención de realizarlas: y si nopiénsese en que para opositar a plazas de policía o alistarseen las fuerzas armadas se necesita acreditar pocas aptitudes.Y no creo que estas profesiones sean menos críticas o másfáciles que desempeñar que todas las aquí descritas.Otro tema que ha salido a relucir con esta polémica es el delintrusismo, que es la otra cara de la moneda de lo antesexpuesto: puesto que no es necesario acreditarse de algunaforma para ejercitar la profesión de informático, cualquierapuede hacerlo.A este respecto voy a contar mi experiencia: cuandocoordinaba un equipo de desarrolladores, solicitamos de unaempresa de servicios un perfil de programador. Dichaempresa, que ya nos había proporcionado anteriormentepersonas que cubrieron satisfactoriamente nuestrasnecesidades no envió el currículum de su candidato. El mismoera licenciado en Farmacia y había realizado un curso devarios meses de programación en Java. Teníamos dosopciones: rechazarlo a priori o confiar en nuestro proveedor yver qué tal trabajaba esa persona. Resultó que era lo quenecesitábamos: un programador que realizaba a conciencia sutrabajo. Acertamos: no nos importó el pedigrí del candidatosino sus resultados.
  • 3. Meses más tarde mi rol cambió y era analista en un proyectointernacional con tres equipos de desarrollo situados enEspaña, Argentina y los Estados Unidos respectivamente.El project leader del mismo era un estadounidense cuyaformación era en... ¡música! El recuerdo que tengo es quesabía orquestar muy bien al equipo, combinandoidiosincrasias y manejando ritmos.En la actualidad me encuentro trabajando con colegas que ensu mayor parte son titulados en telecomunicaciones y sigoaplicando el mismo criterio: no me digas de dónde vienes sinovamos a ver cómo podemos trabajar juntos.Creo que uno de los problemas de la informática es la formaen que se percibe: algo de lo que ya hemos tratado en estosartículos.Y otro el de la ignorancia de lo que un titulado en informáticatiene que estudiar para titularse, ya sea comoingeniero técnico o superior.Podríamos hacer un pequeño test: ¿cuáles de estasasignaturas aparecen en los planes de estudios de dichascarreras?  Á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 ContableLa 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í laignorancia acerca de los conocimientos que deben adquirirsepara ser un titulado en la misma es más que notable. Y si unoignora qué conocimientos tiene su empleado, difícilmentepodrá saber utilizar todo su potencial. Por otro lado no creoque haya que blindar el terreno profesional para que sólo losque tengan carnet de socio puedan acceder al club de lainformática. Pero esto debería ser una regla general a todo elmercado laboral y no sólo a la informática: o todos o ninguno.Finalmente una pequeña autocrítica: los informáticos estamoshabituados a trabajar con máquinas que únicamente atiendena programas, que son la formalización unívoca de unos
  • 4. 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.esCategorías GeneralTema VariosAutor Carlos UrtasunMes DiciembreAño 2008Boletín 12Títu Proyecto piloto TDT: parte 4: fase 2loTex Esta segunda fase arrancó con el segundo comité. Comité en el cualto 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
  • 5. esta segunda fase. Para ello se partía del resultado del análisis deservicios a adaptar a TDT realizados durante la primera fase, quetrajeron no pocos quebraderos de cabeza y de la finalización de lapreparación formal del equipo local.Del análisis teníamos como resultado una lista de posibles servicios aimplementar en TDT, no obstante, no había identificados unas fuentesfiables de información en ninguno de ellos y tampoco había aseguradala incorporación de ningún servicio interactivo (con capacidad derealizar peticiones mediante el uso del canal de retorno) dada laimposibilidad de contar con una interacción con los sistemas deGobierno de Navarra (a través de servicios web) en la fecha presente.Dado que había muchos flecos en prácticamente todos los serviciosque se irían aclarando con el estudio concreto de cada uno y dada laexistencia de un plan de modernización paralelo que iba afectar a lossistemas de la información y por tanto, cambiar la situación actual, lalista, prioridad y posición de cada servicio dentro de la misma podíavariar. De hecho, debía irse adaptando conforme se obtuviese másinformación de los mismos a lo largo de los desarrollos de la segundafase. 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 Alta Inserción manual estática Agenda de ocio y Alta Extracción directa de BBDD cultura Farmacias de Alta Extracción directa de BBDD guardia Centros de salud Alta Extracción directa de BBDD Carreteras Alta Tempos21: analizar alternativas Empleo público Alta Tempos21: previo filtrado de la (convocatorias) información
  • 6. Vivienda Alta- A determinar Media 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ñoEsto es, se habían identificado 10 posibles servicios, de los cuales, los7 primeros eran informativos mientras que los 3 últimos podíanpresentar algo de interactividad.No obstante, existía una gran indeterminación en el posible uso deestos 3 últimos puesto que en el momento del análisis, tal y como hecomentado, no existía ningún servicio web disponible paraimplementar la interactividad en el servicio, circunstancia que podíacambiar por el plan de modernización que afectaba directamente ados de estos servicios.Entre los informativos, tras muchas averiguaciones se vio la dificultady riesgo de emplear el desarrollo de Tempos21 como fuente deinformación ya procesada con lo que se planteó buscar la fuente dedatos original. Para los dos primeros ya se tenía detectada unaalternativa útil y por tanto podían implementarse en TDT, mientrasque en los restantes se sabía de la existencia de bases de datos quealmacenaban cierta información necesaria para cada uno de losservicios pero se desconocía con certeza su naturaleza y por tanto, nose podía asegurar en todos los casos su uso. De echo, para losservicios de Carreteras y Empelo público, ni siquiera se teníaconstancia de la existencia de una base de datos, lo cual implicaría eluso de Tempos21 como fuente de información ante la inexistencia deuna alternativa.Por otro lado, el equipo local se encontraba “preparado”, habíarecibido la formación adecuada relacionada con conceptos generalesde la TDT, el estándar MHP y el uso de la herramienta de autor aemplear iDesginer. No obstante, como hemos adelantado, laformació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
  • 7. experimentación real con los trabajos a realizar, para lo cual sedefinió junto con SiTVi un planteamiento de transferencia deconocimiento: se identificaron una lista de habilidades a adquirir yunos niveles para cada una de ellas, A, B y C, siendo A el nivel másbásico y C el más avanzado. Estas habilidades o conocimiento seagruparon según su aplicación a las tareas de desarrollo, quedando elsiguiente planteamiento: Niveles A B C Toma de requisitos Ingeniería de software - Metodología de X X X desarrollo: toma de requisitos, análisis, diseño aplicación. Análisis funcional Ingeniería de software - Metodología de X X X desarrollo: toma de requisitos, análisis, diseño aplicación. 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 X X X entorno de IDesigner. Java – Desarrollo basado en Java (bajo nivel, X sin uso de IDesigner). Implementación del interfaz Desarrollo MHP – Interfaz X X X gráfico (disposición/layout de componentes) Java – Desarrollo de plugins (personalización X y creación de componentes gráficos para
  • 8. IDesigner).Java – Desarrollo basado en Java (bajo nivel, Xsin uso de IDesigner).Conocimiento del entorno - Desarrollo con el X X Xentorno de IDesignerImplementación de funcionalidadesDesarrollo MHP – Uso de formularios de entrada X X X(procesado de datos).Java – Desarrollo de plugins (personalización Xy creación de componentes gráficos paraIDesigner).Java – Desarrollo basado en Java (bajo nivel, Xsin uso de IDesigner).Conocimiento del entorno - Desarrollo con el X X Xentorno de IDesignerIntegración con servicios webDesarrollo MHP - Canal de retorno. XBackend - Interacción con servicios web: Xpost/xml, get/xml, soap.Java – Desarrollo basado en Java (bajo nivel, Xsin uso de IDesigner).Conocimiento del entorno - Desarrollo con el X Xentorno de IDesignerEjecución de pruebasConocimiento del entorno - Conocimiento de Xpuesta en producción de aplicaciones en ellaboratorio: encapsulador (iMux).Conocimiento del entorno - Realización de pruebas X X Xde aplicaciones.Backend - Parametrización de aplicaciones. XIngeniería de software - Metodología de X X Xpruebas.Puesta en emisión:Backend - Parametrización de aplicaciones. XPuesta en producción de aplicaciones: X X
  • 9. comunicación con Abertis.Dada la nula experiencia en TDT del equipo local se decidió comenzarcon un servicio sencillo de implementar en el que participasen todoslos miembros del equipo. Además, esto permitía arrancar la segundafase del proyecto con un servicio concreto y definido y así tener uncolchón suficiente para ir concretando el resto. Posteriormente, tras laexperiencia adquirida, se podían ir acometiendo más servicios enparalelo mediante la distribución del trabajo entre los miembros delequipos local. Se trabajaría con la lista identificada anterior como sifuera un “pool” de servicios, decidiendo su incorporación al desarrollosegún la información recopilada en cada caso, la viabilidad yevolución de las circunstancias:
  • 10. Por tanto, este plan nos daba 5 servicios a incorporar de aquí al finaldel proyecto, 4 informativos y un último interactivo aún pordeterminar dependiendo del plan de modernización. Se decidiócomenzar por un servicio de modo que todo el equipo pudieraparticipar e ir adaptándose al desarrollo de aplicaciones interactivascon MHP para TDT de forma paulatina. De este modo, en este primerservicio se podía hacer más hincapié en la labor de transferencia deconocimiento que posteriormente se iría diluyendo a lo largo delproyecto conforme el equipo adquiriese soltura y conocimientos yconvirtiéndose más bien en una labor de consultoría. Así pues, en losservicios posteriores, tras esta toma de contacto y adaptación, podíaconfigurarse un equipo más eficiente de modo que se dividiesen lostrabajos y se pudiesen implementar y afrontar dos servicios enparalelo cada vez. Dada la disponibilidad de 4 personas (se contabacon 3 personas en el equipo local y un becario cedido por SiTVi comorefuerzo y apoyo), se podía dividir el equipo en 2 grupos de 2personas cada uno. De modo que en los servicios informativos, unapersona del grupo pudiese dedicarse a las labores de extracción yformateo de datos y la otra persona del grupo concentrarse en eldesarrollo MHP. En el caso del servicio interactivo, no existíaextracción y formateo de datos, pero la interacción complicaba eldesarrollo MHP que podía equilibrarse con la dedicación de dospersonas en este caso. Los roles y responsabilidades de cadaparticipante así como los propios grupos irían cambiando y rotandocon cada desarrollo de modo que todos los miembros del equipo localexperimentasen con todas las partes del desarrollo. La lista deconocimientos y niveles antes citada encajaba dentro de esteplanteamiento de la siguiente manera:
  • 11. Esto es, los conocimientos de nivel A, se adquirirán con el desarrollodel primer servicio. Durante el desarrollo del siguiente servicio, seasimilarán los conocimientos de nivel B, consolidando, a su vez, losde nivel A adquiridos en el desarrollo anterior. De igual modo,durante el último servicio, se aprenderán los conocimientos de nivelC, consolidando los de nivel B adquiridos en anteriores desarrollos yasumiendo la completa responsabilidad de las tareas de nivel A.Así pues, como se ha adelantado, se determinó comenzar con unservicio, 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 todosellos, 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 realmenteidentificada la fuente de información se decidió comenzar con el.METEOROLOGÍAPara profundizar en el análisis de la fuente de información y elservicio, se organizó una reunión con el área de Meteorologíadel Departamento de Agricultura, Ganadería y Alimentación delGobierno de Navarra, responsables del desarrollo de meteorologíapara el portal web www.navarra.es.Aunque se propuso un servicio muy interesante por el cual seproporcionaba información en tiempo real de estacionesmeteorológicas, este hubiese requerido un análisis más profundo ytratándose de un desarrollo más complejo hubiese retrasado eldesarrollo, por lo que fue descartado y se continuó con los planesiniciales. Así pues, se determinó que el servicio a implantar en TDTsería el de la predicción meteorológica. En concreto, las siguientespredicciones:  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.
  • 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 InstitutoNacional de Meteorología (en adelante INM), ahora la actual AgenciaEstatal de Meteorología (AEMET). El formato de datos proporcionadopor el INM venía heredado de mucho tiempo atrás, cuando no seempleaban los caracteres particulares del español como los acentos,las eñes, etc. Esto unido al uso exclusivo de mayúsculas y a lainexistencia de traducciones a diferentes idiomas (entre ellos elEuskera) dificultaba las cosas. La aplicación a diseñar seríamultilingüe, como en todos los casos, aunque la disponibilidad de lainformación estaría sujeta a su existencia. En este caso, lainformación tan solo podía ser servida en español.NOTA: posteriormente, a finales del 2007, los responsables del portalrealizaron un filtrado de la información de modo que esta sevisualizaba en minúsculas y realizaban correcciones ortográficas paraincluir los acentos y las eñes. No obstante, esta información conteníatags html, con lo que requería un procesado previo antes de poderser incluida en TDT. Esta novedad no pudo ser incorporada finalmenteal proyecto por falta de tiempo y recursos.Toda esta información era facilitada en forma de ficheros individualespor cada una de las predicciones anteriores. Estos ficheros estabanlocalizados en un servidor de FTP al que nos dieron acceso para laconexión y descarga de la información.La visualización de esta información, interfaz, presentó algunosproblemas en TDT. En el portal www.navarra.es, la información depredicción correspondiente al día actual, el día siguiente y lospróximos días, eran visualizadas de forma conjunta. Esta informaciónconsistía en un texto y en la imagen de un mapa de navarraactualizados diariamente pero de forma independiente. La imagen delmapa se correspondía con la predicción para el día siguiente, noobstante, esta información se actualizaba en torno al medio día, conlo que en las primeras horas del día el mapa se correspondía con la
  • 13. predicción del día anterior, o visto de otra forma, la previsión del díaactual realizada el día anterior.El interfaz en TDT impedía mostrar las 3 predicciones anteriores deforma conjunta por problemas de espacio. Por esa razón seimplementaron de forma separada, lo cual, planteaba el problema dedonde ubicar el mapa de predicción común. Finalmente se decidió quela predicción del día siguiente contendría el texto y la imagen delmapa 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 formamás óptima de poder haber tenido más libertad sobre la disposiciónde componentes en el interfaz, no obstante, la herencia de losservicios en TDT anteriores marcaba una línea gráfica de la cual noera posible salir.Otro escollo asociado al interfaz en TDT resultaron ser las propiasimágenes por el origen de las mismas. Se trataba de imágenes contamaño y formato adaptado al entorno web, además de tratarse deimágenes de calidad reducida, óptima para entorno web. Estasdebieron ser escaladas para adaptare al interfaz de TDT, acentuandola mala calidad. Esto unido a la diferente visualización de los coloresen TDT dieron como resultado unas imágenes bastante pobres, noobstante, no se contaba con otra fuente de datos alternativa.A continuación se muestran unos bocetos del interfaz que indican laubicación de cada elemento gráfico:
  • 14. Es decir, y como se ha mencionado, por coherencia se mantuvo el
  • 15. 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 laspredicciones a visualizar de forma independiente a modo desecciones.El área útil mostraba la información de predicción correspondiente ala sección elegida. Para el caso de la predicción de hoy y mañana, sedesarrolló un componente que conmutaba entre la predicción de textoy la predicción con la imagen, dado que las limitaciones del interfazen TDT impedían su visualización simultánea.De igual modo, se mantuvo (como se verán en las imágenes deresultado final) el estilo heredado de las aplicaciones anteriores encuanto a uso de colores, diseño de botones, etc.En cuanto al proceso que recogía, procesaba y publicaba lainformació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
  • 16. 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
  • 17. 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óndel back office y su procesado para emisión en TDT. Debíaestablecerse un mecanismo que fuese común y reutilizable en todoslos servicios que independizasen información y presentación. Lógico,pero muy difícil. Cada servicio requería procesos de extraccióndiferentes, como posteriormente se vería, según la fuente de datos yla propia información a extraer en cada caso. No obstante la filosofíaen todos los casos fue la misma, definiendo un formato de ficheroXML particular para cada aplicación que independizaba al menos lainformació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 suactualización en emisión.En torno a esta cuestión, empezaron a tenerse las primeras reunionescon sistemas de Gobierno de Navarra para definir esta plataforma deextracción de datos y publicación en TDT, tanto a nivel hardwarecomo software. Para esto se redactaron una serie de documentossolicitados por sistemas en los cuales se trataba de definir laplataforma, pero de forma bastante abstracta puesto que no seconocían las implicaciones ni requerimientos del resto de servicios pordesarrollar. De nuevo, todo se debía ir definiendo sobre la marcha. Encualquier caso, sistemas estableció una serie de condicionantes queaplicaban tanto a nivel hardware como software que daban una ideade por donde debían ir las cosas. Se comenzó definiendo que estosprocesos podían ser aplicaciones Java que corriesen como demonios,sin necesidad de ningún framework o requisito adicional que el propioproceso, lo cual limitaba mucho las posibilidades. No obstante, comose verá más adelante, estos requerimientos y condicionantes iríancambiando a lo largo del proyecto.La dificultad para ir definiendo todo esto, hizo que la plataformaestuviese alojada de forma temporal en la infraestructuraproporcionada por los CES, hasta el momento en que fuera viable sutraspaso a sistemas de Gobierno, una vez definida por completo laplataforma y disponible una infraestructura donde alojarla. No fue,
  • 18. como se verá posteriormente, hasta el final del proyecto que pudohacerse 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 queera la parte de adquisición y formateo de los datos para construir los
  • 19. ficheros XML base que alimentarían la aplicación MHP. Tambiénexistía una gran dependencia entre la aplicación cliente MHP y elproceso de adquisición de datos debido al fichero XML que relacionabaambas aplicaciones. El diseño del interfaz marcaba la organización dela información en el XML, el cual, a su vez, incidía directamente en elproceso de adquisición de datos y obtención del XML. El publicador,por el contrario, era un proceso que podía ser desarrollado de formaindependiente.Finalmente, el equipo local estaba constituido por 3 personas (ante labaja del miembro proporcionado por SiTVi, lo cual complicaría laplanificación acordad inicialmente) para tres desarrollos: proceso deadquisición de datos, proceso de publicación y aplicación MHP. Lasresponsabilidades de cada miembro, tal y como se ha dicho, iríarotando en cada servicio para que todos los participasen en losdiferentes desarrollos y comprendiesen de esta forma el sistemaglobal.Las pruebas del sistema completo, adquisición y publicación, erancruciales. Se realizaron una serie de pruebas del sistema completo enun entorno de pre-producción habilitado en el laboratorio del CESpara asegurar el correcto flujo y procesado de la información, asícomo una prueba del sistema completo en producción, pactado conAbertis.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 yAlimentación del Gobierno de Navarra para que solicitasen cambios ydiesen su aprobación final.En dicha demostración, se detectó que se precisaba de la autorizacióndel INM para el empleo de sus datos en TDT, algo que, no obstante,no supuso ningún impedimento ni inconveniente pudiéndose resolverde forma satisfactoria a tiempo.En cualquier caso, un retraso aproximadamente de una semana enlas pruebas y la coincidencia de las fiestas de San Fermin con laemisión, pospusieron los planes, ante posibles eventualidades, hasta
  • 20. finales de julio. Un retraso pequeño pero que unido a la baja de unmiembro del equipo, iría pesando a lo largo de los siguientesdesarrollos.A continuación se muestran algunas imágenes de lo que fue e aspectofinal de la aplicación:
  • 21. Cat CES OpenSouce/JavaegoríasTe VariosmaAut Raúl Sanz de AcedoorMes DiciembreAño 2008Bol 12etínTí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
  • 22. embargo no llegamos a ver sus funcionalidades. jQuery nospermite, entre otras cosas, hacer consultas personalizadasmediante código JavaScript.Para ello es necesario descargarnos los archivos JavaScript quenos permiten personalizar la consulta y que son modificables porel desarrollador. También son necesarias las Web Parts quealojan los contenidos y los resultados de la consulta, de unamanera similar a las búsquedas de SharePoint. Todo estepaquete está disponible para los suscriptores a las noticiassemanales de EndUserSharePoint un portal de usuarios deSharePoint donde se recoge información sobre novedades,actualizaciones y recursos interesantes. Un “precio” racionable sise tiene en cuenta lo interesante de la información recibida.Una vez que tenemos la biblioteca jQuery instalada y todos losarchivos JavaScript necesarios, iremos al Sitio donde queremosemplearla y crearemos una biblioteca de documentosllamada QueryResources, que será donde alojemos todos losrecursos necesarios para la personalización.Para crear la biblioteca de documentos vamos a View All SiteContent> Create >Document Library. Una vez creada la bibliotecacargamos los archivos medianteUpload>Upload Multiple Documents.A continuación creamos una página de Web Parts (Web Part
  • 23. Page) llamada SearchQuery.aspx, que guardaremos en la mismabiblioteca en la que tenemos nuestros recursos.Una vez que hemos creado la página de Web Parts, el siguientepaso es añadir las que nos permiten el empleo de jQuery. Enmodo edición, utilizamos la opción Add Web Part y dentro de lagalería que nos aparece, seleccionamos Advanced Web PartGallery and Options que se encuentra en la parte inferior.Al seleccionar dicha opción, nos aparece un cuadro de accionesque nos permite importar las Web Parts directamente del disco
  • 24. duro. Para ello seleccionamos Browse> Import. A continuaciónexaminamos y cargamos, una a una, cada Web Part. Cuando nosaparece en la zona Uploaded Web Part, la arrastramos a la zonade nuestra página donde deseamos implementarla.En mi caso, he añadido jQuery_SearchBox-Top.dwp a lacabecera y jQuery_ContentOfPageToBeSearched-Center.dwp y jQuery_CallToScripts-Bottom.dwp al cuerpo. Y hepersonalizado el texto de prueba.De esta manera la página queda de la siguiente manera:
  • 25. Finalmente, para comprobar que todo funciona correctamente,salimos del modo edición de nuestra página. Y comenzamos aescribir en el cuadro de texto…¡¡¡ Et Voilà!! A medida que vamosescribiendo, las palabras que coinciden con la consulta se vanpintando de amarillo.Como hemos dicho al principio, está es sólo una de las múltiplesfunciones que tiene esta biblioteca. Ya que tenemos un amplioabanico de posibilidades en el que poder trabajar. A continuaciónpodemos ver algunos de los ejemplos:  Página oficial de
  • 26. 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 CES MicrosoftíasTema DesarrolloAutor Goretti Ortigosa RadaMes DiciembreAño 2008Boletín 12Tí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
  • 27. Flex Builder:http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex3emailBlazeDS (Binary distribution):http://opensource.adobe.com/wiki/display/blazeds/Release+BuildsConfiguración del entorno de desarrolloSe han instalado en la carpeta C:FlexEclipse las herramientas que se utilizarán eneste tutorial. Se instala antes eclipse, ya que la instalación de FlexBuilder pide la rutadonde está instalado eclipse. Por comodidad, colocamos el servidor Apache Tomcaten 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
  • 28. Una vez instaladas las herramientas, arrancamos eclipse. Lo primero que debemoshacer 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 TomcatCreación del proyecto de servidorLa descarga de BlazeDS consiste en una aplicación web (blazers.war), queutilizaremos como base para nuestra aplicación de servidor. Para ello, desde eclipse,vamos a File -> Import -> Web -> WAR FileElegimos el fichero blazers.war, y ponemos el nombre de proyecto que queramos,en este caso creamos un proyecto web llamado Coches.
  • 29. Figura 3. Importación del archivo WAR de BlazeDSEn la siguiente pantalla, eclipse nos pregunta si queremos crear proyectos para laslibrerías utilizadas en blazers.war. No seleccionamos ninguna, y finalizamos elproceso 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)
  • 30. Figura 4. Clases de la aplicación CochesPara poder acceder a este servicio, debemos declarar la clase en el fichero remoting-config.xml, de la siguiente forma
  • 31. Figura 5. Configuración del acceso remoto a la aplicaciónDe esta forma, ya tenemos una pequeña aplicación Java en el servidor a la quepodremos acceder desde una aplicación Flex en el cliente, a través de BlazeDS. Parapublicar la aplicación en el servidor Tomcat, vamos a la pestaña de servidores, yañadimos el proyecto Coches a las aplicaciones del servidor.Creación del proyecto clienteEn este tutorial vamos a crear dos proyectos separados, uno para el servidor y otropara el cliente. FlexBuilder nos permite crear la aplicación Java y el cliente Flex en unmismo proyecto, pero en este caso se ha optado por separarlos para ganar enclaridad.Antes de comenzar, debemos arrancar el servidor Tomcat, ya que en la creación delcliente indicaremos donde encontrar la aplicación de servidor. Vamos a File -> NewProject -> FlexBuilder -> Flex Project y creamos el proyecto CochesClient:
  • 32. Figura 6. Creación del proyecto cliente (I)En la primera pantalla, introducimos el nombre del proyecto, CochesClient, ydejamos el resto como se indica en la Figura 6. En la segunda pantalla, debemosindicar la ruta y la URL del proyecto de servidor. La instalación por defecto deTomcat en eclipse no crea las aplicaciones en la carpeta del servidor(C:FlexEclipseapache-tomcat-6.0.18), sino que las crea bajo la carpeta .metadatadel workspace. En la Figura 7 se muestra esta ruta para el entorno de trabajocreado. Para comprobar que todo está bien, tenemos un botón llamado ‘ValidateConfiguration. Una vez que todo está bien, finalizamos el asistente.
  • 33. Figura 7. Creación del proyecto cliente (II)Al crear el proyecto se genera un fichero CochesClient.mxml, donde escribiremos laparte de Flex que accederá a la aplicación. La aplicación cliente constará de unbotó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 latabla 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;
  • 34. 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:
  • 35. - 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 BlogCatego GeneralríasTema DesarrolloAutor Miguel BacaicoaMes Diciembre
  • 36. Año 2008Boletín 12Título Azure es un color… y másTexto 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
  • 37. Services (para almacenar información en la “nube” y compartirlamediante cualquiera de nuestros medios de acceso) , .NET Services(para interactuar con otras infraestructuras de trabajo o ejecutarWorkflows por ejemplo) u otra aplicación alojada en Windows Azure ala que tengamos acceso. ¡El poder de Azure!Una vez conocido lo que vamos a hacer, al tajo. El ejemplo que vamosa desarrollar consistirá en la publicación mediante Live Mesh de unaaplicación desarrollada en SilverLight (aunque podría tratarse decualquier aplicación soportada por Windows Azure). Para empezar, losrequisitos 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
  • 38. 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 losencilla que podríamos desear. En concreto, la instalación de lasSilverlight Tools puede producir un error inesperado e “inexplicado”. Eneste caso tendremos que hacer la instalación de manera manual de losdisitintos elementos del paquete. Para ello hay que lanzar la ejecucióny cuando nos muestre la pantalla de error no cerrarla. Entoncesbuscaremos el directorio temporal de instalación que se habrá creadoautomáticamente en nuestro disco duro C: (normalmente tendrá unnombre compejo, enrevesado… informático vamos) y dentro de esteestará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.mspUna vez realizada esta instalación ya estaremos en condiciones derealizar desarrollos con Visual Studio 2008 y Silverlight para WindowsAzure.En este ejemplo vamos a llevar a cabo el laboratorio para la creaciónde una aplicación Live Mesh. Si seguimos el artículo del mespasado habremos instalado en nuestro PC el Microsoft Azure ServicesKit. Dentro de este se encuentra el Laboratorio denominado“BuildingMeshEnabledWebApplications” que es el que nos interesa eneste caso. Si abrimos Visual Studio 2008 como Administradorespodremos abrir sin problemas la solución de ejemplo, “Begin.sln”,ubicada en la carpeta “Ex01-UnderstandingTheApplication”. Se trata deuna aplicación completa basada en SilverLight para la gestión decampeonatos de un deporte, donde podemos crear ligas, campos,subir fotos de los campos, usar un sencillo tablón de mensajes, ver laprevisión del tiempo, etc.
  • 39. 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 clasesnecesarias para que el anterior funcione (FieldManager.ObjectModel):
  • 40. El proyecto FieldManager.ObjectModel representa un muy buenejemplo de organización de la estructura de un proyecto, con unacarpeta 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 estaaplicación en Live Mesh, habremos de conseguir el acceso a unacuenta de Azure Services para desarrollo. Para ello, accedemos a AzureServices Developer Portal mediante laweb http://lx.azure.microsoft.com y nuestro Windows Live ID. En elcaso de que se trate de la primera vez, habremos de dar de alta lainformación precisa como cuenta de desarrollo:
  • 41. Hecho esto, pasamos a la que será la pantalla principal en nuestraspróximas visitas, desde donde gestionaremos nuestros proyectos,cuenta, etc.
  • 42. Aquí tendremos que seleccionar el enlace “New Project” (a izquierda oderecha, da igual) y pasamos a la pantalla desde la que definiremos elnuevo proyecto a crear. Como veremos existen varios tiposdisponibles, 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
  • 43. APIs” para usar APIs de los Live Services desde cualquier aplicación Web.En nuestro caso, veremos más adelante que crearemos un proyectocon el Live Framework CTP del Azure Services Platform, ya que lo quequeremos 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 yregresaremos a Visual Studio y preparamos una solución para supublicación. Para eso, cerramos la que tenemos abierta y abrimos lasolución “Begin.sln” que está localizada en la carpeta “Ex02-DeployingIntoLiveMesh” que prepararemos para publicar mediante lossiguentes pasos: 1. Añadimos al proyecto WLQuickApps.FieldManager.Silverlight tres
  • 44. referencias (botón derecho sobre el nodo “References”, opción “Add Reference…”) a los ensamblados de Live Framework que encontraremos en “[LiveFxSDK]LibrariesSilverlight”: - Microsoft.LiveFX.Client.dll - Microsoft.LiveFX.ResourceModel.dll - Microsoft.Web.dll2. 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) {
  • 45. 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”.
  • 46. Seleccionamos esta plantilla y le damos el nombre“FieldManagerMeshApp”. Esto nos crear dos proyectos más ennuestra solución, uno de los cuales hemos de borrar ya que nonos hace falta. Se trata de “FieldManagerMeshAppSiverlight”que es el esqueleto de proyecto que podríamos usar en caso deque tuviéramos que crear una aplicación SilverLight desde cero,que en nuestro caso está ya creada. Pincharemos con el botónderecho 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 anuestro proyecto “WLQuickApps.FieldManager.Silverlight”
  • 47. Quitar Añadir4. 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" />
  • 48. <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.
  • 49. 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.
  • 50. Esto nos pasa a otra pantalla donde introduciremos los datos dela aplicación: su etiqueta y descripción. Aceptado esto,tendremos la opción de elegir el tipo de aplicación, que en estecaso se trata de una Mesh-enabled Web application.Seleecionaremos esta y pulsamos Create:Tras esto habremos por fin creado nuestra aplicación Mesh (sincontenido todavía, aún hemos de subirla) y se nos mostrará lapantalla de propiedades de la misma:
  • 51. Volvemos a Visual Studio y pulsamos el enlace “Copy full path ofFieldManagerMeshApp.zip to clipboard” en la ventana dediálogo que teníamos abierta. Cambiamos de nuevo alnavegador, a Azure Services Developer Portal, y pulsamos elbotón “Upload Package”.
  • 52. Pulsamos entonces el botón “Browse” para abrir la ventanda deselección del paquete, pulsamos Ctrl+V para pegar el caminodel mismo y a continuación pulsamos Deploy, con lo que seinicia la copia del paquete a Windows Azure.Una vez completado, copiamos el “Application Self Link” que senos devuelveY de vuelta en Visual Studio lo introducimos en el 3er paso de laventana que tenemos activa:
  • 53. Con esta información completa, una vez que pulsemos Ok seproduce la actualización final de la aplicación en Windows Live ypodremos ejecutarla (estos últimos pasos se simplifican en elcaso de que estemos actualizando una aplicación que ya existacomo Live Mesh application; en este ejemplo es más complejoya que hemos realizado a la vez la creación y definición de unaaplicación Live Mesh y la compilación y subida de una nuevaversión de la misma).Para su ejecución, el mismo Visual Studio abrirá el Live Desktoppor nosotros. En caso de no ser así podemos acceder mediantela webhttps://www.mesh.com/Welcome/Default.aspx
  • 54. 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 LiveCateg CES MicrosoftoríasTema DesarrolloAutor Rafael FloresMes DiciembreAño 2008Boletí 12n
  • 55. Título Creación de un Gadget basado en una animación XAMLTexto 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 " />
  • 56. <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,00,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,01,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="images1.jpg" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 11" AlignmentX="Left" AlignmentY="Top"Opacity="1.000000" /><!—Dibujauna imagen a traves de un pincel definido --> </DiffuseMaterial.Brush> </DiffuseMaterial> <SpecularMaterial SpecularPower="85.3333"><!—cantidad de luz queincide 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="images2.jpg" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 11" 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>
  • 57. <ImageBrush Stretch="UniformToFill" ImageSource="images3.jpg" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 11" 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="images4.jpg" TileMode="None" ViewportUnits="Absolute" Viewport="0 0 11" 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="images5.jpg" ViewportUnits="Absolute" Viewport="0 0 11" 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="images6.jpg" ViewportUnits="Absolute" Viewport="0 0 11" 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>
  • 58. <!—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="{StaticResourceCubeSide01}" Material="{StaticResource BranchesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide02}" Material="{StaticResource FlowersMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide03}" Material="{StaticResource BerriesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide04}" Material="{StaticResource LeavesMaterial1}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide05}" Material="{StaticResource RocksMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide06}" Material="{StaticResource SunsetMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> </ModelVisual3D.Children> </ModelVisual3D> </Page.Resources>
  • 59. <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 elcubo --> </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="{StaticResourceCubeSide01}" Material="{StaticResource BranchesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <!—material 3D que carga para cada cara del cubo --> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide02}" Material="{StaticResource FlowersMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide03}" Material="{StaticResource BerriesMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide04}" Material="{StaticResource LeavesMaterial1}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResourceCubeSide05}" Material="{StaticResource RocksMaterial}"/> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D> <ModelVisual3D.Content> <GeometryModel3D Geometry="{StaticResource
  • 60. 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" Angle="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 quecontiene todos los Gadgets de la Sidebar. La ruta habitualdonde la encontramos es lasiguiente C:UsersusuarioAppDataLocalMicrosoftWindows SidebarGadgets Dentro de dicha carpeta deberemosde crear una con el siguiente formato: “NombreGadget.gadget” en nuestro caso CUBO3D.gadget. En el
  • 61. interior de esta carpeta colocaremos nuestro archivo XAML, ytambién hemos de crear los archivos XML y HTML que definenlas propiedades y el objeto del Gadget (en nuestro caso laanimación XAML), pero vamos por partes.El siguiente paso es crear el archivo XML, que debe tener lasiguiente 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 nombrede nuestro Gadget, en nuestro caso “CUBO3D”<namespace></namespace>: Esta etiqueta define elgrupo al que asociaremos nuestros Gadgets con lo quepodremos gestionarlos de manera agrupada. Es una etiquetainformativa y en nuestro caso lo haremos por ejemplomediante la agrupación “Cesnavarra”<version></version>: La siguiente etiqueta nos indicara laversió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 dereferencia de nuestro Gadget.<copyright></copyright>: Esta etiqueta indica losderechos reservados de autor de nuestro Gadget.<description></description>: La siguiente Etiqueta nosayudara a presentar información descriptiva sobre nuestroGadget.La parte contenida en las etiquetas <hosts></hosts> no lavamos a modificar ya que está predeterminada para elWindows SideBar. Lo único que puede interesarnos modificar
  • 62. va a ser el origen donde obtendremos el contenido de nuestroGadget, que se obtiene a través de una página HTML. Elnombre de este origen puede ser diferente al nombre delGadget. Ej. scr="default.html".El archivo XML lo deberemos de nombrar Gadget.xml, ya queesta es la manera que la Sidebar reconoce nuestro Gadget.El penúltimo paso será crear nuestra página web depresentació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 lomás importante la definición de la carga de nuestra animaciónmediante un iframe.Por último una vez creados todos los elementosprocederemos a incluir nuestro Gadget en la Sidebar deWindows Vista de la siguiente manera:En la Sidebar en la parte superior presionaremos la tecla máslo que nos presentara todos los Gadget que tenemosinstalados en nuestro sistema, entre ellos nuestro CUBO3D.Realizaremos doble click sobre este Gadget y aparecerá ennuestra Sidebar.
  • 63. Categ CES MicrosoftoríasTema DesarrolloAutor Raúl Mayo GonzálezMes DiciembreAño 2008Boletí 12nTí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
  • 64. nos vamos a centrar en las herramientas que distribuye el propio SVN.El SVN tiene un funcionamiento transaccional. Deberíamos tener en cuentaque mientras se hacen las copias se pueden estar haciendo modificacionesen los ficheros bajo el control de SVN y que por lo tanto tendremos nuevasrevisiones. El árbol de directorios y ficheros está fuertemente relacionado através revisiones y Vds, etc. para dar consistencia a SVN. En una palabra: esun sistema complejo.Digamos que debido a esto y a toda esas psicosis que rodean las gestiones decopias de seguridad nos vamos a centrar en los propios comandos del SVN.Éstos nos dan un conocimiento más fino de las modificaciones existentes enel repositorio y además están pensados para garantizar las interrelaciones yconsistencia entre ficheros revisiones directorios etc. del entramado SVN.Subversión permite hacer copias de seguridad con las siguientesherramientas:svnadmin hotcopy: permite hacer copias completas del repositorio encaliente. En realidad es tan trivial como hacer una llamada al cp/copy delsistema 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 exportacionesparciales hasta una revisión concreta o un rango de revisiones. Con elmodifica “–incremental” se pueden hacer ficheros de parciales incrementalessin incluir las revisiones anteriores a la especificadas.tools/backup/ hot-backup.py: esta herramienta se distribuye y se localiza enel directorio “tools/backup”. Si no podríamos localizarlo en la siguientedirección, http://svn.collab.net/repos/svn/trunk/tools/backup/hot-backup.py.inHot-backup es un script que nos va a permitir hacer copias calientes derepositorios de SVN. Automáticamente gestiona los nombres de los ficherosde backup por cada repositorio cuando tienes múltiples repositorios y sepreocupará de evitar las colisiones con los backups previos. Los backupsantiguos los calificará de “rótate off” borrándolos y conservando solo lasversiones de copia más recientes. Podría ser interesante estudiar un modode realizar copias incrementales con la herramienta.Bien, ya hemos visto que SVN se preocupa por la coherencia de susrepositorios y por eso dispone de 3 herramientas de volcado de datos. Tantohotcopy como hot-backup.py son muy fáciles de usar para realizar copias deseguridad completas, sobre todo hot-backup.py que además ofrece un nivelmás fino de generación y automatización de copias.Sin embargo nosotros nos vamos a basar en el svnadmin dump. El método
  • 65. puede ser más elaborado pero nos va a permitir hacer backups máspersonalizados y afinados, como por ejemplo backups incrementales. Sobreesto último ni que decir tiene que un backup completo es el backup másseguro y coherente que se puede realizar. Sin embargo cuando nuestrosrepositorios empiezan a crecer en cuestión de tamaño, podemos tener otrosproblemas como la cantidad de tiempo en la generación de las copias o eltamaño de los ficheros a distribuir a través de nuestros sistemas hasta llegaral sistema de archivados de copias, trafico de red, etc.Las copias incrementales nos van a permitir aligerar las cargas de tráfico yvolumen 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 unosmodificadores en particular:Svnlook: interesante herramienta que distribuye el subversion. Estaherramienta con sus distintos comandos y modificadores tiene comoobjetivo mostrarnos información del repositorio. Tiene muchas opcionespero 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/PruebaRepo01Kikorro2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)57¡¡¡ Esto martxaaaaaaaa : P !!! …… ¡¡¡ FIESTAAAAAAA !!!Podemos observar por filas:Nombre del usuario SVN: KikorroFecha de la modificación : 2002-11-04 09:29:13 -0600 (Mon, 04 Nov 2002)Número de caracteres del mensaje de modificación :27Mensaje sobre la modificación : ¡¡¡ Esto martxaaaaaaaa : P !!!!#svnlook info –r 19 /opt/Repositorios/PruebaRepo01Kikorro
  • 66. 2002-11-05 09:29:13 -0600 (Mon, 04 Nov 2002)141..2..3...14!Vemos que la salida es igual que en el ejemplo anterior, pero esta vez nosesta mostrando un resumen de la información de la revisión 19 (tambiénpodemos observar que al usuario Kikorro se le va mucho la “olla” y quecuenta tan mal como “Bono”)Dejando a un lado las bromas, estas instrucciones las vamos a usar paracomprobar que tanto el repositorio como la revisión existen. En caso de queel repositorio o la revisión fuesen incorrectos se nos mostrarían sendosmensajes 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 ultimarevisión del repositorio indicado. Por ejemplo :#svnlook youngest /opt1/Repositorios/PruebaRepo0119Svnadmin dump/load: hay que decir que estas opciones están orientadas ala exportación y migración de repositorios pero perfectamente nos sirvenpara hacer copias de seguridad.La opción “dump” a secas nos generará un volcado binario del repositorioespecificado. Se pueden especificar volcados hasta una revisión, hasta unrango 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.dumpVamos a tratar de explicar la diferencia entre la fila 3 y la 4: SVN tiene elsiguiente comportamiento por defecto para la opción “dump”. Cada revisiónvolcada debe poder ser restaurada por sí misma. Si es una revisión nueva nohay ningún problema pero si la revisión esta basada en otras anteriores,entonces en el fichero “dump” deben de existir las revisiones necesariasanteriores para poder restaurarse las revisiones especificadas en el rango.Como mínimo va a existir un volcado completo de la primera revisión del
  • 67. repositorio.Especificando el modificador “–-incremental” se cambia el comportamientopor defecto de SVN. Evitaremos un volcado completo de la primera revisióndel repositorio pero debemos ser muy cuidadosos con los “dump” parcialesya sean completos o incrementales si luego queremos restauracionescoherentes.Muy bien: hasta aquí sabemos que podemos hacer copias completas denuestros repositorios preferidos y que incluso podríamos diseñar una políticade copias incrementales por si nuestros repositorios son muy grandes oqueremos aligerar la carga de red. Ahora lo que debemos saber es cómorestaurar estas copias que nos hemos feriado.La opción “load” del comando svnadmin es la que andábamos buscando. Unejemplo 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 anteriormentesobre la restauración coherente de la revisiones: si una revisión se basa enuna anterior, ésta ha de existir, así que siempre ha de haber una copiacompleta desde de la que deben ir partiendo las copias incrementales y porlo tanto la restauración de dichas copias deberá seguir un orden lógico conrespecto 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 > dumpfile3Secuencia de loads.#svnadmin load /opt1/Repositorios/PruebaRepo01 <dumpfile1#svnadmin load /opt1/Repositorios/PruebaRepo01 <dumpfile2#svnadmin load /opt1/Repositorios/PruebaRepo01 <dumpfile3
  • 68. En el ejemplo anterior la primera instrucción equivale a una copia completahasta la revisión 10. También podríamos haberlo indicado de la siguientemanera:#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 elload?? ….. ¡¡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 unrepositorio: 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/PruebaRepo01Si el repositorio está corrupto yo recomendaría eliminar el repositorio enteroy recrearlo desde nuestras propias copias. Como os dije en el primer párrafola creación y despliegue de un controlador de versiones SVN está detalladoen artículos anteriores así que ante la duda os emplazo a que les volváis aechar un vistazo.¡¡¡CONCLUSIONESSSS!!!.Svnlook nos da mucha información del repositorio SVN, pero nos va permitirverificar que existe un repositorio o determinada revisión. Además podemossaber a que revisión corresponde la última modificación registrada en SVN.Svnadmin dump/load nos permite hacer y recargar volcados a fichero denuestros repositorios SVN, además con control por revisiones, de formaincremental, etc.Vemos que tenemos un control muy fino de lo que queremos hacer. Sinembargo se me antoja un poco complicado automatizar todo esto.Vale, no os preocupéis le doy unas vueltas a todo esto: repasamos un pocode shell script y nos montamos un “pseudo script” que haga uso de estos
  • 69. 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.htmlCategorías CES OpenSouce/JavaTema VariosAutor Kike Muro ArbizuMes DiciembreAño 2008Boletín 12Título OntologíasTexto 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.
  • 70.  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 instanciasindividuales de esas clases introduciendo en propiedades específicas informaciónde valor y restricciones adicionales de esas propiedades.Como ayuda a la hora de crear ontologías uno debe recordar las siguientesreglas, 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 sobrecómo de general o detallada va a ser la ontología y para qué se va a usar. Lo quesiempre se debe recordar durante este proceso es que una ontología es unmodelo de la realidad y que los conceptos en la ontología, deben reflejar esarealidad. Así nunca se podría tener un concepto que fuera ent, elfo o hobbit a noser que se estuviera reflejando la realidad del mundo del Señor de losAnillos. 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?
  • 71.  ¿Quién usará y mantendrá la ontología?  …En este caso se creará una ontología sobre personajes del Señor de los Anillosque se usará como ejemplo y ofrecerá relaciones entre ellos.Paso 2. Considere reutilizar ontologías existentesSiempre suele ser conveniente pensar en lo que han hecho otras personas ycomprobar si se puede reutilizar extendiendo las fuentes y refinándolas para quese adecuen a la tarea. Por ejemplo, utilizar ontologías como la Dublin core quepuede servir para clasificar información de películas, libros, etc., o lafoaf (Friendof 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 definidosdentro de la ontología foaf, se tendría que declarar así:<rdf:RDFxmlns="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 ocualquier otro de ellos y se le daría el valor, al igual que se utiliza owl:Class paradefinir 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 denombres en el cuál todos son únicos. Las dos primeras líneas de esa declaraciónindican el espacio de nombres asociado a esa ontología. La primera lo declaracomo el espacio de nombres por defecto, diciendo que los nombres cualificadosque no tengan ningún prefijo se refieren a la ontología actual. La segundaidentifica la URI base del documento. El resto de declaraciones indica queaquellos nombres cualificados que empiecen por rdfs:, owl:, rdf: o fofa: sereferirán a conceptos definidos en esas ontologías.Paso 3. Enumere los términos importantes en la ontologíaEs útil escribir una lista de términos que se quieren explicar al usuario o de losque se quieren hacer afirmaciones.
  • 72. 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 clasesHay 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 lasespecializaciones de orco, elfo, hobbit, ent, etc.Paso 5. Defina las propiedades de las clasesUna vez que se tienen definidas algunas de las clases, se debe describir laestructura interna de los conceptos.En general, hay varios tipos de propiedades de objeto que pueden convertirse enpropiedades 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 propiedadeslleva, es_amigo_de, …Paso 6. Defina los valores que pueden tomar las propiedades de las clasesLas propiedades pueden tener diferentes facetas describiendo el tipo de valor,valores permitidos, el número de valores (cardinalidad), y otras características delos valores que pueden tomar. Por ejemplo, el valor de una propiedad denombre (como por ejemplo “el nombre de un vino”) es una cadena decaracteres.Tipos de valoresEntre 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
  • 73. 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 propiedadLas clases permitidas de tipo instancia son llamadas Rango de unapropiedad. Las clases a las que la propiedad está unida o las clases que lapropiedad describe se llaman dominio de la propiedad.Paso 7. Cree instancias de las clasesEl último paso es crear instancias individuales de las clases en la jerarquía. Ladefinició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 propuestotomando como base el mundo del Señor de los Anillos. No hay relacionescomplicadas ni tampoco se expresa toda la potencia que las ontologías puedentener, pero a modo de ejemplo sirve. Esto viene escrito en notación XML, sedebería guardar en un archivo .owl para que fuera reconocible. Llamaremos aesta ontología LordOfTheRings.owl y se podría acceder a ella enhttp://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
  • 74. s.owl#" xml:base="http://www.servidor.de.ejemplo.es/LordOfTheRings.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 personajesdel Señor de los Anillos. </rdfs:comment> </owl:Ontology> <-- //////////// // Clases // //////////// --><!-- A continuación se pasa a definir las clases de laontología --><!-- La declaración de una clase se hace mediante lasentencia --><!-- 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 cosaque las clases de la ontología no dependan de la propia clase owl:Thing sino deuna 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 cosasinanimadas. </rdfs:comment> <rdfs:subClassOf> <owl:Class rdf:about="#Cosa"/> </rdfs:subClassOf> </owl:Class><!-- Con rdfs:subClassOf, lo que se hace es definir unajerarquía --><!-- de clases, después en el siguiente tag se dirá de queclase --><!-- hereda, en este caso es de la clase Objeto --> <owl:Class rdf:about="#Anillo"> <rdfs:label>Anillo</rdfs:label> <rdfs:subClassOf>
  • 75. <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 cosasanimadas, 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>
  • 76. <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 sery --><!-- 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 puedentener --><!-- 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 siA 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"/>
  • 77. </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 soninversas --><!-- es decir, si A lleva a B, es porque B es llevado porA --> <owl:inverseOf> <owl:ObjectPropertyrdf: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 lasclases --> <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
  • 78. --> </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 sonla 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 relacionesentre --><!-- clases. En owl, todas las clases están solapadassalvo 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>
  • 79. <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>
  • 80. <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>
  • 81. <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/ontology1 01/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
  • 82.  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.ht m  http://www.informandote.com/jornadasIngWEB/articulos/j iw02.pdf  http://www.w3.org/2001/sw/  http://www.w3.org/2008/Talks/1009-bratt-W3C- SemTech/Overview.html  http://swoogle.umbc.edu/Categor CES OpenSouce/JavaíasTema VariosAutor Blanca Cubas CruzMes DiciembreAño 2008Boletín 12Título Automatización copias subversiónTexto 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
  • 83. propio Subversión(SVN), podíamos realizar copias de seguridad con cierto gradode control y nivel de personalización; Podíamos hacer copias completas, copiasde una revisión en concreto, copias de rangos de revisiones, copias incrementalesetc.Concluimos que ese nivel de control y personalización añadía también ciertacomplejidad 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 seudoscript que aunase la combinación de comandos de SVN y de esta manera, dichoscript pudiese programarse en el cron.Vale, pues ha llegado el día de ser consecuente con las promesas hechas, (“ Aleaiacta est”).Para ir empezando, vamos a ir planteando una posible solución.Humm .. ¿Que queremos? ¡¡Ya esta!!, queremos una copia completa de losrepositorios 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 dealguna manera la ultima revisión incluida en cada copia ya seancompletas o parciales; me tengo que plantear algún criterio paranombrar los ficheros de las copias y que reflejen ciertasecuencialidad,por ejemplo; file01, file02, file03, file14 … ¿otra vez?, en fin.Después debería de borrar todos los ficheros para poder volver acomenzar el ciclo…Vale, creo que ya tenemos un plan y suficientes dudas paracomenzar a decidir cosas.Como nombre de ficheros, os propongo lo siguiente.#echo$FECHA‖_‖$HOSTNAME‖_‖$REPOSITORIO‖_‖$TYPOBACKUP‖.dump$R1:$R220090108_KIRNIS_PruebaRepo01_full.dump0:10#
  • 84. Donde  FECHA=` date +%Y%m%d`  HOSTNAME, es una variable de entorno shell.  REPOSITORIO=”PruebaRepo01”  TYPOBACKUP=”full”  R1=0  R2=10En el nombre, le estamos indicando la fecha en que se realizo, elhost 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:1920090107_KIRNIS_PruebaRepo01_inc.dump11:1620090105_KIRNIS_PruebaRepo01_full.dump0:10## FILE_BACKUPS=(`ls -tc *PruebaRepo01*`)# echo ${FILE_BACKUPS[*]}20090108_KIRNIS_PruebaRepo01_inc.dump17:1920090107_KIRNIS_PruebaRepo01_inc.dump11:1620090105_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 losficheros de backups, con el primer listado os quería mostrar que podemosobtener la lista de ficheros del repositorio que nos interesa ordenados por lafecha de creación mas actual; En la siguiente instrucción, “FILE_BACKUPS=(`ls -tc*PruebaRepo01*`)”, estoy guardando la lista por columnas y ordenada por fechade 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 ennuestro 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 sunombre tenemos las revisiones que incluye. En este ejemplo, el fichero debackup, corresponde al repositorio “PruebaRepo01”, es una copia incremental yabarca desde la revisión 17 a la 19.Si tuviéramos que hacer una nueva copia incremental, obtendríamos la últimarevisión incluida en el fichero de backup más actual y luego preguntaríamos alrepositorio cual es la última revisión.#REPOSITORIES_DIR=‖/opt1/Repositories‖#REPOSITORY=‖PruebaRepo01‖#FILE_BACKUPS=(`ls -tc *$REPOSITORY*`)#FILE_BACKUP=‖${FILE_BACKUPS[0]}‖
  • 85. #echo ${FILE_BACKUP#*‖:‖}19#R1=`${FILE_BACKUP#*‖:‖}#R1=` exp. $R1 + 1 `#echo $R120#svnlook youngest $REPOSITORIES_DIR‖/‖$REPOSITORY23#R2=` svnlook youngest $REPOSITORIES_DIR‖/‖$REPOSITORY`#echo $R223#FECHA=`date +%Y%m%d`#TYPEBACKUP=‖inc‖#NEW_BACKUP_FILE=$FECHA‖_‖$HOSTNAME‖_‖$REPOSITORY‖_‖$TYPEBACKUP‖.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:2320090108_KIRNIS_PruebaRepo01_inc.dump17:1920090107_KIRNIS_PruebaRepo01_inc.dump11:1620090105_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 elsímbolo “:”, que en este caso corresponde al valor numérico que representa a laultima revisión incluida en el fichero de backup correspondiente a ese nombre defichero, en este caso, si el nombre del fichero es20090108_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 laultima revisión en 1 para que el la nueva copia incremental incluya soloexclusivamente las nuevas revisiones.Vale, esta es la secuencia de comandos para generar el nuevo fichero de backupincremental en una Shell; esto es lo que deberíamos basar nuestro script a partirde 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 lasvariables 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,
  • 86. directorios, repositorios etc.La siguiente zona corresponde a la zona donde definimos las funciones del queusamos 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 vahaciendo llamadas a doDump en función de si el tipo de copia pasado comoparámetro al script es de tipo completo o incremental.Al final también hacemos una especie de control de errores consideramos que siaunque solo una sola copia parcial de uno de los repositorios ha sido errónea lasalida 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 estescript.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 backupBACKUP_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"/"
  • 87. ## Funciones## getParametros; recogemos los parámetros que se pasan comogetParametros() { 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 escorrecto.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 enel nombre del fichero de backup.getUltimaRevisionBackup() { ## recogemos los parametros de entrada de las funciones. FILENAME=$1 Shift REPOSITORIO=$1 SEPARADORREVISION=‖:‖ REVISION=${FILENAME#*$SEPARADORREVISION}
  • 88. 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 delrepositorio, o hay algo incorrecto o no ha habido revisionesnuevas.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 lasrevisiones. $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
  • 89. }## 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 elnumero de revisiones.## 4 En función del tipo de backup full/inc se llama al métodoDoDump especificando la revisión inicial o no.## 5 control de la salida de ejecución de las instrucciones.getParametros $*cd $BACKUP_DIRERROR=0for REPOSITORY in ${REPOSITORIO_LIST[*]}do FILENAME_BACKUP=$BACKUP_DIR‖/‖$FECHA‖_‖$HOSTNAME‖_‖$REPOSITORY‖_‖$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 fidoneif [ $ERROR = 1 ]then exit 1fiexit 0Para finalizar; Esto es un “pseudo” script, lo que quiero decir esque debéis tomarlo como un script de referencia, no me puedoasegurar que lo copiéis tal cual, lo ejecutéis y no os de errores;
  • 90. 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 CES OpenSouce/JavaíasTema VariosAutor Kike Muro ArbizuMes DiciembreAño 2008
  • 91. Boletín 12Título Collection: Extensión para MediawikiTexto 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
  • 92. pueden chequear que extensiones están activas en una instanciade Mediawiki.Instalando una extensiónMediawiki esta lista para aceptar extensiones nada más terminarde instalarla.En este caso vamos a ver el proceso de instalación de laextensión Collection sobre Red Hat. Esta extensión nos permiteorganizar una selección de páginas en una colección. Con estaextensión también se puede:  editar y estructurar mediante capítulos  exportar como documento PDF  exportar como documento de texto ODF  exportar como DocBook XMLLa extensión Collection ha sido desarrollada bajo la GNU GeneralPublic License por PediaPress GMBH, en colaboración conWikimedia Foundation y la Commonwealth of Learning. Estaextensión se ha testeado con Mediawiki 1.11 y posteriores, conlo que no se asegura que vaya a funcionar para versionesanteriores.Para añadir una extensión se deben seguir los siguientes pasos: 1.- Antes de empezar: Algunas extensiones de Mediawiki requieren lainstalación de un parche, aunque en nuestro caso no esnecesario. La mayoría de las extensiones ofrecen instruccionesde instalación (usando comandos de Unix), en las cuales se sueleespecificar si es necesaria la instalación de algún parche. Paraintroducir 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. Elfichero ExtensionFunctions contiene una serie de funciones quepermiten modularizar las extensiones separándolas del núcleobásico de Mediawiki. La mejor forma de instalar este fichero esdescargando la última versión del repositorio. Una vezdescargado, se copia el fichero ExtensionFunctions.php en elsubdirectorio de Mediawiki $IP/extensions/.
  • 93. Importante: Solo se debe instalar este fichero si se tiene algúnproblema sin él, ya que muchas extensiones no lo necesitan. 3.- Descargar la extensión: Las extensiones generalmente se distribuyen comopaquetes modulares y normalmente, van en elsubdirectorio $IP/extensions/. Se puede encontrar una lista detodas las extensiones documentadas en la página deMediaWiki.org en la sección extensión matrix, además en estamisma página se tiene una lista de todas las extensionesguardadas en el repositorio, desde donde se puede descargar laúltima versión de ellas, el repositorio se encuentraen svn:trunk/extensionsLa versión actual de la extensión que vamos a instalar se obtienedel repositorio de subversión oficial de Mediawiki, que seencuentra enhttp://svn.wikimedia.org/svnroot/mediawiki/. Suinstalación se realiza mediante los siguientes comandos:cd extensions/svn conhttp://svn.mediawiki.org/svnroot/mediawiki/trunk/extensions/CollectionTambié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 laextensión se comprueba si se cumplen los prerrequisitosnecesarios para que funcione. En este caso es necesario tenerinstalado PHP con soporte cURL. En este artículo no vamos ameternos con la instalación de PHP, pero si se quiere másinformación se puede consultar el manual de PHP.También requiere tener htmldoc, gcc y gcc-c++. Primero nosaseguramos 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
  • 94. través de un servidor que puede estar corriendo independientede la instalación de la Mediawiki y puede ser compartido porvarias wikisSi se tiene poco tráfico en la Wiki se puede usar el servidor derenderización público. Para ello, solo se debe mantener el valorpor defecto de la variable deconfiguración $wgCollectionMWServeURL.Una vez comprobado que se cumplen todos los prerrequisitos sepasa a la instalación de la extensión propiamente dicha.Generalmente, se añade al final del fichero LocalSettings.php lasiguiente sentencia:require_once"$IP/extensions/extension_name/extension_name.php";Esta línea fuerza al interprete de PHP a leer el fichero de laextensió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óndel 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
  • 95. Library), g++, odfpy 0.7.0. Nos aseguramos de que tenemos todos los requisitos instalados:yum install g++ perl python python-dev python-setuptoolspython-imagingeasy_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
  • 96. - 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-writersAunque se han comentado estas dos variables, el ficheroLocalSettings.php contiene otras muchas, así que para sabermás acerca de la configuración de estas variables se recomiendaleer el fichero Readme de la extensión.Por último creamos un directorio llamado Collection en eldirectorio extensions de la instalación de Mediawiki:mkdir /opt2/mediawiki-xxx/extensions/CollectionCopiamos en el directorio Collection que acabamos de crearestos 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 noshemos descargado.También debemos dar permisos:chown -R apache:apache /opt2/mediawiki-xxx/extensions/CollectionCon esto ya tenemos instalada la extensión y lista para serusada.Problemas que pueden surgirEs posible que si se accede a la wiki desde una IP externa nos deun error al redireccionar el fichero PDF. Para solucionar esto sepone 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 estaforma se ejecutara en un segundo plano y así poder atender laspeticiones.Otro problema que nos podemos encontrar es que al cerrar laventana en la que se ven los logs nos de un error porque noencuentra por donde sacarlos. Para solucionar esto añadimos un
  • 97. 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/mwlibCategoría CES OpenSouce/JavasTema DesarrolloAutor Elena Gadea AransayMes DiciembreAño 2008Boletín 12

×