mirror of
https://codeberg.org/vlw/cloud-backup.git
synced 2025-09-14 01:53:42 +02:00

* wip(22w9a): sql param fix * wip(22w9b): add azure * wip(22w9c): add single item backup * wip(22w10a): add logger * wip(22w11a): add aws support * Update README.md
110 lines
No EOL
3.4 KiB
Python
110 lines
No EOL
3.4 KiB
Python
import os
|
|
import logging
|
|
from logging.handlers import RotatingFileHandler
|
|
from typing import Union
|
|
|
|
from .cloud import Storage as StorageClient
|
|
from . import Database, FileSystem
|
|
from . import dbname
|
|
|
|
class Backup(FileSystem):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.enable_logging()
|
|
|
|
self.has_change = False
|
|
|
|
self.db = Database()
|
|
self.cloud = StorageClient()
|
|
|
|
self.compress = self.db.get_flag("COMPRESS")
|
|
|
|
# Configure logging
|
|
def enable_logging(self):
|
|
self.log = logging.getLogger(__name__)
|
|
self.log.debug("Start console logging")
|
|
log_format = logging.Formatter("[%(asctime)s][%(levelname)s]: %(name)s: %(message)s")
|
|
|
|
# Log to console
|
|
log_console = logging.StreamHandler()
|
|
log_console.setLevel(logging.INFO)
|
|
log_console.setFormatter(log_format)
|
|
|
|
self.log.addHandler(log_console)
|
|
|
|
# Log to file
|
|
log_file_path = os.getenv("LOG_FILE")
|
|
if log_file_path:
|
|
self.log.debug("Start file logging")
|
|
log_file = RotatingFileHandler(
|
|
log_file_path,
|
|
mode = "a",
|
|
maxBytes = 50 * 1024 * 1024,
|
|
backupCount = 5,
|
|
encoding = None,
|
|
delay = False
|
|
)
|
|
|
|
log_file.setLevel(os.getenv("LOG_LEVEL"))
|
|
log_file.setFormatter(log_format)
|
|
|
|
self.log.addHandler(log_file)
|
|
|
|
# Backup a file or folder
|
|
def backup_item(self, item: Union[list, str], silent: bool = True) -> bool:
|
|
if isinstance(item, str):
|
|
item = self.get_item(item)
|
|
|
|
# Check item against db if it has changed
|
|
db_resp = self.db.check_item(item)
|
|
if not db_resp:
|
|
return
|
|
|
|
# Back up changes to database in silence
|
|
if item[0].endswith(dbname):
|
|
self.db.set_item(item)
|
|
return
|
|
|
|
self.has_change = True
|
|
|
|
self.log.info(f"'{item[0]}': Uploading")
|
|
print(f"⏳ | Uploading: '{item[0]}'", end="\r")
|
|
|
|
blob = item
|
|
# Upload as zip archive
|
|
if self.compress:
|
|
self.log.debug(f"'{item[0]}': Compressing")
|
|
blob = FileSystem.zip(blob)
|
|
|
|
# Upload to cloud
|
|
if self.cloud.upload(blob):
|
|
self.log.debug(f"'{item[0]}': Uploaded")
|
|
print(f"✅ | Upload successful: '{item[0]}'")
|
|
# Update local database
|
|
if not self.db.set_item(item):
|
|
self.log.warn(f"'{item[0]}': Failed to update database")
|
|
print("⚠️ | Failed to update database")
|
|
else:
|
|
self.log.error(f"'{item[0]}': {self.cloud.error}")
|
|
print(f"❌ | Upload failed: '{item[0]}'")
|
|
|
|
# Remove temp zip
|
|
if self.compress:
|
|
FileSystem.delete(blob)
|
|
|
|
# Deprecated: Run when a single item is backed up directly
|
|
if not silent and not self.has_change:
|
|
self.log.info("No changes found")
|
|
print("✅ | Up to date. No changes found")
|
|
|
|
return
|
|
|
|
# Scan TARGET_FOLDER for files and folders to back up
|
|
def backup_all(self):
|
|
# Check all second-level files and folder at target path
|
|
for item in self.all():
|
|
self.backup_item(item)
|
|
|
|
if not self.has_change:
|
|
self.log.info("No changes found")
|
|
print("✅ | Up to date. No changes found") |