Guest User

Untitled

a guest
Jul 21st, 2017
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name MAB file picker
  3. // @version 1.0
  4. // @match https://*.myairbridge.com/*
  5. // @run-at document-idle
  6. // ==/UserScript==
  7.  
  8. (function() {
  9. "use strict";
  10.  
  11. function main() {
  12.     "use strict";
  13.  
  14.     const api = (function() {
  15.         const crc32 = (function() {
  16.             const table = new Uint32Array(256);
  17.  
  18.             for (let i = 0; i < 256; ++i) {
  19.                 let crc = i;
  20.                 for (let j = 0; j < 8; ++j)
  21.                     crc = (crc & 1) ? 3988292384 ^ crc >>> 1 : crc >>> 1;
  22.                 table[i] = crc;
  23.             }
  24.  
  25.             return function crc32(s) {
  26.                 let crc = -1;
  27.                 for (let i = 0; i < s.length; ++i)
  28.                     crc = crc >>> 8 ^ table[(crc ^ s.charCodeAt(i)) & 255];
  29.                 return (crc ^ -1) >>> 0;
  30.             }
  31.         })();
  32.  
  33.         function request(path, action, data) {
  34.             const req = {
  35.                 r: JSON.stringify({
  36.                     action,
  37.                     lang: "en",  // unneeded
  38.                     data,
  39.                     token: ""    // unneeded
  40.                 }),
  41.                 p: "json",
  42.                 v: "2.0",
  43.                 s: ""  // unneeded
  44.             };
  45.             req.s = crc32(
  46.                 unescape(encodeURIComponent([req.r, req.p, req.v].join("|")))
  47.             ).toString(16);
  48.  
  49.             return $.post(path, req, undefined, "json");
  50.         }
  51.  
  52.         return {
  53.             getUploadDetail: (id) => request(
  54.                 "/api2/common/",
  55.                 "GetUploadDetail",
  56.                 {
  57.                     id,
  58.                     login_token: ""  // unneeded
  59.                 }
  60.             ),
  61.             createTicket: (upload, files) => request(
  62.                 "/download/api/",
  63.                 "CreateTicket",
  64.                 {
  65.                     files,
  66.                     src: 1,     // unneeded
  67.                     token: "",  // unneeded
  68.                     upload      // unneeded
  69.                 }
  70.             ),
  71.             createDownload: (content_id, channel, ticket) => request(
  72.                 "/download/api/",
  73.                 "createDownload",
  74.                 {
  75.                     channel,
  76.                     content_id,
  77.                     download_type: "file",
  78.                     login_token: "",       // unneeded
  79.                     source: "html5_beta",  // unneeded
  80.                     ticket
  81.                 }
  82.             ),
  83.             createDownloadPackage: (content_id, files, ticket) => request(
  84.                 "/download/api/",
  85.                 "CreateDownloadPackage",
  86.                 {
  87.                     content_id,
  88.                     files,
  89.                     login_token: "",       // unneeded
  90.                     source: "html5_beta",  // unneeded
  91.                     ticket
  92.                 }
  93.             )
  94.         };
  95.     })();
  96.  
  97.     api.getUploadDetail(
  98.         window.location.href.match(/\/link\/([^/]+)/)[1]
  99.     ).then(({data: {id, channel, files}}) => {
  100.         document.head.insertAdjacentHTML(
  101.             "beforeend",
  102.             `<style type="text/css">
  103.                 .base_download > .button:not(.dlbutton) {
  104.                     display: none !important;
  105.                 }
  106.             </style>`
  107.         );
  108.  
  109.         const selected = new Set();
  110.  
  111.         if (files.length > 1) {
  112.             document.head.insertAdjacentHTML(
  113.                 "beforeend",
  114.                 `<style type="text/css">
  115.                     .file > .name {
  116.                         cursor: pointer !important;
  117.                     }
  118.                     .file.selected,
  119.                     .file.selected > .name > .fade {
  120.                         background: #f5f5f5 !important;
  121.                     }
  122.                     .file.selected > .name,
  123.                     .file.selected > .control {
  124.                         color: #359bce !important;
  125.                         font-weight: bold !important;
  126.                     }
  127.                 </style>`
  128.             );
  129.  
  130.             $(".base_download > .files").on("click", ".file", (e) => {
  131.                 const el = $(e.currentTarget);
  132.                 const file_id = files[el.index()].id;
  133.                 if (!el.hasClass("selected")) {
  134.                     el.addClass("selected");
  135.                     selected.add(file_id);
  136.                 } else {
  137.                     el.removeClass("selected");
  138.                     selected.delete(file_id);
  139.                 }
  140.             });
  141.         }
  142.  
  143.         const button = $("<a class=\"button dlbutton\">Download</a>");
  144.         button.on("click", () => {
  145.             const ids = (selected.size === 0) ? files.map((f) => f.id)
  146.                                               : [...selected];
  147.             api.createTicket(id, ids).then(({data: {ticket}}) => {
  148.                 const dl = (ids.length > 1) ? api.createDownloadPackage(id, ids, ticket)
  149.                                             : api.createDownload(ids[0], channel, ticket);
  150.                 dl.then(({data: {link}}) => window.location.assign(link));
  151.             });
  152.         });
  153.         $(".base_download > .button").first().before(button);
  154.     });
  155. }
  156.  
  157. function inject(fn) {
  158.     const script = document.createElement("script");
  159.     script.type = "text/javascript";
  160.     script.textContent = "(" + fn.toString() + ")();";
  161.     document.documentElement.appendChild(script);
  162.     document.documentElement.removeChild(script);
  163. }
  164.  
  165. // Wait for a download button to become visible before injecting (to ensure that
  166. // the page is fully constructed and the upload is complete, etc).
  167. (new MutationObserver((ms, ob) => {
  168.     const isDownloadButton = (el) => (
  169.         el.nodeType === 1 &&
  170.         el.classList.contains("button") &&
  171.         /^Download/.test(el.textContent) &&
  172.         el.style.display === "inline-block"
  173.     );
  174.  
  175.     for (let i = 0; i < ms.length; ++i) {
  176.         if (isDownloadButton(ms[i].target)) {
  177.             ob.disconnect();
  178.             inject(main);
  179.             return;
  180.         }
  181.     }
  182. })).observe(
  183.     document.body,
  184.     {subtree: true, attributes: true, attributeFilter: ["style"]}
  185. );
  186.  
  187. })();
Add Comment
Please, Sign In to add comment