Greasy Fork

Greasy Fork is available in English.

pan-link

115网盘一键上传

目前为 2024-07-01 提交的版本。查看 最新版本

// ==UserScript==
// @name         pan-link
// @namespace    pan-link
// @version      0.0.1
// @author       monkey
// @description  115网盘一键上传
// @license      MIT
// @icon         https://vitejs.dev/logo.svg
// @match        *://115.com/*
// @match        *://*.115.com/*
// @require      https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/preact/10.6.6/preact.min.js
// @require      https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.min.js
// @grant        GM_addStyle
// @noframes
// ==/UserScript==

(e=>{if(typeof GM_addStyle=="function"){GM_addStyle(e);return}const o=document.createElement("style");o.textContent=e,document.head.append(o)})(" .file-input{display:none}.p-input{padding:10px;width:500px;border-radius:5px;font-size:16px;outline:none;border:none;background-color:#f6c6d954;border-bottom:1px solid #EA4C89}.p-button{background-color:#ea4c89;border-radius:8px;border-style:none;box-sizing:border-box;color:#fff;cursor:pointer;display:inline-block;font-family:Haas Grot Text R Web,Helvetica Neue,Helvetica,Arial,sans-serif;font-size:14px;font-weight:700;height:40px;line-height:20px;list-style:none;margin:0;outline:none;padding:10px 16px;position:relative;text-align:center;text-decoration:none;transition:.3s;vertical-align:baseline;user-select:none;-webkit-user-select:none;touch-action:manipulation}.p-button:hover,.p-button:focus{background-color:#f082ac}@keyframes bar{0%{opacity:0;height:0}}.bar-container{background-color:#f6c6d9;width:1000px;height:10px;border-radius:5px;overflow:hidden;animation:bar .4s ease}.bar-container>div{width:0;height:100%;background-color:#ea4c89;transition:.4s ease-in-out}@keyframes dialogRotateIn{0%{opacity:0;transform:rotateX(-90deg) translate(-1000px) translateY(-1000px)}}dialog{animation:dialogRotateIn .5s;border:none;outline:none;width:400px;border-radius:10px;padding:20px;box-shadow:0 0 10px #00000040;height:200px;font-size:16px;display:flex;flex-direction:column;gap:10px;align-items:center;justify-content:space-around;word-wrap:break-word;word-break:break-all}dialog a span{color:#5af}dialog>div{display:flex;gap:10px}dialog::backdrop{background:#251f1f40}.main-div{display:flex;flex-direction:column;perspective:1000px;overflow:auto}.main-pan{width:100%;min-height:100px}.main-pan .app-main{z-index:999999;top:0;position:sticky;width:100%;background-color:#f0f8ff;display:flex;gap:20px;flex-wrap:wrap;padding:20px} ");

