Add LIFECYCLE filtering, street exceptions UI, address matching improvements, map viewer fixes
This commit is contained in:
@@ -8,6 +8,7 @@ import os
|
||||
import threading
|
||||
import json
|
||||
from datetime import datetime
|
||||
import yaml
|
||||
|
||||
app = Flask(__name__, static_folder='static', template_folder='templates')
|
||||
|
||||
@@ -295,5 +296,64 @@ def serve_data(filename):
|
||||
"""Serve GeoJSON files"""
|
||||
return send_from_directory('/data', filename)
|
||||
|
||||
EXCEPTIONS_FILE = '/data/exceptions.yml'
|
||||
|
||||
DEFAULT_EXCEPTIONS = [
|
||||
{'from': "D Angelo Lane", 'to': "D'Angelo Lane"},
|
||||
{'from': "Lajolla Circle", 'to': "La Jolla Circle"},
|
||||
{'from': "Gardena Court", 'to': "Gardenia Court"},
|
||||
{'from': "Glenmont Court", 'to': "Glenmount Court"},
|
||||
{'from': "Pawleys Island Path", 'to': "Pawley's Island Path"},
|
||||
{'from': "Oday Street", 'to': "O'Day Street"},
|
||||
{'from': "Obrien Place", 'to': "O'Brien Place"},
|
||||
{'from': "Ohara Court", 'to': "O'Hara Court"},
|
||||
]
|
||||
|
||||
def _ensure_exceptions_file():
|
||||
if not os.path.exists(EXCEPTIONS_FILE):
|
||||
os.makedirs(os.path.dirname(EXCEPTIONS_FILE), exist_ok=True)
|
||||
with open(EXCEPTIONS_FILE, 'w') as f:
|
||||
yaml.dump({'corrections': DEFAULT_EXCEPTIONS}, f,
|
||||
default_flow_style=False, allow_unicode=True)
|
||||
|
||||
_ensure_exceptions_file()
|
||||
|
||||
|
||||
@app.route('/exceptions')
|
||||
def exceptions_page():
|
||||
return render_template('exceptions.html')
|
||||
|
||||
|
||||
@app.route('/api/exceptions', methods=['GET'])
|
||||
def get_exceptions():
|
||||
try:
|
||||
with open(EXCEPTIONS_FILE) as f:
|
||||
data = yaml.safe_load(f) or {}
|
||||
return jsonify({'corrections': data.get('corrections', [])})
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/api/exceptions', methods=['POST'])
|
||||
def save_exceptions():
|
||||
data = request.json
|
||||
corrections = data.get('corrections', [])
|
||||
|
||||
# Validate
|
||||
for item in corrections:
|
||||
if not isinstance(item.get('from'), str) or not item['from'].strip():
|
||||
return jsonify({'error': 'Each correction must have a non-empty "from" field'}), 400
|
||||
if not isinstance(item.get('to'), str) or not item['to'].strip():
|
||||
return jsonify({'error': 'Each correction must have a non-empty "to" field'}), 400
|
||||
|
||||
# Atomic write
|
||||
tmp = EXCEPTIONS_FILE + '.tmp'
|
||||
with open(tmp, 'w') as f:
|
||||
yaml.dump({'corrections': corrections}, f,
|
||||
default_flow_style=False, allow_unicode=True)
|
||||
os.replace(tmp, EXCEPTIONS_FILE)
|
||||
return jsonify({'success': True})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5000, debug=True)
|
||||
|
||||
Reference in New Issue
Block a user