Objetos maestros en PHP

Ya comenté el tema de usar clases “principales” para un proyecto… y ahora vuelvo con el mismo tema. Muy creativo, sí…

La idea es la de tener un objeto principal (maestro) con un constructor que crea dentro del propio objeto tantos objetos “internos” como hagan falta, pasándole por referencia su propio objeto al constuctor de los “objetos internos”.

Los “objetos internos” extienden a una plantilla de objeto, y esa plantilla contiene un constructor que a su vez “guarda” como referencia el parámetro pasado por el objeto principal.

Sí, es un lío, así que mejor verlo en código:

class AppObjectSkel {
  function __construct(&$parent) {
    $this->_parent = $parent;
    if(is_callable(array($this, 'init'))) $this->init();
  }
}

class AppDatabase extends AppObjectSkel {
  function init() {
    /* Aquí se inicializa la DB */
  }
}

class AppCache extends AppObjectSkel {
  /* Elemento de cache, no lo inicializamos en este ejemplo */
}

class Application {
  function __construct() {
    $this->database = new AppDatabase($this);
    $this->cache = new AppCache($this);
  }
}

De esta manera se puede acceder de un elemento a otro. Por ejemplo, desde AppCache se puede acceder a AppDatabase pasando por Application, simplemente usando $this->_parent->database. Al tratarse de un valor pasado por referencia, se puede acceder desde AppDatabase a AppCache y reflejar cambios en tiempo real.

Pero hay que tener en cuenta un pequeño detalle: los constructores. Debido a que se hereda de una clase maestra (AppObjectSkel), no se puede poner constructor de ningún tipo (ya sea __constructor o una función con el nombre de la clase), ya que PHP ejecutará únicamente el del objeto creado (AppCache, por ejemplo) y no el de AppObjectSkel (y mucho menos va a ejecutar dos constructores). Se puede evitar esto de varias formas: evitando AppObjectSkel en todos los casos y copiando el construct a cada vez, copiando el construct sólo cuando lo necesitamos (por que pisamos el construct de AppObjectSkel) o simplemente usar una función opcional (llamada init), como pongo en el ejemplo, que sólo se ejecuta si existe y se llama desde AppObjectSkel, a modo de constructor (un constructor invoca a otro).

Desde la propia aplicación simplemente hay que crear una nueva instancia del objeto Application ($app = new Application) y acceder a los diferentes objetos a partir del maestro ($app->db, $app->cache).

Esto llega a ser muy útil cuando la aplicación entera está divida en objetos (AppUsers, AppForums, AppProfiles...) y es necesario hacer transacciones entre los objetos. En lugar de crear una instancia para cada objeto cada vez que se necesitan (por ejemplo, instanciar AppCache desde AppUsers cuando hace falta usar memcache), se pueden instanciar una sola vez y acceder en un entorno protegido (Application, que vendría a ser un “contenedor” relativamente protegido de variables pisadas y globales erradas), a todos los objetos o variables que haga falta.

Con esto después se pueden hacer montones de cambios (instanciar una clase poco usada sólo cuando se necesita, hacer una especie de namespace para tener un cache durante la ejecución del programa…). Y es que ahí, la imaginación es el límite.

Sistemas de recomendaciones

Hace ya algún tiempo (casi 2 meses!) saqué showRSS junto con algunos amigos. Se trata de un servicio web que permite generar un feed completamente personalizable que contiene los torrents de las series seleccionadas por los usuarios, extrayendo los torrents (y por lo tanto, series cubiertas) de EZTV, con el objetivo de sustituir al difunto FeedMyTorrents. El servicio tuvo bastante éxito (portada en Digg, aparición en TorrentFreak, Lifehacker, AppleSfera, y de ahí bastantes más blogs de tamaño medio).

