From 61ef3ce76c50142c7fbd5e71f0fb82e1377b530f Mon Sep 17 00:00:00 2001 From: Patrick Double Date: Tue, 13 Aug 2024 14:18:50 -0500 Subject: [PATCH] find_media_errors.py: run daily --- Dockerfile | 1 + dvrprocess/common/config.py | 2 +- dvrprocess/find_media_errors.py | 18 +++++++++++------- logrotate.conf | 8 ++++++++ media-errors.sh | 6 ++++++ 5 files changed, 27 insertions(+), 8 deletions(-) create mode 100755 media-errors.sh diff --git a/Dockerfile b/Dockerfile index 7ee407d..121777a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -72,6 +72,7 @@ COPY tvshow-summary.sh /etc/cron.daily/tvshow-summary #COPY comchap-apply.sh /etc/cron.daily/comchap-apply COPY comtune-apply.sh /etc/cron.daily/comtune-apply COPY transcode-apply.sh /etc/cron.hourly/transcode-apply +COPY media-errors.sh /etc/cron.daily/media-errors COPY profanity-filter-apply.sh /etc/cron.daily/profanity-filter-apply COPY logrotate.conf /etc/logrotate.d/dvr COPY sendmail-log.sh /usr/sbin/sendmail diff --git a/dvrprocess/common/config.py b/dvrprocess/common/config.py index e776f1f..cef3b85 100644 --- a/dvrprocess/common/config.py +++ b/dvrprocess/common/config.py @@ -289,7 +289,7 @@ def get_file_config(path: str) -> ConfigParser: config = ConfigParser() if os.path.exists(config_path): config.read(config_path) - if config.get('general', 'fingerprint') != _mkv_fingerprint(path): + if config.get('general', 'fingerprint', fallback=None) != _mkv_fingerprint(path): config = ConfigParser() return config diff --git a/dvrprocess/find_media_errors.py b/dvrprocess/find_media_errors.py index 589a24c..abccf1e 100755 --- a/dvrprocess/find_media_errors.py +++ b/dvrprocess/find_media_errors.py @@ -31,6 +31,8 @@ def usage(): Directory containing media. Defaults to {common.get_media_roots()} --nagios Output for Nagios monitoring. Also human readable with statistics and estimates of transcode time. +--cache-only + Only report cached results, do not look for new media errors. --time-limit={config.get_global_config_option('background_limits', 'time_limit')} Limit runtime. Set to 0 for no limit. --ignore-compute @@ -44,10 +46,11 @@ def find_media_errors_cli(argv): nagios_output = False time_limit = config.get_global_config_time_seconds('background_limits', 'time_limit') check_compute = True + cache_only = False try: opts, args = getopt.getopt(argv, "t:d:", - ["terminator=", "dir=", "nagios", "time-limit=", "ignore-compute"]) + ["terminator=", "dir=", "nagios", "time-limit=", "ignore-compute", "cache-only"]) except getopt.GetoptError: usage() return 2 @@ -70,6 +73,8 @@ def find_media_errors_cli(argv): time_limit = config.parse_seconds(arg) elif opt == '--ignore-compute': check_compute = False + elif opt == '--cache-only': + cache_only = True if not roots: roots = common.get_media_roots() @@ -84,7 +89,7 @@ def find_media_errors_cli(argv): return 0 generator = media_errors_generator(media_paths=media_paths, media_roots=roots, - time_limit=time_limit, check_compute=check_compute) + time_limit=time_limit, check_compute=check_compute, cache_only=cache_only) if nagios_output: corrupt_files = list(generator) @@ -122,9 +127,8 @@ def __init__(self, file_name: str, host_file_path: str, size: float, error_count def media_errors_generator(media_paths: list[str], media_roots: list[str], time_limit=config.get_global_config_time_seconds('background_limits', 'time_limit'), - check_compute=True) -> Iterable[MediaErrorFileInfo]: + check_compute=True, cache_only=False) -> Iterable[MediaErrorFileInfo]: time_start = time.time() - only_cached = False for media_path in media_paths: for root, dirs, files in os.walk(media_path, topdown=True): @@ -133,19 +137,19 @@ def media_errors_generator(media_paths: list[str], media_roots: list[str], cached_error_count = config.get_file_config_option(filepath, 'error', 'count') if cached_error_count: error_count = int(cached_error_count) - elif only_cached: + elif cache_only: continue else: duration = time.time() - time_start if 0 < time_limit < duration: logger.debug( f"Time limit expired after processing {common.s_to_ts(int(duration))}, limit of {common.s_to_ts(time_limit)} reached, only using cached data") - only_cached = True + cache_only = True continue if check_compute and common.should_stop_processing(): # when compute limit is reached, use cached data logger.debug("not enough compute available, only using cached data") - only_cached = True + cache_only = True continue error_count = len(tools.ffmpeg.check_output( diff --git a/logrotate.conf b/logrotate.conf index 58a7fed..bedd99a 100644 --- a/logrotate.conf +++ b/logrotate.conf @@ -69,3 +69,11 @@ missingok notifempty } + +/var/log/find_media_errors.log { + rotate 2 + daily + compress + missingok + notifempty +} diff --git a/media-errors.sh b/media-errors.sh new file mode 100755 index 0000000..578401a --- /dev/null +++ b/media-errors.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +# random sleep to prevent multiple programs running at the exact same time +sleep $((5 + RANDOM % 30)) + +exec ionice -c 3 nice -n 15 /usr/local/bin/find_media_errors.py "$@" >>/var/log/find_media_errors.log 2>&1