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
22import warnings
23
24# ##-- end stdlib imports
25
26# ##-- 3rd party imports
27import bibtexparser
28import bibtexparser.model as model
29import pyisbn
30from bibtexparser import middlewares as ms
31from bibtexparser.middlewares.middleware import (BlockMiddleware, LibraryMiddleware)
32from jgdv import Mixin, Proto
33
34# ##-- end 3rd party imports
35
36with warnings.catch_warnings():
37 warnings.simplefilter("ignore", category=SyntaxWarning)
38 import isbn_hyphenate
39
40import bibble._interface as API
41from . import _interface as MAPI
42from bibble.util.middlecore import IdenBlockMiddleware
43from bibble.util.mixins import ErrorRaiser_m
44
45# ##-- types
46# isort: off
47import abc
48import collections.abc
49from typing import TYPE_CHECKING, cast, assert_type, assert_never
50from typing import Generic, NewType
51# Protocols:
52from typing import Protocol, runtime_checkable
53# Typing Decorators:
54from typing import no_type_check, final, override, overload
55
56if TYPE_CHECKING:
57 from jgdv import Maybe
58 from typing import Final
59 from typing import ClassVar, Any, LiteralString
60 from typing import Never, Self, Literal
61 from typing import TypeGuard
62 from collections.abc import Iterable, Iterator, Callable, Generator
63 from collections.abc import Sequence, Mapping, MutableMapping, Hashable
64
65##--|
66
67# isort: on
68# ##-- end types
69
70##-- logging
71logging = logmod.getLogger(__name__)
72##-- end logging
73
74##--|
75
[docs]
76@Proto(API.ReadTime_p)
77@Mixin(ErrorRaiser_m)
78class IsbnValidator(IdenBlockMiddleware):
79 """
80 Try to validate the entry's isbn number
81 """
82
[docs]
83 def on_read(self):
84 Never()
85
[docs]
86 def transform_Entry(self, entry, library):
87 match entry.get(MAPI.ISBN_K):
88 case None:
89 return [entry]
90 case model.Field(value=str() as val) if bool(val):
91 try:
92 isbn = pyisbn.Isbn(MAPI.ISBN_STRIP_RE.sub("", val))
93 if not isbn.validate():
94 raise pyisbn.IsbnError("validation fail")
95 else:
96 return [entry]
97 except pyisbn.IsbnError as err:
98 self._logger.warning("ISBN validation fail: %s : %s", entry.key, val)
99 entry.set_field(model.Field(MAPI.INVALID_ISBN_K, val))
100 entry.set_field(model.Field(MAPI.ISBN_K, ""))
101 return [entry]
102 case model.Field(value=str() as val):
103 del entry[MAPI.ISBN_K]
104 return [entry]
105 case x:
106 raise TypeError(type(x))
107