Ir al contenido principal

This is my blog, more about me at marianoguerra.github.io

🦋 @marianoguerra.org 🐘 @marianoguerra@hachyderm.io 🐦 @warianoguerra

metawtf

jugando un poco con metaclases y decoradores para hacer los plugins de emesene mas seguros.

el problema que intento resolver es el siguiente.

dada una función o un método que pueden llegar a fallar:

def function(a, b):
return a / b

class Object(object):
def __init__(self, num):
self.num = num

def method(self, a, b):
'''return a / b * self.num'''
return a / b * self.num

print "function(1, 2) = ", function(1, 2)
print "Object(10).method(1, 2) = ", Object(10).method(1, 2)

print "trying function(1, 0)"
try:
function(1, 0)
except ZeroDivisionError, error:
print error

print "trying Object(10).method(1, 0)"
try:
Object(10).method(1, 0)
except ZeroDivisionError, error:
print error


cuya salida es:


function(1, 2) = 0
Object(10).method(1, 2) = 0
trying function(1, 0)
integer division or modulo by zero
trying Object(10).method(1, 0)
integer division or modulo by zero


usando el modulo sandbox podemos hacer:

import sandbox

def callback(function, exception_type, exception):
print "exception raised by %s: %s" % (function, exception)

@sandbox.sandbox(callback, Exception)
def safe_function(a, b):
return a / b

class SafeObject(object):
__metaclass__ = sandbox.meta_decorator(sandbox.sandbox,
callback, Exception)

def __init__(self, num):
self.num = num

def method(self, a, b):
'''return a / b * self.num'''
return a / b * self.num

print "safe_function(1, 2) = ", safe_function(1, 2)
print "SafeObject(10).method(1, 2) = ", SafeObject(10).method(1, 2)

print "trying safe_function(1, 0)"
try:
safe_function(1, 0)
except ZeroDivisionError, error:
print error

print "trying SafeObject(10).method(1, 0)"
try:
SafeObject(10).method(1, 0)
except ZeroDivisionError, error:
print error


la salida es:


safe_function(1, 2) = 0
SafeObject(10).method(1, 2) = 0
trying safe_function(1, 0)
exception raised by safe_function: integer division or modulo by zero
trying SafeObject(10).method(1, 0)
exception raised by method: integer division or modulo by zero


la salida es la salida del callback

otra cosa turbia que se puede hacer, es decorar metodos de objetos, no de clases, aca hay un ejemplo:

obj = Object(10)
sandbox.decorate_object(obj, sandbox.sandbox, callback,
ZeroDivisionError)

print "trying obj.method(1, 0)"
obj.method(1, 0)


notese que decora el objeto, no es que lo copia y devuelve uno similar o algo asi.

lo que hace es decorar un objeto del tipo Objeto (que no es seguro).
la salida:


trying obj.method(1, 0)
exception raised by method: integer division or modulo by zero


para que sirve todo esto? basicamente para asegurarme de que los plugins que cargo no emitan excepciones, y que si lo hacen, un metodo que yo defina decida que hacer con ese plugin (pararlo, reportar el error, seguir o preguntarle al usuario que desea hacer con el mismo).
Todo esto sin requerir que el usuario escriba una linea extra de codigo (lo cual no suelen hacer de todas formas, mientras el plugin les funcione a ellos :P)

el modulo permite crear metaclases que decoren con cualquier decorador que reciba una cantidad arbitraria de parametros, no solo el decorador de sandobox, lo mismo con decorate_object, por lo que pueden ser usados para decorar cualquier cosa con cualquier decorador.

para los curiosos que quieren ver el codigo, aca esta:

import types
import inspect
import functools

class sandbox(object):
'''decorator that will catch the exceptions of type
exception_type and call the callback passing the function, the
exception type and the exception object as parameters'''

def __init__(self, callback, exception_type=Exception):
self.callback = callback
self.exception_type= exception_type

def __call__(self, function):
@functools.wraps(function)
def wrapper(*args, **kwds):
try:
return function(*args, **kwds)
except self.exception_type, exception:
self.callback(function, self.exception_type, exception)

return wrapper

# wtf?
def meta_decorator(decorator, *args, **kwds):
'''return a metaclass that used on a class will decorate
all the methods of the *class* with the decorator
passing args and kwds to the decorator'''

