Skip to content

Commit

Permalink
Better backup method (#21)
Browse files Browse the repository at this point in the history
* Better backup method

Co-authored-by: jslay <[email protected]>
  • Loading branch information
jslay88 and jslay authored Feb 21, 2022
1 parent a0d8680 commit b378cc0
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[flake8]
exclude = venv
max-line-length = 120
8 changes: 1 addition & 7 deletions qbt_migrate/classes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import os
import logging
import shutil
from threading import Thread
from datetime import datetime
from typing import Optional
Expand Down Expand Up @@ -44,12 +43,7 @@ def run(self, existing_path: str, new_path: str, target_os: Optional[str] = None
raise NotADirectoryError(self.bt_backup_path)
if create_backup:
backup_filename = f'fastresume_backup{datetime.now().strftime("%Y%m%d%H%M%S")}.zip'
self.backup_folder(self.bt_backup_path,
os.path.join(os.path.dirname(self.bt_backup_path), backup_filename))
if os.path.isfile('/.dockerenv') and self.bt_backup_path == '/tmp/BT_backup':
# Shove backup in /tmp/BT_backup for Docker (not qBittorrent Docker) for persistence
shutil.move(os.path.join(os.path.dirname(self.bt_backup_path), backup_filename),
os.path.join(self.bt_backup_path, backup_filename))
backup_folder(self.bt_backup_path, os.path.join(self.bt_backup_path, backup_filename))

self.logger.info(f'Searching for .fastresume files with path {existing_path} ...')
for fast_resume in self.discover_relevant_fast_resume(self.bt_backup_path, existing_path, not skip_bad_files):
Expand Down
13 changes: 9 additions & 4 deletions qbt_migrate/methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import sys
import logging
import zipfile
from pathlib import Path
from typing import Union


logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -32,11 +34,14 @@ def convert_slashes(path: str, target_os: str):
return path.replace('\\', '/')


def backup_folder(folder_path: str, archive_path: str):
def backup_folder(folder_path: Union[str, os.PathLike], archive_path: Union[str, os.PathLike]):
logger.info(f'Creating Archive {archive_path} ...')
folder_path = Path(folder_path)
archive_path = Path(archive_path)
with zipfile.ZipFile(archive_path, 'w') as archive:
for file in os.listdir(folder_path):
if file.startswith('fastresume') and file.endswith('.zip'):
for file in folder_path.iterdir():
if file == archive_path:
continue
archive.write(os.path.join(folder_path, file))
logger.debug(f'Archiving {file} into {archive_path}...')
archive.write(file)
logger.info('Done!')
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

setup(
name='qbt_migrate',
version='2.1.2',
version='2.1.3',
packages=find_packages(),
install_requires=dependencies,
description='Migrate qBittorrent FastResume files.',
Expand Down
30 changes: 30 additions & 0 deletions tests/test_methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import re
import tempfile
import zipfile
from pathlib import Path

from qbt_migrate.methods import backup_folder


def test_backup_folder():
temp_dir = Path(tempfile.mkdtemp()) # Get a tmp dir
file_count = 20 # Number of test files to build

# Build test files
for x in range(file_count):
with open(temp_dir / f'test_{x}.txt', 'w') as f:
f.write(f'This is file {x}')

# 'test.zip' will fail the filename check in archive if it gets archived
archive_path = temp_dir / 'test.zip'
backup_folder(temp_dir, archive_path) # Call backup_folder

# Validate zip file
with zipfile.ZipFile(archive_path, 'r') as archive:
assert(archive.testzip() is None) # Check no errors
assert(len(archive.infolist()) == file_count) # Assert that it has the correct file count
for file in archive.infolist():
filename = re.findall(r'test_(\d+).txt', file.filename) # Get the integer of the file
assert(len(filename) != 0) # Ensure we got the integer
filename = filename[0]
assert(archive.read(file.filename) == bytes(f'This is file {filename}', 'utf-8')) # Integrity Check

0 comments on commit b378cc0

Please sign in to comment.