diff --git a/pingen/__init__.py b/pingen/__init__.py deleted file mode 100644 index a00e542..0000000 --- a/pingen/__init__.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Guewen Baconnier -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -import ir_attachment -import pingen -import pingen_document -import res_company - diff --git a/pingen/__openerp__.py b/pingen/__openerp__.py deleted file mode 100644 index 4390308..0000000 --- a/pingen/__openerp__.py +++ /dev/null @@ -1,119 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Guewen Baconnier -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -{ - 'name': 'pingen.com integration', - 'version': '1.0', - 'author': 'Camptocamp', - 'maintainer': 'Camptocamp', - 'license': 'AGPL-3', - 'category': 'Reporting', - 'complexity': 'easy', - 'depends': [], - 'external_dependencies': { - 'python': ['requests'], - }, - 'description': """ -Integration with pingen.com -=========================== - -What is pingen.com ------------------- - -Pingen.com is a paid online service. -It sends uploaded documents by letter post. - -Scope of the integration ------------------------- - -One can decide, per document / attachment, if it should be pushed -to pingen.com. The documents are pushed asynchronously. - -A second cron updates the informations of the documents from pingen.com, so we -know which of them have been sent. - -Configuration -------------- - -The authentication token is configured on the company's view. You can also -tick a checkbox if the staging environment (https://stage-api.pingen.com) -should be used. - -The setup of the 2 crons can be changed as well: - - * Run Pingen Document Push - * Run Pingen Document Update - -Usage ------ - -On the attachment view, a new pingen.com tab has been added. -You can tick a box to push the document to pingen.com. - -There is 3 additional options: - - * Send: the document will not be only uploaded, but will be also be sent - * Speed: priority or economy - * Type of print: color or black and white - -Once the configuration is done and the attachment saved, a Pingen Document -is created. You can directly access to the latter on the Link on the right on -the attachment view. - -You can find them in `Settings > Customization > Low Level Objets > Pingen -Documents` or in the more convenient `Documents` menu if you have installed the -`document` module. - -Errors ------- - -Sometimes, pingen.com will refuse to send a document because it does not meet -its requirements. In such case, the document's state becomes "Pingen Error" and -you will need to manually handle the case, either from the pingen.com backend, -or by changing the document on OpenERP and resolving the error on the Pingen -Document. - -When a connection error occurs, the action will be retried on the next scheduler -run. - -Dependencies ------------- - - * Require the Python library `requests `_ - * The PDF files sent to pingen.com have to respect some `formatting rules - `_. - * The address must be in a format accepted by pingen.com: the last line - is the country in English or German. - -""", - 'website': 'http://www.camptocamp.com', - 'data': [ - 'ir_attachment_view.xml', - 'pingen_document_view.xml', - 'pingen_data.xml', - 'res_company_view.xml', - 'security/ir.model.access.csv', - ], - 'tests': [], - 'installable': False, - 'auto_install': False, - 'application': True, -} diff --git a/pingen/i18n/fr.po b/pingen/i18n/fr.po deleted file mode 100644 index 8132281..0000000 --- a/pingen/i18n/fr.po +++ /dev/null @@ -1,396 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * pingen -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 6.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-11-26 10:55+0000\n" -"PO-Revision-Date: 2014-02-25 15:09+0000\n" -"Last-Translator: Yannick Vaucher @ Camptocamp \n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-06 07:28+0000\n" -"X-Generator: Launchpad (build 16996)\n" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:177 -#: code:addons/pingen/pingen_document.py:307 -#: code:addons/pingen/pingen_document.py:414 -#, python-format -msgid "Unexcepted Error when updating the status of Document %s" -msgstr "Erreur inattendue lors de la mise à jour du document %s" - -#. module: pingen -#: field:pingen.document,push_date:0 -msgid "Push Date" -msgstr "Date d'ajout" - -#. module: pingen -#: view:pingen.document:0 -msgid "Errors" -msgstr "Erreurs" - -#. module: pingen -#: field:pingen.document,pingen_id:0 -msgid "Pingen ID" -msgstr "ID Pingen" - -#. module: pingen -#: constraint:res.company:0 -msgid "Error! You can not create recursive companies." -msgstr "Error! You can not create recursive companies." - -#. module: pingen -#: field:ir.attachment,pingen_send:0 -msgid "Send" -msgstr "Envoyer" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:399 -#, python-format -msgid "Connection Error when updating the status of Document %s from Pingen" -msgstr "" -"Erreur de connexion lors de la mise à jour de l'état du document %s depuis " -"Pingen" - -#. module: pingen -#: field:pingen.document,state:0 -msgid "State" -msgstr "État" - -#. module: pingen -#: field:ir.attachment,pingen_color:0 -msgid "Type of print" -msgstr "Type d'impression" - -#. module: pingen -#: view:pingen.document:0 -msgid "Attachment" -msgstr "Attachement" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:405 -#, python-format -msgid "" -"Error when updating the status of Document %s from Pingen: \n" -"%s" -msgstr "" -"Erreur lors de la mise à jour de l'état du document %s depuis Pingen: \n" -"%s" - -#. module: pingen -#: model:ir.actions.act_window,name:pingen.act_attachment_to_pingen_document -#: field:ir.attachment,pingen_document_ids:0 -#: view:pingen.document:0 -msgid "Pingen Document" -msgstr "Document Pingen" - -#. module: pingen -#: field:pingen.document,attachment_id:0 -msgid "Document" -msgstr "Document" - -#. module: pingen -#: help:ir.attachment,pingen_send:0 -msgid "Defines if a document is merely uploaded or also sent" -msgstr "Définit si un fichier est juste ajouté ou également envoyé" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Pending" -msgstr "En attente" - -#. module: pingen -#: selection:ir.attachment,pingen_speed:0 -msgid "Economy" -msgstr "Économique" - -#. module: pingen -#: view:pingen.document:0 -msgid "Errors resolved" -msgstr "Erreurs résolues" - -#. module: pingen -#: sql_constraint:pingen.document:0 -msgid "Only one Pingen document is allowed per attachment." -msgstr "Uniquement un document Pingen est autorisé par attachement." - -#. module: pingen -#: code:addons/pingen/pingen_document.py:168 -#: code:addons/pingen/pingen_document.py:298 -#, python-format -msgid "" -"Error when asking Pingen to send the document %s: \n" -"%s" -msgstr "" -"Erreurs lors de l'envoi du document par Pingen %s: \n" -"%s" - -#. module: pingen -#: view:pingen.document:0 -msgid "Update the letter's informations" -msgstr "Mettre à jour les informations de la lettre" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Canceled" -msgstr "Annulé" - -#. module: pingen -#: selection:pingen.document,state:0 -msgid "Connection Error" -msgstr "Erreur de connexion" - -#. module: pingen -#: model:ir.actions.act_window,name:pingen.action_pingen_document -#: model:ir.ui.menu,name:pingen.menu_pingen_document -msgid "Pingen Documents" -msgstr "Documents Pingen" - -#. module: pingen -#: field:pingen.document,last_error_message:0 -msgid "Error Message" -msgstr "Message d'erreur" - -#. module: pingen -#: selection:ir.attachment,pingen_color:0 -msgid "B/W" -msgstr "N/B" - -#. module: pingen -#: field:res.company,pingen_staging:0 -msgid "Pingen Staging" -msgstr "Staging Pingen" - -#. module: pingen -#: model:ir.model,name:pingen.model_ir_attachment -msgid "ir.attachment" -msgstr "ir.attachment" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "In Sendcenter" -msgstr "Dans le Sendcenter" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Sent" -msgstr "Envoyé" - -#. module: pingen -#: field:pingen.document,post_status:0 -msgid "Post Status" -msgstr "État de la lettre" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:163 -#: code:addons/pingen/pingen_document.py:292 -#, python-format -msgid "Connection Error when asking for sending the document %s to Pingen" -msgstr "Erreur de connexion avec Pingen lors de l'envoi de %s" - -#. module: pingen -#: view:res.company:0 -msgid "Configuration" -msgstr "Configuration" - -#. module: pingen -#: view:pingen.document:0 -msgid "Data" -msgstr "Données" - -#. module: pingen -#: view:pingen.document:0 -msgid "Options" -msgstr "Options" - -#. module: pingen -#: field:res.company,pingen_token:0 -msgid "Pingen Token" -msgstr "Token Pingen" - -#. module: pingen -#: field:ir.attachment,send_to_pingen:0 -msgid "Send to Pingen.com" -msgstr "Ajouter sur Pingen.com" - -#. module: pingen -#: model:ir.model,name:pingen.model_pingen_document -msgid "pingen.document" -msgstr "pingen.document" - -#. module: pingen -#: view:pingen.document:0 -msgid "Dates" -msgstr "Dates" - -#. module: pingen -#: view:pingen.document:0 -msgid "Sendcenter" -msgstr "Sendcenter" - -#. module: pingen -#: sql_constraint:res.company:0 -msgid "The company name must be unique !" -msgstr "The company name must be unique !" - -#. module: pingen -#: field:pingen.document,parsed_address:0 -msgid "Parsed Address" -msgstr "Adresse analysée" - -#. module: pingen -#: view:ir.attachment:0 -#: view:pingen.document:0 -#: view:res.company:0 -msgid "Pingen.com" -msgstr "Pingen.com" - -#. module: pingen -#: field:pingen.document,country_id:0 -msgid "Country" -msgstr "Pays" - -#. module: pingen -#: view:ir.attachment:0 -msgid "Notes" -msgstr "Notes" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Pushed" -msgstr "Ajouté" - -#. module: pingen -#: model:ir.model,name:pingen.model_res_company -msgid "Companies" -msgstr "Compagnies" - -#. module: pingen -#: code:addons/pingen/ir_attachment.py:90 -#, python-format -msgid "The attachment %s is already pushed to pingen.com." -msgstr "L'attachement %s est déjà envoyé sur pingen.com." - -#. module: pingen -#: view:pingen.document:0 -msgid "Attached To" -msgstr "Attaché à" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:136 -#, python-format -msgid "The document does not meet the Pingen requirements." -msgstr "Le document ne remplit pas les exigences de Pingen" - -#. module: pingen -#: code:addons/pingen/ir_attachment.py:89 -#: code:addons/pingen/pingen_document.py:176 -#: code:addons/pingen/pingen_document.py:306 -#: code:addons/pingen/pingen_document.py:413 -#: view:pingen.document:0 -#, python-format -msgid "Error" -msgstr "Erreur" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:162 -#: code:addons/pingen/pingen_document.py:291 -#: code:addons/pingen/pingen_document.py:398 -#, python-format -msgid "Pingen Connection Error" -msgstr "Erreur de connexion avec Pingen" - -#. module: pingen -#: field:pingen.document,send_date:0 -msgid "Date of sending" -msgstr "Date d'envoi" - -#. module: pingen -#: selection:ir.attachment,pingen_speed:0 -msgid "Priority" -msgstr "Priorité" - -#. module: pingen -#: selection:ir.attachment,pingen_color:0 -msgid "Color" -msgstr "Color" - -#. module: pingen -#: model:ir.model,name:pingen.model_pingen_task -msgid "pingen.task" -msgstr "pingen.task" - -#. module: pingen -#: help:pingen.document,pingen_id:0 -msgid "ID of the document in the Pingen Documents" -msgstr "ID du document sur Pingen" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:167 -#: code:addons/pingen/pingen_document.py:297 -#: code:addons/pingen/pingen_document.py:404 -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -#, python-format -msgid "Pingen Error" -msgstr "Erreur Pingen" - -#. module: pingen -#: view:pingen.document:0 -msgid "Actions" -msgstr "Actions" - -#. module: pingen -#: field:pingen.document,pages:0 -msgid "Pages" -msgstr "Pages" - -#. module: pingen -#: field:pingen.document,currency_id:0 -msgid "Currency" -msgstr "Devise" - -#. module: pingen -#: field:pingen.document,cost:0 -msgid "Cost" -msgstr "Coût" - -#. module: pingen -#: view:pingen.document:0 -msgid "Push to pingen.com" -msgstr "Ajouter sur pingen.com" - -#. module: pingen -#: view:pingen.document:0 -msgid "Ask pingen.com to send the document" -msgstr "Demander à pingen.com d'envoyer le document" - -#. module: pingen -#: help:pingen.document,post_id:0 -msgid "ID of the document in the Pingen Sendcenter" -msgstr "ID du document dans le Sendcenter Pingen" - -#. module: pingen -#: field:ir.attachment,pingen_speed:0 -msgid "Speed" -msgstr "Vitesse" - -#. module: pingen -#: field:pingen.document,post_id:0 -msgid "Pingen Post ID" -msgstr "ID de lettre Pingen" - -#. module: pingen -#: help:ir.attachment,pingen_speed:0 -msgid "Defines the sending speed if the document is automatically sent" -msgstr "Définit la vitesse d'envoi si le document est automatiquement envoyé" diff --git a/pingen/i18n/pingen.pot b/pingen/i18n/pingen.pot deleted file mode 100644 index ce80661..0000000 --- a/pingen/i18n/pingen.pot +++ /dev/null @@ -1,388 +0,0 @@ -# Translation of OpenERP Server. -# This file contains the translation of the following modules: -# * pingen -# -msgid "" -msgstr "" -"Project-Id-Version: OpenERP Server 6.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-11-26 10:55+0000\n" -"PO-Revision-Date: 2012-11-26 10:55+0000\n" -"Last-Translator: <>\n" -"Language-Team: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: \n" -"Plural-Forms: \n" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:177 -#: code:addons/pingen/pingen_document.py:307 -#: code:addons/pingen/pingen_document.py:414 -#, python-format -msgid "Unexcepted Error when updating the status of Document %s" -msgstr "" - -#. module: pingen -#: field:pingen.document,push_date:0 -msgid "Push Date" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Errors" -msgstr "" - -#. module: pingen -#: field:pingen.document,pingen_id:0 -msgid "Pingen ID" -msgstr "" - -#. module: pingen -#: constraint:res.company:0 -msgid "Error! You can not create recursive companies." -msgstr "" - -#. module: pingen -#: field:ir.attachment,pingen_send:0 -msgid "Send" -msgstr "" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:399 -#, python-format -msgid "Connection Error when updating the status of Document %s from Pingen" -msgstr "" - -#. module: pingen -#: field:pingen.document,state:0 -msgid "State" -msgstr "" - -#. module: pingen -#: field:ir.attachment,pingen_color:0 -msgid "Type of print" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Attachment" -msgstr "" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:405 -#, python-format -msgid "Error when updating the status of Document %s from Pingen: \n" -"%s" -msgstr "" - -#. module: pingen -#: model:ir.actions.act_window,name:pingen.act_attachment_to_pingen_document -#: field:ir.attachment,pingen_document_ids:0 -#: view:pingen.document:0 -msgid "Pingen Document" -msgstr "" - -#. module: pingen -#: field:pingen.document,attachment_id:0 -msgid "Document" -msgstr "" - -#. module: pingen -#: help:ir.attachment,pingen_send:0 -msgid "Defines if a document is merely uploaded or also sent" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Pending" -msgstr "" - -#. module: pingen -#: selection:ir.attachment,pingen_speed:0 -msgid "Economy" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Errors resolved" -msgstr "" - -#. module: pingen -#: sql_constraint:pingen.document:0 -msgid "Only one Pingen document is allowed per attachment." -msgstr "" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:168 -#: code:addons/pingen/pingen_document.py:298 -#, python-format -msgid "Error when asking Pingen to send the document %s: \n" -"%s" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Update the letter's informations" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Canceled" -msgstr "" - -#. module: pingen -#: selection:pingen.document,state:0 -msgid "Connection Error" -msgstr "" - -#. module: pingen -#: model:ir.actions.act_window,name:pingen.action_pingen_document -#: model:ir.ui.menu,name:pingen.menu_pingen_document -msgid "Pingen Documents" -msgstr "" - -#. module: pingen -#: field:pingen.document,last_error_message:0 -msgid "Error Message" -msgstr "" - -#. module: pingen -#: selection:ir.attachment,pingen_color:0 -msgid "B/W" -msgstr "" - -#. module: pingen -#: field:res.company,pingen_staging:0 -msgid "Pingen Staging" -msgstr "" - -#. module: pingen -#: model:ir.model,name:pingen.model_ir_attachment -msgid "ir.attachment" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "In Sendcenter" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Sent" -msgstr "" - -#. module: pingen -#: field:pingen.document,post_status:0 -msgid "Post Status" -msgstr "" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:163 -#: code:addons/pingen/pingen_document.py:292 -#, python-format -msgid "Connection Error when asking for sending the document %s to Pingen" -msgstr "" - -#. module: pingen -#: view:res.company:0 -msgid "Configuration" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Data" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Options" -msgstr "" - -#. module: pingen -#: field:res.company,pingen_token:0 -msgid "Pingen Token" -msgstr "" - -#. module: pingen -#: field:ir.attachment,send_to_pingen:0 -msgid "Send to Pingen.com" -msgstr "" - -#. module: pingen -#: model:ir.model,name:pingen.model_pingen_document -msgid "pingen.document" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Dates" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Sendcenter" -msgstr "" - -#. module: pingen -#: sql_constraint:res.company:0 -msgid "The company name must be unique !" -msgstr "" - -#. module: pingen -#: field:pingen.document,parsed_address:0 -msgid "Parsed Address" -msgstr "" - -#. module: pingen -#: view:ir.attachment:0 -#: view:pingen.document:0 -#: view:res.company:0 -msgid "Pingen.com" -msgstr "" - -#. module: pingen -#: field:pingen.document,country_id:0 -msgid "Country" -msgstr "" - -#. module: pingen -#: view:ir.attachment:0 -msgid "Notes" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -msgid "Pushed" -msgstr "" - -#. module: pingen -#: model:ir.model,name:pingen.model_res_company -msgid "Companies" -msgstr "" - -#. module: pingen -#: code:addons/pingen/ir_attachment.py:90 -#, python-format -msgid "The attachment %s is already pushed to pingen.com." -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Attached To" -msgstr "" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:136 -#, python-format -msgid "The document does not meet the Pingen requirements." -msgstr "" - -#. module: pingen -#: code:addons/pingen/ir_attachment.py:89 -#: code:addons/pingen/pingen_document.py:176 -#: code:addons/pingen/pingen_document.py:306 -#: code:addons/pingen/pingen_document.py:413 -#: view:pingen.document:0 -#, python-format -msgid "Error" -msgstr "" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:162 -#: code:addons/pingen/pingen_document.py:291 -#: code:addons/pingen/pingen_document.py:398 -#, python-format -msgid "Pingen Connection Error" -msgstr "" - -#. module: pingen -#: field:pingen.document,send_date:0 -msgid "Date of sending" -msgstr "" - -#. module: pingen -#: selection:ir.attachment,pingen_speed:0 -msgid "Priority" -msgstr "" - -#. module: pingen -#: selection:ir.attachment,pingen_color:0 -msgid "Color" -msgstr "" - -#. module: pingen -#: model:ir.model,name:pingen.model_pingen_task -msgid "pingen.task" -msgstr "" - -#. module: pingen -#: help:pingen.document,pingen_id:0 -msgid "ID of the document in the Pingen Documents" -msgstr "" - -#. module: pingen -#: code:addons/pingen/pingen_document.py:167 -#: code:addons/pingen/pingen_document.py:297 -#: code:addons/pingen/pingen_document.py:404 -#: view:pingen.document:0 -#: selection:pingen.document,state:0 -#, python-format -msgid "Pingen Error" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Actions" -msgstr "" - -#. module: pingen -#: field:pingen.document,pages:0 -msgid "Pages" -msgstr "" - -#. module: pingen -#: field:pingen.document,currency_id:0 -msgid "Currency" -msgstr "" - -#. module: pingen -#: field:pingen.document,cost:0 -msgid "Cost" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Push to pingen.com" -msgstr "" - -#. module: pingen -#: view:pingen.document:0 -msgid "Ask pingen.com to send the document" -msgstr "" - -#. module: pingen -#: help:pingen.document,post_id:0 -msgid "ID of the document in the Pingen Sendcenter" -msgstr "" - -#. module: pingen -#: field:ir.attachment,pingen_speed:0 -msgid "Speed" -msgstr "" - -#. module: pingen -#: field:pingen.document,post_id:0 -msgid "Pingen Post ID" -msgstr "" - -#. module: pingen -#: help:ir.attachment,pingen_speed:0 -msgid "Defines the sending speed if the document is automatically sent" -msgstr "" - diff --git a/pingen/ir_attachment.py b/pingen/ir_attachment.py deleted file mode 100644 index cbb950d..0000000 --- a/pingen/ir_attachment.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Guewen Baconnier -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -import requests -import base64 - -from openerp.osv import osv, orm, fields -from openerp.tools.translate import _ - - -class ir_attachment(orm.Model): - - _inherit = 'ir.attachment' - - _columns = { - 'send_to_pingen': fields.boolean('Send to Pingen.com'), - 'pingen_document_ids': fields.one2many( - 'pingen.document', 'attachment_id', - string='Pingen Document', readonly=True), - 'pingen_send': fields.boolean( - 'Send', - help="Defines if a document is merely uploaded or also sent"), - 'pingen_speed': fields.selection( - [('1', 'Priority'), ('2', 'Economy')], - 'Speed', - help="Defines the sending speed if the document is automatically sent"), - 'pingen_color': fields.selection( [('0', 'B/W'), ('1', 'Color')], 'Type of print'), - } - - _defaults = { - 'pingen_send': True, - 'pingen_color': '0', - 'pingen_speed': '2', - } - - def _prepare_pingen_document_vals(self, cr, uid, attachment, context=None): - return {'attachment_id': attachment.id, - 'config': 'created from attachment'} - - def _handle_pingen_document(self, cr, uid, attachment_id, context=None): - """ Reponsible of the related ``pingen.document`` when the ``send_to_pingen`` - field is modified. - - Only one pingen document can be created per attachment. - - When ``send_to_pingen`` is activated: - * Create a ``pingen.document`` if it does not already exist - * Put the related ``pingen.document`` to ``pending`` if it already exist - When it is deactivated: - * Do nothing if no related ``pingen.document`` exists - * Or cancel it - * If it has already been pushed to pingen.com, raises - an `osv.except_osv` exception - """ - pingen_document_obj = self.pool.get('pingen.document') - attachment = self.browse(cr, uid, attachment_id, context=context) - document = attachment.pingen_document_ids[0] if attachment.pingen_document_ids else None - if attachment.send_to_pingen: - if document: - document.write({'state': 'pending'}, context=context) - else: - pingen_document_obj.create( - cr, uid, - self._prepare_pingen_document_vals( - cr, uid, attachment, context=context), - context=context) - else: - if document: - if document.state == 'pushed': - raise osv.except_osv( - _('Error'), - _('The attachment %s is already pushed to pingen.com.') % \ - attachment.name) - document.write({'state': 'canceled'}, context=context) - return - - def create(self, cr, uid, vals, context=None): - attachment_id = super(ir_attachment, self).create(cr, uid, vals, context=context) - if 'send_to_pingen' in vals: - self._handle_pingen_document(cr, uid, attachment_id, context=context) - return attachment_id - - def write(self, cr, uid, ids, vals, context=None): - res = super(ir_attachment, self).write(cr, uid, ids, vals, context=context) - if 'send_to_pingen' in vals: - for attachment_id in ids: - self._handle_pingen_document(cr, uid, attachment_id, context=context) - return res - - def _decoded_content(self, cr, uid, attachment, context=None): - """ Returns the decoded content of an attachment (stored or url) - - Returns None if the type is 'url' and the url is not reachable. - """ - decoded_document = None - if attachment.type == 'binary': - decoded_document = base64.decodestring(attachment.datas) - elif attachment.type == 'url': - response = requests.get(attachment.url) - if response.ok: - decoded_document = requests.content - else: - raise Exception( - 'The type of attachment %s is not handled' % attachment.type) - return decoded_document - diff --git a/pingen/ir_attachment_view.xml b/pingen/ir_attachment_view.xml deleted file mode 100644 index d51a906..0000000 --- a/pingen/ir_attachment_view.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - ir.attachment.pingen.view - ir.attachment - form - - - - - - - - - - - - - - - - - diff --git a/pingen/pingen.py b/pingen/pingen.py deleted file mode 100644 index ecb8c2e..0000000 --- a/pingen/pingen.py +++ /dev/null @@ -1,228 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Guewen Baconnier -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -import requests -import logging -import urlparse -import json -import pytz - -from datetime import datetime -from requests.packages.urllib3.filepost import encode_multipart_formdata - -_logger = logging.getLogger(__name__) - -POST_SENDING_STATUS = { - 100: 'Ready/Pending', - 101: 'Processing', - 102: 'Waiting for confirmation', - 200: 'Sent', - 300: 'Some error occured and object wasn\'t sent', - 400: 'Sending cancelled', -} - -DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S' # this is the format used by pingen API - -TZ = pytz.timezone('Europe/Zurich') # this is the timezone of the pingen API - - -def pingen_datetime_to_utc(dt): - """ Convert a date/time used by pingen.com to UTC timezone - - :param dt: pingen date/time as string (as received from the API) - to convert to UTC - :return: datetime in the UTC timezone - """ - utc = pytz.utc - dt = datetime.strptime(dt, DATETIME_FORMAT) - localized_dt = TZ.localize(dt, is_dst=True) - return localized_dt.astimezone(utc) - - -class PingenException(RuntimeError): - """There was an ambiguous exception that occurred while handling your - request.""" - - -class ConnectionError(PingenException): - """An Error occured with the pingen API""" - - -class APIError(PingenException): - """An Error occured with the pingen API""" - - -class Pingen(object): - """ Interface to the pingen.com API """ - - def __init__(self, token, staging=True): - self._token = token - self.staging = staging - self._session = None - super(Pingen, self).__init__() - - @property - def url(self): - if self.staging: - return 'https://stage-api.pingen.com' - return 'https://api.pingen.com' - - @property - def session(self): - """ Build a requests session """ - if self._session is not None: - return self._session - self._session = requests.Session( - params={'token': self._token}, - # with safe_mode, requests catch errors and - # returns a blank response with an error - config={'safe_mode': True}, - # verify = False required for staging environment - # because the SSL certificate is wrong - verify=not self.staging) - return self._session - - def __enter__(self): - return self - - def __exit__(self, *args): - self.close() - - def close(self): - """Dispose of any internal state. """ - if self._session: - self._session.close() - - def _send(self, method, endpoint, **kwargs): - """ Send a request to the pingen API using requests - - Add necessary boilerplate to call pingen.com API - (authentication, configuration, ...) - - :param boundmethod method: requests method to call - :param str endpoint: endpoint to call - :param kwargs: additional arguments forwarded to the requests method - """ - complete_url = urlparse.urljoin(self.url, endpoint) - - response = method(complete_url, **kwargs) - - if not response.ok: - raise ConnectionError( - "%s: %s" % (response.json['errorcode'], - response.json['errormessage'])) - - if response.json['error']: - raise APIError( - "%s: %s" % (response.json['errorcode'], response.json['errormessage'])) - - return response - - def push_document(self, filename, filestream, send=None, speed=None, color=None): - """ Upload a document to pingen.com and eventually ask to send it - - :param str filename: name of the file to push - :param StringIO filestream: file to push - :param boolean send: if True, the document will be sent by pingen.com - :param int/str speed: sending speed of the document if it is send - 1 = Priority, 2 = Economy - :param int/str color: type of print, 0 = B/W, 1 = Color - :return: tuple with 3 items: - 1. document_id on pingen.com - 2. post_id on pingen.com if it has been sent or None - 3. dict of the created item on pingen (details) - """ - data = { - 'send': send, - 'speed': speed, - 'color': color, - } - - # we cannot use the `files` param alongside - # with the `datas`param when data is a - # JSON-encoded data. We have to construct - # the entire body and send it to `data` - # https://github.com/kennethreitz/requests/issues/950 - formdata = { - 'file': (filename, filestream.read()), - 'data': json.dumps(data), - } - - multipart, content_type = encode_multipart_formdata(formdata) - - response = self._send( - self.session.post, - 'document/upload', - headers={'Content-Type': content_type}, - data=multipart) - - rjson = response.json - - document_id = rjson['id'] - if rjson.get('send'): - # confusing name but send_id is the posted id - posted_id = rjson['send'][0]['send_id'] - item = rjson['item'] - - return document_id, posted_id, item - - def send_document(self, document_id, speed=None, color=None): - """ Send a uploaded document to pingen.com - - :param int document_id: id of the document to send - :param int/str speed: sending speed of the document if it is send - 1 = Priority, 2 = Economy - :param int/str color: type of print, 0 = B/W, 1 = Color - :return: id of the post on pingen.com - """ - data = { - 'speed': speed, - 'color': color, - } - response = self._send( - self.session.post, - 'document/send', - params={'id': document_id}, - data={'data': json.dumps(data)}) - - return response.json['id'] - - def post_infos(self, post_id): - """ Return the information of a post - - :param int post_id: id of the document to send - :return: dict of infos of the post - """ - response = self._send( - self.session.get, - 'post/get', - params={'id': post_id}) - - return response.json['item'] - - @staticmethod - def is_posted(post_infos): - """ return True if the post has been sent - - :param dict post_infos: post infos returned by `post_infos` - """ - return post_infos['status'] == 200 - diff --git a/pingen/pingen_data.xml b/pingen/pingen_data.xml deleted file mode 100644 index 5227210..0000000 --- a/pingen/pingen_data.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - Run Pingen Document Push - - - 1 - hours - -1 - - pingen.document - _push_and_send_to_pingen_cron - (None,) - - - - Run Pingen Document Update - - - 1 - days - -1 - - pingen.document - _update_post_infos_cron - (None,) - - - - diff --git a/pingen/pingen_document.py b/pingen/pingen_document.py deleted file mode 100644 index b613327..0000000 --- a/pingen/pingen_document.py +++ /dev/null @@ -1,426 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Guewen Baconnier -# Copyright 2012 Camptocamp SA -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# -############################################################################## - -import logging - -from cStringIO import StringIO - -from contextlib import closing -from openerp.osv import osv, orm, fields -from openerp.tools.translate import _ -from openerp import pooler, tools -from .pingen import APIError, ConnectionError, POST_SENDING_STATUS, \ - pingen_datetime_to_utc - -_logger = logging.getLogger(__name__) - - -class pingen_document(orm.Model): - """ A pingen document is the state of the synchronization of - an attachment with pingen.com - - It stores the configuration and the current state of the synchronization. - It also serves as a queue of documents to push to pingen.com - """ - - _name = 'pingen.document' - _inherits = {'ir.attachment': 'attachment_id'} - - _columns = { - 'attachment_id': fields.many2one( - 'ir.attachment', 'Document', - required=True, readonly=True, - ondelete='cascade'), - 'state': fields.selection( - [('pending', 'Pending'), - ('pushed', 'Pushed'), - ('sendcenter', 'In Sendcenter'), - ('sent', 'Sent'), - ('error', 'Connection Error'), - ('pingen_error', 'Pingen Error'), - ('canceled', 'Canceled')], - string='State', readonly=True, required=True), - 'push_date': fields.datetime('Push Date', readonly=True), - - # for `error` and `pingen_error` states when we push - 'last_error_message': fields.text('Error Message', readonly=True), - - # pingen IDs - 'pingen_id': fields.integer( - 'Pingen ID', readonly=True, - help="ID of the document in the Pingen Documents"), - 'post_id': fields.integer( - 'Pingen Post ID', readonly=True, - help="ID of the document in the Pingen Sendcenter"), - - # sendcenter infos - 'post_status': fields.char('Post Status', size=128, readonly=True), - 'parsed_address': fields.text('Parsed Address', readonly=True), - 'cost': fields.float('Cost', readonly=True), - 'currency_id': fields.many2one('res.currency', 'Currency', readonly=True), - 'country_id': fields.many2one('res.country', 'Country', readonly=True), - 'send_date': fields.datetime('Date of sending', readonly=True), - 'pages': fields.integer('Pages', readonly=True), - } - - _defaults = { - 'state': 'pending', - } - - _sql_constraints = [ - ('pingen_document_attachment_uniq', - 'unique (attachment_id)', - 'Only one Pingen document is allowed per attachment.'), - ] - - def _get_pingen_session(self, cr, uid, context=None): - """ Returns a pingen session for a user """ - company = self.pool.get('res.users').browse( - cr, uid, uid, context=context).company_id - return self.pool.get('res.company')._pingen(cr, uid, company, context=context) - - def _push_to_pingen(self, cr, uid, document, pingen=None, context=None): - """ Push a document to pingen.com - - :param Pingen pingen: optional pingen object to reuse session - """ - attachment_obj = self.pool.get('ir.attachment') - - decoded_document = attachment_obj._decoded_content( - cr, uid, document.attachment_id, context=context) - - if pingen is None: - pingen = self._get_pingen_session(cr, uid, context=context) - try: - doc_id, post_id, infos = pingen.push_document( - document.datas_fname, - StringIO(decoded_document), - document.pingen_send, - document.pingen_speed, - document.pingen_color) - except ConnectionError as e: - _logger.exception( - 'Connection Error when pushing Pingen Document %s to %s.' % - (document.id, pingen.url)) - raise - - except APIError as e: - _logger.error( - 'API Error when pushing Pingen Document %s to %s.' % - (document.id, pingen.url)) - raise - - error = False - state = 'pushed' - if post_id: - state = 'sendcenter' - elif infos['requirement_failure']: - state = 'pingen_error' - error = _('The document does not meet the Pingen requirements.') - - push_date = pingen_datetime_to_utc(infos['date']) - - document.write( - {'last_error_message': error, - 'state': state, - 'push_date': push_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT), - 'pingen_id': doc_id, - 'post_id': post_id}, - context=context) - _logger.info('Pingen Document %s: pushed to %s' % (document.id, pingen.url)) - - def push_to_pingen(self, cr, uid, ids, context=None): - """ Push a document to pingen.com - - Convert errors to osv.except_osv to be handled by the client. - - Wrapper method for multiple ids (when triggered from button for - instance) for public interface. - """ - assert len(ids) == 1, "Only 1 id is allowed" - with self._get_pingen_session(cr, uid, context=context) as session: - for document in self.browse(cr, uid, ids, context=context): - try: - self._push_to_pingen( - cr, uid, document, pingen=session, context=context) - except ConnectionError as e: - raise osv.except_osv( - _('Pingen Connection Error'), - _('Connection Error when asking for sending the document %s to Pingen') % document.name) - - except APIError as e: - raise osv.except_osv( - _('Pingen Error'), - _('Error when asking Pingen to send the document %s: ' - '\n%s') % (document.name, e)) - - except: - _logger.exception( - 'Unexcepted Error when updating the status of pingen.document %s: ' % - document.id) - raise osv.except_osv( - _('Error'), - _('Unexcepted Error when updating the status of Document %s') % document.name) - return True - - def _push_and_send_to_pingen_cron(self, cr, uid, ids, context=None): - """ Push a document to pingen.com - - Intended to be used in a cron. - - Commit after each record - - Instead of raising, store the error in the pingen.document - """ - if not ids: - ids = self.search( - cr, uid, - # do not retry pingen_error, they should be treated manually - [('state', 'in', ['pending', 'pushed', 'error'])], - limit=100, - context=context) - - with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr, \ - self._get_pingen_session(cr, uid, context=context) as session: - for document in self.browse(loc_cr, uid, ids, context=context): - - if document.state == 'error': - self._resolve_error(loc_cr, uid, document, context=context) - document.refresh() - - try: - if document.state == 'pending': - self._push_to_pingen( - loc_cr, uid, document, pingen=session, context=context) - - elif document.state == 'pushed': - self._ask_pingen_send( - loc_cr, uid, document, pingen=session, context=context) - except ConnectionError as e: - document.write({'last_error_message': e, - 'state': 'error'}, - context=context) - except APIError as e: - document.write({'last_error_message': e, - 'state': 'pingen_error'}, - context=context) - except: - _logger.error('Unexcepted error in pingen cron') - loc_cr.rollback() - raise - - else: - loc_cr.commit() - - return True - - def _resolve_error(self, cr, uid, document, context=None): - """ A document as resolved, put in the correct state """ - if document.post_id: - state = 'sendcenter' - elif document.pingen_id: - state = 'pushed' - else: - state = 'pending' - document.write({'state': state}, context=context) - - def resolve_error(self, cr, uid, ids, context=None): - """ A document as resolved, put in the correct state """ - for document in self.browse(cr, uid, ids, context=context): - self._resolve_error(cr, uid, document, context=context) - return True - - def _ask_pingen_send(self, cr, uid, document, pingen, context=None): - """ For a document already pushed to pingen, ask to send it. - - :param Pingen pingen: pingen object to reuse - """ - # sending has been explicitely asked so we change the option - # for consistency - if not document.pingen_send: - document.write({'pingen_send': True}, context=context) - - try: - post_id = pingen.send_document( - document.pingen_id, - document.pingen_speed, - document.pingen_color) - except ConnectionError as e: - _logger.exception('Connection Error when asking for sending Pingen Document %s to %s.' % - (document.id, pingen.url)) - raise - except APIError as e: - _logger.exception('API Error when asking for sending Pingen Document %s to %s.' % - (document.id, pingen.url)) - raise - - document.write( - {'last_error_message': False, - 'state': 'sendcenter', - 'post_id': post_id}, - context=context) - _logger.info('Pingen Document %s: asked for sending to %s' % (document.id, pingen.url)) - - return True - - def ask_pingen_send(self, cr, uid, ids, context=None): - """ For a document already pushed to pingen, ask to send it. - - Wrapper method for multiple ids (when triggered from button for - instance) for public interface. - """ - assert len(ids) == 1, "Only 1 id is allowed" - with self._get_pingen_session(cr, uid, context=context) as session: - for document in self.browse(cr, uid, ids, context=context): - try: - self._ask_pingen_send(cr, uid, document, pingen=session, context=context) - except ConnectionError as e: - raise osv.except_osv( - _('Pingen Connection Error'), - _('Connection Error when asking for ' - 'sending the document %s to Pingen') % document.name) - - except APIError as e: - raise osv.except_osv( - _('Pingen Error'), - _('Error when asking Pingen to send the document %s: ' - '\n%s') % (document.name, e)) - - except: - _logger.exception( - 'Unexcepted Error when updating the status of pingen.document %s: ' % - document.id) - raise osv.except_osv( - _('Error'), - _('Unexcepted Error when updating the status of Document %s') % document.name) - return True - - def _update_post_infos(self, cr, uid, document, pingen, context=None): - """ Update the informations from pingen of a document in the Sendcenter - - :param Pingen pingen: pingen object to reuse - """ - if not document.post_id: - return - - try: - post_infos = pingen.post_infos(document.post_id) - except ConnectionError as e: - _logger.exception( - 'Connection Error when asking for ' - 'sending Pingen Document %s to %s.' % - (document.id, pingen.url)) - raise - except APIError as e: - _logger.exception( - 'API Error when asking for sending Pingen Document %s to %s.' % - (document.id, pingen.url)) - raise - - currency_ids = self.pool.get('res.currency').search( - cr, uid, [('name', '=', post_infos['currency'])], context=context) - country_ids = self.pool.get('res.country').search( - cr, uid, [('code', '=', post_infos['country'])], context=context) - - send_date = pingen_datetime_to_utc(infos['date']) - - vals = { - 'post_status': POST_SENDING_STATUS[post_infos['status']], - 'cost': post_infos['cost'], - 'currency_id': currency_ids[0] if currency_ids else False, - 'parsed_address': post_infos['address'], - 'country_id': country_ids[0] if country_ids else False, - 'send_date': send_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT), - 'pages': post_infos['pages'], - 'last_error_message': False, - } - if pingen.is_posted(post_infos): - vals['state'] = 'sent' - - document.write(vals, context=context) - _logger.info('Pingen Document %s: status updated' % document.id) - - def _update_post_infos_cron(self, cr, uid, ids, context=None): - """ Update the informations from pingen of a document in the Sendcenter - - Intended to be used in a cron. - - Commit after each record - - Do not raise errors, only skip the update of the record. - """ - if not ids: - ids = self.search( - cr, uid, - [('state', '=', 'sendcenter')], - context=context) - - with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr, \ - self._get_pingen_session(cr, uid, context=context) as session: - for document in self.browse(loc_cr, uid, ids, context=context): - try: - self._update_post_infos( - loc_cr, uid, document, pingen=session, context=context) - except (ConnectionError, APIError): - # will be retried the next time - # In any case, the error has been logged by _update_post_infos - loc_cr.rollback() - except: - _logger.error('Unexcepted error in pingen cron') - loc_cr.rollback() - raise - else: - loc_cr.commit() - return True - - def update_post_infos(self, cr, uid, ids, context=None): - """ Update the informations from pingen of a document in the Sendcenter - - Wrapper method for multiple ids (when triggered from button for - instance) for public interface. - """ - assert len(ids) == 1, "Only 1 id is allowed" - with self._get_pingen_session(cr, uid, context=context) as session: - for document in self.browse(cr, uid, ids, context=context): - try: - self._update_post_infos( - cr, uid, document, pingen=session, context=context) - except ConnectionError as e: - raise osv.except_osv( - _('Pingen Connection Error'), - _('Connection Error when updating the status of Document %s' - ' from Pingen') % document.name) - - except APIError as e: - raise osv.except_osv( - _('Pingen Error'), - _('Error when updating the status of Document %s from Pingen: ' - '\n%s') % (document.name, e)) - - except: - _logger.exception( - 'Unexcepted Error when updating the status of pingen.document %s: ' % - document.id) - raise osv.except_osv( - _('Error'), - _('Unexcepted Error when updating the status of Document %s') % document.name) - return True - diff --git a/pingen/pingen_document_view.xml b/pingen/pingen_document_view.xml deleted file mode 100644 index 1686167..0000000 --- a/pingen/pingen_document_view.xml +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - pingen.document.tree - pingen.document - tree - - - - - - - - - - - - - - pingen.document.form - pingen.document - form - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -