您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
0v0
当前为
// ==UserScript== // @name HKBUMoodle // @namespace http://nickdoth.cc/ // @version 0.2 // @description 0v0 // @require http://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js // @author nickdoth // @match https://buelearning.hkbu.edu.hk/course/view.php?id=* // @grant none // ==/UserScript== (function() { 'use strict'; const SERV = 'http://localhost:3832'; const WS_SERV = 'ws://localhost:3833'; const LOGO_BOOK = '<span title="This file will be opened from your device."> ?</span>'; const LOGO_MONITOR = '<span title="This file has been downloaded."> ✔️</span>'; const ON_OPEN_MSG = ` <img stlye="display:inline" src="${SERV}/ring.svg"/> Opening, plase wait...`; var ws = new WebSocket(WS_SERV); var rpcCall = createRpc(ws); var openFile = rpcCall('openFile'); var listFile = rpcCall('listFile'); var courseId = location.href.match(/\/course\/view\.php\?id=(\d+)/)[1]; console.log('CourseId:', courseId); var resourceLinks = $('a').filter((i, n) => !!isResourceLink(n)); resourceLinks.after(); resourceLinks.each((i, n) => { var alert = $('<span>').attr('class', 'res-alert'); $(n).after(alert); $(n).data('alert', alert); }); resourceLinks.after(LOGO_BOOK); // fetch(`${SERV}/ls/${courseId}`) listFile(courseId).then(files => { var saved = files.filter(n => (/^\d+/.test(n))) .map(n => /^(\d+)/.exec(n)[1]); console.log(saved); resourceLinks.filter((i, n) => saved.indexOf(isResourceLink(n)) >= 0).after(LOGO_MONITOR); }).catch(err => { console.log('Error: listFile:', err); }); $('body').click(function(ev) { var link = $(ev.target).parents('a')[0]; var bid = isResourceLink(link); if (!bid) return; ev.preventDefault(); var sessionId = getSession(); $(link).data('alert').html(ON_OPEN_MSG); // fetch(`${SERV}/open/${courseId}/${bid}?session=${sessionId}`) openFile(courseId, bid, sessionId) .process((hint) => { console.log('Downloading:', bid, hint); $(link).data('alert').html(ON_OPEN_MSG + `(Downloading ${hint})`); }) .then(info => { console.info(info); $(link).data('alert').text(''); }).catch((err) => { console.log('Error: openFile:', err); $(link).data('alert').text(' Open failed.'); }); }); function isResourceLink(target) { if (!target) return null; var r = /\/mod\/resource\/view\.php\?id=(\d+)/.exec(target.href); // console.log(r); if (!r) return null; return r[1]; } function getSession() { return document.cookie; } function createRpc(ws) { var callId = 1; var callings = {}; ws.onmessage = (msg) => { var ret = JSON.parse(msg.data); if (ret.processHint !== undefined && ret.processHint !== null) { callings[ret.id].process(ret.processHint); } else { var calling = callings[ret.id]; if (ret.err) calling.reject(ret.err); else calling.resolve(ret.retVal); } }; function waitConnectionAndSend(confirmSend) { if (ws.readyState === WebSocket.OPEN) { confirmSend(); } else if (ws.readyState === WebSocket.CONNECTING) { ws.addEventListener('open', () => { confirmSend(); ws.removeEventListener('open', confirmSend); }) } } return function rpcFuncBuilder(calleeName) { return function rpcCallFunction() { var args = Array.from(arguments); var promise = new Promise((resolve, reject) => { var id = ++callId; callings[id] = { resolve: resolve, reject: reject, process: (hint) => (promise._process && promise._process(hint)) }; waitConnectionAndSend(function confirmSend() { ws.send(JSON.stringify({ id: id, callee: calleeName, args: args })); }); }); promise.process = function(processCallback) { promise._process = processCallback; return promise; } return promise; } } } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址