您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
添加从eBird下载媒体或在浏览器中浏览的按钮
- // ==UserScript==
- // @name eBird media downloader
- // @name:zh-CN eBird媒体下载器
- // @namespace https://github.com/sun-jiao
- // @match https://*.ebird.org/*
- // @match https://*.macaulaylibrary.org/*
- // @match https://birdsoftheworld.org/*
- // @grant GM_xmlhttpRequest
- // @version 3.0
- // @author Sun Jiao
- // @license GPL_v3
- // @description Add a button to download the medias from eBird or view it in browser.
- // @description:zh-cn 添加从eBird下载媒体或在浏览器中浏览的按钮
- // ==/UserScript==
- const PREFIX = 'https://cdn.download.ams.birds.cornell.edu/api/v1/asset/';
- const SUFFIX = '/2400';
- const SPEC = '/spectrogram_small';
- const AUDIO = '/audio';
- const VIDEO = '/mp4/1280';
- var download = "Download";
- (function() {
- 'use strict';
- setDownload();
- try {
- ebird()
- } catch (error) {
- console.error(error);
- }
- window.addEventListener('load', function () {
- try {
- ebird()
- } catch (error) {
- console.error(error);
- }
- })
- MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
- var observer = new MutationObserver(function(mutations, observer) {
- // fired when a mutation occurs
- try {
- ebird()
- } catch (error) {
- console.error(error);
- }
- // console.log(mutations, observer);
- });
- // define what element should be observed by the observer
- // and what types of mutations trigger the callback
- observer.observe(document, {
- subtree: true,
- attributes: true
- });
- })();
- function setDownload(){
- var userLang = navigator.language || navigator.userLanguage;
- switch(userLang.split("-")[0]){
- case("zh"):{
- download = "下载";
- break;
- }
- case("fr"):{
- download = "Télécharger";
- break;
- }
- case("ja"):{
- download = "ダウンロード";
- break;
- }
- case("uk"):{
- download = "Завантаження файлів";
- break;
- }
- case("ko"):{
- download = "다운로드";
- break;
- }
- case("ru"):{
- download = "скачать";
- break;
- }
- case("pt"):{
- download = "Baixar";
- break;
- }
- }
- }
- function ebird(){
- let lists = document.getElementsByClassName('Lightbox-links');
- for (const list of lists) {
- var href1 = list.getElementsByTagName("div").at(-1).getElementsByTagName("a")[0].getAttribute("href");
- let ID = getID(href1);
- process(list, ID);
- }
- if (window.location.hostname == "macaulaylibrary.org") {
- let lists2 = document.getElementsByClassName("actions");
- for (const list of lists2) {
- let ID = getID(window.location.href);
- process(list, ID);
- }
- }
- }
- function process(list, ID){
- console.log('ID:' + ID);
- var href = PREFIX + ID + SUFFIX;
- if (document.getElementsByClassName("SpectrogramPlayer").length > 0){
- href = PREFIX + ID + AUDIO;
- } else if (document.getElementsByClassName("VideoPlayer-video").length > 0){
- href = PREFIX + ID + VIDEO;
- }
- if(list.getElementsByClassName("Raccoon-s-script").length > 0){
- return;
- }
- var text = "\t<div class=\"Raccoon-s-script\">\r\t\t\t\t<a target=\"_blank\" rel=\"noopener\" class=\"\" href=\"" + href + "\">\r\t\t\t\t\t<svg class=\"Icon Icon--download\" role=\"img\"><use xlink:href=\"#Icon--download\"></use></svg>\r\t\t\t\t\t" + download + "\r\t\t\t\t</a>\r\t\t\t</div>"
- var downloadBtn = stringToHTML(text);
- var new_div = downloadBtn.getElementsByTagName("div")[0]
- list.appendChild(new_div);
- }
- function getID(href){
- //一般来说该媒体文件在Macaulay Library的链接的末尾即是媒体id,例如:https://macaulaylibrary.org/zh-CN/asset/230539581
- //有些情况下,上面那种链接之后还会以#号或者?问号为分隔附一段,应当被删除。
- //例如:https://macaulaylibrary.org/asset/180854341#_ga=2.225998489.2098077357.1654784315-1293864495.1651583523
- //或者:https://macaulaylibrary.org/asset/180854341?_gl=1*v5o4c3*_ga*MTI5Mzg2NDQ5NS4xNjUxNTgzNTIz*_ga_QR4NVXZ8BM*MTY1NDg0MDgwMC4xOC4xLjE2NTQ4NDA4MTQuNDY.#_ga=2.28237631.2098077357.1654784315-1293864495.1651583523
- //有些时候不是以asset结尾,例如:https://macaulaylibrary.org/photo/106358811
- if (href.includes("asset/")){
- return href.split("asset/")[1].split(/[^0-9]/)[0];
- } else {
- return href.split("/").at(-1);
- }
- }
- /**
- * Convert a template string into HTML DOM nodes
- * Copied from: https://www.codegrepper.com/code-examples/javascript/convert+string+to+html+format+in+javascript
- * @param {String} str The template string
- * @return {Node} The template HTML
- */
- function stringToHTML(str) {
- var parser = new DOMParser();
- var doc = parser.parseFromString(str, 'text/html');
- return doc.body;
- }
- /**
- * In fact this is an official function for Array, but not supported for HTMLCollection.
- * see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at
- * @param {Int} num The index number.
- */
- HTMLCollection.prototype.at = function(num) {
- if(num >= 0){
- return this[num];
- } else {
- return this[this.length + num];
- }
- };