Script: Almacenador de avatares

Hoy hablando con mi amigo Iñaki (aka WyrmXD), he recordado que hace unos años él quería hacer un shellscript que almacenara un histórico de todos los avatares de sus contactos de su cliente de mensajería instantánea. No recuerdo bien porqué finalmente no lo hizo. De ese modo, me he propuesto hacer una implementación sencilla pero funcional de ese script. Funciona con el todoterreno kopete, tanto en KDE3 como en KDE4, y está realizado en Python (Un lenguage prácticamente desconocido para mi hasta hoy, pero que tengo muchísimas ganas de aprenderlo). Espero que os sirva de utilidad :)

Es un pequeño demonio que mediante inotify, el subsistema del kernel de Linux que lanza notificaciones de eventos sobre el sistema de ficheros, vigila los cambios en la carpeta de avatares para actualizar nuestro repositorio local. Al arrancar comprueba si hay actualizaciones en todos los avatares, en cuyo caso los almacena. A partir de entonces, queda a la espera de cambios.

A cada contacto se le asigna una carpeta, donde se almacenan sus avatares ordenados por un identificador numérico. Para poder curiosear más cómodamente, el script crea un registro de cambios en el fichero de texto logs.txt.

Las carpetas en las que almacena la información es ~/.kde/share/apps/kopete/adv_avatars.

¡Disfrutadlo!

#!/usr/bin/python
import os, filecmp, shutil
from pyinotify import WatchManager, Notifier, ThreadedNotifier
from pyinotify import EventsCodes, ProcessEvent
from datetime import datetime

homedir = os.environ['HOME']
try:
   kde = os.environ['KDE_SESSION_VERSION']
except KeyError:
   kde = "3"

if kde == "4":
   path = homedir + '/.kde/share/apps/kopete/avatars/Contacts/'
else:
   path = homedir + '/.kde/share/apps/kopete/msnpictures/'
rep = homedir + '/.kde/share/apps/kopete/adv_avatars/'

wm = WatchManager()

# watched events
mask = EventsCodes.IN_MODIFY | EventsCodes.IN_CREATE

class PTmp(ProcessEvent):
  def __init__ (self):
    if kde == "4":
      accounts = os.listdir(path)
      for account in accounts:
        account_path = os.path.join(path,account)
        if os.path.isdir(account_path):
          avatars = os.listdir(account_path)
          for avatar in avatars:
            avatar_path = os.path.join(account_path, avatar)
            if (os.path.isfile(avatar_path)):
              self.addFile(avatar_path, 'init')
    else:
      avatars = os.listdir(path)
      for avatar in avatars:
        avatar_path = os.path.join(path, avatar)
        if (os.path.isfile(avatar_path)):
          self.addFile(avatar_path, 'init')

  def process_IN_CREATE(self, event):
    self.addFile(os.path.join(event.path, event.name), 'modify')

  def process_IN_MODIFY(self, event):
    self.addFile(os.path.join(event.path, event.name), 'create')

  def addFile(self, orig_path, action):
    if orig_path[-4:] == '.png' and os.stat(orig_path).st_size:
      final_path = ""
      a_path = os.path.dirname(orig_path)
      a_name = os.path.basename(orig_path)
      avatar_path = os.path.join(rep, a_path[len(path):], a_name)

      # Si no existe el directorio, lo creamos
      if not os.path.exists(avatar_path):
        os.makedirs(avatar_path)

      # Cogemos todas las imagenes de su directorio
      all_files = os.listdir(avatar_path)
      files = []
      for avatar in all_files:
        if avatar[-4:] == '.png':
          files = files + [avatar]

      if not len(files):
        # Sin ficheros? Creamos el primero
        final_path = os.path.join(avatar_path,'1.png')

      else:
        # Obtenemos el id
        max_id = 0
        for avatar in files:
          avatar_id = (int)(avatar[:-4])
          if avatar_id > max_id:
            max_id = avatar_id

        # Buscamos duplicados
        dupe = False
        for avatar in files:
          tmp_path = os.path.join(avatar_path,avatar)
          if(filecmp.cmp(orig_path, tmp_path)):
            dupe = True
            break

        # Si no esta duplicado, lo metemos
        if not dupe:
          file_name = str(max_id+1) + '.png'
          final_path = os.path.join(avatar_path,file_name)

      if final_path != "":
        shutil.copy2(orig_path, final_path)
        now = datetime.today().strftime("%Y-%m-%d %H:%M:%S")
        log = open(os.path.join(rep, 'log.txt'), "a")
        log.write(now + "\t" + final_path + "\n")
        log.close()

notifier = Notifier(wm, PTmp())
wdd = wm.add_watch(path, mask, rec=True)

while True:  # loop forever
  try:
    # process the queue of events as explained above
    notifier.process_events()
    if notifier.check_events():
      # read notified events and enqeue them
      notifier.read_events()
    # you can do some tasks here...
  except KeyboardInterrupt:
    # destroy the inotify's instance on this interrupt
    notifier.stop()
    break


3 comentarios a “Script: Almacenador de avatares”

  1. Wyrm  on diciembre 19th, 2008

    Oleeee :D ya pondras una galeria no??

  2. chusete  on diciembre 19th, 2008

    Sí, revelando esos avatares que decíamos que a veces publica la gente durante solo unos segundos y nunca da tiempo a verlos

    muahahaha

  3. asdf  on abril 16th, 2011

    y donde copio y pego esto ¿?¿?


Deja un comentario