davidgogh / Download on Google Scholar

// ==UserScript==
// @name           Download on Google Scholar
// @namespace      https://openuserjs.org/users/davidgogh
// @match          https://scholar.google.com/*
// @grant          GM_xmlhttpRequest
// @version        1.2
// @author         davidgogh 
// @original-author clemente
// @license        MIT
// @description    Display a download button next to results
// @description:de Eine Download-Schaltfläche neben den Ergebnissen anzeigen
// @description:es Mostra un botón de descarga junto a los resultados
// @description:fr Ajoute un bouton de téléchargement à côté des résultats
// @description:it Visualizzare un pulsante per il download accanto ai risultati
// @icon           https://scholar.google.com/favicon.ico
// @connect        sci-hub.tw
// @inject-into    content
// @noframes
// @homepageURL    https://openuserjs.org/scripts/davidgogh/Download_on_Google_Scholar
// @supportURL     https://openuserjs.org/scripts/davidgogh/Download_on_Google_Scholar/issues
// ==/UserScript==

/* jshint esversion: 6 */

const SCI_HUB_DOMAIN = "sci-hub.tw";
const SCI_HUB_URL = `https://${SCI_HUB_DOMAIN}`;

function gm_fetch(url) {
  return new Promise((resolve, reject) => {
    GM_xmlhttpRequest({
      method: "GET",
      url: url,
      onload: function ({
        status,
        responseText
      }) {
        if (status < 200 && status >= 300) return reject();
        resolve(responseText);
      },
      onerror: function () {
        reject();
      },
    });
  });
}

async function getDownloadLink(link) {
  try {
    const scihubPageHtml = await gm_fetch(`${SCI_HUB_URL}/${link}`);
    const parser = new DOMParser();
    const scihubPageDocument = parser.parseFromString(scihubPageHtml, "text/html");
    const pdfDownloadLink = scihubPageDocument.querySelector(`a[onclick$="?download=true'"]`);
    const match = pdfDownloadLink.getAttribute("onclick").match(/^location\.href='(.*)'$/);
    const downloadLink = match[1];
    return downloadLink;
  }
  catch (e) {
    // If there is an error, the article is probably not available on Sci-Hub
    return null;
  }
}

function buildDownloadLink(node, downloadLink) {
  const link = document.createElement('a');
  link.textContent = `Download`;
  link.href = downloadLink;
  link.download = true;
  link.style = `color: orange`;

  return link;
}

function buildPreviewLink(node, downloadLink) {
  const previewLink = downloadLink.match(/(.*)\?download=true$/)[1];
  const link = document.createElement('a');
  link.textContent = `Preview`;
  link.href = previewLink;
  link.download = true;
  link.style = `color: green`;

  return link;
}

function addDownloadButtonOnResults() {
  document.querySelectorAll('.gs_r.gs_scl').forEach(async node => {
    const detectedLink = node.querySelector('.gs_rt a').href;
    const downloadLink = await getDownloadLink(detectedLink);

    if (!downloadLink) {
      return;
    }

    const link = buildDownloadLink(node, downloadLink);
    const pLink = buildPreviewLink(node, downloadLink);
    node.querySelector('.gs_ri').querySelector('.gs_fl').prepend(pLink);
    node.querySelector('.gs_ri').querySelector('.gs_fl').prepend(link);
  });
}

addDownloadButtonOnResults();