Files
ua-userscripts/scripts/publisher-uaproxy-banner/publisher-uaproxy-banner.user.js
T

129 lines
4.7 KiB
JavaScript

// ==UserScript==
// @name Algemeen: UA-proxy waarschuwing op uitgeverspagina's
// @namespace https://github.com/glgoose/ua-userscripts
// @version 1.0.0
// @description Rode balk op uitgeverspagina's als de UA-proxy uit staat, met een knop om te verbinden.
// @author glgoose
// @license GPL-3.0-or-later
// @homepageURL https://github.com/glgoose/ua-userscripts/tree/main/scripts/publisher-uaproxy-banner
// @supportURL https://github.com/glgoose/ua-userscripts/issues
// @match *://*.tandfonline.com/*
// @match *://*.taylorfrancis.com/*
// @match *://*.sagepub.com/*
// @match *://*.wiley.com/*
// @match *://*.oup.com/*
// @match *://*.sciencedirect.com/*
// @match *://*.elsevier.com/*
// @match *://*.cambridge.org/*
// @match *://*.jstor.org/*
// @match *://*.springer.com/*
// @match *://*.springernature.com/*
// @match *://*.nature.com/*
// @match *://*.degruyter.com/*
// @match *://*.degruyterbrill.com/*
// @match *://*.brill.com/*
// @match *://*.muse.jhu.edu/*
// @match *://*.journals.uchicago.edu/*
// @match *://*.annualreviews.org/*
// @match *://*.emerald.com/*
// @match *://*.direct.mit.edu/*
// @match *://*.psycnet.apa.org/*
// @match *://*.ingentaconnect.com/*
// @match *://*.bloomsburycollections.com/*
// @run-at document-idle
// @connect 127.0.0.1
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(function () {
'use strict';
var BASE = 'http://127.0.0.1:18088';
var POLL_MS = 3000;
// The token is not in the repo: the first click on Connect asks for it once and keeps it in
// Tampermonkey storage.
var token = GM_getValue('token', '');
var bar = null, text = null, btn = null, timer = null;
function request(method, path, cb) {
GM_xmlhttpRequest({
method: method,
url: BASE + path,
headers: method === 'POST' ? { 'X-UA-Token': token } : {},
timeout: 4000,
onload: function (r) {
var j = null;
try { j = JSON.parse(r.responseText); } catch (e) { /* not JSON */ }
cb(r.status, j);
},
onerror: function () { cb(0, null); },
ontimeout: function () { cb(0, null); },
});
}
// The bar is built once at its final size and never changes height or button width, so
// state changes only swap text (single line, truncated).
function build() {
bar = document.createElement('div');
text = document.createElement('span');
btn = document.createElement('button');
btn.textContent = 'Connect';
btn.style.cssText =
'margin-left:12px;min-width:96px;padding:2px 12px;border:1px solid #fff;border-radius:4px;' +
'background:transparent;color:#fff;font:inherit;font-weight:600;cursor:pointer';
btn.addEventListener('click', connect);
bar.append(text, btn);
bar.style.cssText =
'position:fixed;top:0;left:0;right:0;z-index:2147483647;padding:8px 16px;' +
'background:#b3261e;color:#fff;font:14px/1.4 -apple-system,system-ui,sans-serif;' +
'text-align:center;box-shadow:0 1px 4px rgba(0,0,0,.3);white-space:nowrap;overflow:hidden;' +
'text-overflow:ellipsis';
document.documentElement.appendChild(bar);
}
function render(s) {
var state = s && s.state;
if (state === 'up' || (s && s.on_ua && state === 'down')) { hide(); return; }
if (!bar) build();
var base = 'UA proxy down: this page loaded without UA access, so a Zotero save gets no PDF.';
if (!s) {
text.textContent = 'uaproxyd is not running: this page loaded without UA access.';
btn.disabled = true;
} else if (state === 'connecting') {
text.textContent = s.mfa ? 'Enter ' + s.mfa + ' in the Authenticator app.' : 'Connecting to the UA proxy.';
btn.disabled = true;
} else {
text.textContent = s.error ? base + ' ' + s.error : base;
btn.disabled = false;
}
btn.textContent = state === 'connecting' ? 'Connecting' : 'Connect';
}
function hide() {
if (bar) { bar.remove(); bar = null; }
if (timer) { clearInterval(timer); timer = null; }
}
function poll() {
request('GET', '/status', function (code, j) { render(code === 200 ? j : null); });
}
function connect() {
if (!token) {
token = (window.prompt('uaproxyd token (cat ~/.local/share/uaproxyd/token):') || '').trim();
if (!token) return;
GM_setValue('token', token);
}
btn.disabled = true;
request('POST', '/connect', function (code, j) {
if (code === 403) { token = ''; GM_setValue('token', ''); }
render(code === 202 ? j : null);
});
}
poll();
timer = setInterval(poll, POLL_MS);
})();