#!/usr/bin/env python3 """Mirror WowPlatter's AusPost flat-rate + zone tables → RecordGod Postgres. python3 shipping_sync.py | ssh -C root@100.94.195.115 \ 'docker exec -i recordgod-db psql -U recordgod -d recordgod -q -v ON_ERROR_STOP=1' post_flat_rate = service × size/weight bracket → price (Parcel Post / Express). post_zone = postcode range. Prices use AusPost's 2026-07-01 "own packaging, postage only" rates (the bracket the shop ships records in) — loaded straight in since RecordGod isn't live before the change. Update RATES below from the next Post Charges Guide (John's PDF→Gemini path) and re-run. """ import re import pathlib import sys import pymysql WP_CONFIG = "/opt/homebrew/var/www/monsterrobot.localsite/wp-config.php" SOCK = "/opt/homebrew/var/mysql/mysql.sock" SCHEMA = """ DROP TABLE IF EXISTS post_flat_rate, post_zone CASCADE; CREATE TABLE post_flat_rate (service_key text, packaging_type text, size_label text, weight_min_g int, weight_max_g int, price numeric(10,2)); CREATE TABLE post_zone (postcode_start int, postcode_end int, zone_code text); CREATE INDEX ON post_flat_rate (service_key, weight_min_g, weight_max_g); CREATE INDEX ON post_zone (postcode_start, postcode_end); """ # Current AusPost rates — own packaging, postage only, by weight (effective 2026-07-01 Post Charges Guide). RATES = { # service_key -> {size_label: price} "PARCEL_POST": {"XS": "10.20", "S": "11.70", "M": "16.00", "L": "20.25", "XL": "24.45"}, "EXPRESS_POST": {"XS": "13.20", "S": "15.20", "M": "20.00", "L": "24.75", "XL": "32.95"}, } FR = ["service_key", "packaging_type", "size_label", "weight_min_g", "weight_max_g", "price"] ZN = ["postcode_start", "postcode_end", "zone_code"] def creds(): t = pathlib.Path(WP_CONFIG).read_text() g = lambda k: re.search(rf"'{k}',\s*'([^']*)'", t).group(1) return g("DB_NAME"), g("DB_USER"), g("DB_PASSWORD") def cp(v): if v is None or v == "": return r"\N" return str(v).replace("\\", "\\\\").replace("\t", "\\t").replace("\n", "\\n").replace("\r", "\\r") def block(out, table, cols, rows): out.write(f"COPY {table} ({','.join(cols)}) FROM stdin;\n") for r in rows: out.write("\t".join(cp(r[c]) for c in cols) + "\n") out.write("\\.\n\n") print(f" {table:16} {len(rows):>4}", file=sys.stderr) def main(): name, user, pw = creds() my = pymysql.connect(unix_socket=SOCK, user=user, password=pw, database=name, cursorclass=pymysql.cursors.DictCursor) c = my.cursor() P = "wp_rmp_disc_" out = sys.stdout out.write(SCHEMA) c.execute(f"SELECT {','.join(FR)} FROM {P}post_flat_rates") # structure (brackets) from WowPlatter rows = c.fetchall() for r in rows: # …prices overridden with the current AusPost ones new = RATES.get(r["service_key"], {}).get(r["size_label"]) if new is not None: r["price"] = new block(out, "post_flat_rate", FR, rows) c.execute(f"SELECT {','.join(ZN)} FROM {P}post_zones") block(out, "post_zone", ZN, c.fetchall()) if __name__ == "__main__": main()