diff --git a/public/index.html b/public/index.html index 25fd638..7e5f1bf 100644 --- a/public/index.html +++ b/public/index.html @@ -2624,7 +2624,7 @@ fontFamily: 'JetBrains Mono, monospace' }}>
| ]*>([\s\S]*?)<\/td>/gi); - if (!cells || cells.length < 4) continue; - - // Clean cell content - const cleanCell = (cell) => { - return cell - .replace(/<[^>]*>/g, '') // Remove HTML tags - .replace(/ /g, ' ') - .replace(/&/g, '&') - .replace(/</g, '<') - .replace(/>/g, '>') - .trim(); - }; - - const callsign = cleanCell(cells[0] || ''); - const entity = cleanCell(cells[1] || ''); - const dates = cleanCell(cells[2] || ''); - const qsl = cleanCell(cells[3] || ''); - - // Skip if no valid callsign - if (!callsign || callsign.length < 2 || callsign.includes('CALLSIGN')) continue; - - // Parse dates (format varies: "Jan 15-Feb 28" or "2024 Jan 15-Feb 28") - let startDate = null; - let endDate = null; - let isActive = false; - let isUpcoming = false; + const startMonth = monthNames.indexOf(dateParsed[1].toLowerCase().substring(0, 3)); + const startDay = parseInt(dateParsed[2]); + const startYear = dateParsed[3] ? parseInt(dateParsed[3]) : currentYear; + + const endMonthStr = dateParsed[4] || dateParsed[1]; + const endMonth = monthNames.indexOf(endMonthStr.toLowerCase().substring(0, 3)); + const endDay = parseInt(dateParsed[5]) || startDay + 14; + const endYear = dateParsed[6] ? parseInt(dateParsed[6]) : startYear; + + if (startMonth >= 0) { + startDate = new Date(startYear, startMonth, startDay); + endDate = new Date(endYear, endMonth >= 0 ? endMonth : startMonth, endDay); - const dateMatch = dates.match(/(\w+)\s+(\d+)[\s\-]+(\w+)?\s*(\d+)?/); - if (dateMatch) { - const year = new Date().getFullYear(); - const monthNames = ['jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct', 'nov', 'dec']; - - const startMonth = monthNames.indexOf(dateMatch[1].toLowerCase().substring(0, 3)); - const startDay = parseInt(dateMatch[2]); - const endMonth = dateMatch[3] ? monthNames.indexOf(dateMatch[3].toLowerCase().substring(0, 3)) : startMonth; - const endDay = parseInt(dateMatch[4]) || startDay + 7; - - if (startMonth >= 0) { - startDate = new Date(year, startMonth, startDay); - endDate = new Date(year, endMonth >= 0 ? endMonth : startMonth, endDay); - - // Handle year rollover - if (endDate < startDate) { - endDate.setFullYear(year + 1); - } - - const today = new Date(); - today.setHours(0, 0, 0, 0); - - isActive = startDate <= today && endDate >= today; - isUpcoming = startDate > today; - } + // Handle year rollover for date ranges like "Dec 15 - Jan 5" + if (endDate < startDate && !dateParsed[6]) { + endDate.setFullYear(endYear + 1); } - dxpeditions.push({ - callsign, - entity, - dates, - qsl, - startDate: startDate?.toISOString(), - endDate: endDate?.toISOString(), - isActive, - isUpcoming - }); + const today = new Date(); + today.setHours(0, 0, 0, 0); + + isActive = startDate <= today && endDate >= today; + isUpcoming = startDate > today; } } + + // Extract bands and modes from info + const bandsMatch = info.match(/(\d+(?:-\d+)?m)/g); + const bands = bandsMatch ? bandsMatch.join(' ') : ''; + + const modesMatch = info.match(/\b(CW|SSB|FT8|FT4|RTTY|PSK|FM|AM|DIGI)\b/gi); + const modes = modesMatch ? [...new Set(modesMatch.map(m => m.toUpperCase()))].join(' ') : ''; + + dxpeditions.push({ + callsign, + entity, + dates: dateStr, + qsl, + info: info.substring(0, 100), // Truncate info + bands, + modes, + startDate: startDate?.toISOString(), + endDate: endDate?.toISOString(), + isActive, + isUpcoming + }); } - // Sort: active first, then upcoming by start date, then past + // Sort: active first, then upcoming by start date dxpeditions.sort((a, b) => { if (a.isActive && !b.isActive) return -1; if (!a.isActive && b.isActive) return 1; @@ -259,7 +267,7 @@ app.get('/api/dxpeditions', async (req, res) => { }); const result = { - dxpeditions: dxpeditions.slice(0, 50), // Limit to 50 entries + dxpeditions: dxpeditions.slice(0, 50), active: dxpeditions.filter(d => d.isActive).length, upcoming: dxpeditions.filter(d => d.isUpcoming).length, source: 'NG3K ADXO', |
|---|