written by nicoe, on May 19, 2010 10:03:00 PM.
At work we have a project to realize a pygtk POS interface for OpenERP. It is getting closer and closer everyday and after much hagglings to create the right UI, I had to connect it to the underlying server. Using the so called netrpc protocol out of the box is not really the most pythonic you can get.
So I came up with those classes that made me fells just like home when I needed to work with the OpenERP objects.
class MetaOEObject(type):
def __init__(cls, name, bases, dict):
super(MetaOEObject, cls).__init__(name, bases, dict)
cls.proxy = Config.client.create_proxy(Config.database,
dict['dotted_name'])
cls.fields = cls.proxy.fields_get()
OEObject.proxies[dict['dotted_name']] = cls
class OEObject(object):
proxies = {}
def __init__(self, id=None):
self.id = id
if id is not None:
self.value = self.proxy.read(id)
@classmethod
def select(cls, condition):
ids = cls.proxy.search(condition)
return [cls(id) for id in ids]
def __getattr__(self, name):
if name not in self.fields:
raise AttributeError
elif self.fields[name]['type'] == 'many2one':
oeobj = OEObject.proxies[self.fields[name]['relation']]
if self.value[name]:
return oeobj(self.value[name][0])
else:
return None
elif self.fields[name]['type'] == 'one2many':
oeobj = OEObject.proxies[self.fields[name]['relation']]
return [oeobj(id) for ids in self.value[name]]
elif self.fields[name]['type'] == 'binary':
if not self.value[name]:
return None
filename = os.tempnam()
fd = open(filename, 'w')
fd.write(base64.b64decode(self.value[name]))
fd.flush()
return filename
return self.value[name]
def __str__(self):
print self.dotted_name, self.id
return '<%s (%d)>' % (self.dotted_name, self.id)
class Category(OEObject):
__metaclass__ = MetaOEObject
dotted_name = 'product.category'
class Product(OEObject):
__metaclass__ = MetaOEObject
dotted_name = 'product.product'
Those kind of classes makes use of metaclasses so that proxy and fields are class-attributes which seems nicer to me.
It allows me write pieces of code like this
for category in Category.select([('parent_id', '=', None)]):
page = self.create_category_page(category, notebook)
for product in Product.select([('categ_id', '=', category.id)]):
page.add_product(product)
Which populates a GtkIconView into a notebook used to display products sorted by categories.
Categories:
en, openerp, programming, python |
3 comments
written by nicoe, on May 19, 2010 8:57:00 AM.
J'ai enfin décidé d'utiliser les propriétés de lecteur MP3 de mon Nokia.
Le déclic ce fut l'importation des 45 CDs achetés lors la (triste) liquidation de Caroline Musique. Il faut que je trouve du temps pour écouter tout ça ! Temps tout trouvé puisque je passe vingt cinq minutes dans le bus tous les matins.
libmtp est bien faite et détecte mon téléphone malheureusement soit elle, soit rhythmbox est incapable de transférer les fichiers musicaux correctement puisqu'ils ne respectent pas la hiérarchie Artiste/Album. Tant pis, je l'utilise alors en mass-storage et j'ajoute le fichier .is_audio_player suivant permettant à rhythmbox de correctement transcoder mes précieux flac en mp3 parfaitement compréhensibles par mon GSM.
audio_folders=Music/
folder_depth=2
output_formats=audio/mpeg
Categories:
fr, music |
0 comments
written by nicoe, on May 17, 2010 5:37:00 PM.
Après quelques mois de mort clinique, ce blog est reparti.
Pour combien de temps, nous verrons.
Categories:
fr, vis ta vie |
0 comments
written by nicoe, on Sep 25, 2009 8:15:00 PM.
Avec la sortie de la nouvelle version du bureau GNOME arrive la fonctionnalité que j'attendais vraiment : le passage à WebKit d'epiphany.
WebKit c'est un moteur de rendu Web. WebKit c'est aussi un troll (mourrant) sur l'implication d'Apple dans le logiciel libre car ce moteur est basé sur KHTML et la collaboration entre l'équipe de KDE et celle de la Pomme n'a pas toujours été parfaite.
Mais WebKit c'est surtout une bibliothèque ultra-rapide, j'ai l'impression de revivre et que le net va 5× plus vite depuis que je l'utilise.
Categories:
fr, geek, internet, planetlibre |
0 comments
written by nicoe, on Aug 28, 2009 9:12:00 PM.
Et le voila, cet hymne qu'on attendait depuis si longtemps. Il va retentir dans le stade à l'affiche de FIFA 2010.
Le tirage avait lieu hier, et on est maintenant fixé sur les adversaires du Standard :
Toutes les équipes jouent en rouge et blanc, ce sera l'occasion de voir nos joueurs avec le maillot brun. C'est pas plus mal. Et l'un dans l'autre, le tirage est relativement abordable. Ça pourrait le faire.
Demain rendez-vous à Sclessin pour choper des places pour les trois matches.
EDIT: C'est fait j'ai mes places ! 20 minutes de file, seulement 5 personnes devant moi, le rêve du à une communication très approximative du Standard.
Categories:
football, fr |
0 comments
written by nicoe, on Aug 25, 2009 12:58:00 PM.
Mon appartement est complètement sous eaux pour l'instant. En conséquence, et il en était grand temps, je suis à la recherche d'un nouvel appartement.
Immoweb, me voilà ! Mes critères : de préférence un jardin, un balcon est le minimum minimorum, pas trop loin du centre ville. J'en ai repéré quelques uns, on va voir ce qu'on va voir.
Categories:
fr, vis ta vie |
0 comments
written by nicoe, on Aug 20, 2009 11:10:00 PM.
Résumons nous: le Pukkelpop a comme a son habitude une affiche du tonnerre (Faith No More, Them Crooked Vultures, Squarepusher, Dinosaur Jr, Kraftwerk, et j'en passe).
Et pour illuster cela, lesoir en ligne nous propose un slideshow avec des photos de Ghinzu (qui est passé de 13:50 à 14:30).
Je commence à en avoir marre là. Faire la promotion des groupes locaux, c'est bien, ça peut même faire éclore des vocations. Mais avec Ghinzu on frise l'overdose, n'en jettez plus ! Ils n'ont plus besoin de l'aide des médias pour cartonner (du moins chez nous) et laissons faire : on verra bien si le soufflé prendra.
Categories:
belgique, fr, music, rants |
0 comments
written by nicoe, on Aug 14, 2009 8:18:00 AM.
Il est amusant de constater que Guido utilise print pour déboguer son code (via Matt Harrison).
Je pense que c'est ainsi que fonctionnent 90% des gens qui travaillent en python : pas de Visual Studio Integrated FX 3000 Pouet Pouet, dans des cas extrèmes pdb vient à notre secours. L'essentiel du temps de déboguage est passé à tester (avec py.test pourquoi pas) ou dans une console ipython. Ça nous suffit et cette config explique très bien pourquoi vim et emacs sont les éditeurs les plus répandus dans la communauté.
Categories:
fr, planetlibre, python |
0 comments
written by nicoe, on Aug 9, 2009 8:06:00 AM.
À cause de quelques problèmes de performances, j'ai finallement décidé de me passer de banshee. Et comme on peut le voir avec la commande debtags suivante, le choix n'est pas immense :
kinder:~% debtags search 'works-with-format::oggvorbis &&
uitoolkit::gtk && use::playing &&
! (implemented-in::c-sharp || implemented-in::python)'
alsaplayer-gtk - PCM player designed for ALSA (GTK version)
ardour - digital audio workstation (graphical gtk2 interface)
audacious - small and fast audio player which supports lots of formats
gecko-mediaplayer - Media plug-in for Gecko browsers
geekast - GNOME interface to peercast
geekast-binary - GNOME interface to peercast - binaries
gnome-mplayer - A simple GUI for MPlayer
mplayer - movie player for Unix-like systems
quark - music player daemon controlled from the gnome panel or cli
rhythmbox - music player and organizer for GNOME
somaplayer - player audio for the soma suite
somaplayer-doc - documentation for somaplayer
totem-gstreamer - A simple media player for the GNOME desktop based on GStreamer
totem-xine - A simple media player for the GNOME desktop based on xine
Je suis donc de retour après quelques années de MPD, Quodlibet et autre Banshee sous Rhythmbox. Évidemment entre temps, j'ai attribué des notes à pas mal de morceaux et je ne veux pas perdre ces informations. C'est pourquoi j'ai concocté le petit script suivant :
# -*- encoding: utf8 -*-
import os
import sys
import sqlite3
import urllib
from lxml import etree
RMB_FILE = os.path.expanduser('~/.local/share/rhythmbox/rhythmdb.xml')
XPATH_EXPR = "//entry[@type='song']/location[contains(., '%s')]"
xml_tree = etree.parse(RMB_FILE)
conn = sqlite3.connect(sys.argv[1])
cursor = conn.cursor()
cursor.execute('select uri, rating from coretracks')
for uri, rating in cursor:
if rating == 0:
continue
try:
quoted_uri = urllib.quote(uri.encode('utf8', 'ignore'),
safe="/()+&,!=")
loc_node = xml_tree.xpath(XPATH_EXPR % quoted_uri)[0]
entry = loc_node.getparent()
if not entry.find('rating'):
score = etree.Element('rating')
score.text = '%s' % rating
entry.append(score)
except IndexError:
print >> sys.stderr, '%s (score: %s) not added' % (uri, rating)
continue
print etree.tostring(xml_tree)
Il sortira sur stdin, le nouveau fichier XML utilisable avec rhythmbox et prend en argument le fichier banshee.
Categories:
fr, music, planetlibre |
2 comments
written by nicoe, on Aug 8, 2009 6:39:00 PM.
Avec les changements dont je parlais précédemment, je vais revoir le contenu de mon (je suppose que maintenant je peux utiliser la première personne) site Web.
Première étape: j'ai décidé de migrer le moteur de blog à zine. Celui-ci est écrit en python, m'apparaît très simple à utiliser et la migration s'est déroulée sans trop de soucis puisqu'il supporte l'importation de feed atom. La procédure d'installation est détaillée dans ce sujet du forum de mon hébergeur (l'excellent webfaction).
Techniquement zine est une application WSGI baséé sur werkzeug, ce qui devrait garantir une certaine flexibilité. D'ailleurs un ensemble de plugins existent déjà et j'utilise par exemple celui permettant d'écrire en restructured text.
Quelques manipulations maladroites de Gimp et un peu de chipotages avec la feuille de style, voici le résultat.
Categories:
fr, geek, planetlibre, python |
2 comments