mirror of
https://github.com/ep1cman/unifi-protect-backup.git
synced 2025-12-05 23:53:30 +00:00
Add extra param to purge (#86)
* Added optional argument string to pass directly to the `rclone delete` command used to purge video files. This will allow for immediate deletion of files on destinations where the file might otherwise go to a recycle bin by default. --------- Co-authored-by: Igor Wolbers <igor@sparcobv.onmicrosoft.com> Co-authored-by: Sebastian Goscik <sebastian.goscik@live.co.uk>
This commit is contained in:
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.9.1] - 2023-04-21
|
||||
### Added
|
||||
- Added optional argument string to pass directly to the `rclone delete` command used to purge video files
|
||||
|
||||
## [0.9.0] - 2023-03-24
|
||||
### Added
|
||||
- The ability to send logging out via apprise notifications
|
||||
|
||||
@@ -127,6 +127,10 @@ Options:
|
||||
--rclone-args TEXT Optional extra arguments to pass to `rclone rcat` directly.
|
||||
Common usage for this would be to set a bandwidth limit, for
|
||||
example.
|
||||
--rclone-purge-args TEXT Optional extra arguments to pass to `rclone delete` directly.
|
||||
Common usage for this would be to execute a permanent delete
|
||||
instead of using the recycle bin on a destination.
|
||||
Google Drive example: `--drive-use-trash=false`
|
||||
--detection-types TEXT A comma separated list of which types of detections to backup.
|
||||
Valid options are: `motion`, `person`, `vehicle`, `ring`
|
||||
[default: motion,person,vehicle,ring]
|
||||
@@ -198,6 +202,7 @@ always take priority over environment variables):
|
||||
- `RCLONE_RETENTION`
|
||||
- `RCLONE_DESTINATION`
|
||||
- `RCLONE_ARGS`
|
||||
- `RCLONE_PURGE_ARGS`
|
||||
- `IGNORE_CAMERAS`
|
||||
- `DETECTION_TYPES`
|
||||
- `FILE_STRUCTURE_FORMAT`
|
||||
|
||||
@@ -57,6 +57,14 @@ def _parse_detection_types(ctx, param, value):
|
||||
help="Optional extra arguments to pass to `rclone rcat` directly. Common usage for this would "
|
||||
"be to set a bandwidth limit, for example.",
|
||||
)
|
||||
@click.option(
|
||||
'--rclone-purge-args',
|
||||
default='',
|
||||
envvar='RCLONE_PURGE_ARGS',
|
||||
help="Optional extra arguments to pass to `rclone delete` directly. Common usage for this would "
|
||||
"be to execute a permanent delete instead of using the recycle bin on a destination. "
|
||||
"Google Drive example: `--drive-use-trash=false`",
|
||||
)
|
||||
@click.option(
|
||||
'--detection-types',
|
||||
envvar='DETECTION_TYPES',
|
||||
|
||||
@@ -12,9 +12,9 @@ from unifi_protect_backup.utils import run_command, wait_until
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def delete_file(file_path):
|
||||
async def delete_file(file_path, rclone_purge_args):
|
||||
"""Deletes `file_path` via rclone."""
|
||||
returncode, stdout, stderr = await run_command(f'rclone delete -vv "{file_path}"')
|
||||
returncode, stdout, stderr = await run_command(f'rclone delete -vv "{file_path}" {rclone_purge_args}')
|
||||
if returncode != 0:
|
||||
logger.error(f" Failed to delete file: '{file_path}'")
|
||||
|
||||
@@ -35,6 +35,7 @@ class Purge:
|
||||
retention: relativedelta,
|
||||
rclone_destination: str,
|
||||
interval: relativedelta = relativedelta(days=1),
|
||||
rclone_purge_args: str = "",
|
||||
):
|
||||
"""Init.
|
||||
|
||||
@@ -43,11 +44,13 @@ class Purge:
|
||||
retention (relativedelta): How long clips should be kept
|
||||
rclone_destination (str): What rclone destination the clips are stored in
|
||||
interval (relativedelta): How often to purge old clips
|
||||
rclone_purge_args (str): Optional extra arguments to pass to `rclone delete` directly.
|
||||
"""
|
||||
self._db: aiosqlite.Connection = db
|
||||
self.retention: relativedelta = retention
|
||||
self.rclone_destination: str = rclone_destination
|
||||
self.interval: relativedelta = interval
|
||||
self.rclone_purge_args: str = rclone_purge_args
|
||||
|
||||
async def start(self):
|
||||
"""Main loop - runs forever."""
|
||||
@@ -68,7 +71,7 @@ class Purge:
|
||||
async with self._db.execute(f"SELECT * FROM backups WHERE id = '{event_id}'") as backup_cursor:
|
||||
async for _, remote, file_path in backup_cursor:
|
||||
logger.debug(f" Deleted: {remote}:{file_path}")
|
||||
await delete_file(f"{remote}:{file_path}")
|
||||
await delete_file(f"{remote}:{file_path}", self.rclone_purge_args)
|
||||
deleted_a_file = True
|
||||
|
||||
# delete event from database
|
||||
|
||||
@@ -59,6 +59,7 @@ class UnifiProtectBackup:
|
||||
rclone_destination: str,
|
||||
retention: str,
|
||||
rclone_args: str,
|
||||
rclone_purge_args: str,
|
||||
detection_types: List[str],
|
||||
ignore_cameras: List[str],
|
||||
file_structure_format: str,
|
||||
@@ -87,6 +88,7 @@ class UnifiProtectBackup:
|
||||
(https://rclone.org/filtering/#max-age-don-t-transfer-any-file-older-than-this)
|
||||
rclone_args (str): A bandwidth limit which is passed to the `--bwlimit` argument of
|
||||
`rclone` (https://rclone.org/docs/#bwlimit-bandwidth-spec)
|
||||
rclone_purge_args (str): Optional extra arguments to pass to `rclone delete` directly.
|
||||
detection_types (List[str]): List of which detection types to backup.
|
||||
ignore_cameras (List[str]): List of camera IDs for which to not backup events.
|
||||
file_structure_format (str): A Python format string for output file path.
|
||||
@@ -121,6 +123,7 @@ class UnifiProtectBackup:
|
||||
logger.debug(f" {rclone_destination=}")
|
||||
logger.debug(f" {retention=}")
|
||||
logger.debug(f" {rclone_args=}")
|
||||
logger.debug(f" {rclone_purge_args=}")
|
||||
logger.debug(f" {ignore_cameras=}")
|
||||
logger.debug(f" {verbose=}")
|
||||
logger.debug(f" {detection_types=}")
|
||||
@@ -134,6 +137,7 @@ class UnifiProtectBackup:
|
||||
self.rclone_destination = rclone_destination
|
||||
self.retention = parse_rclone_retention(retention)
|
||||
self.rclone_args = rclone_args
|
||||
self.rclone_purge_args = rclone_purge_args
|
||||
self.file_structure_format = file_structure_format
|
||||
|
||||
self.address = address
|
||||
@@ -238,7 +242,7 @@ class UnifiProtectBackup:
|
||||
|
||||
# Create purge task
|
||||
# This will, every midnight, purge old backups from the rclone remotes and database
|
||||
purge = Purge(self._db, self.retention, self.rclone_destination, self._purge_interval)
|
||||
purge = Purge(self._db, self.retention, self.rclone_destination, self._purge_interval, self.rclone_purge_args)
|
||||
tasks.append(purge.start())
|
||||
|
||||
# Create missing event task
|
||||
|
||||
Reference in New Issue
Block a user