Importar datos a SQL Server directamente desde Excel

Otro de esos pequeños problemas cotidianos que pueden acabar por convertirse en una tarea pesada. Siempre que tengo que importar datos de una hoja Excel acabo dando mil vueltas exportando a csv por aquí, importando por allá, etc. cuando en realidad es extremadamente sencillo, copiar y pegar.

En el Excel, seleccionamos las celdas a copiar y… las copiamos :), Ctrl+C o click en el botón derecho y copiar.

En el cliente de Microsoft SQL Server, abrimos la tabla donde queremos importar los datos y seleccionamos todo haciendo click en la celda superior izquierda, la primera de todas.

Ahora simplemente debemos pegar las celdas que habíamos copiado anteriormente, (Ctrl+V o botón derecho y pegar). Ya está! Así de sencillo. Anda que no le he dado vueltas yo a estas cosas…

Debes prestar atención, eso sí, a las características de cada campo (autonuméricos, campos null, etc…).

Renombrar fotografías en orden cronológico de captura usando la información EXIF

Como sabéis, suelo hacer muchas, muchísimas fotos mensualmente. Además las suelo hacer con distintas cámaras, con lo que al sacarlas de las tarjetas de memoria y meterlas en la misma carpeta no quedan ordenadas cronológicamente. Muchas veces he tenido que pasarme horas renombrándolas para tenerlas bien ordenaditas, sobre todo cuando quiero hacer un libro de fotos.

Hoy estaba decidido a crearme un script propio en PHP usando la librería EXIF que leyese esta información y renombrase las fotos en base a ella cuando me he encontrado con Jhead, un pequeño programilla disponible para Linux, Windows y OSX que lo hace directamente y además tiene multitud de opciones.

Simplemente debes descargar el ejecutable y copiarlo en alguna ruta accesible (/usr/local/bin, c:windows…) y listo para utilizar.

Desde la línea de comandos, nos vamos a la carpeta donde tenemos las fotos mezcladas y ejecutamos:

jhead -n%Y-%m-%d_%H-%M-%S *.jpg

Eso es todo, automáticamente nuestras fotos quedarán ordenadas por nombre, algo como:

  • 2010-01-04_12-05-12.jpg
  • 2010-01-04_12-05-20.jpg
  • 2010-02-01_19-10-02-jpg
  • ….

Es decir: YYYY-MM-DD_HH-MM-SS.jpg.

Un trabajo menos :P.

Reempaquetar el rpm de Portsentry para que loguee en su propio archivo

Desde hace mucho tiempo utilizo como media preventiva de seguridad el paquete Portsentry en los servidores para detectar potenciales accesos maliciosos y bloquearlos directamente en el firewall. El problema es que por defecto Portsentry deja sus logs en el archivo principal del sistema, /var/log/messages, lo que genera tal cantidad de ruido que es imposible encontrar algo útil en el log. El archivo donde loguea Portsentry no es configurable sino que viene predefinido en tiempo de compilación, con lo que deberemos recompilarlo si queremos que sea otro. Podríamos compilar e instalar el fuente directamente, pero no quiero perder las ventajas que ofrece rpm, veamos como hacerlo para Centos5.5 (o RHEL5.5).

Lo primero que debemos hacer es descargar e instalar el rpm con los fuentes desde aquí.

#rpm -ivh portsentry-1.2-1.te.src.rpm

Ahora debemos modificar el archivo donde se configura dónde logueará:

#cd /usr/src/redhat/SOURCES
#tar xvfz portsentry-1.2.tar.gz
#cd portsentry_beta

Editamos el archivo portsentry_config.h cambiando la línea 32 para que quede así:

#define SYSLOG_FACILITY LOG_LOCAL6

Con esto simplemente le decimos que loguee al «facility» local6 en vez de al «daemon» por defecto.

Se guarda el archivo y se empaqueta de nuevo:

#tar cvfz portsentry-1.2.tar.gz portsentry_beta

Ya podemos reconstruir el rpm:

#cd /usr/src/redhat/SPECS
#rpmbuild -ba portsentry.spec

Si todo va bien tendremos el paquete generado:

#cd /usr/src/redhat/RPMS/x86_64

Y ahí estará nuestro portsentry-1.2-1.te.x86_64.rpm preparado para loguear donde queremos que lo haga. Sólo queda instalarlo. Si tu arquitectura es de 32bits lo encontrarás en /usr/src/redhat/RPMS/i386.

Nos queda un detalle, configurar syslog para que guarde donde nos interesa la facility local6. Para eso editamos /etc/syslog.conf. Añadimos al final de todo la línea:

local6.*   /var/log/portsentry.log

y al principio de todo veremos algo parecido a:

*.info;mail.none;authpriv.none;cron.none /var/log/messages

La cambiaremos por:

*.info;mail.none;authpriv.none;cron.none;local6.none    /var/log/messages

Es decir, le decimos que de local6 no loguee nada en /var/log/messages. Solo nos queda reiniciar los demonios:

#/sbin/service syslog restart
#/sbin/service portsentry start

A partir de ahora tendremos nuestro log general bien limpio y la información de se seguridad separada.

SAI Salicru bajo Linux con nut y monitorización en Cacti

Recientemente he tenido que cambiar el SAI que tenía en casa desde hace unos años, un Powermust 1000 que me había dado muy buen resultado, sin embargo las baterías habían llegado a su fin. En App encontré uno con muy buena pinta, con puerto USB para monitorización, indicaban que soportaba Linux y, además, fabricado en España :|, el Salicru SPS 900 One, a un precio insuperable. Me lo llevo :P.

La decepción llegó al instalarlo. La monitorización se hace a través de una aplicación propia, algo que no me convencía ya que estaba acostumbrado a utilizar nut y a tenerlo integrado en Cacti.

Leyendo y probando algunos drivers encontré cómo hacerlo funcionar :). Muy sencillo.

./configure --with-usb --with-snmp --with-cgi --prefix=/usr --with-cgipath=/path/to/cgi-bin/nut/
make
make install

Esto instalará todo lo necesario y dejará los scripts para acceder vía web al estado del SAI en la ruta indicada.

No voy a entrar en detalles de la configuración, sólo indicar que el driver a utilizar es blazer_usb:

cat /etc/ups/ups.conf
[salicru]
driver = blazer_usb
port    = auto
desc    = "Sai Salicru 900"

Con eso iniciamos los demonios upsd y si todo va bien  lo tendremos funcionando. Si vamos a la ruta donde dejamos los scripts web veremos:

Primer paso preparado. Vamos ahora a configurar el monitor de avisos para que sepamos cuando el SAI cambia de estado (se va la luz en casa, vuelve, se queda sin batería, etc.). Esto lo controla el demonio upsmon. Como veis se monitoriza todo bien excepto el nivel de batería, este SAI no informa de ese dato, pero tampoco es algo crítico, los cambios de estado sí que funcionan correctamente, con eso es suficiente para nuestro propósito.

