Libertonia
Portada · Todo · Software Libre · Desarrolladores · Comunidad · Internet · Tecnología · Meta · Diarios
Google Desktop, Gaim y Python

jorginius's Diary
Por jorginius
departamento Indexando conversaciones , Sección Diarios
Puesto a las Sat Apr 1st, 2006 at 01:15:02 AM CET
De acuerdo, en un mundo ideal de Linux, Gaim y Beagle todo esto no nos haría falta pero si:

  1. Eres usuario de MS Windows y de Google Desktop
  2. Tu cliente de mensajería es Windows Gaim
  3. Te preguntas cómo hacer que GDS indexe los mensajes de Gaim igual que los de Trillian Pro

Entonces está entrada de diario está pensada para ti X-D

Nota: también puede servir de pico-tutorial de "Cómo escribir extensiones en Gaim y/o GDS con Python"

 


Hoy, a la hora del café, un amiguete me hablaba de fútbol, de mujeres y de cuánto le gustaría que Google Desktop pudiera indexar los mensajes de Gaim. Me dijo que, por lo visto, había existido antes un plugin (software cerrado) pero que se había muerto de asco al perder interés el autor y dejar de actualizarlo para gaim 1.x y superiores.

Yo le dije que me parecía bastante simple hacer uno, sin conocer a priori ni las tripas de Gaim ni las de Google Desktop (sabiendo, eso sí, que Gaim es extensible, que está portado a Windows, que hay un plugin que guarda logs, que para Google Desktop salen plugins como setas, etc.). Entonces --medio en broma, medio en serio-- el chaval me retó a escribir uno en los cuarenta minutos que nos quedaban.

Quedaría bien que dijera que lo conseguí pero me quedé algo corto de tiempo... Aunque no fue mi culpa O:-), sigue leyendo:

Para implementarlo escogí Python porque Gaim es extensible en ese lenguaje (con PyGaim) y además, en Windows, permite prototipado rápido cuando hay COM de por medio, caso de GDS. Podría haber usado también Perl pero Python (ActivePython) ya estaba instalado en la máquina y además los módulos win32 y yo nos conocíamos de antes.

Después de echar un vistazo rápido tanto al API de Gaim como al API de indexación de GDS, estaba perfactamente seguro que podía escribirlo quince minutos y que me sobrarían cinco :-)

Por desgracia las cosas se torcieron con PyGaim. La interfaz que exporta se supone que es un calco de la de la interfaz C (ha sido generada con SWIG) pero es falso: el prototipo de algunas señales ha cambiado (las del API Conversation en particular) y son cambios gordos:

En la señal received-im-msg y sent-im-msg (generadas en Gaim cuando el usuario manda/recibe un mensaje) no se propaga la conversación (GaimConversation), sólo la cuenta que estás utilizando, el nombre del usuario con el que hablas y el mensaje. Sin la información de GaimConversation, es difícil meter todos los mensajes y respuestas dentro de un contexto, así como llevar un control con marcas de tiempo.

Tras darle bastantes vueltas y pasarme del tiempo, al final tiré la toalla e hice una chapuza: todos los timestamps se calculan independientementes de gaim (con gmtime) y el contexto (el "conversation_id", un entero que pide GDS) se establece a partir de un hash del nombre de nuestro interlocutor, así que todas las conversaciones que tengamos con él --sean del tema que sean-- aparecerán agrupadas juntas en GDS.

Al final escribí el bicho en casi una hora. Considerando que empecé sin saber nada de Gaim ni de Google Desktop os podéis hacer una idea de lo fácil que es extender ese par, si bien PyGaim está un poco en pañales.

No sé si PyGaim 2.0 (para el futuro Gaim 2.0) arregla esos problemas pero aviso que para extender Gaim parece mejor opción Perl y Tcl.

