Source code for bibble.files.path_reader

  1#!/usr/bin/env python3
  2"""
  3
  4See EOF for license/metadata/notes as applicable
  5"""
  6
  7# Imports:
  8from __future__ import annotations
  9
 10# ##-- stdlib imports
 11import datetime
 12import enum
 13import functools as ftz
 14import itertools as itz
 15import logging as logmod
 16import pathlib as pl
 17import re
 18import time
 19import types
 20import weakref
 21from uuid import UUID, uuid1
 22
 23# ##-- end stdlib imports
 24
 25# ##-- 3rd party imports
 26import bibtexparser
 27import bibtexparser.model as model
 28from bibtexparser import middlewares as ms
 29from bibtexparser.middlewares.middleware import (BlockMiddleware, LibraryMiddleware)
 30from jgdv import Proto, Mixin
 31
 32# ##-- end 3rd party imports
 33
 34# ##-- 1st party imports
 35import bibble._interface as API
 36from bibble.util.mixins import ErrorRaiser_m, FieldMatcher_m
 37from bibble.util.middlecore import IdenBlockMiddleware
 38
 39# ##-- end 1st party imports
 40
 41# ##-- types
 42# isort: off
 43import abc
 44import collections.abc
 45from typing import TYPE_CHECKING, cast, assert_type, assert_never
 46from typing import Generic, NewType
 47# Protocols:
 48from typing import Protocol, runtime_checkable
 49# Typing Decorators:
 50from typing import no_type_check, final, override, overload
 51
 52if TYPE_CHECKING:
 53    from jgdv import Maybe
 54    from typing import Final
 55    from typing import ClassVar, Any, LiteralString
 56    from typing import Never, Self, Literal
 57    from typing import TypeGuard
 58    from collections.abc import Iterable, Iterator, Callable, Generator
 59    from collections.abc import Sequence, Mapping, MutableMapping, Hashable
 60
 61##--|
 62
 63# isort: on
 64# ##-- end types
 65
 66##-- logging
 67logging = logmod.getLogger(__name__)
 68##-- end logging
 69
[docs] 70@Proto(API.ReadTime_p) 71@Mixin(ErrorRaiser_m, FieldMatcher_m) 72class PathReader(IdenBlockMiddleware): 73 """ 74 Convert file paths in bibliography to pl.Path's, expanding relative paths 75 according to lib_root 76 """ 77 78 _whitelist = ("file",) 79 80 def __init__(self, *, lib_root:Maybe[pl.Path]=None, **kwargs): 81 super().__init__(**kwargs) 82 self._lib_root = lib_root or pl.Path.cwd() 83 self.set_field_matchers(white=kwargs.pop("whitelist", self._whitelist), black=[]) # type: ignore[attr-defined] 84
[docs] 85 def on_read(self): 86 Never()
87
[docs] 88 def transform_Entry(self, entry, library): 89 match self.match_on_fields(entry, library): 90 case model.Entry() as x: 91 return [x] 92 case Exception() as err: 93 return [self.make_error_block(entry, err)] 94 case x: 95 raise TypeError(type(x))
96
[docs] 97 def field_h(self, field, entry): 98 base = pl.Path(field.value) 99 match base.parts[0]: 100 case "/": 101 field.value = base 102 case "~": 103 field.value = base.expanduser().resolve() 104 case _: 105 field.value = self._lib_root / base 106 107 if not field.value.exists(): 108 return ValueError(f"File does not exist: {field.value}") 109 110 return [field]