Pese a mis temores, aguantó demasiado bien el tirón, y lo mejor de todo, sin posteriores sorpresas (lecturas aleatorias que fallan, índices que revientan y demás marrones aleatorios que suelen surgir). De ahí (y después del «hype») me puse a ver qué cosas interesantes se podían hacer con toda la cantidad de información que mueve semejante monstruo (sobre todo ahora mismo, con unos 15000 usuarios activos y unas 160000 selecciones de series hechas por los usuarios).

Así que me puse manos a la obra y monté una especie de sistema que generase recomendaciones para series. Y menuda basura.

La idea es de generar una lista de series “similares” a las dadas anteriorente. Técnicamente, es poesía. Sin embargo soy incapaz de entender código un mes después de escribirlo (eso es un problemón), y los resultados no son tan precisos como deberían. Al fin y al cabo, funciona pero con sus detalles.

El principio técnico es … algo extraño. Primero se seleccionan los usuarios que ven alguna de las series seleccionadas. Esta lista se procesa de manera a posicionar a los usuarios que mayores coincidencias tienen, y calcular su afinidad. Por dar un ejemplo: si un usuario ve las 5 series que yo he seleccionado más una más, esa serie (y por lo tanto, ese usuario, que pasará con mayor peso a la segunda parte) será mucho más importante que cualquier otra serie que sea vista por un usuario que vea mis 5 series y otras 15 más.

Después de atribuir los puntos a los usuarios, y los bonus a las series, se aplican también una serie de penalizaciones (por ejemplo, en el caso de que un usuario vea mis 5 series escogidas más una, si esa serie es por ejemplo la más vista, no va a tener prácticamente peso en el cálculo final, o de manera opuesta va a tener mucho más peso si se trata de una serie en la larga cola que tiene especial relevancia entre los usuarios con gustos similares a los míos).

Pero ahí vuelve a destacarse otro gran problema: la larga cola. En las series, por ejemplo, Nurse Jackie es reciente y podría cubrir ciertas recomendaciones cuando el usuario por ejemplo ya ve House y Mental. Pero (y por pura estadística), Heroes (que es la serie más suscrita en la plataforma) va a tener mayor relevancia que Nurse Jackie, pese a todos los bonus, aunque sean negativos.

Un método alternativo sería el clustering y k-means (bueno, no voy a hablar demasiado, la explicación técnica induce al suicidio). A parte de que no comprendo la mitad, no contempla de la misma forma la cantidad de suscritos (y después de tantas pruebas puedo decir que algo sí que importa en este caso). El sistema de k-means (a parte de ser horriblemente complicado) se basa en crear “inicios” aleatorios, para crear unas especies de polos (sí, y esto sigue siendo complicado). Y es imprevisible.

Otro problema (y ya de la propia naturaleza del sistema): igual que te puede gustar House, puedes odiar a Mental y Pushing Daisies, y para más inri, estar enganchado a Big Brother. Digno de una muerte dolorosa, sí, pero ocurre… y es que el ser humano… es extraordinario (y en esto no pensé antes).

Hasta aquí, verborrea. Ahora pasemos a lo interesante y triples anidados de listas completamente innecesarios:

  • Diferentes ejemplos de resultados:
    1. House, Mental, Nurse Jackie, Dexter, Bones
      • Fringe
      • Dollhouse
      • Heroes
      • Burn Notice
      • Chuck
      • Lie to me
      • The Mentalist
      • Eureka
      • True Blood
      • Lost
    2. NCIS, CSI: NY, Criminal Minds, Numb3rs, Cold Case
      • CSI
      • CSI: Miami
      • Bones
      • House
      • The Mentalist
      • Fringe
      • Burn Notice
      • Chuck
      • Lie to me
      • Heroes

Las dos “selecciones” son a grandes rasgos de dos temáticas diferentes. La primera, de medicina e investigación criminal, la segunda de investigación criminal y enigmas criminales, por decirlo de alguna forma. Por lo tanto, existe un ‘cruce’ entre las temáticas, aunque sus extremos están bastante alejados. Los elementos en itálica señalan coincidencias en ambas listas y los elementos en negrita señalan a series en el Top 10 de series más suscritas.

