Initial commit

This commit is contained in:
2026-01-26 16:43:01 -05:00
commit 23cb27503e
39 changed files with 96557 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
/**
*
* 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');
})();