Frenschan Thread Image Downloader

Downloads all images individually in a frenschan thread with original filenames (by default).

目前為 2022-04-15 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        Frenschan Thread Image Downloader
// @namespace   Violentmonkey Scripts
// @match       https://www.frenschan.com/*/res/*.html
// @grant       GM_download
// @grant       GM_registerMenuCommand
// @version     1.0
// @license     The Unlicense
// @author      ImpatientImport
// @description Downloads all images individually in a frenschan thread with original filenames (by default).
// ==/UserScript==

/* EDIT ABOVE THIS LINE */

// User preferences

var download_limit = 3000; // speed in milliseconds to delay

/* EDIT BELOW THIS LINE */


function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

(function() {
  'use strict';
  
  // Constants for later reference
  const top_of_thread = document.getElementsByClassName("intro")[0];
  const thread_URL = document.URL;
  const tinyboard_site = thread_URL.toString().split('/')[2];
  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].split(".")[0];
  
  const json_url = "https://"+ tinyboard_site + "/"+ thread_board +"/res/"+ thread_num + ".json"; // important
  
  var media_arr=[], media_fnames=[];
  
  // Gets the JSON file for the Tinyboard thread
  async function get_archive_thread() {
    const site_response = await fetch(json_url);
    const JSON_file = await site_response.json();
    console.log(JSON_file); // debug
    retrieve_media(JSON_file);
    download_images();
  }
  
  // Retrieves media from the thread (in JSON format)
  function retrieve_media(thread_obj) {
    
    const posts_exist = thread_obj.posts != undefined;

    if (posts_exist) {
      const thread_posts = thread_obj.posts;
      //const post_nums = Object.keys(thread_posts);
      const posts_length = thread_posts.length;
      
      for (let i = 0; i < posts_length; i++) {
        
          if(thread_posts[i].tim != null && thread_posts[i].ext != "deleted"){
            media_arr.push("https://" + tinyboard_site + "/" + thread_board + "/src/" + thread_posts[i].tim + thread_posts[i].ext );
            media_fnames.push(thread_posts[i].filename + thread_posts[i].ext);
          }
        
      }
      
    }
    
  }
    
  async function download_images(){

    for (var i=0; i<media_arr.length; i++){

      await sleep(download_limit);
      
      console.log(media_arr[i]);

      GM_download(media_arr[i], media_fnames[i]) // downloads images
      
    }
  }
  
  GM_registerMenuCommand("Download all thread images individually", get_archive_thread);
  
  var indiv_dl_btn;
  var indiv_dlbtn_elem;
  indiv_dl_btn = document.createElement('a');
  indiv_dl_btn.id = "indiv_btn";
  indiv_dl_btn.innerText = "[Download Images]";
  top_of_thread.append(indiv_dl_btn);
  indiv_dlbtn_elem = document.getElementById("indiv_btn");
  indiv_dl_btn.addEventListener("click", get_archive_thread);
  
})();