← 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()