Last active
March 9, 2023 15:36
-
-
Save jakobbouchard/347d5ed66f10c92984a94a83a58bb436 to your computer and use it in GitHub Desktop.
Backblaze Download Stats as CSV
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 Backblaze Stats as CSV | |
// @namespace https://jakobbouchard.dev/ | |
// @source https://gist.github.com/jakobbouchard/347d5ed66f10c92984a94a83a58bb436 | |
// @version 1.0 | |
// @description Adds a "Download CSV" button to the Backblaze buckets view. | |
// @author Jakob Bouchard | |
// @match https://secure.backblaze.com/b2_buckets.htm* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=backblaze.com | |
// @grant none | |
// ==/UserScript== | |
(function () { | |
"use strict"; | |
/** @type {Object.<string, { files: number, size: number }>} */ | |
let data = {}; | |
function createCSVButton() { | |
let csv = '"Bucket","Files","Size in GB"\n'; | |
for (let bucket in data) { | |
csv += `"${bucket}","${data[bucket].files}","${data[bucket].size}"\n`; | |
} | |
const date = new Date(); | |
const ymd = `${date.getFullYear()}-${(date.getMonth() + 1) | |
.toString() | |
.padStart(2, "0")}-${date.getDate().toString().padStart(2, "0")}`; | |
const blob = new Blob([csv], { type: "text/csv" }); | |
const url = URL.createObjectURL(blob); | |
const a = document.createElement("a"); | |
a.setAttribute("href", url); | |
a.setAttribute("download", `backblaze-${ymd}.csv`); | |
a.textContent = "Download CSV"; | |
const welcome = document.querySelector(".welcome_user tbody"); | |
const tr = document.createElement("tr"); | |
const td = document.createElement("td"); | |
const div = document.createElement("div"); | |
div.setAttribute("class", "user-spacing"); | |
div.setAttribute("align", "right"); | |
div.appendChild(a); | |
td.appendChild(div); | |
tr.appendChild(td); | |
welcome.appendChild(tr); | |
} | |
document | |
.querySelectorAll(".bucket-wrapper .storage-buckets") | |
.forEach((bucket) => { | |
const name = bucket.querySelector(".b2-bucket-bucket-name").textContent; | |
/** @type {number} */ | |
let files; | |
/** @type {number} */ | |
let size; | |
const statsLabels = bucket.querySelectorAll(".b2-stats-label"); | |
const statsData = bucket.querySelectorAll(".b2-stats-data"); | |
for (let i = 0; i < statsLabels.length; i++) { | |
if (files && size) break; | |
const label = statsLabels[i]; | |
if (label.textContent.trim() == "Current Files:") { | |
files = parseInt(statsData[i].textContent.replace(/,/g, "").trim()); | |
continue; | |
} | |
if (label.textContent.trim() == "Current Size:") { | |
size = parseFloat( | |
statsData[i].textContent.replace(/,/g, "").replace(/GB/g, "").trim() | |
).toFixed(1); | |
continue; | |
} | |
} | |
data[name] = { files, size }; | |
}); | |
let totalFiles = 0; | |
let totalSize = 0; | |
for (const bucket in data) { | |
const value = data[bucket]; | |
totalFiles += value.files; | |
totalSize += value.size; | |
} | |
data.total = { | |
files: Object.entries(data).reduce( | |
(acc, [key, value]) => acc + value.files, | |
0 | |
), | |
size: Object.entries(data).reduce( | |
(acc, [key, value]) => acc + parseFloat(value.size), | |
0 | |
).toFixed(1), | |
}; | |
console.table(data); | |
createCSVButton(); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment