adsfolio.pdf.watcher
PDF filesystem watcher with polling and optional watchdog backends.
- exception adsfolio.pdf.watcher.PdfNotReadyError[source]
Bases:
RuntimeErrorIndicate that a PDF should be retried after its filesystem state changes.
- class adsfolio.pdf.watcher.PdfWatcher(identifier, renamer, upgrader=None)[source]
Bases:
objectWatch directories for new PDF files and process them.
- Parameters:
identifier (PdfIdentifier)
renamer (PdfRenamer)
upgrader (PdfUpgrader | None)
- poll_loop(directory, sidecar, interval=10.0, recursive=False, callback=None, stop_event=None, auto_upgrade=False, upgrade_interval_hours=24.0, upgrade_kwargs=None, recheck_callback=None, update_locations=True)[source]
Poll filesystem for new PDFs and process them.
- Parameters:
directory (pathlib.Path)
sidecar (adsfolio.pdf.sidecar.Sidecar)
interval (float)
recursive (bool)
callback (collections.abc.Callable[[pathlib.Path], Any] | None)
stop_event (Any | None)
auto_upgrade (bool)
upgrade_interval_hours (float)
recheck_callback (collections.abc.Callable[[], bool] | None)
update_locations (bool)
- Return type:
None
- process_event(event, state, rename_settings, identify_settings)[source]
Process one typed watch event using reusable GUI settings.
- Parameters:
event (WatchEvent) – Detected filesystem event to process.
state (Sidecar or CentralPdfRegistryState) – Root-scoped catalog state owned by the caller’s worker thread.
rename_settings (RenameSettings) – Reusable filename rendering settings.
identify_settings (IdentifySettings) – Reusable identification settings.
- Returns:
Typed processing result. Readiness failures are deferred and expected processing failures are reported as failed outcomes.
- Return type:
- process_new_pdf(pdf_path, sidecar, scheme='{authors}_{bibcode}-{title}', author_format='surname_initials', char_policy='keep', max_authors=3, authors_when_truncated=1, output_unresolved=None, apply=True, journal_map=None, strategies=(IdentifyStrategy.FIRST_PAGE_ARXIV, IdentifyStrategy.FILENAME_BIBCODE, IdentifyStrategy.FILENAME_DOI, IdentifyStrategy.PDF_METADATA_BIBCODE, IdentifyStrategy.PDF_METADATA_DOI, IdentifyStrategy.FIRST_PAGE_BIBCODE, IdentifyStrategy.FIRST_PAGE_DOI, IdentifyStrategy.STRUCTURED_FILENAME, IdentifyStrategy.PDF_METADATA_TITLE, IdentifyStrategy.FIRST_PAGE_TITLE), providers=(DoiProvider.ADS, DoiProvider.CROSSREF, DoiProvider.DATACITE), author_separator='+', author_truncation_suffix='+', _check_annotation_revision=True)[source]
Identify and rename a single PDF, returning resolved metadata.
Every stored record is checked against the PDF’s own identity before the catalog is written or the file is renamed, including a dry run.
- Raises:
IdentityValidationError – If a stored or newly found identity conflicts with the PDF or cannot be independently verified. Nothing is written or moved.
- Parameters:
pdf_path (pathlib.Path)
sidecar (adsfolio.pdf.sidecar.Sidecar)
scheme (str)
author_format (str)
char_policy (str)
max_authors (int)
authors_when_truncated (int)
output_unresolved (pathlib.Path | None)
apply (bool)
journal_map (dict | None)
strategies (tuple[adsfolio.pdf.identify_settings.IdentifyStrategy, ...])
providers (tuple[adsfolio.pdf.doi_providers.DoiProvider, ...])
author_separator (str)
author_truncation_suffix (str)
_check_annotation_revision (bool)
- Return type:
dict | None
- watchdog_loop(directory, sidecar, recursive=False, callback=None, reconciliation_interval=10.0, stop_event=None, auto_upgrade=False, upgrade_interval_hours=24.0, upgrade_kwargs=None, recheck_callback=None, update_locations=True)[source]
Use watchdog Observer backend to react to filesystem events.
- Parameters:
directory (pathlib.Path)
sidecar (adsfolio.pdf.sidecar.Sidecar)
recursive (bool)
callback (collections.abc.Callable[[pathlib.Path], Any] | None)
reconciliation_interval (float)
stop_event (Any | None)
auto_upgrade (bool)
upgrade_interval_hours (float)
recheck_callback (collections.abc.Callable[[], bool] | None)
update_locations (bool)
- Return type:
None
- class adsfolio.pdf.watcher.WatchIdentifyPolicy(root, unresolved_directory, skip_unresolved_directory)[source]
Bases:
objectResolved single-file Identify path policy for one watched root.
- Parameters:
root (pathlib.Path)
unresolved_directory (pathlib.Path)
skip_unresolved_directory (bool)
- excludes(path)[source]
Return whether path is inside the configured skip directory.
- Parameters:
path (pathlib.Path)
- Return type:
- classmethod from_settings(root, settings)[source]
Resolve output and skip containment from reusable settings.
- Parameters:
root (pathlib.Path) – Watched library root.
settings (adsfolio.pdf.identify_settings.IdentifySettings) – Effective Identify settings for the watched root.
- Returns:
Normalized root, unresolved directory, and skip behavior. Relative output paths are rooted under the library; an unset output uses <root>/unresolved for skip containment, matching bulk Identify.
- Return type:
- Raises:
ValueError – If skipping is enabled and the unresolved directory contains the watched root.
- root: pathlib.Path
- unresolved_directory: pathlib.Path