SickGear/lib/adba/aniDBmaper.py
2023-02-09 13:41:15 +00:00

139 lines
6.1 KiB
Python

#!/usr/bin/env python
# coding=utf-8
#
# This file is part of aDBa.
#
# aDBa is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# aDBa is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with aDBa. If not, see <http://www.gnu.org/licenses/>.
from random import shuffle
class AniDBMaper:
blacklist = ('unused', 'retired', 'reserved')
def getAnimeBitsA(self, amask):
map = self.getAnimeMapA()
return self._getBitChain(map, amask)
def getAnimeCodesA(self, aBitChain):
amap = self.getAnimeMapA()
return self._getCodes(amap, aBitChain)
def getFileBitsF(self, fmask):
fmap = self.getFileMapF()
return self._getBitChain(fmap, fmask)
def getFileCodesF(self, bitChainF):
fmap = self.getFileMapF()
return self._getCodes(fmap, bitChainF)
def getFileBitsA(self, amask):
amap = self.getFileMapA()
return self._getBitChain(amap, amask)
def getFileCodesA(self, bitChainA):
amap = self.getFileMapA()
return self._getCodes(amap, bitChainA)
def _getBitChain(self, map, wanted):
"""Return an hex string with the correct bit set corresponding to the wanted fields in the map
"""
bit = 0
for index, field in enumerate(map):
if field in wanted and field not in self.blacklist:
bit ^= 1 << len(map) - index - 1
bit = str(hex(bit)).lstrip("0x").rstrip("L")
bit = ''.join(["0" for unused in range(int(len(map) / 4) - len(bit))]) + bit
return bit
@staticmethod
def _getCodes(map, bit_chain):
"""Returns a list with the corresponding fields as set in the bitChain (hex string)
"""
code_list = []
bit_chain = int(bit_chain, 16)
map_length = len(map)
for i in reversed(list(range(map_length))):
if bit_chain & (2 ** i):
code_list.append(map[map_length - i - 1])
return code_list
@staticmethod
def getAnimeMapA():
# each line is one byte
# only chnage this if the api changes
map = ['aid', 'unused', 'year', 'type', 'related_aid_list', 'related_aid_type', 'category_list', 'category_weight_list',
'romaji_name', 'kanji_name', 'english_name', 'other_name', 'short_name_list', 'synonym_list', 'retired', 'retired',
'episodes', 'highest_episode_number', 'special_ep_count', 'air_date', 'end_date', 'url', 'picname', 'category_id_list',
'rating', 'vote_count', 'temp_rating', 'temp_vote_count', 'average_review_rating', 'review_count', 'award_list', 'is_18_restricted',
'anime_planet_id', 'ANN_id', 'allcinema_id', 'AnimeNfo_id', 'unused', 'unused', 'unused', 'date_record_updated',
'character_id_list', 'creator_id_list', 'main_creator_id_list', 'main_creator_name_list', 'unused', 'unused', 'unused', 'unused',
'specials_count', 'credits_count', 'other_count', 'trailer_count', 'parody_count', 'unused', 'unused', 'unused']
return map
@staticmethod
def getFileMapF():
# each line is one byte
# only chnage this if the api changes
map = ['unused', 'aid', 'eid', 'gid', 'mylist_id', 'list_other_episodes', 'IsDeprecated', 'state',
'size', 'ed2k', 'md5', 'sha1', 'crc32', 'unused', 'unused', 'reserved',
'quality', 'source', 'audio_codec_list', 'audio_bitrate_list', 'video_codec', 'video_bitrate', 'video_resolution', 'file_type_extension',
'dub_language', 'sub_language', 'length_in_seconds', 'description', 'aired_date', 'unused', 'unused', 'anidb_file_name',
'mylist_state', 'mylist_filestate', 'mylist_viewed', 'mylist_viewdate', 'mylist_storage', 'mylist_source', 'mylist_other', 'unused']
return map
@staticmethod
def getFileMapA():
# each line is one byte
# only chnage this if the api changes
map = ['anime_total_episodes', 'highest_episode_number', 'year', 'type', 'related_aid_list', 'related_aid_type', 'category_list', 'reserved',
'romaji_name', 'kanji_name', 'english_name', 'other_name', 'short_name_list', 'synonym_list', 'retired', 'retired',
'epno', 'ep_name', 'ep_romaji_name', 'ep_kanji_name', 'episode_rating', 'episode_vote_count', 'unused', 'unused',
'group_name', 'group_short_name', 'unused', 'unused', 'unused', 'unused', 'unused', 'date_aid_record_updated']
return map
def checkMapping(self, verbos=False):
print("------")
print("File F: " + str(self.checkMapFileF(verbos)))
print("------")
print("File A: " + str(self.checkMapFileA(verbos)))
def checkMapFileF(self, verbos=False):
get_general_map = self.getFileMapF
get_bits = self.getFileBitsF
get_codes = self.getFileCodesF
return self._checkMapGeneral(get_general_map, get_bits, get_codes, verbos=verbos)
def checkMapFileA(self, verbos=False):
get_general_map = self.getFileMapA
get_bits = self.getFileBitsA
get_codes = self.getFileCodesA
return self._checkMapGeneral(get_general_map, get_bits, get_codes, verbos=verbos)
def _checkMapGeneral(self, getGeneralMap, getBits, getCodes, verbos=False):
map = getGeneralMap()
shuffle(map)
mask = [elem for elem in map if elem not in self.blacklist][:5]
bits = getBits(mask)
mask_re = getCodes(bits)
bits_re = getBits(mask_re)
if verbos:
print(mask)
print(mask_re)
print(bits)
print(bits_re)
print("bits are:" + str((bits_re == bits)))
print("map is :" + str((sorted(mask_re) == sorted(mask))))
return (bits_re == bits) and sorted(mask_re) == sorted(mask)