| 
						
						
							
								
							
						
						
					 | 
					@ -29,6 +29,8 @@ import nextcloud_client | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import os | 
					 | 
					 | 
					import os | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import paramiko | 
					 | 
					 | 
					import paramiko | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import requests | 
					 | 
					 | 
					import requests | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					import shutil | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					import subprocess | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import tempfile | 
					 | 
					 | 
					import tempfile | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import odoo | 
					 | 
					 | 
					import odoo | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from datetime import timedelta | 
					 | 
					 | 
					from datetime import timedelta | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -39,6 +41,7 @@ from odoo import api, fields, models, _ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from odoo.exceptions import UserError, ValidationError | 
					 | 
					 | 
					from odoo.exceptions import UserError, ValidationError | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from odoo.http import request | 
					 | 
					 | 
					from odoo.http import request | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					from odoo.service import db | 
					 | 
					 | 
					from odoo.service import db | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					from odoo.tools import find_pg_tool, exec_pg_environ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					_logger = logging.getLogger(__name__) | 
					 | 
					 | 
					_logger = logging.getLogger(__name__) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					ONEDRIVE_SCOPE = ['offline_access openid Files.ReadWrite.All'] | 
					 | 
					 | 
					ONEDRIVE_SCOPE = ['offline_access openid Files.ReadWrite.All'] | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -619,8 +622,8 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        os.makedirs(rec.backup_path) | 
					 | 
					 | 
					                        os.makedirs(rec.backup_path) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    backup_file = os.path.join(rec.backup_path, | 
					 | 
					 | 
					                    backup_file = os.path.join(rec.backup_path, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                               backup_filename) | 
					 | 
					 | 
					                                               backup_filename) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    f = open(backup_file, "wb") | 
					 | 
					 | 
					                    f = open(backup_file, 'wb') | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    odoo.service.db.dump_db(rec.db_name, f, rec.backup_format) | 
					 | 
					 | 
					                    self.dump_data(rec.db_name, f, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                    f.close() | 
					 | 
					 | 
					                    f.close() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    # Remove older backups | 
					 | 
					 | 
					                    # Remove older backups | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    if rec.auto_remove: | 
					 | 
					 | 
					                    if rec.auto_remove: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -632,8 +635,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            if backup_duration.days >= rec.days_to_remove: | 
					 | 
					 | 
					                            if backup_duration.days >= rec.days_to_remove: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                os.remove(file) | 
					 | 
					 | 
					                                os.remove(file) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    if rec.notify_user: | 
					 | 
					 | 
					                    if rec.notify_user: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                        mail_template_success.send_mail(rec.id, | 
					 | 
					 | 
					                        mail_template_success.send_mail(rec.id, force_send=True) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                                        force_send=True) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                except Exception as e: | 
					 | 
					 | 
					                except Exception as e: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    rec.generated_exception = e | 
					 | 
					 | 
					                    rec.generated_exception = e | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    _logger.info('FTP Exception: %s', e) | 
					 | 
					 | 
					                    _logger.info('FTP Exception: %s', e) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -654,8 +656,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        ftp_server.mkd(rec.ftp_path) | 
					 | 
					 | 
					                        ftp_server.mkd(rec.ftp_path) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        ftp_server.cwd(rec.ftp_path) | 
					 | 
					 | 
					                        ftp_server.cwd(rec.ftp_path) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                    with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                        odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                        self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                                rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                    ftp_server.storbinary('STOR %s' % backup_filename, | 
					 | 
					 | 
					                    ftp_server.storbinary('STOR %s' % backup_filename, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                          open(temp.name, "rb")) | 
					 | 
					 | 
					                                          open(temp.name, "rb")) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    if rec.auto_remove: | 
					 | 
					 | 
					                    if rec.auto_remove: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -690,8 +691,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    temp = tempfile.NamedTemporaryFile( | 
					 | 
					 | 
					                    temp = tempfile.NamedTemporaryFile( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        suffix='.%s' % rec.backup_format) | 
					 | 
					 | 
					                        suffix='.%s' % rec.backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                    with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                        odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                        self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                                rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                    try: | 
					 | 
					 | 
					                    try: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        sftp.chdir(rec.sftp_path) | 
					 | 
					 | 
					                        sftp.chdir(rec.sftp_path) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    except IOError as e: | 
					 | 
					 | 
					                    except IOError as e: | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -727,8 +727,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    temp = tempfile.NamedTemporaryFile( | 
					 | 
					 | 
					                    temp = tempfile.NamedTemporaryFile( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        suffix='.%s' % rec.backup_format) | 
					 | 
					 | 
					                        suffix='.%s' % rec.backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                    with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                        odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                        self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                                rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                    try: | 
					 | 
					 | 
					                    try: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        headers = { | 
					 | 
					 | 
					                        headers = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            "Authorization": "Bearer %s" % rec.gdrive_access_token} | 
					 | 
					 | 
					                            "Authorization": "Bearer %s" % rec.gdrive_access_token} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -787,8 +786,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                temp = tempfile.NamedTemporaryFile( | 
					 | 
					 | 
					                temp = tempfile.NamedTemporaryFile( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    suffix='.%s' % rec.backup_format) | 
					 | 
					 | 
					                    suffix='.%s' % rec.backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                    self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                            rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                try: | 
					 | 
					 | 
					                try: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    dbx = dropbox.Dropbox( | 
					 | 
					 | 
					                    dbx = dropbox.Dropbox( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        app_key=rec.dropbox_client_key, | 
					 | 
					 | 
					                        app_key=rec.dropbox_client_key, | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -822,8 +820,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                temp = tempfile.NamedTemporaryFile( | 
					 | 
					 | 
					                temp = tempfile.NamedTemporaryFile( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    suffix='.%s' % rec.backup_format) | 
					 | 
					 | 
					                    suffix='.%s' % rec.backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                    odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                    self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                            rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                headers = { | 
					 | 
					 | 
					                headers = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    'Authorization': 'Bearer %s' % rec.onedrive_access_token, | 
					 | 
					 | 
					                    'Authorization': 'Bearer %s' % rec.onedrive_access_token, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                    'Content-Type': 'application/json'} | 
					 | 
					 | 
					                    'Content-Type': 'application/json'} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -918,8 +915,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            temp = tempfile.NamedTemporaryFile( | 
					 | 
					 | 
					                            temp = tempfile.NamedTemporaryFile( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                suffix='.%s' % rec.backup_format) | 
					 | 
					 | 
					                                suffix='.%s' % rec.backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                            with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                                self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                                        rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                            backup_file_path = temp.name | 
					 | 
					 | 
					                            backup_file_path = temp.name | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            remote_file_path = f"/{folder_name}/{rec.db_name}_" \ | 
					 | 
					 | 
					                            remote_file_path = f"/{folder_name}/{rec.db_name}_" \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                               f"{backup_time}.{rec.backup_format}" | 
					 | 
					 | 
					                                               f"{backup_time}.{rec.backup_format}" | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -929,8 +925,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            temp = tempfile.NamedTemporaryFile( | 
					 | 
					 | 
					                            temp = tempfile.NamedTemporaryFile( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                suffix='.%s' % rec.backup_format) | 
					 | 
					 | 
					                                suffix='.%s' % rec.backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                            with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                                self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                                        rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                            backup_file_path = temp.name | 
					 | 
					 | 
					                            backup_file_path = temp.name | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            remote_file_path = f"/{folder_name}/{rec.db_name}_" \ | 
					 | 
					 | 
					                            remote_file_path = f"/{folder_name}/{rec.db_name}_" \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                               f"{backup_time}.{rec.backup_format}" | 
					 | 
					 | 
					                                               f"{backup_time}.{rec.backup_format}" | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -989,8 +984,7 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            temp = tempfile.NamedTemporaryFile( | 
					 | 
					 | 
					                            temp = tempfile.NamedTemporaryFile( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                suffix='.%s' % rec.backup_format) | 
					 | 
					 | 
					                                suffix='.%s' % rec.backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            with open(temp.name, "wb+") as tmp: | 
					 | 
					 | 
					                            with open(temp.name, "wb+") as tmp: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					                                odoo.service.db.dump_db(rec.db_name, tmp, | 
					 | 
					 | 
					                                self.dump_data(rec.db_name, tmp, rec.backup_format) | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					                                                        rec.backup_format) | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					                            backup_file_path = temp.name | 
					 | 
					 | 
					                            backup_file_path = temp.name | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            remote_file_path = f"{rec.aws_folder_name}/{rec.db_name}_" \ | 
					 | 
					 | 
					                            remote_file_path = f"{rec.aws_folder_name}/{rec.db_name}_" \ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                               f"{backup_time}.{rec.backup_format}" | 
					 | 
					 | 
					                                               f"{backup_time}.{rec.backup_format}" | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -1012,3 +1006,70 @@ class DbBackupConfigure(models.Model): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                        if rec.notify_user: | 
					 | 
					 | 
					                        if rec.notify_user: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                            mail_template_failed.send_mail(rec.id, | 
					 | 
					 | 
					                            mail_template_failed.send_mail(rec.id, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					                                                           force_send=True) | 
					 | 
					 | 
					                                                           force_send=True) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    def dump_data(self, db_name, stream, backup_format): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        """Dump database `db` into file-like object `stream` if stream is None | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return a file object with the dump. """ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        cron_user_id = self.env.ref( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'auto_database_backup.ir_cron_auto_db_backup').user_id.id | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if cron_user_id != self.env.user.id: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            _logger.error( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                'Unauthorized database operation. Backups should only be available from the cron job.') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            raise ValidationError( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                "Unauthorized database operation. Backups should only be available from the cron job.") | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        _logger.info('DUMP DB: %s format %s', db_name, backup_format) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        cmd = [find_pg_tool('pg_dump'), '--no-owner', db_name] | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        env = exec_pg_environ() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        if backup_format == 'zip': | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            with tempfile.TemporaryDirectory() as dump_dir: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                filestore = odoo.tools.config.filestore(db_name) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                cmd.append('--file=' + os.path.join(dump_dir, 'dump.sql')) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                subprocess.run(cmd, env=env, stdout=subprocess.DEVNULL, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                               stderr=subprocess.STDOUT, check=True) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if os.path.exists(filestore): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    shutil.copytree(filestore, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                    os.path.join(dump_dir, 'filestore')) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                with open(os.path.join(dump_dir, 'manifest.json'), 'w') as fh: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    db = odoo.sql_db.db_connect(db_name) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    with db.cursor() as cr: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        json.dump(self._dump_db_manifest(cr), fh, indent=4) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                if stream: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    odoo.tools.osutil.zip_dir(dump_dir, stream, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                              include_dir=False, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                              fnct_sort=lambda | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                                  file_name: file_name != 'dump.sql') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                else: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    t = tempfile.TemporaryFile() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    odoo.tools.osutil.zip_dir(dump_dir, t, include_dir=False, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                              fnct_sort=lambda | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                                  file_name: file_name != 'dump.sql') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    t.seek(0) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    return t | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        else: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            cmd.append('--format=c') | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            process = subprocess.Popen(cmd, env=env, stdout=subprocess.PIPE) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            stdout, _ = process.communicate() | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            if stream: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                stream.write(stdout) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            else: | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                return stdout | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    def _dump_db_manifest(self, cr): | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        """ This function generates a manifest dictionary for database dump.""" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        pg_version = "%d.%d" % divmod(cr._obj.connection.server_version / 100, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                                      100) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        cr.execute( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            "SELECT name, latest_version FROM ir_module_module WHERE state = 'installed'") | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        modules = dict(cr.fetchall()) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        manifest = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'odoo_dump': '1', | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'db_name': cr.dbname, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'version': odoo.release.version, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'version_info': odoo.release.version_info, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'major_version': odoo.release.major_version, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'pg_version': pg_version, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            'modules': modules, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        return manifest | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					
  |