Primero preparamos la configuración.

# cat upsmon.conf
MONITOR salicru@localhost 1 monmaster momi master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"

NOTIFYCMD /bin/avisoups

POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
POWERDOWNFLAG /etc/killpower

NOTIFYMSG ONBATT "El SAI esta funcionando con bateria."
NOTIFYMSG LOWBATT "La bateria del SAI esta muy baja"
NOTIFYMSG SHUTDOWN "El servidor sera apagado inmediatamente"
NOTIFYMSG ONLINE "EL SAI esta funcionando con alimentacion externa"

NOTIFYFLAG ONBATT WALL+EXEC
NOTIFYFLAG LOWBATT WALL+EXEC
NOTIFYFLAG SHUTDOWN WALL+EXEC
NOTIFYFLAG ONLINE WALL+EXEC

RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5

Además de definir los mensajes que queremos recibir, le indicamos también que en los cambios de estado llame al script /bin/avisoups.

# cat /bin/avisoups
#!/bin/bash
/bin/echo "$*" | /usr/local/bin/gammu --sendsms TEXT 666666666
echo "$*" | mail -s "Aviso del SAI" tu@tudominio.com

Este script se ejecutará en cada cambio de estado que se produzca en el SAI y recibirá como parámetro el texto correspondiente al nuevo estado. En mi caso me envío un email y un SMS a través de Gammu.

Levantamos el demonio upsmon y probamos a enchufar y desenchufar la alimentación externa del SAI. Si todo va bien recibirás un email y/o un sms con el aviso :).

Cuando al SAI se le termine la batería apagará el servidor para evitar que se corte la alimentación de golpe. Si configuras la Bios para que arranque automáticamente cuando reciba alimentación, se reiniciará él solito en cuanto vuelva la luz :).

Integración con Cacti

Para integrar la monitorización en Cacti podemos utilizar estas plantillas ya creadas.

Una vez instalada y creada en el host que hace de monitor debemos configurar el «Data source» correspondiente indicando el SAI que debe monitorizar, en mi caso salicru@localhost.

Si todo ha ido bien, comenzaremos a ver la gráfica de nuestro SAI. Tendremos sólo las líneas Input, Output y Load, la de Batteries, como he indicado, no se recibe en este SAI.

Ya tenemos nuestro SAI baratito bien instalado y configurado. A partir de ahora nos avisará cuando haya cortes de luz, apagará el equipo, se encenderá de nuevo automáticamente y, si lo configuramos todo bien, tendremos hasta un SMS en nuestro móvil. Y todo ello monitorizado a través de Cacti :).

Viajeros en Túnez

Este artículo llega con algo de retraso, debería haberse publicado hace un año :P. Las vacaciones de Semana Santa de 2009 nos fuimos a Túnez. Habíamos reservado el viaje en Sunweb a muy buen precio y todo resultó perfecto. Nuestra elección, fuera de los habituales paquetes en grupo, era simplemente avión + estancia en un complejo hotelero en régimen de todo incluido. La idea era movernos después y conocer el país por nuestra cuenta. Según nuestro plan de viaje, al llegar a nuestro destino estaría esperándonos el transporte que nos llevaría al hotel, y así fue 😐 no tuvimos casi ningún problema, y digo casi porque el taxista que nos vino a recoger no hablaba más que francés y árabe (idiomas oficiales) y nosotros castellano e inglés, con lo cual la comunicación era completamente nula :P. Este problema lo tendríamos más veces a lo largo de la semana. Durante el viaje hacia el hotel en Monastir, a unos 170km, nos llevamos más de un susto, era de noche, llegamos muy tarde, y el taxista parecía medio cegato, de vez en cuando se iba en exceso al arcén y nos provocaba algún que otro sobresalto. Nos sirvió para tener nuestra primera toma de contacto con el tráfico local y con la policía, había mucha a lo largo de la autopista que tomamos y paraban a muchos coches. Posteriormente nos enteramos que el presidente del país estaba de visita precisamente en nuestro destino. Nos alojamos en el Hotel Saadia en Monastir, en la costa este de Túnez, la zona más turística del país. El hotel está bastante viejo por dentro aunque las instalaciones son decentes, no creo que se pueda esperar más por el precio que pagamos. Eso sí, lleno de franceses y alemanes con las cervezas permanentemente en la manos y sin prácticamente salir del hotel. Con el todo incluido podías tomar cerveza (de allí) y bebidas espirituosas como Cetradine que aún no sé lo que es :P. Aparte del todo incluido podías tomar alcohol, pero a precios prácticamente de aquí.

La moneda oficial en Túnez es el Dinar y cotiza aproximadamente a medio euro, céntimo arriba céntimo abajo, con lo que hacer la conversión de los precios es muy sencillo, siempre la mitad de los dinares que te pidan :). Este fue más o menos nuestro viaje por Túnez.

Ampliar

He de decir que sí, que nos quedaron muchas cosas por ver como Cartago o Sidi Bou Said, Djerba o Matmata, pero el objetivo no era verlo todo sino mezclarnos entre la gente y disfrutar de la cultura y costumbres locales. Hablemos claro, nos guste o no, tenemos cara de españoles, nos reconocen de lejos y saben distinguir perfectamente un italiano de un francés de un español. Hablamos siempre de las zonas más turísticas, las de costa, una vez desapareces por el interior del país todo cambia completamente, cesan los asedios, los ambientes «comerciales», etc., pero en la costa rápidamente te van a decir: ¿Española? Hola, hola pesicola :P. En Túnez los hoteles suelen estar apartados de las «ciudades» y agrupados en torno a calles llamadas siempre «Routé Turistique«.

Contra lo que suele ser habitual en mis relatos, en este no encontraréis comentarios y fotos gastronómicos, no porque no comiésemos :P, sino porque lo hacíamos en los hoteles, con lo cual no aportan mucha información sobre los usos y costumbres de la gente. Las comidas de los hoteles están más o menos adaptadas al turismo internacional con un toque local y una enorme influencia francesa. No encontrarás cerdo, obviamente, pero sí ensaladas variadas, ternera, cordero, pescado, pizza y pasta… todo bastante habitual, lo más destacado, sin duda, la bollería del desayuno. Para prevenir sorpresas procura que el agua sea siempre embotellada, en los hoteles sería muy raro que te diesen agua del grifo, sin embargo, ¿con que lavan las frutas y verduras?, ¿con qué agua te vas a duchar? ¿quien no traga algo de agua mientras se ducha?. Lo mismo al lavarte los dientes… en fin, suerte.

Monastir

