From a3f68f2ba77f218e434a352f04c22a681fe0bb27 Mon Sep 17 00:00:00 2001 From: liukai <659801@qq.com> Date: Tue, 13 Jun 2017 23:35:40 +0800 Subject: [PATCH] fix bug --- CHANGELOG.md | 17 +++ README.md | 39 ++++--- safari2aria.safariextension/Info.plist | 6 +- safari2aria.safariextension/js/endscript.js | 117 +++++--------------- safari2aria.safariextension/js/global.js | 92 +++++++++++++-- safari2aria.safariextz | Bin 205902 -> 205919 bytes 6 files changed, 153 insertions(+), 118 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..5793caa --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,17 @@ +### v1.2更新内容: +1. 优化代码结构,修复包含iframe页面下载重复问题 +2. 图片下载 + +### v1.1.2: +1. 增加自动更新 + +### v1.1: +1. 增加快捷键来切换默认rpc服务 (option+shift+[123456789]) +2. 增加快捷键展示当前默认rpc服务(option+shift+`) +3. 设置界面可以设置默认rpc服务 +4. 增加快捷键临时禁制拦截 (按着cmd点击链接) + +### v1.0: +1. 自动拦截指定后缀文件的下载事件并通过aria2c来下载该文件 +2. 可配置多个aria2c服务地址 +3. 右键链接后可选择指定aria2c服务进行下载) \ No newline at end of file diff --git a/README.md b/README.md index 600ec85..1479c92 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -# # safari2aria +# safari2aria + +用 aria2c 来替代你的 safari 默认下载 请搭配mac下的safari进行食用 -### v1.1.2更新内容: -增加自动更新 -### v1.1更新内容: -1. 增加快捷键来切换默认rpc服务 (option+shift+[123456789]) -2. 增加快捷键展示当前默认rpc服务(option+shift+`) -3. 设置界面可以设置默认rpc服务 -4. 增加快捷键临时禁制拦截 (按着cmd点击链接) - -### 暂时实现了一些基础功能: -1. 自动拦截指定后缀文件的下载事件并通过aria2c来下载该文件 -2. 可配置多个aria2c地址 -3. 右键链接后可选择指定aria2c服务进行下载 + +### 已有功能: +1. 拦截指定后缀文件下载 +2. 多aria2c服务支持 +3. 右键菜单指定aria2c服务 + +### 快捷键: +1. 切换默认rpc服务 (option+shift+[123456789]) +2. 展示当前默认rpc服务(option+shift+`) +3. 临时禁用或启用拦截(按着cmd点击链接) [下载链接](https://github.com/miniers/safari2aria/releases) @@ -25,8 +25,8 @@ ![image](https://user-images.githubusercontent.com/2039910/27039821-b4518ce6-4fc1-11e7-8dc2-a9b9c1621ae0.png) -### 已知问题: -1. 如果aria2c端没有配置ssl证书,则https网站的下载请求无法发送至aria2c +### 注意事项: +如果aria2c端没有配置ssl证书,则https网站的下载请求无法发送至aria2c 该问题为safari的安全策略,暂时没有思路修复 @@ -49,3 +49,12 @@ rpc-secure=true rpc-certificate=01 01 01 01 01 01 01 ``` +## 友情福利 + +鉴于有些用户没有申请域名或者证书,现提供一套自用ssl证书用以搭建本地aria2c https支持 +域名: aria2.zc.ci +解析: 127.0.0.1 +证书下载地址:[aria2.zc.ci.zip](https://github.com/miniers/safari2aria/files/1070942/aria2.zc.ci.zip) + +请参照注意事项在aria2c的配置文件中添加证书 + diff --git a/safari2aria.safariextension/Info.plist b/safari2aria.safariextension/Info.plist index 153ef7b..a544c28 100644 --- a/safari2aria.safariextension/Info.plist +++ b/safari2aria.safariextension/Info.plist @@ -13,9 +13,9 @@ CFBundleInfoDictionaryVersion 1.0 CFBundleShortVersionString - 1.1.2 + 1.2 CFBundleVersion - 1.1.2 + 1.2 Chrome Database Quota @@ -56,7 +56,7 @@ Update From Gallery Update Manifest URL - https://gist.githubusercontent.com/miniers/c62891753a2b9c05a154ea5d53efebee/raw/cdbfd3126f0b1120517039e6b15709b6fdd7b07d/update.plist + http://miniers.github.io/safari2aria/update.plist?t=1.1.3 Website https://github.com/miniers/safari2aria diff --git a/safari2aria.safariextension/js/endscript.js b/safari2aria.safariextension/js/endscript.js index 4973bf4..f5abdb5 100644 --- a/safari2aria.safariextension/js/endscript.js +++ b/safari2aria.safariextension/js/endscript.js @@ -1,56 +1,16 @@ -var ARIA2 = (function() { - var jsonrpc_version = '2.0'; - function get_auth(url) { - return url.match(/^(?:(?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(?:\/\/)?(?:([^:@]*(?::[^:@]*)?)?@)?/)[1]; - }; - - function request(jsonrpc_path, method, params,cb) { - var xhr = new XMLHttpRequest(); - var auth = get_auth(jsonrpc_path); - jsonrpc_path = jsonrpc_path.replace(/^((?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(\/\/)?(?:(?:[^:@]*(?::[^:@]*)?)?@)?(.*)/, '$1$2$3'); // auth string not allowed in url for firefox - - var request_obj = { - jsonrpc: jsonrpc_version, - method: method, - id: (new Date()).getTime().toString(), - }; - if (params) request_obj['params'] = params; - if (auth && auth.indexOf('token:') == 0) params.unshift(auth); - - xhr.open("POST", jsonrpc_path+"?tm="+(new Date()).getTime().toString(), true); - xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); - if (auth && auth.indexOf('token:') != 0) { - xhr.setRequestHeader("Authorization", "Basic "+btoa(auth)); - } - xhr.send(JSON.stringify(request_obj)); - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - if (xhr.status === 200) { - cb&&cb() - } else { - console.log('failed'); - cb&cb("err"); - } - } - } - }; - - return function(jsonrpc_path) { - this.jsonrpc_path = jsonrpc_path; - this.addUri = function (uri, options,cb) { - request(this.jsonrpc_path, 'aria2.addUri', [[uri, ], options],cb); - }; - return this; - } -})(); - - -safe_title = function safe_title(title) { - return title.replace(/[\\\|\:\*\"\?\<\>]/g, "_"); -}; function linkForTarget (e) { - return "BODY" === e.tagName ? null : e.href ? e.href : e.parentNode ? linkForTarget(e.parentNode) : void 0 + var result = null; + if ("BODY" === e.tagName) { + result = null + } else if (e.tagName === "IMG" && e.src) { + result = e.src + } else if (e.href) { + result = e.href + } else if (e.parentNode) { + result = linkForTarget(e.parentNode) + } + return result } function linksFromContainer (e) { @@ -88,33 +48,16 @@ function selectedLinks () { } return null } -function sendToAria2 (e) { - var aria = ARIA2(e[0]); - if (e[1]) { - aria.addUri(e[1], { - header: 'Cookie: ' + document.cookie - },function (err) { - if(err){ - miniToastr.error('添加到aria2失败') - }else{ - miniToastr.success('添加到aria2成功') - } - }); - } -} function handleMessage (e) { - if ("sendToAria2" === e.name && e.message[2] === document.location.href){ - sendToAria2(e.message); - } - if(e.name === "changeRpc"){ - miniToastr.success('成功切换默认下载服务至'+e.message); +if (e.name === "changeRpc") { + miniToastr.success('成功切换默认下载服务至' + e.message); } - if(e.name === "currentRpc"){ - miniToastr.success('当前下载服务为'+e.message); + if (e.name === "currentRpc") { + miniToastr.success('当前下载服务为' + e.message); } - if(e.name === "showMassage"){ - miniToastr[e.message.action](e.message.text); + if (e.name === "showMassage") { + miniToastr[e.message.action || "success"](e.message.text); } } @@ -129,38 +72,30 @@ function handleContextMenu (e) { //handle command key -document.onkeydown=function(event){ - var unicode=event.charCode ? event.charCode : event.keyCode; - if(unicode === 91) //chrome:COMMAND - { - isCommandKeyPressed = true; - } - keyPressed[unicode]=true; +document.onkeydown = function (event) { + var unicode = event.charCode ? event.charCode : event.keyCode; + keyPressed[unicode] = true; sendKeyPressEvent() }; -document.onkeyup=function (event){ - var unicode=event.charCode ? event.charCode : event.keyCode; - if(unicode === 91){ - isCommandKeyPressed = false; - } - keyPressed[unicode]=false; +document.onkeyup = function (event) { + var unicode = event.charCode ? event.charCode : event.keyCode; + keyPressed[unicode] = false; sendKeyPressEvent() }; function sendKeyPressEvent () { safari.self.tab.dispatchMessage("keyPress", { - keyPressed:keyPressed + keyPressed: keyPressed }); } -var isCommandKeyPressed,isShiftPressd; //cmd键是否被按压 -var keyPressed={}; -var rpcList=[]; +var keyPressed = {}; miniToastr.init({ appendTarget: document.body, timeout: 5000 }); +sendKeyPressEvent(); document.addEventListener("contextmenu", handleContextMenu, !1); safari.self.addEventListener("message", handleMessage, !1); \ No newline at end of file diff --git a/safari2aria.safariextension/js/global.js b/safari2aria.safariextension/js/global.js index 7844522..cdfe99a 100644 --- a/safari2aria.safariextension/js/global.js +++ b/safari2aria.safariextension/js/global.js @@ -1,3 +1,71 @@ +var ARIA2 = (function () { + var jsonrpc_version = '2.0'; + + function get_auth (url) { + return url.match(/^(?:(?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(?:\/\/)?(?:([^:@]*(?::[^:@]*)?)?@)?/)[1]; + } + + function request (jsonrpc_path, method, params, cb) { + var xhr = new XMLHttpRequest(); + var auth = get_auth(jsonrpc_path); + jsonrpc_path = jsonrpc_path.replace(/^((?![^:@]+:[^:@\/]*@)[^:\/?#.]+:)?(\/\/)?(?:(?:[^:@]*(?::[^:@]*)?)?@)?(.*)/, '$1$2$3'); // auth string not allowed in url for firefox + + var request_obj = { + jsonrpc: jsonrpc_version, + method: method, + id: (new Date()).getTime().toString(), + }; + if (params) request_obj['params'] = params; + if (auth && auth.indexOf('token:') == 0) params.unshift(auth); + + xhr.open("POST", jsonrpc_path + "?tm=" + (new Date()).getTime().toString(), true); + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); + if (auth && auth.indexOf('token:') != 0) { + xhr.setRequestHeader("Authorization", "Basic " + btoa(auth)); + } + xhr.send(JSON.stringify(request_obj)); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status === 200) { + cb && cb() + } else { + console.log('failed'); + cb & cb("err"); + } + } + } + } + + return function (jsonrpc_path) { + this.jsonrpc_path = jsonrpc_path; + this.addUri = function (uri, options, cb) { + request(this.jsonrpc_path, 'aria2.addUri', [[uri,], options], cb); + }; + return this; + } +})(); + +function sendToAria2 (e) { + var aria = ARIA2(e[0].url); + if (e[1]) { + aria.addUri(e[1], { + header: 'Cookie: ' + document.cookie + }, function (err) { + if (err) { + showToast("showMassage", { + action:'error', + text:['添加到',e[0].name,'失败'].join('') + }); + } else { + showToast("showMassage", { + action:'success', + text:['添加到',e[0].name,'成功'].join('') + }); + } + }); + } +} + function openPreferences (e) { "showOptions" === e.key && (safari.application.activeBrowserWindow.openTab().url = safari.extension.baseURI + "options.html", optionsEvent = e) } @@ -23,8 +91,11 @@ function messageHandler (e) { keyPressAction(e.message) } } +function showToast (type,msg) { + safari.application.activeBrowserWindow.activeTab.page.dispatchMessage(type, msg); +} function keyPressAction (keys) { - keyPressed = keys.keyPressed || {}; + var keyPressed = keys.keyPressed || {}; isCommandPressed = keyPressed[91]; isShiftPressd = keyPressed[16]; isOptionPressd = keyPressed[18]; @@ -36,22 +107,25 @@ function keyPressAction (keys) { name:'updateSafari2Aria', message:config }); - safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("changeRpc", rpcList[config.defaultRpcIndex].name); + showToast("changeRpc", rpcList[config.defaultRpcIndex].name); break; } } if(keyPressed[192]){ - safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("currentRpc", rpcList[config.defaultRpcIndex].name); + showToast("currentRpc", rpcList[config.defaultRpcIndex].name); } } } function handleCommand (e) { - var n = [e.command].concat(e.userInfo); - safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("sendToAria2", n) + var index = e.command.split('.')[1]; + var rpc = index&&rpcList[index]?rpcList[index]:rpcList[0]; + var n = [rpc].concat(e.userInfo); + sendToAria2(n) } function validateCommand (e) { - if ("DownloadWithAria2" === e.command) { + var match = e.command&&e.command.match(/^DownloadWithAria2/); + if (match&&match.length>=0) { var a = e.userInfo; (a && a.length && a[0]) || (e.target.disabled = !0) } @@ -63,11 +137,11 @@ function handleNavigation (e) { for (var n = 0; n < fileTypes.length; n++)if (a === fileTypes[n]) { e.preventDefault(); var t = [ - rpcList[config.defaultRpcIndex].url, + rpcList[config.defaultRpcIndex], e.url, e.target.url ]; - safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("sendToAria2", t); + sendToAria2(t); break } } @@ -75,7 +149,7 @@ function handleNavigation (e) { function handleContextMenu(event) { rpcList.forEach(function (rpc,index) { - event.contextMenu.appendContextMenuItem(rpc.url, ['下载至',rpc.name].join('')); + event.contextMenu.appendContextMenuItem(["DownloadWithAria2",index].join("."), ['下载至',rpc.name].join('')); }); } diff --git a/safari2aria.safariextz b/safari2aria.safariextz index 730055149ed6a8fe7fb54c3e2edf5ed119c5e8c7..5598d7563a7b0862921a5ba1affbf94f29d37c8e 100644 GIT binary patch delta 6336 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 CvQhB> delta 6398 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 M`~3m8`~3nCCavvqm;e9(