mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[FIX] reuse session between calls
This commit is contained in:
@@ -56,7 +56,8 @@ class Pingen(object):
|
|||||||
|
|
||||||
def __init__(self, token, staging=True):
|
def __init__(self, token, staging=True):
|
||||||
self._token = token
|
self._token = token
|
||||||
self.staging = True
|
self.staging = staging
|
||||||
|
self._session = None
|
||||||
super(Pingen, self).__init__()
|
super(Pingen, self).__init__()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -65,6 +66,32 @@ class Pingen(object):
|
|||||||
return 'https://stage-api.pingen.com'
|
return 'https://stage-api.pingen.com'
|
||||||
return 'https://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):
|
def _send(self, method, endpoint, **kwargs):
|
||||||
""" Send a request to the pingen API using requests
|
""" Send a request to the pingen API using requests
|
||||||
|
|
||||||
@@ -77,23 +104,6 @@ class Pingen(object):
|
|||||||
"""
|
"""
|
||||||
complete_url = urlparse.urljoin(self.url, endpoint)
|
complete_url = urlparse.urljoin(self.url, endpoint)
|
||||||
|
|
||||||
auth_param = {'token': self._token}
|
|
||||||
if 'params' in kwargs:
|
|
||||||
kwargs['params'].update(auth_param)
|
|
||||||
else:
|
|
||||||
kwargs['params'] = auth_param
|
|
||||||
|
|
||||||
# with safe_mode, requests catch errors and
|
|
||||||
# returns a blank response with an error
|
|
||||||
config = {'safe_mode': True}
|
|
||||||
if 'config' in kwargs:
|
|
||||||
kwargs['config'].update(config)
|
|
||||||
else:
|
|
||||||
kwargs['config'] = config
|
|
||||||
|
|
||||||
# verify = False required for staging environment
|
|
||||||
# because the SSL certificate is wrong
|
|
||||||
kwargs['verify'] = not self.staging
|
|
||||||
response = method(complete_url, **kwargs)
|
response = method(complete_url, **kwargs)
|
||||||
|
|
||||||
if not response.ok:
|
if not response.ok:
|
||||||
@@ -140,7 +150,7 @@ class Pingen(object):
|
|||||||
multipart, content_type = encode_multipart_formdata(formdata)
|
multipart, content_type = encode_multipart_formdata(formdata)
|
||||||
|
|
||||||
response = self._send(
|
response = self._send(
|
||||||
requests.post,
|
self.session.post,
|
||||||
'document/upload',
|
'document/upload',
|
||||||
headers={'Content-Type': content_type},
|
headers={'Content-Type': content_type},
|
||||||
data=multipart)
|
data=multipart)
|
||||||
@@ -169,7 +179,7 @@ class Pingen(object):
|
|||||||
'color': color,
|
'color': color,
|
||||||
}
|
}
|
||||||
response = self._send(
|
response = self._send(
|
||||||
requests.post,
|
self.session.post,
|
||||||
'document/send',
|
'document/send',
|
||||||
params={'id': document_id},
|
params={'id': document_id},
|
||||||
data={'data': json.dumps(data)})
|
data={'data': json.dumps(data)})
|
||||||
@@ -183,7 +193,7 @@ class Pingen(object):
|
|||||||
:return: dict of infos of the post
|
:return: dict of infos of the post
|
||||||
"""
|
"""
|
||||||
response = self._send(
|
response = self._send(
|
||||||
requests.get,
|
self.session.get,
|
||||||
'post/get',
|
'post/get',
|
||||||
params={'id': post_id})
|
params={'id': post_id})
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ from cStringIO import StringIO
|
|||||||
|
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
from openerp.osv import osv, orm, fields
|
from openerp.osv import osv, orm, fields
|
||||||
from openerp import tools
|
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
from openerp import pooler
|
from openerp import pooler
|
||||||
from .pingen import APIError, ConnectionError, POST_SENDING_STATUS
|
from .pingen import APIError, ConnectionError, POST_SENDING_STATUS
|
||||||
@@ -91,16 +90,24 @@ class pingen_document(orm.Model):
|
|||||||
'Only one Pingen document is allowed per attachment.'),
|
'Only one Pingen document is allowed per attachment.'),
|
||||||
]
|
]
|
||||||
|
|
||||||
def _push_to_pingen(self, cr, uid, document, context=None):
|
def _get_pingen_session(self, cr, uid, context=None):
|
||||||
""" Push a document to pingen.com """
|
""" 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')
|
attachment_obj = self.pool.get('ir.attachment')
|
||||||
|
|
||||||
decoded_document = attachment_obj._decoded_content(
|
decoded_document = attachment_obj._decoded_content(
|
||||||
cr, uid, document.attachment_id, context=context)
|
cr, uid, document.attachment_id, context=context)
|
||||||
|
|
||||||
company = self.pool.get('res.users').browse(
|
if pingen is None:
|
||||||
cr, uid, uid, context=context).company_id
|
pingen = self._get_pingen_session(cr, uid, context=context)
|
||||||
pingen = self.pool.get('res.company')._pingen(cr, uid, company, context=context)
|
|
||||||
try:
|
try:
|
||||||
doc_id, post_id, infos = pingen.push_document(
|
doc_id, post_id, infos = pingen.push_document(
|
||||||
document.datas_fname,
|
document.datas_fname,
|
||||||
@@ -145,27 +152,29 @@ class pingen_document(orm.Model):
|
|||||||
Wrapper method for multiple ids (when triggered from button for
|
Wrapper method for multiple ids (when triggered from button for
|
||||||
instance) for public interface.
|
instance) for public interface.
|
||||||
"""
|
"""
|
||||||
for document in self.browse(cr, uid, ids, context=context):
|
with self._get_pingen_session(cr, uid, context=context) as session:
|
||||||
try:
|
for document in self.browse(cr, uid, ids, context=context):
|
||||||
self._push_to_pingen(cr, uid, document, context=context)
|
try:
|
||||||
except ConnectionError as e:
|
self._push_to_pingen(
|
||||||
raise osv.except_osv(
|
cr, uid, document, pingen=session, context=context)
|
||||||
_('Pingen Connection Error'),
|
except ConnectionError as e:
|
||||||
_('Connection Error when asking for sending the document %s to Pingen') % document.name)
|
raise osv.except_osv(
|
||||||
|
_('Pingen Connection Error'),
|
||||||
|
_('Connection Error when asking for sending the document %s to Pingen') % document.name)
|
||||||
|
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_('Pingen Error'),
|
_('Pingen Error'),
|
||||||
_('Error when asking Pingen to send the document %s: '
|
_('Error when asking Pingen to send the document %s: '
|
||||||
'\n%s') % (document.name, e))
|
'\n%s') % (document.name, e))
|
||||||
|
|
||||||
except:
|
except:
|
||||||
_logger.exception(
|
_logger.exception(
|
||||||
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
||||||
document.id)
|
document.id)
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_('Error'),
|
_('Error'),
|
||||||
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _push_and_send_to_pingen_cron(self, cr, uid, ids, context=None):
|
def _push_and_send_to_pingen_cron(self, cr, uid, ids, context=None):
|
||||||
@@ -186,28 +195,35 @@ class pingen_document(orm.Model):
|
|||||||
context=context)
|
context=context)
|
||||||
|
|
||||||
with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr:
|
with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr:
|
||||||
for document in self.browse(loc_cr, uid, ids, context=context):
|
with 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':
|
if document.state == 'error':
|
||||||
self._resolve_error(loc_cr, uid, document, context=context)
|
self._resolve_error(loc_cr, uid, document, context=context)
|
||||||
document.refresh()
|
document.refresh()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if document.state == 'pending':
|
if document.state == 'pending':
|
||||||
self._push_to_pingen(loc_cr, uid, document, context=context)
|
self._push_to_pingen(
|
||||||
|
loc_cr, uid, document, pingen=session, context=context)
|
||||||
|
|
||||||
elif document.state == 'pushed':
|
elif document.state == 'pushed':
|
||||||
self._ask_pingen_send(loc_cr, uid, document, context=context)
|
self._ask_pingen_send(
|
||||||
except ConnectionError as e:
|
loc_cr, uid, document, pingen=session, context=context)
|
||||||
document.write({'last_error_message': e, 'state': 'error'}, context=context)
|
except ConnectionError as e:
|
||||||
except APIError as e:
|
document.write({'last_error_message': e,
|
||||||
document.write({'last_error_message': e, 'state': 'pingen_error'}, context=context)
|
'state': 'error'},
|
||||||
except:
|
context=context)
|
||||||
_logger.error('Unexcepted error in pingen cron')
|
except APIError as e:
|
||||||
loc_cr.rollback()
|
document.write({'last_error_message': e,
|
||||||
raise
|
'state': 'pingen_error'},
|
||||||
|
context=context)
|
||||||
|
except:
|
||||||
|
_logger.error('Unexcepted error in pingen cron')
|
||||||
|
loc_cr.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
loc_cr.commit()
|
loc_cr.commit()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -227,17 +243,16 @@ class pingen_document(orm.Model):
|
|||||||
self._resolve_error(cr, uid, document, context=context)
|
self._resolve_error(cr, uid, document, context=context)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _ask_pingen_send(self, cr, uid, document, context=None):
|
def _ask_pingen_send(self, cr, uid, document, pingen, context=None):
|
||||||
""" For a document already pushed to pingen, ask to send it.
|
""" 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
|
# sending has been explicitely asked so we change the option
|
||||||
# for consistency
|
# for consistency
|
||||||
if not document.pingen_send:
|
if not document.pingen_send:
|
||||||
document.write({'pingen_send': True}, context=context)
|
document.write({'pingen_send': True}, context=context)
|
||||||
|
|
||||||
company = self.pool.get('res.users').browse(
|
|
||||||
cr, uid, uid, context=context).company_id
|
|
||||||
pingen = self.pool.get('res.company')._pingen(cr, uid, company, context=context)
|
|
||||||
try:
|
try:
|
||||||
post_id = pingen.send_document(
|
post_id = pingen.send_document(
|
||||||
document.pingen_id,
|
document.pingen_id,
|
||||||
@@ -267,39 +282,39 @@ class pingen_document(orm.Model):
|
|||||||
Wrapper method for multiple ids (when triggered from button for
|
Wrapper method for multiple ids (when triggered from button for
|
||||||
instance) for public interface.
|
instance) for public interface.
|
||||||
"""
|
"""
|
||||||
for document in self.browse(cr, uid, ids, context=context):
|
with self._get_pingen_session(cr, uid, context=context) as session:
|
||||||
try:
|
for document in self.browse(cr, uid, ids, context=context):
|
||||||
self._ask_pingen_send(cr, uid, document, context=context)
|
try:
|
||||||
except ConnectionError as e:
|
self._ask_pingen_send(cr, uid, document, pingen=session, context=context)
|
||||||
raise osv.except_osv(
|
except ConnectionError as e:
|
||||||
_('Pingen Connection Error'),
|
raise osv.except_osv(
|
||||||
_('Connection Error when asking for '
|
_('Pingen Connection Error'),
|
||||||
'sending the document %s to Pingen') % document.name)
|
_('Connection Error when asking for '
|
||||||
|
'sending the document %s to Pingen') % document.name)
|
||||||
|
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_('Pingen Error'),
|
_('Pingen Error'),
|
||||||
_('Error when asking Pingen to send the document %s: '
|
_('Error when asking Pingen to send the document %s: '
|
||||||
'\n%s') % (document.name, e))
|
'\n%s') % (document.name, e))
|
||||||
|
|
||||||
except:
|
except:
|
||||||
_logger.exception(
|
_logger.exception(
|
||||||
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
||||||
document.id)
|
document.id)
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_('Error'),
|
_('Error'),
|
||||||
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _update_post_infos(self, cr, uid, document, context=None):
|
def _update_post_infos(self, cr, uid, document, pingen, context=None):
|
||||||
""" Update the informations from pingen of a document in the Sendcenter
|
""" Update the informations from pingen of a document in the Sendcenter
|
||||||
|
|
||||||
|
:param Pingen pingen: pingen object to reuse
|
||||||
"""
|
"""
|
||||||
if not document.post_id:
|
if not document.post_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
company = self.pool.get('res.users').browse(
|
|
||||||
cr, uid, uid, context=context).company_id
|
|
||||||
pingen = self.pool.get('res.company')._pingen(cr, uid, company, context=context)
|
|
||||||
try:
|
try:
|
||||||
post_infos = pingen.post_infos(document.post_id)
|
post_infos = pingen.post_infos(document.post_id)
|
||||||
except ConnectionError as e:
|
except ConnectionError as e:
|
||||||
@@ -350,19 +365,21 @@ class pingen_document(orm.Model):
|
|||||||
context=context)
|
context=context)
|
||||||
|
|
||||||
with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr:
|
with closing(pooler.get_db(cr.dbname).cursor()) as loc_cr:
|
||||||
for document in self.browse(loc_cr, uid, ids, context=context):
|
with self._get_pingen_session(cr, uid, context=context) as session:
|
||||||
try:
|
for document in self.browse(loc_cr, uid, ids, context=context):
|
||||||
self._update_post_infos(loc_cr, uid, document, context=context)
|
try:
|
||||||
except (ConnectionError, APIError):
|
self._update_post_infos(
|
||||||
# will be retried the next time
|
loc_cr, uid, document, pingen=session, context=context)
|
||||||
# In any case, the error has been logged by _update_post_infos
|
except (ConnectionError, APIError):
|
||||||
loc_cr.rollback()
|
# will be retried the next time
|
||||||
except:
|
# In any case, the error has been logged by _update_post_infos
|
||||||
_logger.error('Unexcepted error in pingen cron')
|
loc_cr.rollback()
|
||||||
loc_cr.rollback()
|
except:
|
||||||
raise
|
_logger.error('Unexcepted error in pingen cron')
|
||||||
|
loc_cr.rollback()
|
||||||
|
raise
|
||||||
|
|
||||||
loc_cr.commit()
|
loc_cr.commit()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def update_post_infos(self, cr, uid, ids, context=None):
|
def update_post_infos(self, cr, uid, ids, context=None):
|
||||||
@@ -371,27 +388,29 @@ class pingen_document(orm.Model):
|
|||||||
Wrapper method for multiple ids (when triggered from button for
|
Wrapper method for multiple ids (when triggered from button for
|
||||||
instance) for public interface.
|
instance) for public interface.
|
||||||
"""
|
"""
|
||||||
for document in self.browse(cr, uid, ids, context=context):
|
with self._get_pingen_session(cr, uid, context=context) as session:
|
||||||
try:
|
for document in self.browse(cr, uid, ids, context=context):
|
||||||
self._update_post_infos(cr, uid, document, context=context)
|
try:
|
||||||
except ConnectionError as e:
|
self._update_post_infos(
|
||||||
raise osv.except_osv(
|
cr, uid, document, pingen=session, context=context)
|
||||||
_('Pingen Connection Error'),
|
except ConnectionError as e:
|
||||||
_('Connection Error when updating the status of Document %s'
|
raise osv.except_osv(
|
||||||
' from Pingen') % document.name)
|
_('Pingen Connection Error'),
|
||||||
|
_('Connection Error when updating the status of Document %s'
|
||||||
|
' from Pingen') % document.name)
|
||||||
|
|
||||||
except APIError as e:
|
except APIError as e:
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_('Pingen Error'),
|
_('Pingen Error'),
|
||||||
_('Error when updating the status of Document %s from Pingen: '
|
_('Error when updating the status of Document %s from Pingen: '
|
||||||
'\n%s') % (document.name, e))
|
'\n%s') % (document.name, e))
|
||||||
|
|
||||||
except:
|
except:
|
||||||
_logger.exception(
|
_logger.exception(
|
||||||
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
'Unexcepted Error when updating the status of pingen.document %s: ' %
|
||||||
document.id)
|
document.id)
|
||||||
raise osv.except_osv(
|
raise osv.except_osv(
|
||||||
_('Error'),
|
_('Error'),
|
||||||
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
_('Unexcepted Error when updating the status of Document %s') % document.name)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user