class MetaDecorator(type):
def __init__(cls, name, bases, dct):
type.__init__(cls, name, bases, dct)
methods = [x for x in dct if isinstance(dct[x],
types.FunctionType)]

dec = decorator(*args, **kwds)

for method in methods:
setattr(cls, method, dec(getattr(cls, method)))

return MetaDecorator

class MethodSandbox(object):
'''wrap a method with the sandbox decorator and return a callable
object that is almost identical to the method'''

def __init__(self, method, callback, exception_type=Exception):
functools.update_wrapper(self, method)
self.method = method
self.callback = callback
self.exception_type = exception_type

def __call__(self, *args, **kwds):
try:
return self.method(*args, **kwds)
except self.exception_type, exception:
self.callback(self.method, self.exception_type, exception)

def decorate_object(obj, decorator, *args, **kwds):
'''wrap all the obj methods with the sandbox decorator,
and calling the callback parameter when an exception is raised
it decorates all the methods on an *object*'''
dec = decorator(*args, **kwds)

[setattr(obj, method, dec(getattr(obj, method)))\
for method in dir(obj) if inspect.ismethod(getattr(obj, method))]

nicevte 0.1 :P

en el post anterior les comente de evilvte, bueno, hice un minifork para arreglar un bug (cuando cerraba dejaba el proceso corriendo), agregue el boton cerrar a cada tab, agregue scroll cuando los tabs son mas largos que la ventana, tabs reordenables y tabs que se expanden hasta ocupar toda la pantalla.

que le falta? que el boton de cerrar no haga el tab tan largo.

screenshot obligado :P


copia esto de aca abajo en una terminal:

wget http://marianoguerra.com.ar/nicevte-0.1.tar.gz && tar -xzf nicevte-0.1.tar.gz && cd nicevte-0.1 && ./configure && make && sudo make install && evilvte

lo baja lo desempaca, lo configura, lo compila, lo instala y lo corre, eso es user friendlyness :P

PD: si, el binario se sigue llamando evilvte, cosas de la vida ;)

user friendlyness

an VTE based super lightweight terminal emulator

evilvte is a terminal emulator. It supports almost everything VTE provides.
It also supports tabs, tabbar autohide, and switch encoding at runtime.
Configuration is via editing source code and recompilation.

http://www.calno.com/evilvte/

fuera de eso, esta genial, liviana, levanta al instante, buen reemplazo de xterm con lo que se le extraña en xterm de gnome-terminal (tabs y colores como la gente)

otra vez lavoz.com.ar

titulo: Robots asesinos
nota al pie de la imagen: ROBOTS. En realidad, son pequeños tanques operados a control remoto por soldados

eso si que es periodismo serio.

le recomiendo otros titulares

enfermedad mortal incurable se exparse por el mundo
bah, en realidad es la gripe

hombre mueve objetos con la mente
mmmh, digamos que lo mueve con un hilo y no te das cuenta

boca goleo a river 6 a 0
no, en realidad jugo con estudiantes y empataron.

Bordes redondeados en fluxbox

me negaba a empezar a estudiar sin bordes redondeados en fluxbox (?), por desgracia los muchachos de ubuntu lo compilan sin soporte para bordes redondeados asi que lo tuve que hacer yo.

la receta:

wget http://surfnet.dl.sourceforge.net/sourceforge/fluxbox/fluxbox-1.0.0.tar.gz
tar -xvzf fluxbox-1.0.0.tar.gz
cd fluxbox-1.0.0/
sudo aptitude install libimlib2-dev xlibs-dev libxft-dev libxpm-dev
./configure --enable-imlib2 --enable-nls --enable-xft --enable-xpm --enable-shape --enable-render
make
sudo make install
vim /home/mariano/.fluxbox/startup # cambiar /usr/bin/fluxbox por /usr/local/bin/fluxbox

y listo..

Porque me gusta el software libre

* Quiero subir mis albums a picasa
* Picasa no soporta subir cantidades de fotos a albums en linux
* Busco un proyecto que lo haga
* No lo encuentro
* Busco como hacerlo y lo hago
* Funciona
* Quiero agregarle soporte para Thumbails
* Busco algun proyecto que haga eso
* Encuentro uno
* Le mando mi codigo
* Lo agrega a su proyecto