Las coincidencias son demasiado abundantes, ya que en ambos casos las series con mayor número de suscriptores ganan por encima de las series que realmente serían buenas sugerencias (por ejemplo, Dollhouse en la primera selección, pienso). Luego, las posibles selecciones (que se encontrarían a los “extremos” de ambas temáticas) en ciertos casos pueden no ser un reflejo de lo que el usuario espera.

El cruce entre las series también se reporta a cualquier otro set de sugerencias. Las series en sí también evolucionan y no siempre mantiene una temática definida (por ejemplo, Lost pasó de ser una serie intrigante a ser una mierda intrigante). En ocasiones los “grupos” de series se solapan entre sí, así que del momento en el cual se escogen series que podrían pertenecer a grupos distintos (Bones, Dexter, NCIS) el resultado de la sugerencia es completamente inútil y sin sentido.

Pero sigamos…

  • El problema técnico:
    1. Lecturas a la base de datos: para calcular absolutamente todo se necesita recurrir a la base de datos, y eso hace una media de 3000 lecturas por recomendación.
    2. Cache: la solución al primer problema sería guardar el set cada lectura en memcache (el sistema de MySQL se revela inútil en estos casos). Sin embargo, debido a que se tratan de consultas muy precisas (y con muchos datos devueltos), por ejemplo, los shows de X usuario, el hit rate es bastante bajo (y a falta de RAM, termina siendo un mal amigo para un sistema como showRSS).
    3. La larga cola: esto sí que es un monstruo, y pura estadística. Cuanto más se ve una serie, más posibilidades hay de que se cuele en las sugerencias, y por mucha penalización que exista, es casi inevitable.
    4. La interfaz: no es realmente un problema técnico, pero si un verdadero marrón, a mitad entre diseño y técnica… por que cuando 150 líneas de JS dejan de funcionar sin motivo aparente bajo Internet Explorer, a uno le entran unos instintos asesinos bastante preocupantes.

A la larga, es muy difícil mantener un proyecto así funcionando. Requiere tener una máquina aislada (aunque se trate de un VPS, de lo contrario un pico de uso o simplemente un capullo abusón reventarían un servidor entero), suficiente RAM como para tener un cache funcional (y no un cache “peligroso”), y un programador que sepa interpretar su propio código (prometo no volver a usar nombres de variables abstractos sin documentar, lo prometo, por mi bien).

¿Y cual es la utilidad real? Posiblemente, ninguna. La información así es interesante para hacer tartitas y barritas, pero no para ayudar a descubrir nuevas cosas…

Concluyendo: Las sugerencias no funcionan… por ahora. Y es que el ser humano es imprevisible (y espero que nadie me pida nunca consejo sobre estos temas, al menos por ahora), por ahora tocará seguir encontrando series a la vieja usanza: amigos, zapping y EZTV.

¿Alguien dijo recomendaciones personalizadas? De moda, e inútil.

Euskal Encounter 17

Y esperando a la 18! Ha estado genial, con montones de conferencias, gente interesante, concursos, noches en vela… :-) … y a diferencia de la Campus Party, no nos hemos asado!

