feat: KöPi - nur spezifische Filialen anzeigen
This commit is contained in:
@@ -56,12 +56,33 @@ function extractNextData(html) {
|
|||||||
try { return JSON.parse(html.slice(start, end)); } catch { return null; }
|
try { return JSON.parse(html.slice(start, end)); } catch { return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Händler-Filter ────────────────────────────────────────────────────────────
|
// ── Gewünschte Filialen ──────────────────────────────────────────────────────
|
||||||
const TARGET_PUBLISHERS = ['rewe','edeka','netto','trinkgut','getränke','penny','aldi','lidl'];
|
const TARGET_STORES = [
|
||||||
|
{ name: 'edeka', street: 'düsseldorfer landstr', label: 'EDEKA E center Angerbogen' },
|
||||||
|
{ name: 'edeka', street: 'angerbogen', label: 'EDEKA E center Angerbogen' },
|
||||||
|
{ name: 'e center', street: 'düsseldorfer', label: 'EDEKA E center Angerbogen' },
|
||||||
|
{ name: 'rewe', street: 'mündelheimer', label: 'REWE Mündelheimer Str.' },
|
||||||
|
{ name: 'rewe', street: 'keniastr', label: 'REWE XXL Schwinning' },
|
||||||
|
{ name: 'netto', street: 'bonnefeld', label: 'Netto Im Bonnefeld' },
|
||||||
|
{ name: 'kaufland', street: 'auf der höhe', label: 'Kaufland Kaßlerfeld' },
|
||||||
|
{ name: 'penny', street: 'sittardsberger', label: 'Penny Sittardsberger Allee' },
|
||||||
|
{ name: 'trinkgut', street: 'keniastr', label: 'Trinkgut Keniastraße' },
|
||||||
|
];
|
||||||
|
|
||||||
|
function matchesTargetStore(publisherName, storeName, street) {
|
||||||
|
const p = (publisherName || '').toLowerCase();
|
||||||
|
const s = (storeName || '').toLowerCase();
|
||||||
|
const r = (street || '').toLowerCase();
|
||||||
|
for (const t of TARGET_STORES) {
|
||||||
|
if ((p.includes(t.name) || s.includes(t.name)) && r.includes(t.street)) return t.label;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function isTargetPublisher(name) {
|
function isTargetPublisher(name) {
|
||||||
if (!name) return false;
|
if (!name) return false;
|
||||||
const n = name.toLowerCase();
|
const n = name.toLowerCase();
|
||||||
return TARGET_PUBLISHERS.some(p => n.includes(p));
|
return ['rewe','edeka','e center','netto','kaufland','penny','trinkgut'].some(p => n.includes(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Angebote via Puppeteer (BrochureBox_Basic + OfferGrid) ──────────────────
|
// ── Angebote via Puppeteer (BrochureBox_Basic + OfferGrid) ──────────────────
|
||||||
@@ -171,10 +192,12 @@ async function scrapeProspekte() {
|
|||||||
const cached = cacheGet(cacheKey);
|
const cached = cacheGet(cacheKey);
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
|
|
||||||
|
// Koordinaten rund um deine Filialen (alle im Süden Duisburgs)
|
||||||
const locations = [
|
const locations = [
|
||||||
{ lat: 51.4332, lng: 6.7625, city: 'Duisburg', zip: '47051' },
|
{ lat: 51.3750, lng: 6.7680, city: 'Duisburg', zip: '47259' }, // Im Bonnefeld / Netto
|
||||||
{ lat: 51.5167, lng: 6.9833, city: 'Essen', zip: '45127' },
|
{ lat: 51.4020, lng: 6.7616, city: 'Duisburg', zip: '47055' }, // REWE Mündelheimer
|
||||||
{ lat: 51.2217, lng: 6.7762, city: 'Düsseldorf', zip: '40213' },
|
{ lat: 51.4406, lng: 6.7555, city: 'Duisburg', zip: '47059' }, // Kaufland / REWE Kenia / Trinkgut
|
||||||
|
{ lat: 51.3900, lng: 6.7900, city: 'Duisburg', zip: '47259' }, // Penny Sittardsberger
|
||||||
];
|
];
|
||||||
|
|
||||||
const allBrochures = new Map();
|
const allBrochures = new Map();
|
||||||
@@ -199,20 +222,24 @@ async function scrapeProspekte() {
|
|||||||
const publisher = c.publisher?.name || '';
|
const publisher = c.publisher?.name || '';
|
||||||
const store = c.closestStore;
|
const store = c.closestStore;
|
||||||
|
|
||||||
|
const storeStreet = store ? `${store.street || ''} ${store.streetNumber || ''}`.trim() : '';
|
||||||
|
const matchLabel = matchesTargetStore(publisher, store?.name, storeStreet);
|
||||||
|
|
||||||
allBrochures.set(id, {
|
allBrochures.set(id, {
|
||||||
id,
|
id,
|
||||||
publisher,
|
publisher,
|
||||||
title: c.title || '',
|
title: c.title || '',
|
||||||
store: store?.name || publisher,
|
store: store?.name || publisher,
|
||||||
|
storeLabel: matchLabel || store?.name || publisher,
|
||||||
city: store?.city || loc.city,
|
city: store?.city || loc.city,
|
||||||
street: store ? `${store.street || ''} ${store.streetNumber || ''}`.trim() : '',
|
street: storeStreet,
|
||||||
zip: store?.zip || loc.zip,
|
zip: store?.zip || loc.zip,
|
||||||
image: c.brochureImages?.find(i => i.size === '260x270')?.url || c.brochureImage?.url || null,
|
image: c.brochureImages?.find(i => i.size === '260x270')?.url || c.brochureImage?.url || null,
|
||||||
validFrom: c.validFrom || null,
|
validFrom: c.validFrom || null,
|
||||||
validTo: c.validUntil || null,
|
validTo: c.validUntil || null,
|
||||||
pageCount: c.pageCount || null,
|
pageCount: c.pageCount || null,
|
||||||
url: `https://www.kaufda.de/webapp/brochure/${id}`,
|
url: `https://www.kaufda.de/webapp/brochure/${id}`,
|
||||||
isTarget: isTargetPublisher(publisher),
|
isTarget: !!matchLabel,
|
||||||
badges: c.contentBadges?.map(b => b.name) || [],
|
badges: c.contentBadges?.map(b => b.name) || [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,11 +183,11 @@ function ProspektCard({ b }) {
|
|||||||
<div style={{ display:'inline-block', background:`${color}22`, border:`1px solid ${color}44`,
|
<div style={{ display:'inline-block', background:`${color}22`, border:`1px solid ${color}44`,
|
||||||
borderRadius:4, padding:'2px 8px', marginBottom:6,
|
borderRadius:4, padding:'2px 8px', marginBottom:6,
|
||||||
color, fontFamily:'monospace', fontSize:10, fontWeight:700 }}>
|
color, fontFamily:'monospace', fontSize:10, fontWeight:700 }}>
|
||||||
{b.publisher}
|
{b.storeLabel || b.publisher}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ color:'#fff', fontFamily:'monospace', fontSize:11, marginBottom:3, lineHeight:1.4 }}>{b.title}</div>
|
<div style={{ color:'#fff', fontFamily:'monospace', fontSize:11, marginBottom:3, lineHeight:1.4 }}>{b.title}</div>
|
||||||
<div style={{ color:'rgba(255,255,255,0.4)', fontFamily:'monospace', fontSize:10, marginBottom:2 }}>
|
<div style={{ color:'rgba(255,255,255,0.4)', fontFamily:'monospace', fontSize:10, marginBottom:2 }}>
|
||||||
📍 {b.store}{b.city && b.store !== b.city ? ` · ${b.city}` : ''}
|
📍 {b.street || b.store}{b.city ? ` · ${b.city}` : ''}
|
||||||
</div>
|
</div>
|
||||||
{b.street && <div style={{ color:'rgba(255,255,255,0.3)', fontFamily:'monospace', fontSize:9 }}>{b.street}</div>}
|
{b.street && <div style={{ color:'rgba(255,255,255,0.3)', fontFamily:'monospace', fontSize:9 }}>{b.street}</div>}
|
||||||
{(b.validFrom || b.validTo) && (
|
{(b.validFrom || b.validTo) && (
|
||||||
|
|||||||
Reference in New Issue
Block a user