diff --git a/dvrprocess/comchap.py b/dvrprocess/comchap.py index 1b317ea..99e2e89 100755 --- a/dvrprocess/comchap.py +++ b/dvrprocess/comchap.py @@ -13,7 +13,7 @@ import common import edl_normalize -from common import hwaccel, tools, config, constants, edl_util +from common import hwaccel, tools, config, constants, edl_util, fsutil logger = logging.getLogger(__name__) @@ -297,7 +297,7 @@ def do_comchap(infile, outfile, edlfile=None, delete_edl=True, delete_meta=True, if not os.path.isfile(local_comskip_ini) or os.stat(edlbakfile).st_mtime >= os.stat(local_comskip_ini).st_mtime: if not os.path.isfile(edlfile): edl_normalize.edl_simplify(edlbakfile, edlfile) - common.match_owner_and_perm(edlfile, infile) + fsutil.match_owner_and_perm(edlfile, infile) return 0 if input_info is None: @@ -361,13 +361,13 @@ def do_comchap(infile, outfile, edlfile=None, delete_edl=True, delete_meta=True, if not os.path.isfile(edlfile): if backup_edl and not force and os.path.isfile(edlbakfile): edl_normalize.edl_simplify(edlbakfile, edlfile) - common.match_owner_and_perm(edlfile, infile) + fsutil.match_owner_and_perm(edlfile, infile) else: run_comskip = True elif backup_edl: if not os.path.isfile(edlbakfile): edl_normalize.edl_normalize(edlfile, edlbakfile) - common.match_owner_and_perm(edlbakfile, infile) + fsutil.match_owner_and_perm(edlbakfile, infile) if modify_video: # the current hash is only available if we're allowed to modify the video @@ -422,10 +422,10 @@ def do_comchap(infile, outfile, edlfile=None, delete_edl=True, delete_meta=True, # copying permissions may have failed, but the file may have been copied if not os.path.exists(edlfile): raise e - common.match_owner_and_perm(edlfile, infile) + fsutil.match_owner_and_perm(edlfile, infile) if backup_edl or os.path.exists(edlbakfile): edl_normalize.edl_normalize(edlfile, edlbakfile) - common.match_owner_and_perm(edlbakfile, infile) + fsutil.match_owner_and_perm(edlbakfile, infile) if not modify_video: return 0 @@ -535,7 +535,7 @@ def do_comchap(infile, outfile, edlfile=None, delete_edl=True, delete_meta=True, if tempoutfile is not None: os.replace(tempoutfile, outfile) if infile != outfile: - common.match_owner_and_perm(target_path=outfile, source_path=infile) + fsutil.match_owner_and_perm(target_path=outfile, source_path=infile) else: # add K_COMSKIP_HASH marker if infile.endswith(".mkv") and infile == outfile: diff --git a/dvrprocess/comcut.py b/dvrprocess/comcut.py index cbfed0d..55a3bac 100755 --- a/dvrprocess/comcut.py +++ b/dvrprocess/comcut.py @@ -12,7 +12,7 @@ import common from comchap import comchap, write_chapter_metadata, compute_comskip_ini_hash, find_comskip_ini -from common import crop_frame, hwaccel, subtitle, tools, config, constants, edl_util +from common import crop_frame, hwaccel, subtitle, tools, config, constants, edl_util, fsutil from profanity_filter import MASK_STR KEYFRAME_DISTANCE_TOLERANCE = 1.0 @@ -547,7 +547,7 @@ def comcut(infile, outfile, delete_edl=True, force_clear_edl=False, delete_meta= if temp_outfile is not None: shutil.move(temp_outfile, outfile) - common.match_owner_and_perm(target_path=outfile, source_path=infile) + fsutil.match_owner_and_perm(target_path=outfile, source_path=infile) if force_clear_edl or (not delete_edl and infile == outfile): # change EDL file to match cut diff --git a/dvrprocess/common/__init__.py b/dvrprocess/common/__init__.py index 7262b68..d837102 100644 --- a/dvrprocess/common/__init__.py +++ b/dvrprocess/common/__init__.py @@ -7,7 +7,6 @@ import os import re import signal -import stat import subprocess import sys import threading @@ -1381,28 +1380,6 @@ def get_common_episode_duration(video_infos: list[dict]): return stats_list[0][0] -def match_owner_and_perm(target_path: str, source_path: str) -> bool: - result = True - source_stat = os.stat(source_path) - try: - os.chown(target_path, source_stat.st_uid, source_stat.st_gid) - except OSError: - logger.warning(f"Changing ownership of {target_path} failed, continuing") - result = False - - try: - st_mode = source_stat.st_mode - # if source is dir and has suid or guid and target is a file, mask suid/guid - if os.path.isfile(target_path): - st_mode &= ~(stat.S_ISUID | stat.S_ISGID | 0o111) - os.chmod(target_path, st_mode) - except OSError: - logger.warning(f"Changing permission of {target_path} failed, continuing") - result = False - - return result - - def is_truthy(value) -> bool: if value is None: return False diff --git a/dvrprocess/common/config.py b/dvrprocess/common/config.py index 6bcb440..e776f1f 100644 --- a/dvrprocess/common/config.py +++ b/dvrprocess/common/config.py @@ -10,6 +10,7 @@ from functools import lru_cache from . import constants +from .fsutil import match_owner_and_perm _config_lock = threading.Lock() @@ -305,6 +306,7 @@ def set_file_config(path: str, config: ConfigParser): config.set('general', 'fingerprint', _mkv_fingerprint(path)) with open(config_path, "wt") as file: config.write(file) + match_owner_and_perm(target_path=config_path, source_path=path) def get_file_config_option(path: str, section: str, option: str) -> str: diff --git a/dvrprocess/common/fsutil.py b/dvrprocess/common/fsutil.py new file mode 100644 index 0000000..963b93f --- /dev/null +++ b/dvrprocess/common/fsutil.py @@ -0,0 +1,27 @@ +import logging +import os +import stat + +logger = logging.getLogger(__name__) + + +def match_owner_and_perm(target_path: str, source_path: str) -> bool: + result = True + source_stat = os.stat(source_path) + try: + os.chown(target_path, source_stat.st_uid, source_stat.st_gid) + except OSError: + logger.warning(f"Changing ownership of {target_path} failed, continuing") + result = False + + try: + st_mode = source_stat.st_mode + # if source is dir and has suid or guid and target is a file, mask suid/guid + if os.path.isfile(target_path): + st_mode &= ~(stat.S_ISUID | stat.S_ISGID | 0o111) + os.chmod(target_path, st_mode) + except OSError: + logger.warning(f"Changing permission of {target_path} failed, continuing") + result = False + + return result diff --git a/dvrprocess/comtune.py b/dvrprocess/comtune.py index f8d79df..ee699bd 100755 --- a/dvrprocess/comtune.py +++ b/dvrprocess/comtune.py @@ -31,7 +31,7 @@ INI_GROUP_MAIN_SETTINGS, INI_GROUP_MAIN_SCORING, INI_GROUP_GLOBAL_REMOVES, INI_GROUP_LOGO_FINDING, \ INI_GROUP_LOGO_INTERPRETATION, INI_GROUP_VERSIONS, INI_ITEM_VERSIONS_VIDEO_STATS, INI_ITEM_VERSIONS_GAD_TUNING, \ INI_GROUP_DETAILED_SETTINGS, get_comskip_hwassist_options, INI_GROUP_INPUT_CORRECTION -from common import tools, config, constants, edl_util, progress +from common import tools, config, constants, edl_util, progress, fsutil TUNE_SHOW_MIN_VIDEO_COUNT = 5 @@ -422,7 +422,7 @@ def write_ini(path, max_avg_brightness, max_volume, non_uniformity): with open(path, "w") as f: config.write(f, space_around_delimiters=False) - common.match_owner_and_perm(target_path=path, source_path=os.path.dirname(os.path.abspath(path))) + fsutil.match_owner_and_perm(target_path=path, source_path=os.path.dirname(os.path.abspath(path))) def write_ini_from_solution(path, genes: list[ComskipGene], solution: list, write_complete_config=False, @@ -448,7 +448,7 @@ def write_ini_from_solution(path, genes: list[ComskipGene], solution: list, writ with open(path, "w") as f: config.write(f, space_around_delimiters=False) - common.match_owner_and_perm(target_path=path, source_path=os.path.dirname(os.path.abspath(path))) + fsutil.match_owner_and_perm(target_path=path, source_path=os.path.dirname(os.path.abspath(path))) def is_tuned(path, workdir): diff --git a/dvrprocess/dvr_post_process.py b/dvrprocess/dvr_post_process.py index 2ad1ad2..5329487 100755 --- a/dvrprocess/dvr_post_process.py +++ b/dvrprocess/dvr_post_process.py @@ -16,7 +16,7 @@ from ass_parser import CorruptAssLineError import common -from common import crop_frame, hwaccel, tools, config, constants +from common import crop_frame, hwaccel, tools, config, constants, fsutil from profanity_filter import do_profanity_filter SHORT_VIDEO_SECONDS = 30 @@ -440,7 +440,7 @@ def do_dvr_post_process(input_file, if file.startswith(f".~{base_filename}.") and file.endswith(".srt") and not file.endswith('.cc.srt'): os.remove(os.path.join(cc_root, file)) elif file.startswith(f".~{base_filename}.cc."): - common.match_owner_and_perm(target_path=os.path.join(cc_root, file), source_path=filename) + fsutil.match_owner_and_perm(target_path=os.path.join(cc_root, file), source_path=filename) else: cc_returncode = 0 @@ -684,7 +684,7 @@ def do_dvr_post_process(input_file, f", keeping the original") return 0 - common.match_owner_and_perm(target_path=temp_filename, source_path=filename) + fsutil.match_owner_and_perm(target_path=temp_filename, source_path=filename) # Hide original file in case OUTPUT_TYPE is the same as input os.replace(filename, hidden_filename) diff --git a/dvrprocess/profanity_filter.py b/dvrprocess/profanity_filter.py index 3c0f5ea..a0fb4ac 100755 --- a/dvrprocess/profanity_filter.py +++ b/dvrprocess/profanity_filter.py @@ -27,7 +27,7 @@ from thefuzz import process as fuzzprocess import common -from common import subtitle, tools, config, constants, progress, edl_util +from common import subtitle, tools, config, constants, progress, edl_util, fsutil from common.vosk import kaldi_recognizer # Increment when a coding change materially effects the output @@ -773,7 +773,7 @@ def do_profanity_filter(input_file, dry_run=False, keep=False, force=False, filt # logger.info(f"Finished filtering of {filename} to {temp_filename}") - common.match_owner_and_perm(target_path=temp_filename, source_path=filename) + fsutil.match_owner_and_perm(target_path=temp_filename, source_path=filename) # Hide original file in case OUTPUT_TYPE is the same as input if not debug: