Skip to content

Instantly share code, notes, and snippets.

@jhthorsen
Last active June 10, 2020 23:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhthorsen/34c878e08879c8f411d2e544bac60ac3 to your computer and use it in GitHub Desktop.
Save jhthorsen/34c878e08879c8f411d2e544bac60ac3 to your computer and use it in GitHub Desktop.
Google Photos delete script - Use at own risk!
async function gPhotosPurge(nSelectedLast = -1) {
gPhotosPurgeSelectPhotos();
const nSelected = await gPhotosPurgeWaitFor(gPhotosPurgeGetNumberOfSelected, 'nSelected>0', 2000);
return nSelected > 200 || nSelected == nSelectedLast ? gPhotosPurgeExecute(nSelected) : nSelected ? gPhotosPurge(nSelected) : console.info('[gPhotosPurge] nSelected=0');
}
async function gPhotosPurgeExecute(nSelected) {
console.info('[gPhotosPurge] Deleting ' + nSelected + ' photos...');
deleteBtn = await gPhotosPurgeWaitFor(() => document.querySelector('button[title="Delete"]'), 'deleteBtn');
deleteBtn.focus();
deleteBtn.click();
confirmBtn = await gPhotosPurgeWaitFor(() => {
const els = document.querySelectorAll('button');
for (let i = 0; i < els.length; i++) {
if (els[i].textContent.match(/Move to trash/)) return els[i];
}
return null;
}, 'confirmBtn');
if (!confirmBtn) return console.info('[gPhotosPurge] No confirm button.');
confirmBtn.click();
await gPhotosPurgeWaitFor(() => {
return gPhotosPurgeGetNumberOfSelected() ? true : null;
}, 'nSelected=0', 20000);
setTimeout(gPhotosPurge, 4000);
}
function gPhotosPurgeSelectPhotos() {
['Burst photo', 'Collage ', 'Effects ', 'Photo ', 'Video '].forEach(label => {
const els = document.querySelectorAll('[aria-label*="' + label + '"][role="checkbox"]');
for (let i = 0; i < els.length; i++) {
if (els[i].getAttribute('aria-checked') != 'false') continue;
els[i].focus();
els[i].click();
}
});
}
function gPhotosPurgeGetNumberOfSelected() {
let clearEl = document.querySelector('[aria-label="Clear selection"]');
while (clearEl && (clearEl = clearEl.parentNode)) {
const selectedText = (clearEl.textContent || '').match(/(\d+)\s*selected/i);
if (selectedText) return parseInt(selectedText[1], 10);
}
return null;
}
function gPhotosPurgeWaitFor(cb, desc, timeout = 5000) {
let guard = timeout / 250;
return new Promise((resolve, reject) => {
const tid = setInterval(() => {
try {
if (!guard--) throw 'Waitfor timeout! ' + desc;
const res = cb();
if (res !== null) return [clearInterval(tid), resolve(res)];
} catch (err) {
clearInterval(tid);
reject(err);
}
}, 200);
});
}
gPhotosPurge();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment