1#!/usr/bin/env python3
2"""
3
4"""
5
6# Imports:
7from __future__ import annotations
8
9# ##-- stdlib imports
10import datetime
11import enum
12import functools as ftz
13import itertools as itz
14import logging as logmod
15import pathlib as pl
16import re
17import time
18import types
19import weakref
20from uuid import UUID, uuid1
21
22# ##-- end stdlib imports
23
24# ##-- 3rd party imports
25import bibtexparser
26import bibtexparser.model as model
27from bibtexparser import middlewares as ms
28from bibtexparser.middlewares.middleware import (BlockMiddleware,
29 LibraryMiddleware)
30from jgdv import Proto
31# ##-- end 3rd party imports
32
33import bibble._interface as API
34from bibble.util.middlecore import IdenLibraryMiddleware
35import bibble.model as bmodel
36
37# ##-- types
38# isort: off
39import abc
40import collections.abc
41from typing import TYPE_CHECKING, cast, assert_type, assert_never
42from typing import Generic, NewType
43# Protocols:
44from typing import Protocol, runtime_checkable
45# Typing Decorators:
46from typing import no_type_check, final, override, overload
47
48if TYPE_CHECKING:
49 from jgdv import Maybe
50 from typing import Final
51 from typing import ClassVar, Any, LiteralString
52 from typing import Never, Self, Literal
53 from typing import TypeGuard
54 from collections.abc import Iterable, Iterator, Callable, Generator
55 from collections.abc import Sequence, Mapping, MutableMapping, Hashable
56
57 type Logger = logmod.Logger
58##--|
59
60# isort: on
61# ##-- end types
62
63##-- logging
64logging = logmod.getLogger(__name__)
65##-- end logging
66
[docs]
67class FailureLogHandler(IdenLibraryMiddleware):
68 """ Middleware to Filter failed blocks of a library,
69 either to a logger output, or to a file
70 Put at end of parse stack
71
72 Will log out where the failed blocks start by line.
73 """
74
94
[docs]
95 def _find_source_file(self, block, library) -> Maybe[str]:
96 match block:
97 case model.Entry():
98 target_key = block.key
99 case _:
100 return None
101
102 match bmodel.MetaBlock.find_in(library):
103 case None:
104 return None
105 case bmodel.MetaBlock() as meta if 'sources' not in meta.data:
106 return None
107 case bmodel.MetaBlock() as meta:
108 data = meta.data
109 sources = meta.data['sources']
110
111 for source in sources:
112 if source in data and target_key in data[source]:
113 return source
114 ##--|
115 else:
116 return None
117
118
[docs]
119class FailureWriteHandler(IdenLibraryMiddleware):
120 """ Middleware to Filter failed blocks of a library,
121 either to a logger output, or to a file
122 Put at end of parse stack
123
124 Will log out where the failed blocks start by line.
125 """
126
127 def __init__(self, *, file:Maybe[str|pl.Path]=None, **kwargs):
128 super().__init__(**kwargs)
129 match file:
130 case str() as x:
131 self.file_target = pl.Path(x)
132 case pl.Path() as x:
133 self.file_target = x
134 case _:
135 self.file_target = None
136
137
157
[docs]
158 def write_failures_to_file(self, reports:list) -> None:
159 match reports:
160 case []:
161 return
162 case _ if self.file_target is None:
163 return
164 case _:
165 pass
166
167 total = len(reports)
168 with self.file_target.open("w") as f:
169 for rep, err, raw in reports:
170 f.writelines(["\n\n--------------------\n",
171 rep,
172 f"\nError: {err}",
173 "\n--------------------\n",
174 raw,
175 ])
176
[docs]
177 def _find_source_file(self, block, library) -> Maybe[str]:
178 match block:
179 case model.Entry():
180 target_key = block.key
181 case _:
182 return None
183
184 match bmodel.MetaBlock.find_in(library):
185 case None:
186 return None
187 case bmodel.MetaBlock() as meta if 'sources' not in meta.data:
188 return None
189 case bmodel.MetaBlock() as meta:
190 data = meta.data
191 sources = meta.data['sources']
192
193 for source in sources:
194 if source in data and target_key in data[source]:
195 return source
196 ##--|
197 else:
198 return None