El plugin ha sido escrito y testeado (poco o nada X-D) para Gaim 1.5.0 (PyGaim 1.5.0-1) y Google Desktop 2.0. Es feo, sucio y despreciable: así que si tenéis alguna sugerencia (especialmente en lo del "conversation_id" o veis algún bug no dudéis en decirlo.

# -*- coding: UTF-8 -*-
import sha
import time
import pywintypes
import pythoncom
import win32com.client
import gaim

_NAME          = "GaimDS"
_VERSION       = "0.1"
_DESCRIPTION   = "Indexa conversaciones en GDS"
# TODO: no hay entrada en el registro de Gaim
_GAIM_PATH     = "C:\\Archivos de programa\\Gaim\\gaim.exe"

PLUGIN_INFO = {
    'python_api_version' : 2,
    'name'         : _NAME,
    'version'      : _VERSION,
    'summary'      : _DESCRIPTION,
    'description'  : _DESCRIPTION,
    'author'       : "Jorge Rodríguez <jorginius@gmail.com>",
    'url'          : "http://libertonia.escomposlinux.org/user/jorginius/Diary",
    'load'         : "gds_load",
    'unload'       : "gds_unload"
}

_EVENT_FACTORY = None
_GUID = '{10a51bce-6670-65da-f0c0-40a8060c107f}'

def register_im_cb(nil, account, buddy, msg, flags):	
 	event = self.event_factory.CreateEvent(_GUID, "Google.Desktop.IM")
 	username = gaim.gaim_account_get_username(account)

 	event.AddProperty("format", "text/html")
 	event.AddProperty("content", "%s: %s" % (username, buddy))
	event.AddProperty("user_name", username)
 	event.AddProperty("buddy_name", buddy)
 	event.AddProperty("message_time", pywintypes.Time(time.gmtime()))
	event.AddProperty("conversation_id", 
		int(sha.sha(buddy).hexdigest()[12:28], 16))
	event.Sent()

def gds_load(plugin):
	try:
		obj = win32com.client.Dispatch("GoogleDesktopSearch.Register")
		obj.RegisterComponent(_GUID,
                                      ["Title", _NAME, 
                                       "Description", _DESCRIPTION, 
                                       "Icon", _GAIM_PATH + ",1"])
		_EVENT_FACTORY = win32com.client.Dispatch (
                                           "GoogleDesktopSearch.EventFactory")
	except: pass
	
	handle = gaim.gaim_conversations_get_handle()
	gaim.gaim_python_signal_connect(plugin,
					handle,
					"sent-im-msg",
					register_im_cb,
					None)

	gaim.gaim_python_signal_connect(plugin, 
					handle,
					"received-im-msg",		
                                        register_im_cb,
					None)
def gds_unload(plugin): pass

¿Alguno ha escrito otros plugins para Google Desktop? y, por añadir algo más de chicha: ¿qué pensáis de Google Desktop?.

He visto que jamarier y man ls se preguntan sobre alternativas a WinFS en "El parto de la burra..." (de la historia ¿Vista con dioptrías?). A nivel práctico, no debería haber mucha diferencia entre el futuro WinFS y el actualísimo Google Desktop, Spotlight o Beagle, por muy a nivel de aplicación que sean esos tres últimos.

< Terminología de ordenadores (14 comments) | OpenLaszlo (5 comments) >
Enlaces Relacionados
· escomposlinux.org
· Gaim
· Beagle
· Google Desktop
· Windows Gaim
· había existido antes un plugin
· PyGaim
· ActivePython
· API de Gaim
· API de indexación de GDS
· SWIG
· API Conversation
· received-im-msg
· sent-im-msg
· GaimConversation
· "El parto de la burra..."
· ¿Vista con dioptrías?
· Spotlight
· More on jorginius's Diary
· Also by jorginius

Encuesta
¿Google Desktop es...?
· Software propietario luego no existe para mí 66%
· Imprescindible: lo mejor que han inventado desde la cafeína 0%
· Uso Win. No lo he probado pero el concepto me atrae 0%
· Uso Win. No lo he probado pero no me atrae 33%
· Lo he probado y me parece un (otro) hype de Google 0%
· Solo lo uso para indexar las fotos de la rubia 0%

Votos: 3
Resultados | Otras Encuestas

Menu
· crear cuenta
· FAQ
· búsqueda
· Fuentes de Noticias

Login
Nueva cuenta
Usuario:
Contraseña:

Ver: Modo: Orden:
Google Desktop, Gaim y Python | 6 comentarios (6 temáticos, editoriales, 0 ocultos)
Fallo/despiste/copié el que no era :-) (none / 0) (#1)
por jorginius ("jorginius" en Google Mail) a las Sat Apr 1st, 2006 at 03:57:04 AM CET
(Información Usuario) http://www.rodriguezmoreno.com

Cambiad mentalmente ese "self.event_factory" por un "_EVENT_FACTORY". Algún día debería ser orientado a objetos pero no hoy :-)



