This commit is contained in:
睿 安
2026-01-21 16:48:36 +08:00
commit abba5cb273
246 changed files with 57473 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
import difflib
import os
import typing
import urllib.request
import simplejson as json
class FuzzyDict(dict):
"""Provides a dictionary that performs fuzzy lookup"""
def __init__(self, cutoff: float = 0.6):
"""Construct a new FuzzyDict instance
items is an dictionary to copy items from (optional)
cutoff is the match ratio below which matches should not be considered
cutoff needs to be a float between 0 and 1 (where zero is no match
and 1 is a perfect match)"""
super(FuzzyDict, self).__init__()
self.cutoff = cutoff
# short wrapper around some super (dict) methods
self._dict_contains = lambda key: super(FuzzyDict, self).__contains__(key)
self._dict_getitem = lambda key: super(FuzzyDict, self).__getitem__(key)
def _search(self, lookfor: typing.Any, stop_on_first: bool = False):
"""Returns the value whose key best matches lookfor
if stop_on_first is True then the method returns as soon
as it finds the first item
"""
# if the item is in the dictionary then just return it
if self._dict_contains(lookfor):
return True, lookfor, self._dict_getitem(lookfor), 1
# set up the fuzzy matching tool
ratio_calc = difflib.SequenceMatcher()
ratio_calc.set_seq1(lookfor)
# test each key in the dictionary
best_ratio = 0
best_match = None
best_key = None
for key in self:
# if the current key is not a string
# then we just skip it
try:
# set up the SequenceMatcher with other text
ratio_calc.set_seq2(key)
except TypeError:
continue
# we get an error here if the item to look for is not a
# string - if it cannot be fuzzy matched and we are here
# this it is definitely not in the dictionary
try:
# calculate the match value
ratio = ratio_calc.ratio()
except TypeError:
break
# if this is the best ratio so far - save it and the value
if ratio > best_ratio:
best_ratio = ratio
best_key = key
best_match = self._dict_getitem(key)
if stop_on_first and ratio >= self.cutoff:
break
return best_ratio >= self.cutoff, best_key, best_match, best_ratio
def __contains__(self, item: typing.Any):
if self._search(item, True)[0]:
return True
else:
return False
def __getitem__(self, lookfor: typing.Any):
matched, key, item, ratio = self._search(lookfor)
if not matched:
raise KeyError(
"'%s'. closest match: '%s' with ratio %.3f"
% (str(lookfor), str(key), ratio)
)
return item
__HERE = os.path.abspath(os.path.dirname(__file__))
with open(os.path.join(__HERE, "map_filename.json"), "r", encoding="utf8") as f:
FILENAMES: FuzzyDict = FuzzyDict()
for k, v in json.load(f).items():
FILENAMES[k] = v
with open(os.path.join(__HERE, "city_coordinates.json"), "r", encoding="utf8") as f:
COORDINATES: FuzzyDict = FuzzyDict()
for k, v in json.load(f).items():
COORDINATES[k] = v
EXTRA = {}
def register_url(asset_url: str):
if asset_url:
registry = asset_url + "/registry.json"
try:
contents = urllib.request.urlopen(registry).read()
contents = json.loads(contents)
except Exception as e:
raise e
files = {}
pinyin_names = set()
for name, pinyin in contents["PINYIN_MAP"].items():
file_name = contents["FILE_MAP"][pinyin]
files[name] = [file_name, "js"]
pinyin_names.add(pinyin)
for key, file_name in contents["FILE_MAP"].items():
if key not in pinyin_names:
# English names
files[key] = [file_name, "js"]
js_folder_name = contents["JS_FOLDER"]
if js_folder_name == "/":
js_file_prefix = f"{asset_url}/"
else:
js_file_prefix = f"{asset_url}/{js_folder_name}/"
EXTRA[js_file_prefix] = files
def register_files(asset_files: dict):
if asset_files:
FILENAMES.update(asset_files)
def register_coords(coords: dict):
if coords:
COORDINATES.update(coords)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,218 @@
{
"蒲隆地": "BI",
"圣卢西亚": "LC",
"巴巴多斯": "BB",
"安道尔": "AD",
"利比里亚": "LR",
"吉尔吉斯斯坦": "KG",
"阿曼": "OM",
"利比亚": "LY",
"根西": "GG",
"南非": "ZA",
"阿塞拜疆": "AZ",
"巴拉圭": "PY",
"匈牙利": "HU",
"巴勒斯坦": "PS",
"泰国": "TH",
"黎巴嫩": "LB",
"英属维尔京群岛": "VG",
"特立尼达和多巴哥": "TT",
"巴基斯坦": "PK",
"加拿大": "CA",
"保加利亚": "BG",
"马来西亚": "MY",
"叙利亚": "SY",
"毛里塔尼亚": "MR",
"白俄罗斯": "BY",
"秘鲁": "PE",
"摩洛哥": "MA",
"莱索托": "LS",
"法罗群岛": "FO",
"圣基茨和尼维斯": "KN",
"阿根廷": "AR",
"委内瑞拉": "VE",
"塞舌尔": "SC",
"英属印度洋领地": "IO",
"瓦努阿图": "VU",
"纳米比亚": "NA",
"马拉维": "MW",
"克罗地亚": "HR",
"玻利维亚": "BO",
"塞内加尔": "SN",
"希腊": "GR",
"蒙古": "MN",
"东帝汶": "TL",
"新加坡": "SG",
"意大利": "IT",
"皮特凱恩群島": "PN",
"芬兰": "FI",
"圭亚那": "GY",
"福克兰群岛": "FK",
"毛里求斯": "MU",
"马其顿": "MK",
"新西兰": "NZ",
"波斯尼亚-黑塞哥维那": "BA",
"吐瓦鲁": "TV",
"以色列": "IL",
"塞尔维亚": "RS",
"密克罗尼西亚联邦": "FM",
"斯洛文尼亚": "SI",
"阿富汗": "AF",
"科威特": "KW",
"英国": "GB",
"汤加": "TO",
"贝宁": "BJ",
"撒拉威阿拉伯民主共和国": "",
"海地": "HT",
"格鲁吉亚": "GE",
"安提瓜和巴布达": "AG",
"刚果金": "CD",
"澳大利亚": "AU",
"史瓦济兰": "SZ",
"马达加斯加": "MG",
"哥伦比亚": "CO",
"多米尼加共和国": "DO",
"爱沙尼亚": "EE",
"哥斯达黎加": "CR",
"塞浦路斯": "CY",
"沙特阿拉伯": "SA",
"南苏丹": "SS",
"荷兰": "NL",
"圣马力诺": "SM",
"罗马尼亚": "RO",
"智利": "CL",
"几内亚比索": "GW",
"尼加拉瓜": "NI",
"特克斯和凯科斯群岛": "TC",
"珊瑚海群岛领地": "",
"泽西": "JE",
"奥地利": "AT",
"蒙特塞拉特": "MS",
"纽埃": "NU",
"圣文森特和格林纳丁斯": "VC",
"伯利兹": "BZ",
"斯洛伐克": "SK",
"哈萨克斯坦": "KZ",
"直布罗陀": "GI",
"柬埔寨": "KH",
"立陶宛": "LT",
"中非共和国": "CF",
"瑞典": "SE",
"爱尔兰": "IE",
"赤道几内亚": "GQ",
"亚美尼亚": "AM",
"捷克": "CZ",
"冈比亚": "GM",
"格陵兰": "GL",
"科索沃": "",
"印度": "IN",
"多哥": "TG",
"挪威": "NO",
"土耳其": "TR",
"拉脱维亚": "LV",
"佛得角": "CV",
"乌兹别克斯坦": "UZ",
"肯尼亚": "KE",
"博茨瓦纳": "BW",
"加蓬": "GA",
"塔吉克斯坦": "TJ",
"尼日尔": "NE",
"布基纳法索": "BF",
"安圭拉": "AI",
"老挝": "LA",
"阿尔巴尼亚": "AL",
"厄瓜多尔": "EC",
"葡萄牙": "PT",
"乍得": "TD",
"南乔治亚和南桑威奇群岛": "GS",
"几内亚": "GN",
"冰岛": "IS",
"托克劳": "TK",
"摩纳哥": "MC",
"埃及": "EG",
"马绍尔群岛": "MH",
"巴拿马": "PA",
"巴林": "BH",
"苏里南": "SR",
"帕劳": "PW",
"尼日利亚": "NG",
"加纳": "GH",
"牙买加": "JM",
"巴哈马": "BS",
"波兰": "PL",
"土库曼": "TM",
"古巴": "CU",
"吉布提": "DJ",
"马恩岛": "IM",
"巴布亚新几内亚": "PG",
"文莱": "BN",
"摩尔多瓦": "MD",
"开曼群岛": "KY",
"安哥拉": "AO",
"乌克兰": "UA",
"喀麦隆": "CM",
"萨尔瓦多": "SV",
"萨摩亚": "WS",
"黑山": "ME",
"孟加拉国": "BD",
"韩国": "KR",
"苏丹": "SD",
"厄立特里亚": "ER",
"库克群岛": "CK",
"马里": "ML",
"伊朗": "IR",
"伊拉克": "IQ",
"日本": "JP",
"突尼斯": "TN",
"津巴布韦": "ZW",
"菲律宾": "PH",
"约旦": "JO",
"埃塞俄比亚": "ET",
"德国": "DE",
"巴西": "BR",
"卢旺达": "RW",
"洪都拉斯": "HN",
"梵蒂冈": "VA",
"基里巴斯": "KI",
"阿拉伯联合酋长国": "AE",
"墨西哥": "MX",
"塞拉利昂": "SL",
"所罗门群岛": "SB",
"斯里兰卡": "LK",
"俄罗斯": "RU",
"法国": "FR",
"危地马拉": "GT",
"越南": "VN",
"坦桑尼亚": "TZ",
"比利时": "BE",
"丹麦": "DK",
"索马里": "SO",
"美国": "US",
"马尔代夫": "MV",
"列支敦士登": "LI",
"科摩罗": "KM",
"百慕达群岛": "BM",
"不丹": "BT",
"朝鲜": "KP",
"莫桑比克": "MZ",
"印度尼西亚, 印尼": "ID",
"也门": "YE",
"刚果-布拉柴维尔": "CG",
"乌拉圭": "UY",
"圣赫勒拿-阿森松和特里斯坦-达库尼亚": "SH",
"尼泊尔": "NP",
"多米尼克": "DM",
"马耳他": "MT",
"阿尔及利亚": "DZ",
"卡塔尔": "QA",
"赞比亚": "ZM",
"缅甸": "MM",
"卢森堡": "LU",
"斐济": "FJ",
"西班牙": "ES",
"乌干达": "UG",
"中国": "CN",
"中国香港": "HK",
"中国台湾": "TW",
"china": "CN"
}

File diff suppressed because it is too large Load Diff