Y a continuación, una chuleta para el año que viene (sí, siempre viene bien y tal):

  • Equipaje: La tienda de campaña, el saco de dormir y eventualmente la esterilla son impepinables… Y unas chanclas no te vendrían mal si piensas ducharte. Y si te da cosa de que te vean el pito, lleva bañador (aunque tampoco es que importe, no?) En cuanto a la maleta, un trolley debería ser más que suficiente. No hay que olvidar que según vayas en metro, tren o simplemente en coche, vas a arrastrar el equipaje tanto en el aparcamiento como dentro y fuera del recinto (y el recinto es enorme!!).
     
  • La tienda de campaña: Yo no llevé ni esterilla ni tienda de campaña, y me arrepiento profundamente. en cualquier caso la esterilla que hace falta, y la tienda de campaña merece mucho la pena. Además, Decathlon vende tiendas de campaña para interior, pequeñas, que se montan solitas (en 2s, dicen). Eso sí, mínimo media hora para volver a montar todo de vuelta.
     
  • Al llegar: La acreditación empieza el día anterior a la inauguración, normalmente al medio día (13h). Es decir, que pese a que la inauguración es al día siguiente por la tarde, la red ya funciona y es posible instalarse sin problemas (como hace la gran mayoría de gente) un día antes. Pese a ello, oficialmente no se considera día de party (aunque todo funciona como un día corriente de party). Y por cierto, esa primera noche pre-party-oficial no apagan las luces, no insistáis!
     
  • Instalarse: En cuanto llegues, instala tu tienda de campaña. Busca un lugar bien situado, eso puede ser por ejemplo relativamente cerca de las duchas (sin inundarte), teniendo los accesos al pabellón del recinto y al exterior a una distancia correcta (evitando ruidos) y en un lugar por el que no pase todo el mundo. Y si tienes miedo por tu equipaje, simplemente llévalo contigo mientras montas la tienda, aunque la seguridad en el recinto es muy buena y está generalmente bien vigilado (tanto servicio de urgencias médicas como vigilancia).
     
  • Las duchas: Las duchas son una mierda. Una-soberana-mierda. Si te duchas, te van a ver el pito, así que si tienes un trauma personal con ello mejor evita limpiarte :-P . Una de las razones por las que viene bien tener una tienda de campaña propia cerca de las duchas, es que puedes llevarte simplemente un bote de jabón, una toalla y unas chanclas, en lugar de tener que cargar con tu ropa de recambio hasta las duchas (o sin cambiarte, da igual), puesto que allí no hay lugar donde dejar tu ropa “a buen recaudo” mientras que te enjabonas y demás cosas.
     
  • Los servicios: Suelen estar ocupados la mayoría del tiempo. Más de uno se ha quedado sin papel higiénico en plena «tarea» (además de que el papel es simplemente horrible). Llevar tu propio papel higiénico no es una idea descabellada (o comprarlo, teniendo en cuenta que hay un Eroski cerca, ahora lo comentaré). Y si no te importa demasiado (como a la mayoría de los mortales), limítate a comprobar que hay papel antes de pasar, y evita dentro de lo posible guarrear todo (visto que hay cola, es posible que el que pase después te vea la cara…). Todos los servicios (o WC) están situados en la parte trasera del pabellón, debajo de las rampas de acceso a la party (la acreditación se sitúa a un nivel superior, y hay escaleras mecánicas y ascensores para bajar al lugar de la party en sí). De cierta forma, el acceso, los servicios y el acceso al pabellón de descanso están en la parte “trasera” del recinto, y por lo tanto las filas AA-AB serían las más alejadas de los servicios, y AA-AB también las más alejadas de las zona de descanso, pero las más cercanas a la zona de pizza, control de escena y pantallas. Así que el sitio también es algo importante!
     
  • Alimentación y aprovisionamiento: En el propio pabellón hay máquinas (pegadas a la zona de acceso y servicios). Las hay de café (de las cuales una a mi me timó dos veces, mierda), de Coca-Cola, de snacks, sandwiches… En la zona opuesta (parte «backstage», tras las pantallas) hay un bar en el que sirven (de 20h a 8h) algunos platos calientes a un precio no demasiado elevado (aunque creo que se exceden bastante en el precio de las bebidas). Y hay un telepizza con pocas y caras ofertas pero con buenas pizzas, en la zona de AA-01 (esquina opuesta al acceso al pabellón de descanso, por cierto).Fuera hay un Eroski, y más lejos un Decathlon, un Media Markt y un par de negocios más. Por cierto, si necesitas un disco duro o algún tipo de hardware a buen precio, pide antes precios en la party y en los propios stands que se suelen instalar (por ejemplo ModPC-Bexitec, tienen hardware a muy buenos precios). Si vas con alguien o simplemente consumes mucho, conviene ir al Eroski el primer o segundo día para “llenar el carro” durante toda la party (simplemente por el ahorro y disponibilidad, merece la pena). Y si tienes por ahí una neverita portátil y no te es un incordio llevarla, puede serte muy útil.
     
  • Ordenadores y red: Si vas a querer llevar dos ordenadores, necesitas un switch. En mi caso llevé dos y de ello me arrepiento bastante, puesto que al final casi no jugué (tenía intención de participar en partidas LAN, pero apenas había y si no, había ya lío con otros temas, es difícil aburrirse!). La red es Gigabit, es decir, que cualquier instalación Fast Ethernet (100mbit), ya sea por una tarjeta de red no-gigabit o un switch que no soporta gigabit, es un desperdicio de recursos… y al intercambiar ficheros por DC++ (Direct Connect), se nota mucho la diferencia! Hay que compartir un mínimo de 2 GB para poder conectarse al DC++, y el programa tiene que hashear antes todos tus archivos, así que merece la pena configurar el DC junto con lo que vas a compartir previamente. La red asigna direcciones IP públicas, y la diferencia de velocidad de navegación en internet (en comparación a un ADSL residencial) no se nota demasiado (salvando algunas diferencias, por ejemplo es prácticamente imposible saturar la conexión para que vaya lenta!). Por cierto, no lleves algún router o volverás sin él, limítate a llevar un switch si realmente lo necesitas, y otra vez más, piensa en reducir tu equipaje al mínimo.
     
  • Concursos: Hay concursos de muchos tipos y con diferentes premios. En algunos como el Hackit se puede participar simplemente por diversión. Un consejo personal: no te cortes, hay muchos concursos, muchos premios, y mucha gente se corta simplemente pensando que no van a llegar a ningún lado… y se equivocan ;-) .
     
  • Último día: Si tienes que volver en tren o si se da el caso, en avión, duerme aunque sea un poco antes (y eso va por retorcida experiencia, el día de la vuelta dormí apenas 2h cuando ya era de día, y de milagro no me quedo allí). También ten un especial cuidado con tus pertenencias, aunque sin exagerar (la seguridad sigue estando muy presente como el resto de días, pero una cámara o un móvil sin dueño no se ven de la misma manera que cualquier otro día).

