2
0

config.lua 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. -- Copyright 2017-2019 Xingwang Liao <kuoruan@gmail.com>
  2. -- Licensed to the public under the MIT License.
  3. local sys = require "luci.sys"
  4. local util = require "luci.util"
  5. local m, s, o
  6. local function aria2_info()
  7. if sys.call("command -v aria2c >/dev/null") ~= 0 then
  8. return nil
  9. end
  10. local info = {}
  11. local line
  12. for line in util.execi("aria2c -v 2>/dev/null | grep -E '^(aria2 version|Enabled Features)'") do
  13. if line:match("^aria2 version") then
  14. local _, _, v = line:find("([%d%.]+)$")
  15. info.version = v
  16. elseif line:match("^Enabled Features") then
  17. info.gzip = line:find("GZip") ~= nil
  18. info.https = line:find("HTTPS") ~= nil
  19. info.bt = line:find("BitTorrent") ~= nil
  20. info.sftp = line:find("SFTP") ~= nil
  21. info.adns = line:find("Async DNS") ~= nil
  22. info.cookie = line:find("Firefox3 Cookie") ~= nil
  23. end
  24. end
  25. return info
  26. end
  27. local aria2 = aria2_info()
  28. m = Map("aria2", "%s - %s" % { translate("Aria2"), translate("Settings") },
  29. "<p>%s</p><p>%s</p>" % {
  30. translate("Aria2 is a lightweight multi-protocol &amp; multi-source, cross platform download utility."),
  31. translatef("For more information, please visit: %s",
  32. "<a href=\"https://aria2.github.io\" target=\"_blank\">https://aria2.github.io</a>")
  33. })
  34. if not aria2 then
  35. m:section(SimpleSection, nil, "<span style=\"color: red;\">%s</span>" %
  36. translate("Error: Can't find aria2c in PATH, please reinstall aria2."))
  37. m.reset = false
  38. m.submit = false
  39. return m
  40. end
  41. m:append(Template("aria2/settings_header"))
  42. s = m:section(NamedSection, "main", "aria2")
  43. s.addremove = false
  44. s.anonymous = true
  45. s:tab("basic", translate("Basic Options"))
  46. o = s:taboption("basic", Flag, "enabled", translate("Enabled"))
  47. o.rmempty = false
  48. o = s:taboption("basic", ListValue, "user", translate("Run daemon as user"),
  49. translate("Leave blank to use default user."))
  50. o:value("")
  51. local user
  52. for user in util.execi("cat /etc/passwd | cut -d':' -f1") do
  53. o:value(user)
  54. end
  55. o = s:taboption("basic", Value, "dir", translate("Download directory"),
  56. translate("The directory to store the downloaded file. For example <code>/mnt/sda1</code>."))
  57. o.rmempty = false
  58. o = s:taboption("basic", Value, "config_dir", translate("Config file directory"),
  59. translate("The directory to store the config file, session file and DHT file."))
  60. o.placeholder = "/var/etc/aria2"
  61. o = s:taboption("basic", Flag, "enable_logging", translate("Enable logging"))
  62. o.rmempty = false
  63. o = s:taboption("basic", Value, "log", translate("Log file"),
  64. translate("The file name of the log file."))
  65. o:depends("enable_logging", "1")
  66. o.placeholder = "/var/log/aria2.log"
  67. o = s:taboption("basic", ListValue, "log_level", translate("Log level"))
  68. o:depends("enable_logging", "1")
  69. o:value("debug", translate("Debug"))
  70. o:value("info", translate("Info"))
  71. o:value("notice", translate("Notice"))
  72. o:value("warn", translate("Warn"))
  73. o:value("error", translate("Error"))
  74. o.default = "warn"
  75. o = s:taboption("basic", Value, "max_concurrent_downloads", translate("Max concurrent downloads"))
  76. o.placeholder = "5"
  77. s:tab("rpc", translate("RPC Options"))
  78. o = s:taboption("rpc", Flag, "pause", translate("Pause"), translate("Pause download after added."))
  79. o.enabled = "true"
  80. o.disabled = "false"
  81. o.default = "false"
  82. o = s:taboption("rpc", Flag, "pause_metadata", translate("Pause metadata"),
  83. translate("Pause downloads created as a result of metadata download."))
  84. o.enabled = "true"
  85. o.disabled = "false"
  86. o.default = "false"
  87. o = s:taboption("rpc", Value, "rpc_listen_port", translate("RPC port"))
  88. o.datatype = "range(1024,65535)"
  89. o.placeholder = "6800"
  90. o = s:taboption("rpc", ListValue, "rpc_auth_method", translate("RPC authentication method"))
  91. o:value("none", translate("No Authentication"))
  92. o:value("user_pass", translate("Username & Password"))
  93. o:value("token", translate("Token"))
  94. o = s:taboption("rpc", Value, "rpc_user", translate("RPC username"))
  95. o:depends("rpc_auth_method", "user_pass")
  96. o = s:taboption("rpc", Value, "rpc_passwd", translate("RPC password"))
  97. o:depends("rpc_auth_method", "user_pass")
  98. o.password = true
  99. o = s:taboption("rpc", Value, "rpc_secret", translate("RPC token"))
  100. o:depends("rpc_auth_method", "token")
  101. o.template = "aria2/value_with_btn"
  102. o.btntext = translate("Generate Randomly")
  103. o.btnclick = "randomToken();"
  104. if aria2.https then
  105. o = s:taboption("rpc", Flag, "rpc_secure", translate("RPC secure"),
  106. translate("RPC transport will be encrypted by SSL/TLS. The RPC clients must use https"
  107. .. " scheme to access the server. For WebSocket client, use wss scheme."))
  108. o.enabled = "true"
  109. o.disabled = "false"
  110. o.rmempty = false
  111. o = s:taboption("rpc", Value, "rpc_certificate", translate("RPC certificate"),
  112. translate("Use the certificate in FILE for RPC server. The certificate must be either"
  113. .. " in PKCS12 (.p12, .pfx) or in PEM format.<br/>PKCS12 files must contain the"
  114. .. " certificate, a key and optionally a chain of additional certificates. Only PKCS12"
  115. .. " files with a blank import password can be opened!<br/>When using PEM, you have to"
  116. .. " specify the \"RPC private key\" as well."))
  117. o:depends("rpc_secure", "true")
  118. o.datatype = "file"
  119. o = s:taboption("rpc", Value, "rpc_private_key", translate("RPC private key"),
  120. translate("Use the private key in FILE for RPC server. The private key must be"
  121. .. " decrypted and in PEM format."))
  122. o:depends("rpc_secure", "true")
  123. o.datatype = "file"
  124. end
  125. o = s:taboption("rpc", Flag, "_use_ws", translate("Use WebSocket"))
  126. o = s:taboption("rpc", Value, "_rpc_url", translate("Json-RPC URL"))
  127. o.template = "aria2/value_with_btn"
  128. o.onmouseover = "this.focus();this.select();"
  129. o.btntext = translate("Show URL")
  130. o.btnclick = "showRPCURL();"
  131. s:tab("http", translate("HTTP/FTP/SFTP Options"))
  132. o = s:taboption("http", Flag, "enable_proxy", translate("Enable proxy"))
  133. o.rmempty = false
  134. o = s:taboption("http", Value, "all_proxy", translate("All proxy"),
  135. translate("Use a proxy server for all protocols."))
  136. o:depends("enable_proxy", "1")
  137. o.placeholder = "[http://][USER:PASSWORD@]HOST[:PORT]"
  138. o = s:taboption("http", Value, "all_proxy_user", translate("Proxy user"))
  139. o:depends("enable_proxy", "1")
  140. o = s:taboption("http", Value, "all_proxy_passwd", translate("Proxy password"))
  141. o:depends("enable_proxy", "1")
  142. o.password = true
  143. if aria2.https then
  144. o = s:taboption("http", Flag, "check_certificate", translate("Check certificate"),
  145. translate("Verify the peer using certificates specified in \"CA certificate\" option."))
  146. o.enabled = "true"
  147. o.disabled = "false"
  148. o.default = "true"
  149. o.rmempty = false
  150. o = s:taboption("http", Value, "ca_certificate", translate("CA certificate"),
  151. translate("Use the certificate authorities in FILE to verify the peers. The certificate"
  152. .. " file must be in PEM format and can contain multiple CA certificates."))
  153. o:depends("check_certificate", "true")
  154. o.datatype = "file"
  155. o = s:taboption("http", Value, "certificate", translate("Certificate"),
  156. translate("Use the client certificate in FILE. The certificate must be either in PKCS12"
  157. .. " (.p12, .pfx) or in PEM format.<br/>PKCS12 files must contain the certificate, a"
  158. .. " key and optionally a chain of additional certificates. Only PKCS12 files with a"
  159. .. " blank import password can be opened!<br/>When using PEM, you have to specify the"
  160. .. " \"Private key\" as well."))
  161. o.datatype = "file"
  162. o = s:taboption("http", Value, "private_key", translate("Private key"),
  163. translate("Use the private key in FILE. The private key must be decrypted and in PEM"
  164. .. " format. The behavior when encrypted one is given is undefined."))
  165. o.datatype = "file"
  166. end
  167. if aria2.gzip then
  168. o = s:taboption("http", Flag, "http_accept_gzip", translate("HTTP accept gzip"),
  169. translate("Send <code>Accept: deflate, gzip</code> request header and inflate response"
  170. .. " if remote server responds with <code>Content-Encoding: gzip</code> or"
  171. .. " <code>Content-Encoding: deflate</code>."))
  172. o.enabled = "true"
  173. o.disabled = "false"
  174. o.default = "false"
  175. end
  176. o = s:taboption("http", Flag, "http_no_cache", translate("HTTP no cache"),
  177. translate("Send <code>Cache-Control: no-cache</code> and <code>Pragma: no-cache</code>"
  178. .. " header to avoid cached content. If disabled, these headers are not sent and you"
  179. .. " can add Cache-Control header with a directive you like using \"Header\" option."))
  180. o.enabled = "true"
  181. o.disabled = "false"
  182. o.default = "false"
  183. o = s:taboption("http", DynamicList, "header", translate("Header"),
  184. translate("Append HEADERs to HTTP request header."))
  185. o = s:taboption("http", Value, "connect_timeout", translate("Connect timeout"),
  186. translate("Set the connect timeout in seconds to establish connection to HTTP/FTP/proxy server." ..
  187. " After the connection is established, this option makes no effect and \"Timeout\" option is used instead."))
  188. o.datatype = "uinteger"
  189. o.placeholder = "60"
  190. o = s:taboption("http", Value, "timeout", translate("Timeout"))
  191. o.datatype = "uinteger"
  192. o.placeholder = "60"
  193. o = s:taboption("http", Value, "lowest_speed_limit", translate("Lowest speed limit"),
  194. "%s %s" % {
  195. translate("Close connection if download speed is lower than or equal to this value (bytes per sec). " ..
  196. "0 means has no lowest speed limit."),
  197. translate("You can append K or M.")
  198. })
  199. o.placeholder = "0"
  200. o = s:taboption("http", Value, "max_connection_per_server", translate("Max connection per server"),
  201. translate("The maximum number of connections to one server for each download."))
  202. o.datatype = "uinteger"
  203. o.placeholder = "1"
  204. o = s:taboption("http", Value, "split", translate("Max number of split"),
  205. translate("Download a file using N connections."))
  206. o.datatype = "uinteger"
  207. o.placeholder = "5"
  208. o = s:taboption("http", Value, "min_split_size", translate("Min split size"),
  209. translate("Don't split less than 2*SIZE byte range. Possible values: 1M-1024M."))
  210. o.placeholder = "20M"
  211. o = s:taboption("http", Value, "max_tries", translate("Max tries"))
  212. o.datatype = "uinteger"
  213. o.placeholder = "5"
  214. o = s:taboption("http", Value, "retry_wait", translate("Retry wait"),
  215. translate("Set the seconds to wait between retries."))
  216. o.datatype = "uinteger"
  217. o.placeholder = "0"
  218. o = s:taboption("http", Value, "user_agent", translate("User agent"),
  219. translate("Set user agent for HTTP(S) downloads."))
  220. o.placeholder = "aria2/%s" % { aria2.version and aria2.version or "$VERSION" }
  221. if aria2.bt then
  222. s:tab("bt", translate("BitTorrent Options"))
  223. o = s:taboption("bt", Flag, "enable_dht", translate("IPv4 <abbr title=\"Distributed Hash Table\">DHT</abbr> enabled"),
  224. "%s %s" % {
  225. translate("Enable IPv4 DHT functionality. It also enables UDP tracker support."),
  226. translate("This option will be ignored if a private flag is set in a torrent.")
  227. })
  228. o.enabled = "true"
  229. o.disabled = "false"
  230. o.default = "true"
  231. o.rmempty = false
  232. o = s:taboption("bt", Flag, "enable_dht6", translate("IPv6 <abbr title=\"Distributed Hash Table\">DHT</abbr> enabled"),
  233. "%s %s" % {
  234. translate("Enable IPv6 DHT functionality."),
  235. translate("This option will be ignored if a private flag is set in a torrent.")
  236. })
  237. o.enabled = "true"
  238. o.disabled = "false"
  239. o = s:taboption("bt", Flag, "bt_enable_lpd", translate("<abbr title=\"Local Peer Discovery\">LPD</abbr> enabled"),
  240. "%s %s" % {
  241. translate("Enable Local Peer Discovery."),
  242. translate("This option will be ignored if a private flag is set in a torrent.")
  243. })
  244. o.enabled = "true"
  245. o.disabled = "false"
  246. o.default = "false"
  247. o = s:taboption("bt", Flag, "enable_peer_exchange", translate("Enable peer exchange"),
  248. "%s %s" % {
  249. translate("Enable Peer Exchange extension."),
  250. translate("This option will be ignored if a private flag is set in a torrent.")
  251. })
  252. o.enabled = "true"
  253. o.disabled = "false"
  254. o.default = "true"
  255. o.rmempty = false
  256. o = s:taboption("bt", Flag, "bt_save_metadata", translate("Save metadata"),
  257. translate("Save meta data as \".torrent\" file. This option has effect only when BitTorrent"
  258. .. " Magnet URI is used. The file name is hex encoded info hash with suffix \".torrent\"."))
  259. o.enabled = "true"
  260. o.disabled = "false"
  261. o.default = "false"
  262. o = s:taboption("bt", Flag, "bt_remove_unselected_file", translate("Remove unselected file"),
  263. translate("Removes the unselected files when download is completed in BitTorrent. Please"
  264. .. " use this option with care because it will actually remove files from your disk."))
  265. o.enabled = "true"
  266. o.disabled = "false"
  267. o.default = "false"
  268. o = s:taboption("bt", Flag, "bt_seed_unverified", translate("Seed unverified"),
  269. translate("Seed previously downloaded files without verifying piece hashes."))
  270. o.enabled = "true"
  271. o.disabled = "false"
  272. o.default = "false"
  273. o = s:taboption("bt", Value, "listen_port", translate("BitTorrent listen port"),
  274. translate("Set TCP port number for BitTorrent downloads. Accept format: \"6881,6885\","
  275. .. " \"6881-6999\" and \"6881-6889,6999\". Make sure that the specified ports are open"
  276. .. " for incoming TCP traffic."))
  277. o.placeholder = "6881-6999"
  278. o = s:taboption("bt", Value, "dht_listen_port", translate("DHT Listen port"),
  279. translate("Set UDP listening port used by DHT (IPv4, IPv6) and UDP tracker. Make sure that the "
  280. .. "specified ports are open for incoming UDP traffic."))
  281. o:depends("enable_dht", "true")
  282. o:depends("enable_dht6", "true")
  283. o.placeholder = "6881-6999"
  284. o = s:taboption("bt", ListValue, "follow_torrent", translate("Follow torrent"))
  285. o:value("true", translate("True"))
  286. o:value("false", translate("False"))
  287. o:value("mem", translate("Keep in memory"))
  288. o = s:taboption("bt", Value, "max_overall_upload_limit", translate("Max overall upload limit"),
  289. "%s %s" % {
  290. translate("Set max overall upload speed in bytes/sec. 0 means unrestricted."),
  291. translate("You can append K or M.")
  292. })
  293. o.placeholder = "0"
  294. o = s:taboption("bt", Value, "max_upload_limit", translate("Max upload limit"),
  295. "%s %s" % {
  296. translate("Set max upload speed per each torrent in bytes/sec. 0 means unrestricted."),
  297. translate("You can append K or M.")
  298. })
  299. o.placeholder = "0"
  300. o = s:taboption("bt", Value, "bt_max_open_files", translate("Max open files"),
  301. translate("Specify maximum number of files to open in multi-file BitTorrent download globally."))
  302. o.datatype = "uinteger"
  303. o.placeholder = "100"
  304. o = s:taboption("bt", Value, "bt_max_peers", translate("Max peers"),
  305. translate("Specify the maximum number of peers per torrent, 0 means unlimited."))
  306. o.datatype = "uinteger"
  307. o.placeholder = "55"
  308. o = s:taboption("bt", Value, "bt_request_peer_speed_limit", translate("Request peer speed limit"),
  309. "%s %s" % {
  310. translate("If the whole download speed of every torrent is lower than SPEED, aria2"
  311. .. " temporarily increases the number of peers to try for more download speed."
  312. .. " Configuring this option with your preferred download speed can increase your"
  313. .. " download speed in some cases."),
  314. translate("You can append K or M.")
  315. })
  316. o.placeholder = "50K"
  317. o = s:taboption("bt", Value, "bt_stop_timeout", translate("Stop timeout"),
  318. translate("Stop BitTorrent download if download speed is 0 in consecutive N seconds. If 0 is"
  319. .. " given, this feature is disabled."))
  320. o.datatype = "uinteger"
  321. o.placeholder = "0"
  322. o = s:taboption("bt", Value, "peer_id_prefix", translate("Prefix of peer ID"),
  323. translate("Specify the prefix of peer ID. The peer ID in BitTorrent is 20 byte length."
  324. .. " If more than 20 bytes are specified, only first 20 bytes are used. If less than 20"
  325. .. " bytes are specified, random byte data are added to make its length 20 bytes."))
  326. o.placeholder = "A2-%s-" % {
  327. aria2.version and string.gsub(aria2.version, "%.", "-") or "$MAJOR-$MINOR-$PATCH"
  328. }
  329. o = s:taboption("bt", Value, "seed_ratio", translate("Seed ratio"),
  330. translate("Specify share ratio. Seed completed torrents until share ratio reaches RATIO."
  331. .. " You are strongly encouraged to specify equals or more than 1.0 here. Specify 0.0 if"
  332. .. " you intend to do seeding regardless of share ratio."))
  333. o.datatype = "ufloat"
  334. o.placeholder = "1.0"
  335. o = s:taboption("bt", Value, "seed_time", translate("Seed time"),
  336. translate("Specify seeding time in minutes. If \"Seed ratio\" option is"
  337. .. " specified along with this option, seeding ends when at least one of the conditions"
  338. .. " is satisfied. Specifying 0 disables seeding after download completed."))
  339. o.datatype = "ufloat"
  340. o = s:taboption("bt", DynamicList, "bt_tracker", translate("Additional BT tracker"),
  341. translate("List of additional BitTorrent tracker's announce URI."))
  342. o.placeholder = "http://tracker.example.com/announce"
  343. end
  344. s:tab("advance", translate("Advanced Options"))
  345. o = s:taboption("advance", Flag, "disable_ipv6", translate("IPv6 disabled"),
  346. translate("Disable IPv6. This is useful if you have to use broken DNS and want to avoid terribly"
  347. .. " slow AAAA record lookup."))
  348. o.enabled = "true"
  349. o.disabled = "false"
  350. o.default = "false"
  351. o = s:taboption("advance", Value, "auto_save_interval", translate("Auto save interval"),
  352. translate("Save a control file (*.aria2) every N seconds. If 0 is given, a control file is not"
  353. .. " saved during download."))
  354. o.datatype = "range(0, 600)"
  355. o.placeholder = "60"
  356. o = s:taboption("advance", Value, "save_session_interval", translate("Save session interval"),
  357. translate("Save error/unfinished downloads to session file every N seconds. If 0 is given, file"
  358. .. " will be saved only when aria2 exits."))
  359. o.datatype = "uinteger"
  360. o.placeholder = "0"
  361. o = s:taboption("advance", Value, "disk_cache", translate("Disk cache"),
  362. "%s %s" % {
  363. translate("Enable disk cache (in bytes), set 0 to disabled."),
  364. translate("You can append K or M.")
  365. })
  366. o.placeholder = "16M"
  367. o = s:taboption("advance", ListValue, "file_allocation", translate("File allocation"),
  368. translate("Specify file allocation method. If you are using newer file systems such as ext4"
  369. .. " (with extents support), btrfs, xfs or NTFS (MinGW build only), \"falloc\" is your best choice."
  370. .. " It allocates large(few GiB) files almost instantly, but it may not be available if your system"
  371. .. " doesn't have posix_fallocate(3) function. Don't use \"falloc\" with legacy file systems such as"
  372. .. " ext3 and FAT32 because it takes almost same time as \"prealloc\" and it blocks aria2 entirely"
  373. .. " until allocation finishes."))
  374. o:value("none", translate("None"))
  375. o:value("prealloc", translate("prealloc"))
  376. o:value("trunc", translate("trunc"))
  377. o:value("falloc", translate("falloc"))
  378. o.default = "prealloc"
  379. o = s:taboption("advance", Flag, "force_save", translate("Force save"),
  380. translate("Save download to session file even if the download is completed or removed."
  381. .. " This option also saves control file in that situations. This may be useful to save"
  382. .. " BitTorrent seeding which is recognized as completed state."))
  383. o.enabled = "true"
  384. o.disabled = "false"
  385. o.default = "false"
  386. o = s:taboption("advance", Value, "max_overall_download_limit", translate("Max overall download limit"),
  387. "%s %s" % {
  388. translate("Set max overall download speed in bytes/sec. 0 means unrestricted."),
  389. translate("You can append K or M.")
  390. })
  391. o.placeholder = "0"
  392. o = s:taboption("advance", Value, "max_download_limit", translate("Max download limit"),
  393. "%s %s" % {
  394. translate("Set max download speed per each download in bytes/sec. 0 means unrestricted."),
  395. translate("You can append K or M.")
  396. })
  397. o.placeholder = "0"
  398. s = m:section(NamedSection, "main", "aria2", translate("Extra Settings"),
  399. translate("Settings in this section will be added to config file."))
  400. s.addremove = false
  401. s.anonymous = true
  402. o = s:option(DynamicList, "extra_settings", translate("Settings list"),
  403. translate("List of extra settings. Format: option=value, eg. <code>netrc-path=/tmp/.netrc</code>."))
  404. o.placeholder = "option=value"
  405. return m