Initial commit
This commit is contained in:
110
code/bookmarklets/play-international-championships-dates.js
Normal file
110
code/bookmarklets/play-international-championships-dates.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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'
|
||||
);
|
||||
})();
|
||||
Reference in New Issue
Block a user