From 73eaa81e2a75871e225b8d0540ecadab4399bea7 Mon Sep 17 00:00:00 2001 From: jonathan Date: Tue, 1 Jun 2021 14:37:43 +0200 Subject: [PATCH] migrate to pathlib --- ffplayout/filters/v_drawtext.py | 6 ++--- ffplayout/folder.py | 10 +++----- ffplayout/output/hls.py | 16 +++++------- ffplayout/playlist.py | 12 ++++----- ffplayout/utils.py | 45 ++++++++++++++++----------------- 5 files changed, 41 insertions(+), 48 deletions(-) diff --git a/ffplayout/filters/v_drawtext.py b/ffplayout/filters/v_drawtext.py index 520d3b6c..01e7a966 100644 --- a/ffplayout/filters/v_drawtext.py +++ b/ffplayout/filters/v_drawtext.py @@ -2,8 +2,8 @@ custom video filter, which get loaded automatically """ -import os import re +from pathlib import Path from ..utils import lower_third @@ -13,11 +13,11 @@ def filter_link(node): extract title from file name and overlay it """ font = '' - source = os.path.basename(node.get('source')) + source = str(Path(node.get('source')).name) match = re.match(lower_third.regex, source) title = match[1] if match else source - if lower_third.fontfile and os.path.isfile(lower_third.fontfile): + if lower_third.fontfile and Path(lower_third.fontfile).is_file(): font = f":fontfile='{lower_third.fontfile}'" if lower_third.text_from_filename: diff --git a/ffplayout/folder.py b/ffplayout/folder.py index 0bf62a7d..87eb037b 100644 --- a/ffplayout/folder.py +++ b/ffplayout/folder.py @@ -19,11 +19,10 @@ This module handles folder reading. It monitor file adding, deleting or moving """ -import glob -import os import random import time from copy import deepcopy +from pathlib import Path from watchdog.events import PatternMatchingEventHandler from watchdog.observers import Observer @@ -58,8 +57,7 @@ class MediaStore: """ for ext in storage.extensions: self.store.extend( - glob.glob(os.path.join(self.folder, '**', f'*{ext}'), - recursive=True)) + [str(f) for f in Path(self.folder).rglob(f'*{ext}')]) def sort_or_radomize(self): """ @@ -124,8 +122,8 @@ class MediaWatcher: add file to media list only if it is completely copied """ file_size = -1 - while file_size != os.path.getsize(event.src_path): - file_size = os.path.getsize(event.src_path) + while file_size != Path(event.src_path).stat().st_size: + file_size = Path(event.src_path).stat().st_size time.sleep(1) self._media.add(event.src_path) diff --git a/ffplayout/output/hls.py b/ffplayout/output/hls.py index 7b78833c..865eb1e7 100644 --- a/ffplayout/output/hls.py +++ b/ffplayout/output/hls.py @@ -19,9 +19,8 @@ This module write the files compression directly to a hls (m3u8) playlist. """ -import os import re -from glob import iglob +from pathlib import Path from subprocess import PIPE, Popen from threading import Thread @@ -44,23 +43,20 @@ def clean_ts(): for m3u8_file in m3u8_files: messenger.debug(f'cleanup *.ts files from: "{m3u8_file}"') test_num = 0 - hls_path = os.path.dirname(m3u8_file) + hls_path = Path(m3u8_file).parent - if os.path.isfile(m3u8_file): + if Path(m3u8_file).is_file(): with open(m3u8_file, 'r') as m3u8: for line in m3u8: if '.ts' in line: test_num = int(re.findall(r'(\d+).ts', line)[0]) break - for ts_file in iglob(os.path.join(hls_path, '*.ts')): - ts_num = int(re.findall(r'(\d+).ts', ts_file)[0]) + for ts_file in hls_path.rglob('*.ts'): + ts_num = int(re.findall(r'(\d+).ts', str(ts_file))[0]) if test_num > ts_num: - try: - os.remove(ts_file) - except OSError: - pass + ts_file.unlink(missing_ok=True) def output(): diff --git a/ffplayout/playlist.py b/ffplayout/playlist.py index 96cc712b..7f31f4ec 100644 --- a/ffplayout/playlist.py +++ b/ffplayout/playlist.py @@ -21,12 +21,12 @@ Empty, missing or any other playlist related failure should be compensate. Missing clips will be replaced by a dummy clip. """ -import os import socket import time from copy import deepcopy from datetime import timedelta from math import isclose +from pathlib import Path from threading import Thread import requests @@ -161,7 +161,7 @@ def validate_thread(clip_nodes, list_date): if probe.is_remote: if not probe.video[0]: missing.append(f'Remote file not exist: "{source}"') - elif source is None or not os.path.isfile(source): + elif source is None or not Path(source).is_file(): missing.append(f'File not exist: "{source}"') if not type(node.get('in')) in [int, float]: @@ -219,8 +219,8 @@ class PlaylistReader: json_file = stdin_args.playlist else: year, month, _ = self.list_date.split('-') - json_file = os.path.join(playlist.path, year, month, - f'{self.list_date}.json') + json_file = str(Path(playlist.path).joinpath( + year, month, f'{self.list_date}.json')) if '://' in json_file: json_file = json_file.replace('\\', '/') @@ -241,9 +241,9 @@ class PlaylistReader: messenger.error(f'No valid playlist from url: {json_file}') self.error = True - elif os.path.isfile(json_file): + elif Path(json_file).is_file(): # check last modification time from playlist - mod_time = os.path.getmtime(json_file) + mod_time = Path(json_file).stat().st_mtime if mod_time > self.last_mod_time: with open(json_file, 'r', encoding='utf-8') as playlist_file: self.nodes = valid_json(playlist_file) diff --git a/ffplayout/utils.py b/ffplayout/utils.py index 1db4c943..9feb530e 100644 --- a/ffplayout/utils.py +++ b/ffplayout/utils.py @@ -22,7 +22,6 @@ This module contains default variables and helper functions import json import logging import math -import os import re import signal import smtplib @@ -35,8 +34,9 @@ from datetime import date, datetime, timedelta from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.utils import formatdate -from glob import glob from logging.handlers import TimedRotatingFileHandler +from pathlib import Path +from platform import system from shutil import which from subprocess import STDOUT, CalledProcessError, check_output from types import SimpleNamespace @@ -44,8 +44,8 @@ from types import SimpleNamespace import yaml # path to user define configs -CONFIG_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), - 'conf.d') +CONFIG_PATH = Path(__file__).parent.absolute().joinpath('conf.d') + # ------------------------------------------------------------------------------ # argument parsing @@ -88,7 +88,7 @@ stdin_parser.add_argument( ) # read dynamical new arguments -for arg_file in glob(os.path.join(CONFIG_PATH, 'argparse_*')): +for arg_file in CONFIG_PATH.glob('argparse_*'): with open(arg_file, 'r') as _file: config = yaml.safe_load(_file) @@ -164,7 +164,7 @@ def read_config(): if stdin_args.config: cfg_path = stdin_args.config - elif os.path.isfile('/etc/ffplayout/ffplayout.yml'): + elif Path('/etc/ffplayout/ffplayout.yml').is_file(): cfg_path = '/etc/ffplayout/ffplayout.yml' else: cfg_path = 'ffplayout.yml' @@ -242,7 +242,7 @@ playlist.length = _p_length log.to_file = _cfg['logging']['log_to_file'] log.backup_count = _cfg['logging']['backup_count'] -log.path = _cfg['logging']['log_path'] +log.path = Path(_cfg['logging']['log_path']) log.level = _cfg['logging']['log_level'] log.ff_level = _cfg['logging']['ffmpeg_level'] @@ -333,17 +333,16 @@ encoder_logger = logging.getLogger('encoder') encoder_logger.setLevel(log.ff_level) if log.to_file and log.path != 'none': - if log.path and os.path.isdir(log.path): - playout_log = os.path.join(log.path, 'ffplayout.log') - decoder_log = os.path.join(log.path, 'decoder.log') - encoder_log = os.path.join(log.path, 'encoder.log') + if log.path.is_dir(): + playout_log = log.path('ffplayout.log') + decoder_log = log.path('decoder.log') + encoder_log = log.path('encoder.log') else: - base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - log_dir = os.path.join(base_dir, 'log') - os.makedirs(log_dir, exist_ok=True) - playout_log = os.path.join(log_dir, 'ffplayout.log') - decoder_log = os.path.join(log_dir, 'decoder.log') - encoder_log = os.path.join(log_dir, 'encoder.log') + log_dir = Path(__file__).parent.absolute().joinpath('log') + log_dir.mkdir(exist_ok=True) + playout_log = log_dir.joinpath('ffplayout.log') + decoder_log = log_dir.joinpath('decoder.log') + encoder_log = log_dir.joinpath('encoder.log') p_format = logging.Formatter('[%(asctime)s] [%(levelname)s] %(message)s') f_format = logging.Formatter('[%(asctime)s] %(message)s') @@ -388,7 +387,7 @@ class Mailer: self.time = None self.timestamp = get_time('stamp') self.rate_limit = 600 - self.temp_msg = os.path.join(tempfile.gettempdir(), 'ffplayout.txt') + self.temp_msg = Path(tempfile.gettempdir()).joinpath('ffplayout.txt') def current_time(self): """ @@ -438,8 +437,8 @@ class Mailer: """ send message only when is new or the rate_limit is pass """ - if os.path.isfile(self.temp_msg): - mod_time = os.path.getmtime(self.temp_msg) + if Path(self.temp_msg).is_file(): + mod_time = Path(self.temp_msg).stat().st_mtime with open(self.temp_msg, 'r', encoding='utf-8') as msg_file: last_msg = msg_file.read() @@ -612,7 +611,7 @@ class MediaProbe: else: self.is_remote = False - if not self.src or not os.path.isfile(self.src): + if not self.src or not Path(self.src).is_file(): self.audio.append(None) self.video.append(None) @@ -673,7 +672,7 @@ def handle_sighub(sig, frame): signal.signal(signal.SIGTERM, handle_sigterm) -if os.name == 'posix': +if system() == 'Linux': signal.signal(signal.SIGHUP, handle_sighub) @@ -922,7 +921,7 @@ def src_or_dummy(node): node['src_cmd'] = [ '-i', node['source'] ] + set_length(86400, node['seek'], node['out']) - elif node.get('source') and os.path.isfile(node['source']): + elif node.get('source') and Path(node['source']).is_file(): if node['out'] > node['duration']: if node['seek'] > 0.0: messenger.warning(