diff --git a/README.md b/README.md index b53a5c5d..90ee145b 100644 --- a/README.md +++ b/README.md @@ -45,8 +45,8 @@ You'll find them in the app folder[^3]: [^3]:The app is installed by default in `%LocalAppData%\Programs\Sfvip All x64`, `%LocalAppData%\Programs\Sfvip All x86` or the installation directory you've specified during the installation. # Build -[![version](https://custom-icon-badges.demolab.com/badge/Build%201.4.12.43-informational?logo=github)](/build_config.py#L27) -[![Sloc](https://custom-icon-badges.demolab.com/badge/Sloc%208.5k-informational?logo=file-code)](https://api.codetabs.com/v1/loc/?github=sebdelsol/sfvip-all) +[![version](https://custom-icon-badges.demolab.com/badge/Build%201.4.12.44-informational?logo=github)](/build_config.py#L27) +[![Sloc](https://custom-icon-badges.demolab.com/badge/Sloc%208.4k-informational?logo=file-code)](https://api.codetabs.com/v1/loc/?github=sebdelsol/sfvip-all) [![Ruff](https://custom-icon-badges.demolab.com/badge/Ruff-informational?logo=ruff-color)](https://docs.astral.sh/ruff/) [![Python](https://custom-icon-badges.demolab.com/badge/Python%203.11.8-linen?logo=python-color)](https://www.python.org/downloads/release/python-3118/) [![mitmproxy](https://custom-icon-badges.demolab.com/badge/Mitmproxy%2010.2.4-linen?logo=mitmproxy-black)](https://mitmproxy.org/) diff --git a/build/changelog.md b/build/changelog.md index 6a6b0631..106fa013 100644 --- a/build/changelog.md +++ b/build/changelog.md @@ -1,3 +1,6 @@ +## 1.4.12.44 +* Fix minor bugs. + ## 1.4.12.43 * Option to modify _Sfvip All_ install directory. * When updating the Install directory won't be asked again diff --git a/build_config.py b/build_config.py index dcdf3807..6376b970 100644 --- a/build_config.py +++ b/build_config.py @@ -24,7 +24,7 @@ class Build: main: ClassVar = "sfvip_all.py" company: ClassVar = "sebdelsol" name: ClassVar = "Sfvip All" - version: ClassVar = "1.4.12.43" + version: ClassVar = "1.4.12.44" dir: ClassVar = "build" enable_console: ClassVar = False logs_dir: ClassVar = "../logs" diff --git a/requirements.txt b/requirements.txt index 2915f62f..d01dea38 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ # packages to run the app for both environments mitmproxy>=10.1.6 msgspec>=0.18.6 +psutil>=5.9.8 tkinter-tooltip>=2.2.0 watchdog>=3.0.0 # for downloading the player and libmpv diff --git a/src/mitm/cache.py b/src/mitm/cache.py index 29ca7fc6..1fd3cab7 100644 --- a/src/mitm/cache.py +++ b/src/mitm/cache.py @@ -16,6 +16,10 @@ ValidMediaTypes = Literal["vod", "series"] +def _in_beetween(value: float, min_value: float, max_value: float) -> float: + return max(min_value, min(value, max_value)) + + class MacQuery(NamedTuple): server: str type: ValidMediaTypes @@ -129,7 +133,7 @@ def valid(self) -> bool: @property def missing_percent(self) -> float: - return ((self.total - self.actual) / self.total) if self.total else 1 + return _in_beetween((self.total - self.actual) / self.total, 0, 100) if self.total else 1 class MacCacheSave(MACCacheFile): @@ -219,7 +223,7 @@ class AllCached(NamedTuple): def title(self, loaded: MacCacheLoad) -> str: if missing_percent := loaded.missing_percent: - percent = max(1, min(round(missing_percent * 100), 99)) + percent = _in_beetween(round(missing_percent * 100), 1, 99) missing_str = f"⚠️ {self.missing.format(percent=percent)}" else: missing_str = f"✔ {self.complete}" @@ -244,7 +248,7 @@ class MACCache(CacheCleaner): cached_all_category = "cached_all_category" cached_header = "ListCached" cached_header_bytes = cached_header.encode() - clean_after_days = 15 + clean_after_days = 30 suffixes = MediaTypes all_category = "*" diff --git a/src/sfvip/shared.py b/src/sfvip/shared.py index 731cd71b..77d3702a 100644 --- a/src/sfvip/shared.py +++ b/src/sfvip/shared.py @@ -4,7 +4,9 @@ from pathlib import Path from typing import Optional -from ..winapi import mutex, pids +import psutil + +from ..winapi import mutex from .utils.retry import RetryIfException logger = logging.getLogger(__name__) @@ -30,7 +32,7 @@ def _save(self) -> None: json.dump(self, f, indent=2) def _clean_pids(self, pid_to_remove: Optional[str]) -> None: - clean_pids = [pid for pid in self if not pids.exists(int(pid)) or pid == pid_to_remove] + clean_pids = [pid for pid in self if not psutil.pid_exists(int(pid)) or pid == pid_to_remove] for pid in clean_pids: del self[pid] diff --git a/src/winapi/pids.py b/src/winapi/pids.py deleted file mode 100644 index 211d16f7..00000000 --- a/src/winapi/pids.py +++ /dev/null @@ -1,41 +0,0 @@ -import ctypes -from ctypes.wintypes import HANDLE, LPDWORD - -_SYNCHRONIZE = 0x00100000 -_ERROR_ACCESS_DENIED = 0x00000005 - - -class ExitCodeProcess(ctypes.Structure): - _fields_ = [("hProcess", HANDLE), ("lpExitCode", LPDWORD)] # HANDLE # LPDWORD - - -def exists(pid: int) -> bool: - """ - Check whether a process with the given pid exists. Works on Windows only - Works even if the process is not owned by the current user - """ - kernel32 = ctypes.windll.kernel32 - - process = kernel32.OpenProcess(_SYNCHRONIZE, 0, pid) - if not process: - if kernel32.GetLastError() == _ERROR_ACCESS_DENIED: - # Access is denied. This means the process exists! - return True - return False - - ec = ExitCodeProcess() - out = kernel32.GetExitCodeProcess(process, ctypes.byref(ec)) - if not out: - if kernel32.GetLastError() == _ERROR_ACCESS_DENIED: - # Access is denied. This means the process exists! - kernel32.CloseHandle(process) - return True - kernel32.CloseHandle(process) - return False - if bool(ec.lpExitCode): - # There is an exit code, it quit - kernel32.CloseHandle(process) - return False - # No exit code, it's running. - kernel32.CloseHandle(process) - return True