mirror of
https://codeberg.org/vlw/cloud-backup.git
synced 2025-09-14 01:53:42 +02:00
wip(22w8f): add folder walker
This commit is contained in:
parent
3f51be9e55
commit
b2eae61ec1
6 changed files with 63 additions and 29 deletions
16
backup.py
16
backup.py
|
@ -1,18 +1,6 @@
|
|||
import sys
|
||||
from src import Database, FileSystem
|
||||
|
||||
class Backup(FileSystem):
|
||||
def __init__(self, argv):
|
||||
super().__init__()
|
||||
self.db = Database()
|
||||
from src import Backup
|
||||
|
||||
def backup(self, obj: list) -> bool:
|
||||
db_response = self.db.check_obj(obj)
|
||||
return True
|
||||
|
||||
def backup_all(self):
|
||||
for item in self.all():
|
||||
self.backup(item)
|
||||
|
||||
Backup(sys.argv).backup_all()
|
||||
Backup().backup_all()
|
||||
print("OK")
|
|
@ -3,6 +3,7 @@ from dotenv import load_dotenv
|
|||
from .glob import file_exists
|
||||
from .db import Database
|
||||
from .fs import FileSystem
|
||||
from .backup import Backup
|
||||
|
||||
if not file_exists(".env"):
|
||||
raise FileNotFoundError("Environment variable file does not exist. Copy '.env.example' to '.env'")
|
||||
|
|
25
src/backup.py
Normal file
25
src/backup.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
from typing import Union
|
||||
|
||||
from . import Database, FileSystem
|
||||
|
||||
class Backup(FileSystem):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.db = Database()
|
||||
|
||||
def backup_item(self, item: Union[list, str]) -> 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 True
|
||||
|
||||
self.db.set_item(item)
|
||||
|
||||
return True
|
||||
|
||||
def backup_all(self):
|
||||
for item in self.all():
|
||||
self.backup_item(item)
|
|
@ -11,6 +11,6 @@ CREATE TABLE manifest (
|
|||
|
||||
INSERT INTO flags
|
||||
VALUES
|
||||
("CALC_CHECKSUM", 1),
|
||||
("ZIP", 1),
|
||||
("BUCKET_OK", 0),
|
||||
("INIT", 1);
|
|
@ -4,9 +4,27 @@ class Database(SQLite):
|
|||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
# Test if a candidate item should be backed up
|
||||
def check_item(self, obj: list) -> bool:
|
||||
sql = f"SELECT anchor, mtime, chksum FROM manifest WHERE anchor = '{obj.anchor}'"
|
||||
data = self.query(sql)
|
||||
def item_exists(self, item: list) -> bool:
|
||||
sql = f"SELECT anchor FROM manifest WHERE anchor = '{item[0]}'"
|
||||
res = self.query(sql)
|
||||
|
||||
return True
|
||||
return res
|
||||
|
||||
# Test if a candidate item should be backed up
|
||||
def check_item(self, item: list) -> bool:
|
||||
sql = f"SELECT anchor, mtime, chksum FROM manifest WHERE anchor = '{item[0]}'"
|
||||
res = self.query(sql)
|
||||
if not res:
|
||||
return True
|
||||
|
||||
return res
|
||||
|
||||
# Insert or update item in database
|
||||
def set_item(self, item: list) -> bool:
|
||||
values = ",".join(item)
|
||||
sql = f"INSERT INTO manifest (anchor, mtime, chksum) VALUES ({values})"
|
||||
if not self.item_exists(item):
|
||||
sql = f"UPDATE manifest SET anchor = '{item[0]}', mtime = '{item[1]}', chksum = '{item[2]}' WHERE anchor = '{item[0]}'"
|
||||
res = self.query(sql)
|
||||
|
||||
return res
|
20
src/fs/fs.py
20
src/fs/fs.py
|
@ -11,20 +11,22 @@ class FileSystem:
|
|||
def get_path() -> str:
|
||||
return os.getenv("SOURCE_FOLDER")
|
||||
|
||||
# Calculate a CRC32 checksum of provided data
|
||||
@staticmethod
|
||||
def chksum(data: str) -> str:
|
||||
return zlib.crc32(data)
|
||||
encoded = data.encode("utf-8")
|
||||
return zlib.crc32(encoded)
|
||||
|
||||
# Get metadata from candidate file or folder
|
||||
def make_obj(self, anchor: str) -> list:
|
||||
mtime = os.path.getmtime(anchor)
|
||||
if os.path.isdir(anchor):
|
||||
def get_item(self, path: list) -> list:
|
||||
mtime = os.path.getmtime(path)
|
||||
chksum = FileSystem.chksum(path + str(mtime))
|
||||
|
||||
data = [path, mtime, chksum]
|
||||
return data
|
||||
|
||||
data = [anchor, mtime, chksum]
|
||||
return obj
|
||||
|
||||
# Get all second-level files and folders for path
|
||||
def all(self) -> list:
|
||||
content = os.listdir(self.path)
|
||||
content = list(map(self.make_obj, content))
|
||||
content = [os.path.join(self.path, f) for f in os.listdir(self.path)]
|
||||
content = list(map(self.get_item, content))
|
||||
return content
|
Loading…
Add table
Reference in a new issue