/** * SPDX-License-Identifier: LicenseRef-GPL-3.0-or-later-WITH-js-exceptions * * Make files on drive.google.com downloadable without nonfree js * * Copyright (C) 2021 Wojtek Kosior <koszko@koszko.org> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * As additional permission under GNU GPL version 3 section 7, you * may distribute forms of that code without the copy of the GNU * GPL normally required by section 4, provided you include this * license notice and, in case of non-source distribution, a URL * through which recipients can access the Corresponding Source. * If you modify file(s) with this exception, you may extend this * exception to your version of the file(s), but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. * * As a special exception to the GPL, any HTML file which merely * makes function calls to this code, and for that purpose * includes it by reference shall be deemed a separate work for * copyright law purposes. If you modify this code, you may extend * this exception to your version of the code, but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * * I, Wojtek Kosior, thereby promise not to sue for violation of this file's * license. Although I request that you do not make use of this code in a * proprietary program, I am not going to enforce this in court. */ /* Use with: https://drive.google.com/file/d/** */ const og = {}; for (const node of document.head.childNodes) { if (node.tagName === "STYLE") { document.head.removeChild(node); continue; } if (node.tagName !== "META") continue; const match = /^og:(.+)/.exec(node.getAttribute("property")); if (!match) continue; og[match[1]] = node.getAttribute("content"); } const match = new RegExp("/file/d/([^/]+)").exec(document.URL); const file_id = match && match[1]; /* Extract file's mime type from script. */ let mime_type; for (const script of document.scripts) { const match = /itemJson\s*:\s*(\[.*\])\s*}\s*;$/.exec(script.textContent); if (!match) continue; let data; try { data = JSON.parse(match[1]); } catch(e) { console.log(e); continue; } if (/^[^\/]+\/[^\/]+$/.test(data[11])) mime_type = data[11]; } /* If file is folder, redirect to its page. */ const redirect = file_id && /^application\/vnd.google-apps.(folder|shortcut)$/.test(mime_type); if (redirect) window.location.href = `https://drive.google.com/drive/folders/${file_id}`; const download_link = file_id && `https://drive.google.com/uc?export=download&id=${file_id}`; const body = document.createElement("body"); const name_div = document.createElement("div"); const download_div = document.createElement("div"); const download_button = document.createElement("a"); const type_div = document.createElement("div"); const type_span = document.createElement("span"); const show_image_div = document.createElement("div"); const show_image_button = document.createElement("button"); const image = document.createElement("img"); let button_text = "download"; if (!og.title) button_text += " file"; else name_div.textContent = og.title; name_div.setAttribute("style", "font-weight: bold; display:inline-block;"); if (download_link) download_button.setAttribute("href", download_link); else button_text += " (unavailable)"; download_button.textContent = button_text; download_button.setAttribute("style", "border-radius: 5px; padding: 10px; color: black; background-color: lightgreen; text-decoration: none; box-shadow: -4px 8px 8px #888;"); download_div.appendChild(download_button); download_div.setAttribute("style", "padding: 10px; display: inline-block; margin: 0 0 10px;"); type_span.textContent = "type: "; type_span.setAttribute("style", "font-weight: bold; display:inline-block; white-space: pre;"); type_div.setAttribute("style", "margin: 0 0 10px;"); type_div.appendChild(type_span); if (mime_type || og.type) type_div.append(mime_type || og.type); function show_image() { const image = document.createElement("img"); image.setAttribute("src", og.image); image.setAttribute("width", og["image:width"]); image.setAttribute("height", og["image:height"]); image.setAttribute("style", "border: 1px solid #eee;"); document.body.replaceChild(image, show_image_div); } show_image_button.setAttribute("style", "border-radius: 5px; padding: 10px; color: black; background-color: lightgreen; box-shadow: -4px 8px 8px #888; font-family: inherit; font-size: inherit; border: none;"); show_image_button.textContent = "show image"; show_image_button.addEventListener("click", show_image); show_image_div.appendChild(show_image_button); body.setAttribute("style", "margin: 20px;"); if (og.title) body.appendChild(name_div); body.appendChild(download_div); if (og.type) body.appendChild(type_div); if (og.image && og["image:width"] && og["image:height"]) body.appendChild(show_image_div); if (!redirect) document.documentElement.replaceChild(body, document.body);