Skip to content

Instantly share code, notes, and snippets.

@jakobbouchard
Last active March 9, 2023 15:36
Show Gist options
  • Save jakobbouchard/347d5ed66f10c92984a94a83a58bb436 to your computer and use it in GitHub Desktop.
Save jakobbouchard/347d5ed66f10c92984a94a83a58bb436 to your computer and use it in GitHub Desktop.
Backblaze Download Stats as CSV
// ==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