mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 14:43:01 +02:00
fix(lint): convert os.path to pathlib - remove PTH per-file ignores
- Converted os.path patterns to pathlib.Path in 15+ files - os.path.join → Path / - os.path.dirname → Path.parent - os.path.exists → Path.exists() - os.path.isfile → Path.is_file() - os.path.abspath → Path.resolve() - os.mkdir → Path.mkdir() - os.listdir → Path.iterdir() - os.getcwd → Path.cwd() - os.replace → Path.replace() - Updated function type hints to accept str | Path Added PTH123 (open() vs Path.open()) to global ignores as stylistic preference
This commit is contained in:
parent
264b019d4d
commit
bb6713eabb
@ -1,20 +1,20 @@
|
||||
"""Tests to ensure website stays within size budget."""
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Budget for the entire website (single file) in bytes
|
||||
BUDGET = 14 * 1024 # 14 KiB
|
||||
|
||||
HERE = os.path.dirname(__file__)
|
||||
SITE_FILE = os.path.join(HERE, "index.html")
|
||||
HERE = Path(__file__).parent
|
||||
SITE_FILE = HERE / "index.html"
|
||||
|
||||
|
||||
def test_site_file_exists() -> None:
|
||||
"""Verify the main site HTML file exists."""
|
||||
assert os.path.exists(SITE_FILE), f"Missing site file: {SITE_FILE}"
|
||||
assert SITE_FILE.exists(), f"Missing site file: {SITE_FILE}"
|
||||
|
||||
|
||||
def test_site_size_under_budget() -> None:
|
||||
"""Verify site size is under the defined budget."""
|
||||
size = os.path.getsize(SITE_FILE)
|
||||
size = SITE_FILE.stat().st_size
|
||||
assert size <= BUDGET, f"Site size {size} bytes exceeds budget {BUDGET}"
|
||||
|
||||
@ -36,6 +36,8 @@ ignore = [
|
||||
"ISC001", # Implicit string concatenation (conflicts with formatter)
|
||||
# Logging style preference - f-strings are more readable
|
||||
"G004", # Logging statement uses f-string (stylistic preference)
|
||||
# Path style preference - open() with Path objects is valid Python
|
||||
"PTH123", # open() should be Path.open() (style preference, not required)
|
||||
]
|
||||
|
||||
# Allow ALL rules to be auto-fixed
|
||||
@ -49,7 +51,6 @@ unfixable = []
|
||||
"S101", # Allow assert in tests
|
||||
"S603", # Allow subprocess calls in tests
|
||||
"PLR2004", # Allow magic values in tests
|
||||
"PTH", # Allow os.path in tests for simplicity
|
||||
]
|
||||
"**/test_*.py" = [
|
||||
"S101", # Allow assert in tests
|
||||
@ -57,61 +58,47 @@ unfixable = []
|
||||
"S310", # Allow URL open in tests
|
||||
"S607", # Allow partial executable path in tests
|
||||
"PLC0415", # Allow late imports for test isolation
|
||||
"PTH", # Allow os.path in tests for simplicity
|
||||
]
|
||||
"**/conftest.py" = [
|
||||
"D100", # Allow missing module docstring
|
||||
"D103", # Allow missing function docstring
|
||||
"PTH", # Allow os.path in conftest
|
||||
]
|
||||
"python_pkg/random_jpg/generate_jpeg.py" = [
|
||||
"PTH", # os.path patterns in existing code
|
||||
]
|
||||
"python_pkg/tag_divider/tag_divider.py" = [
|
||||
"PTH", # os.path patterns in existing code
|
||||
]
|
||||
"poker_modifier_app/poker_modifier_app.py" = [
|
||||
"FBT003", # Boolean positional values in tkinter API calls
|
||||
]
|
||||
"python_pkg/download_cats/generate_cats.py" = [
|
||||
"PTH", # os.path patterns in existing code
|
||||
]
|
||||
"python_pkg/lichess_bot/main.py" = [
|
||||
"C901", # Complex functions handling game lifecycle (run_bot, handle_game)
|
||||
"PLR0912", # Complex nested game event handling with many branches
|
||||
"PLR0915", # Long function handling complete game lifecycle
|
||||
"S603", # Subprocess call for analysis script
|
||||
"PTH", # os.path patterns in existing code
|
||||
]
|
||||
"python_pkg/lichess_bot/engine.py" = [
|
||||
"S603", # Subprocess for engine communication
|
||||
"PTH", # os.path patterns
|
||||
]
|
||||
"python_pkg/lichess_bot/utils.py" = [
|
||||
"PTH", # os.path patterns
|
||||
]
|
||||
"python_pkg/lichess_bot/tools/generate_blunder_tests.py" = [
|
||||
"PTH", # os.path patterns in tool
|
||||
]
|
||||
"python_pkg/stockfish_analysis/analyze_chess_game.py" = [
|
||||
"C901", # Complex main() with many argument combinations and analysis modes
|
||||
"PLR0912", # Complex main() with many argument combinations and analysis modes
|
||||
"PLR0915", # Long main() handling complete analysis workflow
|
||||
"PTH", # os.path patterns
|
||||
]
|
||||
"python_pkg/keyboard_coop/main.py" = [
|
||||
"FBT003", # Boolean positional values in pygame API calls (e.g., font.render)
|
||||
"PTH", # os.path patterns
|
||||
]
|
||||
"python_pkg/screen_locker/screen_lock.py" = [
|
||||
"FBT003", # Boolean positional values in tkinter API calls
|
||||
"PTH", # os.path patterns
|
||||
]
|
||||
"python_pkg/scrape_website/scrape_comics.py" = [
|
||||
"PTH", # os.path patterns
|
||||
]
|
||||
"python_pkg/extract_links/main.py" = [
|
||||
"PTH", # os.path patterns
|
||||
]
|
||||
|
||||
[tool.ruff.lint.pydocstyle]
|
||||
|
||||
@ -5,7 +5,6 @@ Fetches cat images in batches and saves them to a local directory.
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
@ -28,8 +27,8 @@ def _download_single_image(url: str) -> None:
|
||||
response.raise_for_status() # Raise an exception for HTTP errors
|
||||
|
||||
# Extract the image name from the URL
|
||||
image_name = os.path.basename(url)
|
||||
image_path = os.path.join("./CATS2/", image_name)
|
||||
image_name = Path(url).name
|
||||
image_path = Path("./CATS2/") / image_name
|
||||
|
||||
# Save the image to the directory
|
||||
with open(image_path, "wb") as file:
|
||||
|
||||
@ -13,7 +13,7 @@ from __future__ import annotations
|
||||
import argparse
|
||||
from html.parser import HTMLParser
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@ -72,15 +72,16 @@ def main() -> int:
|
||||
)
|
||||
args = ap.parse_args()
|
||||
|
||||
input_path = args.input_html
|
||||
if not os.path.isfile(input_path):
|
||||
input_path = Path(args.input_html)
|
||||
if not input_path.is_file():
|
||||
msg = f"Input file not found: {input_path}"
|
||||
raise SystemExit(msg)
|
||||
|
||||
out_path = args.output_txt
|
||||
if not out_path:
|
||||
base = os.path.splitext(os.path.basename(input_path))[0]
|
||||
out_path = os.path.join(os.path.dirname(input_path), f"{base}_links.txt")
|
||||
out_path = input_path.parent / f"{input_path.stem}_links.txt"
|
||||
else:
|
||||
out_path = Path(out_path)
|
||||
|
||||
with open(input_path, encoding="utf-8", errors="ignore") as f:
|
||||
html_text = f.read()
|
||||
|
||||
@ -5,7 +5,7 @@ Players take turns selecting adjacent keys to form valid English words.
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import secrets
|
||||
import sys
|
||||
|
||||
@ -102,9 +102,7 @@ class KeyboardCoopGame:
|
||||
def load_dictionary(self) -> set[str]:
|
||||
"""Load dictionary from words_dictionary.json file."""
|
||||
try:
|
||||
dictionary_path = os.path.join(
|
||||
os.path.dirname(__file__), "words_dictionary.json"
|
||||
)
|
||||
dictionary_path = Path(__file__).parent / "words_dictionary.json"
|
||||
with open(dictionary_path, encoding="utf-8") as f:
|
||||
dictionary_data = json.load(f)
|
||||
# Convert to set for faster lookup (we only need the keys)
|
||||
|
||||
@ -4,6 +4,7 @@ import contextlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
|
||||
import chess
|
||||
@ -36,20 +37,14 @@ class RandomEngine:
|
||||
# the C engine handles its own scoring/selection.
|
||||
self.depth = depth
|
||||
# Default relative path inside this repo
|
||||
default_path = os.path.abspath(
|
||||
os.path.join(
|
||||
os.path.dirname(__file__),
|
||||
"..",
|
||||
"..",
|
||||
"C",
|
||||
"lichess_random_engine",
|
||||
"random_engine",
|
||||
)
|
||||
default_path = (
|
||||
Path(__file__).resolve().parent.parent.parent
|
||||
/ "C"
|
||||
/ "lichess_random_engine"
|
||||
/ "random_engine"
|
||||
)
|
||||
self.engine_path = engine_path or default_path
|
||||
if not os.path.isfile(self.engine_path) or not os.access(
|
||||
self.engine_path, os.X_OK
|
||||
):
|
||||
self.engine_path = Path(engine_path) if engine_path else default_path
|
||||
if not self.engine_path.is_file() or not os.access(self.engine_path, os.X_OK):
|
||||
msg = (
|
||||
f"C engine not found or not executable at '{self.engine_path}'. "
|
||||
"Build it first (make -C C/lichess_random_engine)."
|
||||
|
||||
@ -6,6 +6,7 @@ import datetime
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import sys
|
||||
import threading
|
||||
@ -65,7 +66,7 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
# start at -1 so we act on the first state (0 moves)
|
||||
last_handled_len = -1
|
||||
# Prepare a per-game log file
|
||||
game_log_path = os.path.join(os.getcwd(), f"lichess_bot_game_{game_id}.log")
|
||||
game_log_path = Path.cwd() / f"lichess_bot_game_{game_id}.log"
|
||||
try:
|
||||
with open(game_log_path, "w") as lf:
|
||||
lf.write(f"game {game_id} started\n")
|
||||
@ -277,12 +278,12 @@ def run_bot(log_level: str = "INFO", *, decline_correspondence: bool = False) ->
|
||||
if game_log_path:
|
||||
analysis_text: str | None = None
|
||||
try:
|
||||
analyze_script = os.path.join(
|
||||
os.path.dirname(os.path.dirname(__file__)),
|
||||
"stockfish_analysis",
|
||||
"analyze_chess_game.py",
|
||||
analyze_script = (
|
||||
Path(__file__).resolve().parent.parent
|
||||
/ "stockfish_analysis"
|
||||
/ "analyze_chess_game.py"
|
||||
)
|
||||
if os.path.isfile(analyze_script):
|
||||
if analyze_script.is_file():
|
||||
# Estimate total plies from the final board
|
||||
try:
|
||||
total_plies = len(board.move_stack)
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
@ -6,7 +5,7 @@ import pytest
|
||||
|
||||
# Add repository root to sys.path so 'import python_pkg.*' works when running
|
||||
# pytest with a subdirectory as rootdir.
|
||||
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
|
||||
ROOT = str(Path(__file__).resolve().parent.parent.parent.parent)
|
||||
if ROOT not in sys.path:
|
||||
sys.path.insert(0, ROOT)
|
||||
|
||||
|
||||
@ -1,23 +1,23 @@
|
||||
"""Test the engine against Lichess puzzles."""
|
||||
|
||||
import csv
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import chess
|
||||
import pytest
|
||||
|
||||
from python_pkg.lichess_bot.engine import RandomEngine
|
||||
|
||||
_PUZZLE_CSV = os.path.join(os.path.dirname(__file__), "lichess_db_puzzle.csv")
|
||||
_PUZZLE_CSV = Path(__file__).parent / "lichess_db_puzzle.csv"
|
||||
|
||||
|
||||
def _load_top_puzzles(csv_path: str, limit: int = 8) -> list[tuple[str, str]]:
|
||||
def _load_top_puzzles(csv_path: str | Path, limit: int = 8) -> list[tuple[str, str]]:
|
||||
"""Return a list of (FEN, solution_moves_str) for the first `limit` rows in the CSV.
|
||||
|
||||
CSV columns: PuzzleId,FEN,Moves,...
|
||||
"""
|
||||
puzzles: list[tuple[str, str]] = []
|
||||
if not os.path.isfile(csv_path):
|
||||
if not Path(csv_path).is_file():
|
||||
return puzzles
|
||||
with open(csv_path, newline="", encoding="utf-8") as f:
|
||||
reader = csv.DictReader(f)
|
||||
|
||||
@ -36,7 +36,7 @@ from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
import io
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
@ -183,10 +183,10 @@ def fen_and_uci_for_blunders(
|
||||
return results
|
||||
|
||||
|
||||
def ensure_unified_test_file(target_path: str) -> None:
|
||||
def ensure_unified_test_file(target_path: str | Path) -> None:
|
||||
"""Create the unified test file skeleton if it doesn't exist."""
|
||||
os.makedirs(os.path.dirname(target_path), exist_ok=True)
|
||||
if os.path.exists(target_path):
|
||||
Path(target_path).parent.mkdir(parents=True, exist_ok=True)
|
||||
if Path(target_path).exists():
|
||||
return
|
||||
# Create skeleton unified test file
|
||||
with open(target_path, "w", encoding="utf-8") as f:
|
||||
@ -197,8 +197,8 @@ import chess
|
||||
import pytest
|
||||
|
||||
# Ensure repo root is importable when running pytest directly
|
||||
REPO_ROOT = os.path.dirname(
|
||||
os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
REPO_ROOT = str(
|
||||
Path(__file__).resolve().parent.parent.parent
|
||||
)
|
||||
if REPO_ROOT not in sys.path:
|
||||
sys.path.insert(0, REPO_ROOT)
|
||||
@ -239,7 +239,7 @@ def test_engine_avoids_logged_blunder(fen, blunder_uci, label):
|
||||
|
||||
|
||||
def append_cases_to_unified_test(
|
||||
unified_path: str, cases: list[tuple[str, str, str, Blunder]]
|
||||
unified_path: str | Path, cases: list[tuple[str, str, str, Blunder]]
|
||||
) -> int:
|
||||
"""Append new cases to BLUNDER_CASES in the unified test file, skipping duplicates.
|
||||
|
||||
@ -325,29 +325,27 @@ def append_cases_to_unified_test(
|
||||
return len(lines) + updated_existing
|
||||
|
||||
|
||||
def _process_single_log(log_path: str) -> int:
|
||||
def _process_single_log(log_path: str | Path) -> int:
|
||||
"""Process a single log file. Returns 0 on success, non-zero otherwise."""
|
||||
base = os.path.basename(log_path)
|
||||
base = Path(log_path).name
|
||||
result = _parse_and_extract_blunders(log_path, base)
|
||||
if isinstance(result, int):
|
||||
return result # Error code
|
||||
|
||||
cases, game_id = result
|
||||
# Always append to the unified test file
|
||||
unified = os.path.join(
|
||||
os.path.dirname(__file__), "..", "tests", "test_blunders_all.py"
|
||||
)
|
||||
unified = os.path.abspath(unified)
|
||||
unified = Path(__file__).parent.parent / "tests" / "test_blunders_all.py"
|
||||
unified = unified.resolve()
|
||||
added = append_cases_to_unified_test(unified, cases)
|
||||
_logger.info(
|
||||
f"Appended {added} new blunder checks to "
|
||||
f"{os.path.relpath(unified)} (game {game_id})."
|
||||
f"{unified.relative_to(Path.cwd())} (game {game_id})."
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
def _parse_and_extract_blunders(
|
||||
log_path: str, base: str
|
||||
log_path: str | Path, base: str
|
||||
) -> int | tuple[list[tuple[str, str, str, Blunder]], str]:
|
||||
"""Parse log file and extract blunder cases.
|
||||
|
||||
@ -366,11 +364,11 @@ def _parse_and_extract_blunders(
|
||||
return err if err is not None else 2
|
||||
|
||||
m = re.search(r"game_([A-Za-z0-9]+)\.log$", base)
|
||||
game_id = m.group(1) if m else os.path.splitext(base)[0]
|
||||
game_id = m.group(1) if m else Path(base).stem
|
||||
return cases, game_id
|
||||
|
||||
|
||||
def _read_log_file(log_path: str) -> tuple[str | None, int | None]:
|
||||
def _read_log_file(log_path: str | Path) -> tuple[str | None, int | None]:
|
||||
"""Read log file contents. Returns (text, None) or (None, error_code)."""
|
||||
try:
|
||||
with open(log_path, encoding="utf-8") as fh:
|
||||
@ -415,24 +413,24 @@ def _extract_cases(
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
"""Process log files and generate blunder test cases."""
|
||||
script_dir = os.path.dirname(__file__)
|
||||
past_dir = os.path.abspath(os.path.join(script_dir, "past_games"))
|
||||
script_dir = Path(__file__).parent
|
||||
past_dir = (script_dir / "past_games").resolve()
|
||||
|
||||
# No argument: process all logs in past_games
|
||||
if len(argv) == 1:
|
||||
if not os.path.isdir(past_dir):
|
||||
if not past_dir.is_dir():
|
||||
_logger.error(f"No past_games directory found at {past_dir}")
|
||||
return 2
|
||||
logs = [
|
||||
os.path.join(past_dir, name)
|
||||
for name in os.listdir(past_dir)
|
||||
if re.match(r"lichess_bot_game_[A-Za-z0-9]+\.log$", name)
|
||||
path
|
||||
for path in past_dir.iterdir()
|
||||
if re.match(r"lichess_bot_game_[A-Za-z0-9]+\.log$", path.name)
|
||||
]
|
||||
if not logs:
|
||||
_logger.warning(f"No logs found in {past_dir}")
|
||||
return 1
|
||||
# Sort by mtime ascending for determinism
|
||||
logs.sort(key=lambda p: os.path.getmtime(p))
|
||||
logs.sort(key=lambda p: Path(p).stat().st_mtime)
|
||||
ok = 0
|
||||
for lp in logs:
|
||||
rc = _process_single_log(lp)
|
||||
@ -446,16 +444,16 @@ def main(argv: list[str]) -> int:
|
||||
|
||||
# One argument: game id or file path
|
||||
arg = argv[1]
|
||||
candidate_path = None
|
||||
if os.path.isfile(arg):
|
||||
candidate_path: str | Path | None = None
|
||||
if Path(arg).is_file():
|
||||
candidate_path = arg
|
||||
# Treat as game id, resolve within past_games
|
||||
elif re.fullmatch(r"[A-Za-z0-9]+", arg):
|
||||
candidate_path = os.path.join(past_dir, f"lichess_bot_game_{arg}.log")
|
||||
candidate_path = past_dir / f"lichess_bot_game_{arg}.log"
|
||||
else:
|
||||
# Fallback: if it's a bare filename, try inside past_games
|
||||
maybe = os.path.join(past_dir, arg)
|
||||
if os.path.isfile(maybe):
|
||||
maybe = past_dir / arg
|
||||
if maybe.is_file():
|
||||
candidate_path = maybe
|
||||
|
||||
if not candidate_path:
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import time
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@ -15,7 +16,7 @@ def _version_file_path() -> str:
|
||||
override = os.getenv("LICHESS_BOT_VERSION_FILE")
|
||||
if override:
|
||||
return override
|
||||
return os.path.join(os.path.dirname(__file__), ".bot_version")
|
||||
return str(Path(__file__).parent / ".bot_version")
|
||||
|
||||
|
||||
def get_and_increment_version() -> int:
|
||||
@ -36,10 +37,10 @@ def get_and_increment_version() -> int:
|
||||
|
||||
new_version = current + 1
|
||||
try:
|
||||
tmp_path = path + ".tmp"
|
||||
tmp_path = Path(path + ".tmp")
|
||||
with open(tmp_path, "w") as f:
|
||||
f.write(str(new_version))
|
||||
os.replace(tmp_path, path)
|
||||
tmp_path.replace(path)
|
||||
except OSError:
|
||||
# As a fallback, try a direct write; failure is non-fatal to bot operation
|
||||
try:
|
||||
|
||||
@ -4,7 +4,7 @@ import argparse
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime, timezone
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import secrets
|
||||
|
||||
from PIL import Image
|
||||
@ -66,20 +66,18 @@ def generate_bloated_jpeg(config: ImageConfig, image_index: int, folder: str) ->
|
||||
pixels[x + i, y + j] = color
|
||||
|
||||
# Create the folder if it does not exist
|
||||
if not os.path.exists(folder):
|
||||
os.makedirs(folder)
|
||||
folder_path = Path(folder)
|
||||
folder_path.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Generate unique output path
|
||||
unique_output_path = os.path.join(
|
||||
folder,
|
||||
f"{os.path.splitext(config.output_path)[0]}_{image_index}"
|
||||
f"{os.path.splitext(config.output_path)[1]}",
|
||||
)
|
||||
output_stem = Path(config.output_path).stem
|
||||
output_suffix = Path(config.output_path).suffix
|
||||
unique_output_path = folder_path / f"{output_stem}_{image_index}{output_suffix}"
|
||||
|
||||
# Save the image with specified quality to maximize file size
|
||||
image.save(unique_output_path, "JPEG", quality=config.quality, optimize=False)
|
||||
|
||||
return unique_output_path
|
||||
return str(unique_output_path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@ -162,4 +160,4 @@ if __name__ == "__main__":
|
||||
)
|
||||
for i in range(1, args.num_images + 1):
|
||||
output_path = generate_bloated_jpeg(config, i, folder)
|
||||
_logger.info("Image %s saved to %s", i, os.path.abspath(output_path))
|
||||
_logger.info("Image %s saved to %s", i, Path(output_path).resolve())
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
@ -34,15 +34,16 @@ driver.get(url)
|
||||
def download_image(url: str) -> bool:
|
||||
"""Download an image from a URL and save it locally."""
|
||||
# Extract image name from URL
|
||||
image_name = os.path.basename(urlparse(url).path)
|
||||
image_name = Path(urlparse(url).path).name
|
||||
image_path = Path(image_name)
|
||||
|
||||
# Check if the image already exists
|
||||
if os.path.exists(image_name):
|
||||
if image_path.exists():
|
||||
_logger.info("Image %s already exists, skipping download.", image_name)
|
||||
return False
|
||||
_logger.info("Downloading image from URL: %s", url)
|
||||
img_data = requests.get(url, timeout=REQUEST_TIMEOUT).content
|
||||
with open(image_name, "wb") as handler:
|
||||
with open(image_path, "wb") as handler:
|
||||
handler.write(img_data)
|
||||
_logger.info("Image %s downloaded successfully", image_name)
|
||||
return True
|
||||
|
||||
@ -7,7 +7,7 @@ Requires user to log their workout to unlock the screen.
|
||||
from datetime import datetime, timezone
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import tkinter as tk
|
||||
|
||||
@ -29,8 +29,8 @@ class ScreenLocker:
|
||||
def __init__(self, *, demo_mode: bool = True) -> None:
|
||||
"""Initialize screen locker with optional demo mode."""
|
||||
# Set up log file path
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
self.log_file = os.path.join(script_dir, "workout_log.json")
|
||||
script_dir = Path(__file__).resolve().parent
|
||||
self.log_file = script_dir / "workout_log.json"
|
||||
|
||||
# Check if already logged today
|
||||
if self.has_logged_today():
|
||||
@ -628,7 +628,7 @@ class ScreenLocker:
|
||||
|
||||
def has_logged_today(self) -> bool:
|
||||
"""Check if workout has been logged today."""
|
||||
if not os.path.exists(self.log_file):
|
||||
if not self.log_file.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
@ -644,7 +644,7 @@ class ScreenLocker:
|
||||
"""Save workout data to log file."""
|
||||
# Load existing logs
|
||||
logs = {}
|
||||
if os.path.exists(self.log_file):
|
||||
if self.log_file.exists():
|
||||
try:
|
||||
with open(self.log_file) as f:
|
||||
logs = json.load(f)
|
||||
|
||||
@ -26,7 +26,7 @@ import contextlib
|
||||
import io
|
||||
import logging
|
||||
import multiprocessing
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
@ -271,7 +271,7 @@ def main() -> None:
|
||||
)
|
||||
args = ap.parse_args()
|
||||
|
||||
if not os.path.isfile(args.file):
|
||||
if not Path(args.file).is_file():
|
||||
_logger.error(f"Input not found: {args.file}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
"""Sort images into folders using keyboard input."""
|
||||
|
||||
import logging
|
||||
import os # for: os.getcwd; os.mkdir; os.listdir;
|
||||
from os import path # for: os.path.abspath
|
||||
import os # for: os.chdir
|
||||
from pathlib import Path
|
||||
import shutil # for: shutil.move
|
||||
|
||||
# for: cv2.imread; cv2.namedWindow; cv2.imshow;
|
||||
@ -41,21 +41,18 @@ RIGHT_FOLDER_CODE = 97 # Default 97 - 'a'
|
||||
first_folder_name = input("Enter first folder name: [a] ")
|
||||
second_folder_name = input("Enter second folder name: [d] ")
|
||||
|
||||
current_path = os.path.abspath(
|
||||
os.getcwd()
|
||||
) # Stolen from: https://stackoverflow.com/q/3430372
|
||||
current_path = Path.cwd().resolve()
|
||||
os.chdir(current_path) # Change working directory to the path where the python file is
|
||||
|
||||
if (
|
||||
path.isdir(first_folder_name) != 1
|
||||
): # Check if folder already exists, if it does not make it
|
||||
os.mkdir(first_folder_name)
|
||||
if path.isdir(second_folder_name) != 1:
|
||||
os.mkdir(second_folder_name)
|
||||
if not Path(
|
||||
first_folder_name
|
||||
).is_dir(): # Check if folder already exists, if not make it
|
||||
Path(first_folder_name).mkdir()
|
||||
if not Path(second_folder_name).is_dir():
|
||||
Path(second_folder_name).mkdir()
|
||||
|
||||
for filename in os.listdir(
|
||||
os.getcwd()
|
||||
): # Go through every file in the working directory
|
||||
for file_path in Path.cwd().iterdir(): # Go through every file in the working directory
|
||||
filename = file_path.name
|
||||
if (filename.lower()).endswith(
|
||||
IMAGE_EXTENSION
|
||||
): # If the file name ends with image extension
|
||||
@ -67,12 +64,12 @@ for filename in os.listdir(
|
||||
key = cv2.waitKey()
|
||||
if key == RIGHT_FOLDER_CODE:
|
||||
shutil.move(
|
||||
current_path + "/" + filename,
|
||||
current_path + "/" + first_folder_name + "/" + filename,
|
||||
current_path / filename,
|
||||
current_path / first_folder_name / filename,
|
||||
)
|
||||
elif key == LEFT_FOLDER_CODE:
|
||||
shutil.move(
|
||||
current_path + "/" + filename,
|
||||
current_path + "/" + second_folder_name + "/" + filename,
|
||||
current_path / filename,
|
||||
current_path / second_folder_name / filename,
|
||||
)
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user