Je suis un grand amateur de vin et après m’être essayé au livre de cave papier (rébarbatif il va s’en dire) pour gérer le stocks de bouteilles de ma cave à vin, j’ai cherché et essayé nombre d’application (sous Linux il va s’en dire).
Malheureusement, je n’ai jamais trouvé mon bonheur, même si OpenCellar était quand même ce que j’avais trouvé de mieux.
J’ai donc profité de mon week-end pour mettre en place une gestion de cave à vins qui convient à mes besoins (et aux vôtres aussi peut être :))
J’attendais plusieurs choses d’une « application » de gestion de cave à vins et je suis surpris de ne rien trouver d’adéquat (ou alors j’ai mal cherché et je suis ouvert à vos suggestions :))
– une application légère (donc en mode web)
– fonctionnant sous Linux (donc le prérequis précédent convient)
– fonctionnant en local (pas de cloud machin truc)
– permettant l’ajout et le retrait de bouteille avec son smartphone (car se rendre dans la cave à vin, choisir la bouteille, puis aller sur son pc ou son portable, ouvrir le site web, retirer la bouteille, c’est un peu lourd, alors que le smartphone, on l’a souvent avec soi)
N’étant pas un grand développeur web dans l’âme (ni avec mes doigts d’ailleurs), j’ai d’abord cherché une base de site sur laquelle commencer car je n’avais pas vraiment envie de passer plusieurs heures a faire du css, du div et toute la joie inhérente à ce genre d’application.
J’ai trouvé les projets de Christophe Coenraets sur Github qui à écrit plusieurs articles et applications pour gérer sa cave à vin (je vous invite d’ailleurs à lire ses billets à ce sujet (http://coenraets.org/blog/2011/12/restful-services-with-jquery-php-and-the-slim-framework/ , http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/ , http://coenraets.org/blog/2012/01/using-backbone-js-with-a-restful-java-back-end/).
Mon choix s’est porté sur sa version PHP, plus léger pour moi à mettre en œuvre.
Le plus de son application, c’est la présence d’une API permettant d’ajouter, mettre à jour ou lister le contenu de sa cave (oh voui j’adore ça lister mes vins avec un curl -i -X GET http://localhost/cellar/api/wines 😀 )
Je ne vous ferais pas l’affront de la mise en place du dépôt sous votre serveur web fétiche (penser à activer les méthodes PUT,DELETE et POST), cela coule de source.
On peuple la base et voila le premier résultat (a peu près, la c’est ma version modifiée)
Car oui j’ai d’abord modifié quelques fonctions.
Pour gérer les bouteilles avec mon smartphone, j’ai d’abord pensé à des étiquettes RFID, mais avec le nombre de précieux flacons, j’allais exploser mon budget « loisir« .
Donc mon choix s’est plutôt tourné vers un élément que l’on retrouve « presque » sur toutes les bouteilles, le code barre (ou EAN 13 pour les puristes).
Dans l’ensemble, j’ai très peu de bouteilles sans, principalement des achats direct au producteur, donc ne saisir qu’une infime quantité de stock à la mimine m’allait parfaitement (au pire, je pourrais faire du RFID avec elles).
NB: Dans ma folie habituelle, je vous avouerais être d’abord parti sur de la reconnaissance de l’étiquette avec OpenCV et de l’OCR mais vu l’ampleur du projet, je me suis vite raisonné 😀
Mes premières modifications apportées sur le code : ajout du champ EAN, traduction des champs, modification de la recherche sur la région en plus du nom et ajout d’un champ quantité.
Mes premiers tests de l’API était sympa mais il m’en fallait plus.
Etant plus à l’aise avec Python que PHP ou JavaScript, j’ai rapidement codé ma propre API.
Celle ci permet plusieurs choses :
– POSTer le code EAN d’une bouteille et la créer si besoin (en mettant la quantité à 1 par défaut et en lui affectant l’image ‘codeEAN’.png), si le code existe, ajouter +1 à la quantité. Possibilité également de faire -1 sur la quantité.
class addean: def POST(self,uri): try : ID = web.data() except: return web.badrequest() con = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqlpasswd, db=mysqldb); cur = con.cursor() print ID cur.execute("""SELECT * from wine where EAN=%s""", (ID,)) result = cur.fetchone() if result is None: print "no bottle" print ID data = {'EAN': ID, 'picture': ID+'.png'} data = json.dumps(data) req = urllib2.Request(url, data, {'Content-Type': 'application/json'}) f = urllib2.urlopen(req) response = f.read() f.close() else: cur.execute("""UPDATE wine SET nombre=(nombre+1) where EAN=%s""", (ID,)) con.commit() print "Number of rows updated: %d" % cur.rowcount con.close() class removeean: def POST(self,uri): try : ID = web.data() except: return web.badrequest() con = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqlpasswd, db=mysqldb); cur = con.cursor() print ID cur.execute("""SELECT * from wine where EAN=%s""", (ID,)) result = cur.fetchone() if result is None: print "new bottle" print ID data = {'EAN': ID, 'picture': ID+'.png'} data = json.dumps(data) req = urllib2.Request(url, data, {'Content-Type': 'application/json'}) f = urllib2.urlopen(req) response = f.read() f.close() else: cur.execute("""UPDATE wine SET nombre=(nombre-1) where EAN=%s""", (ID,)) con.commit() print "Number of rows updated: %d" % cur.rowcount con.close() |
– POSTer la photo de l’étiquette et l’inclure dans la fiche.
class index: def POST(self,uri): try: web.cookies().filename filenamereceived = web.cookies().filename except: filenamereceived == "generic" try : data = web.data() except: return web.badrequest() if data == "": return web.badrequest() print filenamereceived b64response = base64.b64encode(data) fh = open(winepics+filenamereceived+".png", "wb") fh.write(b64response.decode('base64')) fh.close() return "200 STORED" |
Maintenant que mon API était prête, il fallait pouvoir utiliser le smartphone.
La meilleure application d’automatisation sous android est pour moi Tasker. De plus, de nombreux plugins existent et l’un des maîtres du plugin Tasker est sûrement João Dias alias joaomgcd.
J’utilise quasiment tout ses plugins (qui ne coûte pas grand chose pour une efficacité redoutable, dont le fameux AutoRemote) et en cherchant un plugin « barcode » (code barre) pour Tasker, et bien il existe AutoBarcode ! Magique, ce type est un génie 😀
Un peu de « codage » Tasker pour réaliser ce que je veux :
Lancer un scan de code barre,
une fois effectué, lancer une « scène » Tasker me demandant si je veux ajouter ou retirer cette bouteille :
– je retire, je fais -1 sur la quantité
– j’ajoute, je fais +1 si le code EAN existe, sinon j’appelle l’API du site pour créer la bouteille avec son code EAN. Je continue en demandant si je veux ajouter une photo, si non, je sors, si oui, je lance l’appareil photo qui me permet de photographier l’étiquette et de la POSTer en la nommant ‘codeEAN’.png.
Bien sur la création de la bouteille lie automatiquement l’image à l’url ../pics/’codeEAN’.png.
Il ne me reste alors qu’a me rendre sur le site web pour compléter la fiche de la bouteille.
En quelques heures, j’ai enfin pu me créer un site de gestion de ma cave à vin efficace et qui répond à mes besoins.
L’ajout ou le retrait d’une bouteille se fait avec le smartphone en premier lieu (on peut le faire sur le site aussi).
Si vous voulez vous aussi déployer ce genre d’application chez vous, j’ai bien évidemment tout mis sur mon Github en forkant le projet de Christophe et en y ajoutant les éléments nécessaires 😀
Amusez vous bien 🙂