Created
August 23, 2023 14:59
-
-
Save Dan-Q/04dba4476a8157143694c7bc8d75d4d2 to your computer and use it in GitHub Desktop.
Userscript to download all of the logs on a Geocaching.com cache page as JSON
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Download JSON cachelogs | |
// @namespace dllogs.geocaching.danq.me | |
// @match https://www.geocaching.com/geocache/* | |
// @grant GM_registerMenuCommand | |
// @version 1.0 | |
// @author Dan Q | |
// @description Download all logs against a particular Geocaching.com geocache as a JSON file | |
// ==/UserScript== | |
function downloadLogsWrapper(){ | |
let logScroller; | |
let cycleDuration = 100; | |
let cyclesWaitedForLogsToLoad = 0; | |
let maxCyclesWaitedForLogsToLoad = 30; | |
let logScrollerDialog = document.createElement('dialog'); | |
logScrollerDialog.style.position = 'fixed'; | |
logScrollerDialog.style.left = 'calc(50% - 14vw)'; | |
logScrollerDialog.style.top = 'calc(50% - 5vh)'; | |
logScrollerDialog.style.height = '10vh'; | |
logScrollerDialog.style.width = '28vw'; | |
logScrollerDialog.style.display = 'grid'; | |
logScrollerDialog.style.placeContent = 'center'; | |
logScrollerDialog.style.textAlign = 'center'; | |
document.body.appendChild(logScrollerDialog); | |
logScrollerDialog.innerHTML = 'Starting up...'; | |
logScrollerDialog.showModal(); | |
let footerRoot = document.getElementById('gc-footer-root'); | |
function scrollToGetMoreLogs(){ | |
logScrollerDialog.innerHTML = 'Scrolling to get more logs<br>'; | |
footerRoot.scrollIntoView(); | |
cyclesWaitedForLogsToLoad = 0; | |
clearInterval(logScroller); | |
logScroller = setInterval(maybeScrollToGetMoreLogs, cycleDuration); | |
} | |
function maybeScrollToGetMoreLogs(){ | |
cyclesWaitedForLogsToLoad++; | |
logScrollerDialog.innerHTML += '.'; | |
let needToScroll = footerRoot.getBoundingClientRect().top > window.innerHeight; | |
if(!needToScroll) { | |
if(cyclesWaitedForLogsToLoad >= maxCyclesWaitedForLogsToLoad) { | |
clearInterval(logScroller); | |
downloadLogs(); | |
} | |
return; | |
} | |
scrollToGetMoreLogs(); | |
} | |
// kickstart process: | |
setTimeout(scrollToGetMoreLogs, 100); | |
function downloadLogs(){ | |
logScrollerDialog.innerHTML = 'Downloading logs as JSON'; | |
let gcCode = document.getElementById('ctl00_ContentBody_CoordInfoLinkControl1_uxCoordInfoCode').innerText.trim(); | |
let logData = Array.from(document.querySelectorAll('#cache_logs_table tbody tr')).map(tr=>{ | |
const author = tr.querySelector('.h5'); | |
return { | |
cache: { | |
name: document.getElementById('ctl00_ContentBody_CacheName').innerText.trim(), | |
code: gcCode, | |
type: document.querySelector('.cacheImage').attributes.title.value.trim(), | |
}, | |
author: { | |
name: author.innerText.trim(), | |
guid: author.href.replace(/^.*\/profile\/\?guid=/, ''), | |
premium: !!author.nextElementSibling.innerText.match(/Premium/), | |
}, | |
log: { | |
type: tr.querySelector('.h4').innerText.trim(), | |
text: tr.querySelector('.LogText').innerText.trim(), | |
date: tr.querySelector('.LogDate').innerText.trim(), | |
luid: tr.querySelector('a[title="View Log"]').href.replace(/^.*\/seek\/log\.aspx\?LUID=/, ''), | |
}, | |
}; | |
}); | |
let logDataEncoded = `data:text/json;charset=utf-8,${encodeURIComponent(JSON.stringify(logData))}`; | |
let logDataLink = document.createElement('a'); | |
logDataLink.setAttribute("href", logDataEncoded); | |
logDataLink.setAttribute("download", `${gcCode}.logs.json`); | |
logDataLink.click(); | |
setTimeout(()=>logScrollerDialog.remove(), 1000); | |
} | |
} | |
GM_registerMenuCommand('Download logs', downloadLogsWrapper); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment