Last active
May 11, 2018 11:20
-
-
Save jbruggem/1cdd7a211e6bbdc1b7a3f97b0d4a7208 to your computer and use it in GitHub Desktop.
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 hubic delete | |
// @version 1 | |
// @grant none | |
// @include https://hubic.com/home/* | |
// @require https://cdn.jsdelivr.net/npm/async@2.6.0/dist/async.min.js | |
// ==/UserScript== | |
var originalLocation; | |
// TODO: where does it hang ? | |
// activityTick ? | |
var activityTick = Date.now(); | |
function activityHappened(){ activityTick = Date.now(); } | |
function mainDeleteAll(){ | |
originalLocation = normalUrl(window.location); | |
window.addEventListener('hashchange', (e) => { | |
const deleteFirstFolder = e.oldURL.length > e.newURL.length; | |
console.log("hashchange! Call handleFolder", deleteFirstFolder); | |
setTimeout(() => handleFolder(originalLocation, deleteFirstFolder), 1000); | |
return true; | |
}); | |
setInterval(function checkForActivity(){ | |
// in seconds | |
if((Date.now() - activityTick)/1000 > 10){ | |
console.log("Activity tick expired ! Restarting."); | |
activityHappened(); | |
const parentLoc = parentLocation(originalLocation); | |
if(parentLoc === normalUrl){ | |
console.log("Call handleFolder"); | |
handleFolder(originalLocation, null); | |
}else{ | |
console.log("Change location to: " + parentLoc); | |
window.location = parentLoc; | |
} | |
} | |
}, 1000); | |
handleFolder(originalLocation, null); | |
} | |
function handleFolder(rootLocation, deleteFirstFolder=false){ | |
console.log("handleFolder", window.location); | |
activityHappened(); | |
if(!normalUrl(window.location).startsWith(rootLocation)){ | |
console.error("ERROR OUT OF ORIGINAL LOCATION BOUNDS"); | |
console.error(normalUrl(window.location), rootLocation); | |
return; | |
} | |
const allFiles = Array.from(document.querySelectorAll(".file-line.file")); | |
const files = allFiles.filter((e) => !e.classList.contains("browser-file-line-operation-doing")); | |
async.waterfall([ | |
(cb) => { | |
function wait(){ | |
if(0 < Array.from(document.querySelectorAll("ul.browser")).length){ | |
console.log("Page is loaded !"); | |
cb(); | |
}else{ | |
console.log("Wait for page load."); | |
setTimeout(wait, 500); | |
} | |
} | |
wait(); | |
}, | |
(cb) => { | |
console.log("handleFolder: deleteFirstFolder?", deleteFirstFolder); | |
activityHappened(); | |
const dirs = document.querySelectorAll(".file-line.directory"); | |
const firstDir = dirs.item(0); | |
if(deleteFirstFolder && dirs.length > 0 && firstDir !== null){ | |
console.log("handleFolder: deleteFile (folder)", firstDir); | |
deleteFile(firstDir, (err) => setTimeout(cb, 500)); | |
}else{ | |
cb(); | |
} | |
}, | |
(cb) => { | |
console.log("handleFolder: deleteFiles"); | |
activityHappened(); | |
deleteFiles(files, rootLocation, cb); | |
}, | |
(cb) => { | |
const dirs = document.querySelectorAll(".file-line.directory"); | |
console.log("handleFolder: dirs ", dirs); | |
activityHappened(); | |
if(0 == dirs.length) { | |
if(normalUrl(window.location) === rootLocation){ | |
console.log("***********************************"); | |
console.log("FINISHED DELETING EVERYTHING"); | |
console.log("***********************************"); | |
} else { | |
console.log("handleFolder: go to parent"); | |
window.location = parentLocation(rootLocation); | |
} | |
} else { | |
console.log("handleFolder: go to child"); | |
const nextURL = normalUrl(window.location) + '/' + dirs.item(0).dataset.itemKey; | |
console.log(nextURL); | |
window.location = nextURL; | |
} | |
cb(); | |
}, | |
]); | |
} | |
function deleteFiles(files, rootLocation, cbEndDeleteFiles){ | |
console.log("deleteFiles: ", files); | |
activityHappened(); | |
if(files.length == 0){ | |
console.log("No files. return."); | |
return cbEndDeleteFiles(); | |
} | |
function checkedEnd(){ | |
activityHappened(); | |
if(0 < document.querySelectorAll(".file-line.file").length){ | |
console.log("async.eachSeries ended but files remaining. Restarting."); | |
deleteFiles(files, rootLocation, cbEndDeleteFiles); | |
}else{ | |
console.log("deleteFiles ended."); | |
cbEndDeleteFiles(); | |
} | |
} | |
async.eachLimit(files, 10, deleteFile, () => { | |
console.log("Delete files done, waiting."); | |
checkedEnd(); | |
}); | |
} | |
function deleteFile(li, cbFileDeleted){ | |
console.log("deleteFile: ", normalUrl(window.location), li.dataset.itemKey); | |
activityHappened(); | |
async.waterfall([ | |
(cbRemove) => { | |
console.log("remove"); | |
async.retry({times: 5, interval: 300}, | |
(cb) => { | |
activityHappened(); | |
li.querySelector("input").click(); | |
document.querySelector("#browser-action-others").click(); | |
document.querySelector(".browser-other-action.browser-action-remove").click(); | |
const button = document.querySelector(".browser-modal-action.browser-modal-main-action.ui-button.ui-button-text-only") | |
if(button){ | |
button.click(); | |
cb(null); | |
}else{ | |
cb('failed'); | |
} | |
}, | |
cbRemove); | |
}, | |
(cbWait) => { | |
console.log("wait"); | |
async.retry({times: 40, interval: 500}, | |
(cb) => { | |
activityHappened(); | |
// if parentNode is null, deletion was a success | |
cb(li.parentNode); | |
}, | |
cbWait); | |
}, | |
], | |
(err) => { | |
activityHappened(); | |
console.log("deleteFile ended ", err === null ? "succcess" : "failure"); | |
cbFileDeleted(err); | |
} | |
); | |
} | |
function normalUrl(url){ | |
url = url.toString(); | |
if(url.endsWith("/")){ | |
url = url.substr(0, url.length - 1); | |
} | |
return url; | |
} | |
function parentLocation(rootLocation){ | |
const par = normalUrl(window.location).split("/").slice(0, -1).join("/"); | |
console.log("Estimated parent of", normalUrl(window.location), "is ", par, "(If equal to root, will return: ", normalUrl(rootLocation)," )"); | |
return par.startsWith(normalUrl(rootLocation)) ? par : normalUrl(rootLocation); | |
} | |
function prepareUI(){ | |
document.querySelector("body").insertAdjacentHTML("afterbegin", | |
'<div style="position:fixed; z-index: 1000; background: black; bottom: 0; right: 0">'+ | |
'<a id="mainDeleteAll" style="cursor: pointer; display: block; padding: 1.5em; color:white; font-weight:bold">' + | |
'RECURSIVE DELETE EVERYTHING</a></div>'); | |
document.querySelector("#mainDeleteAll").addEventListener('click', () => { | |
console.log("mainDeleteAll"); | |
conf = confirm("sure ?"); | |
console.log(conf); | |
if(true === conf){ | |
mainDeleteAll(); | |
} | |
}); | |
} | |
prepareUI(); | |
console.log("hubic delete loaded"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment