From 9575e7a3a73d1f30ba4efe0d5d991ba5a1d17e52 Mon Sep 17 00:00:00 2001 From: "Guewen Baconnier @ Camptocamp" Date: Mon, 19 Nov 2012 16:49:28 +0100 Subject: [PATCH] [IMP] push a pingen.task --- pingen/__openerp__.py | 13 +++- pingen/pingen_task.py | 115 ++++++++++++++++++++++++++++++++++++ pingen/pingen_task_view.xml | 10 +++- 3 files changed, 132 insertions(+), 6 deletions(-) diff --git a/pingen/__openerp__.py b/pingen/__openerp__.py index 3b48d34..314c473 100644 --- a/pingen/__openerp__.py +++ b/pingen/__openerp__.py @@ -37,13 +37,20 @@ What is pingen.com Pingen.com is a paid online service. It send uploaded documents by letter post. -Integration ------------ +Scope of the integration +------------------------ One can decide, per document / attachment, if it should be pushed to pingen.com. The documents are pushed asynchronously. - """, +Dependencies +------------ + + * Require the Python library `requests `_ + * The PDF files sent to pingen.com have to respect some `formatting rules + `_. + +""", 'website': 'http://www.camptocamp.com', 'init_xml': [], 'update_xml': [ diff --git a/pingen/pingen_task.py b/pingen/pingen_task.py index af6bd74..771aa56 100644 --- a/pingen/pingen_task.py +++ b/pingen/pingen_task.py @@ -19,8 +19,21 @@ # ############################################################################## +import requests +import urlparse +import base64 +import logging + +from cStringIO import StringIO + from openerp.osv import orm, fields +# TODO should be configurable +BASE_URL = 'https://stage-api.pingen.com' +TOKEN = '6bc041af6f02854461ef31c2121ef853' + +_logger = logging.getLogger(__name__) + class pingen_task(orm.Model): """ A pingen task is the state of the synchronization of @@ -43,6 +56,20 @@ class pingen_task(orm.Model): ('canceled', 'Canceled')], string='State', readonly=True, required=True), 'config': fields.text('Configuration (tmp)'), + 'date': fields.datetime('Creation Date'), + 'push_date': fields.datetime('Pushed Date'), + 'send': fields.boolean( + 'Send', + help="Defines if a document is merely uploaed or also sent"), + 'speed': fields.selection( + [(1, 'Priority'), (2, 'Economy')], + 'Speed', + help="Defines the sending speed if the document is automatically sent"), + 'color': fields.selection( [(0, 'B/W'), (1, 'Color')], 'Type of print'), + 'last_error_code': fields.integer('Error Code', readonly=True), + 'last_error_message': fields.text('Error Message', readonly=True), + 'pingen_id': fields.integer('Pingen ID'), + } _defaults = { @@ -55,3 +82,91 @@ class pingen_task(orm.Model): 'Only one Pingen task is allowed per attachment.'), ] + def _push_to_pingen(self, cr, uid, task_id, context=None): + """ Push a document to pingen.com + + + """ + success = False + push_url = urlparse.urljoin(BASE_URL, 'document/upload') + auth = {'token': TOKEN} + + config = { + 'send': False, + 'speed': 2, + 'color': 1, + } + + task = self.browse(cr, uid, task_id, context=context) + + if task.type == 'binary': + decoded_document = base64.decodestring(task.datas) + else: + url_resp = requests.get(task.url) + if url_resp.status_code != 200: + task.write({'last_error_code': False, + 'last_error_message': "%s" % req.error, + 'state': 'error'}, + context=context) + return False + decoded_document = requests.content + + document = {'file': (task.datas_fname, StringIO(decoded_document))} + try: + # TODO extract + req = requests.post( + push_url, + params=auth, + data=config, + files=document, + # verify = False required for staging environment + verify=False) + req.raise_for_status() + except (requests.HTTPError, + requests.Timeout, + requests.ConnectionError) as e: + msg = ('%s Message: %s. \n' + 'It occured when pushing the Pingen Task %s to pingen.com. \n' + 'It will be retried later.' % (e.__doc__, e, task.id)) + _logger.error(msg) + task.write( + {'last_error_code': False, + 'last_error_message': msg, + 'state': 'error'}, + context=context) + else: + response = req.json + if response['error']: + task.write( + {'last_error_code': response['errorcode'], + 'last_error_message': 'Error from pingen.com: %s' % response['errormessage'], + 'state': 'error'}, + context=context) + else: + task.write( + {'last_error_code': False, + 'last_error_message': False, + 'state': 'pushed', + 'pingen_id': response['id'],}, + context=context) + _logger.info('Pingen Task %s pushed to pingen.com.' % task.id) + success = True + + return success + + def push_to_pingen(self, cr, uid, ids, context=None): + """ Push a document to pingen.com + + Wrapper method for multiple ids (when triggered from button) + """ + for task_id in ids: + self._push_to_pingen(cr, uid, task_id, context=context) + return True + + + # r = requests.get(push_url, params=auth, verify=False) + + + # TODO: resolve = put in pending or put in pushed + + diff --git a/pingen/pingen_task_view.xml b/pingen/pingen_task_view.xml index 83540ca..1aeea82 100644 --- a/pingen/pingen_task_view.xml +++ b/pingen/pingen_task_view.xml @@ -8,8 +8,9 @@ tree - - + + + @@ -20,8 +21,11 @@ form
- + + + +