{"id":1800,"date":"2016-10-31T19:32:09","date_gmt":"2016-10-31T18:32:09","guid":{"rendered":"http:\/\/blog.guiguiabloc.fr\/?p=1800"},"modified":"2016-10-31T21:58:32","modified_gmt":"2016-10-31T20:58:32","slug":"gestion-dune-cave-a-vins-avec-tasker-et-python","status":"publish","type":"post","link":"http:\/\/blog.guiguiabloc.fr\/index.php\/2016\/10\/31\/gestion-dune-cave-a-vins-avec-tasker-et-python\/","title":{"rendered":"Gestion d&rsquo;une Cave \u00e0 vins avec Tasker et Python"},"content":{"rendered":"<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/winecellar.png\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1802\" alt=\"winecellar\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/winecellar-300x234.png\" width=\"300\" height=\"234\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/winecellar-300x234.png 300w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/winecellar.png 350w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Je suis un grand amateur de vin et apr\u00e8s m&rsquo;\u00eatre essay\u00e9 au livre de cave papier (r\u00e9barbatif il va s&rsquo;en dire) pour g\u00e9rer le stocks de bouteilles de ma cave \u00e0 vin, j&rsquo;ai cherch\u00e9 et essay\u00e9 nombre d&rsquo;application (sous Linux il va s&rsquo;en dire).<br \/>\nMalheureusement, je n&rsquo;ai jamais trouv\u00e9 mon bonheur, m\u00eame si<a title=\"http:\/\/www.open-cellar.com\/\" href=\"http:\/\/www.open-cellar.com\/\" target=\"_blank\"> OpenCellar<\/a> \u00e9tait quand m\u00eame ce que j&rsquo;avais trouv\u00e9 de mieux.<br \/>\nJ&rsquo;ai donc profit\u00e9 de mon week-end pour mettre en place une gestion de cave \u00e0 vins qui convient \u00e0 mes besoins (et aux v\u00f4tres aussi peut \u00eatre :))<\/p>\n<p>J&rsquo;attendais plusieurs choses d&rsquo;une \u00ab\u00a0application\u00a0\u00bb de gestion de cave \u00e0 vins et je suis surpris de ne rien trouver d&rsquo;ad\u00e9quat (ou alors j&rsquo;ai mal cherch\u00e9 et je suis ouvert \u00e0 vos suggestions :))<\/p>\n<p>&#8211; une application l\u00e9g\u00e8re (donc en mode web)<br \/>\n&#8211; fonctionnant sous Linux (donc le pr\u00e9requis pr\u00e9c\u00e9dent convient)<br \/>\n&#8211; fonctionnant en local (pas de cloud machin truc)<br \/>\n&#8211; permettant l&rsquo;ajout et le retrait de bouteille avec son smartphone (car se rendre dans la cave \u00e0 vin, choisir la bouteille, puis aller sur son pc ou son portable, ouvrir le site web, retirer la bouteille, c&rsquo;est un peu lourd, alors que le smartphone, on l&rsquo;a souvent avec soi)<\/p>\n<p>N&rsquo;\u00e9tant pas un grand d\u00e9veloppeur web dans l&rsquo;\u00e2me (ni avec mes doigts d&rsquo;ailleurs), j&rsquo;ai d&rsquo;abord cherch\u00e9 une base de site sur laquelle commencer car je n&rsquo;avais pas vraiment envie de passer plusieurs heures a faire du css, du div et toute la joie inh\u00e9rente \u00e0 ce genre d&rsquo;application.<\/p>\n<p>J&rsquo;ai trouv\u00e9 les projets de <a title=\"http:\/\/coenraets.org\/blog\/\" href=\"http:\/\/coenraets.org\/blog\/\" target=\"_blank\">Christophe Coenraets<\/a> sur <a title=\"https:\/\/github.com\/ccoenraets\" href=\"https:\/\/github.com\/ccoenraets\" target=\"_blank\">Github<\/a> qui \u00e0 \u00e9crit plusieurs articles et applications pour g\u00e9rer sa cave \u00e0 vin (je vous invite d&rsquo;ailleurs \u00e0 lire ses billets \u00e0 ce sujet (<a title=\"http:\/\/coenraets.org\/blog\/2011\/12\/restful-services-with-jquery-php-and-the-slim-framework\/\" href=\"hthttp:\/\/coenraets.org\/blog\/2011\/12\/restful-services-with-jquery-php-and-the-slim-framework\/tp:\/\/\" target=\"_blank\">http:\/\/coenraets.org\/blog\/2011\/12\/restful-services-with-jquery-php-and-the-slim-framework\/<\/a> , <a title=\"http:\/\/coenraets.org\/blog\/2011\/12\/restful-services-with-jquery-and-java-using-jax-rs-and-jersey\/\" href=\"http:\/\/coenraets.org\/blog\/2011\/12\/restful-services-with-jquery-and-java-using-jax-rs-and-jersey\/\" target=\"_blank\">http:\/\/coenraets.org\/blog\/2011\/12\/restful-services-with-jquery-and-java-using-jax-rs-and-jersey\/<\/a> , <a title=\"http:\/\/coenraets.org\/blog\/2012\/01\/using-backbone-js-with-a-restful-java-back-end\/\" href=\"http:\/\/coenraets.org\/blog\/2012\/01\/using-backbone-js-with-a-restful-java-back-end\/\" target=\"_blank\">http:\/\/coenraets.org\/blog\/2012\/01\/using-backbone-js-with-a-restful-java-back-end\/<\/a>).<br \/>\nMon choix s&rsquo;est port\u00e9 sur<a title=\"https:\/\/github.com\/ccoenraets\/wine-cellar-php\" href=\"https:\/\/github.com\/ccoenraets\/wine-cellar-php\" target=\"_blank\"> sa version PHP<\/a>, plus l\u00e9ger pour moi \u00e0 mettre en \u0153uvre.<br \/>\nLe plus de son application, c&rsquo;est la pr\u00e9sence d&rsquo;une API permettant d&rsquo;ajouter, mettre \u00e0 jour ou lister le contenu de sa cave (oh voui j&rsquo;adore \u00e7a lister mes vins avec un curl -i -X GET http:\/\/localhost\/cellar\/api\/wines \ud83d\ude00 )<\/p>\n<p>Je ne vous ferais pas l&rsquo;affront de la mise en place du d\u00e9p\u00f4t sous votre serveur web f\u00e9tiche (penser \u00e0 activer les m\u00e9thodes PUT,DELETE et POST), cela coule de source.<\/p>\n<p>On peuple la base et voila le premier r\u00e9sultat (a peu pr\u00e8s, la c&rsquo;est ma version modifi\u00e9e)<\/p>\n<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine1.png\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1804\" alt=\"screenwine1\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine1-300x240.png\" width=\"300\" height=\"240\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine1-300x240.png 300w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine1-900x720.png 900w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine1.png 1020w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>Car oui j&rsquo;ai d&rsquo;abord modifi\u00e9 quelques fonctions.<br \/>\nPour g\u00e9rer les bouteilles avec mon smartphone, j&rsquo;ai d&rsquo;abord pens\u00e9 \u00e0 des <a title=\"https:\/\/www.amazon.co.uk\/Stickers-label-LARGE-CAPACITY-smartphones\/dp\/B008IJN4JE\/ref=pd_day0_23_8?_encoding=UTF8&amp;psc=1&amp;refRID=8WT308PXMVECJGD177CC\" href=\"https:\/\/www.amazon.co.uk\/Stickers-label-LARGE-CAPACITY-smartphones\/dp\/B008IJN4JE\/ref=pd_day0_23_8?_encoding=UTF8&amp;psc=1&amp;refRID=8WT308PXMVECJGD177CC\" target=\"_blank\">\u00e9tiquettes RFID<\/a>, mais avec le nombre de pr\u00e9cieux flacons, j&rsquo;allais exploser mon budget \u00ab\u00a0<a title=\"NON, ne clique pas !!!\" href=\"http:\/\/www.pornhub.com\/\" target=\"_blank\">loisir<\/a>\u00ab\u00a0.<br \/>\nDonc mon choix s&rsquo;est plut\u00f4t tourn\u00e9 vers un \u00e9l\u00e9ment que l&rsquo;on retrouve \u00ab\u00a0presque\u00a0\u00bb sur toutes les bouteilles, le code barre (ou<a title=\"https:\/\/fr.wikipedia.org\/wiki\/EAN_13\" href=\"https:\/\/fr.wikipedia.org\/wiki\/EAN_13\" target=\"_blank\"> EAN 13<\/a> pour les puristes).<br \/>\nDans l&rsquo;ensemble, j&rsquo;ai tr\u00e8s peu de bouteilles sans, principalement des achats direct au producteur, donc ne saisir qu&rsquo;une infime quantit\u00e9 de stock \u00e0 la mimine m&rsquo;allait parfaitement (au pire, je pourrais faire du RFID avec elles).<\/p>\n<p>NB: Dans ma folie habituelle, je vous avouerais \u00eatre d&rsquo;abord parti sur de la reconnaissance de l&rsquo;\u00e9tiquette avec<a title=\"http:\/\/opencv.org\/\" href=\"http:\/\/opencv.org\/\" target=\"_blank\"> OpenCV <\/a>et de <a title=\"https:\/\/fr.wikipedia.org\/wiki\/Reconnaissance_optique_de_caract%C3%A8res\" href=\"https:\/\/fr.wikipedia.org\/wiki\/Reconnaissance_optique_de_caract%C3%A8res\" target=\"_blank\">l&rsquo;OCR<\/a> mais vu l&rsquo;ampleur du projet, je me suis vite raisonn\u00e9 \ud83d\ude00<\/p>\n<p>Mes premi\u00e8res modifications apport\u00e9es sur le code : ajout du champ EAN, traduction des champs, modification de la recherche sur la r\u00e9gion en plus du nom et ajout d&rsquo;un champ quantit\u00e9.<\/p>\n<p>Mes premiers tests de l&rsquo;API \u00e9tait sympa mais il m&rsquo;en fallait plus.<br \/>\nEtant plus \u00e0 l&rsquo;aise avec Python que PHP ou JavaScript, j&rsquo;ai rapidement cod\u00e9 ma propre API.<\/p>\n<p>Celle ci permet plusieurs choses :<br \/>\n&#8211; POSTer le code EAN d&rsquo;une bouteille et la cr\u00e9er si besoin (en mettant la quantit\u00e9 \u00e0 1 par d\u00e9faut et en lui affectant l&rsquo;image &lsquo;codeEAN&rsquo;.png), si le code existe, ajouter +1 \u00e0 la quantit\u00e9. Possibilit\u00e9 \u00e9galement de faire -1 sur la quantit\u00e9.<\/p>\n<pre lang=\"python\">\r\nclass addean:\r\ndef POST(self,uri):\r\ntry :\r\nID = web.data()\r\nexcept:\r\nreturn web.badrequest()\r\ncon = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqlpasswd, db=mysqldb);\r\ncur = con.cursor()\r\nprint ID\r\ncur.execute(\"\"\"SELECT * from wine where EAN=%s\"\"\", (ID,))\r\nresult = cur.fetchone()\r\nif result is None:\r\nprint \"no bottle\"\r\nprint ID\r\ndata = {'EAN': ID, 'picture': ID+'.png'}\r\ndata = json.dumps(data)\r\nreq = urllib2.Request(url, data, {'Content-Type': 'application\/json'})\r\nf = urllib2.urlopen(req)\r\nresponse = f.read()\r\nf.close()\r\nelse:\r\ncur.execute(\"\"\"UPDATE wine SET nombre=(nombre+1) where EAN=%s\"\"\", (ID,))\r\ncon.commit()\r\nprint \"Number of rows updated: %d\" % cur.rowcount\r\ncon.close()\r\n\r\nclass removeean:\r\ndef POST(self,uri):\r\ntry :\r\nID = web.data()\r\nexcept:\r\nreturn web.badrequest()\r\ncon = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqlpasswd, db=mysqldb);\r\ncur = con.cursor()\r\nprint ID\r\ncur.execute(\"\"\"SELECT * from wine where EAN=%s\"\"\", (ID,))\r\nresult = cur.fetchone()\r\nif result is None:\r\nprint \"new bottle\"\r\nprint ID\r\ndata = {'EAN': ID, 'picture': ID+'.png'}\r\ndata = json.dumps(data)\r\nreq = urllib2.Request(url, data, {'Content-Type': 'application\/json'})\r\nf = urllib2.urlopen(req)\r\nresponse = f.read()\r\nf.close()\r\nelse:\r\ncur.execute(\"\"\"UPDATE wine SET nombre=(nombre-1) where EAN=%s\"\"\", (ID,))\r\ncon.commit()\r\nprint \"Number of rows updated: %d\" % cur.rowcount\r\ncon.close()\r\n<\/pre>\n<p>&#8211; POSTer la photo de l&rsquo;\u00e9tiquette et l&rsquo;inclure dans la fiche.<\/p>\n<pre lang=\"python\">\r\nclass index:\r\ndef POST(self,uri):\r\ntry:\r\nweb.cookies().filename\r\nfilenamereceived = web.cookies().filename\r\nexcept:\r\nfilenamereceived == \"generic\"\r\ntry :\r\ndata = web.data()\r\nexcept:\r\nreturn web.badrequest()\r\nif data == \"\":\r\nreturn web.badrequest()\r\nprint filenamereceived\r\nb64response = base64.b64encode(data)\r\nfh = open(winepics+filenamereceived+\".png\", \"wb\")\r\nfh.write(b64response.decode('base64'))\r\nfh.close()\r\nreturn \"200 STORED\"\r\n<\/pre>\n<p>Maintenant que mon API \u00e9tait pr\u00eate, il fallait pouvoir utiliser le smartphone.<\/p>\n<p>La meilleure application d&rsquo;automatisation sous android est pour moi <a title=\"https:\/\/play.google.com\/store\/apps\/details?id=net.dinglisch.android.taskerm&amp;hl=fr\" href=\"https:\/\/play.google.com\/store\/apps\/details?id=net.dinglisch.android.taskerm&amp;hl=fr\" target=\"_blank\">Tasker<\/a>. De plus, de nombreux plugins existent et l&rsquo;un des ma\u00eetres du plugin Tasker est s\u00fbrement<a title=\" https:\/\/joaoapps.com\/\" href=\" https:\/\/joaoapps.com\/\" target=\"_blank\"> Jo\u00e3o Dias alias joaomgcd<\/a>.<br \/>\nJ&rsquo;utilise quasiment tout ses plugins (qui ne co\u00fbte pas grand chose pour une efficacit\u00e9 redoutable, dont le fameux <a title=\"https:\/\/joaoapps.com\/autoremote\/\" href=\"https:\/\/joaoapps.com\/autoremote\/\" target=\"_blank\">AutoRemote<\/a>) et en cherchant un plugin \u00ab\u00a0barcode\u00a0\u00bb (code barre) pour Tasker, et bien il existe<a title=\"https:\/\/play.google.com\/store\/apps\/details?id=com.joaomgcd.barcode\" href=\"https:\/\/play.google.com\/store\/apps\/details?id=com.joaomgcd.barcode\" target=\"_blank\"> AutoBarcode<\/a> ! Magique, ce type est un g\u00e9nie \ud83d\ude00<\/p>\n<p>Un peu de \u00ab\u00a0codage\u00a0\u00bb Tasker pour r\u00e9aliser ce que je veux :<\/p>\n<p>Lancer un scan de code barre,<\/p>\n<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212503.png\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1805\" alt=\"Screenshot_20161030-212503\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212503-300x168.png\" width=\"300\" height=\"168\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212503-300x168.png 300w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212503-900x506.png 900w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212503.png 1024w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>une fois effectu\u00e9, lancer une \u00ab\u00a0sc\u00e8ne\u00a0\u00bb Tasker me demandant si je veux ajouter ou retirer cette bouteille :<\/p>\n<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212537.png\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1806\" alt=\"Screenshot_20161030-212537\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212537-168x300.png\" width=\"168\" height=\"300\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212537-168x300.png 168w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212537.png 576w\" sizes=\"(max-width: 168px) 100vw, 168px\" \/><\/a><\/p>\n<p>&#8211; je retire, je fais -1 sur la quantit\u00e9<br \/>\n&#8211; j&rsquo;ajoute, je fais +1 si le code EAN existe, sinon j&rsquo;appelle l&rsquo;API du site pour cr\u00e9er 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&rsquo;appareil photo qui me permet de photographier l&rsquo;\u00e9tiquette et de la POSTer en la nommant &lsquo;codeEAN&rsquo;.png.<\/p>\n<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212547.png\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1807\" alt=\"Screenshot_20161030-212547\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212547-168x300.png\" width=\"168\" height=\"300\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212547-168x300.png 168w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/Screenshot_20161030-212547.png 576w\" sizes=\"(max-width: 168px) 100vw, 168px\" \/><\/a><br \/>\nBien sur la cr\u00e9ation de la bouteille lie automatiquement l&rsquo;image \u00e0 l&rsquo;url ..\/pics\/&rsquo;codeEAN&rsquo;.png.<\/p>\n<p>Il ne me reste alors qu&rsquo;a me rendre sur le site web pour compl\u00e9ter la fiche de la bouteille.<\/p>\n<p><a href=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine2.png\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-1808\" alt=\"screenwine2\" src=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine2-300x246.png\" width=\"300\" height=\"246\" srcset=\"http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine2-300x246.png 300w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine2-900x738.png 900w, http:\/\/blog.guiguiabloc.fr\/wp-content\/2016\/10\/screenwine2.png 974w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nEn quelques heures, j&rsquo;ai enfin pu me cr\u00e9er un site de gestion de ma cave \u00e0 vin efficace et qui r\u00e9pond \u00e0 mes besoins.<br \/>\nL&rsquo;ajout ou le retrait d&rsquo;une bouteille se fait avec le smartphone en premier lieu (on peut le faire sur le site aussi).<\/p>\n<p>Si vous voulez vous aussi d\u00e9ployer ce genre d\u2019application chez vous, j&rsquo;ai bien \u00e9videmment tout mis sur<a title=\"https:\/\/github.com\/guiguiabloc\/wine-cellar-php\" href=\"https:\/\/github.com\/guiguiabloc\/wine-cellar-php\" target=\"_blank\"> mon Github<\/a> en forkant le projet de Christophe et en y ajoutant les \u00e9l\u00e9ments n\u00e9cessaires \ud83d\ude00<\/p>\n<p>Amusez vous bien \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Je suis un grand amateur de vin et apr\u00e8s m&rsquo;\u00eatre essay\u00e9 au livre de cave papier (r\u00e9barbatif il va s&rsquo;en dire) pour g\u00e9rer le stocks de bouteilles de ma cave \u00e0 vin, j&rsquo;ai cherch\u00e9 et essay\u00e9 nombre d&rsquo;application (sous Linux &hellip; <a href=\"http:\/\/blog.guiguiabloc.fr\/index.php\/2016\/10\/31\/gestion-dune-cave-a-vins-avec-tasker-et-python\/\">Read More <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[170,188],"_links":{"self":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1800"}],"collection":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/comments?post=1800"}],"version-history":[{"count":5,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1800\/revisions"}],"predecessor-version":[{"id":1812,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/posts\/1800\/revisions\/1812"}],"wp:attachment":[{"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/media?parent=1800"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/categories?post=1800"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.guiguiabloc.fr\/index.php\/wp-json\/wp\/v2\/tags?post=1800"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}