Greasy Fork is available in English.

Bypass paywalls for scientific documents

Bypass paywalls for scientific documents by downloading them from sci-hub instead of paying something like 50 bucks for each paper. This script adds download buttons on Google Scholar, Scopus and Web Of Science, which lead to sci-hub.tw. In this way you can get free access to scientific papers even if you (or your university) can't afford their prices.

Installa questo script?
Script suggerito dall'autore

Potresti essere interessato/a anche a Sci-hub button

Installa questo script
  1. // ==UserScript==
  2. // @name Bypass paywalls for scientific documents
  3. // @namespace StephenP
  4. // @version 3.4.3.1
  5. // @description Bypass paywalls for scientific documents by downloading them from sci-hub instead of paying something like 50 bucks for each paper. This script adds download buttons on Google Scholar, Scopus and Web Of Science, which lead to sci-hub.tw. In this way you can get free access to scientific papers even if you (or your university) can't afford their prices.
  6. // @author StephenP
  7. // @include http://scholar.google.*/scholar?*
  8. // @match http://www.scopus.com/record/display.uri?*
  9. // @match http://apps.webofknowledge.com/full_record.do?*
  10. // @match http://apps.webofknowledge.com/InterService.do?*
  11. // @match http://apps.webofknowledge.com/CitedFullRecord.do?*
  12. // @include https://scholar.google.*/scholar?*
  13. // @match https://www.scopus.com/record/display.uri?*
  14. // @match https://www.scopus.com/*
  15. // @match https://apps.webofknowledge.com/full_record.do?*
  16. // @match https://apps.webofknowledge.com/InterService.do?*
  17. // @match https://apps.webofknowledge.com/CitedFullRecord.do?*
  18. // @contributionURL https://buymeacoffee.com/stephenp_greasyfork
  19. // Following permissions are necessary to keep the sci-hub domain updated: once a day, the script checks if Sci-Hub can be reached at the known domain:
  20. // if it can't be reached, the script retrieves the new domain (if it's been updated) from Sci-Hub's official VK account.
  21. // @grant GM.setValue
  22. // @grant GM.getValue
  23. // @grant GM.deleteValue
  24. // @grant GM.xmlHttpRequest
  25. // @connect vk.com
  26. // @connect *
  27. // "connect *" is used as Sci-hub's domain can change, and the script needs to check whatever it thinks is the sci-hub's domain to see if it's valid.
  28. // @license AGPL-3.0-or-later
  29. // ==/UserScript==
  30. /*
  31. Copyright (C) 2021 StephenP
  32.  
  33. This program is free software: you can redistribute it and/or modify
  34. it under the terms of the GNU Affero General Public License as
  35. published by the Free Software Foundation, either version 3 of the
  36. License, or (at your option) any later version.
  37.  
  38. This program is distributed in the hope that it will be useful,
  39. but WITHOUT ANY WARRANTY; without even the implied warranty of
  40. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  41. GNU Affero General Public License for more details.
  42.  
  43. You should have received a copy of the GNU Affero General Public License
  44. along with this program. If not, see <https://www.gnu.org/licenses/>.
  45. */
  46. (async function(){
  47. var sciHubDomain=await getSciHubDomain();
  48. if(sciHubDomain.toString().split(".").length>=2){//the last check, to verify if the result of getSciHubDomain is actually a web domain.
  49. start(sciHubDomain);
  50. }
  51. else{
  52. start("https://sci-hub.ru/");//fallback to default domain
  53. }
  54. })();
  55. async function getSciHubDomain(){
  56. var url=await GM.getValue("scihubDomain", "none");
  57. let date=new Date();
  58. const tsNow=date.getDate().toString()+"/"+date.getMonth().toString()+"/"+date.getFullYear().toString();
  59. var tsOld=await GM.getValue("lastSync", false);
  60. if((url==="none")||(tsNow!==tsOld)){
  61. if(!(await isSciHubReachable(url))){
  62. var newUrl=await setSciHubDomain(url);
  63. if(!(await isSciHubReachable(newUrl))){
  64. console.log("%cOld sci-hub domain ("+url+") is not available and no new domain has been found", "color: red; background-color: white; font-size: 2em");
  65. GM.deleteValue("lastSync");
  66. return url;
  67. }
  68. else{
  69. let dateb=new Date();
  70. GM.setValue("lastSync",dateb.getDate().toString()+"/"+dateb.getMonth().toString()+"/"+dateb.getFullYear().toString());
  71. return newUrl;
  72. }
  73. }
  74. else{
  75. let datec=new Date();
  76. GM.setValue("lastSync",datec.getDate().toString()+"/"+datec.getMonth().toString()+"/"+datec.getFullYear().toString());
  77. return url;
  78. }
  79. }
  80. else{
  81. console.log("%cSci-hub domain has been already checked today and it was working. The script will keep using "+url, "color: green; background-color: white; font-size: 2em");
  82. return url;
  83. }
  84. }
  85. async function setSciHubDomain(oldUrl){
  86. return new Promise((resolve, reject) =>{
  87. console.log("%cRequesting new sci-hub domain from official sci-hub's vk account", "color: orange; background-color: white; font-size: 2em");
  88. GM.xmlHttpRequest({
  89. method: "GET",
  90. url: "https://vk.com/sci_hub",
  91. onload: function(response) {
  92. let parser = new DOMParser();
  93. let doc = parser.parseFromString(response.responseText, "text/html");
  94. var url="not available";
  95. var possibleLinks=doc.querySelectorAll(".group_info_row.info a");
  96. if(possibleLinks.length==1){
  97. url=possibleLinks[0].textContent;
  98. }
  99. else if(possibleLinks.length>1){
  100. url=doc.querySelector('.group_info_row.info a[href*="sci-hub"]').textContent;
  101. }
  102. if(!oldUrl.includes(url)){
  103. console.log("%cNew sci-hub domain has been retrieved: "+url, "color: green; background-color: white; font-size: 2em");
  104. GM.setValue("scihubDomain","https://"+url+"/");
  105. }
  106. resolve("https://"+url+"/");
  107. },
  108. onerror: function(response){
  109. resolve(oldUrl);
  110. }
  111. });
  112. });
  113. }
  114. async function isSciHubReachable(d){
  115. if(d==="none"){
  116. return false;
  117. }
  118. else{
  119. return new Promise((resolve, reject) =>{
  120. console.log("%cTesting if sci-hub can be reached", "color: orange; background-color: white; font-size: 2em");
  121. GM.xmlHttpRequest({
  122. method: "GET",
  123. url: d+"donate",
  124. onload: function(response) {
  125. if((response.responseText.includes("12PCbUDS4ho7vgSccmixKTHmq9qL2mdSns"))||(response.responseText.includes("bc1q7eqheemcu6xpgr42vl0ayel6wj087nxdfjfndf"))){//if it's not the original sci-hub page, it's most likely not to show the real bitcoin addresses for donations. This is not a failsafe method, as a fake page could display another address and keep the real ones hidden.
  126. console.log("%cSci-hub is available, no need to update the domain.", "color: green; background-color: white; font-size: 2em");
  127. resolve(true);
  128. }
  129. else{
  130. console.log("%cSci-hub domain available, but there isn't the sci-hub website there. I'll try to update the domain.", "color: orange; background-color: white; font-size: 2em");
  131. resolve(false);
  132. }
  133. },
  134. onerror: function(response) {
  135. console.log("%cSci-hub domain not available, I'll try to update the domain.", "color: orange; background-color: white; font-size: 2em");
  136. resolve(false);
  137. }
  138. });
  139. });
  140. }
  141. }
  142. function start(sciHubUrl) {
  143. 'use strict';
  144. console.log("%cCurrent Sci-Hub domain: "+sciHubUrl, "color: green; background-color: white; font-size: 2em");
  145. var documentId;
  146. var site=window.location.href.toString();
  147. var i;
  148. if(site.includes("://www.scopus.com/")){
  149. try{
  150. var fullDocument=document.createElement("LI");
  151. fullDocument.innerHTML="Full text from Sci-Hub";
  152. fullDocument.style.cursor="pointer";
  153. fullDocument.style.color="#ff6c00";
  154. console.log("::Bypass paywalls for scientific documents:: Obtaining document id...");
  155. documentId=document.getElementById("recordDOI").innerHTML;
  156. console.log("::Bypass paywalls for scientific documents:: Document id is "+documentId);
  157. fullDocument.addEventListener('click',function(){window.open(sciHubUrl+documentId)});
  158. console.log("::Bypass paywalls for scientific documents:: Finding a place where to put the Sci-Hub button...");
  159. document.getElementById('quickLinks').children[0].appendChild(fullDocument);
  160. console.log("::Bypass paywalls for scientific documents:: Sci-Hub button placed!");
  161. var donateBtn=document.createElement("LI");
  162. donateBtn.innerHTML="Donate to Sci-Hub";
  163. donateBtn.style.cursor="pointer";
  164. donateBtn.addEventListener('click',function(){donate(sciHubUrl)});
  165. console.log("::Bypass paywalls for scientific documents:: Finding a place where to put the donation button...");
  166. document.getElementById('quickLinks').children[0].appendChild(donateBtn);
  167. console.log("::Bypass paywalls for scientific documents:: Donation button placed!");
  168. }
  169. catch(err){
  170. console.log("::Bypass paywalls for scientific documents:: Error! "+err);
  171. }
  172. }
  173. else if(site.includes("://apps.webofknowledge.com/")){
  174. var mode;
  175. var genericID=document.getElementsByClassName("block-record-info block-record-info-source")[0].getElementsByClassName("FR_label");
  176. for(i=0;i<=genericID.length;i++){
  177. if((genericID[i].innerHTML==="DOI:")||(genericID[i].innerHTML==="PMID:")){
  178. documentId=genericID[i].parentNode.children[1].innerHTML;
  179. console.log(documentId);
  180. break;
  181. }
  182. }
  183. if(documentId!==undefined){
  184. addButtonWOS(sciHubUrl,documentId);
  185. }
  186. }
  187. else if(site.includes("://scholar.google.")){
  188. var resourcesList=document.getElementById('gs_res_ccl_mid');
  189. var results=resourcesList.children.length;
  190. var gs_ggs_gs_fl;
  191. for(i=0;i<results;i++){
  192. try{
  193. if(resourcesList.children[i].getElementsByClassName("gs_ggs gs_fl").length==0){
  194. gs_ggs_gs_fl=document.createElement("div");
  195. gs_ggs_gs_fl.setAttribute("class","gs_ggs gs_fl");
  196. gs_ggs_gs_fl.appendChild(document.createElement("div"));
  197. gs_ggs_gs_fl.children[0].setAttribute("class","gs_ggsd");
  198. gs_ggs_gs_fl.children[0].appendChild(document.createElement("div"));
  199. gs_ggs_gs_fl.children[0].children[0].setAttribute("class","gs_or_ggsm");
  200. resourcesList.children[i].insertBefore(gs_ggs_gs_fl,resourcesList.children[i].firstChild);
  201. addButtonScholar(sciHubUrl,resourcesList.children[i].firstChild);
  202. }
  203. else{
  204. addButtonScholar(sciHubUrl,resourcesList.children[i].firstChild);
  205. }
  206. }
  207. catch(err){
  208. console.error(err+"//"+resourcesList.children[i].lastElementChild.innerHTML);
  209. }
  210. }
  211. }
  212. }
  213. function addButtonWOS(sciHubUrl,documentId){
  214. try{
  215. var site=window.location.href.toString();
  216. const fTBtn=document.getElementsByClassName("solo_full_text")[0];
  217. var sciHubBtn = fTBtn.cloneNode(true);
  218. var list=document.getElementsByClassName("l-columns-item")[0];
  219. sciHubBtn.setAttribute("alt","Break the walls and free the knowledge that publishers taken hostage\!");
  220. sciHubBtn.setAttribute("title","Break the walls and free the knowledge that publishers taken hostage\!");
  221. sciHubBtn.setAttribute("id","sciHubBtn");
  222. sciHubBtn.getElementsByTagName('A')[0].innerHTML="Search on Sci-Hub";
  223. sciHubBtn.getElementsByTagName('A')[0].removeAttribute("href");
  224. sciHubBtn.getElementsByTagName('A')[0].removeAttribute("onclick");
  225. sciHubBtn.getElementsByTagName('A')[0].addEventListener("click",function(){window.open(sciHubUrl+documentId);});
  226. sciHubBtn.style.cursor="pointer";
  227. fTBtn.children[0].style.marginLeft="0";
  228. sciHubBtn.style.marginRight="0";
  229. list.insertAdjacentHTML('beforeend','<li><a style="font-size: 12px; margin-left: 10px; color: green; text-decoration: underline;" href="javascript:;">Donate to Sci-Hub project</a></li>');
  230. list.lastChild.lastChild.removeAttribute("href");
  231. list.lastChild.lastChild.addEventListener("click", function(){donate(sciHubUrl);});
  232. list.lastChild.lastChild.style.cursor="pointer";
  233. fTBtn.parentNode.insertBefore(sciHubBtn, fTBtn);
  234. //list.insertBefore(sciHubBtn,list.lastChild);
  235. }
  236. catch(err){
  237. console.log(err);
  238. }
  239. //setAttribute('onclick',donate(sciHubUrl));
  240. }
  241. function addButtonScholar(sciHubUrl,linkDiv){
  242. //alert(linkDiv.innerHTML);
  243. var link;
  244. try{
  245. link=linkDiv.getElementsByTagName("A")[0].href;
  246. }
  247. catch(err){
  248. link=linkDiv.parentNode.getElementsByClassName("gs_rt")[0].getElementsByTagName("A")[0].href;
  249. }
  250. if(link.includes("scholar?output")){
  251. link=linkDiv.parentNode.getElementsByClassName("gs_rt")[0].getElementsByTagName("A")[0].href;
  252. }
  253. if(link!=undefined){
  254. var creatingElement;
  255. if((link!=undefined)&&(link.search("patents.google")==-1)){
  256. creatingElement=document.createElement("a");
  257. creatingElement.innerHTML='<a>Search on Sci-Hub</a>';
  258. linkDiv.getElementsByClassName("gs_or_ggsm")[0].appendChild(creatingElement);
  259. linkDiv.getElementsByClassName("gs_or_ggsm")[0].lastChild.addEventListener("click", function(){window.open(sciHubUrl+link);});
  260. linkDiv.getElementsByClassName("gs_or_ggsm")[0].lastChild.style.cursor="pointer";
  261. //setAttribute("onclick",'window.open(\"'+sciHubUrl+link+'\");');
  262. }
  263. }
  264. document.head.innerHTML = document.head.innerHTML.replace(/13px 8px 9px 8px/g, '0px 8px 0px 8px');
  265. }
  266. function donate(sciHubUrl){
  267. window.open(sciHubUrl+'#donate');
  268. }