find panda

check panda.chaika.moe for related galleries when searching

От 02.12.2022. Виж последната версия.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name find panda
// @namespace http://tampermonkey.net/
// @version 0.2
// @description check panda.chaika.moe for related galleries when searching
// @description:zh 在搜索时检查panda.chaika.moe里是否有相关的画廊
// @author ayasechan
// @license LGPL
// @icon https://www.google.com/s2/favicons?sz=64&domain=e-hentai.org
// @run-at document-start
// @match https://exhentai.org/*
// @match https://e-hentai.org/*
// @grant GM_xmlhttpRequest
// @grant GM_getResourceText
// @connect panda.chaika.moe
// @resource iziToast.min.css https://cdn.jsdelivr.net/npm/[email protected]/dist/css/iziToast.min.css
// @resource iziToast.min.js https://cdn.jsdelivr.net/npm/[email protected]/dist/js/iziToast.min.js
// ==/UserScript==

/**
 * Tips:
 * 
 * 目前的匹配模式很简单
 * 优先匹配搜索时的第一个 group 或 artist 标签
 * 匹配成功后会忽略其他搜索内容和标签
 * 使用标签搜索时会且只会匹配上述两个标签
 * 
 * 没有出现这两个标签时 则将所有的搜索的内容都视为关键词
 * 
 * 其他e站支持的语法 比如排除 精确搜索什么的都不支持
 * 因此要使脚本成功运行 最好只使用简单的关键词搜索
 */


/*
  inject resource
*/
((...names) => {
  if (typeof GM_getResourceText === void 0) {
    const text = "need grant GM_getResourceText permission";
    alert(text);
    throw text;
  }
  for (const name of names) {
    const data = GM_getResourceText(name);
    if (!data.length) {
      console.warn(`resource ${name} have no content`);
    }
    if (name.endsWith(".js")) {
      const el = document.createElement("script");
      el.textContent = data;
      document.body.appendChild(el);
    } else if (name.endsWith(".css")) {
      const el = document.createElement("style");
      el.textContent = data;
      document.body.appendChild(el);
    }
  }
})('iziToast.min.css', 'iziToast.min.js');




(function() {
  "use strict";
  const request = (url, { json = null, form = null } = {}) => {
    return new Promise((resolve, reject) => {
      const r = GM_xmlhttpRequest != null ? GM_xmlhttpRequest : XMLHttpRequest;
      let method = "POST";
      let ct, data;
      if (json) {
        ct = "application/json";
        data = JSON.stringify(json);
      } else if (form) {
        ct = "application/x-www-form-urlencoded";
        data = new FormData();
        for (const [k, v] of Object.entries(form)) {
          data.append(k, v);
        }
      } else {
        method = "GET";
      }
      r({
        url,
        data,
        method,
        headers: {
          "Content-Type": ct
        },
        onload: (resp) => {
          resolve(resp.responseText);
        },
        onerror: (err) => {
          reject(err);
        }
      });
    });
  };
  const main = async () => {
    const kw = parseKeyword();
    if (!kw) {
      return;
    }
    let content;
    try {
      content = await request(
        `https://panda.chaika.moe/archive-autocomplete/?q=${kw}`
      );
    } catch (error) {
      alert("can not connect to panda.chaika.moe. see more info from dev tool");
      throw error;
    }
    if (content === noMatchesFound) {
      console.log(`nothing found in panda for ${kw}`);
      return;
    }
    const openPanda = () => {
      window.open(`https://panda.chaika.moe/search/?title=${kw}`);
    };
    iziToast.show({
      message: "Find a panda",
      messageColor: "#ffffff",
      color: "#363940",
      timeout: 1e4,
      position: "topRight",
      onOpened: (_, el) => {
        el.addEventListener("click", openPanda);
      },
      onClosed: (_, el) => {
        el.removeEventListener("click", openPanda);
      }
    });
  };
  const parseKeyword = () => {
    var _a, _b, _c;
    const u = new URL(location.href);
    const f_search = u.searchParams.get("f_search");
    if (f_search) {
      const result2 = f_search.match(fSearchRegex);
      if (result2) {
        const kw = (_c = (_a = result2.groups) == null ? void 0 : _a.kw1) != null ? _c : (_b = result2.groups) == null ? void 0 : _b.kw2;
        if (kw) {
          return kw;
        }
      }
      return f_search;
    }
    const result = u.pathname.match(tagRegex);
    if (result) {
      return result[1].replaceAll("+", " ");
    }
  };
  const tagRegex = /^\/tag\/(?:artist|group):([\w\+]+)$/i;
  const fSearchRegex = /(?:artist|group|circle|a|g):(?:(?<kw1>\w+)\$|"(?<kw2>[\w ]+)\$")/i;
  const noMatchesFound = '<span class="block"><em>No matches found</em></span>';
  main();
})();