/* * This script extracts event data from a table on a webpage and generates an iCalendar (.ics) file for download. * It looks for a table with specific headers ('event', 'date', 'venue', 'address'), parses the event details, * and then creates an iCalendar file with the extracted event information. The file is then automatically * downloaded to the user's device. */ javascript: (() => { function extractEventData() { let tables = document.querySelectorAll('table'); if (tables.length > 1) { tables = [tables[0]]; } const data = []; tables.forEach(table => { const headers = []; const rows = table.querySelectorAll('tr'); const firstRow = rows[0]; firstRow.querySelectorAll('td').forEach(td => { headers.push(td.textContent.trim().toLowerCase()); }); if ( headers.includes('event') && headers.includes('date') && headers.includes('venue') && headers.includes('address') ) { Array.from(rows) .slice(1) .forEach(row => { const cells = row.querySelectorAll('td'); const rowData = {}; cells.forEach((cell, j) => { const header = headers[j]; let cellText = cell.innerHTML .replace(//gi, ', ') .trim(); cellText = cellText.replace(/<\/?[^>]+(>|$)/g, '').trim(); if (header === 'event') { rowData.event = cellText; } else if (header === 'date') { const month = cellText.split(' ')[0]; const year = cellText.split(',')[1].trim(); const startDay = cellText .split(' ')[1] .split(cellText.includes(' – ') ? ' – ' : '–')[0] .trim(); const endDay = cellText .split(cellText.includes(' – ') ? ' – ' : '–')[1] .split(',')[0] .trim(); rowData.startDate = `${month} ${startDay}, ${year}`; rowData.endDate = `${month} ${endDay}, ${year}`; } else if (header === 'venue') { rowData.venue = cellText; } else if (header === 'location') { rowData.address = cellText; } }); data.push(rowData); }); } }); console.log(data); return data; } const data = extractEventData(); function createICal(events) { let icalContent = 'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//FragginWagon//International-Championships\n'; events.forEach(event => { icalContent += 'BEGIN:VEVENT\n'; icalContent += `DTSTART:${new Date(event.startDate).toISOString().replace(/[-:]/g, '').split('.')[0]}Z\n`; icalContent += `DTEND:${new Date(event.endDate).toISOString().replace(/[-:]/g, '').split('.')[0]}Z\n`; icalContent += `SUMMARY:${event.event} \n`; icalContent += `LOCATION:${event.location}\n`; icalContent += 'END:VEVENT\n'; }); icalContent += 'END:VCALENDAR'; return icalContent; } function downloadICal(content, filename) { const blob = new Blob([content], { type: 'text/calendar' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } const newIcalContent = createICal(data); downloadICal( newIcalContent, 'play_pokemon_international_championships_events.ics' ); })();