mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-10-11 06:16:35 +08:00
[FR] Specify recycle bin path per category #77
This commit is contained in:
parent
56a856ac4f
commit
f838af409b
2 changed files with 40 additions and 16 deletions
|
@ -1,4 +1,4 @@
|
||||||
import logging, os, requests, stat, time
|
import logging, os, requests, stat, time, re
|
||||||
from modules import util
|
from modules import util
|
||||||
from modules.util import Failed, check
|
from modules.util import Failed, check
|
||||||
from modules.qbittorrent import Qbt
|
from modules.qbittorrent import Qbt
|
||||||
|
@ -177,6 +177,7 @@ class Config:
|
||||||
self.recyclebin['enabled'] = self.util.check_for_attribute(self.data, "enabled", parent="recyclebin", var_type="bool", default=True)
|
self.recyclebin['enabled'] = self.util.check_for_attribute(self.data, "enabled", parent="recyclebin", var_type="bool", default=True)
|
||||||
self.recyclebin['empty_after_x_days'] = self.util.check_for_attribute(self.data, "empty_after_x_days", parent="recyclebin", var_type="int", default_is_none=True)
|
self.recyclebin['empty_after_x_days'] = self.util.check_for_attribute(self.data, "empty_after_x_days", parent="recyclebin", var_type="int", default_is_none=True)
|
||||||
self.recyclebin['save_torrents'] = self.util.check_for_attribute(self.data, "save_torrents", parent="recyclebin", var_type="bool", default=False)
|
self.recyclebin['save_torrents'] = self.util.check_for_attribute(self.data, "save_torrents", parent="recyclebin", var_type="bool", default=False)
|
||||||
|
self.recyclebin['split_by_category'] = self.util.check_for_attribute(self.data, "split_by_category", parent="recyclebin", var_type="bool", default=False)
|
||||||
|
|
||||||
# Assign directories
|
# Assign directories
|
||||||
if "directory" in self.data:
|
if "directory" in self.data:
|
||||||
|
@ -313,28 +314,46 @@ class Config:
|
||||||
files = []
|
files = []
|
||||||
size_bytes = 0
|
size_bytes = 0
|
||||||
if not self.args["skip_recycle"]:
|
if not self.args["skip_recycle"]:
|
||||||
n_info = ''
|
|
||||||
if self.recyclebin['enabled'] and self.recyclebin['empty_after_x_days']:
|
if self.recyclebin['enabled'] and self.recyclebin['empty_after_x_days']:
|
||||||
recycle_files = [os.path.join(path, name) for path, subdirs, files in os.walk(self.recycle_dir) for name in files]
|
if self.recyclebin['split_by_category']:
|
||||||
|
if "cat" in self.data and self.data["cat"] is not None:
|
||||||
|
save_path = list(self.data["cat"].values())
|
||||||
|
cleaned_save_path = [os.path.join(s.replace(self.root_dir, self.remote_dir), os.path.basename(self.recycle_dir.rstrip('/'))) for s in save_path]
|
||||||
|
recycle_path = [self.recycle_dir]
|
||||||
|
for dir in cleaned_save_path:
|
||||||
|
if os.path.exists(dir): recycle_path.append(dir)
|
||||||
|
else:
|
||||||
|
e = (f'No categories defined. Checking Recycle Bin directory {self.recycle_dir}.')
|
||||||
|
self.notify(e, 'Empty Recycle Bin', False)
|
||||||
|
logger.warning(e)
|
||||||
|
recycle_path = [self.recycle_dir]
|
||||||
|
else:
|
||||||
|
recycle_path = [self.recycle_dir]
|
||||||
|
recycle_files = [os.path.join(path, name) for r_path in recycle_path for path, subdirs, files in os.walk(r_path) for name in files]
|
||||||
recycle_files = sorted(recycle_files)
|
recycle_files = sorted(recycle_files)
|
||||||
if recycle_files:
|
if recycle_files:
|
||||||
util.separator(f"Emptying Recycle Bin (Files > {self.recyclebin['empty_after_x_days']} days)", space=False, border=False)
|
body = []
|
||||||
|
util.separator(f"Emptying Recycle Bin (Files > {self.recyclebin['empty_after_x_days']} days)", space=True, border=True)
|
||||||
|
prevfolder = ''
|
||||||
for file in recycle_files:
|
for file in recycle_files:
|
||||||
|
folder = re.search(f".*{os.path.basename(self.recycle_dir.rstrip('/'))}", file).group(0)
|
||||||
|
if folder != prevfolder: body += util.separator(f"Searching: {folder}", space=False, border=False)
|
||||||
fileStats = os.stat(file)
|
fileStats = os.stat(file)
|
||||||
filename = file.replace(self.recycle_dir, '')
|
filename = os.path.basename(file)
|
||||||
last_modified = fileStats[stat.ST_MTIME] # in seconds (last modified time)
|
last_modified = fileStats[stat.ST_MTIME] # in seconds (last modified time)
|
||||||
now = time.time() # in seconds
|
now = time.time() # in seconds
|
||||||
days = (now - last_modified) / (60 * 60 * 24)
|
days = (now - last_modified) / (60 * 60 * 24)
|
||||||
if (self.recyclebin['empty_after_x_days'] <= days):
|
if (self.recyclebin['empty_after_x_days'] <= days):
|
||||||
num_del += 1
|
num_del += 1
|
||||||
n_info += (f"{'Did not delete' if dry_run else 'Deleted'} {filename} from the recycle bin. (Last modified {round(days)} days ago).\n")
|
body += util.print_line(f"{'Did not delete' if dry_run else 'Deleted'} {filename} from {folder} (Last modified {round(days)} days ago).", loglevel)
|
||||||
files += [str(filename)]
|
files += [str(filename)]
|
||||||
size_bytes += os.path.getsize(file)
|
size_bytes += os.path.getsize(file)
|
||||||
if not dry_run: os.remove(file)
|
if not dry_run: os.remove(file)
|
||||||
|
prevfolder = re.search(f".*{os.path.basename(self.recycle_dir.rstrip('/'))}", file).group(0)
|
||||||
if num_del > 0:
|
if num_del > 0:
|
||||||
if not dry_run: util.remove_empty_directories(self.recycle_dir, "**/*")
|
if not dry_run:
|
||||||
body = []
|
for path in recycle_path:
|
||||||
body += util.print_multiline(n_info.rstrip(), loglevel)
|
util.remove_empty_directories(path, "**/*")
|
||||||
body += util.print_line(f"{'Did not delete' if dry_run else 'Deleted'} {num_del} files ({util.human_readable_size(size_bytes)}) from the Recycle Bin.", loglevel)
|
body += util.print_line(f"{'Did not delete' if dry_run else 'Deleted'} {num_del} files ({util.human_readable_size(size_bytes)}) from the Recycle Bin.", loglevel)
|
||||||
attr = {
|
attr = {
|
||||||
"function": "empty_recyclebin",
|
"function": "empty_recyclebin",
|
||||||
|
@ -346,7 +365,7 @@ class Config:
|
||||||
}
|
}
|
||||||
self.send_notifications(attr)
|
self.send_notifications(attr)
|
||||||
else:
|
else:
|
||||||
logger.debug('No files found in "' + self.recycle_dir + '"')
|
logger.debug('No files found in "' + recycle_path + '"')
|
||||||
return num_del
|
return num_del
|
||||||
|
|
||||||
def send_notifications(self, attr):
|
def send_notifications(self, attr):
|
||||||
|
|
|
@ -710,13 +710,18 @@ class Qbt:
|
||||||
tor_files = []
|
tor_files = []
|
||||||
try:
|
try:
|
||||||
info_hash = torrent.hash
|
info_hash = torrent.hash
|
||||||
|
save_path = torrent.save_path.replace(self.config.root_dir, self.config.remote_dir)
|
||||||
# Define torrent files/folders
|
# Define torrent files/folders
|
||||||
for file in torrent.files:
|
for file in torrent.files:
|
||||||
tor_files.append(os.path.join(torrent.save_path, file.name))
|
tor_files.append(os.path.join(save_path, file.name))
|
||||||
except NotFound404Error:
|
except NotFound404Error:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.config.recyclebin['split_by_category']:
|
||||||
|
recycle_path = os.path.join(save_path, os.path.basename(self.config.recycle_dir.rstrip('/')))
|
||||||
|
else:
|
||||||
|
recycle_path = self.config.recycle_dir
|
||||||
# Create recycle bin if not exists
|
# Create recycle bin if not exists
|
||||||
recycle_path = self.config.recycle_dir
|
|
||||||
torrent_path = os.path.join(recycle_path, 'torrents')
|
torrent_path = os.path.join(recycle_path, 'torrents')
|
||||||
torrents_json_path = os.path.join(recycle_path, 'torrents_json')
|
torrents_json_path = os.path.join(recycle_path, 'torrents_json')
|
||||||
|
|
||||||
|
@ -756,7 +761,7 @@ class Qbt:
|
||||||
logger.info(backup_str)
|
logger.info(backup_str)
|
||||||
torrent_json["tracker_torrent_files"] = tracker_torrent_files
|
torrent_json["tracker_torrent_files"] = tracker_torrent_files
|
||||||
if "files" not in torrent_json:
|
if "files" not in torrent_json:
|
||||||
files_cleaned = [f.replace(self.config.root_dir, '') for f in tor_files]
|
files_cleaned = [f.replace(self.config.remote_dir, '') for f in tor_files]
|
||||||
torrent_json["files"] = files_cleaned
|
torrent_json["files"] = files_cleaned
|
||||||
torrent_json["deleted_contents"] = info['torrents_deleted_and_contents']
|
torrent_json["deleted_contents"] = info['torrents_deleted_and_contents']
|
||||||
logger.debug("")
|
logger.debug("")
|
||||||
|
@ -770,8 +775,8 @@ class Qbt:
|
||||||
|
|
||||||
# Move files from torrent contents to Recycle bin
|
# Move files from torrent contents to Recycle bin
|
||||||
for file in tor_files:
|
for file in tor_files:
|
||||||
src = file.replace(self.config.root_dir, self.config.remote_dir)
|
src = file
|
||||||
dest = os.path.join(recycle_path, file.replace(self.config.root_dir, ''))
|
dest = os.path.join(recycle_path, file.replace(self.config.remote_dir, ''))
|
||||||
# Move files and change date modified
|
# Move files and change date modified
|
||||||
try:
|
try:
|
||||||
util.move_files(src, dest, True)
|
util.move_files(src, dest, True)
|
||||||
|
@ -781,7 +786,7 @@ class Qbt:
|
||||||
# Delete torrent and files
|
# Delete torrent and files
|
||||||
torrent.delete(delete_files=False)
|
torrent.delete(delete_files=False)
|
||||||
# Remove any empty directories
|
# Remove any empty directories
|
||||||
util.remove_empty_directories(torrent.save_path.replace(self.config.root_dir, self.config.remote_dir), "**/*")
|
util.remove_empty_directories(save_path, "**/*")
|
||||||
else:
|
else:
|
||||||
torrent.delete(delete_files=False)
|
torrent.delete(delete_files=False)
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Add table
Reference in a new issue