From b23121c23c0ccc3756b687d12506dc853fe5a75a Mon Sep 17 00:00:00 2001 From: jc3213 Date: Mon, 16 Sep 2024 22:34:21 +0800 Subject: [PATCH] merged aria2.app into this repository --- i18n.js | 122 ++++++++++++++++++++++++++++ index.css | 137 +++++++++++++++++++++++++++++++ index.html | 232 +++++++++++++++++++++++++++++++++++++++++++++++++++++ index.js | 121 ++++++++++++++++++++++++++++ 4 files changed, 612 insertions(+) create mode 100644 i18n.js create mode 100644 index.css create mode 100644 index.html create mode 100644 index.js diff --git a/i18n.js b/i18n.js new file mode 100644 index 0000000..c2d5fea --- /dev/null +++ b/i18n.js @@ -0,0 +1,122 @@ +var i18n; +var i18nUser = document.querySelector('#aria2_i18n'); +var i18nCss = document.createElement('style'); +var languages = { + en: { + manager_title: 'Aria2 Task Manager', + common_default: 'Default', + common_disabled: 'Disabled', + common_save: 'Save', + time_day: 'd', + time_hour: 'h', + time_minute: 'm', + time_minute_full: 'Minute', + time_second: 's', + popup_newdld: 'New DL', + popup_queue: 'Task Queue', + popup_purge: 'Purge', + popup_options: 'Options', + queue_active: 'Downloading', + queue_waiting: 'Wait in Queue', + queue_paused: 'Download Paused', + queue_complete: 'Completed', + queue_removed: 'Download Stopped', + queue_error: 'Error Occured', + popup_download: 'DL Speed', + popup_upload: 'UL Speed', + popup_active: 'Active', + popup_waiting: 'Waiting', + popup_stopped: 'Stopped', + task_submit: 'Submit', + task_referer: 'Referer', + task_entry: 'Download Urls', + task_base64: 'Upload', + task_download: 'Max Download Speed', + task_upload: 'Max Upload Speed', + task_proxy: 'Proxy Server', + task_save: 'Save', + task_files: 'Download Files', + task_urls: 'Download Urls', + aria2_adv_dir: 'Download Folder', + aria2_http_split: 'Download Sections', + aria2_http_size: 'Section Size', + aria2_max_connection: 'Max Connections per Server', + aria2_bt_ratio: 'Seeding Ratio', + aria2_bt_seed: 'Seeding Time', + aria2_bt_remove: 'Remove Unselected Files', + aria2_true: 'True', + aria2_false: 'False', + option_jsonrpc: 'JSON-RPC Server', + option_manager_interval: 'Refresh Interval' + }, + zh: { + manager_title: 'Aria2 任务管理器', + common_default: '默认', + common_disabled: '禁用', + common_save: '保存', + time_day: '日', + time_hour: '时', + time_minute: '分', + time_minute_full: '分', + time_second: '秒', + popup_newdld: '新下载', + popup_queue: '任务队列', + popup_purge: '清理', + popup_options: '选项', + queue_active: '正在下载', + queue_waiting: '等待队列', + queue_paused: '下载暂停', + queue_complete: '已经完成', + queue_removed: '下载停止', + queue_error: '发生错误', + popup_download: '下载速度', + popup_upload: '上传速度', + popup_active: '活跃', + popup_waiting: '等待', + popup_stopped: '停止', + task_submit: '确认', + task_referer: '引用页', + task_entry: '下载链接', + task_base64: '上传', + task_download: '最大下载速度', + task_upload: '最大上传速度', + task_proxy: '代理服务器', + task_save: '保存', + task_files: '下载文件', + task_urls: '下载链接', + aria2_adv_dir: '下载文件夹', + aria2_http_split: '多线程', + aria2_http_size: '线程容量', + aria2_max_connection: '每服务器最大连接数', + aria2_bt_ratio: '分享率', + aria2_bt_seed: '分享时间', + aria2_bt_remove: '删除未选定文件', + aria2_true: '是', + aria2_false: '否', + option_jsonrpc: 'JSON-RPC 服务器', + option_manager_interval: '更新间隔' + } +}; + +document.head.append(i18nCss); +i18nUser.addEventListener('change', (event) => i18nUserInterface(localStorage.locale = i18nUser.value)); +i18nUserInterface(i18nUser.value = localStorage.locale || navigator.language.slice(0, 2)); + +function i18nUserInterface(lang) { + i18n = languages[lang] ?? languages.en; + document.querySelectorAll('[i18n]').forEach((item) => { + item.textContent = i18n[item.getAttribute('i18n')]; + }); + i18nCss.innerText = `:root { + --download: "${i18n.popup_download}"; + --upload: "${i18n.popup_upload}"; + --active: "${i18n.popup_active}"; + --waiting: "${i18n.popup_waiting}"; + --stopped: "${i18n.popup_stopped}"; + --queue: "${i18n.popup_queue}"; + --day: "${i18n.time_day}"; + --hour: "${i18n.time_hour}"; + --minute: "${i18n.time_minute}"; + --second: "${i18n.time_second}"; + }`; +} diff --git a/index.css b/index.css new file mode 100644 index 0000000..a25d951 --- /dev/null +++ b/index.css @@ -0,0 +1,137 @@ +body { + width: 1280px; + margin: 8px auto; +} + +textarea { + padding: 3px; + width: calc(100% - 12px); + resize: none; + border-width: 1px; + border-style: inset; + overflow-y: auto; + overflow-x: hidden; +} + +body:not(.adduri) > #adduri, body:not(.setting) > #setting { + display: none; +} + +body > #menu, #adduri, #setting { + border-width: 1px; + border-style: solid; + position: fixed; + z-index: 999999; +} + +body > #menu { + border-width: 0px 1px 1px; + padding: 8px; + top: 0px; + width: 1262px; +} + +#choose, #adduri, #setting { + top: 56px; +} + +#choose { + left: calc(50% + 642px); +} + +#choose::before { + content: var(--queue); + display: block; + font-size: 18px; + font-weight: bold; + text-align: center; +} + +#adduri, #setting { + right: calc(50% - 640px); + width: 600px; + padding: 8px; +} + +#setting > :first-child { + margin-top: 0px; +} + +#aria2_ver { + padding: 4px; + margin-right: 3px; +} + +#aria2_ver::before { + content: "v"; +} + +#queue { + margin-top: 46px; +} + +.adduri [data-bid="download_btn"], .setting [data-bid="options_btn"] { + border-style: inset; +} + +.adduri [data-bid="download_btn"]:active, .setting [data-bid="options_btn"]:active { + border-style: outset; +} + +.jsonrpc, .entries { + display: grid; + grid-column-gap: 3px; +} + +.jsonrpc { + grid-template-columns: auto 1fr 1fr auto; +} + +.entries { + grid-template-columns: 1fr auto auto 0px; +} + +#adduri > :first-child { + margin: 0px 0px 5px; +} + +#stats { + margin-right: 150px; + grid-template-columns: repeat(2, 1fr) repeat(3, 15%); +} + +#stats > :nth-child(1)::before { + content: var(--download); +} + +#stats > :nth-child(2)::before { + content: var(--upload); +} + +#stats > :nth-child(3)::before { + content: var(--active); +} + +#stats > :nth-child(4)::before { + content: var(--waiting); +} + +#stats > :nth-child(5)::before { + content: var(--stopped); +} + +.day:not(:empty)::after { + content: var(--day); +} + +.hour:not(:empty)::after { + content: var(--hour); +} + +.minute:not(:empty)::after { + content: var(--minute); +} + +.second:not(:empty)::after { + content: var(--second); +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..6531fdc --- /dev/null +++ b/index.html @@ -0,0 +1,232 @@ + + + + + Aria2 Task Manager + + + + + + +
+
Downloading
+
Wait in Queue
+
Download Paused
+
Completed
+
Download Stopped
+
Error Occured
+
+
+
+

JSON-RPC Server

+
+ + + + +
+
+ + +
+
+
+

Referer

+
+ + + + +
+
+
+

Download Urls

+
+ +
+
+ + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
🖥️
+
⏲️
+
📦
+
📶️
+
+
+
+ + + +
+
+
+
+
+ + + + + + + + +
+

+
+ +
+
+

+
+ + +
+
+
+
+
+
+ + +
+
+
+
+
+ +
0
+
0
+
+
+ + + + + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..75290d3 --- /dev/null +++ b/index.js @@ -0,0 +1,121 @@ +var aria2Global = {}; +var changes = {}; +var config = {}; +var [setting, ...options] = document.querySelectorAll('#setting, #setting [name]'); +var [adduri, ...download]= document.querySelectorAll('#adduri, #adduri [name]'); +var [entry, uploader] = adduri.querySelectorAll('#entry, #uploader'); + +document.addEventListener('click', (event) => { + switch (event.target.id) { + case 'proxy_btn': + event.target.previousElementSibling.value = localStorage.aria2Proxy || ''; + break; + case 'enter_btn': + downloadSubmit(); + break; + case 'commit_btn': + managerOptionsSave(); + break; + } +}); + +downBtn.addEventListener('click', async (event) => { + manager.toggle('adduri'); + manager.remove('setting') +}); + +optionsBtn.addEventListener('click', (event) => { + manager.toggle('setting'); + manager.remove('adduri'); +}); + +document.getElementById('commit').addEventListener('click', (event) => { + options.forEach((entry) => { localStorage[entry.name] = config[entry.name] ?? entry.dataset.value; }); + if ('interval' in changes) { + clearInterval(aria2Alive); + aria2Interval = config.interval * 1000; + aria2Alive = setInterval(aria2ClientUpdate, aria2Interval); + } + if ('proxy' in changes) { + aria2Proxy = config.proxy; + } + if ('scheme' in changes) { + aria2RPC.method = config.scheme; + } + if ('secret' in changes) { + aria2RPC.secret = config.scheme; + } + if ('jsonrpc' in changes) { + aria2RPC.url = config.jsonrpc; + } + changes = {}; +}); + +async function downloadSubmit() { + var sessions = []; + var urls = entry.value.match(/(https?:\/\/|ftp:\/\/|magnet:\?)[^\s\n]+/g); + if (urls) { + urls.forEach((url) => sessions.push({url, options: aria2Global})); + aria2RPC.call(...sessions); + } + entry.value = ''; + manager.remove('adduri'); +} + +uploader.addEventListener('change', async (event) => { + var sessions = []; + await Promise.all([...event.target.files].map(async (file) => { + var type = file.name.slice(file.name.lastIndexOf('.') + 1); + var b64encode = await getFileData(file); + var download = type === 'torrent' ? {method: 'aria2.addTorrent', params: [b64encode, [], aria2Global]} : {method: 'aria2.addMetalink', params: [b64encode, aria2Global]}; + sessions.push(download); + })); + await aria2RPC.call(...sessions); + event.target.value = ''; + manager.remove('adduri'); +}); + +function getFileData(file) { + return new Promise((resolve) => { + var reader = new FileReader(); + reader.onload = (event) => { + var base64 = reader.result.slice(reader.result.indexOf(',') + 1); + resolve(base64); + }; + reader.readAsDataURL(file); + }); +} + +NodeList.prototype.disposition = function (json) { + return ParseOptions(this, json); +} + +setting.addEventListener('change', (event) => { + config[event.target.name] = changes[event.target.name] = event.target.value; +}); + +options.forEach((entry) => { + config[entry.name] = entry.value = localStorage[entry.name] ?? entry.dataset.value; +}); + +function ParseOptions(nodes, json) { + var result = {}; + nodes.forEach((node) => { + var value = json[node.name]; + if (value) { + node.value = result[node.name] = value; + } + }); + return result; +} + +(async function () { + aria2ClientSetup({jsonrpc: config.scheme + '://' + config.jsonrpc, secret: config.secret, interval: config.interval, proxy: config.proxy}); + var [global, version] = await aria2RPC.call({method: 'aria2.getGlobalOption'}, {method: 'aria2.getVersion'}); + var options = global.result; + options['min-split-size'] = getFileSize(options['min-split-size']); + options['max-download-limit'] = getFileSize(options['max-download-limit']); + options['max-upload-limit'] = getFileSize(options['max-upload-limit']); + aria2Global = ParseOptions(download, options); + document.querySelector('#aria2_ver').textContent = version.result.version; +})();