<commit_before>##############################################################################
#
#    Copyright (C) 2014-2015 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: <NAME>, <NAME> <<EMAIL>>
#
#    The licence is in the file __manifest__.py
#
##############################################################################
"""
This module reads a zip file containing scans of mail and finds the relation
between the database and the mail.
"""
import base64
import logging
import traceback
from pathlib import Path

from odoo import fields, models, api, _
from odoo.exceptions import UserError
from odoo.tools.config import config
from odoo.addons.queue_job.job import job, related_action

logger = logging.getLogger(__name__)

try:
    from PyPDF2 import PdfFileWriter, PdfFileReader
    from PyPDF2.pdf import PageObject
    import pysftp
except ImportError:
    logger.warning("Please install python dependencies.")


class SftpConnection:
    """
    Class helper used to handle connection between server and SFTP server.
    """

    def __init__(self, key_data=None):
        self.sftp_config = {
            "username": config.get("sftp_user"),
            "password": config.get("sftp_pwd"),
            "host": config.get("sftp_ip"),
            "port": int(config.get("sftp_port", 22))
        }

        self.credential_ok = all(self.sftp_config.values())

        if not self.credential_ok:
            logger.error(
                """
                Missing credentials for sftp connection to NAS. 
                Please update configuration file with :
                - sftp_user
                - sftp_pwd
                - sftp_ip
                - sftp_port (default 22)
                """
            )

        cnopts = pysftp.CnOpts()

        try:
            key = pysftp.RSAKey(data=base64.decodebytes(key_data.encode("utf-8")))
            cnopts.hostkeys.add(config.get("sftp_ip"), "ssh-rsa", key)
        except:
            cnopts.hostkeys = None
            logger.warning(
                "No hostkeys defined in StfpConnection. Connection will be unsecured."
                "Please configure parameter sbc_switzerland.nas_ssh_key"
                "with ssh_key data.")

        self.sftp_config.update({"cnopts": cnopts})

    def get_connection(self, starting_dir=None):
        """
        Use instance config to start a connection with sftp server
        raise AssertionError if credential are not set or IOError if
        starting_dir is not None and points to a not existing directory
        :param starting_dir: (optional) starting dir for the connection
        :return: Return a pysftp connection object
        """

        assert self.credential_ok, "Missing credentials for sftp connection to NAS."

        conn = pysftp.Connection(**self.sftp_config)
        if starting_dir:
            conn.chdir(starting_dir)

        return conn


class ImportLettersHistory(models.Model):
    _inherit = "import.letters.history"

    manual_import = fields.Boolean("Manual import", default=False)

    @api.onchange("data", "import_folder_path")
    def _compute_nber_letters(self):
        to_check = self.filtered(lambda l: l.state != "done")
        others = self - to_check
        for letter in to_check:
            try:
                with letter._get_connection() as sftp:
                    letter.nber_letters = len(sftp.listdir(letter.import_folder_path))
            except (FileNotFoundError, TypeError):
                others += letter
        super(ImportLettersHistory, others)._compute_nber_letters()

    def unlink(self):
        running_job = self.env["queue.job"].search_count([
            ("model_name", "=", self._name),
            ("state", "not in", ["done", "failed", "cancelled"]),
            ("record_ids", "in", self.ids)
        ])
        if running_job:
            raise UserError(_(<commit_msg>Catch SSH errors on letters import count<commit_after>##############################################################################
#
#    Copyright (C) 2014-2015 Compassion CH (http://www.compassion.ch)
#    Releasing children from poverty in Jesus' name
#    @author: <NAME>, <NAME> <<EMAIL>>
#
#    The licence is in the file __manifest__.py
#
##############################################################################
"""
This module reads a zip file containing scans of mail and finds the relation
between the database and the mail.
"""
import base64
import logging
import traceback
from pathlib import Path

from paramiko.ssh_exception import SSHException

from odoo import fields, models, api, _
from odoo.exceptions import UserError
from odoo.tools.config import config
from odoo.addons.queue_job.job import job, related_action

logger = logging.getLogger(__name__)

try:
    from PyPDF2 import PdfFileWriter, PdfFileReader
    from PyPDF2.pdf import PageObject
    import pysftp
except ImportError:
    logger.warning("Please install python dependencies.")


class SftpConnection:
    """
    Class helper used to handle connection between server and SFTP server.
    """

    def __init__(self, key_data=None):
        self.sftp_config = {
            "username": config.get("sftp_user"),
            "password": config.get("sftp_pwd"),
            "host": config.get("sftp_ip"),
            "port": int(config.get("sftp_port", 22))
        }

        self.credential_ok = all(self.sftp_config.values())

        if not self.credential_ok:
            logger.error(
                """
                Missing credentials for sftp connection to NAS. 
                Please update configuration file with :
                - sftp_user
                - sftp_pwd
                - sftp_ip
                - sftp_port (default 22)
                """
            )

        cnopts = pysftp.CnOpts()

        try:
            key = pysftp.RSAKey(data=base64.decodebytes(key_data.encode("utf-8")))
            cnopts.hostkeys.add(config.get("sftp_ip"), "ssh-rsa", key)
        except:
            cnopts.hostkeys = None
            logger.warning(
                "No hostkeys defined in StfpConnection. Connection will be unsecured."
                "Please configure parameter sbc_switzerland.nas_ssh_key"
                "with ssh_key data.")

        self.sftp_config.update({"cnopts": cnopts})

    def get_connection(self, starting_dir=None):
        """
        Use instance config to start a connection with sftp server
        raise AssertionError if credential are not set or IOError if
        starting_dir is not None and points to a not existing directory
        :param starting_dir: (optional) starting dir for the connection
        :return: Return a pysftp connection object
        """

        assert self.credential_ok, "Missing credentials for sftp connection to NAS."

        conn = pysftp.Connection(**self.sftp_config)
        if starting_dir:
            conn.chdir(starting_dir)

        return conn


class ImportLettersHistory(models.Model):
    _inherit = "import.letters.history"

    manual_import = fields.Boolean("Manual import", default=False)

    @api.onchange("data", "import_folder_path")
    def _compute_nber_letters(self):
        to_check = self.filtered(lambda l: l.state != "done")
        others = self - to_check
        for letter in to_check:
            try:
                with letter._get_connection() as sftp:
                    letter.nber_letters = len(sftp.listdir(letter.import_folder_path))
            except (FileNotFoundError, TypeError, SSHException):
                others += letter
        super(ImportLettersHistory, others)._compute_nber_letters()

    def unlink(self):
        running_job = self.env["queue.job"].search_count([
            ("model_name", "=", self._name),
            ("state", "not in", ["done", "failed", "cancelled"]),
            ("record_ids", "in", self.ids)
        ])
        if running_job:
            raise UserError(_(
{'fraction_non_alphanumeric': 0.13002008032128515, 'fraction_numerical': 0.004769076305220884, 'mean_word_length': 2.4768760907504364, 'pattern_counts': {'":': 10, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4145983', 'n_tokens_mistral': 2321, 'n_tokens_neox': 2133, 'n_words': 600}