El destino original del viaje contratado y donde pasamos la mayor parte de nuestro tiempo. A la puerta misma del hotel teníamos la parada de autobús que nos llevaba a Monastir hacia un lado y a Soussè hacia el otro. En pocos minutos estábamos en el centro de la ciudad. A los autobuses se entra por la parte de atrás, curioso :P. En el momento de regresar resultó que el autobús daba una buena vuelta recogiendo gente, pero sobre todo estudiantes que acababan de salir del colegio y del instituto. Aunque parezca raro están mucho menos acostumbrados a ver turistas de lo que creemos, se nos quedaban mirando, las chicas bajaban la cabeza e intentaban por todos los medios no rozarse conmigo, algo complicado dentro del bus.

Monastir es una pequeña ciudad situada en el Golfo de Hammamet, destino de playa por excelencia dentro del país. No es que haya mucho que ver, pero merece la pena un paseo y entretenerse viendo el mausoleo de Habib Boruguiba, la mezquita o callejear por la medina. Vamos con una batallita, no hay muchas más. No habíamos dado ni dos pasos cuando nos aborda un tío hablando en inglés y nos cuenta que es el cocinero de nuestro hotel (y nos dice el nombre) 😐 que nos había visto la noche anterior al llegar, que si queremos nos hace de guía. Bueno venga, vamos, no tenemos nada que perder. Total que empezamos a hablar con él mientras nos da una vuelta por el mercado primero y por la medina después. Al entrar al mercado nos avisa, vigilad los bolsos e intentad no hacer fotos directamente a la gente, que majo el tío :P. Damos una vuelta por la zona de carnicería, con los corderos degollados colgando y las cabezas ya cortadas en una esquina, la sección de frutas y verduras, un puesto muy majo solo de especias… De ahí a la medina, nos va llevando por callejuelas de un lado a otro a un paso bastante acelerado mientras charlamos con él. Muy amena la conversación (siempre en inglés). Que si donde has aprendido inglés (en el colegio) que si cuanto es el salario medio en España, y cosas por el estilo. Acabamos en la típica tienda (probablemente de algún familiar) de alfombras y productos tradicionales de recuerdo y regalo (pipas, rosas del desierto…). Sus familiares nos suben a la parte de arriba para enseñarnos el muestrario de alfombras. Oye, que no nos interesan, que no vamos a comprar. Alfombras muy baratas, ¿cual querer?. Que no mira, lo siento, no nos interesan. Tras 15 o 20 minutos salimos de la tienda y nuestro amigo, siempre muy amable, nos pregunta si habían sido muy pesados :P, no tranquilo, no te preocupes. De ahí nos lleva junto algún otro conocido suyo que tiene una pequeña finca con camellos donde unos turistas alemanes se entretienen paseando a lomos del animal. Aquí el hombre captó que no nos interesaba nada y nos indicó por donde seguir al tiempo que nos decía que él se quedaba. Le dimos unas moneditas y continuamos por nuestro camino.

Cuando varias personas más nos vinieron con la misma historia de que eran los cocineros de nuestro hotel descubrimos que era todo para sacarnos algunas monedas y llevarnos a sus tiendas, pero sobre todo descubrimos que llevábamos la pulsera del todo incluido del hotel, por eso sabían cuál era el nuestro :P. Ya lo decía mi pareja, no les hagas ni caso, pasa de ellos, tienen que hacerlo porque es su manera de sobrevivir, pero ni caso :P. Alguna tenían que meternos :P, no hubo más novatadas :).Con la recepcionista de las mañanas en el hotel tuvimos también alguna que otra conversación, siempre encantadora con nosotros. Cuando le preguntamos donde podíamos alquilar un coche su respuesta fue algo como (siempre en inglés) Ah españoles, siempre quieren ver cosas… de muy buen rollo eh, que no se me interprete mal. Al final llegó a decirnos algo como: Estos estúpidos alemanes que solo vienen para estar todo el día con una cerveza en la mano tirados en la piscina :O. Ella misma llamó para ayudarnos con lo del coche, habló con el hombre y nos dio el precio, ¿estáis de acuerdo? Pues si venga, mañana a primera hora lo recogemos. Unos 40€ por día. Y eso hicimos al día siguiente. Un Renault Clio sedán casi nuevo, con aire acondicionado e incluso ordenador de a bordo, muy útil este último ya que el coche te lo dan en reserva, así que a la vuelta lo devolvimos igual :P. ¿Qué quiere esto decir? Fácil, que el coche lo coges vacío y se lo tienes que devolver igual, pero claro, tú lo devuelves con la gasolina que te sobre del viaje, que lo mismo es en reserva que con medio depósito, así que con el ordenador de abordo controlamos perfectamente lo que nos quedaba :).

Llenamos el depósito, compramos una botella de agua y… comienza el viaje.

Empecé a conducir con bastantes dudas y poco seguro, la experiencia inicial con el chofer y lo que vimos no nos dio precisamente confianza, pero poco fue mejorando. Al poco de salir nos topamos con el primer control de la policía. Creedme, es muy complicado comunicarte cuando no hablamos el mismo idioma. Nos pidieron el contrato de alquiler del coche y poco más. Puede continuar. Aunque nos pararon más veces ya nunca nos pidieron nada, de hecho hay otra anécdota muy buena. Sería a mitad de viaje cuando nos para otro agente a la salida de algún pueblo. Se acerca y empieza a decirnos algo en francés, algo que obviamente no entendimos y pusimos cara rara, con lo que el agente, siempre sonriente, nos grita «nacionalitè! nacionalitè«, ah coño, era eso :P, España oiga!, «Oh España, ¿region?«; pues Valencia mire usted. Pues muy bien, ale, continúe… :O.

Y es que policía hay mucha. Prácticamente en todas las entradas y salidas de los pueblos y ciudades te encontrarás con una patrulla, pero la mayoría, al ver que eres turista, no te harán ni parar. Eso sí, tu haz siempre el amago de parar y, si ves un control con señal de stop, para :P, si quieren que continúes ya te lo dirán, pero por si acaso tu para, no hagas como yo que en el primero hice el amago de seguir y rápidamente vinieron a gritarme algo que no entendía pero que vamos, estaba claro, «¿no has visto el stop o qué?» :P.

¡Cuidado con las ovejas y corderos! Pastan a sus anchas por los arcenes de las carreteras, incluso en la autopista te encontrarás rebaños de ellas en la mediana, cruzando de lado a lado. Bien es cierto que éramos casi los únicos que circulaban por el tramo entre Sfax y Sousse de la P1 que llega hasta la capital, hasta casi llegar a Monastir no empezamos a ver coches. Prueba del poco tráfico que lleva es que ni los peajes están en funcionamiento, la autopista es gratuita en ese tramo, no así en el que une Sousse con Túnez, el más turístico.

Sbeitla

