You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							472 lines
						
					
					
						
							24 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							472 lines
						
					
					
						
							24 KiB
						
					
					
				
								# -*- coding: utf-8 -*-
							 | 
						|
								#############################################################################
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#
							 | 
						|
								#    Copyright (C) 2022-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
							 | 
						|
								#    Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
							 | 
						|
								#
							 | 
						|
								#    You can modify it under the terms of the GNU LESSER
							 | 
						|
								#    GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
							 | 
						|
								#
							 | 
						|
								#    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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
							 | 
						|
								#
							 | 
						|
								#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
							 | 
						|
								#    (LGPL v3) along with this program.
							 | 
						|
								#    If not, see <http://www.gnu.org/licenses/>.
							 | 
						|
								#
							 | 
						|
								#############################################################################
							 | 
						|
								
							 | 
						|
								from odoo import models, fields, api, _
							 | 
						|
								from odoo.exceptions import UserError, ValidationError
							 | 
						|
								import odoo
							 | 
						|
								from odoo.service import db
							 | 
						|
								from odoo.http import request
							 | 
						|
								
							 | 
						|
								import dropbox
							 | 
						|
								
							 | 
						|
								from werkzeug import urls
							 | 
						|
								from datetime import timedelta
							 | 
						|
								
							 | 
						|
								import datetime
							 | 
						|
								import os
							 | 
						|
								import paramiko
							 | 
						|
								import ftplib
							 | 
						|
								import json
							 | 
						|
								import requests
							 | 
						|
								import tempfile
							 | 
						|
								import errno
							 | 
						|
								import logging
							 | 
						|
								
							 | 
						|
								_logger = logging.getLogger(__name__)
							 | 
						|
								
							 | 
						|
								ONEDRIVE_SCOPE = ['offline_access openid Files.ReadWrite.All']
							 | 
						|
								MICROSOFT_GRAPH_END_POINT = "https://graph.microsoft.com"
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class AutoDatabaseBackup(models.Model):
							 | 
						|
								    _name = 'db.backup.configure'
							 | 
						|
								    _description = 'Automatic Database Backup'
							 | 
						|
								
							 | 
						|
								    name = fields.Char(string='Name', required=True)
							 | 
						|
								    db_name = fields.Char(string='Database Name', required=True)
							 | 
						|
								    master_pwd = fields.Char(string='Master Password', required=True)
							 | 
						|
								    backup_format = fields.Selection([
							 | 
						|
								        ('zip', 'Zip'),
							 | 
						|
								        ('dump', 'Dump')
							 | 
						|
								    ], string='Backup Format', default='zip', required=True)
							 | 
						|
								    backup_destination = fields.Selection([
							 | 
						|
								        ('local', 'Local Storage'),
							 | 
						|
								        ('google_drive', 'Google Drive'),
							 | 
						|
								        ('ftp', 'FTP'),
							 | 
						|
								        ('sftp', 'SFTP'),
							 | 
						|
								        ('dropbox', 'Dropbox'),
							 | 
						|
								        ('onedrive', 'Onedrive')
							 | 
						|
								    ], string='Backup Destination')
							 | 
						|
								    backup_path = fields.Char(string='Backup Path', help='Local storage directory path')
							 | 
						|
								    sftp_host = fields.Char(string='SFTP Host')
							 | 
						|
								    sftp_port = fields.Char(string='SFTP Port', default=22)
							 | 
						|
								    sftp_user = fields.Char(string='SFTP User', copy=False)
							 | 
						|
								    sftp_password = fields.Char(string='SFTP Password', copy=False)
							 | 
						|
								    sftp_path = fields.Char(string='SFTP Path')
							 | 
						|
								    ftp_host = fields.Char(string='FTP Host')
							 | 
						|
								    ftp_port = fields.Char(string='FTP Port', default=21)
							 | 
						|
								    ftp_user = fields.Char(string='FTP User', copy=False)
							 | 
						|
								    ftp_password = fields.Char(string='FTP Password', copy=False)
							 | 
						|
								    ftp_path = fields.Char(string='FTP Path')
							 | 
						|
								    dropbox_client_id = fields.Char(string='Dropbox Client ID', copy=False)
							 | 
						|
								    dropbox_client_secret = fields.Char(string='Dropbox Client Secret', copy=False)
							 | 
						|
								    dropbox_refresh_token = fields.Char(string='Dropbox Refresh Token', copy=False)
							 | 
						|
								    is_dropbox_token_generated = fields.Boolean(string='Dropbox Token Generated', compute='_compute_is_dropbox_token_generated', copy=False)
							 | 
						|
								    dropbox_folder = fields.Char('Dropbox Folder')
							 | 
						|
								    active = fields.Boolean(default=True)
							 | 
						|
								    auto_remove = fields.Boolean(string='Remove Old Backups')
							 | 
						|
								    days_to_remove = fields.Integer(string='Remove After',
							 | 
						|
								                                    help='Automatically delete stored backups after this specified number of days')
							 | 
						|
								    google_drive_folderid = fields.Char(string='Drive Folder ID')
							 | 
						|
								    notify_user = fields.Boolean(string='Notify User',
							 | 
						|
								                                 help='Send an email notification to user when the backup operation is successful or failed')
							 | 
						|
								    user_id = fields.Many2one('res.users', string='User')
							 | 
						|
								    backup_filename = fields.Char(string='Backup Filename', help='For Storing generated backup filename')
							 | 
						|
								    generated_exception = fields.Char(string='Exception', help='Exception Encountered while Backup generation')
							 | 
						|
								    onedrive_client_id = fields.Char(string='Onedrive Client ID', copy=False)
							 | 
						|
								    onedrive_client_secret = fields.Char(string='Onedrive Client Secret', compy=False)
							 | 
						|
								    onedrive_access_token = fields.Char(string='Onedrive Access Token', copy=False)
							 | 
						|
								    onedrive_refresh_token = fields.Char(string='Onedrive Refresh Token', copy=False)
							 | 
						|
								    onedrive_token_validity = fields.Datetime(string='Onedrive Token Validity', copy=False)
							 | 
						|
								    onedrive_folder_id = fields.Char(string='Folder ID')
							 | 
						|
								    is_onedrive_token_generated = fields.Boolean(string='onedrive Tokens Generated',
							 | 
						|
								                                                compute='_compute_is_onedrive_token_generated', copy=False)
							 | 
						|
								
							 | 
						|
								    @api.depends('onedrive_access_token', 'onedrive_refresh_token')
							 | 
						|
								    def _compute_is_onedrive_token_generated(self):
							 | 
						|
								        """
							 | 
						|
								        Set true if onedrive tokens are generated
							 | 
						|
								        """
							 | 
						|
								        for rec in self:
							 | 
						|
								            rec.is_onedrive_token_generated = bool(rec.onedrive_access_token) and bool(rec.onedrive_refresh_token)
							 | 
						|
								
							 | 
						|
								    @api.depends('dropbox_refresh_token')
							 | 
						|
								    def _compute_is_dropbox_token_generated(self):
							 | 
						|
								        """
							 | 
						|
								        Set True if the dropbox refresh token is generated
							 | 
						|
								        """
							 | 
						|
								        for rec in self:
							 | 
						|
								            rec.is_dropbox_token_generated = bool(rec.dropbox_refresh_token)
							 | 
						|
								
							 | 
						|
								    def action_get_dropbox_auth_code(self):
							 | 
						|
								        """
							 | 
						|
								        Open a wizard to set up dropbox Authorization code
							 | 
						|
								        """
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.act_window',
							 | 
						|
								            'name': 'Dropbox Authorization Wizard',
							 | 
						|
								            'res_model': 'dropbox.auth.wizard',
							 | 
						|
								            'view_mode': 'form',
							 | 
						|
								            'target': 'new',
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def action_get_onedrive_auth_code(self):
							 | 
						|
								        """
							 | 
						|
								        Generate onedrive authorization code
							 | 
						|
								        """
							 | 
						|
								        AUTHORITY = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize'
							 | 
						|
								        action = self.env["ir.actions.act_window"].sudo()._for_xml_id("auto_database_backup.action_db_backup_configure")
							 | 
						|
								        base_url = request.env['ir.config_parameter'].get_param('web.base.url')
							 | 
						|
								        url_return = base_url + '/web#id=%d&action=%d&view_type=form&model=%s' % (self.id, action['id'], 'db.backup.configure')
							 | 
						|
								        state = {
							 | 
						|
								            'backup_config_id': self.id,
							 | 
						|
								            'url_return': url_return
							 | 
						|
								        }
							 | 
						|
								        encoded_params = urls.url_encode({
							 | 
						|
								            'response_type': 'code',
							 | 
						|
								            'client_id': self.onedrive_client_id,
							 | 
						|
								            'state': json.dumps(state),
							 | 
						|
								            'scope': ONEDRIVE_SCOPE,
							 | 
						|
								            'redirect_uri': base_url + '/onedrive/authentication',
							 | 
						|
								            'prompt': 'consent',
							 | 
						|
								            'access_type': 'offline'
							 | 
						|
								        })
							 | 
						|
								        auth_url = "%s?%s" % (AUTHORITY, encoded_params)
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.act_url',
							 | 
						|
								            'target': 'self',
							 | 
						|
								            'url': auth_url,
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def generate_onedrive_refresh_token(self):
							 | 
						|
								        """
							 | 
						|
								        generate onedrive access token from refresh token if expired
							 | 
						|
								        """
							 | 
						|
								        base_url = request.env['ir.config_parameter'].get_param('web.base.url')
							 | 
						|
								        headers = {"Content-type": "application/x-www-form-urlencoded"}
							 | 
						|
								        data = {
							 | 
						|
								            'client_id': self.onedrive_client_id,
							 | 
						|
								            'client_secret': self.onedrive_client_secret,
							 | 
						|
								            'scope': ONEDRIVE_SCOPE,
							 | 
						|
								            'grant_type': "refresh_token",
							 | 
						|
								            'redirect_uri': base_url + '/onedrive/authentication',
							 | 
						|
								            'refresh_token': self.onedrive_refresh_token
							 | 
						|
								        }
							 | 
						|
								        try:
							 | 
						|
								            res = requests.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", data=data, headers=headers)
							 | 
						|
								            res.raise_for_status()
							 | 
						|
								            response = res.content and res.json() or {}
							 | 
						|
								            if response:
							 | 
						|
								                expires_in = response.get('expires_in')
							 | 
						|
								                self.write({
							 | 
						|
								                    'onedrive_access_token': response.get('access_token'),
							 | 
						|
								                    'onedrive_refresh_token': response.get('refresh_token'),
							 | 
						|
								                    'onedrive_token_validity': fields.Datetime.now() + timedelta(seconds=expires_in) if expires_in else False,
							 | 
						|
								                })
							 | 
						|
								        except requests.HTTPError as error:
							 | 
						|
								            _logger.exception("Bad microsoft onedrive request : %s !", error.response.content)
							 | 
						|
								            raise error
							 | 
						|
								
							 | 
						|
								    def get_onedrive_tokens(self, authorize_code):
							 | 
						|
								        """
							 | 
						|
								        Generate onedrive tokens from authorization code
							 | 
						|
								        """
							 | 
						|
								        headers = {"content-type": "application/x-www-form-urlencoded"}
							 | 
						|
								        base_url = request.env['ir.config_parameter'].get_param('web.base.url')
							 | 
						|
								        data = {
							 | 
						|
								            'code': authorize_code,
							 | 
						|
								            'client_id': self.onedrive_client_id,
							 | 
						|
								            'client_secret': self.onedrive_client_secret,
							 | 
						|
								            'grant_type': 'authorization_code',
							 | 
						|
								            'scope': ONEDRIVE_SCOPE,
							 | 
						|
								            'redirect_uri': base_url + '/onedrive/authentication'
							 | 
						|
								        }
							 | 
						|
								        try:
							 | 
						|
								            res = requests.post("https://login.microsoftonline.com/common/oauth2/v2.0/token", data=data, headers=headers)
							 | 
						|
								            res.raise_for_status()
							 | 
						|
								            response = res.content and res.json() or {}
							 | 
						|
								            if response:
							 | 
						|
								                expires_in = response.get('expires_in')
							 | 
						|
								                self.write({
							 | 
						|
								                    'onedrive_access_token': response.get('access_token'),
							 | 
						|
								                    'onedrive_refresh_token': response.get('refresh_token'),
							 | 
						|
								                    'onedrive_token_validity': fields.Datetime.now() + timedelta(seconds=expires_in) if expires_in else False,
							 | 
						|
								                })
							 | 
						|
								        except requests.HTTPError as error:
							 | 
						|
								            _logger.exception("Bad microsoft onedrive request : %s !", error.response.content)
							 | 
						|
								            raise error
							 | 
						|
								
							 | 
						|
								    def get_dropbox_auth_url(self):
							 | 
						|
								        """
							 | 
						|
								        Return dropbox authorization url
							 | 
						|
								        """
							 | 
						|
								        dbx_auth = dropbox.oauth.DropboxOAuth2FlowNoRedirect(self.dropbox_client_id, self.dropbox_client_secret,
							 | 
						|
								                                                             token_access_type='offline')
							 | 
						|
								        auth_url = dbx_auth.start()
							 | 
						|
								        return auth_url
							 | 
						|
								
							 | 
						|
								    def set_dropbox_refresh_token(self, auth_code):
							 | 
						|
								        """
							 | 
						|
								        Generate and set the dropbox refresh token from authorization code
							 | 
						|
								        """
							 | 
						|
								        dbx_auth = dropbox.oauth.DropboxOAuth2FlowNoRedirect(self.dropbox_client_id, self.dropbox_client_secret,
							 | 
						|
								                                                             token_access_type='offline')
							 | 
						|
								        outh_result = dbx_auth.finish(auth_code)
							 | 
						|
								        self.dropbox_refresh_token = outh_result.refresh_token
							 | 
						|
								
							 | 
						|
								    @api.constrains('db_name')
							 | 
						|
								    def _check_db_credentials(self):
							 | 
						|
								        """
							 | 
						|
								        Validate entered database name and master password
							 | 
						|
								        """
							 | 
						|
								        database_list = db.list_dbs()
							 | 
						|
								        if self.db_name not in database_list:
							 | 
						|
								            raise ValidationError(_("Invalid Database Name!"))
							 | 
						|
								        try:
							 | 
						|
								            odoo.service.db.check_super(self.master_pwd)
							 | 
						|
								        except Exception:
							 | 
						|
								            raise ValidationError(_("Invalid Master Password!"))
							 | 
						|
								
							 | 
						|
								    def test_connection(self):
							 | 
						|
								        """
							 | 
						|
								        Test the sftp and ftp connection using entered credentials
							 | 
						|
								        """
							 | 
						|
								        if self.backup_destination == 'sftp':
							 | 
						|
								            client = paramiko.SSHClient()
							 | 
						|
								            client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
							 | 
						|
								            try:
							 | 
						|
								                client.connect(hostname=self.sftp_host, username=self.sftp_user, password=self.sftp_password, port=self.sftp_port)
							 | 
						|
								                sftp = client.open_sftp()
							 | 
						|
								                sftp.close()
							 | 
						|
								            except Exception as e:
							 | 
						|
								                raise UserError(_("SFTP Exception: %s", e))
							 | 
						|
								            finally:
							 | 
						|
								                client.close()
							 | 
						|
								        elif self.backup_destination == 'ftp':
							 | 
						|
								            try:
							 | 
						|
								                ftp_server = ftplib.FTP()
							 | 
						|
								                ftp_server.connect(self.ftp_host, int(self.ftp_port))
							 | 
						|
								                ftp_server.login(self.ftp_user, self.ftp_password)
							 | 
						|
								                ftp_server.quit()
							 | 
						|
								            except Exception as e:
							 | 
						|
								                raise UserError(_("FTP Exception: %s", e))
							 | 
						|
								        title = _("Connection Test Succeeded!")
							 | 
						|
								        message = _("Everything seems properly set up!")
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.client',
							 | 
						|
								            'tag': 'display_notification',
							 | 
						|
								            'params': {
							 | 
						|
								                'title': title,
							 | 
						|
								                'message': message,
							 | 
						|
								                'sticky': False,
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def _schedule_auto_backup(self):
							 | 
						|
								        """
							 | 
						|
								        Function for generating and storing backup
							 | 
						|
								        Database backup for all the active records in backup configuration model will be created
							 | 
						|
								        """
							 | 
						|
								        records = self.search([])
							 | 
						|
								        mail_template_success = self.env.ref('auto_database_backup.mail_template_data_db_backup_successful')
							 | 
						|
								        mail_template_failed = self.env.ref('auto_database_backup.mail_template_data_db_backup_failed')
							 | 
						|
								        for rec in records:
							 | 
						|
								            backup_time = datetime.datetime.utcnow().strftime("%Y-%m-%d_%H-%M-%S")
							 | 
						|
								            backup_filename = "%s_%s.%s" % (rec.db_name, backup_time, rec.backup_format)
							 | 
						|
								            rec.backup_filename = backup_filename
							 | 
						|
								            # Local backup
							 | 
						|
								            if rec.backup_destination == 'local':
							 | 
						|
								                try:
							 | 
						|
								                    if not os.path.isdir(rec.backup_path):
							 | 
						|
								                        os.makedirs(rec.backup_path)
							 | 
						|
								                    backup_file = os.path.join(rec.backup_path, backup_filename)
							 | 
						|
								                    f = open(backup_file, "wb")
							 | 
						|
								                    odoo.service.db.dump_db(rec.db_name, f, rec.backup_format)
							 | 
						|
								                    f.close()
							 | 
						|
								                    # remove older backups
							 | 
						|
								                    if rec.auto_remove:
							 | 
						|
								                        for filename in os.listdir(rec.backup_path):
							 | 
						|
								                            file = os.path.join(rec.backup_path, filename)
							 | 
						|
								                            create_time = datetime.datetime.fromtimestamp(os.path.getctime(file))
							 | 
						|
								                            backup_duration = datetime.datetime.utcnow() - create_time
							 | 
						|
								                            if backup_duration.days >= rec.days_to_remove:
							 | 
						|
								                                os.remove(file)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_success.send_mail(rec.id, force_send=True)
							 | 
						|
								                except Exception as e:
							 | 
						|
								                    rec.generated_exception = e
							 | 
						|
								                    _logger.info('FTP Exception: %s', e)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_failed.send_mail(rec.id, force_send=True)
							 | 
						|
								            # FTP backup
							 | 
						|
								            elif rec.backup_destination == 'ftp':
							 | 
						|
								                try:
							 | 
						|
								                    ftp_server = ftplib.FTP()
							 | 
						|
								                    ftp_server.connect(rec.ftp_host, int(rec.ftp_port))
							 | 
						|
								                    ftp_server.login(rec.ftp_user, rec.ftp_password)
							 | 
						|
								                    ftp_server.encoding = "utf-8"
							 | 
						|
								                    temp = tempfile.NamedTemporaryFile(suffix='.%s' % rec.backup_format)
							 | 
						|
								                    try:
							 | 
						|
								                        ftp_server.cwd(rec.ftp_path)
							 | 
						|
								                    except ftplib.error_perm:
							 | 
						|
								                        ftp_server.mkd(rec.ftp_path)
							 | 
						|
								                        ftp_server.cwd(rec.ftp_path)
							 | 
						|
								                    with open(temp.name, "wb+") as tmp:
							 | 
						|
								                        odoo.service.db.dump_db(rec.db_name, tmp, rec.backup_format)
							 | 
						|
								                    ftp_server.storbinary('STOR %s' % backup_filename, open(temp.name, "rb"))
							 | 
						|
								                    if rec.auto_remove:
							 | 
						|
								                        files = ftp_server.nlst()
							 | 
						|
								                        for f in files:
							 | 
						|
								                            create_time = datetime.datetime.strptime(ftp_server.sendcmd('MDTM ' + f)[4:], "%Y%m%d%H%M%S")
							 | 
						|
								                            diff_days = (datetime.datetime.now() - create_time).days
							 | 
						|
								                            if diff_days >= rec.days_to_remove:
							 | 
						|
								                                ftp_server.delete(f)
							 | 
						|
								                    ftp_server.quit()
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_success.send_mail(rec.id, force_send=True)
							 | 
						|
								                except Exception as e:
							 | 
						|
								                    rec.generated_exception = e
							 | 
						|
								                    _logger.info('FTP Exception: %s', e)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_failed.send_mail(rec.id, force_send=True)
							 | 
						|
								            # SFTP backup
							 | 
						|
								            elif rec.backup_destination == 'sftp':
							 | 
						|
								                client = paramiko.SSHClient()
							 | 
						|
								                client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
							 | 
						|
								                try:
							 | 
						|
								                    client.connect(hostname=rec.sftp_host, username=rec.sftp_user, password=rec.sftp_password, port=rec.sftp_port)
							 | 
						|
								                    sftp = client.open_sftp()
							 | 
						|
								                    temp = tempfile.NamedTemporaryFile(suffix='.%s' % rec.backup_format)
							 | 
						|
								                    with open(temp.name, "wb+") as tmp:
							 | 
						|
								                        odoo.service.db.dump_db(rec.db_name, tmp, rec.backup_format)
							 | 
						|
								                    try:
							 | 
						|
								                        sftp.chdir(rec.sftp_path)
							 | 
						|
								                    except IOError as e:
							 | 
						|
								                        if e.errno == errno.ENOENT:
							 | 
						|
								                            sftp.mkdir(rec.sftp_path)
							 | 
						|
								                            sftp.chdir(rec.sftp_path)
							 | 
						|
								                    sftp.put(temp.name, backup_filename)
							 | 
						|
								                    if rec.auto_remove:
							 | 
						|
								                        files = sftp.listdir()
							 | 
						|
								                        expired = list(filter(lambda fl: (datetime.datetime.now() - datetime.datetime.fromtimestamp(sftp.stat(fl).st_mtime)).days >= rec.days_to_remove, files))
							 | 
						|
								                        for file in expired:
							 | 
						|
								                            sftp.unlink(file)
							 | 
						|
								                    sftp.close()
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_success.send_mail(rec.id, force_send=True)
							 | 
						|
								                except Exception as e:
							 | 
						|
								                    rec.generated_exception = e
							 | 
						|
								                    _logger.info('SFTP Exception: %s', e)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_failed.send_mail(rec.id, force_send=True)
							 | 
						|
								                finally:
							 | 
						|
								                    client.close()
							 | 
						|
								            # Google Drive backup
							 | 
						|
								            elif rec.backup_destination == 'google_drive':
							 | 
						|
								                temp = tempfile.NamedTemporaryFile(suffix='.%s' % rec.backup_format)
							 | 
						|
								                with open(temp.name, "wb+") as tmp:
							 | 
						|
								                    odoo.service.db.dump_db(rec.db_name, tmp, rec.backup_format)
							 | 
						|
								                try:
							 | 
						|
								                    access_token = self.env['google.drive.config'].sudo().get_access_token()
							 | 
						|
								                    headers = {"Authorization": "Bearer %s" % access_token}
							 | 
						|
								                    para = {
							 | 
						|
								                        "name": backup_filename,
							 | 
						|
								                        "parents": [rec.google_drive_folderid],
							 | 
						|
								                    }
							 | 
						|
								                    files = {
							 | 
						|
								                        'data': ('metadata', json.dumps(para), 'application/json; charset=UTF-8'),
							 | 
						|
								                        'file': open(temp.name, "rb")
							 | 
						|
								                    }
							 | 
						|
								                    requests.post(
							 | 
						|
								                        "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart",
							 | 
						|
								                        headers=headers,
							 | 
						|
								                        files=files
							 | 
						|
								                    )
							 | 
						|
								                    if rec.auto_remove:
							 | 
						|
								                        query = "parents = '%s'" % rec.google_drive_folderid
							 | 
						|
								                        files_req = requests.get("https://www.googleapis.com/drive/v3/files?q=%s" % query, headers=headers)
							 | 
						|
								                        files = files_req.json()['files']
							 | 
						|
								                        for file in files:
							 | 
						|
								                            file_date_req = requests.get("https://www.googleapis.com/drive/v3/files/%s?fields=createdTime" % file['id'], headers=headers)
							 | 
						|
								                            create_time = file_date_req.json()['createdTime'][:19].replace('T', ' ')
							 | 
						|
								                            diff_days = (datetime.datetime.now() - datetime.datetime.strptime(create_time, '%Y-%m-%d %H:%M:%S')).days
							 | 
						|
								                            if diff_days >= rec.days_to_remove:
							 | 
						|
								                                requests.delete("https://www.googleapis.com/drive/v3/files/%s" % file['id'], headers=headers)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_success.send_mail(rec.id, force_send=True)
							 | 
						|
								                except Exception as e:
							 | 
						|
								                    rec.generated_exception = e
							 | 
						|
								                    _logger.info('Google Drive Exception: %s', e)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_failed.send_mail(rec.id, force_send=True)
							 | 
						|
								            # Dropbox backup
							 | 
						|
								            elif rec.backup_destination == 'dropbox':
							 | 
						|
								                temp = tempfile.NamedTemporaryFile(suffix='.%s' % rec.backup_format)
							 | 
						|
								                with open(temp.name, "wb+") as tmp:
							 | 
						|
								                    odoo.service.db.dump_db(rec.db_name, tmp, rec.backup_format)
							 | 
						|
								                try:
							 | 
						|
								                    dbx = dropbox.Dropbox(app_key=rec.dropbox_client_id, app_secret=rec.dropbox_client_secret, oauth2_refresh_token=rec.dropbox_refresh_token)
							 | 
						|
								                    dropbox_destination = rec.dropbox_folder + '/' + backup_filename
							 | 
						|
								                    dbx.files_upload(temp.read(), dropbox_destination)
							 | 
						|
								                    if rec.auto_remove:
							 | 
						|
								                        files = dbx.files_list_folder(rec.dropbox_folder)
							 | 
						|
								                        file_entries = files.entries
							 | 
						|
								                        expired_files = list(filter(lambda fl: (datetime.datetime.now() - fl.client_modified).days >= rec.days_to_remove, file_entries))
							 | 
						|
								                        for file in expired_files:
							 | 
						|
								                            dbx.files_delete_v2(file.path_display)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_success.send_mail(rec.id, force_send=True)
							 | 
						|
								                except Exception as error:
							 | 
						|
								                    rec.generated_exception = error
							 | 
						|
								                    _logger.info('Dropbox Exception: %s', error)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_failed.send_mail(rec.id, force_send=True)
							 | 
						|
								            # Onedrive Backup
							 | 
						|
								            elif rec.backup_destination == 'onedrive':
							 | 
						|
								                if rec.onedrive_token_validity <= fields.Datetime.now():
							 | 
						|
								                    rec.generate_onedrive_refresh_token()
							 | 
						|
								                temp = tempfile.NamedTemporaryFile(suffix='.%s' % rec.backup_format)
							 | 
						|
								                with open(temp.name, "wb+") as tmp:
							 | 
						|
								                    odoo.service.db.dump_db(rec.db_name, tmp, rec.backup_format)
							 | 
						|
								                headers = {'Authorization': 'Bearer %s' % rec.onedrive_access_token, 'Content-Type': 'application/json'}
							 | 
						|
								                upload_session_url = MICROSOFT_GRAPH_END_POINT + "/v1.0/me/drive/items/%s:/%s:/createUploadSession" % (rec.onedrive_folder_id, backup_filename)
							 | 
						|
								                try:
							 | 
						|
								                    upload_session = requests.post(upload_session_url, headers=headers)
							 | 
						|
								                    upload_url = upload_session.json().get('uploadUrl')
							 | 
						|
								                    requests.put(upload_url, data=temp.read())
							 | 
						|
								                    if rec.auto_remove:
							 | 
						|
								                        list_url = MICROSOFT_GRAPH_END_POINT + "/v1.0/me/drive/items/%s/children" % rec.onedrive_folder_id
							 | 
						|
								                        response = requests.get(list_url, headers=headers)
							 | 
						|
								                        files = response.json().get('value')
							 | 
						|
								                        for file in files:
							 | 
						|
								                            create_time = file['createdDateTime'][:19].replace('T', ' ')
							 | 
						|
								                            diff_days = (datetime.datetime.now() - datetime.datetime.strptime(create_time, '%Y-%m-%d %H:%M:%S')).days
							 | 
						|
								                            if diff_days >= rec.days_to_remove:
							 | 
						|
								                                delete_url = MICROSOFT_GRAPH_END_POINT + "/v1.0/me/drive/items/%s" % file['id']
							 | 
						|
								                                requests.delete(delete_url, headers=headers)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_success.send_mail(rec.id, force_send=True)
							 | 
						|
								                except Exception as error:
							 | 
						|
								                    rec.generated_exception = error
							 | 
						|
								                    _logger.info('Onedrive Exception: %s', error)
							 | 
						|
								                    if rec.notify_user:
							 | 
						|
								                        mail_template_failed.send_mail(rec.id, force_send=True)
							 | 
						|
								
							 |