Greasy Fork is available in English.
微博内容页增加图片下载的按钮
// ==UserScript==
// @name 微博图片下载器
// @namespace https://1mether.me/
// @version 0.1
// @description 微博内容页增加图片下载的按钮
// @author 乙醚(@locoda)
// @match http*://*.weibo.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=weibo.com
// @license MIT
// ==/UserScript==
(function () {
"use strict";
// ==============
// = Main =
// ==============
var observer = new MutationObserver(function (mutations, observer) {
// console.log(mutations);
processWeiboTimeline();
});
observer.observe(document, {
subtree: true,
childList: true,
});
// ================================
// = Button Injection Utils =
// ================================
function processWeiboTimeline() {
var divs = Array.from(document.querySelectorAll("article"));
divs.forEach((div) => {
if (
div.querySelector("div[class^=picture]") &&
!div.querySelector(".download-button")
) {
injectImageDownloadButton(div);
}
});
}
function injectImageDownloadButton(element) {
// 图片下载按钮
const like = Array.from(
element.querySelectorAll(".woo-box-item-flex")
).pop();
var download = like.cloneNode(true);
download.classList.add("download-button");
var btn = download.querySelector("button");
btn.removeChild(btn.firstChild);
btn.firstChild.textContent = "下载";
btn.firstChild.classList.remove("woo-like-liked");
btn.addEventListener("click", function () {
getInfoAndDownloadImages(element);
});
like.parentElement.appendChild(download);
}
function getInfoAndDownloadImages(element) {
// 获取图片链接
const id = element
.querySelector("a[class^=head-info_time]")
.href.split("/")
.pop()
.split("?")[0];
fetch("https://weibo.com/ajax/statuses/show?id=" + id)
.then((response) => response.json())
.then((response) => {
console.log(response);
const prefix = response.user.screen_name + "_" + id + "_";
var imgs = [];
if (response.hasOwnProperty("retweeted_status")) {
response = response.retweeted_status;
}
for (var pic in response.pic_infos) {
imgs.push(response.pic_infos[pic].largest.url);
}
downloadImages(imgs, prefix);
});
}
// ========================
// = Download Utils =
// ========================
function downloadImages(imgs, prefix = "") {
console.debug("正在下载图片: " + imgs);
// Thanks to https://github.com/y252328/Instagram_Download_Button
if (imgs.length <= 10) {
// 同时最多下载十张图
imgs.forEach((img, index) =>
downloadOneImage(img, appendIndexToPrefix(prefix, index))
);
} else {
// 设置延时下载更多图片 https://stackoverflow.com/questions/56244902/56245610#56245610
imgs.forEach((img, index) => {
setTimeout(function () {
downloadOneImage(img, appendIndexToPrefix(prefix, index));
}, index * 200);
});
}
}
function appendIndexToPrefix(prefix, index) {
return (
prefix +
(index + 1).toLocaleString("en-US", {
minimumIntegerDigits: 3,
useGrouping: false,
}) +
"_"
);
}
function downloadOneImage(img, prefix = "") {
fetch(img, {
headers: new Headers({
Origin: window.location.origin,
}),
mode: "cors",
cache: "no-cache",
})
.then((response) => response.blob())
.then((blob) =>
dowloadBlob(
window.URL.createObjectURL(blob),
prefix + img.substring(img.lastIndexOf("/") + 1)
)
)
.catch((e) => console.error(e));
}
function dowloadBlob(blob, filename) {
var a = document.createElement("a");
a.download = sanitizeFileName(filename);
a.href = blob;
document.body.appendChild(a);
a.click();
a.remove();
}
// ======================
// = Naming Utils =
// ======================
function sanitizeFileName(input, replacement = "_") {
// Thanks to https://github.com/parshap/node-sanitize-filename/blob/master/index.js
const illegalRe = /[\/\?<>\\:\*\|"]/g;
const controlRe = /[\x00-\x1f\x80-\x9f]/g;
const reservedRe = /^\.+$/;
const windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i;
const windowsTrailingRe = /[\. ]+$/;
return input
.split(/\s/g)
.filter((s) => s)
.join("_")
.replace(illegalRe, replacement)
.replace(controlRe, replacement)
.replace(reservedRe, replacement)
.replace(windowsReservedRe, replacement)
.replace(windowsTrailingRe, replacement);
}
})();