Demás cosas: posiblemente se me hayan quedado en el tintero, sin que yo sea consciente. Iré añadiendo cosas según se me ocurran :-) , espero que le sea útil a alguien! (A parte de mi, claro)… Y espero veros el año que viene ;-)

Botón ‘atrás’ y hashes de dirección con AJAX

Páginas como Gmail, Facebook o Tuenti usan el modelo ‘hash’ en las URL. Por ejemplo, la siguiente URL:

http://www.tuenti.com/#m=Search&func=view_friends_page&job=243354

Lleva a una búsqueda en Tuenti. Sin embargo, el contenido después de # en la URL no se envía al servidor, puesto que se trata de un ‘hash’ de URL. Este contenido sí que es accesible mediante JavaScript, usando la variable window.location.hash.

Tiene dos grandes ventajas al usarlo junto con AJAX: por una parte, funciona el botón de retroceso (“atrás”) aunque la aplicación esté basada en AJAX (esto depende la implementación, claro). Por otra parte, se puede ‘compartir’ el enlace, de tal forma que aunque sea una consulta inicialmente lanzada por AJAX, se pueda reproducir al entrar en el mismo enlace (con el mismo hash).

He programado un pequeño ejemplo, disponible aquí. Es muy sencillo, aunque todo está bien explicado en el propio código (sólo que en inglés). El archivo de funciones JavaScript (igual de importante que el la serie de capas que contiene la página) está aquí.

