windows running

This commit is contained in:
Jesse Bannon 2023-02-24 16:11:57 -08:00
parent ddcdcd5647
commit d1705e3942
6 changed files with 84 additions and 55 deletions

4
.gitignore vendored
View file

@ -142,4 +142,6 @@ docker/*.whl
docker/root/*.whl
docker/root/defaults/examples
.local/
.local/
ffmpeg.exe

View file

@ -1,11 +1,6 @@
import argparse
import errno
import fcntl
import gc
import os
import sys
from contextlib import contextmanager
from pathlib import Path
from typing import List
from typing import Tuple
@ -13,8 +8,8 @@ from ytdl_sub.cli.download_args_parser import DownloadArgsParser
from ytdl_sub.cli.main_args_parser import parser
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.subscriptions.subscription import Subscription
from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.file_handler import FileHandlerTransactionLog
from ytdl_sub.utils.file_lock import working_directory_lock
from ytdl_sub.utils.logger import Logger
logger = Logger.get()
@ -119,45 +114,6 @@ def _view_url_from_cli(
return subscription, subscription.download(dry_run=True)
@contextmanager
def _working_directory_lock(config: ConfigFile):
"""
Create and try to lock the file /tmp/working_directory_name
Raises
------
ValidationException
Lock is acquired from another process running ytdl-sub in the same working directory
OSError
Other lock error occurred
"""
working_directory_path = Path(os.getcwd()) / config.config_options.working_directory
lock_file_path = (
Path(os.getcwd())
/ config.config_options.lock_directory
/ str(working_directory_path).replace("/", "_")
)
lock_file = open(lock_file_path, "w", encoding="utf-8")
try:
fcntl.lockf(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
except OSError as exc:
if exc.errno in (errno.EACCES, errno.EAGAIN):
raise ValidationException(
"Cannot run two instances of ytdl-sub "
"with the same working directory at the same time"
) from exc
lock_file.close()
raise exc
try:
yield
finally:
fcntl.flock(lock_file, fcntl.LOCK_UN)
lock_file.close()
def main() -> List[Tuple[Subscription, FileHandlerTransactionLog]]:
"""
Entrypoint for ytdl-sub, without the error handling
@ -172,7 +128,7 @@ def main() -> List[Tuple[Subscription, FileHandlerTransactionLog]]:
config: ConfigFile = ConfigFile.from_file_path(args.config).initialize()
transaction_logs: List[Tuple[Subscription, FileHandlerTransactionLog]] = []
with _working_directory_lock(config=config):
with working_directory_lock(config=config):
if args.subparser == "sub":
transaction_logs = _download_subscriptions_from_yaml_files(config=config, args=args)

View file

@ -1,4 +1,5 @@
import subprocess
import sys
import tempfile
from typing import Dict
from typing import List
@ -26,7 +27,10 @@ class FFMPEG:
@classmethod
def _ensure_installed(cls):
try:
subprocess.check_output(["which", "ffmpeg"])
if sys.platform.startswith("win32"):
subprocess.check_output([".\\ffmpeg", "-version"])
else:
subprocess.check_output(["which", "ffmpeg"])
except subprocess.CalledProcessError as subprocess_error:
raise ValidationException(
"Trying to use a feature which requires ffmpeg, but it cannot be found"

View file

@ -0,0 +1,67 @@
import errno
import os
import sys
from contextlib import contextmanager
from pathlib import Path
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.logger import Logger
logger = Logger.get()
@contextmanager
def _working_directory_lock_unix(config: ConfigFile):
"""
Create and try to lock the file /tmp/working_directory_name
Raises
------
ValidationException
Lock is acquired from another process running ytdl-sub in the same working directory
OSError
Other lock error occurred
"""
# pylint: disable=import-outside-toplevel
import fcntl
working_directory_path = Path(os.getcwd()) / config.config_options.working_directory
lock_file_path = (
Path(os.getcwd())
/ config.config_options.lock_directory
/ str(working_directory_path).replace("/", "_")
)
lock_file = open(lock_file_path, "w", encoding="utf-8")
try:
fcntl.lockf(lock_file, fcntl.LOCK_EX | fcntl.LOCK_NB)
except OSError as exc:
if exc.errno in (errno.EACCES, errno.EAGAIN):
raise ValidationException(
"Cannot run two instances of ytdl-sub "
"with the same working directory at the same time"
) from exc
lock_file.close()
raise exc
try:
yield
finally:
fcntl.flock(lock_file, fcntl.LOCK_UN)
lock_file.close()
@contextmanager
def working_directory_lock(config: ConfigFile):
if sys.platform.startswith("win32"):
logger.info(
"Working directory lock not supported in Windows. "
"Ensure only one instance of ytdl-sub runs at once using working directory %s",
config.config_options.working_directory,
)
yield
else:
with _working_directory_lock_unix(config):
yield

View file

@ -3,9 +3,9 @@ from pathlib import Path
REGENERATE_FIXTURES: bool = False
RESOURCE_PATH = Path("tests/resources")
_FILE_FIXTURE_PATH = RESOURCE_PATH / "file_fixtures"
RESOURCE_PATH: Path = Path("tests") / "resources"
_FILE_FIXTURE_PATH: Path = RESOURCE_PATH / "file_fixtures"
def copy_file_fixture(fixture_name: str, output_file_path: str | Path) -> None:
def copy_file_fixture(fixture_name: str, output_file_path: Path) -> None:
shutil.copy(_FILE_FIXTURE_PATH / fixture_name, output_file_path)

View file

@ -3,9 +3,9 @@ import time
import pytest
from ytdl_sub.cli.main import _working_directory_lock
from ytdl_sub.config.config_file import ConfigFile
from ytdl_sub.utils.exceptions import ValidationException
from ytdl_sub.utils.file_lock import working_directory_lock
@pytest.fixture
@ -18,15 +18,15 @@ def config() -> ConfigFile:
def test_working_directory_lock(config: ConfigFile):
new_pid = os.fork()
if new_pid == 0: # is child
with _working_directory_lock(config=config):
with working_directory_lock(config=config):
time.sleep(3)
return
time.sleep(1)
with pytest.raises(ValidationException, match="Cannot run two instances of ytdl-sub"):
with _working_directory_lock(config=config):
with working_directory_lock(config=config):
time.sleep(1)
time.sleep(3)
with _working_directory_lock(config=config):
with working_directory_lock(config=config):
pass