学人VIP

解锁图文

目前为 2022-11-29 提交的版本。查看 最新版本

// ==UserScript==
// @name         学人VIP
// @namespace    studyVIP.taozhiyu.gitee.io
// @version      0.3
// @description  解锁图文
// @author       涛之雨
// @match        *://gbr.businessreview.global/articles/view/*
// @match        *://www.businessreview.global/*
// @icon         https://gbr.businessreview.global/img/GBR-logo_black_50x50.png
// @require      https://cdn.bootcdn.net/ajax/libs/hls.js/1.0.8-0.canary.7807/hls.min.js
// @require      https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.19.0/js/md5.min.js
// @resource     jq https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.slim.min.js
// @require      https://cdn.jsdelivr.net/npm/@zip.js/[email protected]/dist/zip-full.min.js
// @antifeature  tracking ============================================>>>说明:我们仅会在经济学人文章阅读页面收集您使用本插件的情况,以帮助作者了解插件的用户数量。这个操作仅会收集您的IP地址信息,不包含您鼠标、键盘点击在内的所有操作,没有任何安全风险,不会产生性能损耗。为了保护您的知情权以及使用体验,特告知于您。本插件系开源脚本,所有代码均可查看源码,请您放心安装。 <<<============================================
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @grant        window.onurlchange
// @run-at       document-start
// @license      GPL3.0
// @homepage     https://greasyfork.org/zh-CN/scripts/441874
// ==/UserScript==
/*global Hls zip md5 $*/
/* jshint esversion: 11 */
(function() {
    'use strict';
    const addElement=(tag,args)=>{
        const dom=document.createElement(tag);
        for(const arg in args){
            dom[arg]=args[arg];
        }
        document.body.append(dom);
    },
          main=(url)=>{
              if(location.host==="www.businessreview.global"){
                  const path = (url?new URL(url):location).pathname.replace(/-/g,"_").split("/");
                  let targ=path.length===4?path[1]:"en_GB";
                  window.location.replace(`https://gbr.businessreview.global/articles/view/${path.slice(-1)+(targ==="en_GB"?'/en_GB/zh_CN':'/zh_CN/en_GB')}`);
                  return;
              }
              addElement('script', {
                  textContent:GM_getResourceText("jq")
              });
              const path = location.pathname.split("/"),lang = path[4];
              fetch('https://api.hummingbird.businessreview.global/api/article?id=' + path[3]).then(a=>a.json()).then(tao=>{
                  var script = document.createElement("script");
                  script.type = "text/javascript";
                  script.src = "//js.users.51.la/21234891.js";
                  document.body.appendChild(script);
                  const Dom=document.querySelector(".maincontent");
                  Dom.innerHTML='';
                  document.querySelectorAll(".store_btns,.cover").forEach(a=>a.remove());
                  tao.body.content.map(a=>{
                      switch (a.type) {
                          case "image":
                              for (const i of a.data) {
                                  if (i.lang === lang) {
                                      Dom.innerHTML+=`<figure><img src="https://businessreviewglobal-cdn.com/article_images/${path[3]}/${encodeURIComponent(i.image_path)}" alt="" class="img-responsive"><figcaption>&ZeroWidthSpace;</figcaption></figure>`;
                                      break;
                                  }
                              }
                              break;
                          case "paragraph":
                              for (const i of a.data) {
                                  if (i.lang === lang) {
                                      Dom.innerHTML+=`<p>${i.text}</p>`;
                                      break;
                                  }
                              }
                              break;
                          case "subtitle":
                              //似乎没什么用?
                              break;
                          case "video":
                              for (const i of a.data) {
                                  if (i.lang === lang) {
                                      const url=i.url;
                                      if(Hls.isSupported()) {
                                          const vid=btoa((Math.random()+"").slice(2)).substr(0,10);
                                          Dom.innerHTML+=`<video id=v_${vid} controls style="width: -webkit-fill-available;"></video>`;
                                          var video = document.getElementById(`v_${vid}`);
                                          var hls = new Hls();
                                          var m3u8Url = decodeURIComponent(url);
                                          hls.loadSource(m3u8Url);
                                          hls.attachMedia(video);
                                      }else Dom.innerHTML+=`<br><p>不支持hls播放器</p><br>`;
                                      break;
                                  }
                              }
                              break;
                          default:
                              console.log("未识别的类型",a);
                      }
                  });
                  const verifyZipPassword = async (file, password) => {
                      let reader, mp3blob = "";
                      try {
                          reader = new zip.ZipReader(new zip.BlobReader(file), { password });
                          const entries = await reader.getEntries();
                          try {
                              const audioBlob = await entries[0].getData(new zip.BlobWriter());
                              var newreader = new FileReader();
                              newreader.addEventListener("loadend", function(){
                                  const newAudioBlob=new Blob([newreader.result],{type: 'mp3'});
                                  mp3blob = URL.createObjectURL(audioBlob);
                                  $(".progress").hide();
                                  $("#TPlayer").show();
                                  document.querySelector('#TPlayer').src=mp3blob;
                              });
                              newreader.readAsArrayBuffer(audioBlob);
                          } catch (error) {
                              return { state: false, error };
                          }
                      } finally {
                          if(reader&&reader.close)await reader.close();
                      }
                      return {state: true,url:mp3blob};
                  };
                  const requestmp3=async (mp3zipurl)=>{
                      try{
                          const rep=await fetch(mp3zipurl).catch(a=>console.log('无音频'));
                          if (!rep) {
                              return;
                          }
                        $('body').append($('<div style="position:fixed;left:0px;width:97vw;padding-right:60px;bottom:3%;margin-bottom:-12px;height: 54px;display:flex;align-items:center;box-shadow: #00000066 3px 2px 10px 0px;border-radius: 90px;"><div class="progress progress-striped active" style="width: 100%;margin-bottom: unset;"><div class="progress-bar progress-bar-success"><span class="sr-only">0%</span></div></div><audio id="TPlayer" src="" controls style="width: 100%;display: none;"></audio></div>'));
                          let size = 0;
                          const body = rep.body,
                                len = rep.headers.get('Content-Length');
                          const reader = body.getReader();
                          const steam=await new ReadableStream({
                              start(controller) {
                                  return pump();
                                  function pump() {
                                      return reader.read().then(res => {
                                          const { done, value } = res;
                                          if (done) {
                                              controller.close();
                                              $(".progress-bar span").text('100%');
                                              return;
                                          }
                                          size += value.length || 0;
                                          var rate = (100 * size / Number(len)).toFixed(2) + "%";
                                          $(".progress-bar").width(rate);
                                          $(".progress-bar span").text(rate);
                                          controller.enqueue(value);
                                          return pump();
                                      });
                                  }
                              }
                          });
                          const blob=await (new Response(steam)),
                                a = await blob.blob();
                          verifyZipPassword(a, md5('2q09kj876$A&21786351+_))l;k98zTRWE%$#*&^'+mp3zipurl.split("/").pop()))
                              .then(a=>{
                              URL.revokeObjectURL(a);
                          })
                              .catch(err => console.error(err));
                      }catch(e){
                          console.log(e);
                      }
                  };
                  requestmp3("https://businessreviewglobal-cdn.com/"+tao.publication_date.substr(0,7)+'/audio/'+path[3]+'_mp3.zip');
              });
              if(document.referrer.match("www.businessreview.global")){
                  document.querySelector('.language_switcher a').onclick=function(e){
                      e.stopPropagation();
                      e.preventDefault();
                      window.location.replace(this.href);
                  };
              }
          },
          switchPage=(url)=>{
              GM_addStyle(`
@media (min-width: 60rem){
    div[class*='-page_wrapper__articlelist__'] {
        grid-column: 1/-1!important;
    }
}
div[class^='sticky-subscription_sticky-node'],
aside[class*='-page_wrapper__aside']{
    display:none!important;
}`);
              if(url.match(/www\.businessreview\.global(\/zh-CN)?\/(business|finance|technology|latest)\/|gbr\.businessreview\.global\/articles\/view/)){
                  main(url);
              }
          };
    if (window.onurlchange === null) {
        window.addEventListener('urlchange', ({url}) => switchPage(url));
    }
    switchPage(location.href);
})();