Posts Tagged 'sweetter'

EventManager en python

Hoy he estado implementando un sistema de plugins para www.sweetter.net, y para ello he decidido utilizar un modelo de señales, de tal forma que se puedan enlazar funciones a señales, y cuando se lance esta señal, se hace una llamada a todas las funciones enlazadas a esta señal.

La idea es simple, pero la implementación lo es aún más. Solo es necesario implementar un par de clases, Event y EventManager.

La clase Event
Como su propio nombre indica, esta clase representa un evento, o señal. Como atributos de clase tiene:

  • (str)self.name, para nombrar a la señal.
  • (dict)self.listeners, para guardar todas las funciones conectadas a esta señal, junto con los posibles parametros de estas.

Como metodos tiene:

  • add(self, function, data=None)
  • , que conecta una funcion a este evento, en data se pueden pasar los parametros de la función, como una tupla, o un dict. Si no se pasan, se llama a la función sin parametros.

  • def delete(self, function), esta es la inversa a la función anterior, desconecta una función de una señal.
  • def called(self, data=None), en esta función es donde está el meollo de la cuestión, ya que se encarga de llamar a las funciones de este evento. Si se pasa el parametro data, pues se utilizan estos parametros para la llamada a todas las funciones conectadas a esta señal

La clase EventManager
Esta clase es la encargada de gestionar todos los eventos que tengamos, y que emite las señales.
Como atributos:

  • (dict)self.events, en este parametro se almacenan todos los eventos.

Como metodos:

  • def add_event(self, Event), este metodo añade un evento al EventManager.
  • def del_event(self, Event), este metodo es el inverso del anterior, borra un evento.
  • def connect(self, event, function, data=None), con este metodo se conecta una función con un evento, el evento debe existir en el event manager.
  • def disconnect(self, event, function), esta es la función inversa a la anterior.
  • def signal(self, event, data=None), esta es la función encargada de mandar señales, así que se llama cuando queramos generar un evento.

Ejemplo de uso

import events
em = events.EventManager()
em.add_event(events.Event('misenal1'))
...
em.add_event(events.Event('otrasenal'))
em.connect('misenal1', print)
em.connect('misenal1', str.join, [['uno', 'dos', 'tres']])
em.connect('otrasenal', str.split, "cadena dos")
...
em.signal('misenal1', 'esto se imprimiria')
em.signal('otrasenal')
...

Aquí el código completo

class Event():
    def __init__(self, name):
        self.name = name
        self.listeners = {}

    def add(self, function, data=None):
        self.listeners[function] = data
    
    def delete(self, function):
        self.listeners.pop(function)

    def called(self, data=None):
        for function, d in self.listeners.items():
            if data is None:
                if d is None:
                    function()
                else:
                    if type(d) == type([]):
                        function(*d)
                    elif type(d) == type({}):
                        function(**d)
                    else:
                        function(d)
            else:
                if type(data) == type([]):
                    function(*data)
                elif type(data) == type({}):
                    function(**data)
                else:
                    function(data)


class EventManager():
    def __init__(self):
        self.events = {}

    def add_event(self, Event):
        self.events[Event.name] = Event

    def del_event(self, Event):
        self.events.pop(Event.name)

    def connect(self, event, function, data=None):
        self.events[event].add(function, data)

    def disconnect(self, event, function):
        self.events[event].delete(function)

    def signal(self, event, data=None):
        if data is None:
            self.events[event].called()
        else:
            self.events[event].called(data)

Sweetter 2.0

En el autobús, camino del Congreso de Hispalinux (cáceres), surgió la idea de implementar un twitter libre. Y durante todo el fin de semana es a lo que nos hemos dedicado.

Nuestra implementación no tiene como objetivo copiar a twitter, también tenemos pensadas muchas funcionalidades, para hacer más divertido el uso de sweetter.

En principio en sweetter puedes escribir hasta un máximo de 133 caracteres, tenemos pensado que varíe segun el karma. Y este karma se calculará a partir de los followers que tengas y de los votos a tus comentarios (esta parte está por implementar).

Ayer le introduje la posibilidad de poner TODO, así se puede utilizar como un sistema de asignación de tareas.

Y con las cosas que tenía ya implementadas, y el dominio comprado, pues ayer lo publicamos en SUGUS http://sweetter.net. Penyaskito ya nos advirtió de que antes de publicar esperaramos a la auditoría que él nos iba a hacer, pero no podíamos esperar, así que ayer por la tarde estaba funcionando.

Y como buen hacker, Penyaskito encontró un fallo en mi código (una cosa arto dificil), y se ha adueñado de la página durante toda la noche. Me comentó por donde había entrado, y ya lo he solucionado.