(function (preact, axios) {
  'use strict';

  var f$1 = 0;
  function u$1(e2, t2, n, o2, i2, u2) {
    t2 || (t2 = {});
    var a2, c2, p2 = t2;
    if ("ref" in p2) for (c2 in p2 = {}, t2) "ref" == c2 ? a2 = t2[c2] : p2[c2] = t2[c2];
    var l2 = { type: e2, props: p2, key: n, ref: a2, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, constructor: void 0, __v: --f$1, __i: -1, __u: 0, __source: i2, __self: u2 };
    if ("function" == typeof e2 && (a2 = e2.defaultProps)) for (c2 in a2) void 0 === p2[c2] && (p2[c2] = a2[c2]);
    return preact.options.vnode && preact.options.vnode(l2), l2;
  }
  const MIX_API = {
    progress: () => {
    },
    abort: null,
    url: "",
    key: ""
  };
  function genRandomStr(length = 12, keys = "abcdef0123456789") {
    let result = "";
    for (let i2 = 0; i2 < length; i2++) {
      result += keys[Math.random() * keys.length ^ 0];
    }
    return result;
  }
  function getType(file) {
    let contentType = file.type;
    if (!(contentType == null ? void 0 : contentType.endsWith("; charset=UTF-8"))) {
      contentType += "; charset=UTF-8";
    }
    return contentType;
  }
  function getDownloadHeader(file) {
    return {
      "content-disposition": `inline;filename=${encodeURIComponent(file.name)}`
    };
  }
  function getFileSize(bytes) {
    if (bytes === 0) return "0 B";
    let k2 = 1024;
    let sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
    let i2 = Math.floor(Math.log(bytes) / Math.log(k2));
    return (bytes / Math.pow(k2, i2)).toPrecision(3) + " " + sizes[i2];
  }
  async function get115Auth() {
    const response = await axios.post(
      "https://uplb.115.com/3.0/sampleinitupload.php",
      {},
      {
        withCredentials: true
      }
    );
    return response.data;
  }
  function genFormData(object) {
    let formData = new FormData();
    for (let key in object) {
      formData.append(key, object[key]);
    }
    return formData;
  }
  async function upload115(file, key = MIX_API.key || genRandomStr(40)) {
    const token = await get115Auth();
    const { accessid, callback, host, object, policy, signature } = token;
    let data = genFormData({
      name: file.name,
      key,
      policy,
      OSSAccessKeyId: accessid,
      signature,
      "x-oss-object-acl": "public-read",
      "Content-Disposition": getDownloadHeader(file)["content-disposition"],
      file
    });
    let controller = new AbortController();
    MIX_API.abort = () => controller.abort();
    await axios.post(`https://fhnfile.oss-cn-shenzhen.aliyuncs.com`, data, {
      headers: {
        "content-type": getType(file)
      },
      timeout: 1e3 * 60 * 60,
      signal: controller.signal,
      onUploadProgress(event) {
        if (!MIX_API.abort) return;
        MIX_API.progress(event.total, event.loaded);
      }
    });
    return `https://fhnfile.oss-cn-shenzhen.aliyuncs.com/${key}`;
  }
  var t, r, u, i, o = 0, f = [], c = [], e = preact.options, a = e.__b, v = e.__r, l = e.diffed, m = e.__c, s = e.unmount, d = e.__;
  function h(n, t2) {
    e.__h && e.__h(r, n, o || t2), o = 0;
    var u2 = r.__H || (r.__H = { __: [], __h: [] });
    return n >= u2.__.length && u2.__.push({ __V: c }), u2.__[n];
  }
  function p(n) {
    return o = 1, y(D, n);
  }
  function y(n, u2, i2) {
    var o2 = h(t++, 2);
    if (o2.t = n, !o2.__c && (o2.__ = [D(void 0, u2), function(n2) {
      var t2 = o2.__N ? o2.__N[0] : o2.__[0], r2 = o2.t(t2, n2);
      t2 !== r2 && (o2.__N = [r2, o2.__[1]], o2.__c.setState({}));
    }], o2.__c = r, !r.u)) {
      var f2 = function(n2, t2, r2) {
        if (!o2.__c.__H) return true;
        var u3 = o2.__c.__H.__.filter(function(n3) {
          return !!n3.__c;
        });
        if (u3.every(function(n3) {
          return !n3.__N;
        })) return !c2 || c2.call(this, n2, t2, r2);
        var i3 = false;
        return u3.forEach(function(n3) {
          if (n3.__N) {
            var t3 = n3.__[0];
            n3.__ = n3.__N, n3.__N = void 0, t3 !== n3.__[0] && (i3 = true);
          }
        }), !(!i3 && o2.__c.props === n2) && (!c2 || c2.call(this, n2, t2, r2));
      };
      r.u = true;
      var c2 = r.shouldComponentUpdate, e2 = r.componentWillUpdate;
      r.componentWillUpdate = function(n2, t2, r2) {
        if (this.__e) {
          var u3 = c2;
          c2 = void 0, f2(n2, t2, r2), c2 = u3;
        }
        e2 && e2.call(this, n2, t2, r2);
      }, r.shouldComponentUpdate = f2;
    }
    return o2.__N || o2.__;
  }
  function _(n, u2) {
    var i2 = h(t++, 3);
    !e.__s && C(i2.__H, u2) && (i2.__ = n, i2.i = u2, r.__H.__h.push(i2));
  }
  function g() {
    var n = h(t++, 11);
    if (!n.__) {
      for (var u2 = r.__v; null !== u2 && !u2.__m && null !== u2.__; ) u2 = u2.__;
      var i2 = u2.__m || (u2.__m = [0, 0]);
      n.__ = "P" + i2[0] + "-" + i2[1]++;
    }
    return n.__;
  }
  function j() {
    for (var n; n = f.shift(); ) if (n.__P && n.__H) try {
      n.__H.__h.forEach(z), n.__H.__h.forEach(B), n.__H.__h = [];
    } catch (t2) {
      n.__H.__h = [], e.__e(t2, n.__v);
    }
  }
  e.__b = function(n) {
    r = null, a && a(n);
  }, e.__ = function(n, t2) {
    n && t2.__k && t2.__k.__m && (n.__m = t2.__k.__m), d && d(n, t2);
  }, e.__r = function(n) {
    v && v(n), t = 0;
    var i2 = (r = n.__c).__H;
    i2 && (u === r ? (i2.__h = [], r.__h = [], i2.__.forEach(function(n2) {
      n2.__N && (n2.__ = n2.__N), n2.__V = c, n2.__N = n2.i = void 0;
    })) : (i2.__h.forEach(z), i2.__h.forEach(B), i2.__h = [], t = 0)), u = r;
  }, e.diffed = function(n) {
    l && l(n);
    var t2 = n.__c;
    t2 && t2.__H && (t2.__H.__h.length && (1 !== f.push(t2) && i === e.requestAnimationFrame || ((i = e.requestAnimationFrame) || w)(j)), t2.__H.__.forEach(function(n2) {
      n2.i && (n2.__H = n2.i), n2.__V !== c && (n2.__ = n2.__V), n2.i = void 0, n2.__V = c;
    })), u = r = null;
  }, e.__c = function(n, t2) {
    t2.some(function(n2) {
      try {
        n2.__h.forEach(z), n2.__h = n2.__h.filter(function(n3) {
          return !n3.__ || B(n3);
        });
      } catch (r2) {
        t2.some(function(n3) {
          n3.__h && (n3.__h = []);
        }), t2 = [], e.__e(r2, n2.__v);
      }
    }), m && m(n, t2);
  }, e.unmount = function(n) {
    s && s(n);
    var t2, r2 = n.__c;
    r2 && r2.__H && (r2.__H.__.forEach(function(n2) {
      try {
        z(n2);
      } catch (n3) {
        t2 = n3;
      }
    }), r2.__H = void 0, t2 && e.__e(t2, r2.__v));
  };
  var k = "function" == typeof requestAnimationFrame;
  function w(n) {
    var t2, r2 = function() {
      clearTimeout(u2), k && cancelAnimationFrame(t2), setTimeout(n);
    }, u2 = setTimeout(r2, 100);
    k && (t2 = requestAnimationFrame(r2));
  }
  function z(n) {
    var t2 = r, u2 = n.__c;
    "function" == typeof u2 && (n.__c = void 0, u2()), r = t2;
  }
  function B(n) {
    var t2 = r;
    n.__c = n.__(), r = t2;
  }
  function C(n, t2) {
    return !n || n.length !== t2.length || t2.some(function(t3, r2) {
      return t3 !== n[r2];
    });
  }
  function D(n, t2) {
    return "function" == typeof t2 ? t2(n) : t2;
  }
  function ProgressBar({ percent }) {
    const id = g();
    _(() => {
      document.getElementById(id).style.width = `${percent.current / Math.max(percent.total, 1) * 100}%`;
    }, [percent]);
    return /* @__PURE__ */ u$1("div", { class: "progress-div", children: [
      /* @__PURE__ */ u$1("div", { className: "bar-container", children: /* @__PURE__ */ u$1("div", { id }) }),
      /* @__PURE__ */ u$1("p", { children: [
        "当前上传进度: ",
        getFileSize(percent.current),
        "/",
        getFileSize(percent.total)
      ] })
    ] });
  }
  function FileDialog({ open = true }) {
    const id = g();
    function close() {
      const dialog = document.getElementById(id);
      if (dialog) {
        dialog.close();
        dialog.style.display = "none";
      }
    }
    _(() => {
      const dialog = document.getElementById(id);
      if (open && dialog) {
        dialog.style.display = "flex";
        dialog.showModal();
      } else {
        close();
      }
    }, [open]);
    return open && /* @__PURE__ */ u$1("dialog", { id, style: {
      display: "none"
    }, children: [
      /* @__PURE__ */ u$1("h2", { children: "上传成功!" }),
      /* @__PURE__ */ u$1("a", { href: MIX_API.url, target: "__blank", children: [
        "文件地址: ",
        /* @__PURE__ */ u$1("span", { children: MIX_API.url })
      ] }),
      /* @__PURE__ */ u$1("div", { children: [
        /* @__PURE__ */ u$1("button", { className: "p-button", onClick: () => {
          MIX_API.url = "";
          close();
        }, children: "关闭" }),
        /* @__PURE__ */ u$1("button", { className: "p-button", onClick: async () => {
          await navigator.clipboard.writeText(url);
        }, children: "复制地址" })
      ] })
    ] });
  }
  async function startUploadFile(file) {
    try {
      const result = await upload115(file);
      MIX_API.url = result;
    } catch (e2) {
      if (e2.message === "canceled") return;
      alert(`上传失败,发生错误: ${e2.message}`);
    } finally {
      MIX_API.abort = null;
    }
  }
  function App() {
    const fileInputId = g();
    const [percent, setPercent] = p({
      total: 0,
      current: 0
    });
    return /* @__PURE__ */ u$1("div", { className: "app-main", children: [
      percent.total > 0 && /* @__PURE__ */ u$1(ProgressBar, { percent }),
      /* @__PURE__ */ u$1("button", { onClick: () => {
        if (MIX_API.abort) {
          MIX_API.abort();
          return;
        }
        document.getElementById(fileInputId).click();
      }, className: "p-button", children: MIX_API.abort ? "取消上传" : "上传文件" }),
      /* @__PURE__ */ u$1("input", { type: "text", placeholder: "文件路径(不填则随机)", className: "p-input", onInput: (event) => {
        MIX_API.key = event.target.value.trim();
      } }),
      /* @__PURE__ */ u$1(FileDialog, { open: !!MIX_API.url }),
      /* @__PURE__ */ u$1("input", { type: "file", onChange: async (event) => {
        const file = event.target.files[0];
        event.target.value = "";
        MIX_API.progress = (total, current) => {
          setPercent({
            total,
            current
          });
        };
        await startUploadFile(file);
        setPercent({
          total: 0,
          current: 0
        });
      }, className: "file-input", id: fileInputId })
    ] });
  }
  preact.render(
    /* @__PURE__ */ u$1(App, {}),
    (() => {
      const app = document.createElement("div");
      app.classList.add("main-pan");
      const newDiv = document.createElement("div");
      newDiv.classList.add("main-div");
      const bodyChildren = document.body.childNodes;
      while (bodyChildren.length > 0) {
        newDiv.appendChild(bodyChildren[0]);
      }
      document.body.appendChild(newDiv);
      newDiv.prepend(app);
      return app;
    })()
  );

})(preact, axios);