Add hierarchical geography and cloud-hosted profile images
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
"""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]
|
||||
Reference in New Issue
Block a user