comicbox.enums.maps.identifiers

[docs] module comicbox.enums.maps.identifiers

  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
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
"""Identifier maps."""

from types import MappingProxyType
from typing import Any

from bidict import frozenbidict

from comicbox.enums.comicbox import AlternateIdSources, IdSources
from comicbox.identifiers import DEFAULT_ID_SOURCE

ID_SOURCE_NAME_MAP: frozenbidict[IdSources, str] = frozenbidict(
    {
        # DBs
        IdSources.ANILIST: "AniList",
        IdSources.COMICVINE: "Comic Vine",
        IdSources.COMIXOLOGY: "ComiXology",
        IdSources.GCD: "Grand Comics Database",
        IdSources.KITSU: "Kitsu",
        IdSources.LCG: "League of Comic Geeks",
        IdSources.PANELSYNDICATE: "Panel Syndicate",
        IdSources.MANGADEX: "MangaDex",
        IdSources.MANGAUPDATES: "MangaUpdates",
        IdSources.MARVEL: "Marvel",
        IdSources.METRON: "Metron",
        IdSources.MYANIMELIST: "MyAnimeList",
        # GITNs
        IdSources.ASIN: "Amazon",
        IdSources.GTIN: "GTIN",
        IdSources.ISBN: "ISBN",
        IdSources.UPC: "UPC",
    }
)

_ID_SOURCE_ALIASES: MappingProxyType[IdSources, frozenset[str]] = MappingProxyType(
    {
        IdSources.ANILIST: frozenset({"anilist.co"}),
        IdSources.ASIN: frozenset(
            {
                "amazon.com",
                "amazon.ca",
                "amazon.co.uk",
                "amazon.co.jp",
                "amazon.com.mx",
                "amazon.com.br",
                "amazon.es",
                "amazon.de",
                "amazon.fr",
                "amazon.it",
            }
        ),
        IdSources.COMICVINE: frozenset(
            {
                AlternateIdSources.CVDB_ALTERNATE.value,
                "comicvine.gamespot.com",
                "comicvine.com",
                "www.comicvine.com",
                "stage.comicvine.com",
                "www.stage.comicvine.com",
            }
        ),
        IdSources.COMIXOLOGY: frozenset(
            {"comixology.com", AlternateIdSources.CMXDB_ALTERNATE.value}
        ),
        IdSources.GCD: frozenset({"comics.org"}),
        IdSources.GTIN: frozenset(
            {"gs1.org", "gs1us.org", "gtinlookup.info", "gtinlookup.org"}
        ),
        IdSources.ISBN: frozenset({"isbnsearch.org", "isbndb.com"}),
        IdSources.KITSU: frozenset({"kistu.app"}),
        IdSources.LCG: frozenset({"leagueofcomicgeeks.com"}),
        IdSources.MANGADEX: frozenset({"mangadex.org"}),
        IdSources.MANGAUPDATES: frozenset({"mangaupdates.com"}),
        IdSources.MARVEL: frozenset({"marvel.com"}),
        IdSources.METRON: frozenset({"metron.cloud"}),
        IdSources.MYANIMELIST: frozenset({"myanimelist.net"}),
        IdSources.PANELSYNDICATE: frozenset({"panelsyndicate.com"}),
        IdSources.UPC: frozenset({"barcodelookup.com", "go-upc.com"}),
    }
)

_ID_SOURCE_ALIAS_TO_SOURCE_MAP: MappingProxyType[str, IdSources] = MappingProxyType(
    {
        alias.value.lower()
        if isinstance(alias, IdSources)
        else alias.lower(): id_source
        for id_source, aliases in _ID_SOURCE_ALIASES.items()
        for alias in aliases | {id_source, ID_SOURCE_NAME_MAP[id_source]}
    }
)


def get_id_source_by_alias(
    id_source_alias: str, default: IdSources | None = DEFAULT_ID_SOURCE
) -> IdSources | None:
    """Get id source by alias."""
    return _ID_SOURCE_ALIAS_TO_SOURCE_MAP.get(id_source_alias.lower(), default)


def _build_source_alias_tree(
    node: dict[Any, Any], source: IdSources, parts: list[str]
) -> None:
    if isinstance(node, IdSources):
        return
    part = parts[0]
    if len(parts) == 1:
        node[part] = source
    else:
        if part not in node:
            node[part] = {}
        _build_source_alias_tree(node[part], source, parts[1:])


def _create_source_alias_tree() -> dict:
    tree = {}
    for source, aliases in _ID_SOURCE_ALIASES.items():
        for alias in aliases:
            parts = alias.split(".")
            if len(parts) <= 1:
                continue
            parts.reverse()
            _build_source_alias_tree(tree, source, parts)
    return tree


SOURCE_ALIAS_TREE = _create_source_alias_tree()