feat(ecommerce): release Ari Shopping Frontend v2
Build and Push Frontend / build (push) Successful in 1m57s
Build and Push Frontend / build (push) Successful in 1m57s
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
import argparse,csv,hashlib,io,json,re,sys,urllib.request
|
||||
from datetime import datetime,timezone
|
||||
from pathlib import Path
|
||||
try:
|
||||
from PIL import Image,ImageOps
|
||||
except ImportError:
|
||||
Image=ImageOps=None
|
||||
ROOT=Path(__file__).resolve().parents[1];OUT=ROOT/'data/products.json';IMG=ROOT/'assets/img/products'
|
||||
def b(v,d=False): return str(v or '').strip().lower() in {'1','true','yes','si','sí'} if str(v or '').strip() else d
|
||||
def n(v,d=0):
|
||||
try:return int(float(str(v or '').strip()))
|
||||
except:return d
|
||||
def slug(v):return re.sub(r'[^a-zA-Z0-9_-]+','-',v.strip()).strip('-').lower() or hashlib.sha256(v.encode()).hexdigest()[:12]
|
||||
def download(url):
|
||||
req=urllib.request.Request(url,headers={'User-Agent':'AriShoppingCatalogSync/2.0'});data=urllib.request.urlopen(req,timeout=25).read(12*1024*1024+1)
|
||||
if len(data)>12*1024*1024:raise ValueError('Imagen demasiado grande')
|
||||
return data
|
||||
def image(data,dst):
|
||||
if Image is None:raise RuntimeError('Instala Pillow')
|
||||
im=ImageOps.exif_transpose(Image.open(io.BytesIO(data))).convert('RGB');canvas=Image.new('RGB',(1200,1200),'white');im.thumbnail((1080,1080),Image.Resampling.LANCZOS);canvas.paste(im,((1200-im.width)//2,(1200-im.height)//2));canvas.save(dst,'WEBP',quality=86,method=6)
|
||||
def main():
|
||||
ap=argparse.ArgumentParser();ap.add_argument('--source',type=Path,default=ROOT/'catalog-source.csv');ap.add_argument('--download-images',action='store_true');a=ap.parse_args();items=[]
|
||||
with a.source.open(encoding='utf-8-sig') as f:
|
||||
for row in csv.DictReader(f):
|
||||
pid=slug(row.get('id') or row['name']);imgs=[];urls=[u.strip() for u in row.get('image_urls','').split('|') if u.strip()]
|
||||
if a.download_images:
|
||||
for i,u in enumerate(urls,1):
|
||||
try:dst=IMG/f'{pid}-{i}.webp';image(download(u),dst);imgs.append(str(dst.relative_to(ROOT)).replace('\\','/'))
|
||||
except Exception as e:print(f'AVISO {pid}: {e}',file=sys.stderr)
|
||||
if not imgs:
|
||||
local=IMG/f'{pid}.svg';imgs=[str(local.relative_to(ROOT)).replace('\\','/')] if local.exists() else urls
|
||||
items.append({'id':pid,'name':row['name'].strip(),'category':row.get('category','Otros').strip(),'price':n(row.get('price')),'compareAtPrice':n(row.get('compare_at_price')),'featured':b(row.get('featured')),'new':b(row.get('new')),'description':row.get('description','').strip(),'tags':[t.strip() for t in row.get('tags','').split('|') if t.strip()],'images':imgs,'stock':n(row.get('stock')),'available':b(row.get('available'),True),'source':{'type':'authorized-feed','name':row.get('source_name','Fuente autorizada'),'url':row.get('source_url','')}})
|
||||
OUT.write_text(json.dumps({'version':'2.0.0','updatedAt':datetime.now(timezone.utc).isoformat(),'currency':'COP','products':items},ensure_ascii=False,indent=2)+'\n');print(f'OK: {len(items)} productos')
|
||||
if __name__=='__main__':raise SystemExit(main())
|
||||
@@ -0,0 +1 @@
|
||||
Pillow==11.3.0
|
||||
Reference in New Issue
Block a user