La última vez que posteo código sin mirar, palabra (none / 0) (#2)
por jorginius ("jorginius" en Google Mail) a las Sat Apr 1st, 2006 at 04:11:24 AM CET
(Información Usuario) http://www.rodriguezmoreno.com

Joer, que salvajada... Ese:

_EVENT_FACTORY = win32com.client.Dispatch(...)

Tiene que ir fuera del try. En fin, dejaré de mirarlo porque es una pena X-D

[ Padre ]


 
Versión Post-resaca (none / 0) (#3)
por jorginius ("jorginius" en Google Mail) a las Sat Apr 1st, 2006 at 02:42:06 PM CET
(Información Usuario) http://www.rodriguezmoreno.com

Bueno, esta debería ser la buena. Cosas que se han arreglado:

  • Errores de teclexia a mansalva (como esos enteros de 4 bytes de 64 bits X-D)
  • Registra con el Google Desktop 2.0 a pelo. Por lo visto el tema del registro ha cambiado entre la versión 1.0 y la 2.0, así que el anterior código sólo registraba si habías actualizado de la 1.0 (es decir, tenías los interfaces antiguos)
  • Por un fallo estúpido --de PyGaim y mío-- antes sólo se registraba lo que recibíamos y no lo que escribíamos.
# -*- coding: UTF-8 -*-
import sha
import time
import win32com.client
import pywintypes
import gaim

_NAME          = "GaimDS"
_VERSION       = "0.2"
_DESCRIPTION   = "Indexa conversaciones en GDS"
_GAIM_PATH     = "C:\\Archivos de programa\\Gaim\\gaim.exe"

PLUGIN_INFO = {
    'python_api_version' : 2,
    'name'             : _NAME,
    'version'          : _VERSION,
    'summary'          : _DESCRIPTION,
    'description'      : _DESCRIPTION,
    'author'           : "Jorge Rodríguez <jorginius@gmail.com>",
    'url'              : "http://libertonia.escomposlinux.org/Diary/jorginius",
    'load'             : "gds_load",
    'unload'           : "gds_unload"
}

_EVENT_FACTORY = None
_GUID = '{10a51bce-6670-65da-f0c0-40a8060c107f}'
_GDS = win32com.client.gencache.EnsureModule(
			'{3D056FE7-EA8E-481A-B18F-0B02EBF6B3C1}', 0, 1, 0)

def register_im_cb(mode, account, buddy, msg, *args):
 	event = _EVENT_FACTORY.CreateEvent(_GUID, "Google.Desktop.IM")
	username = gaim.gaim_account_get_username(account)
	
 	event.AddProperty("format", "text/html")
 	if mode == "recv":
 		event.AddProperty("content", "%s: %s" % (buddy, msg))
 	else:
		event.AddProperty("content", "%s: %s" % (username, msg))

	event.AddProperty("title", "Gaim Chat")
	event.AddProperty("user_name", username)
 	event.AddProperty("buddy_name", buddy)
 	event.AddProperty("message_time", pywintypes.Time(time.gmtime()))
 	event.AddProperty("conversation_id",	
	        int(sha.sha(buddy).hexdigest()[16:24], 16))
	event.Send(0x01)

def gds_load(plugin):
	global _EVENT_FACTORY
	try:
		reg = _GDS.GoogleDesktopRegistrar()
		reg.StartComponentRegistration(_GUID,
                     ["Title", _NAME, 
                      "Description", _DESCRIPTION, 
                      "Icon", _GAIM_PATH + ",0"])		
		ireg = reg.GetRegistrationInterface("GoogleDesktop.IndexingRegistration")
		ireg.RegisterIndexingPlugin(_NAME)
		reg.FinishComponentRegistration()
	except: pass

	_EVENT_FACTORY = win32com.client.Dispatch('GoogleDesktopSearch.EventFactory')
	
	handle = gaim.gaim_conversations_get_handle()
	gaim.gaim_python_signal_connect(plugin,
					handle,
					"sent-im-msg",
					register_im_cb,
					"sent")
	gaim.gaim_python_signal_connect(plugin, 
					handle,
					"received-im-msg",
					register_im_cb,
					"recv")
    
def gds_unload(plugin): pass




 
Esto es para meta información. (none / 0) (#4)
por jamarier a las Sat Apr 1st, 2006 at 05:54:26 PM CET
(Información Usuario) http://barbacana.net/blog/

No he tenido ocasión de probar el google desktop, pero si beagle y me parece una pesadilla:
  • Me consume muchos recursos
  • Ciertos tipos de ficheros están asociados a ciertas aplicaciones. Así si no usas evolution, para beagle no tienes ficheros de correo (aun cuando uses el mbox o mdir, clásico entre clásicos).
  • A veces, no me ha encontrado cosas que fehacientemente sabía que estaba ahí
  • ¡NO USO GNOME! y no encuentro sitio donde decirle que en vez de buscar nautilus (y no encontrarlo y por tanto no abrir el fichero) que use el rox-filer. Igualmente me pasa con otros ficheros...


Supongo que alguna o todas estas cosas se solucionarían configurando bien los registros gconf... No he tenido mucho tiempo para dedicarle

Respecto al sistema de ficheros «base de datos», la idea es para hacer una gestión documental:


Referente a la magia, tengo libros de magia. En los cuales tengo un autor, una editorial, un número de efectos que empiezan en un número de páginas determinadas, elementos que intervienen (cartas, monedas, esponjas, cuchillos, fuego...) y otros comentarios. Marcas que puedo situar para acceder rápidamente puntos interesantes...

Igualmente tengo videos, en los cuales tambien hay magos, números, elementos empleados, marcadores temporales para indicar comienzo y final...

Y en menor medida, tengo conferencias grabadas (solo audio) en los que igualmente me interesaría marcadores temporales, contenidos, y otros comentarios.


La idea es por tanto añadir a la información estándar del sistema de ficheros (tamaño, nombre, dirección) estos tags con información adicional. De forma que pueda hacer consultas tipo: «find -extra 'nombre' 'Tamariz' -extra 'elemento' 'monedas' -size -200M » Y salgan todos los documentos, videos, fotos, charlas, etc que tenga sobre Tamariz haya monedas y su tamaño sea inferior a 200M.

No se como funciona el WinFs (salvo que dicen que es un sistema de ficheros-base de datos), tampoco como es el google desktop (supongo que es algo como beagle), pero creo que falta no el sistema de recuperar la información, sino el de almacenarla.

En mi último intento al respecto, he creado una base de datos independiente a los ficheros y no estoy muy contento. Si quieres mover un fichero de sitio, tienes que editar la base de datos. (a parte de que el interface de usuario apesta, pero eso es culpa mía).

Hay algunos formatos como el mp3 que permiten la inclusión de tags para este tipo de cosas, pero son dependientes de formato, si tengo ogg, o wav o au pierdo la ventaja de dicha información.

Así que repito la pregunta ¿existe un sistema de ficheros que permita que los usuarios introduzcan información arbitraria sobre los ficheros almacenados? He estado mirando reiserfs4 pero parece que la historia de base de datos solo es para la gestión de nodos de ficheros, no para guardar información sobre los ficheros. Corregidme si me equivoco.

P.D. Python...., sin comentarios :-)

-----
Opinión expresada por alguien que puede que no sea yo.



WinFS no hace magia (none / 0) (#5)
por jorginius ("jorginius" en Google Mail) a las Sat Apr 1st, 2006 at 07:52:21 PM CET
(Información Usuario) http://www.rodriguezmoreno.com

Ciertos tipos de ficheros están asociados a ciertas aplicaciones. Así si no usas evolution, para beagle no tienes ficheros de correo (aun cuando uses el mbox o mdir, clásico entre clásicos).

Tanto Beagle como Google Desktop son extensibles: es perfectamente posible (y sencillísimo) escribir un plugin indexador de buzones mbox o mdir.

Mirando los ejemplos que pones, de audio y vídeo:

Está resuelto en GDS con un indexador que entiende tags de MP3, AVI, WMA, ASF, WMV, AAC, MP4, OGG, WAV Pack, RAW, etc. Virtualmente cualquier formato de audio/contenedor que exista ahí fuera.

Para vídeo, hay indexadores de AVI con cabecera INFO y de Realmedia, si bien para lo que quieres hacer con los vídeos de Tamariz haría falta tenerlos en contenedores MPEGv7 (MPEG47) --que permite insertar tags y meta información en cualquier punto-- y un indexador que entienda ese formato, cosa que (de momento) no existe.

Salvando ese problema y conformándose con la cabecera INFO de AVI o similar, exactamente lo mismo que propones con "find" se puede hacer con GDS (incluso la consulta por línea de órdenes).

¿Sería complicado tener todo eso en Beagle? pues supongo que no: sería cosa de escribir uno usando id3lib, libogg, etc.

Por desgracia, hasta que Beagle no resuelva:
  1. Su inestabilidad crónica (no sólo a nivel de uso sino de interfaces también)
  2. Su "problema" de dependencias: es bastante duro tener que usar la vm de Mono para algo que debería ser una pieza fundamental del sistema
  3. La estabilidad de D-BUS.
  4. Etc


La gente no se va a volcar en desarrollar extensiones para él. Un poco lo de siempre: mientras no sea estable no va a tener la masa crítica detras suficiente para ser atractivo pero sin esa masa crítica nunca será estable.

GDS es casi todo lo que debería ser Beagle: estable, aplicación/lenguaje agnóstico (interfaz COM y ya: puedes programar en cualquier lenguaje con soporte, incluso jscript y vbscript) y bajo consumo de recursos (estamos hablando de unas 10 megas de memoria entre la base de datos y el demonio supervisor e inapreciable uso de la cpu cuando está en segundo plano)

No se como funciona el WinFs (salvo que dicen que es un sistema de ficheros-base de datos), tampoco como es el google desktop (supongo que es algo como beagle), pero creo que falta no el sistema de recuperar la información, sino el de almacenarla.

Ten en cuenta que con WinFS tendrás el mismo problema que con Beagle o GDS: si tu aplicación no almacena metadatos en WinFS entonces no podrás hacer búsquedas más que por el nombre de archivo y el contenido, como ahora. Si evolution no da información a WinFS entonces todo seguirá igual.

La única diferencia con Beagle y GDS es que WinFS vendrá integrado en el sistema operativo lo que hará que muchos fabricantes migren rápidamente... Pero la migración, actualizar las aplicaciones para que publiquen metadatos, hay que hacerla.

El que mejor lo tiene es Spotlight, ya que en Mac OS X a las aplicaciones no les resulta ni extraño ni moderno lo de los metadatos y ya hay mucha información para empezar a indexar.

Observa que en WinFS los archivos siguen estando sobre NTFS y los datos separados (igual que en Beagle). Esto tiene sentido porque, almacenando los archivos sobre la misma base de datos relacional como blobs, perjudicamos las búsquedas ya que el RDBMS tiene que mover todo aquello cada vez que hay un query.

Por tema de rendimiento, es razonable tener dos bases de datos enlazadas pero separadas: una especializada en el acceso a archivos (el sistema de archivos) y otra en búsquedas (la relacional), aunque pueda haber problemas de coherencia.

De la misma manera, si tu formato contenedor de vídeo no permite meter tags en puntos de tiempo (lo de Tamariz), WinFS no va a añadir esa característica como no sea con un campo de notas adicional para que escribas "en tal minuto pasa esto"

[ Padre ]


 
Enlace a la versión más reciente de GaimDS (none / 0) (#6)
por jorginius ("jorginius" en Google Mail) a las Sun Apr 2nd, 2006 at 09:10:58 PM CET
(Información Usuario) http://www.rodriguezmoreno.com

Bueno, para no torturar más a libertonia publicando scripts, por pequeños que sean, cuelgo la última versión en mi espacio de googlepages gaimds.py.

¿Qué cosas se han añadido: pues ahora agrupa las conversaciones de un mismo contacto por días (me da igual hacer el hash de un nick que de un nick más la fecha actual) y codifica los mensajes a utf-8 antes de indexarlos (en la anterior versión, GD se hacía un pequeño lío con eñes y tildes)

Este enlace también lo publiqué en el grupo de noticias del plugin original y el autor ha publicado como respuesta los fuentes de Gaimindexer. Está buscando a alguien que se haga cargo: es un pequeño proyecto en C# que parsea los logs de Gaim (hay que activar la función de "Historial" en las conversaciones).

Por desgracia hay que reescribirlo casi entero porque:

  • No funciona con el formato actual de logs de Gaim
  • No se registra correctamente en el actual Google Desktop


Así que creo que no merece la pena darle continuidad.



 
Google Desktop, Gaim y Python | 6 comentarios (6 temáticos, editoriales, 0 ocultos)
Ver: Modo: Orden:

ecol Logo Powered by Scoop
Todas las Marcas Registradas y copyrights de esta página son propiedad de sus respectivos dueños.
Los comentarios son propiedad del que los escribe.
Los iconos de las noticias y el logotipo son propiedad de Javier Malonda.
El Resto © 2002 Escomposlinux.org y aledaños.

Puedes sindicar los contenidos de libertonia en formato RSS 1.0 y RDF 0.9. También se puede sindicar la cola de envíos pendientes de moderación.

El proyecto escomposlinux.org está dedicado a la memoria de tas

crear cuenta | faq | búsqueda