Greasy Fork

来自缓存

Greasy Fork is available in English.

4plebs Thread Image Downloader

Download all images individually in a thread with original filenames (by default). Optional thread API button, for development purposes.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name        4plebs Thread Image Downloader
// @namespace   Violentmonkey Scripts
// @match       https://archive.4plebs.org/*/thread/*
// @grant       GM_download
// @grant       GM_registerMenuCommand
// @version     1.0
// @license     The Unlicense
// @author      ImpatientImport
// @description Download all images individually in a thread with original filenames (by default). Optional thread API button, for development purposes.
// ==/UserScript==

(function() {
  'use strict';
  
  // Constants for later reference
  const top_of_thread = document.getElementsByClassName("post_controls")[0];
  const thread_URL = document.URL;
  const url_path = new URL(thread_URL).pathname;
  const url_path_split = url_path.toString().split('/')
  const thread_board = url_path_split[1];
  const thread_num = url_path_split[3];
  const api_url = "https://archive.4plebs.org/_/api/chan/thread/?board=" + thread_board + "&num=" + thread_num; // important
  
  /* EDIT BENEATH THIS LINE */
  
  // User preferences
  var indiv_button_enabled = true;
  
  var api_button_enabled = false;
  
  var keep_original_filenames = true;
  
  /* EDIT ABOVE THIS LINE */

  
  // Individual thread image downloader button
  
  var indiv_dl_btn;
  var indiv_dlbtn_elem;
  if (indiv_button_enabled){
    indiv_dl_btn = document.createElement('a');
    indiv_dl_btn.id = "indiv_btn";
    indiv_dl_btn.classList.add("btnr", "parent"); 
    indiv_dl_btn.innerText = "Indiv DL";
    top_of_thread.append(indiv_dl_btn);

    indiv_dlbtn_elem = document.getElementById("indiv_btn");
  }
  
  // API button for getting the JSON of a thread in a new tab
  
  var api_btn;
  var api_btn_elem;
  if (api_button_enabled){
    api_btn = document.createElement('a');
    api_btn.id = "api_btn";
    api_btn.href = api_url;
    api_btn.target = "new";
    api_btn.classList.add("btnr", "parent"); 
    api_btn.innerText = "Thread API";
    top_of_thread.append(api_btn);

    api_btn_elem = document.getElementById("api_btn");
  }
  
  // Retrieves media from the thread (in JSON format)
  // If OP only, ignore posts, else get posts
  function retrieve_media(thread_obj) {
    var media_arr = [];
    var media_fnames = [];
    var return_value = [];

    const OP = thread_obj[thread_num].op.media;
    //console.log(OP); // debug

    media_arr.push(OP.media_link);
    media_fnames.push(OP.media_filename);

    // Boolean, checks if posts are present in thread
    const posts_exist = thread_obj[thread_num].posts != undefined;

    if (posts_exist) {
      const thread_posts = thread_obj[thread_num].posts;
      const post_nums = Object.keys(thread_posts);
      const posts_length = post_nums.length;

      //Adds all post image urls and original filenames to the above arrays
      for (let i = 0; i < posts_length; i++) {

        //equivalent to: thread[posts][post_num][media]
        var temp_media_post = thread_posts[post_nums[i]].media;

        //if media exists,
        if (temp_media_post !== null) {
          //then push media to arrays
          media_arr.push(temp_media_post.media_link)
          
          if (keep_original_filenames){
            media_fnames.push(temp_media_post.media_filename);
            
            //console.log(temp_media_post.media_filename); //debug
          }
          else{
            media_fnames.push(temp_media_post.media_orig);
            
            //console.log(temp_media_post.media_orig); //debug
          }

        }
      }
    }

    // Adds the media link array with the media filenames array into the final return
    return_value[0] = media_arr;
    return_value[1] = media_fnames;
    
    for (var i=0; i<media_arr.length; i++){
      //console.log(media_fnames[i] + " "+ media_arr[i]); //debug
      
      GM_download(media_arr[i], media_fnames[i]);
    }  

  }

  // Gets the JSON file for the 4plebs thread with the API
  async function get_4plebs_thread() {
    const API_response = await fetch(api_url);
    const JSON_file = await API_response.json();
    //console.log(JSON_file); // debug
    retrieve_media(JSON_file);
  }

  GM_registerMenuCommand("Download all thread images individually", get_4plebs_thread);
  
  
  // Download thread button event listener(s)
  
  indiv_dlbtn_elem.addEventListener("click", get_4plebs_thread);
    
})();