Podríamos haber parado en Kairouan para ver la gran mezquita, pero preferimos continuar hasta las ruinas de la antigua ciudad romana de Sbeitla.

Nada más llegar dejamos el coche y nos acercamos al edificio principal donde vendían las entradas. Como curiosidad, hay dos tipos de entradas, las normales y las que dan permiso para hacer fotos :O, ¿alguien las compra?, yo diría que no ;). Al otro lado de la calle está la entrada al recinto de las ruinas, totalmente cercado, por cierto.

Sbeitla fue fundada en el s.II por los romanos y probablemente tuvo gran prosperidad debido sobre todo a las fábricas de aceite de oliva. Durante el Bajo Imperio Romano (s.III al V) comenzó su decadencia hasta ser ocupada por los vándalos primero, bizantinos después y, finalmente, por los árabes (647).

Las ruinas dan fe del tamaño que tenía la ciudad, con un espléndido foro, uno de los mejor conservados del mundo, los templos, el teatro, anfiteatro…

El día estaba nublado con lo que las fotos no son de lo mejor, lo suficiente para ver que son unas buenas ruinas.

A lo largo de todo el recinto se mezclan restos romanos con otros bizantinos. En la foto de abajo a la derecha, la Iglesia de Servus.

En Sbeitla, a diferencia de lo que era habitual, había tres templos, cada uno de ellos consagrado a una de las divinidades romanas más importantes, Júpiter, Juno y Minerva.

Dentro del recinto había algunos «locales» intentando vender lo que ellos decían que eran monedas originales de la época :P, otra vez solo con verte ya te decían «español, español». No caigáis en el engaño, es solo la manera que tienen de ganarse la vida.

Tozeur

Dejamos Sbeitla y continuamos nuestro viaje hacia el sur, queremos desierto :P. A lo largo del camino ves la transición del verde al marrón que sufre el paisaje, poco a poco y sin que te des ni cuenta te ves inmerso en la aridez del desierto, y, por si no te percatas por ti mismo, las señales de tráfico te avisan de «peligro, camellos en la calzada» :|, está usted entrando en el desierto, amigo español.

Tras el cansancio del día por los muchos kilómetros de coche, el calor, las áridas vistas y las caminatas por las ruinas romanas, buscamos un hotel y nos tiramos a descansar. Pero ¡qué hotel!, el Palm Beach Tozeur Hotel‎. Espectacular, por dentro es como un oasis. Eso sí, lujo asiático a precio occidental, unos 180 euros la noche según recuerdo.

Hicimos noche y al día siguiente nos dimos una vuelta por el famoso palmeral, que es precisamente eso, palmeras, palmeras y más palmeras llenas de turistas paseando en calesa, lo siento, eso no es para mí :P. No sé que esperaba encontrar la verdad, pero lo que vi no me impacto, dije, ah, sí, un gran palmeral que contrasta con la aridez del desierto que lo rodea, sin duda, pero poco más. Rodeando el palmeral pensamos que en algún punto habría algo interesante que ver, pero qué va. El palmeral está dividido en parcelas privadas, todo es privado, cada trozo tiene un dueño, con lo que no hay opción a moverte por ahí al libre albedrío. Pero en un determinado momento nos encontramos con algo que no sabíamos lo que era.

Vámonos para adentro, a ver qué es esto. Pues era una especie de centro de interpretación cultural y religioso donde explicaban a grupos de escolares los orígenes de la historia y de la religión, pero lo que más nos llamó la atención fue la libertad con la que contaban el origen de las tres religiones hermanas (cristianismo, judaísmo e islamismo) y su evolución a lo largo de los siglos. Muy instructivo, no recuerdo que en España se muestre a los críos el origen común de las tres religiones ;), algo que sin duda ayudaría mucho en respeto y tolerancia.

Chott el Jerid

La ruta del día nos llevaba a Douz y el camino pasaba sobre el impresionante lago de agua salada de Chott el Jerid a través de una carretera prácticamente recta de bastantes kilómetros de largo, más abajo tenéis alguna foto. Aquí me veis en mitad de la carretera que lo cruza con el coche alquilado :P.

El calor y el viento consiguen secar la humedad que se filtra, dejando a la vista una alfombra blanca de cristales de sal sobre la que puedes caminar tranquilamente, no es excesivamente firme pero sí lo suficiente como para aplacar tu curiosidad.

Como os decía, la carretera cruza el lago durante unos 20km.

En realidad no se sabe con seguridad cómo y de donde llega el agua salada a una zona tan interior del país. Probablemente hace millones de años era parte del Mar Mediterráneo.

Con el calor sofocante del verano la vista del Chott (lago) tiene que ser realmente espectacular.

Tras la parada, continuamos el trayecto hasta nuestra siguiente parada.

Douz

Puerta del desierto. Así es como se conoce a este pequeño pueblo del sur del país, el último antes de llegar al Sahara, el objetivo de nuestra estancia.

Y aquí comienza la mejor anécdota del viaje. Una vez llegamos a Douz buscamos, como habíamos hecho anteriormente, la «routé turistiqué» para reservar habitación en algún hotel. Hasta ahora siempre había sido muy sencillo, pero esta vez por mucho que seguimos las indicaciones no conseguíamos llegar a la zona de hoteles. Pero la diosa fortuna vino en nuestra ayuda en forma de «information touristique«. Marta y yo nos miramos… ¿aquí? imposible. Vamos a ver. Bajamos del coche y entramos en la «oficina«. Hola, ¿españoles?… ummm, sí. Y así conocimos a Alí.

Alí habla, además de árabe y francés, español, inglés e italiano con fluidez :O. Lo primero que hicimos fue buscar hotel, qué queréis ¿3 estrellas? ¿4? ¿5? Va venga, empecemos con 4 a ver que tienes por ahí, y llegamos al Sun Palm Douz Hotel.

Vosotros no preocupar, yo negociar precio en hotel, vosotros esperar, no hablar con personal. 😐

Bueno venga, a ver en qué queda todo esto. Total que mientras esperábamos tenían las tarifas oficiales a la vista, no recuerdo cuanto era. Después de un rato hablando (a gritos, claro :P) con el personal de recepción, volvió. Todo arreglado, y su precio era la mitad que la tarifa oficial. No está nada mal. Aceptamos. Y después llegó el comentario:

Vosotros pagar a mí, no en el hotel, no preocupar, yo tener acuerdo con director del hotel.

Uff, que mosqueo.

Y ya de paso nos ofrece excursiones. ¿Pasar la noche en el desierto? ¿montar en camello? ¿Ruta en 4×4 por el desierto? ¿Atardecer en el desierto? Ummm, esta última cuadra con nuestros planes. ¿Cuánto? 20 dinares por persona. Venga va, sin regatear ni nada, que el hotel nos ha salido bien. De acuerdo, a eso de las seis de la tarde vengo por aquí y nos vamos. ¿Pero cómo? ¿en el coche alquilado? Sí, no preocupar.