Ya tengo visor de imagenes multiplataforma para administrar mi album web de picasa.



El proyecto (http://www.kiyut.com/products/ekspos/index.html) es un visor de imagenes multiplataforma escrito en java, ahora soporta seleccionar fotos y subirlas a tu album web de picasa, su licencia es BSD, por lo cual tuve que cambiar la licencia de mi codigo.

si tienen el mismo problema que yo, ya esta solucionado :)

como hacer algo simple de la manera complicada

class Kiace(object):
pass

kiace = Kiace()

for (num, l) in enumerate("kiace"):
setattr(kiace, l, (num, l))

l = [getattr(kiace, name) for name in dir(kiace) if not name.startswith('_')]
l.sort(cmp = lambda x, y: x[0] - y[0])

print ''.join([x[1] for x in l])


basicamente imprime kiace creando un objeto vacio, le agrega atributos, despues obtiene los atributos y los ordena para imprimir kiace

(?)

en realidad es una excusa para probar el resaltado de sintaxis HTML que nos proveen los muchachos de dpaste.com ;)

No me quedo atras!

como se puede leer en http://www.cesarius.net/desarrollador-de-amarok-se-tatua-el-logo-en-el-brazo/ el desarrollador de amarok se tatuó el logo de su proyecto en el brazo, tuza (mi nuevo asistente de marketing para america latina) me mando una propuesta para que evalúe, se las pongo acá a ver que les parece:

lavoz.com.ar informacion confiable? al instante

titulo del articulo (por si lo cambian)

El fraude a Société Générale alcanzó los 50 millones de euros

titulo de clarin

Francia: Société Générale admitió que el fraude llegó a alcanzar los 50.000 millones de euros

primer párrafo de la nota en lavoz.com.ar

El presunto autor del fraude multimillonario contra Société Générale, uno de los mayores bancos de Francia, compró activos por un valor que alcanzó los 50.000 millones de euros

se les olvidaron unos ceros..

Instalar solaris [Done]

Siempre quise probar solaris, y hoy llego el CD que había pedido hace unas semanas, así que no pude evitar gastar mi escaso tiempo en instalarlo, acá van una serie de observaciones y screenshots.

Observaciones:

  • Bootea en modo texto: no es para quejarse, un usuario que quiere ver eye candy no va a instalar solaris, pero mi examen es compararlo con ubuntu así que voy a notar las diferencias.
  • 768 MB de RAM para la instalación gráfica: no se si es bueno o malo, pero me obligo a ponerle los 512 MB que tenia por ahí :)
  • Aunque eleji la instalación gráfica el teclado se configura en una interfaz en ncurses.
  • En la seleccion de particiones, no puedo cambiar el tipo de partición a solaris si hay dos particiones del mismo tipo (WTF?).
  • Durante la instalación no hay información detallada sobre que esta haciendo, mas que un mensaje de "Instalando Solaris".
  • La consola de debug, que esta media escondida, es una consola en motif (feo), que no autocompleta y tiene el delete configurado raro.
  • La instalación demora casi 3 horas.
  • Grub se instalo sin detectarme ubuntu, ahora lo único que puedo bootear es solaris.
  • Cuando seleccionas reiniciar o apagar en cualquier lado, se demora mas de un minuto en hacerlo y no da ninguna información de que en realidad esta haciendo lo que le pediste (tanto en la instalación como en el uso del escritorio)
  • No tiene documentación offline, asume que tu red es dhcp y no te deja configurarla en ningún momento durante la instalación. Cuando booteas y vas a Administración -> Redes te dice que no se puede mostrar porque esta habilitado no se que cosa y que para usarla la tenes que deshabilitar (te dice que leas el man para deshabilitarlo).
  • No tengo sonido (aunque para ser una notebook, detecto todo el resto del hardware bastante bien)
  • La consola de root no es bash :S
  • CDE es horrible! (uso gnome 2.18)
  • A diferencia de MS, Sun si usa su lenguaje (Java) para sus aplicaciones.
  • tiene svn, python 2.4.4 y pygtk instalado.
  • emesene funciona una pinturita :P.
  • El look&feel es bastante bonito.
Bueno, basta de observaciones y a los screenshots! :P