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