Así que descansamos un poco y a la hora acordada aparece Alí y ya él nos dirige. El hotel estaba justo delante del desierto, es decir, la parte de atrás daba a una pequeña carretera y al otro lado ya es todo desierto.

Ahora gira por ahí a la derecha y todo recto. ¿Por ahí? ¿Por el medio del desierto? Sí, no preocupar, yo llevar muchos años llevando gente y nunca pasar nada… Ummm, siempre hay una primera vez para todo, pero en fin, vamos allá…

Y valió la pena. Primero nos llevó a una zona de dunas y oasis, espectacular. Nunca habríamos llegado sin él, la verdad, no habríamos pasado de la pequeña carretera de la que os hablaba.

Las vistas de las zonas dunares por un lado, el oasis del palmeras al otro y el sol del atardecer nos dejó ensimismados, una estampa realmente bella.

Más fotos…

Y más fotos de las dunas.

Pero Alí tenía prisa porque se nos acababa el sol y quedaba todavía algo que ver. De vuelta a la carretera y ahora gira por el otro lado… todo recto, no veo nada, el sol de frente me ciega, da igual, tu sigue recto, corre, corre, sube, acelera, hay gente por el medio, da igual, sigue… :O

Y llegamos a una pequeña colina ya en el desierto, con un poblado a un lado, caravanas de bereberes al otro y unas vistas simplemente espectaculares. A los pies de la colina tenemos los restos de un antiguo asentamiento bereber abandonado hace cien años según nos cuenta Ali por el avance del desierto y la erosión causada por la arena y la acción del viento.

Aquí podéis verlo con más detalle.

Al frente, sólo el desierto.

Y comienza el espectáculo en que el desierto se engulle al mismísimo sol.

Ali sabía perfectamente a donde nos llevaba, quedamos realmente satisfechos con la excursión ya que de no ser por él no nos habríamos atrevido a adentrarnos en el desierto con el coche de alquiler, aún así no íbamos muy confiados, pero resultó bien.

De vuelta al hotel pagamos a Alí lo acordado, tanto la excursión como el hotel, rezando para que al día siguiente no hubiese problemas, y no los hubo, entregamos la llave y nos fuimos tal y como estaba previsto.

Nuestra experiencia con él fue muy buena, es un tío agradable y está acostumbrado a tratar con turistas. Durante el tiempo que estuvo con nosotros no pararon de llamarlo por teléfono para acordar con él más viajes y excursiones. Tal como lo dejamos en el hotel se fue directamente con otro grupo con el que había quedado.

Y aquí os dejo la oferta de Alí:

Si vosotros o amigos volver, reservar sólo avión. Yo recoger en aeropuerto de Túnez con 4×4 sin conductor, vosotros conducir, pasar 3 o 4 días en desierto, yo tener jaima con ducha y aire acondicionado. Entrar por Douz, salir por Matmata, y paasar otros 3 o 4 días en la playa. Todo por 400 euros por persona, comidas y hoteles incluidos.

Tlf: 0021698232154

Email: chokribouarif@yahoo.fr

Si algún día volvemos a Túnez hablaremos con él sin duda alguna.

El día siguiente era el último día que estaríamos en ruta, así que, tras desayunar, comenzamos el largo trayecto que nos quedaba hasta llegar a…

El Djem

Y allí nos recibe imponente el espectacular anfiteatro.

Con capacidad para 35.000 personas, fue el más grande tras el Coliseum de Roma (45000) y el de Capua, pero es el que mejor se conserva con el paso de los años. Aunque las gradas inferiores de la zona norte han sido parcialmente restauradas, el grueso del monumento mantiene su estructura y aspecto originales.

No he estado en el Coliseum por lo que no puedo comparar, pero os aseguro que este es impresionante. Si habéis visto Gladiator habréis visto este anfiteatro ya que aquí se rodaron las escenas de lucha.

img_5380

Toda la zona de gradas es una obra de ingeniería descomunal, por algo llevan ahí dos mil años en pie. Fijáos en el tamaño de las estructuras sobre las que se levanta el graderío.

Una cosa interesante de El Djem es que puedes subir hasta arriba de todo, tanto los vomitorios como las escaleras están perfectamente preparados para ir ascendiendo hasta la parte más alta.

El anfiteatro es Patrimonio de la Humanidad desde 1979.

Como veis, aún se conservan los fosos de los leones además de un complicado sistema de canalizaciones y cisternas con el que recogían el agua de la lluvia. No eran nadie los romanos en temas arquitectónicos :P.

Como la mayoría de recintos de este tipo, la destrucción comenzó con los propios habitantes de la localidad que vieron en el anfiteatro como una cantera de la que extraer piedra para sus viviendas. Parece ser que permaneció intacto hasta 1695, más de mil quinientos años. Y aún a pesar de todo se encuentra muy bien conservado aún.


Apurando la gasolina que nos quedaba llegamos de vuelta a nuestro hotel y pusimos fin a las excursiones. Los últimos días los queríamos dedicar a descansar y relajarnos en la piscina sin hacer nada más que leer y bañarnos, pero llovió, hizo muy mal tiempo, con lo que poco pudimos hacer.

Aquí termina este artículo. Me ha costado mucho tiempo escribirlo pero me he reído mucho recordando algunos momentos. Seguramente casi nadie se leerá todo el rollo que os he soltado, pero ahí queda eso, seguro que alguien que tenga previsto viajar a Túnez se molestará en leerlo :P.

Una vez más, recomendar a todo el mundo adentrarse en el país y abandonar las zonas de costa, tanto la gente como el paisaje cambian completamente y descubres de verdad otra cultura, otra forma de vivir y, si te molestas, entenderás la forma de vida de muchos inmigrantes árabes en nuestro país.

Albufera de Valencia

Ampliar

Con la esperada llegada del buen tiempo nos acercamos el sábado por la mañana a dar una vuelta por la Albufera. Aquí os dejo algunas fotos que dan muestra de la belleza de la zona.

A) Embarcadero

En el corazón de la Albufera se encuentra el mirador-embarcadero desde donde puedes dar un paseo en barca.


B) Centro de interpretación

Al comienzo del desvío hacia El Palmar se encuentra el Centro de Interpretacion desde donde podéis acercaos  por un pequeño sendero al centro de observación de aves ya que la Albufera es un humedal protegido, lugar de paso para miles de aves en sus trayectos migratorios.

Nunca se me había ocurrido parar aquí, suerte que en el embarcadero han puesto una caseta de información del parque y se nos ocurrió preguntar :P.









C) El Palmar