El principio “simplificado es el siguiente”:

  1. El usuario accede a la página
  2. Se incluye la función ‘launch()’ mediante jQuery a los eventos a ejecutar una vez se haya cargado el DOM
  3. Esta función simplemente ‘lanza’ la carga de la primera página, según tenga o no hash.
  4. La función ‘load_page()’ se ejecuta y carga el contenido. Al mismo tiempo crea un ‘timeout’ con la función ‘verify_hash()’, que ‘vigila’ el hash para detectar cambios.
  5. La función ‘verify_hash()’ crea a su vez otro timeout que llama a la misma función. En caso de que el hash haya cambiado, lanza ‘load_page()’, de la misma forma que hace ‘launch()’.

El ejemplo dado también incluye un timer de ‘timeout’ (en caso de que se ‘cuelgue’ la petición AJAX), una serie de capas de ‘Loading’ y comprueba que el usuario tenga JavaScript activado (en el caso contrario, sólo ve un mensaje alertando de la necesidad de tener JavaScript activado, sin dejar trazas de la aplicación).

Si se carga el hash #m=1&abc=2, la consulta AJAX (siempre GET) será a ./pageloader?m=1&abc=2, incluyendo siempre como GET el contenido del hash. De la misma forma, se pueden incluir enlaces con hashes (se lanza la consulta AJAX al clickearlos) y el botón de retroceso funciona sin problemas.

Intenté poner una función que lanzase automáticamente el cambio de página sin esperar al intervalo de comprobación (al hacer click en un enlace), sin embargo generaba conflictos con los timers. De cualquier manera, la diferencia de tiempo entre el click y la petición AJAX no es muy grande.

El ejemplo aquí y el script aquí. No olvidarse de mirar los comentarios del código ;-) .

Ego al día

Como de costumbre y por los pelos, intento no estar demasiado tiempo sin escribir en el blog. Esto es, escribir al menos una vez al mes, por mantener la cara. Me va a crecer un baobab en la mano a este paso, de lo vago que soy (en serio!).

  • Ego: He estado de breves-vacaciones en un islote (MissLila dixit). En el avión me he tragado dos season finales, NCIS en la vuelta y House en la ida (estos se merecen una mención, ahí viene).
  • Series: Hay que fastidiarse. House deja todo en el aire (“¡¡PERO QUE DEMONIOS VA A PASAR!!”) y NCIS más de lo mismo.
  • Proyectos: Aaaah-aah! Estoy trabando un proyecto fifty-fifty con un amigo del liceo. Tengo bastantes esperanzas puestas, aunque como de costumbre el panorama es deprimente por adelantado, así que sólo queda ir de frente. Es mi primer proyecto en compartido, a ver qué sale.
  • Blogging: Estoy probando Qumana para escribir en offline y usando un editor de escritorio (de hecho, el post anterior sobre YQL lo he escrito en el avión). Pese a que usa Java funciona bastante bien y el resultado es bueno (aunque no me resisto a meterle mano al post directamente desde la vista de código).
  • Así que por ahora mis proyectos actuales poco se tocan. Ahí están, de vez en cuando pongo algún que otro bugfix pero no los toco demasiado, estoy con “lo otro”. Me tiene entusiasmado.

Espero poder bloguear más a menudo (JAJAJA, esto no me lo creo ni yo, lo llevo diciendo desde hace meses)…  Aunque sea sobre programación.

YQL o la gran base de datos que es Internet

Leyendo korben.info (un blog en francés) me he encontrado un post la mar de interesante sobre YQL.

YQL es "Yahoo! Query Language" y es básicamente un sistema de "queries"estructuradas que permite lanzar "consultas" contra Interner entero.

Esto se hace usando una estructura XML pura que es consultada mediante consultas YQL (pseudo-SQL) que pasan antes por Yahoo!, por ejemplo: (hay mejores ejemplos por ahí, merece la pena echar un vistazo)

