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

111 lines
3.6 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 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(/<br\s*\/?>/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'
);
})();