Finalizamos en El Palmar, reducto de la Valencia más tradicional, aquella de Cañas y Barro de Blasco Ibañez. Mucho ha cambiado desde entonces y el pueblo vive casi en exclusiva del turismo (gastronómico). Aún así el cultivo de arroz, además de la pesca, sigue siendo su forma de vida.

Adobe Air XI – Despliega tus aplicaciones directamente desde la web

Vuelvo con un artículo sobre la serie que hice hace algún tipo acerca de Adobe Air.

Uno de los principales problemas con los que me he encontrado al desarrollar con Air es a la hora del despliegue, ya que los clientes deben instalarse primero el framework y después la aplicación, lo que da lugar a muchas dudas y potenciales problemas. Para solucionarlo existe una librería de Adobe que permite saber si un cliente tiene instalado el framework y tu aplicación directamente desde una página web y lanzar la instalación de ambos en caso de que no los tenga, de esta manera los usuarios no tienen que descargar nada, todo muy sencillo e intuitivo.

Para interactuar con esta librería existe además una pequeña aplicación Flash que se distribuye con el sdk de Flex con los conceptos básicos: comprobar si el cliente tiene el framework y lanzar la instalación si es necesario. La podéis encontrar en:

C:Archivos de programaAdobeAdobe Flash Builder 4sdks4.0.0samplesbadge

Sin embargo puede ser realmente tedioso configurarla y programarla adecuadamente, así que existe Badger, una aplicación AIR que enmascara todo este proceso con un sencillo asistente donde rellenas los parámetros, incluidas las cadenas de texto a utilizar, y te genera el código necesario. Puedes descargarla aquí.

Al ejecutarla veremos la pantalla principal.

Por defecto solo hay un template, así que el primer menú lo podemos obviar. Con el segundo seleccionas tu aplicación AIR para que Badger cargue automáticamente algunos de los parámetros y, cuando has terminado, con la última opción «Export badge» generas el código.

Dentro de la configuración hay dos campos importantes. «application url«, debes introducir la url completa (con http://) desde donde se descargará la aplicación, y «publisher ID«, donde tienes que seleccionar la ruta donde la tienes instalada localmente para que Badger lea automáticamente este dato, imprescindible para comprobar si el cliente ya la tiene instalada.

Al subir todos los archivos generados a tu web (el html puedes integrarlo adecuadamente) y cargar la url en un navegador verás algo parecido a esto suponiendo que no tienes la aplicación (o el framework) instalados.

Al hacer click en «Instalar», si no tienes el framework instalado, te pedirá autorización y comenzará la descarga:

Para finalmente acabar instalando tu aplicación.

Si el cliente ya tuviese la aplicación instalada podremos lanzarla automáticamente también. Para conseguirlo es necesario, primero, que en el descriptor de la aplicación hayas configurado el siguiente parámetro a «true«:

<allowBrowserInvocation>true</allowBrowserInvocation>

Ahora, si el cliente ya tiene nuestra aplicación, veremos algo como esto:

Y al hacer click en «Lanzar ahora» nuestra aplicación se cargará ella sola :).

Como veis es muy sencillo para el cliente instalar así nuestras aplicaciones AIR, nada que ver con tener que descargar el framework por un lado y la aplicación por el otro.

Nuevo proyecto en 5 horas: UsayTira.me, direcciones de correo de usar y tirar explicado paso a paso

Parece que últimamente me aburro mucho :P. Hace unos días, leyendo un artículo, se me ocurrió de nuevo explicar cómo se hacen esos sistemas de correo instantáneos que se suelen utilizar para registrarse en webs y que después no te envíen spam :P. La idea me pareció muy adecuada para poner un ejemplo práctico de algo que vimos hace tiempo sobre otras utilidades para un servidor de correo y, tal y como me ocurrió hace unos meses, lo que era un artículo se convierte en proyecto.

La idea, por tanto, es crear un sistema que, sin necesidad de ningún registro, te permita crear una cuenta de correo y recibir y leer emails en ella por espacio de una hora, al cabo de este tiempo la cuenta se autodestruye y todos los emails serán devueltos. En nuestra aplicación tendremos dos opciones para crear la cuenta, aleatoria o personalizada, creo que no hacen falta más explicaciones. Una vez usas una cuenta puedes volver a ella más tarde cuando la necesites volviendo a crear una cuenta personalizada con el mismo usuario. Esto es útil, por ejemplo, para que te recuerden la contraseña que utilizaste para registrar en aquella web de descarga de películas y de la que ya no te acuerdas ;).

Qué necesitamos

  • Servidor Linux con Qmail como MTA.
  • Apache, PHP y MySQL.
  • Pear MimeDecode: para procesar los correos entrantes con PHP.
  • Una plantilla superchula de FreeCssTemplates
  • Jquery: para todo lo que es ajax y Javascript
  • ZeroClipboard:  para copiar y pegar automáticamente
  • Jquery ScrollTo: pluggin para desplazar el scroll automáticamente.
  • Una imagen de «Cargando» para las acciones ajax que personalizas aquí.
  • Diccionarios de palabras «aleatorias». Aquí hay unos cuantos.
  • Adodb (opcional) para el acceso a base de datos.

Eso es todo, sólo hay que juntar las piezas adecuadamente.

Preparando Qmail

Nuestro primer paso, antes de ponernos con los temas puramente web, será configurar adecuadamente el servidor de correo para nuestro propósito. Para ello necesitamos crear un usuario del sistema que reciba todo el correo dirigido a un dominio. Esto lo podemos hacer del siguiente modo:

adduser -g users -s /dev/null usaytirame
passwd usaytirame UNACLAVESUPERCOMPLICADA

Añadimos nuestro nombre de host en:

/var/qmail/control/rcpthosts

usaytira.me

Y el usuario al que dirigiremos los correos en:

/var/qmail/control/virtualdomains

usaytira.me:usaytirame

Reiniciando Qmail conseguiremos que los correos enviados a cualquier cuenta del dominio vayan al buzón del usuario indicado, es decir cualquiercosa[arroba]usaytira.me.

Pero no queremos que los correos vayan al buzón del usuario sino simplemente procesarlos. Para eso editamos el archivo:

/home/usaytirame/.qmail-default

|preline /usr/bin/php /home/usaytirame/procesa.php

Sólo con esa línea. Con este comando conseguimos redirigir los correos entrantes a un script en el que podremos recuperarlos y reutilizarlos a nuestro antojo como veremos a continuación.

Procesando los emails entrantes

Vamos a comenzar por crear una base de datos donde guardaremos los emails recibidos. Como queremos poder acceder a los emails dirigidos a cada cuenta independientemente, haremos dos tablas, una (emails) la utilizaremos como tabla maestra para las cuentas de correo que se creen y en la otra (correos) iremos almacenando los emails recibidos para cada una de esas cuentas.  La estructura sería poco más o menos la siguiente:

CREATE TABLE IF NOT EXISTS `emails` (
  `idEmail` int(11) NOT NULL auto_increment,
  `fecha` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `email` varchar(255) NOT NULL,
  `ip` varchar(15) NOT NULL,
  PRIMARY KEY  (`idEmail`),
  KEY `email` (`email`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `correos` (
  `id` int(11) NOT NULL auto_increment,
  `idEmail` int(11) NOT NULL,
  `de` varchar(255) NOT NULL,
  `para` varchar(255) NOT NULL,
  `subject` varchar(255) NOT NULL,
  `fecha` varchar(255) NOT NULL,
  `body` text NOT NULL,
  `fullmail` text NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `idEmail` (`idEmail`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Creo que es suficientemente descriptiva. El campo fecha de emails nos servirá para controlar los 60 minutos de duración máxima.

Pues ya tenemos todo preparado. Veamos cómo procesamos los emails.

/home/usaytirame/procesa.php

include ("mimeDecode.php");

$email=file("php://stdin");
$email=implode("", $email);

$params['include_bodies'] = true;
$params['decode_bodies'] = true;
$params['decode_headers'] = true;
$params['input'] = $email;
$structure = Mail_mimeDecode::decode($params);

$subject = quoted_printable_decode(trim($structure->headers['subject']));
$ddate = quoted_printable_decode(trim($structure->headers['date']));
$from = quoted_printable_decode(trim($structure->headers['from']));
$to = quoted_printable_decode(trim($structure->headers['to']));

if(ereg("<(.*)>", $to, $p))
    $to=$p[1];
$to=strtolower($to);

Tenemos la primera parte del procesado preparada. De aquí debemos destacar:

$email=file("php://stdin");

Con esto leemos desde la entrada estandar el contenido del email. Recordad que no estamos en una aplicación web sino en un script ejecutado en la consola del sistema.

La otra línea importante es:

$structure = Mail_mimeDecode::decode($params);

Con ella conseguimos procesar el email y separar su estructura en un array asociativo con los distintos parámetros. Os ayudará mucho ver el contenido de ese array:

print_r($structure)

Llegados a este punto podemos hacer una prueba. Necesitamos el contenido completo de un email, podemos sacarlo de nuestro cliente de correo o del propio servidor.

cat prueba.eml | /home/usaytirame/procesa.php

Si todo ha ido bien veremos en pantalla un array con la estructura del correo.

No voy a detallar todo el proceso ya que alargaría mucho el artículo. Vamos con el siguiente paso:

$query="select idEmail from emails where email=".$conn->quote($to);
$rs=$conn->Execute($query);
if($rs->recordcount()==0){
        exit(100);
}else{
        $idEmail=$rs->fields['idEmail'];
        $content = get_content($structure);
        $query="insert into correos
            (idEmail, de, para, subject, fecha, body, fullmail)
            VALUES
           ($idEmail,
            ".$conn->Quote($from).",
            ".$conn->Quote($to).",
            ".$conn->Quote($subject).",
            ".$conn->Quote($ddate).",
            ".$conn->Quote($content).",
            ".$conn->Quote($email).")";
        $rs=$conn->Execute($query);
}

En la primera parte del script comprobamos si la cuenta a la que va destinado el email existe en nuestra base de datos, si no, muy importante, devolvemos un código 100 que indica a qmail que debe devolver el correo ya que no existe el usuario.

Si la cuenta existe recogemos el cuerpo del mensaje. Yo lo hago con la función get_content, que analiza la estructura del correo y devuelve el contenido. Esta parte os la dejo a vosotros. Básicamente consiste en comprobar las distintas partes que puede tener un correo y devolver lo que estimemos oportuno. Un detalle muy importante a tener en cuenta es la codificación tanto del email como de nuestra base de datos y la aplicación web. En mi caso las dos últimas están en UTF-8, con lo que debo convertir todos los textos del email a esta misma codificación. La estructura que teníamos inicialmente en un array tendrá parámetros que nos indican el charset en el que viene el email. Las funciones de conversión de PHP te pueden ser útiles: iconv, utf8_encode, etc.Finalmente introducimos todos los campos del email en la base de datos.

Puedes volver a probar a procesar el email de prueba tal y como hicimos antes. Recuerda que debes añadir el registro de la tabla emails para que  guarde el correo, si no la cuenta no existirá. Una vez te funcione desde la línea de comandos ya puedes probar a enviarte un correo real :).

La aplicación web

No creo que hacer la parte web propiamente dicha necesite muchas explicaciones. Tenemos ya todos los elementos preparados, sólo debemos añadir los formularios para crear la cuenta de correo (aleatoria o personalizada) y, con un poco de ajax, ir cargando los correos a medida que van llegando. No  hay más truco.

Añadiré, eso sí, algunas aclaraciones interesantes.

Para crear las cuentas aleatorias, en vez de utilizar una secuencia aleatoria de números y letras, que daría como resultado algo ininteligible, usamos los diccionarios que comentaba más arriba. Los importamos en una tabla de la base de datos y simplemente tenemos que buscar aleatoriamente una palabra que no esté utilizada todavía como cuenta de correo, sencillo y muy impactante visualmente ya que estás ofreciendo cuentas legibles y con sentido.

Como en cualquier otra aplicación accesible públicamente, hay que añadir algún tipo de mecanismo de seguridad. En mi caso lo he hecho implementando una blacklist de direcciones IP. Cada vez que se crea una cuenta actualizo en una base de datos el número de cuentas que se han creado desde esa IP, si pasa del límite que estimemos oportuno, esa IP se pasa a la tabla de lista negra y cuando intente crear una nueva cuenta no se le dejará.

Nos falta una cosa: Eliminar las cuentas que tienen más de una hora. Muy sencillo, una tarea en el CRON que ejecuta un script que lanza una consulta a la base de datos que elimina las cuentas (y sus correos asociados) que se crearon hace más de 60 minutos.

Finalmente he añadido la opción de reiniciar esos 60 minutos de tiempo, simplemente actualizando el timestamp de la base de datos y algunos efectos visuales para plegar y desplegar los mensajes usando Jquery.

No hay mucho más, en unas cinco horas tenemos la aplicación hecha y funcionando.

Conclusiones

Como conclusión, la misma que hice hace unos meses con el primer proyecto. La copio tal cual porque es igual de válida.

Bueno, y todo este rollo ¿para qué?. Pues muy sencillo, para que veais que hoy en día la tecnología está al alcance de todos, es sencillo y rápido crear un proyecto en Internet, hay de todo por todas las esquinas, la tecnología no es lo importante, lo que verdaderamente cuenta es cómo mueves ese producto tecnológico para rentabilizarlo y obtener un beneficio de él.

Ya tengo mi proyecto superchulo funcionando, sólo me ha costado unas 5 horas de trabajo. Le he puesto un poco de Adsense por aquí y por allí. ¿Y ahora qué? ¿A esperar a que la gente entre y me haga millonario? 😛 Es mucho más complicado que eso como todos sabéis, primero tienes que tener una masa de usuarios elevada que le dé movimiento al proyecto y después tienes que conseguir que la mayoría de ellos sean gente normal, no gente técnica, usuarios avanzados que no pagamos por nada ni pinchamos en publicidad 😛 .

Hoy en día, en Internet, como en cualquier negocio, las técnicas de marketing y venta son mucho más importantes que la tecnología en sí misma, es duro reconocerlo, pero es así. De nada sirve que tengas el mejor producto del mundo mundial si no consigues que la gente lo utilice y se deje dinero, así de claro. Si tienes los conocimientos adecuados para mover el negocio, no te preocupes, la tecnología te la aporta cualquier partner por un módico precio, pero poner en manos de otro toda la estrategia de ventas de tu negocio no está tan claro ¿no?.

Espero que os sirva de algo el artículo. He querido mostrar, fundamentalmente, cómo utilizando algunas librerías que puedes obtener sin coste puedes hacer algo realmente útil y funcional con muy poco esfuerzo. Seguro que sacáis alguna idea.

Perdón por el rollo 😛 , al final me ha costado mucho más escribir el artículo que implementarlo.

Podíamos haber añadido una opción que he visto por ahí que consiste en crear una cuenta automáticamente cada vez que entra un email para una cuenta que no existe, pero estaríamos creando cuentas para todo el spam que recibamos, así que prefiero no hacerlo. Si quisierais hacerlo creo que ya sabéis cómo.

Segmentation fault al instanciar un webservice WCF de .NET desde PHP

Recientemente nos hemos encontrado con un problema que nos ha tenido varios días bloqueados hasta conseguir averiguar el origen. Llevamos mucho tiempo utilizando webservices programados en .NET desde aplicaciones PHP sin ningún problema, pero esta vez estaba hecho con la nueva tecnología WCF (Windows Communication Foundation) de Microsoft .NET 3.5. El problema era que en cuanto lo subimos a producción la aplicación PHP devolvía un pantallazo en blanco sin más información. Analizando los logs vimos que el proceso de Apache provocaba un Segmentation Fault con lo que no llegábamos a ver ninguna excepción.

Tras muchas pruebas conseguimos aislar el error en la línea de código que instanciaba el nuevo webservice, si eliminábamos esa parte todo funcionaba correctamente.

$client=new SoapClient("http://wcf.tudominio.com/webservice/ws.svc?wsdl");

Lo más curioso es que en los entornos de preproducción sí que funcionaba, no entendíamos nada. Analizando las máquinas de los distintos entornos todas eran idénticas en cuanto a versiones y configuración excepto algunos parámetros SOAP para PHP, en la máquina de producción tienen la caché de wsdl activada mientras que en los demás está desactivada.

soap.wsdl_cache_enabled = 1
soap.wsdl_cache_dir = /tmp/
soap.wsdl_cache_ttl = 7200
soap.wsdl_cache_limit = 50

No puede ser que el error sea el cacheo. Pues sí, lo es, en cuanto desactivamos la caché del servidor de producción todo comenzó a funcionar correctamente.

Perfecto, pero la caché tiene que estar activada, la aplicación hace uso de unos 35 webservices, si para cada instancia de cada uno de ellos hay que cargar previamente el wsdl, el rendimiento cae por los suelos, es imprescindible.

Pues nada, solución increíblemente cutre:

ini_set('soap.wsdl_cache_enabled', '0');
ini_set('soap.wsdl_cache_ttl', '0');
ini_set('soap.wsdl_cache', '0');

$client = new SoapClient("http://wcf.tudominio.com/webservice/ws.svc?wsdl");

ini_set('soap.wsdl_cache_enabled', '1');
ini_set('soap.wsdl_cache_ttl', '7200');
ini_set('soap.wsdl_cache', '3');

Así es, desactivamos la caché antes de instanciar sólo este webservice y la volvemos a activar después. No hemos encontrado otra manera de solucionarlo ni hemos encontrado ninguna referencia de alguien que haya sufrido el mismo problema. La solución es mala, muy mala, no deja de ser un apaño, pero funciona y nos permite salir del paso hasta que sepamos por qué ocurre.

Aumenta tu productividad integrando el sistema de incidencias en el entorno de desarrollo: Eclipse + Mylyn + TFS

Si hace unas semanas veíamos como integrar las incidencias de Jira en Eclipse, hoy veremos como hacer lo propio con Microsoft Team Foundation Server (TFS).

En determinados proyectos nos vemos obligados utilizar TFS para el control de versiones, pero en nuestro caso lo utilizamos desde Eclipse utilizando un plugin desarrollado por Teamprise. A finales de 2009 Microsoft compró esta empresa con lo que el plugin se llama ahora Microsoft Visual Studio Team Explorer Everywhere 2010, casi nada :P, así que ya es parte de Visual Studio.

El paso final de la integración consiste en poder acceder a las incidencias del TFS desde el sistema integrado en Eclipse, Mylyn. Para conseguirlo Teamprise tiene otro plugin, Teamprise Mylyn Conector.

La instalación es muy sencilla, se descomprime en la carpeta de Eclipse, se reinicia éste y a funcionar. Veamos como configurarlo. Si no visualizamos la lista de tareas en nuestro Eclipse, vamos a «Window -> Show view -> Task list», nos aparecerá la ventana correspondiente. Haciendo click con el botón derecho vamos a «New -> Query» y en la ventana que se abre seleccionamos «Add task repository«.

En la nueva ventana seleccionamos «Teamprise repository«:

Indicamos los datos del TFS:

Seleccionamos el nuevo repositorio creado:

El proyecto al que necesitamos acceder:

Y el tipo de incidencias a cargar: Eso es todo, en la ventana de «Task list» nos aparecerá la lista de las incidencias:

Tal y como veíamos en el caso de Jira, desde ahí podremos ver las incidencias, modificarlas, crear otras nuevas, asociar contextos, programar las tareas, etc.

¿La pega? Que no permite realizar filtros en las incidencias. Así como cuando vimos la integración con Jira la creación de consultas era muy completa, permitiendo múltiples filtros, en este caso se limita a recoger todas las incidencias del tipo indicado, no pudiendo, por ejemplo, recoger sólo las incidencias o tareas asociadas a nuestro usuario. Es un mal menor, sí, pero limita tu productividad ya que tienes que revisar todas las incidencias una por una hasta encontrar las tuyas. En el propio plugin de TFS el comportamiento es muy parecido, no puedes hacer filtros en las incidencias, como mucho puedes ordenarlas alfabéticamente por el «Asigned to» y localizar las tuyas, poco útil también.