SELECT * FROM twitter.user.status WHERE id=’adrinavarro’

SELECT * FROM search.web WHERE query=’vacaciones’

SELECT * FROM lastfm.tag WHERE tag=’beck’ AND api_key=’?’

La idea es muy sencilla y a más de uno le va a gustar. Hay una recopilación de las tablas en datatables.org. Para quién le interese probar, existe una consola de pruebas para ejecutar consultas y analizar el resultado.

Para más información, docs sobre YQL y ejemplos (en francés).

Actualizando

Llevo una eternidad sin escribir en este blog y ya va siendo hora de ponerse al día. Me niego a estar más de un mes sin escribir (y por los pelos). Además, tengo un caos mental impresionante… pero allá vamos.

Han, he, cambiado un montón de cosas. Como no quiero estancarme en lo personal, simplemente diré que los tiempos cambian, Murphy me sigue puteando (maldito mal tiempo). Ah, y cuando unos nacen otros mueren (va en serio). Oh, y sí, me muero de sueño y me pica un ojo (momento Juankiblog).

Al grano. Voy por orden y enumerando los proyectos, para decir qué cambia y qué no (vale, sólo lo que cambia, vale):

Linkloo: Un pequeño “tumblelog” de información sobre el servicio. Arriba del todo, los antiguos “Canales” renovados. Por ahora son poco precisos pero voy a ir mejorándolos con el tiempo. También hay un montón de parcheos (bugfixes). Montones, cientos, a saco (si Feedburner/Google me putea –cambia la ubicación de los feeds–, yo el doble –y soy cabrón–). La idea es que este proyecto “automantenga”: evitar que se atasque controlando todo a muy bajo nivel, separando las operaciones y “vigilando” todo un poco mediante un sistema (sencillísimo) de procesos. Y lo que falló fue eso, se atascó y tardé una parte de la eternidad en darme cuenta y parte de la otra en saber qué fallaba. Pero bueno, no debería a volver a dar problemas.

fileSpawn: Hace tiempo que migré la infraestructura a Lighttpd y no me arrepiento. Más bien lo contrario. Ahora mismo estoy limitando la velocidad por descarga por usuario y en este momento (baja actividad –20h de la tarde–, últimamente está todo de bajón) envía a unos 5500 kB/s (50 Mbps) o un 25% de la capacidad (65 usuarios únicos ahora mismo, aunque llega hasta 300-350 sin despeinarse). Lo que antes era una carga por servidor de 5-10 puntos (y que se vaya a tomar por saco en hora punta) ahora no pasa de 1.50-2 –y eso cuando está cargado– (pero lo mejor de todo es que funciona siempre, no como antes). Va a ser que Lighttpd es genial, sí. Por lo demás: hay un “tumblelog” de información (también) y (¡por fin!) registro de usuarios (interesante sobre todo para guardar los nuevos archivos subidos).

- aquícerca: Estoy pensando como hacerlo aún más útil. Y sigo acordándome de la madre de los programadores de Apple –todos–, hay que ver las que se trae la maldita SDK para apps nativas. Por eso se sobreentiende que sigo programando para web (insertar chiste sobre casinos y furcías aquí). Y lo que toca anunciar: versión básica. Bastante más rápida que la completa, sólo que no usa AJAX ni JavaScript, y por lo tanto tampoco tiene soporte para mapas. Funciona perfectamente en el iPhone (y es más rápida que la otra, con sus carencias y diferencias) pero ahora funciona también en otros móviles (Nokia, Sony Ericsson…) sin problemas. El próximo objetivo es hacer una versión iPhone aún más rápida (¡mucho más rápida!).

Estoy convencido de que me dejo algo, así que esto se queda como “primera entrega”. Pero eso no significa que me vaya sin mencionar al ego (oh, mi querido ego): he “renovado” (y una mierda)  la home de este saco (va a ser “he puesto”, no creo que lo otro se mereciese el término de home). Es un fusilamiento en toda regla de Netvibes, un buen ejemplo para la definición de algo así como “no tener nada que hacer”.

