astra/iphone-encoder-counter

A CR2450-powered MSP430 FRAM counter combines an always-on dual-channel TMR rotation sensor, pushbutton input, and ST25DV NFC tag with an integrated tuned printed antenna and I²C/GPIO interface.

Version
1.0.3
License
unset
Stars
0

scripts/check_live_stock.py

from pathlib import Path
import urllib.request,json,re,concurrent.futures,datetime,csv
r=Path(__file__).resolve().parents[1];bom=list(csv.DictReader(open(r/'fabrication/bom.csv')));ids=sorted({x['JLCPCB Part #'] for x in bom}|{'C17292544'})
def fetch(code):
 url='https://jlcpcb.com/partdetail/'+code
 try:
  raw=urllib.request.urlopen(url,timeout=30).read().decode()
  chunks=[]
  for chunk in re.findall(r'self\.__next_f\.push\((\[.*?\])\)</script>',raw):
   try:
    item=json.loads(chunk)
    if item[0]==1:chunks.append(item[1])
   except (ValueError,IndexError):pass
  s=''.join(chunks)
  # Product purchase record contains the exact code and live available stock.
  matches=re.findall(r'\{[^{}]*"componentCode":"'+code+r'"[^{}]*"overseasStockCount":\d+[^{}]*\}',s)
  assert matches,'No exact product inventory record found'
  obj=json.loads(matches[0]);fields=['componentCode','componentModelEn','componentSpecificationEn','overseasStockCount','canPresaleNumber','initialPrice','preMinPurchaseNum','encapsulationNumber','isBuyComponent','allowPostFlag','assemblyComponentFlag']
  result={k:obj[k] for k in fields if k in obj};result['url']=url;return code,result
 except Exception as e:return code,{'url':url,'error':str(e)}
results={}
for code in ids:
 results[code]=fetch(code)[1]
report={'checked_at_utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'source':'JLCPCB direct product purchase records; overseasStockCount','batch_assumption':5,'stock_reserved':False,'parts':results}
(r/'validation/live-jlc-stock.json').write_text(json.dumps(report,indent=2)+'\n')
for k,v in results.items():print(k,v.get('componentModelEn'),v.get('overseasStockCount'),v.get('error',''))