From f5079c7cd7f59d054f856f33af204a86483ba220 Mon Sep 17 00:00:00 2001 From: Pdboy Sir <63764630+sirpdboy@users.noreply.github.com> Date: Wed, 17 Jan 2024 02:07:09 +0800 Subject: [PATCH] restore aria2 1.36.0 --- aria2/Config.in | 83 ++ aria2/Makefile | 122 +++ aria2/files/aria2.conf | 23 + aria2/files/aria2.init | 363 ++++++++ ...s-unlock-connection-per-server-limit.patch | 29 + ...wnload-retry-on-slow-speed-and-reset.patch | 61 ++ ...tion-add-option-to-retry-on-http-4xx.patch | 239 +++++ ...isable-auto-added-Want-Digest-header.patch | 123 +++ luci-app-aria2/Makefile | 18 + luci-app-aria2/luasrc/controller/aria2.lua | 39 + .../luasrc/model/cbi/aria2/config.lua | 411 +++++++++ .../luasrc/model/cbi/aria2/files.lua | 41 + .../luasrc/view/aria2/log_template.htm | 71 ++ .../luasrc/view/aria2/settings_header.htm | 118 +++ .../luasrc/view/aria2/value_with_btn.htm | 22 + luci-app-aria2/po/zh-cn/aria2.po | 871 ++++++++++++++++++ .../root/etc/uci-defaults/40_luci-aria2 | 25 + 17 files changed, 2659 insertions(+) create mode 100644 aria2/Config.in create mode 100644 aria2/Makefile create mode 100644 aria2/files/aria2.conf create mode 100644 aria2/files/aria2.init create mode 100644 aria2/patches/0001-options-unlock-connection-per-server-limit.patch create mode 100644 aria2/patches/0002-download-retry-on-slow-speed-and-reset.patch create mode 100644 aria2/patches/0003-option-add-option-to-retry-on-http-4xx.patch create mode 100644 aria2/patches/0004-Disable-auto-added-Want-Digest-header.patch create mode 100644 luci-app-aria2/Makefile create mode 100644 luci-app-aria2/luasrc/controller/aria2.lua create mode 100644 luci-app-aria2/luasrc/model/cbi/aria2/config.lua create mode 100644 luci-app-aria2/luasrc/model/cbi/aria2/files.lua create mode 100644 luci-app-aria2/luasrc/view/aria2/log_template.htm create mode 100644 luci-app-aria2/luasrc/view/aria2/settings_header.htm create mode 100644 luci-app-aria2/luasrc/view/aria2/value_with_btn.htm create mode 100644 luci-app-aria2/po/zh-cn/aria2.po create mode 100644 luci-app-aria2/root/etc/uci-defaults/40_luci-aria2 diff --git a/aria2/Config.in b/aria2/Config.in new file mode 100644 index 0000000..23003c3 --- /dev/null +++ b/aria2/Config.in @@ -0,0 +1,83 @@ +menu "Aria2 Configuration" + depends on PACKAGE_aria2 + +choice + prompt "SSL Library" + default ARIA2_OPENSSL + +config ARIA2_OPENSSL + bool "OpenSSL" + +config ARIA2_GNUTLS + bool "GnuTLS" + +config ARIA2_NOSSL + bool "No SSL Support" + +endchoice + +choice + prompt "Crypto Library" + depends on !ARIA2_OPENSSL + default ARIA2_NOCRYPTO + +config ARIA2_NETTLE + bool "Nettle" + +config ARIA2_LIBGCRYPT + bool "Libgcrypt" + +config ARIA2_NOCRYPTO + bool "No Crypto Library" + +endchoice + +choice + prompt "XML Library" + default ARIA2_NOXML + +config ARIA2_LIBXML2 + bool "Libxml2" + +config ARIA2_EXPAT + bool "Expat" + +config ARIA2_NOXML + bool "No XML Library" + +endchoice + +config ARIA2_GMP + bool "GNU Multiple Precision Arithmetic Library" + depends on ARIA2_NETTLE + default n + +config ARIA2_BITTORRENT + bool "Enable Bittorrent Support" + depends on ARIA2_OPENSSL || ARIA2_LIBGCRYPT || \ + (ARIA2_NETTLE && ARIA2_GMP) + default y + +config ARIA2_METALINK + bool "Enable Metalink Support" + depends on !ARIA2_NOXML + default y + +config ARIA2_SFTP + bool "Enable SFTP Support" + default y + +config ARIA2_ASYNC_DNS + bool "Enable Async DNS Support" + default y + +config ARIA2_COOKIE + bool "Enable Firefox3/Chromium Cookie Support" + default y + +config ARIA2_WEBSOCKET + bool "Enable JSON-RPC over WebSocket Support" + depends on ARIA2_OPENSSL || ARIA2_LIBGCRYPT || ARIA2_NETTLE + default y + +endmenu diff --git a/aria2/Makefile b/aria2/Makefile new file mode 100644 index 0000000..2096a9e --- /dev/null +++ b/aria2/Makefile @@ -0,0 +1,122 @@ +# +# Copyright (C) 2012-2018 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=aria2 +PKG_VERSION:=1.36.0 +PKG_RELEASE:=21 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=https://github.com/aria2/aria2/releases/download/release-$(PKG_VERSION)/ +PKG_HASH:=skip +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +PKG_MAINTAINER:=Imre Kaloz , \ + Hsing-Wang Liao +PKG_LICENSE:=GPLv2 +PKG_LICENSE_FILES:=COPYING +PKG_CPE_ID:=cpe:/a:tatsuhiro_tsujikawa:aria2 + +PKG_CONFIG_DEPENDS := \ + CONFIG_ARIA2_NOSSL \ + CONFIG_ARIA2_OPENSSL \ + CONFIG_ARIA2_GNUTLS \ + CONFIG_ARIA2_NOCRYPTO \ + CONFIG_ARIA2_NETTLE \ + CONFIG_ARIA2_LIBGCRYPT \ + CONFIG_ARIA2_LIBXML2 \ + CONFIG_ARIA2_EXPAT \ + CONFIG_ARIA2_GMP \ + CONFIG_ARIA2_BITTORRENT \ + CONFIG_ARIA2_METALINK \ + CONFIG_ARIA2_SFTP \ + CONFIG_ARIA2_ASYNC_DNS \ + CONFIG_ARIA2_COOKIE \ + CONFIG_ARIA2_WEBSOCKET + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/aria2/config + source "$(SOURCE)/Config.in" +endef + +define Package/aria2 + SECTION:=net + CATEGORY:=Network + SUBMENU:=File Transfer + TITLE:=lightweight download utility + URL:=https://aria2.github.io/ + DEPENDS:=+zlib +libstdcpp +ARIA2_OPENSSL:libopenssl +ARIA2_GNUTLS:libgnutls \ + +ARIA2_NETTLE:libnettle +ARIA2_LIBGCRYPT:libgcrypt +ARIA2_GMP:libgmp \ + +ARIA2_LIBXML2:libxml2 +ARIA2_EXPAT:libexpat +ARIA2_SFTP:libssh2 \ + +ARIA2_ASYNC_DNS:libcares +ARIA2_COOKIE:libsqlite3 + USERID:=aria2=6800:aria2=6800 +endef + +define Package/aria2/description + aria2 is a lightweight multi-protocol & multi-source command-line download + utility +endef + +CONFIGURE_ARGS += \ + --disable-nls \ + $(if $(CONFIG_ARIA2_NOSSL),--disable,--enable)-ssl \ + $(if $(CONFIG_ARIA2_BITTORRENT),--enable,--disable)-bittorrent \ + $(if $(CONFIG_ARIA2_METALINK),--enable,--disable)-metalink \ + $(if $(CONFIG_ARIA2_WEBSOCKET),--enable,--disable)-websocket \ + $(if $(CONFIG_ARIA2_OPENSSL),--with,--without)-openssl \ + $(if $(CONFIG_ARIA2_GNUTLS),--with,--without)-gnutls \ + $(if $(CONFIG_ARIA2_NETTLE),--with,--without)-libnettle \ + $(if $(CONFIG_ARIA2_LIBGCRYPT),--with,--without)-libgcrypt \ + $(if $(CONFIG_ARIA2_GMP),--with,--without)-libgmp \ + $(if $(CONFIG_ARIA2_LIBXML2),--with,--without)-libxml2 \ + $(if $(CONFIG_ARIA2_EXPAT),--with,--without)-libexpat \ + $(if $(CONFIG_ARIA2_SFTP),--with,--without)-libssh2 \ + $(if $(CONFIG_ARIA2_ASYNC_DNS),--with,--without)-libcares \ + $(if $(CONFIG_ARIA2_COOKIE),--with,--without)-sqlite3 \ + --without-libuv \ + --with-libz + +TARGET_CXXFLAGS += -ffunction-sections -fdata-sections -flto +TARGET_LDFLAGS += -Wl,--gc-sections -flto + +define Package/aria2/conffiles +/etc/config/aria2 +endef + +define Download/aria2.conf + URL:=https://github.com/P3TERX/aria2.conf/archive + URL_FILE:=master.zip + FILE:=aria2.conf + HASH:=skip +endef + +define Build/Prepare + $(call Build/Prepare/Default) + unzip $(DL_DIR)/aria2.conf -d $(PKG_BUILD_DIR)/ + sed -i '/rpc-secret/d' $(PKG_BUILD_DIR)/aria2.conf-master/* +endef + + +define Package/aria2/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/aria2c $(1)/usr/bin + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/aria2.init $(1)/etc/init.d/aria2 + + $(INSTALL_DIR) $(1)/etc/config + $(INSTALL_CONF) ./files/aria2.conf $(1)/etc/config/aria2 + + $(INSTALL_DIR) $(1)/usr/share/aria2 + $(INSTALL_BIN) $(PKG_BUILD_DIR)/aria2.conf-master/* $(1)/usr/share/aria2/ +endef + +$(eval $(call Download,aria2.conf)) +$(eval $(call BuildPackage,aria2)) diff --git a/aria2/files/aria2.conf b/aria2/files/aria2.conf new file mode 100644 index 0000000..0181adc --- /dev/null +++ b/aria2/files/aria2.conf @@ -0,0 +1,23 @@ + +# You can use most aria2 command-line options, replace '-' with '_'. +# eg. 'rpc-secret' ==> 'rpc_secret' +# +# We do not support all options at this time. But you can add any option +# with 'list extra_settings'. +# +# You can also add new config sections to define multi instance. +# +config aria2 'main' + option enabled '0' + option user 'aria2' + option dir '/mnt/sda1/aria2' + option config_dir '/var/etc/aria2' + option bt_enable_lpd 'true' + option enable_dht 'true' + option follow_torrent 'true' + option file_allocation 'none' + option save_session_interval '30' + option split '128' + option min_split_size '100K' + option max_connection_per_server '128' + list extra_settings 'dht-file-path=/usr/share/aria2/dht.dat' diff --git a/aria2/files/aria2.init b/aria2/files/aria2.init new file mode 100644 index 0000000..d680570 --- /dev/null +++ b/aria2/files/aria2.init @@ -0,0 +1,363 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2016-2017 Hsing-wang Liao +# Licensed to the public under the Apache License 2.0. + +START=99 +USE_PROCD=1 + +NAME=aria2 +PROG=/usr/bin/aria2c + +_info() { + logger -p daemon.info -t "$NAME" "$*" +} + +_err() { + logger -p daemon.err -t "$NAME" "$*" +} + +_make_dir() { + local d + for d in "$@"; do + if [ ! -d "$d" ]; then + mkdir -p "$d" 2>/dev/null || return 1 + fi + done + + return 0 +} + +_create_file() { + touch "$@" 2>/dev/null +} + +_change_owner() { + local u="$1"; shift + + local d + for d in "$@"; do + if [ -f "$d" ]; then + chown "$u" "$d" 2>/dev/null || return 1 + elif [ -d "$d" ]; then + chown -R "$u" "$d" 2>/dev/null || return 1 + fi + done + + return 0 +} + +_change_file_mode() { + local mod="$1"; shift + chmod "$mod" "$@" 2>/dev/null +} + +_reset_dir_mode() { + local d + for d in "$@"; do + if [ -d "$d" ]; then + find "$d" -type d -exec chmod 755 {} \; 2>/dev/null + find "$d" -type f -exec chmod 644 {} \; 2>/dev/null + fi + done +} + +append_options() { + local o; local v + for o in "$@"; do + v="$(eval echo "\$$o")" + [ -n "$v" ] && \ + echo "${o//_/-}=$v" >>"$config_file_tmp" + done +} + +append_setting() { + local s="$1" + [ -n "$s" ] && \ + echo "$s" >>"$config_file_tmp" +} + +append_header() { + local h="$1" + [ -n "$h" ] && \ + echo "header=\"$h\"" >>"$config_file_tmp" +} + +aria2_validate() { + uci_load_validate "$NAME" aria2 "$1" "$2" \ + 'enabled:bool:0' \ + 'enable_logging:bool' \ + 'enable_proxy:bool' \ + 'config_dir:string:/var/etc/aria2' \ + 'user:string' \ + 'all_proxy:string' \ + 'all_proxy_passwd:string' \ + 'all_proxy_user:string' \ + 'auto_save_interval:range(0,600)' \ + 'bt_enable_lpd:or("true","false")' \ + 'bt_detach_seed_only:or("true","false")' \ + 'bt_load_saved_metadata:or("true","false")' \ + 'bt_prioritize_piece:string' \ + 'bt_max_open_files:uinteger' \ + 'bt_max_peers:uinteger' \ + 'bt_remove_unselected_file:or("true","false")' \ + 'bt_request_peer_speed_limit:string' \ + 'bt_save_metadata:or("true","false")' \ + 'bt_seed_unverified:or("true","false")' \ + 'bt_stop_timeout:uinteger' \ + 'bt_tracker:list(string)' \ + 'ca_certificate:file' \ + 'certificate:file' \ + 'check_certificate:or("true","false"):true' \ + 'check_integrity:or("true","false")' \ + 'connect_timeout:uinteger' \ + 'dht_listen_port:string' \ + 'dir:string' \ + 'disable_ipv6:or("true","false")' \ + 'disk_cache:string' \ + 'enable_dht:or("true","false"):true' \ + 'enable_dht6:or("true","false")' \ + 'enable_peer_exchange:or("true","false")' \ + 'event_poll:or("epoll","kqueue","port","poll","select")' \ + 'file_allocation:or("none","prealloc","trunc","falloc")' \ + 'follow_torrent:or("true","false","mem")' \ + 'force_save:or("true","false")' \ + 'http_accept_gzip:or("true","false")' \ + 'http_no_cache:or("true","false")' \ + 'listen_port:string' \ + 'log:string' \ + 'log_level:or("debug","info","notice","warn","error")' \ + 'lowest_speed_limit:string' \ + 'max_concurrent_downloads:uinteger' \ + 'max_connection_per_server:uinteger' \ + 'max_download_limit:string' \ + 'max_overall_download_limit:string' \ + 'max_overall_upload_limit:string' \ + 'max_tries:uinteger' \ + 'max_upload_limit:string' \ + 'min_split_size:string' \ + 'pause:or("true","false")' \ + 'pause_metadata:or("true","false")' \ + 'peer_id_prefix:string' \ + 'private_key:file' \ + 'retry_wait:uinteger' \ + 'rpc_auth_method:or("none","user_pass","token")' \ + 'rpc_certificate:file' \ + 'rpc_listen_port:range(1024,65535)' \ + 'rpc_passwd:string' \ + 'rpc_private_key:file' \ + 'rpc_secret:string' \ + 'rpc_secure:or("true","false")' \ + 'rpc_user:string' \ + 'save_session_interval:uinteger' \ + 'seed_ratio:ufloat' \ + 'seed_time:ufloat' \ + 'split:uinteger' \ + 'timeout:uinteger' \ + 'user_agent:string' +} + +aria2_start() { + local section="$1" + [ "$2" = "0" ] || { _err "Validation failed."; return 1; } + + [ "$enabled" = "1" ] || { _info "Instance \"$section\" disabled."; return 1; } + [ -n "$dir" ] || { _err "Please set download dir."; return 1; } + [ -d "$dir" ] || _make_dir "$dir" || { + _err "Can't create download dir: $dir" + return 1 + } + + config_file="$config_dir/$NAME.conf.$section" + config_file_tmp="$config_dir/$NAME.conf.tmp" + session_file="$config_dir/$NAME.session.$section" + + _make_dir "$config_dir" || { + _err "Can't create config dir: $config_dir" + return 1 + } + + _create_file "$session_file" "$config_file" "$config_file_tmp" || { + _err "Can't create files: $session_file, $config_file, $config_file_tmp" + return 1 + } + + # create tmp file + cat >"$config_file_tmp" <<-EOF + # Auto generated file, changes to this file will be lost. + EOF + + append_setting "dir=$dir" + append_setting "enable-rpc=true" + append_setting "rpc-allow-origin-all=true" + append_setting "rpc-listen-all=true" + append_setting "quiet=true" + append_setting "continue=true" + append_setting "input-file=$session_file" + append_setting "save-session=$session_file" + + if [ -z "$enable_logging" ]; then + append_options "log" "log_level" + elif [ "$enable_logging" = "1" ]; then + log=${log:-"/var/log/aria2.log"} + + local log_dir + log_dir="$(dirname "$log")" + + _make_dir "$log_dir" || { + _err "Can't create log dir: $log_dir" + return 1 + } + + # create or clear log file + echo >"$log" + + append_setting "log=$log" + append_options "log_level" + fi + + if [ -z "$enable_proxy" ] || [ "$enable_proxy" = "1" ]; then + append_options "all_proxy" "all_proxy_user" "all_proxy_passwd" + fi + + unset_auth_method() { + uci -q batch <<-EOF + set $NAME.$section.rpc_auth_method="" + commit $NAME + EOF + } + + if [ -z "$rpc_auth_method" ]; then + if [ -n "$rpc_secret" ]; then + append_setting "rpc-secret=$rpc_secret" + elif [ -n "$rpc_user" ]; then + append_setting "rpc-user=$rpc_user" + append_setting "rpc-passwd=$rpc_passwd" + else + _info "It is recommended to set RPC secret." + fi + elif [ "$rpc_auth_method" = "token" ]; then + if [ -n "$rpc_secret" ]; then + append_setting "rpc-secret=$rpc_secret" + else + unset_auth_method + fi + elif [ "$rpc_auth_method" = "user_pass" ]; then + if [ -n "$rpc_user" ]; then + append_setting "rpc-user=$rpc_user" + append_setting "rpc-passwd=$rpc_passwd" + else + _info "Please set RPC user." + unset_auth_method + fi + fi + + if [ ."$rpc_secure" = ."true" ] && [ -n "$rpc_certificate" ]; then + append_setting "rpc-secure=true" + append_options "rpc_certificate" "rpc_private_key" + fi + + if [ ."$check_certificate" = ."true" ]; then + append_setting "check-certificate=true" + append_options "ca_certificate" + elif [ ."$check_certificate" = ."false" ]; then + append_setting "check-certificate=false" + fi + + if [ ."$enable_dht" = ."true" ]; then + dht_file="$config_dir/dht.dat.$section" + _create_file "$dht_file" || { + _err "Can't create DHT file: $dht_file" + return 1 + } + + append_setting "enable-dht=true" + append_setting "dht-file-path=$dht_file" + fi + + if [ ."$enable_dht6" = ."true" ] && [ ."$disable_ipv6" != ."true" ]; then + dht6_file="$config_dir/dht6.dat.$section" + _create_file "$dht6_file" || { + _err "Can't create DHT6 file: $dht6_file" + return 1 + } + + append_setting "enable-dht6=true" + append_setting "dht-file-path6=$dht6_file" + fi + + if [ -n "$bt_tracker" ]; then + local bt_tracker_list; local t + for t in $bt_tracker; do + if [ -z "$bt_tracker_list" ]; then + bt_tracker_list="$t" + else + bt_tracker_list="$bt_tracker_list,$t" + fi + done + + append_setting "bt-tracker=$bt_tracker_list" + fi + + append_options "auto_save_interval" "bt_enable_lpd" "bt_max_open_files" "bt_max_peers" \ + "bt_remove_unselected_file" "bt_request_peer_speed_limit" "bt_prioritize_piece" \ + "bt_stop_timeout" "bt_detach_seed_only" "bt_save_metadata" "bt_load_saved_metadata" \ + "bt_seed_unverified" "certificate" "check_integrity" "connect_timeout" "dht_listen_port" \ + "disable_ipv6" "disk_cache" "enable_peer_exchange" "event_poll" "file_allocation" \ + "follow_torrent" "force_save" "http_accept_gzip" "http_no_cache" "listen_port" \ + "lowest_speed_limit" "max_concurrent_downloads" "max_connection_per_server" \ + "max_download_limit" "max_overall_download_limit" "max_overall_upload_limit" "max_tries" \ + "max_upload_limit" "min_split_size" "pause" "pause_metadata" "peer_id_prefix" "private_key" \ + "retry_wait" "rpc_listen_port" "save_session_interval" "seed_ratio" "seed_time" "split" "timeout" \ + "user_agent" + + config_list_foreach "$section" "header" append_header + config_list_foreach "$section" "extra_settings" append_setting + + cd /usr/share/aria2 && sh ./tracker.sh >/dev/null 2>&1 & + cat /usr/share/aria2/aria2.conf > "$config_file" + echo '' >> "$config_file" + sed '/^$/d' "$config_file_tmp" >> "$config_file" + rm -f "$config_file_tmp" + + _reset_dir_mode "$config_dir" + _change_file_mode 600 "$config_file" + + if [ -n "$user" ]; then + if ( user_exists "$user" && _change_owner "$user" "$config_dir" "$log" ); then + _info "Aria2 will run with user '$user'." + if [ "$user" != "root" ]; then + _info "Please make sure user '$user' has write access to download dir: $dir" + fi + else + _info "Setting run user to '$user' failed, default user will be used." + user= + fi + fi + + procd_open_instance "$NAME.$section" + procd_set_param command "$PROG" + procd_append_param command --conf-path="$config_file" + + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + + procd_set_param file "$config_file" + [ -n "$user" ] && \ + procd_set_param user "$user" + + procd_add_jail "$NAME.$section" log + procd_add_jail_mount "$ca_certificate" "$certificate" "$rpc_certificate" "$rpc_private_key" + procd_add_jail_mount_rw "$dir" "$config_dir" "$log" + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "$NAME" + procd_add_validation aria2_validate +} + +start_service() { + config_load "$NAME" + config_foreach aria2_validate "aria2" aria2_start +} diff --git a/aria2/patches/0001-options-unlock-connection-per-server-limit.patch b/aria2/patches/0001-options-unlock-connection-per-server-limit.patch new file mode 100644 index 0000000..65c2837 --- /dev/null +++ b/aria2/patches/0001-options-unlock-connection-per-server-limit.patch @@ -0,0 +1,29 @@ +--- /src/OptionHandlerFactory.cc 2018-05-15 20:33:25.000000000 +0800 ++++ /src/OptionHandlerFactory.cc 2018-07-05 10:40:25.000000000 +0800 +@@ -440,7 +440,7 @@ + { + OptionHandler* op(new NumberOptionHandler(PREF_MAX_CONNECTION_PER_SERVER, + TEXT_MAX_CONNECTION_PER_SERVER, +- "1", 1, 16, 'x')); ++ "64", 1, -1, 'x')); + op->addTag(TAG_BASIC); + op->addTag(TAG_FTP); + op->addTag(TAG_HTTP); +@@ -501,7 +501,7 @@ + } + { + OptionHandler* op(new UnitNumberOptionHandler( +- PREF_MIN_SPLIT_SIZE, TEXT_MIN_SPLIT_SIZE, "20M", 1_m, 1_g, 'k')); ++ PREF_MIN_SPLIT_SIZE, TEXT_MIN_SPLIT_SIZE, "1M", 1_k, 1_g, 'k')); + op->addTag(TAG_BASIC); + op->addTag(TAG_FTP); + op->addTag(TAG_HTTP); +@@ -905,7 +905,7 @@ std::vector OptionHandlerFactory::createOptionHandlers() + } + { + OptionHandler* op(new UnitNumberOptionHandler( +- PREF_PIECE_LENGTH, TEXT_PIECE_LENGTH, "1M", 1_m, 1_g)); ++ PREF_PIECE_LENGTH, TEXT_PIECE_LENGTH, "1M", 1_k, 1_g)); + op->addTag(TAG_ADVANCED); + op->addTag(TAG_FTP); + op->addTag(TAG_HTTP); diff --git a/aria2/patches/0002-download-retry-on-slow-speed-and-reset.patch b/aria2/patches/0002-download-retry-on-slow-speed-and-reset.patch new file mode 100644 index 0000000..68361cd --- /dev/null +++ b/aria2/patches/0002-download-retry-on-slow-speed-and-reset.patch @@ -0,0 +1,61 @@ +From 66524bee738e98742c908d93c993d0a78a2d9891 Mon Sep 17 00:00:00 2001 +From: myfreeer +Date: Sat, 18 Nov 2017 11:55:04 +0800 +Subject: [PATCH 3/4] download: retry on slow speed and conection close + +This would provide better speed on bad network conditions +--- + src/DownloadCommand.cc | 2 +- + src/SocketBuffer.cc | 3 ++- + src/SocketCore.cc | 2 +- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc +index 2db41e4..f49eb80 100644 +--- a/src/DownloadCommand.cc ++++ b/src/DownloadCommand.cc +@@ -306,7 +306,7 @@ void DownloadCommand::checkLowestDownloadSpeed() const + startupIdleTime_) { + int nowSpeed = peerStat_->calculateDownloadSpeed(); + if (nowSpeed <= lowestDownloadSpeedLimit_) { +- throw DL_ABORT_EX2(fmt(EX_TOO_SLOW_DOWNLOAD_SPEED, nowSpeed, ++ throw DL_RETRY_EX2(fmt(EX_TOO_SLOW_DOWNLOAD_SPEED, nowSpeed, + lowestDownloadSpeedLimit_, + getRequest()->getHost().c_str()), + error_code::TOO_SLOW_DOWNLOAD_SPEED); +diff --git a/src/SocketBuffer.cc b/src/SocketBuffer.cc +index 62862ff..1906173 100644 +--- a/src/SocketBuffer.cc ++++ b/src/SocketBuffer.cc +@@ -39,6 +39,7 @@ + + #include "SocketCore.h" + #include "DlAbortEx.h" ++#include "DlRetryEx.h" + #include "message.h" + #include "fmt.h" + #include "LogFactory.h" +@@ -158,7 +159,7 @@ ssize_t SocketBuffer::send() + } + ssize_t slen = socket_->writeVector(iov, num); + if (slen == 0 && !socket_->wantRead() && !socket_->wantWrite()) { +- throw DL_ABORT_EX(fmt(EX_SOCKET_SEND, "Connection closed.")); ++ throw DL_RETRY_EX(fmt(EX_SOCKET_SEND, "Connection closed.")); + } + // A2_LOG_NOTICE(fmt("num=%zu, amount=%d, bufq.size()=%zu, SEND=%d", + // num, amount, bufq_.size(), slen)); +diff --git a/src/SocketCore.cc b/src/SocketCore.cc +index 77dc30c..537375a 100644 +--- a/src/SocketCore.cc ++++ b/src/SocketCore.cc +@@ -1009,7 +1009,7 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname) + + if (rv == TLS_ERR_ERROR) { + // Damn those error. +- throw DL_ABORT_EX(fmt("SSL/TLS handshake failure: %s", ++ throw DL_RETRY_EX(fmt("SSL/TLS handshake failure: %s", + handshakeError.empty() + ? tlsSession_->getLastErrorString().c_str() + : handshakeError.c_str())); +-- +2.17.1 diff --git a/aria2/patches/0003-option-add-option-to-retry-on-http-4xx.patch b/aria2/patches/0003-option-add-option-to-retry-on-http-4xx.patch new file mode 100644 index 0000000..cde2a90 --- /dev/null +++ b/aria2/patches/0003-option-add-option-to-retry-on-http-4xx.patch @@ -0,0 +1,239 @@ +From 8adbc01dc5975a64c55fe594d8c758c71e8183b3 Mon Sep 17 00:00:00 2001 +From: myfreeer +Date: Sun, 22 Jul 2018 19:59:02 +0800 +Subject: [PATCH] option: add option to retry on http 400, 403, 406, or unknown + + --retry-on-400[=true|false] Configure whether retry or not when + HTTP server returns 400 Bad Request. + Only effective if retry-wait > 0. + + Possible Values: true, false + Default: false + Tags: #advanced, #http + + --retry-on-403[=true|false] Configure whether retry or not when + HTTP server returns 403 Forbidden. + Only effective if retry-wait > 0. + + Possible Values: true, false + Default: false + Tags: #advanced, #http + + --retry-on-406[=true|false] Configure whether retry or not when + HTTP server returns 406 Not Acceptable. + Only effective if retry-wait > 0. + + Possible Values: true, false + Default: false + Tags: #advanced, #http + + --retry-on-unknown[=true|false] Configure whether retry or not when + HTTP server returns unknown status code. + Only effective if retry-wait > 0. + + Possible Values: true, false + Default: false + Tags: #advanced, #http +--- + src/HttpSkipResponseCommand.cc | 42 +++++++++++++++++++++++++++++----- + src/OptionHandlerFactory.cc | 40 ++++++++++++++++++++++++++++++++ + src/prefs.cc | 8 +++++++ + src/prefs.h | 8 +++++++ + src/usage_text.h | 16 +++++++++++++ + 5 files changed, 108 insertions(+), 6 deletions(-) + +diff --git a/src/HttpSkipResponseCommand.cc b/src/HttpSkipResponseCommand.cc +index a722d77..de4ad6c 100644 +--- a/src/HttpSkipResponseCommand.cc ++++ b/src/HttpSkipResponseCommand.cc +@@ -204,7 +204,7 @@ bool HttpSkipResponseCommand::processResponse() + auto statusCode = httpResponse_->getStatusCode(); + if (statusCode >= 400) { + switch (statusCode) { +- case 401: ++ case 401: // Unauthorized + if (getOption()->getAsBool(PREF_HTTP_AUTH_CHALLENGE) && + !httpResponse_->getHttpRequest()->authenticationUsed() && + getDownloadEngine()->getAuthConfigFactory()->activateBasicCred( +@@ -213,15 +213,41 @@ bool HttpSkipResponseCommand::processResponse() + return prepareForRetry(0); + } + throw DL_ABORT_EX2(EX_AUTH_FAILED, error_code::HTTP_AUTH_FAILED); +- case 404: ++ case 404: // Not Found + if (getOption()->getAsInt(PREF_MAX_FILE_NOT_FOUND) == 0) { + throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND, + error_code::RESOURCE_NOT_FOUND); + } + throw DL_RETRY_EX2(MSG_RESOURCE_NOT_FOUND, + error_code::RESOURCE_NOT_FOUND); +- case 502: +- case 503: ++ case 400: // Bad Request ++ if (getOption()->getAsBool(PREF_RETRY_ON_400) ++ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) { ++ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode), ++ error_code::HTTP_PROTOCOL_ERROR); ++ } ++ break; ++ case 403: // Forbidden ++ if (getOption()->getAsBool(PREF_RETRY_ON_403) ++ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) { ++ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode), ++ error_code::HTTP_PROTOCOL_ERROR); ++ } ++ break; ++ case 406: // Not Acceptable ++ if (getOption()->getAsBool(PREF_RETRY_ON_406) ++ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) { ++ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode), ++ error_code::HTTP_PROTOCOL_ERROR); ++ } ++ break; ++ case 408: // Request Timeout ++ case 429: // Too Many Requests ++ case 502: // Bad Gateway ++ case 503: // Service Unavailable ++ case 507: // Insufficient Storage ++ case 520: // https://github.com/aria2/aria2/issues/1229 ++ case 521: // https://github.com/aria2/aria2/issues/1229 + // Only retry if pretry-wait > 0. Hammering 'busy' server is not + // a good idea. + if (getOption()->getAsInt(PREF_RETRY_WAIT) > 0) { +@@ -230,12 +256,16 @@ bool HttpSkipResponseCommand::processResponse() + } + throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, statusCode), + error_code::HTTP_SERVICE_UNAVAILABLE); +- case 504: ++ case 504: // Gateway Timeout + // This is Gateway Timeout, so try again + throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode), + error_code::HTTP_SERVICE_UNAVAILABLE); + }; +- ++ if (getOption()->getAsBool(PREF_RETRY_ON_UNKNOWN) ++ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) { ++ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode), ++ error_code::HTTP_PROTOCOL_ERROR); ++ } + throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, statusCode), + error_code::HTTP_PROTOCOL_ERROR); + } +diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc +index 5768f7b..decb03e 100644 +--- a/src/OptionHandlerFactory.cc ++++ b/src/OptionHandlerFactory.cc +@@ -934,6 +934,46 @@ std::vector OptionHandlerFactory::createOptionHandlers() + op->setChangeOptionForReserved(true); + handlers.push_back(op); + } ++ { ++ OptionHandler* op(new BooleanOptionHandler( ++ PREF_RETRY_ON_400, TEXT_RETRY_ON_400, A2_V_FALSE, OptionHandler::OPT_ARG)); ++ op->addTag(TAG_ADVANCED); ++ op->addTag(TAG_HTTP); ++ op->setInitialOption(true); ++ op->setChangeGlobalOption(true); ++ op->setChangeOptionForReserved(true); ++ handlers.push_back(op); ++ } ++ { ++ OptionHandler* op(new BooleanOptionHandler( ++ PREF_RETRY_ON_403, TEXT_RETRY_ON_403, A2_V_FALSE, OptionHandler::OPT_ARG)); ++ op->addTag(TAG_ADVANCED); ++ op->addTag(TAG_HTTP); ++ op->setInitialOption(true); ++ op->setChangeGlobalOption(true); ++ op->setChangeOptionForReserved(true); ++ handlers.push_back(op); ++ } ++ { ++ OptionHandler* op(new BooleanOptionHandler( ++ PREF_RETRY_ON_406, TEXT_RETRY_ON_406, A2_V_FALSE, OptionHandler::OPT_ARG)); ++ op->addTag(TAG_ADVANCED); ++ op->addTag(TAG_HTTP); ++ op->setInitialOption(true); ++ op->setChangeGlobalOption(true); ++ op->setChangeOptionForReserved(true); ++ handlers.push_back(op); ++ } ++ { ++ OptionHandler* op(new BooleanOptionHandler( ++ PREF_RETRY_ON_UNKNOWN, TEXT_RETRY_ON_UNKNOWN, A2_V_FALSE, OptionHandler::OPT_ARG)); ++ op->addTag(TAG_ADVANCED); ++ op->addTag(TAG_HTTP); ++ op->setInitialOption(true); ++ op->setChangeGlobalOption(true); ++ op->setChangeOptionForReserved(true); ++ handlers.push_back(op); ++ } + { + OptionHandler* op(new BooleanOptionHandler( + PREF_REUSE_URI, TEXT_REUSE_URI, A2_V_TRUE, OptionHandler::OPT_ARG)); +diff --git a/src/prefs.cc b/src/prefs.cc +index 937e927..33eff91 100644 +--- a/src/prefs.cc ++++ b/src/prefs.cc +@@ -327,6 +327,14 @@ PrefPtr PREF_ENABLE_ASYNC_DNS6 = makePref("enable-async-dns6"); + PrefPtr PREF_MAX_DOWNLOAD_RESULT = makePref("max-download-result"); + // value: 1*digit + PrefPtr PREF_RETRY_WAIT = makePref("retry-wait"); ++// value: true | false ++PrefPtr PREF_RETRY_ON_400 = makePref("retry-on-400"); ++// value: true | false ++PrefPtr PREF_RETRY_ON_403 = makePref("retry-on-403"); ++// value: true | false ++PrefPtr PREF_RETRY_ON_406 = makePref("retry-on-406"); ++// value: true | false ++PrefPtr PREF_RETRY_ON_UNKNOWN = makePref("retry-on-unknown"); + // value: string + PrefPtr PREF_ASYNC_DNS_SERVER = makePref("async-dns-server"); + // value: true | false +diff --git a/src/prefs.h b/src/prefs.h +index e1f8397..019e774 100644 +--- a/src/prefs.h ++++ b/src/prefs.h +@@ -280,6 +280,14 @@ extern PrefPtr PREF_ENABLE_ASYNC_DNS6; + extern PrefPtr PREF_MAX_DOWNLOAD_RESULT; + // value: 1*digit + extern PrefPtr PREF_RETRY_WAIT; ++// value: true | false ++extern PrefPtr PREF_RETRY_ON_400; ++// value: true | false ++extern PrefPtr PREF_RETRY_ON_403; ++// value: true | false ++extern PrefPtr PREF_RETRY_ON_406; ++// value: true | false ++extern PrefPtr PREF_RETRY_ON_UNKNOWN; + // value: string + extern PrefPtr PREF_ASYNC_DNS_SERVER; + // value: true | false +diff --git a/src/usage_text.h b/src/usage_text.h +index d73b50d..75d34a0 100644 +--- a/src/usage_text.h ++++ b/src/usage_text.h +@@ -64,6 +64,22 @@ + _(" --retry-wait=SEC Set the seconds to wait between retries. \n" \ + " With SEC > 0, aria2 will retry download when the\n" \ + " HTTP server returns 503 response.") ++#define TEXT_RETRY_ON_400 \ ++ _(" --retry-on-400[=true|false] Configure whether retry or not when\n" \ ++ " HTTP server returns 400 Bad Request.\n" \ ++ " Only effective if retry-wait > 0.") ++#define TEXT_RETRY_ON_403 \ ++ _(" --retry-on-403[=true|false] Configure whether retry or not when\n" \ ++ " HTTP server returns 403 Forbidden.\n" \ ++ " Only effective if retry-wait > 0.") ++#define TEXT_RETRY_ON_406 \ ++ _(" --retry-on-406[=true|false] Configure whether retry or not when\n" \ ++ " HTTP server returns 406 Not Acceptable.\n" \ ++ " Only effective if retry-wait > 0.") ++#define TEXT_RETRY_ON_UNKNOWN \ ++ _(" --retry-on-unknown[=true|false] Configure whether retry or not when\n" \ ++ " HTTP server returns unknown status code.\n" \ ++ " Only effective if retry-wait > 0.") + #define TEXT_TIMEOUT \ + _(" -t, --timeout=SEC Set timeout in seconds.") + #define TEXT_MAX_TRIES \ +-- +2.18.0 diff --git a/aria2/patches/0004-Disable-auto-added-Want-Digest-header.patch b/aria2/patches/0004-Disable-auto-added-Want-Digest-header.patch new file mode 100644 index 0000000..65a473d --- /dev/null +++ b/aria2/patches/0004-Disable-auto-added-Want-Digest-header.patch @@ -0,0 +1,123 @@ +From b938aa51e50852d1b185db3188357073ad374416 Mon Sep 17 00:00:00 2001 +From: myfreeer +Date: Sun, 13 Dec 2020 15:40:56 +0800 +Subject: [PATCH] option: add option to disable Want-Digest header + +Sending this HTTP header should be optional. +Should close https://github.com/myfreeer/aria2-build-msys2/issues/10 + + --http-want-digest[=true|false] Send Want-Digest HTTP requser header + with only limited hash algorithms: + SHA-512, SHA-256, and SHA-1. + The Want-Digest HTTP header is primarily used + in a HTTP request, to ask the responder to + provide a digest of the requested resource + using the Digest response header + + Possible Values: true, false + Default: false + Tags: #advanced, #http +--- + src/AbstractProxyRequestCommand.cc | 1 + + src/HttpRequestCommand.cc | 1 + + src/OptionHandlerFactory.cc | 12 ++++++++++++ + src/prefs.cc | 2 ++ + src/prefs.h | 2 ++ + src/usage_text.h | 8 ++++++++ + 6 files changed, 26 insertions(+) + +diff --git a/src/AbstractProxyRequestCommand.cc b/src/AbstractProxyRequestCommand.cc +index bd2bcb3..1feed07 100644 +--- a/src/AbstractProxyRequestCommand.cc ++++ b/src/AbstractProxyRequestCommand.cc +@@ -72,6 +72,7 @@ bool AbstractProxyRequestCommand::executeInternal() + if (httpConnection_->sendBufferIsEmpty()) { + auto httpRequest = make_unique(); + httpRequest->setUserAgent(getOption()->get(PREF_USER_AGENT)); ++ httpRequest->setNoWantDigest(!getOption()->getAsBool(PREF_HTTP_WANT_DIGEST)); + httpRequest->setRequest(getRequest()); + httpRequest->setProxyRequest(proxyRequest_); + +diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc +index a2b8e7e..8c50153 100644 +--- a/src/HttpRequestCommand.cc ++++ b/src/HttpRequestCommand.cc +@@ -90,6 +90,7 @@ createHttpRequest(const std::shared_ptr& req, + { + auto httpRequest = make_unique(); + httpRequest->setUserAgent(option->get(PREF_USER_AGENT)); ++ httpRequest->setNoWantDigest(!option->getAsBool(PREF_HTTP_WANT_DIGEST)); + httpRequest->setRequest(req); + httpRequest->setFileEntry(fileEntry); + httpRequest->setSegment(segment); +diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc +index a058eb9..9ff615a 100644 +--- a/src/OptionHandlerFactory.cc ++++ b/src/OptionHandlerFactory.cc +@@ -1106,6 +1106,18 @@ std::vector OptionHandlerFactory::createOptionHandlers() + op->setChangeOptionForReserved(true); + handlers.push_back(op); + } ++ { ++ OptionHandler* op( ++ new BooleanOptionHandler(PREF_HTTP_WANT_DIGEST, ++ TEXT_HTTP_WANT_DIGEST, ++ A2_V_FALSE, OptionHandler::OPT_ARG)); ++ op->addTag(TAG_ADVANCED); ++ op->addTag(TAG_HTTP); ++ op->setInitialOption(true); ++ op->setChangeGlobalOption(true); ++ op->setChangeOptionForReserved(true); ++ handlers.push_back(op); ++ } + { + OptionHandler* op(new BooleanOptionHandler( + PREF_ENABLE_HTTP_KEEP_ALIVE, TEXT_ENABLE_HTTP_KEEP_ALIVE, A2_V_TRUE, +diff --git a/src/prefs.cc b/src/prefs.cc +index 9793706..bdb33e2 100644 +--- a/src/prefs.cc ++++ b/src/prefs.cc +@@ -437,6 +437,8 @@ PrefPtr PREF_HTTP_ACCEPT_GZIP = makePref("http-accept-gzip"); + // value: true | false + PrefPtr PREF_CONTENT_DISPOSITION_DEFAULT_UTF8 = + makePref("content-disposition-default-utf8"); ++// values: true | false ++PrefPtr PREF_HTTP_WANT_DIGEST = makePref("http-want-digest"); + + /** + * Proxy related preferences +diff --git a/src/prefs.h b/src/prefs.h +index f014d9c..c88f2d0 100644 +--- a/src/prefs.h ++++ b/src/prefs.h +@@ -389,6 +389,8 @@ extern PrefPtr PREF_HTTP_NO_CACHE; + extern PrefPtr PREF_HTTP_ACCEPT_GZIP; + // value: true | false + extern PrefPtr PREF_CONTENT_DISPOSITION_DEFAULT_UTF8; ++// value: true | false ++extern PrefPtr PREF_HTTP_WANT_DIGEST; + + /**; + * Proxy related preferences +diff --git a/src/usage_text.h b/src/usage_text.h +index 7a0a981..aee3ac0 100644 +--- a/src/usage_text.h ++++ b/src/usage_text.h +@@ -560,6 +560,14 @@ + " Content-Disposition header as UTF-8 instead of\n" \ + " ISO-8859-1, for example, the filename parameter,\n" \ + " but not the extended version filename*.") ++#define TEXT_HTTP_WANT_DIGEST \ ++ _(" --http-want-digest[=true|false] Send Want-Digest HTTP requser header\n" \ ++ " with only limited hash algorithms:\n" \ ++ " SHA-512, SHA-256, and SHA-1.\n" \ ++ " The Want-Digest HTTP header is primarily used\n" \ ++ " in a HTTP request, to ask the responder to\n" \ ++ " provide a digest of the requested resource\n" \ ++ " using the Digest response header") + #define TEXT_EVENT_POLL \ + _(" --event-poll=POLL Specify the method for polling events.") + #define TEXT_BT_EXTERNAL_IP \ +-- +2.29.2 + diff --git a/luci-app-aria2/Makefile b/luci-app-aria2/Makefile new file mode 100644 index 0000000..e628e81 --- /dev/null +++ b/luci-app-aria2/Makefile @@ -0,0 +1,18 @@ +# +# Copyright (C) 2017-2019 Xingwang Liao +# +# This is free software, licensed under the MIT License. +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI Support for Aria2 +LUCI_DEPENDS:=+aria2 +ariang +LUCI_PKGARCH:=all + +PKG_MAINTAINER:=Xingwang Liao +PKG_LICENSE:=MIT + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luci-app-aria2/luasrc/controller/aria2.lua b/luci-app-aria2/luasrc/controller/aria2.lua new file mode 100644 index 0000000..15e8f07 --- /dev/null +++ b/luci-app-aria2/luasrc/controller/aria2.lua @@ -0,0 +1,39 @@ +module("luci.controller.aria2",package.seeall) +local ucic = luci.model.uci.cursor() +local http = require "luci.http" +local util = require "luci.util" + +function index() + if not nixio.fs.access("/etc/config/aria2")then return end + entry({"admin","nas","aria2"},firstchild(),_("Aria2")).dependent=false + entry({"admin","nas","aria2","config"},cbi("aria2/config"),_("Configuration"),1) + entry({"admin","nas","aria2","file"},form("aria2/files"),_("Files"),2) + entry({"admin","nas","aria2","log"},firstchild(),_("Log"),3) + entry({"admin","nas","aria2","log","view"},template("aria2/log_template")) + entry({"admin","nas","aria2","log","read"},call("action_log_read")) + entry({"admin", "nas", "aria2", "clear_log"}, call("clear_log")).leaf = true + entry({"admin","nas","aria2","status"},call("action_status")) +end + +function action_status() +local t={ +running=(luci.sys.call("pidof aria2c >/dev/null")==0) +} +http.prepare_content("application/json") +http.write_json(t) +end + +function clear_log() + luci.sys.call("cat > /var/log/aria2_1.log") +end + +function action_log_read() + local t={log="",syslog=""} + local o=ucic:get("aria2","main","log")or"/var/log/aria2.log" + if nixio.fs.access(o) then + t.log=util.trim(luci.sys.exec("tail -n 50 %s | sed 'x;1!H;$!d;x'"%o)) + end + t.syslog=util.trim(luci.sys.exec("[ -f '/var/log/aria2_1.log' ] && cat /var/log/aria2_1.log")) + http.prepare_content("application/json") + http.write_json(t) +end diff --git a/luci-app-aria2/luasrc/model/cbi/aria2/config.lua b/luci-app-aria2/luasrc/model/cbi/aria2/config.lua new file mode 100644 index 0000000..c5009f7 --- /dev/null +++ b/luci-app-aria2/luasrc/model/cbi/aria2/config.lua @@ -0,0 +1,411 @@ +local a=require"luci.sys" +local i=require"luci.util" +local o,t,e +local function n() +if a.call("command -v aria2c >/dev/null")~=0 then +return nil +end +local t={} +local e +for e in i.execi("aria2c -v 2>/dev/null | grep -E '^(aria2 version|Enabled Features)'")do +if e:match("^aria2 version")then +local a,a,e=e:find("([%d%.]+)$") +t.version=e +elseif e:match("^Enabled Features")then +t.gzip=e:find("GZip")~=nil +t.https=e:find("HTTPS")~=nil +t.bt=e:find("BitTorrent")~=nil +t.sftp=e:find("SFTP")~=nil +t.adns=e:find("Async DNS")~=nil +t.cookie=e:find("Firefox3 Cookie")~=nil +end +end +return t +end +local a=n() +o=Map("aria2","%s - %s"%{translate("Aria2"),translate("Settings")}, +"

%s

%s

"%{ +translate("Aria2 is a lightweight multi-protocol & multi-source, cross platform download utility."), +translatef("") +}) +if not a then +o:section(SimpleSection,nil,"%s"% +translate("Error: Can't find aria2c in PATH, please reinstall aria2.")) +o.reset=false +o.submit=false +return o +end +o:append(Template("aria2/settings_header")) +t=o:section(NamedSection,"main","aria2") +t.addremove=false +t.anonymous=true +t:tab("basic",translate("Basic Options")) +e=t:taboption("basic",Flag,"enabled",translate("Enabled")) +e.rmempty=false +e=t:taboption("basic",ListValue,"user",translate("Run daemon as user"), +translate("Leave blank to use default user.")) +e:value("") +local n +for t in i.execi("cat /etc/passwd | cut -d':' -f1")do +e:value(t) +end +mount=t:taboption("basic",Value,"dir",translate("Download directory"), +translate("The directory to store the downloaded file. eg. /mnt/sda1")) +mount.rmempty=false +for t in i.execi("mount | awk '{print $3}' | grep mnt")do +mount:value(t) +end +e=t:taboption("basic",Value,"config_dir",translate("Config file directory"), +translate("The directory to store the config file, session file and DHT file.")) +e.placeholder="/var/etc/aria2" +e=t:taboption("basic",Flag,"enable_Pro",translate("Enable Aria2 Pro"),translate("When enabled, the original system configuration directory will be merged.")) +e.rmempty=false +e=t:taboption("basic",Value,"Pro",translate("Aria2 Pro file"), +translate("Use the configuration scheme of p3terx to realize the enhancement and expansion of aria2 function.")) +e:depends("enable_Pro","1") +e.default="/usr/share/aria2" +e=t:taboption("basic",Flag,"enable_logging",translate("Enable logging")) +e.rmempty=false +e=t:taboption("basic",Value,"log",translate("Log file"), +translate("The file name of the log file.")) +e:depends("enable_logging","1") +e.placeholder="/var/log/aria2.log" +e=t:taboption("basic",ListValue,"log_level",translate("Log level")) +e:depends("enable_logging","1") +e:value("debug",translate("Debug")) +e:value("info",translate("Info")) +e:value("notice",translate("Notice")) +e:value("warn",translate("Warn")) +e:value("error",translate("Error")) +e.default="warn" +e=t:taboption("basic",Value,"max_concurrent_downloads",translate("Max concurrent downloads")) +e.placeholder="5" +t:tab("rpc",translate("RPC Options")) +e=t:taboption("rpc",Flag,"pause",translate("Pause"),translate("Pause download after added.")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("rpc",Flag,"pause_metadata",translate("Pause metadata"), +translate("Pause downloads created as a result of metadata download.")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("rpc",Value,"rpc_listen_port",translate("RPC port"),translate("The webui port defaults to 6800.")) +e.datatype="range(1024,65535)" +e.placeholder="6800" +e=t:taboption("rpc",ListValue,"rpc_auth_method",translate("RPC authentication method")) +e:value("none",translate("No Authentication")) +e:value("user_pass",translate("Username & Password")) +e:value("token",translate("Token")) +e=t:taboption("rpc",Value,"rpc_user",translate("RPC username")) +e:depends("rpc_auth_method","user_pass") +e=t:taboption("rpc",Value,"rpc_passwd",translate("RPC password")) +e:depends("rpc_auth_method","user_pass") +e.password=true +e=t:taboption("rpc",Value,"rpc_secret",translate("RPC token")) +e:depends("rpc_auth_method","token") +e.template="aria2/value_with_btn" +e.btntext=translate("generate randomly") +e.btnclick="randomToken();" +if a.https then +e=t:taboption("rpc",Flag,"rpc_secure",translate("RPC secure"), +translate("RPC transport will be encrypted by SSL/TLS. The RPC clients must use https" +.." scheme to access the server. For WebSocket client, use wss scheme.")) +e.enabled="true" +e.disabled="false" +e.rmempty=false +e=t:taboption("rpc",Value,"rpc_certificate",translate("RPC certificate"), +translate("Use the certificate in FILE for RPC server. The certificate must be either" +.." in PKCS12 (.p12, .pfx) or in PEM format.
PKCS12 files must contain the" +.." certificate, a key and optionally a chain of additional certificates. Only PKCS12" +.." files with a blank import password can be opened!
When using PEM, you have to" +.." specify the \"RPC private key\" as well.")) +e:depends("rpc_secure","true") +e.datatype="file" +e=t:taboption("rpc",Value,"rpc_private_key",translate("RPC private key"), +translate("Use the private key in FILE for RPC server. The private key must be" +.." decrypted and in PEM format.")) +e:depends("rpc_secure","true") +e.datatype="file" +end +e=t:taboption("rpc",Flag,"_use_ws",translate("Use WebSocket")) +e=t:taboption("rpc",Value,"_rpc_url",translate("Json-RPC URL")) +e.template="aria2/value_with_btn" +e.onmouseover="this.focus();this.select();" +e.btntext=translate("Show URL") +e.btnclick="showRPCURL();" +t:tab("http",translate("HTTP/FTP/SFTP Options")) +e=t:taboption("http",Flag,"enable_proxy",translate("Enable proxy")) +e.rmempty=false +e=t:taboption("http",Value,"all_proxy",translate("All proxy"), +translate("Use a proxy server for all protocols.")) +e:depends("enable_proxy","1") +e.placeholder="[http://][USER:PASSWORD@]HOST[:PORT]" +e=t:taboption("http",Value,"all_proxy_user",translate("Proxy user")) +e:depends("enable_proxy","1") +e=t:taboption("http",Value,"all_proxy_passwd",translate("Proxy password")) +e:depends("enable_proxy","1") +e.password=true +if a.https then +e=t:taboption("http",Flag,"check_certificate",translate("Check certificate"), +translate("Verify the peer using certificates specified in \"CA certificate\" option.")) +e.enabled="true" +e.disabled="false" +e.default="true" +e.rmempty=false +e=t:taboption("http",Value,"ca_certificate",translate("CA certificate"), +translate("Use the certificate authorities in FILE to verify the peers. The certificate" +.." file must be in PEM format and can contain multiple CA certificates.")) +e:depends("check_certificate","true") +e.datatype="file" +e=t:taboption("http",Value,"certificate",translate("Certificate"), +translate("Use the client certificate in FILE. The certificate must be either in PKCS12" +.." (.p12, .pfx) or in PEM format.
PKCS12 files must contain the certificate, a" +.." key and optionally a chain of additional certificates. Only PKCS12 files with a" +.." blank import password can be opened!
When using PEM, you have to specify the" +.." \"Private key\" as well.")) +e.datatype="file" +e=t:taboption("http",Value,"private_key",translate("Private key"), +translate("Use the private key in FILE. The private key must be decrypted and in PEM" +.." format. The behavior when encrypted one is given is undefined.")) +e.datatype="file" +end +if a.gzip then +e=t:taboption("http",Flag,"http_accept_gzip",translate("HTTP accept gzip"), +translate("Send Accept: deflate, gzip request header and inflate response" +.." if remote server responds with Content-Encoding: gzip or" +.." Content-Encoding: deflate.")) +e.enabled="true" +e.disabled="false" +e.default="false" +end +e=t:taboption("http",Flag,"http_no_cache",translate("HTTP no cache"), +translate("Send Cache-Control: no-cache and Pragma: no-cache" +.." header to avoid cached content. If disabled, these headers are not sent and you" +.." can add Cache-Control header with a directive you like using \"Header\" option.")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("http",DynamicList,"header",translate("Header"), +translate("Append HEADERs to HTTP request header.")) +e=t:taboption("http",Value,"connect_timeout",translate("Connect timeout"), +translate("Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server.".. +" After the connection is established, this option makes no effect and \"Timeout\" option is used instead.")) +e.datatype="uinteger" +e.placeholder="60" +e=t:taboption("http",Value,"timeout",translate("Timeout")) +e.datatype="uinteger" +e.placeholder="60" +e=t:taboption("http",Value,"lowest_speed_limit",translate("Lowest speed limit"), +"%s %s"%{ +translate("Close connection if download speed is lower than or equal to this value(bytes per sec). ".. +"0 means has no lowest speed limit."), +translate("You can append K or M.") +}) +e.placeholder="0" +e=t:taboption("http",Value,"max_connection_per_server",translate("Max connection per server"), +translate("The maximum number of connections to one server for each download.")) +e.datatype="uinteger" +e.placeholder="1" +e=t:taboption("http",Value,"split",translate("Max number of split"), +translate("Download a file using N connections.")) +e.datatype="uinteger" +e.placeholder="5" +e=t:taboption("http",Value,"min_split_size",translate("Min split size"), +translate("Don't split less than 2*SIZE byte range. Possible values: 1M-1024M.")) +e.placeholder="20M" +e=t:taboption("http",Value,"max_tries",translate("Max tries")) +e.datatype="uinteger" +e.placeholder="5" +e=t:taboption("http",Value,"retry_wait",translate("Retry wait"), +translate("Set the seconds to wait between retries.")) +e.datatype="uinteger" +e.placeholder="0" +e=t:taboption("http",Value,"user_agent",translate("User agent"), +translate("Set user agent for HTTP(S) downloads.")) +e.placeholder="aria2/%s"%{a.version and a.version or"$VERSION"} +if a.bt then +t:tab("bt",translate("BitTorrent Options")) +e=t:taboption("bt",Flag,"enable_dht",translate("IPv4 DHT enabled"), +"%s %s"%{ +translate("Enable IPv4 DHT functionality. It also enables UDP tracker support."), +translate("This option will be ignored if a private flag is set in a torrent.") +}) +e.enabled="true" +e.disabled="false" +e.default="true" +e.rmempty=false +e=t:taboption("bt",Flag,"enable_dht6",translate("IPv6 DHT enabled"), +"%s %s"%{ +translate("Enable IPv6 DHT functionality."), +translate("This option will be ignored if a private flag is set in a torrent.") +}) +e.enabled="true" +e.disabled="false" +e=t:taboption("bt",Flag,"bt_enable_lpd",translate("LPD enabled"), +"%s %s"%{ +translate("Enable Local Peer Discovery."), +translate("This option will be ignored if a private flag is set in a torrent.") +}) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("bt",Flag,"enable_peer_exchange",translate("Enable peer exchange"), +"%s %s"%{ +translate("Enable Peer Exchange extension."), +translate("This option will be ignored if a private flag is set in a torrent.") +}) +e.enabled="true" +e.disabled="false" +e.default="true" +e.rmempty=false +e=t:taboption("bt",Flag,"bt_save_metadata",translate("Sava metadata"), +translate("Save meta data as \".torrent\" file. This option has effect only when BitTorrent" +.." Magnet URI is used. The file name is hex encoded info hash with suffix \".torrent\".")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("bt",Flag,"bt_remove_unselected_file",translate("Remove unselected file"), +translate("Removes the unselected files when download is completed in BitTorrent. Please" +.." use this option with care because it will actually remove files from your disk.")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("bt",Flag,"bt_seed_unverified",translate("Seed unverified"), +translate("Seed previously downloaded files without verifying piece hashes.")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("bt",Value,"listen_port",translate("BitTorrent listen port"), +translate("Set TCP port number for BitTorrent downloads. Accept format: \"6881,6885\"," +.." \"6881-6999\" and \"6881-6889,6999\". Make sure that the specified ports are open" +.." for incoming TCP traffic.")) +e.placeholder="6881-6999" +e=t:taboption("bt",Value,"dht_listen_port",translate("DHT Listen port"), +translate("Set UDP listening port used by DHT(IPv4, IPv6) and UDP tracker. Make sure that the " +.."specified ports are open for incoming UDP traffic.")) +e:depends("enable_dht","true") +e:depends("enable_dht6","true") +e.placeholder="6881-6999" +e=t:taboption("bt",ListValue,"follow_torrent",translate("Follow torrent")) +e:value("true",translate("True")) +e:value("false",translate("False")) +e:value("mem",translate("Keep in memory")) +e=t:taboption("bt",Value,"max_overall_upload_limit",translate("Max overall upload limit"), +"%s %s"%{ +translate("Set max overall upload speed in bytes/sec. 0 means unrestricted."), +translate("You can append K or M.") +}) +e.placeholder="0" +e=t:taboption("bt",Value,"max_upload_limit",translate("Max upload limit"), +"%s %s"%{ +translate("Set max upload speed per each torrent in bytes/sec. 0 means unrestricted."), +translate("You can append K or M.") +}) +e.placeholder="0" +e=t:taboption("bt",Value,"bt_max_open_files",translate("Max open files"), +translate("Specify maximum number of files to open in multi-file BitTorrent download globally.")) +e.datatype="uinteger" +e.placeholder="100" +e=t:taboption("bt",Value,"bt_max_peers",translate("Max peers"), +translate("Specify the maximum number of peers per torrent, 0 means unlimited.")) +e.datatype="uinteger" +e.placeholder="55" +e=t:taboption("bt",Value,"bt_request_peer_speed_limit",translate("Request peer speed limit"), +"%s %s"%{ +translate("If the whole download speed of every torrent is lower than SPEED, aria2" +.." temporarily increases the number of peers to try for more download speed." +.." Configuring this option with your preferred download speed can increase your" +.." download speed in some cases."), +translate("You can append K or M.") +}) +e.placeholder="50K" +e=t:taboption("bt",Value,"bt_stop_timeout",translate("Stop timeout"), +translate("Stop BitTorrent download if download speed is 0 in consecutive N seconds. If 0 is" +.." given, this feature is disabled.")) +e.datatype="uinteger" +e.placeholder="0" +e=t:taboption("bt",Value,"peer_id_prefix",translate("Prefix of peer ID"), +translate("Specify the prefix of peer ID. The peer ID in BitTorrent is 20 byte length." +.." If more than 20 bytes are specified, only first 20 bytes are used. If less than 20" +.." bytes are specified, random byte data are added to make its length 20 bytes.")) +e.placeholder="A2-%s-"%{ +a.version and string.gsub(a.version,"%.","-")or"$MAJOR-$MINOR-$PATCH" +} +e=t:taboption("bt",Value,"seed_ratio",translate("Seed ratio"), +translate("Specify share ratio. Seed completed torrents until share ratio reaches RATIO." +.." You are strongly encouraged to specify equals or more than 1.0 here. Specify 0.0 if" +.." you intend to do seeding regardless of share ratio.")) +e.datatype="ufloat" +e.placeholder="1.0" +e=t:taboption("bt",Value,"seed_time",translate("Seed time"), +translate("Specify seeding time in minutes. If \"Seed ratio\" option is" +.." specified along with this option, seeding ends when at least one of the conditions" +.." is satisfied. Specifying 0 disables seeding after download completed.")) +e.datatype="ufloat" +e=t:taboption("bt",DynamicList,"bt_tracker",translate("Additional BT tracker"), +translate("List of additional BitTorrent tracker's announce URI.")) +e.placeholder="http://tracker.example.com/announce" +end +t:tab("advance",translate("Advanced Options")) +e=t:taboption("advance",Flag,"disable_ipv6",translate("IPv6 disabled"), +translate("Disable IPv6. This is useful if you have to use broken DNS and want to avoid terribly" +.." slow AAAA record lookup.")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("advance",Value,"auto_save_interval",translate("Auto save interval"), +translate("Save a control file(*.aria2) every N seconds. If 0 is given, a control file is not" +.." saved during download.")) +e.datatype="range(0, 600)" +e.placeholder="60" +e=t:taboption("advance",Value,"save_session_interval",translate("Save session interval"), +translate("Save error/unfinished downloads to session file every N seconds. If 0 is given, file" +.." will be saved only when aria2 exits.")) +e.datatype="uinteger" +e.placeholder="0" +e=t:taboption("advance",Value,"disk_cache",translate("Disk cache"), +"%s %s"%{ +translate("Enable disk cache (in bytes), set 0 to disabled."), +translate("You can append K or M.") +}) +e.placeholder="16M" +e=t:taboption("advance",ListValue,"file_allocation",translate("File allocation"), +translate("Specify file allocation method. If you are using newer file systems such as ext4" +.." (with extents support), btrfs, xfs or NTFS(MinGW build only), \"falloc\" is your best choice." +.." It allocates large(few GiB) files almost instantly, but it may not be available if your system" +.." doesn't have posix_fallocate(3) function. Don't use \"falloc\" with legacy file systems such as" +.." ext3 and FAT32 because it takes almost same time as \"prealloc\" and it blocks aria2 entirely" +.." until allocation finishes.")) +e:value("none",translate("None")) +e:value("prealloc",translate("prealloc")) +e:value("trunc",translate("trunc")) +e:value("falloc",translate("falloc")) +e.default="falloc" +e=t:taboption("advance",Flag,"force_save",translate("Force save"), +translate("Save download to session file even if the download is completed or removed." +.." This option also saves control file in that situations. This may be useful to save" +.." BitTorrent seeding which is recognized as completed state.")) +e.enabled="true" +e.disabled="false" +e.default="false" +e=t:taboption("advance",Value,"max_overall_download_limit",translate("Max overall download limit"), +"%s %s"%{ +translate("Set max overall download speed in bytes/sec. 0 means unrestricted."), +translate("You can append K or M.") +}) +e.placeholder="0" +e=t:taboption("advance",Value,"max_download_limit",translate("Max download limit"), +"%s %s"%{ +translate("Set max download speed per each download in bytes/sec. 0 means unrestricted."), +translate("You can append K or M.") +}) +e.placeholder="0" +t=o:section(NamedSection,"main","aria2",translate("Extra Settings"), +translate("Settings in this section will be added to config file.")) +t.addremove=false +t.anonymous=true +e=t:option(DynamicList,"extra_settings",translate("Settings list"), +translate("List of extra settings. Format: option=value, eg. netrc-path=/tmp/.netrc.")) +e.placeholder="option=value" +return o diff --git a/luci-app-aria2/luasrc/model/cbi/aria2/files.lua b/luci-app-aria2/luasrc/model/cbi/aria2/files.lua new file mode 100644 index 0000000..05d0656 --- /dev/null +++ b/luci-app-aria2/luasrc/model/cbi/aria2/files.lua @@ -0,0 +1,41 @@ +local t,a,e +local n=require"nixio.fs" +local o=require"luci.util" +local i=require"luci.model.uci".cursor() +if i:get("aria2","main","Pro")then +config_dir=i:get("aria2","main","Pro")or"" +else +config_dir=i:get("aria2","main","config_dir")or"" +end +local s="%s/aria2.conf.main"%config_dir +local h="%s/aria2.session"%config_dir +local i="/etc/config/aria2"%config_dir +t=SimpleForm("aria2","%s - %s"%{translate("Aria2"),translate("Files")}, +translate("Here shows the files used by aria2.")) +t.reset=false +t.submit=false +a=t:section(SimpleSection,nil,translatef("在%s下的config文件内容",i)) +e=a:option(TextValue,"_session") +e.rows=20 +e.readonly=true +e.cfgvalue=function() +local e=n.readfile(i)or translate("File does not exist.") +return o.trim(e)~=""and e or translate("Empty file.") +end +a=t:section(SimpleSection,nil,translatef("在%s下的config文件内容",s)) +e=a:option(TextValue,"_config") +e.rows=20 +e.readonly=true +e.cfgvalue=function() +local e=n.readfile(s)or translate("File does not exist.") +return o.trim(e)~=""and e or translate("Empty file.") +end +a=t:section(SimpleSection,nil,translatef("在%s下的session文件内容",h)) +e=a:option(TextValue,"_session") +e.rows=20 +e.readonly=true +e.cfgvalue=function() +local e=n.readfile(h)or translate("File does not exist.") +return o.trim(e)~=""and e or translate("Empty file.") +end +return t diff --git a/luci-app-aria2/luasrc/view/aria2/log_template.htm b/luci-app-aria2/luasrc/view/aria2/log_template.htm new file mode 100644 index 0000000..65ad9f6 --- /dev/null +++ b/luci-app-aria2/luasrc/view/aria2/log_template.htm @@ -0,0 +1,71 @@ +<%# + Copyright 2017-2019 Xingwang Liao + Licensed to the public under the MIT License. +-%> + +<% css = [[ + + #log_text { + padding: 15px; + text-align: left; + } + #log_text pre { + word-break: break-all; + margin: 0; + font-size : 10pt; + font-family :Arial; + + + } + .description { + background-color: #93ccff; + font-size : 15pt; + +]] +-%> + +<%+header%> + + + +
+

<%:Aria2%> - <%:Log Data%>

+
+ +
+ <%:Loading%> + <%:Collecting data...%> +
+
<%:Refresh every 10 seconds.%>
+
+
+ +<%+footer%> diff --git a/luci-app-aria2/luasrc/view/aria2/settings_header.htm b/luci-app-aria2/luasrc/view/aria2/settings_header.htm new file mode 100644 index 0000000..a567656 --- /dev/null +++ b/luci-app-aria2/luasrc/view/aria2/settings_header.htm @@ -0,0 +1,118 @@ +<%# + Copyright 2017-2019 Xingwang Liao + Licensed to the public under the MIT License. +-%> + +<% + local ipkg = require "luci.model.ipkg" + local has_ui = false + + local uilist = { + supported = { + ["ariang"] = "AriaNg", + ["webui-aria2"] = "WebUI-Aria2", + ["yaaw"] = "YAAW" + }, + installed = {} + } + + for k in pairs(uilist.supported) do + if ipkg.installed(k) then + uilist.installed[#uilist.installed + 1] = k + has_ui = true + end + end + + local ar_state = (luci.sys.call("ps 2>/dev/null | grep aria2c 2>/dev/null | grep /usr/bin >/dev/null") == 0) +%> + +
+

+ <%:Collecting data...%> +

+ <% if has_ui and ar_state then %> +

+ <%:Installed web interface: %> + <%- for _, v in pairs(uilist.installed) do %> + + <%- end %> +

+ <% end %> +

+ + diff --git a/luci-app-aria2/luasrc/view/aria2/value_with_btn.htm b/luci-app-aria2/luasrc/view/aria2/value_with_btn.htm new file mode 100644 index 0000000..487e107 --- /dev/null +++ b/luci-app-aria2/luasrc/view/aria2/value_with_btn.htm @@ -0,0 +1,22 @@ +<%# + Copyright 2017-2019 Xingwang Liao + Licensed to the public under the MIT License. +-%> + +<%+cbi/valueheader%> + /> + <%- if self.btntext then -%> +
><%=self.btntext%>
+ <% end %> +<%+cbi/valuefooter%> diff --git a/luci-app-aria2/po/zh-cn/aria2.po b/luci-app-aria2/po/zh-cn/aria2.po new file mode 100644 index 0000000..b93b49a --- /dev/null +++ b/luci-app-aria2/po/zh-cn/aria2.po @@ -0,0 +1,871 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:296 +msgid "LPD enabled" +msgstr "启用LPD" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:414 +msgid "Additional BT tracker" +msgstr "额外的BT Tracker" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:419 +msgid "Advanced Options" +msgstr "高级选项" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:169 +msgid "All proxy" +msgstr "全局代理" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:228 +msgid "Append HEADERs to HTTP request header." +msgstr "追加的HTTP请求头。" + +#: applications/luci-app-aria2/luasrc/controller/aria2.lua:18 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:35 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:14 +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:45 +msgid "Aria2" +msgstr "Aria2" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:37 +msgid "" +"Aria2 is a lightweight multi-protocol & multi-source, cross platform " +"download utility." +msgstr "Aria2是一个轻量、多线程,跨平台的下载工具。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:428 +msgid "Auto save interval" +msgstr "定时保存会话间隔" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:56 +msgid "Basic Options" +msgstr "基本选项" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:276 +msgid "BitTorrent Options" +msgstr "BT 选项" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:335 +msgid "BitTorrent listen port" +msgstr "BitTorrent监听端口" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:189 +msgid "CA certificate" +msgstr "CA证书" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:195 +msgid "Certificate" +msgstr "证书" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:182 +msgid "Check certificate" +msgstr "检查证书" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:242 +msgid "" +"Close connection if download speed is lower than or equal to this " +"value(bytes per sec). 0 means has no lowest speed limit." +msgstr "" +"如果速度小于或等于这个速度(byte/s),关闭下载下载连接。0表示不限制下载速" +"度。" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:49 +#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:29 +msgid "Collecting data..." +msgstr "正在收集数据..." + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:73 +msgid "Config file directory" +msgstr "配置文件目录" + +#: applications/luci-app-aria2/luasrc/controller/aria2.lua:21 +msgid "Configuration" +msgstr "配置" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:230 +msgid "Connect timeout" +msgstr "连接超时时间" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:19 +msgid "Content of config file: %s" +msgstr "配置文件的内容:%s" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:29 +msgid "Content of session file: %s" +msgstr "Session文件的内容:%s" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:341 +msgid "DHT Listen port" +msgstr "DHT监听端口" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:87 +msgid "Debug" +msgstr "调试" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:422 +msgid "" +"Disable IPv6. This is useful if you have to use broken DNS and want to avoid " +"terribly slow AAAA record lookup." +msgstr "" +"禁用IPv6。如果你的DNS有问题并希望避免AAAA查询过慢,可以启用此选项。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:440 +msgid "Disk cache" +msgstr "磁盘缓存" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:259 +msgid "Don't split less than 2*SIZE byte range. Possible values: 1M-1024M." +msgstr "当数据小于2*SIZE时不分割。可能的值:1M-1024M。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:254 +msgid "Download a file using N connections." +msgstr "使用N线程下载文件。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:69 +msgid "Download directory" +msgstr "下载文件夹" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:26 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:36 +msgid "Empty file." +msgstr "文件为空。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:280 +msgid "Enable IPv4 DHT functionality. It also enables UDP tracker support." +msgstr "启用IPv4 DHT功能。会同时启用UDP Tracker支持。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:290 +msgid "Enable IPv6 DHT functionality." +msgstr "启用IPv6 DHT功能。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:298 +msgid "Enable Local Peer Discovery." +msgstr "启用本地Peer查找。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:307 +msgid "Enable Peer Exchange extension." +msgstr "启用Peer交换扩展。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:442 +msgid "Enable disk cache (in bytes), set 0 to disabled." +msgstr "启用硬盘缓存(byte),0 表示禁用。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:77 +msgid "Enable logging" +msgstr "启用日志" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:305 +msgid "Enable peer exchange" +msgstr "启用Peer交换" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:166 +msgid "Enable proxy" +msgstr "启用代理" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:58 +msgid "Enabled" +msgstr "启用" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:91 +msgid "Error" +msgstr "错误" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:44 +msgid "Error: Can't find aria2c in PATH, please reinstall aria2." +msgstr "错误:未在PATH中找到aria2c,请重新安装Aria2。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:482 +msgid "Extra Settings" +msgstr "附加选项" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:39 +msgid "Failed to load log data." +msgstr "获取日志数据失败。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:350 +msgid "False" +msgstr "否" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:447 +msgid "File allocation" +msgstr "文件分配" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:25 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:35 +msgid "File does not exist." +msgstr "文件不存在。" + +#: applications/luci-app-aria2/luasrc/controller/aria2.lua:24 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:14 +msgid "Files" +msgstr "文件" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:348 +msgid "Follow torrent" +msgstr "自动添加下载的种子" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:460 +msgid "Force save" +msgstr "强制保存" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:129 +msgid "Generate Randomly" +msgstr "随机生成" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:210 +msgid "HTTP accept gzip" +msgstr "HTTP使用Gzip" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:219 +msgid "HTTP no cache" +msgstr "HTTP无缓存" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:164 +msgid "HTTP/FTP/SFTP Options" +msgstr "HTTP/FTP/SFTP选项" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:227 +msgid "Header" +msgstr "请求头" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/files.lua:15 +msgid "Here shows the files used by aria2." +msgstr "这里展示了Aria2使用的文件。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:278 +msgid "IPv4 DHT enabled" +msgstr "启用IPv4DHT" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:288 +msgid "IPv6 DHT enabled" +msgstr "启用IPv6DHT" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:421 +msgid "IPv6 disabled" +msgstr "禁用IPv6" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:379 +msgid "" +"If the whole download speed of every torrent is lower than SPEED, aria2 " +"temporarily increases the number of peers to try for more download speed. " +"Configuring this option with your preferred download speed can increase your " +"download speed in some cases." +msgstr "" +"如果某个BT任务的下载速度小于配置的速度,Aria2会临时提高Peer的数量来尝试" +"获得更大的下载速度。在某些情况下,配置此选项能提高你的下载速度。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:88 +msgid "Info" +msgstr "信息" + +#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:33 +msgid "Installed web interface:" +msgstr "已安装的WEB界面:" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:158 +msgid "Json-RPC URL" +msgstr "Json-RPC URL" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:351 +msgid "Keep in memory" +msgstr "保存在内存中" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:34 +msgid "Last 50 lines of log file:" +msgstr "日志文件的最新50行:" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:36 +msgid "Last 50 lines of syslog:" +msgstr "系统日志的最新50行:" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:62 +msgid "Leave blank to use default user." +msgstr "留空以使用默认用户。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:415 +msgid "List of additional BitTorrent tracker's announce URI." +msgstr "额外的BT Tracker通告链接。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:488 +msgid "" +"List of extra settings. Format: option=value, eg. netrc-path=/tmp/." +"netrc." +msgstr "" +"额外设置的列表。格式:option=value,例如:netrc-path=/tmp/.netrc。" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:48 +msgid "Loading" +msgstr "正在加载" + +#: applications/luci-app-aria2/luasrc/controller/aria2.lua:27 +msgid "Log" +msgstr "日志" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:45 +msgid "Log Data" +msgstr "日志数据" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:80 +msgid "Log file" +msgstr "日志文件" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:85 +msgid "Log level" +msgstr "日志记录等级" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:240 +msgid "Lowest speed limit" +msgstr "最低限速" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:94 +msgid "Max concurrent downloads" +msgstr "最大同时下载任务数" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:248 +msgid "Max connection per server" +msgstr "单服务器最大连接数" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:475 +msgid "Max download limit" +msgstr "最大下载限速" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:253 +msgid "Max number of split" +msgstr "单文件最大线程数" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:367 +msgid "Max open files" +msgstr "最大打开文件数" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:468 +msgid "Max overall download limit" +msgstr "最大全局下载限速" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:353 +msgid "Max overall upload limit" +msgstr "最大全局上传限速" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:372 +msgid "Max peers" +msgstr "最大 Peer 数量" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:262 +msgid "Max tries" +msgstr "最大重试次数" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:360 +msgid "Max upload limit" +msgstr "最大上传限速" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:258 +msgid "Min split size" +msgstr "最小文件分片大小" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:115 +msgid "No Authentication" +msgstr "无认证" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:35 +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:37 +msgid "No log data." +msgstr "无日志数据。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:454 +msgid "None" +msgstr "无" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:89 +msgid "Notice" +msgstr "注意" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:99 +msgid "Pause" +msgstr "暂停" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:99 +msgid "Pause download after added." +msgstr "在下载任务添加后不开始下载。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:105 +msgid "Pause downloads created as a result of metadata download." +msgstr "暂停下载内容为元数据的下载(磁力链接和 Matalink)。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:104 +msgid "Pause metadata" +msgstr "暂停元数据" + +#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:64 +msgid "Please input token length:" +msgstr "请输入密钥长度:" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:393 +msgid "Prefix of peer ID" +msgstr "Peer ID前缀" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:203 +msgid "Private key" +msgstr "私钥" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:177 +msgid "Proxy password" +msgstr "代理密码" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:174 +msgid "Proxy user" +msgstr "代理用户名" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:97 +msgid "RPC Options" +msgstr "RPC选项" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:114 +msgid "RPC authentication method" +msgstr "RPC认证方式" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:140 +msgid "RPC certificate" +msgstr "RPC证书" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:122 +msgid "RPC password" +msgstr "RPC密码" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:110 +msgid "RPC port" +msgstr "RPC端口" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:149 +msgid "RPC private key" +msgstr "RPC私钥" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:133 +msgid "RPC secure" +msgstr "RPC加密" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:126 +msgid "RPC token" +msgstr "RPC令牌" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:134 +msgid "" +"RPC transport will be encrypted by SSL/TLS. The RPC clients must use https " +"scheme to access the server. For WebSocket client, use wss scheme." +msgstr "" +"用SSL/TLS加密RPC连接。RPC客户端必须使用HTTPS协议来连接服务端,对于 " +"WebSocket客户端,则使用WSS协议。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:119 +msgid "RPC username" +msgstr "RPC用户名" + +#: applications/luci-app-aria2/luasrc/view/aria2/log_template.htm:51 +msgid "Refresh every 10 seconds." +msgstr "每10秒刷新。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:322 +msgid "Remove unselected file" +msgstr "删除未选择的文件" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:323 +msgid "" +"Removes the unselected files when download is completed in BitTorrent. " +"Please use this option with care because it will actually remove files from " +"your disk." +msgstr "BT下载完成时删除未选择的文件。文件将从磁盘中被完全删除,请谨慎使用。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:377 +msgid "Request peer speed limit" +msgstr "单个Peer限速" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:266 +msgid "Retry wait" +msgstr "重试等待" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:61 +msgid "Run daemon as user" +msgstr "以此用户权限运行" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:315 +msgid "Sava metadata" +msgstr "保存元数据" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:429 +msgid "" +"Save a control file(*.aria2) every N seconds. If 0 is given, a control file " +"is not saved during download." +msgstr "" +"每N秒保存下载“控制文件”(*.aria2)。设置0表示在下载过程中不保存控制文件。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:461 +msgid "" +"Save download to session file even if the download is completed or removed. " +"This option also saves control file in that situations. This may be useful " +"to save BitTorrent seeding which is recognized as completed state." +msgstr "" +"即使下载已完成或已删除,也将其保存到会话文件。开启此选项也会同时保存“控制文" +"件”。此选项可能有助于保持被识别为已完成状态的BT做种。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:435 +msgid "" +"Save error/unfinished downloads to session file every N seconds. If 0 is " +"given, file will be saved only when aria2 exits." +msgstr "" +"每 N 秒将失败的/未完成的下载保存到Session文件。设置0则仅在Aria2退出时保" +"存。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:316 +msgid "" +"Save meta data as \".torrent\" file. This option has effect only when " +"BitTorrent Magnet URI is used. The file name is hex encoded info hash with " +"suffix \".torrent\"." +msgstr "" +"将元数据保存到\".torrent\"文件。此选项仅在下载连接为BT磁力链接时生效。文" +"件名为Hash值,后缀为\".torrent\"。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:434 +msgid "Save session interval" +msgstr "Session保存间隔" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:330 +msgid "Seed previously downloaded files without verifying piece hashes." +msgstr "继续之前的BT任务时, 无需再次校验分片Hash。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:401 +msgid "Seed ratio" +msgstr "做种比率" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:408 +msgid "Seed time" +msgstr "做种时间" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:329 +msgid "Seed unverified" +msgstr "不校验种子" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:211 +msgid "" +"Send Accept: deflate, gzip request header and inflate response " +"if remote server responds with Content-Encoding: gzip or " +"Content-Encoding: deflate." +msgstr "" +"发送Accept: deflate, gzip请求头,当服务器响应头包含 " +"Content-Encoding: gzip或者Content-Encoding: deflate时解压响应数据。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:220 +msgid "" +"Send Cache-Control: no-cache and Pragma: no-cache " +"header to avoid cached content. If disabled, these headers are not sent and " +"you can add Cache-Control header with a directive you like using \"Header\" " +"option." +msgstr "" +"发送 Cache-Control: no-cachePragma: no-cache 请" +"求头来防止缓存内容,禁用则不发送。你也可用使用“请求头”选项来设置Cache-" +"Control请求头。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:336 +msgid "" +"Set TCP port number for BitTorrent downloads. Accept format: \"6881,6885\", " +"\"6881-6999\" and \"6881-6889,6999\". Make sure that the specified ports are " +"open for incoming TCP traffic." +msgstr "" +"为BT下载设置TCP端口。支持的格式:\"6881,6885\",\"6881-6999\" 和 " +"\"6881-6889,6999\"。请确保正确放行了这些端口的TCP入站通信。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:342 +msgid "" +"Set UDP listening port used by DHT(IPv4, IPv6) and UDP tracker. Make sure " +"that the specified ports are open for incoming UDP traffic." +msgstr "" +"为DHT(IPv4,IPv6)和UDP tracker设置UDP监听端口。请确保正确放行了这些端" +"口的UDP入站通信。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:477 +msgid "" +"Set max download speed per each download in bytes/sec. 0 means unrestricted." +msgstr "设置每个任务的最大下载速度(byte/s),0表示不限制。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:470 +msgid "Set max overall download speed in bytes/sec. 0 means unrestricted." +msgstr "设置全局最大下载速度(byte/s),0表示不限制。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:355 +msgid "Set max overall upload speed in bytes/sec. 0 means unrestricted." +msgstr "设置全局最大上传速度,0表示不限制。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:362 +msgid "" +"Set max upload speed per each torrent in bytes/sec. 0 means unrestricted." +msgstr "设置每个任务的最大上传速度(byte/s),0表示不限制。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:231 +msgid "" +"Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy " +"server. After the connection is established, this option makes no effect and " +"\"Timeout\" option is used instead." +msgstr "" +"设置HTTP、FTP和代理服务器的连接超时时间。当连接建立后,该选项失去作用," +"而“超时时间”选项会被使用。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:267 +msgid "Set the seconds to wait between retries." +msgstr "设置重试的时间间隔。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:272 +msgid "Set user agent for HTTP(S) downloads." +msgstr "为HTTP(S)下载设置UA。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:35 +msgid "Settings" +msgstr "设置" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:483 +msgid "Settings in this section will be added to config file." +msgstr "这个区域中的配置信息将被添加到配置文件中。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:487 +msgid "Settings list" +msgstr "设置列表" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:161 +msgid "Show URL" +msgstr "显示URL" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:448 +msgid "" +"Specify file allocation method. If you are using newer file systems such as " +"ext4 (with extents support), btrfs, xfs or NTFS(MinGW build only), \"falloc" +"\" is your best choice. It allocates large(few GiB) files almost instantly, " +"but it may not be available if your system doesn't have posix_fallocate(3) " +"function. Don't use \"falloc\" with legacy file systems such as ext3 and " +"FAT32 because it takes almost same time as \"prealloc\" and it blocks aria2 " +"entirely until allocation finishes." +msgstr "" +"指定文件分配方式。如果你使用的文件系统较新,例如:ext4(支持扩展分区)," +"btrfs,xfs或者NTFS(仅限 MinGW 版本),强烈推荐 \"falloc\",这种方式几乎能" +"立即分配比较大的文件(GB),但是它要求你的系统支持posix_fallocate(3) 函数。" +"不要在ext3或者FAT32这些旧文件系统中使用 \"falloc\",因为它花费的时间和 " +"\"prealloc\" 几乎一样多,而且在文件分配过程中会阻塞整个Aria2进程。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:368 +msgid "" +"Specify maximum number of files to open in multi-file BitTorrent download " +"globally." +msgstr "设置BT全局最大同时下载的文件数量。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:409 +msgid "" +"Specify seeding time in minutes. If \"Seed ratio\" option is specified along " +"with this option, seeding ends when at least one of the conditions is " +"satisfied. Specifying 0 disables seeding after download completed." +msgstr "" +"指定做种时间(分钟)。如果同时指定了“做种比率”选项,那么将在任一条件满足时停" +"止做种。设置0表示下载完成后停止做种。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:402 +msgid "" +"Specify share ratio. Seed completed torrents until share ratio reaches " +"RATIO. You are strongly encouraged to specify equals or more than 1.0 here. " +"Specify 0.0 if you intend to do seeding regardless of share ratio." +msgstr "" +"指定做种比率。BT下载完成之后持续做种,直到比率达到指定值。强烈建议将此选项设" +"置为大于或等于1.0。设置为0.0来无限做种。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:373 +msgid "Specify the maximum number of peers per torrent, 0 means unlimited." +msgstr "设置每个BT任务的最大 Peer 数量,0表示不限制。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:394 +msgid "" +"Specify the prefix of peer ID. The peer ID in BitTorrent is 20 byte length. " +"If more than 20 bytes are specified, only first 20 bytes are used. If less " +"than 20 bytes are specified, random byte data are added to make its length " +"20 bytes." +msgstr "" +"配置Peer ID前缀。Peer ID的长度为20字节。如果配置超过了20字节,将仅使用" +"前面的20字节。如果配置少于20字节,将添加额外的随机字符来让长度达到20字" +"节。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:388 +msgid "" +"Stop BitTorrent download if download speed is 0 in consecutive N seconds. If " +"0 is given, this feature is disabled." +msgstr "" +"当BT任务在N秒的持续时间内的下载速度一直为0,则停止下载。0表示禁用。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:387 +msgid "Stop timeout" +msgstr "停止超时时间" + +#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:48 +msgid "The Aria2 service is not running." +msgstr "Aria2 未运行" + +#: applications/luci-app-aria2/luasrc/view/aria2/settings_header.htm:47 +msgid "The Aria2 service is running." +msgstr "Aria2 运行中" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:74 +msgid "The directory to store the config file, session file and DHT file." +msgstr "用于放置配置文件,Session文件和DHT文件的目录。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:70 +msgid "The directory to store the downloaded file. eg. /mnt/sda1" +msgstr "用于放置下载文件的目录。例如:/mnt/sda1" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:81 +msgid "The file name of the log file." +msgstr "日志文件名。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:249 +msgid "The maximum number of connections to one server for each download." +msgstr "单一服务器最大连接数量。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:281 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:291 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:299 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:308 +msgid "This option will be ignored if a private flag is set in a torrent." +msgstr "如果种子文件具有“私有”属性,该选项将会被忽略。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:236 +msgid "Timeout" +msgstr "超时" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:117 +msgid "Token" +msgstr "令牌" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:349 +msgid "True" +msgstr "是" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:156 +msgid "Use WebSocket" +msgstr "使用WebSocket" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:170 +msgid "Use a proxy server for all protocols." +msgstr "为所有协议设置代理服务器。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:190 +msgid "" +"Use the certificate authorities in FILE to verify the peers. The certificate " +"file must be in PEM format and can contain multiple CA certificates." +msgstr "" +"使用文件中的证书来验证对端。证书文件必须为PEM格式并且可以包含多个证书。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:141 +msgid "" +"Use the certificate in FILE for RPC server. The certificate must be either " +"in PKCS12 (.p12, .pfx) or in PEM format.
PKCS12 files must contain the " +"certificate, a key and optionally a chain of additional certificates. Only " +"PKCS12 files with a blank import password can be opened!
When using PEM, " +"you have to specify the \"RPC private key\" as well." +msgstr "" +"使用文件中的证书作为RPC服务器。证书必须为PKCS12 (.p12, .pfx) 或者PEM格" +"式。
PKCS12 文件必须包含证书,一个密钥和可选的附加证书链。只有导入密码为" +"空白的PKCS12文件才能被打开。
使用PEM 时,你必须同时指定“RPC私钥”。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:196 +msgid "" +"Use the client certificate in FILE. The certificate must be either in PKCS12 " +"(.p12, .pfx) or in PEM format.
PKCS12 files must contain the " +"certificate, a key and optionally a chain of additional certificates. Only " +"PKCS12 files with a blank import password can be opened!
When using PEM, " +"you have to specify the \"Private key\" as well." +msgstr "" +"使用文件中的客户端证书。证书必须为PKCS12 (.p12, .pfx) 或者PEM格式。
PKCS12文件必须包含证书,一个密钥和可选的附加证书链。只有导入密码为空白的 " +"PKCS12文件才能被打开。
使用PEM时,你必须同时指定“RPC私钥”。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:150 +msgid "" +"Use the private key in FILE for RPC server. The private key must be " +"decrypted and in PEM format." +msgstr "使用文件中的私钥作为RPC服务器。私钥必须解密并且为PEM格式。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:204 +msgid "" +"Use the private key in FILE. The private key must be decrypted and in PEM " +"format. The behavior when encrypted one is given is undefined." +msgstr "使用文件中的私钥。私钥必须解密并且为PEM格式,不支持加密的私钥。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:271 +msgid "User agent" +msgstr "User Agent" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:116 +msgid "Username & Password" +msgstr "用户名与密码" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:183 +msgid "" +"Verify the peer using certificates specified in \"CA certificate\" option." +msgstr "使用“CA证书”里配置的证书来验证对端。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:90 +msgid "Warn" +msgstr "警告" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:244 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:356 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:363 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:383 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:443 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:471 +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:478 +msgid "You can append K or M." +msgstr "你可以追加K或者M。" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:457 +msgid "falloc" +msgstr "" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:455 +msgid "prealloc" +msgstr "" + +#: applications/luci-app-aria2/luasrc/model/cbi/aria2/config.lua:456 +msgid "trunc" +msgstr "" + +msgid "AriaNg" +msgstr "打开AriaNg的Web管理界面" + +msgid "WebUI-Aria2" +msgstr "打开WebUI-Aria2的Web管理界面" + +msgid "YAAW" +msgstr "打开YAAW的Web管理界面" + +msgid "Enable Aria2 Pro" +msgstr "启用扩展功能" + +msgid "Aria2 Pro file" +msgstr "扩展保存目录" + +msgid "Use the configuration scheme of p3terx to realize the enhancement and expansion of aria2 function." +msgstr "" +"使用P3TERX的配置方案实现Aria2的增强和扩展,
默认放置在(包括系统配置)/usr/share/aria2下。" + +msgid "generate randomly" +msgstr "随机生成" + +msgid "The webui port defaults to 6800." +msgstr "WebUI端口默认6800。" + +msgid "When enabled, the original system configuration directory will be merged." +msgstr "启用后,系统配置文件的目录合并此处。" + +msgid "AriaNg" +msgstr "打开AriaNg的Web管理界面" + +msgid "WebUI-Aria2" +msgstr "打开WebUI-Aria2的Web管理界面" + +msgid "YAAW" +msgstr "打开YAAW的Web管理界面" \ No newline at end of file diff --git a/luci-app-aria2/root/etc/uci-defaults/40_luci-aria2 b/luci-app-aria2/root/etc/uci-defaults/40_luci-aria2 new file mode 100644 index 0000000..fc6190d --- /dev/null +++ b/luci-app-aria2/root/etc/uci-defaults/40_luci-aria2 @@ -0,0 +1,25 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@aria2[-1] + add ucitrack aria2 + set ucitrack.@aria2[-1].init=aria2 + commit ucitrack +EOF + +if [ ."$(uci -q get aria2.main)" != ."aria2" ]; then + uci -q batch <<-EOF >/dev/null + add aria2 aria2 + rename aria2.@aria2[-1]="main" + set aria2.main.enabled=0 + set aria2.main.dir="/var/run/aria2" + set aria2.main.config_dir="/var/etc/aria2" + add_list aria2.main.header="" + add_list aria2.main.bt_tracker="" + add_list aria2.main.extra_setting="" + commit aria2 + EOF +fi + +rm -f /tmp/luci-indexcache +exit 0