¿Somos terroristas?

Mientras que unos países censuran internet, otros se limitan a desarrollar tecnología que al fin y al cabo nos vigila (pero dicen que no, ahora depende de nosotros – y si somos paranoicos o no). El debate del autómata, publicidad contextual y perfiles de personas… Igualito que con la publicidad en Gmail. Que según se vea, también tiene su lado malo, como relata (ficción, claro) Cory Doctorow en ‘Engoogleados’. Merece la pena leerlo aunque sólo sea para pensar un poco sobre lo que trata y la pérdida de privacidad en Internet. Que –parece ser– es lo que internet arruinó (entre otras cosas, claro).

Y ahora, la gente de ThePirateBay ha sacado una VPN que simplemente no guarda registros (parece ser que las demás ‘anónimas’ los guardan pero no los entregan bajo ningún concepto, ¿será cierto?). Auque lo más preocupante –creo– es que lleguemos a este punto en el que se van restringiendo las libertades individuales y las VPN son una opción a considerar para ‘mantenernos seguros’ (bromas de condones a parte, por favor).

Nos vinieron con la ley contra el P2P (intercambio de datos). Por suerte, la rechazó el Parlamento Europeo. Menos mal. Aunque internet sigue teniendo enemigos, ahora se va dividiendo en dos partes. Los que censuran y los que no. Al fin y al cabo España no está nada mal, casi no existe censura. Bueno, sólo un poco y de jueces torpes, muy torpes.

A ver cuanto tardan en darnos en las narices a nosotros también. Miedo me da…

Mundo surrealista

Un paréntesis en el aburrido mundo del código y cosas incomprensibles para la mayor parte de los mortales. Sólo una cosa, surrealista, como no.

¡¡Mira que mansión tengo!! Ups...

Pinta un pene en el tejado de su casa y sus padres se enteran por Google Earth“. Tener una mansión de un millón para esto. Y no para fardar de casa por Google Earth… ups, un falo.

Maldito “Desvío de llamadas activado”

Ni un mes llevo con el iPhone y ya estoy cansado de las ventanitas de “Desvió de llamadas activado”. Al llamar a alguien –por error o no– te tragas la ventana, con todo el rollo de tener que “Aceptar” la alerta antes de poder colgar rápidamente. Vamos, un gran fallo.

Aquí viene una solución que he encontrado buscando y que me ha funcionado con el último firmware (2.2.1). Basta con tener el iPhone 3G jailbreakeado, Cydia instalado, actualizado y cinco minutos libres. El proceso es sencillo:

  1. Abres Cydia.
  2. En la ‘pestaña’ o ventana “Home”, seleccionas “More package sources”, justo debajo de “Featured packages”.
  3. En la lista buscas el repo llamado “iPhone-Notes.de”.
  4. Pinchas, confirmas, le das a instalar, aceptas todo y vuelves a la pantalla de Cydia.
  5. En la lista de secciones verás un par de nuevas secciones. El paquete está en “Tweaks (2.2)”.
  6. Dentro de la sección “Tweaks (2.2)” hay un paquete llamado “ForwardMsgFix”.
  7. Tocas sobre el paquete, confirmas, instalas y sales de Cydia.
  8. Apagas el iPhone por completo (apretas en el botón power durante unos segundos, deslizas la barra ‘Apagar’ y esperas a que se apague completamente – puede tardar un rato).
  9. Vuelves a encender de la misma forma, apretando el botón de power. Lo que se dice reiniciar, vamos.
  10. Voilà!

Todo sea por encajar una chorrada en 10 pasos, pero vamos. Estoy feliz, ya puedo cancelar alegremente esas llamadas fatídicas de errores de toque. Y torpeza, claro.