← back to Eur Recrawl
parse_pricelist.py
63 lines
#!/usr/bin/env python3
"""
Parse the Osborne & Little INC April-2026 US trade price list (all brands) into
structured, colorway-aware trade prices. This is the authoritative cost source
for the whole EUR- universe (O&L, Nina Campbell, Designers Guild, Christian
Lacroix, + the rest of the list). retail = trade / 0.65 / 0.85 (x1.810).
Input : /tmp/oal_pl.txt (pdftotext -layout of pdfs/myzt3fdy.1tk.pdf)
Output: prices.csv (code, pattern, trade_price, collection, colorways, retail_x181)
"""
import re, csv, os
HERE = os.path.dirname(os.path.abspath(__file__))
SRC = "/tmp/oal_pl.txt"
MARKUP = 1 / 0.65 / 0.85 # 1.8100...
# CODE PATTERN... PRICE COLLECTION COLORWAYS ...width/origin codes
LINE = re.compile(
r'^\s*([A-Z]{1,5}\d{3,}(?:-\d+)?)\s+' # 1 mfr code (W7907, PDG1107-01, PCL004, NCW4107...)
r'(.+?)\s{2,}' # 2 pattern name (>=2 spaces before price col)
r'(\d{1,4}\.\d{2})\s+' # 3 trade price
r'([A-Za-z][\w&\' .-]*?)\s{2,}' # 4 collection
r'([\d]{1,3}(?:\s*,\s*[\d]{1,3})*)' # 5 colorways (e.g. 01,03)
)
def main():
rows, seen = [], set()
for raw in open(SRC, encoding="utf-8", errors="replace"):
m = LINE.match(raw)
if not m:
continue
code, pattern, price, coll, cws = m.groups()
price = float(price)
if price <= 0 or price > 100000:
continue
colorways = [c.strip() for c in cws.split(",") if c.strip()]
for cw in colorways:
key = (code, cw)
if key in seen:
continue
seen.add(key)
rows.append({
"code": code,
"colorway": cw,
"sku_code": f"{code}-{cw}", # W7907-03 form (matches live mfr code)
"pattern": pattern.strip(),
"collection": coll.strip(),
"trade_price": f"{price:.2f}",
"retail_x181": f"{price * MARKUP:.2f}",
})
cols = ["code", "colorway", "sku_code", "pattern", "collection", "trade_price", "retail_x181"]
with open(os.path.join(HERE, "prices.csv"), "w", newline="") as f:
w = csv.DictWriter(f, fieldnames=cols); w.writeheader(); w.writerows(rows)
# validation: the canary W7907-03 must be trade 326.00 -> retail 590.05
canary = [r for r in rows if r["sku_code"] == "W7907-03"]
print(f"parsed price rows (code x colorway): {len(rows)}")
print(f"distinct codes: {len(set(r['code'] for r in rows))}")
print("CANARY W7907-03:", canary[0] if canary else "NOT FOUND")
if __name__ == "__main__":
main()