← back to Japan Enrich
annotate_distributor.py
63 lines
#!/usr/bin/env python3
"""Persist a `distributor` (buy-from channel) field into the staging JSONL rows.
Mirrors the viewer's distInfo() (viewer-local/server.js) so the data layer carries
the same value the UI derives on the fly — Sangetsu is the mill but only orderable
through the Goodrich distributor; Lilycolor & Greenland sell direct. Onboarding into
dw_unified (us_distributor / supplier_name) can then read the field straight off the
row instead of re-deriving it. Idempotent + atomic (temp file + rename). Git is the
undo path (staging/*.jsonl are tracked)."""
import json, os, sys, tempfile
from urllib.parse import urlparse
DIR = os.path.join(os.path.dirname(__file__), 'staging')
DIST_BY_HOST = [
('sangetsu-goodrich.co.th', 'Goodrich (Thailand)'),
('sangetsu-goodrich.vn', 'Goodrich (Vietnam)'),
('goodrichglobal.com', 'Goodrich (Singapore)'),
]
# (file, source) — source hard-set per file to match the viewer's per-file scoping
FILES = [
('sangetsu-staging.jsonl', 'sangetsu'),
('lilycolor-unified-staging.jsonl', 'lilycolor'),
('greenland-staging.jsonl', 'greenland'),
]
def dist(source, url):
host = ''
try:
host = urlparse(url or '').netloc.replace('www.', '')
except Exception:
host = ''
for h, label in DIST_BY_HOST:
if host.endswith(h):
return label, False
if source == 'sangetsu': return 'Goodrich', False # sangetsu w/o recognized host still via Goodrich
if source == 'lilycolor': return 'Lilycolor (direct)', True
if source == 'greenland': return 'Greenland (direct)', True
return None, False
def run():
for fname, source in FILES:
path = os.path.join(DIR, fname)
if not os.path.exists(path):
print(f'skip (missing): {fname}'); continue
n = 0; counts = {}
fd, tmp = tempfile.mkstemp(dir=DIR, suffix='.tmp')
with os.fdopen(fd, 'w') as out, open(path) as f:
for line in f:
line = line.strip()
if not line:
continue
r = json.loads(line)
label, direct = dist(source, r.get('source_url'))
r['distributor'] = label
r['distributor_direct'] = direct
out.write(json.dumps(r, ensure_ascii=False) + '\n')
n += 1; counts[label] = counts.get(label, 0) + 1
os.replace(tmp, path)
print(f'{fname}: {n} rows -> {counts}')
if __name__ == '__main__':
run()