Files
memory-infrastructure-palace/code/bookmarklets/play-regional-special-dates.js
2026-01-26 16:43:01 -05:00

118 lines
3.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
*
* This bookmarklet extracts event data from the first four tables on a webpage,
* specifically looking for tables that contain 'date', 'venue', and 'location' headers.
* It processes the event data to identify special events and formats the dates.
* The extracted data is then used to create an iCalendar (.ics) file, which is
* automatically downloaded to the user's device.
*
* Functions:
* - extractEventData: Extracts event data from the first four tables on the webpage.
* - createICal: Creates an iCalendar (.ics) content string from the extracted event data.
* - downloadICal: Initiates the download of the iCalendar (.ics) file with the given content and filename.
*/
javascript: (() => {
function extractEventData() {
let tables = document.querySelectorAll('table');
if (tables.length > 4) {
tables = Array.from(tables).slice(0, 4);
}
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('date') &&
headers.includes('venue') &&
headers.includes('location')
) {
Array.from(rows)
.slice(1)
.forEach(row => {
const cells = row.querySelectorAll('td');
const rowData = {};
if (
Array.from(cells).some(cell =>
cell.querySelector('span[style*="color: #2dc26b"]')
)
) {
rowData.specialEvent = true;
}
cells.forEach((cell, j) => {
const header = headers[j];
let cellText = cell.innerHTML.replace(/<br\s*\/?>/gi, ', ').trim();
cellText = cellText.replace(/<\/?[^>]+(>|$)/g, '').trim();
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.location = cellText;
}
});
data.push(rowData);
});
}
});
return data;
}
const data = extractEventData(tables);
function createICal(events) {
let icalContent =
'BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:-//FragginWagon//P!P //Regional-Special-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.specialEvent ? 'Special Event' : 'Regional'} - ${event.venue} \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(extractEventData());
downloadICal(newIcalContent, 'play_pokemon_regional_special_events.ics');
})();