Files
ucvl-home-vision/geography.py
T

67 lines
3.4 KiB
Python

"""Versioned offline location paths. Administrative geography is not an ACL boundary."""
import json
from pathlib import Path
DATA = json.loads((Path(__file__).parent/'web/data/geography.json').read_text(encoding='utf8'))
def normalize(value, clean):
if not isinstance(value, dict):
raise ValueError('地域信息格式不正确')
mode = value.get('mode')
if mode not in ('china', 'world', 'custom'):
raise ValueError('请选择中国、世界或自定义地域')
result = dict(version=1, mode=mode, dataset=DATA['version'], body='地球', countryCode='', country='',
provinceCode='', cityCode='', districtCode='', province='', city='', district='', path='')
if mode == 'china':
result.update(countryCode='CN', country='中国')
children = DATA['china']
manual = False
for field in ('province', 'city', 'district'):
code = value.get(field+'Code', '')
if not isinstance(code, str): raise ValueError('地域编码格式不正确')
if manual:
result[field] = clean(value.get(field, ''), 100)
continue
if not code:
if any(value.get(k+'Code') for k in ('city','district') if ('province','city','district').index(k)>('province','city','district').index(field)):
raise ValueError('请先选择上级地区')
continue
item = next((x for x in children if x['code']==code), None)
if not item: raise ValueError('地区不属于所选上级,请重新选择')
result[field+'Code'], result[field] = item['code'], item['name']
manual = item.get('manual', False)
children = item.get('children', [])
elif mode == 'world':
code = value.get('countryCode', '')
if code not in DATA['countries']: raise ValueError('请选择国家或地区')
if code == 'CN': raise ValueError('中国地区请使用中国分级选择')
result.update(countryCode=code, country=DATA['countries'][code])
for field in ('province','city','district'):
result[field] = clean(value.get(field, ''), 100)
else:
result['body'] = clean(value.get('body', '地球'), 100, True)
for field in ('country','province','city','district'):
result[field] = clean(value.get(field, ''), 100)
result['path'] = clean(value.get('path', ''), 1000)
return result
def apply(item, data, old, clean, problem, prefix=''):
key = prefix+'Geography' if prefix else 'geography'
if key not in data:
if key in (old or {}):
previous = old[key]
names = {f:prefix+f.title() if prefix else f for f in ('country','province','city','district')}
if any(k in data and data[k] != old.get(k,'') for k in names.values()):
# An older client can edit text but cannot keep now-inconsistent codes.
item[key] = normalize(dict(mode='custom',body=previous.get('body','地球'),
path=previous.get('path',''),**{f:data.get(k,old.get(k,'')) for f,k in names.items()}),clean)
else: item[key] = previous
return
try: result = normalize(data[key], clean)
except ValueError as error: raise problem(str(error))
item[key] = result
for field in ('country','province','city','district'):
item[prefix+field.title() if prefix else field] = result[field]