File: _msk.py

package info (click to toggle)
isbnlib 3.9.3-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 596 kB
  • sloc: python: 4,575; makefile: 4
file content (63 lines) | stat: -rw-r--r-- 1,786 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# -*- coding: utf-8 -*-
"""Hyphenate an ISBN."""

import logging

from ._core import EAN13, canonical, to_isbn13
from ._data.data4mask import ranges
from ._exceptions import NotValidISBNError

LOGGER = logging.getLogger(__name__)


def msk(isbn, separator='-'):
    """Transform a canonical ISBN to a `masked` one.

    `Mask` the ISBN, separating by identifier
    ISBN-10 identifiers: country-publisher-title-check

    Used the iterative version of the `sliding-window` algorithm.
    Not pretty, but fast! Lines 42-52 implement the search loop.
    O(n) for n (number of keys),
    if data structure like 'ranges' in data4mask.py
    """
    ib = canonical(isbn)
    ean = EAN13(ib)
    if len(ib) not in (10, 13) or ean is None:
        LOGGER.critical('%s is not a valid ISBN', isbn)
        raise NotValidISBNError(isbn)

    isbn10 = False
    if len(ib) == 10:
        check10 = ib[-1]
        ib = to_isbn13(ib)
        isbn10 = True

    idx = None
    check = ib[-1:]  # <-- HACK!
    cur = 3
    igi = cur
    buf = ib[igi:cur + 1]
    group = ib[0:cur] + '-' + buf

    for _ in range(6):  # pragma: no cover
        if group in ranges:
            sevens = ib[cur + 1:cur + 8].ljust(7, '0')
            for l in ranges[group]:
                if l[0] <= int(sevens) <= l[1]:
                    idx = l[2]
                    break
            break
        cur += 1
        buf = ib[igi:cur + 1]
        group = group + buf[-1:]  # <-- HACK!

    if idx:
        if isbn10:
            group = group[4:]
            check = check10
        return separator.join(
            [group, ib[cur + 1:cur + idx + 1], ib[cur + idx + 1:-1], check])
    LOGGER.warning('identifier not found! '
                   'Please, update the program.')  # pragma: no cover
    return None