[IMP] pingen: pre-commit stuff

This commit is contained in:
Anna Janiszewska
2023-01-26 12:55:11 +01:00
parent eb4a9f3b5a
commit 0529340243
17 changed files with 471 additions and 385 deletions

View File

@@ -1,77 +1,85 @@
# -*- coding: utf-8 -*-
# Author: Guewen Baconnier
# Copyright 2012-2017 Camptocamp SA
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import logging
from requests.exceptions import ConnectionError
from cStringIO import StringIO
from requests.exceptions import ConnectionError
import odoo
from odoo import models, fields, _
from odoo import _, fields, models
from odoo.exceptions import UserError
from .pingen import APIError, pingen_datetime_to_utc, POST_SENDING_STATUS
from .pingen import POST_SENDING_STATUS, APIError, pingen_datetime_to_utc
_logger = logging.getLogger(__name__)
class PingenDocument(models.Model):
""" A pingen document is the state of the synchronization of
"""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'}
_name = "pingen.document"
_inherits = {"ir.attachment": "attachment_id"}
attachment_id = fields.Many2one(
'ir.attachment', 'Document',
required=True, readonly=True,
ondelete='cascade')
"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, default='pending')
push_date = fields.Datetime('Push Date', readonly=True)
[
("pending", "Pending"),
("pushed", "Pushed"),
("sendcenter", "In Sendcenter"),
("sent", "Sent"),
("error", "Connection Error"),
("pingen_error", "Pingen Error"),
("canceled", "Canceled"),
],
string="State",
readonly=True,
required=True,
default="pending",
)
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)
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")
"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")
"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)
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)
_sql_constraints = [
('pingen_document_attachment_uniq',
'unique (attachment_id)',
'Only one Pingen document is allowed per attachment.'),
(
"pingen_document_attachment_uniq",
"unique (attachment_id)",
"Only one Pingen document is allowed per attachment.",
),
]
def _get_pingen_session(self):
""" Returns a pingen session for a user """
"""Returns a pingen session for a user"""
return self.company_id._pingen()
def _push_to_pingen(self, pingen=None):
""" Push a document to pingen.com
"""Push a document to pingen.com
:param Pingen pingen: optional pingen object to reuse session
"""
decoded_document = self.attachment_id._decoded_content()
@@ -83,36 +91,41 @@ class PingenDocument(models.Model):
StringIO(decoded_document),
self.pingen_send,
self.pingen_speed,
self.pingen_color)
self.pingen_color,
)
except ConnectionError:
_logger.exception(
'Connection Error when pushing Pingen Document %s to %s.' %
(self.id, pingen.url))
"Connection Error when pushing Pingen Document %s to %s."
% (self.id, pingen.url)
)
raise
except APIError:
_logger.error(
'API Error when pushing Pingen Document %s to %s.' %
(self.id, pingen.url))
"API Error when pushing Pingen Document %s to %s."
% (self.id, pingen.url)
)
raise
error = False
state = 'pushed'
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'])
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"])
self.write(
{'last_error_message': error,
'state': state,
'push_date': fields.Datetime.to_string(push_date),
'pingen_id': doc_id,
'post_id': post_id},)
_logger.info(
'Pingen Document %s: pushed to %s' % (self.id, pingen.url))
{
"last_error_message": error,
"state": state,
"push_date": fields.Datetime.to_string(push_date),
"pingen_id": doc_id,
"post_id": post_id,
},
)
_logger.info("Pingen Document %s: pushed to %s" % (self.id, pingen.url))
def push_to_pingen(self):
""" Push a document to pingen.com
"""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.
@@ -123,117 +136,126 @@ class PingenDocument(models.Model):
try:
session = self._get_pingen_session()
self._push_to_pingen(pingen=session)
except ConnectionError as e:
state = 'error'
error_msg = _('Connection Error when asking for '
'sending the document %s to Pingen') % self.name
except ConnectionError:
state = "error"
error_msg = (
_(
"Connection Error when asking for "
"sending the document %s to Pingen"
)
% self.name
)
except APIError as e:
state = 'pingen_error'
error_msg = _('Error when asking Pingen to send the document %s: '
'\n%s') % (self.name, e)
except Exception as e:
state = "pingen_error"
error_msg = _(
"Error when asking Pingen to send the document %s: " "\n%s"
) % (self.name, e)
except Exception:
_logger.exception(
'Unexpected Error when updating the status of pingen.document '
'%s: ' % self.id)
error_msg = _('Unexpected Error when updating the '
'status of Document %s') % self.name
"Unexpected Error when updating the status of pingen.document "
"%s: " % self.id
)
error_msg = (
_("Unexpected Error when updating the " "status of Document %s")
% self.name
)
finally:
if error_msg:
vals = {'last_error_message': error_msg}
vals = {"last_error_message": error_msg}
if state:
vals.update({'state': state})
vals.update({"state": state})
with odoo.registry(self.env.cr.dbname).cursor() as new_cr:
new_env = odoo.api.Environment(
new_cr, self.env.uid, self.env.context)
new_cr, self.env.uid, self.env.context
)
self.with_env(new_env).write(vals)
raise UserError(error_msg)
return True
def _push_and_send_to_pingen_cron(self):
""" Push a document to pingen.com
"""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
"""
with odoo.api.Environment.manage():
with odoo.registry(self.env.cr.dbname).cursor() as new_cr:
new_env = odoo.api.Environment(
new_cr, self.env.uid, self.env.context)
new_env = odoo.api.Environment(new_cr, self.env.uid, self.env.context)
# Instead of raising, store the error in the pingen.document
self = self.with_env(new_env)
not_sent_docs = self.search([('state', '!=', 'sent')])
not_sent_docs = self.search([("state", "!=", "sent")])
for document in not_sent_docs:
session = document._get_pingen_session()
if document.state == 'error':
if document.state == "error":
document._resolve_error()
document.refresh()
try:
if document.state == 'pending':
if document.state == "pending":
document._push_to_pingen(pingen=session)
elif document.state == 'pushed':
elif document.state == "pushed":
document._ask_pingen_send(pingen=session)
except ConnectionError as e:
document.write({'last_error_message': e,
'state': 'error'})
document.write({"last_error_message": e, "state": "error"})
except APIError as e:
document.write({'last_error_message': e,
'state': 'pingen_error'})
except BaseException as e:
_logger.error('Unexpected error in pingen cron')
document.write(
{"last_error_message": e, "state": "pingen_error"}
)
except BaseException:
_logger.error("Unexpected error in pingen cron")
return True
def _resolve_error(self):
""" A document as resolved, put in the correct state """
"""A document as resolved, put in the correct state"""
if self.post_id:
state = 'sendcenter'
state = "sendcenter"
elif self.pingen_id:
state = 'pushed'
state = "pushed"
else:
state = 'pending'
self.write({'state': state})
state = "pending"
self.write({"state": state})
def resolve_error(self):
""" A document as resolved, put in the correct state """
"""A document as resolved, put in the correct state"""
for document in self:
document._resolve_error()
return True
def _ask_pingen_send(self, pingen):
""" 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
# for consistency
if not self.pingen_send:
self.write({'pingen_send': True})
self.write({"pingen_send": True})
try:
post_id = pingen.send_document(
self.pingen_id,
self.pingen_speed,
self.pingen_color)
self.pingen_id, self.pingen_speed, self.pingen_color
)
except ConnectionError:
_logger.exception(
'Connection Error when asking for sending Pingen Document %s '
'to %s.' % (self.id, pingen.url))
"Connection Error when asking for sending Pingen Document %s "
"to %s." % (self.id, pingen.url)
)
raise
except APIError:
_logger.exception(
'API Error when asking for sending Pingen Document %s to %s.' %
(self.id, pingen.url))
"API Error when asking for sending Pingen Document %s to %s."
% (self.id, pingen.url)
)
raise
self.write(
{'last_error_message': False,
'state': 'sendcenter',
'post_id': post_id})
{"last_error_message": False, "state": "sendcenter", "post_id": post_id}
)
_logger.info(
'Pingen Document %s: asked for sending to %s' % (
self.id, pingen.url))
"Pingen Document %s: asked for sending to %s" % (self.id, pingen.url)
)
return True
def ask_pingen_send(self):
""" For a document already pushed to pingen, ask to send it.
"""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.
"""
@@ -241,27 +263,34 @@ class PingenDocument(models.Model):
try:
session = self._get_pingen_session()
self._ask_pingen_send(pingen=session)
except ConnectionError as e:
except ConnectionError:
raise UserError(
_('Connection Error when asking for '
'sending the document %s to Pingen') % self.name)
_(
"Connection Error when asking for "
"sending the document %s to Pingen"
)
% self.name
)
except APIError as e:
raise UserError(
_('Error when asking Pingen to send the document %s: '
'\n%s') % (self.name, e))
_("Error when asking Pingen to send the document %s: " "\n%s")
% (self.name, e)
)
except BaseException as e:
except BaseException:
_logger.exception(
'Unexpected Error when updating the status '
'of pingen.document %s: ' % self.id)
"Unexpected Error when updating the status "
"of pingen.document %s: " % self.id
)
raise UserError(
_('Unexpected Error when updating the status '
'of Document %s') % self.name)
_("Unexpected Error when updating the status " "of Document %s")
% self.name
)
return True
def _update_post_infos(self, pingen):
""" Update the informations from
"""Update the informations from
pingen of a document in the Sendcenter
:param Pingen pingen: pingen object to reuse
"""
@@ -271,44 +300,43 @@ class PingenDocument(models.Model):
post_infos = pingen.post_infos(self.pingen_id)
except ConnectionError:
_logger.exception(
'Connection Error when asking for '
'sending Pingen Document %s to %s.' %
(self.id, pingen.url))
"Connection Error when asking for "
"sending Pingen Document %s to %s." % (self.id, pingen.url)
)
raise
except APIError:
_logger.exception(
'API Error when asking for sending Pingen Document %s to %s.' %
(self.id, pingen.url))
"API Error when asking for sending Pingen Document %s to %s."
% (self.id, pingen.url)
)
raise
country = self.env['res.country'].search(
[('code', '=', post_infos['country'])])
send_date = pingen_datetime_to_utc(post_infos['date'])
country = self.env["res.country"].search([("code", "=", post_infos["country"])])
send_date = pingen_datetime_to_utc(post_infos["date"])
vals = {
'post_status': POST_SENDING_STATUS[post_infos['status']],
'parsed_address': post_infos['address'],
'country_id': country.id,
'send_date': fields.Datetime.to_string(send_date),
'pages': post_infos['pages'],
'last_error_message': False,
}
"post_status": POST_SENDING_STATUS[post_infos["status"]],
"parsed_address": post_infos["address"],
"country_id": country.id,
"send_date": fields.Datetime.to_string(send_date),
"pages": post_infos["pages"],
"last_error_message": False,
}
if pingen.is_posted(post_infos):
vals['state'] = 'sent'
vals["state"] = "sent"
self.write(vals)
_logger.info('Pingen Document %s: status updated' % self.id)
_logger.info("Pingen Document %s: status updated" % self.id)
def _update_post_infos_cron(self):
""" Update the informations from pingen of a
"""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."""
with odoo.api.Environment.manage():
with odoo.registry(self.env.cr.dbname).cursor() as new_cr:
new_env = odoo.api.Environment(
new_cr, self.env.uid, self.env.context)
new_env = odoo.api.Environment(new_cr, self.env.uid, self.env.context)
# Instead of raising, store the error in the pingen.document
self = self.with_env(new_env)
pushed_docs = self.search([('state', '!=', 'sent')])
pushed_docs = self.search([("state", "!=", "sent")])
for document in pushed_docs:
session = document._get_pingen_session()
try:
@@ -319,12 +347,12 @@ class PingenDocument(models.Model):
# logged by _update_post_infos
pass
except BaseException as e:
_logger.error('Unexcepted error in pingen cron: %', e)
_logger.error("Unexcepted error in pingen cron: %", e)
raise
return True
def update_post_infos(self):
""" Update the informations from pingen of a document in the Sendcenter
"""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.
"""
@@ -332,19 +360,26 @@ class PingenDocument(models.Model):
try:
session = self._get_pingen_session()
self._update_post_infos(pingen=session)
except ConnectionError as e:
except ConnectionError:
raise UserError(
_('Connection Error when updating the status '
'of Document %s from Pingen') % self.name)
_(
"Connection Error when updating the status "
"of Document %s from Pingen"
)
% self.name
)
except APIError as e:
raise UserError(
_('Error when updating the status of Document %s from '
'Pingen: \n%s') % (self.name, e))
except BaseException as e:
_("Error when updating the status of Document %s from " "Pingen: \n%s")
% (self.name, e)
)
except BaseException:
_logger.exception(
'Unexpected Error when updating the status '
'of pingen.document %s: ' % self.id)
"Unexpected Error when updating the status "
"of pingen.document %s: " % self.id
)
raise UserError(
_('Unexpected Error when updating the status '
'of Document %s') % self.name)
_("Unexpected Error when updating the status " "of Document %s")
% self.name
)
return True