Skip to content

Instantly share code, notes, and snippets.

@sebastian-berlin-wmse
Created March 10, 2026 16:38
Show Gist options
  • Select an option

  • Save sebastian-berlin-wmse/2bd84fbefaae189a0384641f5f352da8 to your computer and use it in GitHub Desktop.

Select an option

Save sebastian-berlin-wmse/2bd84fbefaae189a0384641f5f352da8 to your computer and use it in GitHub Desktop.
ISCC upload helper
// ==UserScript==
// @name ISCC upload helper
// @namespace sebastian.berlin@wikimedia.se
// @version 2026-02-27
// @description Add link to CommonsDB registry
// @author You
// @match https://commons.wikimedia.org/wiki/Special:UploadWizard*
// @icon https://www.google.com/s2/favicons?sz=64&domain=wikimedia.org
// @grant GM.xmlHttpRequest
// ==/UserScript==
async function init() {
let require = await mw.loader.using( '@wikimedia/codex', "api" );
let { createMwApp, ref } = require("vue");
let { CdxButton } = require( '@wikimedia/codex' );
let mountPoint = document.querySelector("#mwe-upwiz-files").appendChild( document.createElement( 'div' ) );
let api = new mw.Api();
createMwApp( {
setup() {
let iscc = ref("");
return { iscc };
},
methods: {
async makeIscc () {
let thumb = document.querySelector(".mwe-upwiz-thumbnail-link img");
let data = thumb.getAttribute("src").split(",")[1];
let imageBuffer = Uint8Array.fromBase64(data);
let filename = "eW91ci1tZWRpYS1maWxlLmpwZw==";
let isccUrl = "https://demo.iscc.io/api/v1/iscc";
// Bypass CSP
let response = await GM.xmlHttpRequest({
method: "POST",
url: isccUrl,
responseType: "json",
headers: {
"X-Upload-Filename": filename,
"content-type": "application/octet-stream",
accept: "application/json"
},
data: imageBuffer
});
let isccData = response.response;
/*let request = new Request(isccUrl, {
method: "POST",
headers: {
"X-Upload-Filename": filename,
"content-type": "application/octet-stream",
accept: "application/json"
},
body: imageBuffer
});
let response = await fetch(request);
if(!response.ok) {
this.iscc = `HTTP error! Status: ${response.status}`;
}
let isccData = await response.response; */
// Remove the "ISCC:" prefix.
this.iscc = isccData.iscc.split(":")[1];
},
async addUrl() {
this.urls.push({value: this.newUrl});
let storedUrls = JSON.parse(localStorage.getItem("wikispeechProducerUrls")) || [];
storedUrls.push(this.newUrl);
localStorage.setItem("wikispeechProducerUrls", JSON.stringify(storedUrls));
},
saveUrl() {
localStorage.setItem("wikispeechProducerUrl", this.selectedUrl);
this.open = false;
}
},
components: {
CdxButton
},
template: `
<cdx-button @click="makeIscc">Generate ISCC</cdx-button>
ISCC = <a target="_blank" :href="'https://registry.commonsdb.org/explorer/' + iscc">{{ iscc }}</a>
`
} )
.mount( mountPoint );
clearInterval(initIntervalId);
};
let initIntervalId = setInterval(() => {
console.log("Trying init.");
init();
},
1000
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment