// ==UserScript== // @name 仓库用度盘投稿助手 // @namespace moe.jixun.dupan.galacg // @version 1.1.11 // @description 简易功能增强, 方便仓库投稿用 // @author Jixun // @include http://pan.baidu.com/disk/home* // @include http://yun.baidu.com/disk/home* // @include https://pan.baidu.com/disk/home* // @include https://yun.baidu.com/disk/home* // 因为需要抢在页面脚本执行之前, 因此必须申请一个权限。 // TamperMonkey 测试通过, GreaseMonkey 未知. // @grant unsafeWindow // @run-at document-start // The following thrid party scripts were injected to the page: // https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js // @downloadURL none // ==/UserScript== var INFO = '[仓库助手]'; var oRequire; if (window.require) { console.warn("%s 覆盖方式安装,若无效请刷新。", INFO); oRequire = window.require; window.require = fakeRequire; } else { console.info("%s 钩子方式安装,若失效请报告。", INFO); Object.defineProperty(window, 'require', { set: function (require) { oRequire = require; }, get: function () { return fakeRequire; } }); } var __AppId = 250528; function _ (fn) { return fn.toString().match(/\/\*([\s\S]+)\*\//)[1]; } function sprintf () { var arg = arguments, len = arg.length - 1, inp = arg[0]; if (len < 1) return; for (var i=len; i>0; i--) { inp = inp.replace (new RegExp('(\\$|%)'+i,'g'), arg[i]); } return inp; } function fakeRequire (module) { // console.info('%s Load module: %s', INFO, module); if (module == 'disk-system:widget/pageModule/list/listMenu.js') { if (!_G.injected) { initScript(); _G.injected = true; } } else if (module == 'system-core:pluginControl/register/register.js') { if (!_G.btnInjected) { registerPlugin(); _G.btnInjected = true; } } return oRequire.apply(this, arguments); } function appendAfter (list, name, item, noPush) { for (var i = 0; i < list.length; i++) { if (list[i] instanceof Array) { if (appendAfter(list[i], name, item, true)) { return ; } } else if (list[i].title === name) { i++; list.splice(i, i, item); return true; } } if (!noPush) list.push(item); } var _G = {}; function initScript () { // Load module _G.FaceData = oRequire('system-core:data/faceData.js'); _G.ListInit = oRequire("disk-system:widget/pageModule/list/listInit.js"); var fileCtxMenu = _G.FaceData.getData().contextMenu.file; appendAfter(fileCtxMenu, '分享', { index: 8, keyboard: 'u', title: '自定义分享', display: isFileChecked, action: lazyDialog('loadCustomShareDialog') }); fileCtxMenu.push({ index: 2, // '删除' 的 index。 keyboard: 'r', position: 'bottom', title: '批量重命名', display: isFileChecked, action: lazyDialog('loadBatchRenameDialog') }); setTimeout(delayLoad, 200); delayLoadDuCode(); // ESC 将关闭所有漂浮窗口 document.addEventListener('keyup', function(e) { if (e.keyCode == 0x1b) { $('.dialog-close').click(); } }, false); } function registerPlugin () { define('function-widget:jixun/standard-code.js', function (require, exports, module) { exports.start = lazyDialog('loadStandardCodeDialog'); }); window.manifest.push ({ "name": "标准提取码插件", "group": "moe.jixun.code", "version": '1.0', "type": "1", "description": "类似于 115 的标准提取码", "filesType": "*", "buttons": [ { "index": 3, "disabled": "none", "title": "标准提取码", "buttonStyle": "normal", "pluginId": "JIXUNSTDCODE", "position": 'tools' } ], "preload": false, "depsFiles": [], "entranceFile": "function-widget:jixun/standard-code.js", "pluginId": "JIXUNSTDCODE" }); } function isFileChecked () { return _G.ListInit.getCheckedItems().length > 0; } function lazyDialog (name) { return function () { if (_G[name]) { _G[name](); } else { loadDependencies(); _G.Tip.show({ mode: 'loading', msg: '正在努力加载中 ...' }); } }; } function nextId () { if (!nextId.id) nextId.id = 0; return nextId.id++; } function confirmDialog (data) { loadDependencies(); var dialog; var dialogData = { id: "confirm-" + nextId(), show: true, title: data.title, body: $('
').append(data.body), buttons: [{ name: "confirm", title: data.sureText || "确定", type: "big", color: "blue", padding: ["50px", "50px"], click: function() { if ($.isFunction(data.onSure)) { data.onSure.apply(this, arguments); } else { dialog.hide(); } } }, { name: "cancel", title: data.cancelText || "取消", type: "big", padding: ["50px", "50px"], click: function() { if ($.isFunction(data.onCancel)) { data.onCancel.apply(this, arguments); } else { dialog.hide(); } } }] }; dialog = new _G.Dialog(dialogData); return dialog; } function delayLoad () { _G.loadCustomShareDialog = (function () { var _tplCustomShare = _(function () {/*

请输入提取码:

无效的提取码, 脚本将随机生成一个分享代码 :<

分享地址:

提取码:

投稿代码:

*/}); var dialog, $footer, $key, $tplCustomShare; function showDialog () { $tplCustomShare = $(_tplCustomShare); dialog = confirmDialog({ title: '自定义分享', body: $tplCustomShare, onSure: function () { handleConfirm(); dialog.hide(); }, onCancel: function () { dialog.hide(); }, }); $footer = dialog.$dialog.find(_G.Dialog.QUERY.dialogFooter); $key = $('#jx_shareKey', $tplCustomShare) .blur (function () { if (!isCodeValid(this.value = this.value.trim())) { $('#jx_errmsg', $tplCustomShare) .removeClass ('jx_hide'); } }) .focus (function () { $('#jx_errmsg', $tplCustomShare) .addClass ('jx_hide'); }) .val(genKey (4)); } function handleConfirm () { var key = $key.val(); if (!isCodeValid(key)) { key = genKey(4); $key.val(key); } _G.Tip.show({ mode: 'loading', msg: '正在分享,请稍后 ...', autoClose: false }); var sharedItems = _G.ListInit.getCheckedItems(); $.ajax ({ url: '/share/set?' + $.param({ channel: 'chunlei', bdstoken: this.token, app_id: __AppId }), type: 'POST', data: { fid_list: JSON.stringify(sharedItems.map(getFileId)), schannel: 4, channel_list: '[]', pwd: key }, dataType: 'json' }).success(function (r) { _G.Tip.hide(); _G.Tip.show({ mode: 'success', msg: '分享成功!' }); $footer.children('.g-button-blue-large').hide(); $footer.children('.g-button-large').find('.text').text('关闭'); $('#jx_shortUrl', $tplCustomShare).val (r.shorturl || '很抱歉, 分享失败 :<'); $('#jx_shareCode', $tplCustomShare).val (key); $tplCustomShare.toggleClass ('jx_hide'); var title = fixCode(sharedItems[0].server_filename) + (sharedItems.length == 1 ? '' : ' 等文件'); $('#jx_dlboxCode', $tplCustomShare).val ('[dlbox title="' + title + '" from="浩瀚的宇宙" time="' + makeDate(new Date()) + '" info="提取:' + key + '" link1="度娘|' + r.shorturl + '#' + key + '"][/dlbox]' ); dialog.show(); }).fail(function () { _G.Tip.hide(); _G.Tip.show({ mode: 'failure', msg: '网络错误,请稍后重试。' }); }); } /* 依赖函数表 */ function isCodeValid(code) { return encodeURIComponent(code).replace(/%[A-F\d]{2}/g, '-').length == 4; } function fixCode (code) { return code.replace(/"/g, '"').replace(/\]/g, ']'); } function fixWidthDigits (d) { return ('0' + d.toString()).slice(-2); } function makeDate (d) { return sprintf('%1.%2.%3', d.getFullYear (), fixWidthDigits(d.getMonth () + 1), fixWidthDigits(d.getDate ()) ); } function genKey (size) { // length => 26 + 10, 36 var keySet = 'abcdefghijklmnopqrstuvwxyz0123456789'; for (var i = (size || 4) | 0, r = ''; i--; ) r += keySet[0 | (Math.random() * 36)]; return r; } function getFileId (item) { return item.fs_id; } /* 收尾 */ return showDialog; })(); _G.loadBatchRenameDialog = (function () { var _tplConfirmRename = _(function () {/*

请输入新的命名规则 (自动储存):

:n 表示不带扩展名的文件名; :e 表示扩展名; :E 表示 .扩展名;
:d 表示一位随机数字; :c 表示一位随机字符; :t 表示当前时间戳

*/}); var dialog, $tplConfirmRename; function showDialog () { $tplConfirmRename = $(_tplConfirmRename); $('#jx_nameRule', $tplConfirmRename).val(localStorage.jxRenameRule || '[GalACG] :d:d:d:d:d:d:d:d:d:d:E'); dialog = confirmDialog({ title: '确认批量重命名', body: $tplConfirmRename, onSure: function () { handleConfirm(); dialog.hide(); }, onCancel: function () { dialog.hide(); }, }); } function handleConfirm () { // 储存批量重命名记录 var _nameRule = $('#jx_nameRule', $tplConfirmRename).val(); localStorage.jxRenameRule = _nameRule; var _flist = _G.ListInit.getCheckedItems().map(toReplacePayload); _G.Tip.show({ mode: 'loading', msg: '正在批量重命名,请稍后 ...', autoClose: false }); $.ajax ({ url: '/api/filemanager?' + $.param({ channel: 'chunlei', bdstoken: yunData.MYBDSTOKEN, app_id: __AppId, opera: 'rename' }), type: 'POST', data: { filelist: JSON.stringify(_flist) } }).success(function () { _G.Tip.hide(); _G.Message.trigger('system-refresh'); }).fail(function () { _G.Tip.hide(); _G.Tip.show({ mode: 'failure', msg: '批量重命名失败, 请稍后重试!' }); }); function toReplacePayload (item) { return { path: item.path, newname: _nameRule.replace(/:([cdeEn])/g, fixName.bind(item.server_filename)) }; } } /* 依赖函数表 */ function fixName (z, code) { switch (code) { case 'n': var name = this.match(/^(.+)\./); return name ? name [1] : this; case 'c': return String.fromCharCode(97 + Math.random() * 26); case 'd': return Math.random().toString().slice(3,4); case 't': return +new Date(); case 'e': var ext = this.match(/\.([^.]+)$/); return ext ? ext[1] : ''; case 'E': return this.match(/\.[^.]+$/) || ''; } } /* 收尾 */ return showDialog; })(); } function delayLoadDuCode () { var _amd = define.amd; delete define.amd; var libHandlebars = document.createElement('script'); libHandlebars.src = 'https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.js'; libHandlebars.onload = function () { define.amd = _amd; _G.loadStandardCodeDialog = delayLoadDuStdCode(); }; document.head.appendChild(libHandlebars); function delayLoadDuStdCode () { Handlebars.registerHelper('size', parseSize); var _tplEncodeFiles = Handlebars.compile(_(function () {/* {{#each files}}
  • {{ name }} ({{size size}})
  • {{/each}} */})); var _tplStandardCode = _(function () {/*

    扩展阅读: 肚娘代码说明 [游侠] | 标准度娘提取码 [梦姬]

    文件列表 (版本: --):

      无效的提取码! 请确保您输入的神秘代码无误。

      */}); var dialog, $tplStandardCode, codeInfo, jx_list, jx_code, jx_errmsg, jx_version; var failed = 0; function showDialog () { $tplStandardCode = $(_tplStandardCode); dialog = confirmDialog({ title: '通用提取码', body: $tplStandardCode, onSure: function () { handleConfirm(); dialog.hide(); }, onCancel: function () { dialog.hide(); }, }); jx_list = $('.jx_list', $tplStandardCode); jx_code = $('.jx_code', $tplStandardCode); jx_errmsg = $('.jx_errmsg', $tplStandardCode); jx_version = $('.jx_version', $tplStandardCode); jx_code.blur(function () { var code = jx_code.val(); codeInfo = DuParser.parse(code); jx_errmsg.toggleClass('jx_hide', !code || !!codeInfo); if (codeInfo) { jx_version.text(codeInfo.ver); jx_list.html(_tplEncodeFiles({ files: codeInfo })); } else { jx_version.text('--'); } }).focus(function () { jx_errmsg.addClass('jx_hide'); jx_list.text(''); jx_version.text('--'); }); } var _curDir; function handleConfirm () { _curDir = _G.ListInit.currentKey; if (_curDir.slice(-1) != '/') _curDir += '/'; saveFile(0); } function saveFile (i) { if (i >= codeInfo.length) { _G.Tip.show({ mode: 'success', msg: sprintf('转存完毕 (失败 %1 个)!', failed) }); _G.Message.trigger('system-refresh'); return ; } _G.Tip.show({ mode: 'loading', msg: sprintf('正在转存文件 (%1/%2), 请稍后 ..', i + 1, codeInfo.length), autoClose: false }); var file = codeInfo[i]; $.ajax ({ url: '/api/rapidupload', type: 'POST', data: { path: _curDir + file.name, 'content-md5': file.md5, 'slice-md5': file.md5s, 'content-length': file.size } }).success(function (r) { _G.Tip.hide(); if (r.errno) failed++; }).fail(function (r) { failed++; }).always(function () { saveFile(i + 1); }); } /* 依赖函数表 */ function parseSize (size) { // 超过 GB if (size.length > 9) { size = size.slice(0,-7); return size.slice(0,-2) + '.' + size.slice(-2) + ' GB'; } return (parseInt(size) / 1024 / 1024).toFixed(2) + ' MB'; } /** * 一个简单的类似于 NodeJS Buffer 的实现. * 用于解析游侠度娘提取码。 * @param {SimpleBuffer} */ function SimpleBuffer (str) { this.fromString(str); } SimpleBuffer.toStdHex = function toStdHex (n) { return ('0' + n.toString(16)).slice(-2); }; SimpleBuffer.prototype.fromString = function fromString (str) { var len = str.length; this.buf = new Uint8Array(len); for (var i = 0; i < len; i++) { this.buf[i] = str.charCodeAt(i); } }; SimpleBuffer.prototype.readUnicode = function readUnicode(index, size) { if (size & 1) size ++; var bufText = Array.prototype.slice.call(this.buf, index, index + size).map(SimpleBuffer.toStdHex); var buf = ['']; for (var i = 0; i < size; i+=2) buf.push(bufText[i+1] + bufText[i]); return JSON.parse('"' + buf.join('\\u') + '"'); }; SimpleBuffer.prototype.readNumber = function readNumber (index, size) { var ret = 0; for (var i = index + size; i > index; ) ret = this.buf[--i] + (ret * 256); return ret; }; SimpleBuffer.prototype.readUInt = function readUInt (index) { return this.readNumber(index, 4); }; SimpleBuffer.prototype.readULong = function readULong (index) { return this.readNumber(index, 8); }; SimpleBuffer.prototype.readHex = function readHex (index, size) { return Array.prototype.slice.call(this.buf, index, index + size).map(SimpleBuffer.toStdHex).join(''); }; function DuParser () {} DuParser.parse = function generalDuCodeParse (szUrl) { var r; if (szUrl.indexOf('BDLINK') === 0) { r = DuParser.parseDu_v1(szUrl); r.ver = '游侠 v1'; } else { r = DuParser.parseDu_v2(szUrl); r.ver = '梦姬标准'; } return r; }; DuParser.parseDu_v1 = function parseDu_v1 (szUrl) { var raw = atob(szUrl.slice(6).replace(/\s/g, '')); if (raw.slice(0, 5) !== 'BDFS\x00') return null; var buf = new SimpleBuffer(raw); var ptr = 9; var arrFiles = []; var fileInfo, nameSize; var total = buf.readUInt(5); for (i = 0; i < total; i++) { // 大小 (8 bytes) // MD5 + MD5S (0x20) // nameSize (4 bytes) // Name (unicode) fileInfo = {}; fileInfo.size = buf.readULong(ptr + 0); fileInfo.md5 = buf.readHex(ptr + 8, 0x10); fileInfo.md5s = buf.readHex(ptr + 0x18, 0x10); nameSize = buf.readUInt(ptr + 0x28) << 1; fileInfo.nameSize = nameSize; ptr += 0x2C; fileInfo.name = buf.readUnicode(ptr, nameSize); arrFiles.push(fileInfo); ptr += nameSize; } return arrFiles; }; DuParser.parseDu_v2 = function parseDu_v2 (szUrl) { return szUrl.split('\n').map(function (z) { // unsigned long long: 0~18446744073709551615 return z.trim().match(/([\dA-F]{32})#([\dA-F]{32})#([\d]{1,20})#([\s\S]+)/); }).filter(function (z) { return z; }).map(function (info) { return { md5: info[1], md5s: info[2], size: info[3], name: info[4] }; }); }; /* 收尾 */ return showDialog; } } function loadDependencies () { _G.Message = oRequire("disk-system:widget/system/util/message.js"); _G.Tip = oRequire("system-core:system/uiService/tip/tip.js"); _G.Dialog = oRequire("system-core:system/uiService/dialog/dialog.js"); _G.Context = oRequire("system-core:context/context.js").instanceForSystem; _G.ui = _G.Context.ui; } // Inject style var style = document.createElement('style'); style.textContent = _(function () {/* .jx_btn { background: #fefefe; background: linear-gradient(to bottom, #fefefe 0%,#f2f2f2 88%); display: inline-block; line-height: 25px; vertical-align: middle; margin: 0 0 0 10px; text-decoration: none; border: 1px solid #AAA; padding: 0px 20px; height: 26px; border-radius: 2px; min-width: 3em; text-align: center; } .jx_btn, .jx_btn:hover, .jx_btn:focus { color: #666; } .jx_btn:active { color: #06C; background: #e3e3e3; background: -moz-linear-gradient(top, #e3e3e3 0%, #f7f7f7 12%); background: -webkit-linear-gradient(top, #e3e3e3 0%,#f7f7f7 12%); background: linear-gradient(to bottom, #e3e3e3 0%,#f7f7f7 12%); } .jx-input { margin: 9px 0; _margin: 7px 0; padding: 0 0 0 5px; width: 200px; height: 24px; vertical-align: middle; border: 1px solid #3b8cff; border: 1px solid rgba(58,140,255,.3); background: #fff; border-radius: 2px; } .jx_hide { display: none } .jx_c_warn { color: red } .jx_list { text-align: left; max-height: 3em; overflow-y: scroll; overflow-x: hidden; line-height: 1; padding: .2em; margin-bottom: .5em; } .jx_list .name { color: black; } .jx_list .size { color: #777; } textarea.jx{ width: 100%; min-height: 4em; } */}); document.head.appendChild(style);