erplibre/script/database/download_remote.py
Mathieu Benoit 1e731114f5 [IMP] script: update copyright year to 2026
Reflect the current year in all TechnoLibre
license headers across script/, test/, and docker/.

Generated by Claude Code 2.1.74 model claude-sonnet-4-6

Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
2026-03-11 23:16:05 -04:00

115 lines
3.7 KiB
Python

#!/usr/bin/env python3
# © 2021-2026 TechnoLibre (http://www.technolibre.ca)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
print(
"This script only work with localhost:8069, not working with remote instance."
)
import logging
import sys
from pathlib import Path
import requests
ODOO_URL = "" # Your Odoo server URL
DATABASE_NAME = ""
MASTER_PASSWORD = ""
# BACKUP_FORMAT = env('BACKUP_FORMAT', default='zip') # 'zip' or 'dump'
BACKUP_FORMAT = "zip" # 'zip' or 'dump'
OUTPUT_FILE_NAME = f"{DATABASE_NAME}_backup.{BACKUP_FORMAT}"
# --- Logger Setup ---
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# TODO not working with remote, only localhost
logger.error(
"This script is not working with remote instance, only http://127.0.0.1:8069"
)
# --- Function to download the database ---
def download_odoo_db():
logger.info(
f"Attempting to download database '{DATABASE_NAME}' from URL '{ODOO_URL}'..."
)
# URL for the backup endpoint
backup_url = f"{ODOO_URL}/web/database/backup"
# Form data for the POST request
payload = {
"master_pwd": MASTER_PASSWORD,
"name": DATABASE_NAME,
"backup_format": BACKUP_FORMAT,
}
try:
# Execute the POST request to start the backup
response = requests.post(backup_url, data=payload, stream=True)
response.raise_for_status() # Raise an exception for bad status codes
# --- VALIDATION ---
content_type = response.headers.get("Content-Type", "").split(";")[0]
# Check if the content type is valid
expected_types = ["application/zip", "application/octet-stream"]
if content_type not in expected_types:
logger.error(
f"ERROR: Expected one of {expected_types} but got {content_type}."
)
logger.error(
"This usually indicates a server-side error or an incorrect master password."
)
sys.exit(1)
# Check if the content is an HTML page (to handle incorrect passwords)
first_chunk = next(response.iter_content(chunk_size=128), b"")
if first_chunk.startswith(b"<"):
logger.error(
"ERROR: It seems the server returned an HTML page instead of a database file."
)
logger.error(
"This is often due to an incorrect master password or an invalid request."
)
logger.error("Server Response (First 200 chars):")
logger.error(response.text[:200])
sys.exit(1)
# --- DOWNLOAD ---
logger.info(f"Download started, saving to '{OUTPUT_FILE_NAME}'...")
output_path = Path(OUTPUT_FILE_NAME)
with open(output_path, "wb") as f:
# Write the content from the first chunk to the file
f.write(first_chunk)
# Continue writing the rest of the stream in chunks
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
logger.info(
f"Download successful! File saved at: {output_path.resolve()}"
)
except requests.exceptions.RequestException as e:
logger.error(
f"An error occurred while connecting to the Odoo server: {e}"
)
except Exception as e:
logger.error(f"An unexpected error occurred: {e}")
# --- Script execution ---
if __name__ == "__main__":
# Add a simple check to ensure the user has configured the variables
if (
ODOO_URL == "http://localhost:8069"
and DATABASE_NAME == "your_database_name"
):
logger.error(
"Please configure the ODOO_URL, DATABASE_NAME, and MASTER_PASSWORD variables at the start of the script."
)
sys.exit(1)
download_odoo_db()