# Copyright 2022 (c) Anna Schumaker. """Extra path handling for URIs.""" import pathlib import threading import urllib class ReaddirThread(threading.Thread): """An object to manager asynchronous tree iteration.""" def __init__(self, directory: pathlib.Path): """Initialize an IterTreeResult.""" super().__init__() self.root = directory self._files = [] self._lock = threading.Lock() self._stop_event = threading.Event() def __read_directory(self, directory: pathlib.Path) -> None: if self._stop_event.is_set(): return for path in directory.iterdir(): if path.is_dir(): self.__read_directory(path) else: with self._lock: self._files.append(path) def poll_result(self) -> list[pathlib.Path] | None: """Poll for the result of the IterTreeThread.""" with self._lock: if self.is_alive() or len(self._files): files = self._files self._files = [] return files return None def run(self) -> None: """Run the IterTreeThread.""" self.__read_directory(self.root) def stop(self) -> None: """Signal the thread to stop.""" self._stop_event.set() def readdir_async(directory: pathlib.Path) -> ReaddirThread: """Iterate through a directory tree asynchronously.""" if directory.is_dir(): res = ReaddirThread(directory) res.start() return res def from_uri(uri: str) -> pathlib.Path: """Make a path from a uri.""" if parsed := urllib.parse.urlparse(uri): return pathlib.Path(urllib.parse.unquote(parsed.path)) return pathlib.Path(uri)