.* to download everything from the feed." )
41 | match.template = "rtorrent/tvalue"
42 | match.rmempty = false
43 | match.rows = 1
44 |
45 | exclude = rss_rule:option(TextValue, "exclude", "Exclude",
46 | 'Exclude torrents that names match this (case-insensitive) lua pattern.'
47 | % "https://www.lua.org/pil/20.2.html")
48 | exclude.rows = 1
49 |
50 | minsize = rss_rule:option(Value, "minsize", "Min size (MiB):")
51 |
52 | maxsize = rss_rule:option(Value, "maxsize", "Max size (MiB):")
53 |
54 | local feeds = common.uci_sections(map.config, "rss-feed")
55 | if feeds:empty() then
56 | feed = rss_rule:option(DummyValue, "feed", "Feed")
57 | feed.template = "rtorrent/dvalue"
58 | feed.rawhtml = true
59 | feed.value = '/root/.rtorrent.rc config file.")
26 | form.handle = function(self, state, data)
27 | if state == FORM_VALID then luci.http.redirect(nixio.getenv("REQUEST_URI")) end
28 | return true
29 | end
30 |
31 | bandwidth_limits = form:section(SimpleSection, "Bandwidth limits")
32 |
33 | download_limit = bandwidth_limits:option(Value, "global_down_max_rate_kb", "Download limit (KiB/sec)",
34 | "Global download rate (0: unlimited).throttle.global_down.max_rate.set_kb.")
36 | download_limit.template = "rtorrent/value"
37 | download_limit.rmempty = false
38 | download_limit.default = throttle:get("global_down_max_rate") / 1024
39 | download_limit.datatype = "uinteger"
40 | download_limit.write = function(self, section, value)
41 | if value ~= tostring(download_limit.default) then
42 | rtorrent.call("throttle.global_down.max_rate.set_kb", "", value)
43 | end
44 | end
45 |
46 | upload_limit = bandwidth_limits:option(Value, "global_up_max_rate_kb", "Upload limit (KiB/sec)",
47 | "Global upload rate (0: unlimited).throttle.global_up.max_rate.set_kb.")
49 | upload_limit.template = "rtorrent/value"
50 | upload_limit.rmempty = false
51 | upload_limit.default = throttle:get("global_up_max_rate") / 1024
52 | upload_limit.datatype = "uinteger"
53 | upload_limit.write = function(self, section, value)
54 | if value ~= tostring(upload_limit.default) then
55 | rtorrent.call("throttle.global_up.max_rate.set_kb", "", value)
56 | end
57 | end
58 |
59 | global_limits = form:section(SimpleSection, "Global limits")
60 |
61 | max_downloads_global = global_limits:option(Value, "max_downloads_global", "Download slots",
62 | "Maximum number of simultaneous downloads (0: unlimited).throttle.max_downloads.global.set.")
64 | max_downloads_global.rmempty = false
65 | max_downloads_global.default = throttle:get("max_downloads_global")
66 | max_downloads_global.datatype = "uinteger"
67 | max_downloads_global.write = function(self, section, value)
68 | if value ~= tostring(max_downloads_global.default) then
69 | rtorrent.call("throttle.max_downloads.global.set", "", value)
70 | end
71 | end
72 |
73 | max_uploads_global = global_limits:option(Value, "max_uploads_global", "Upload slots",
74 | "Maximum number of simultaneous uploads (0: unlimited).throttle.max_uploads.global.set.")
76 | max_uploads_global.rmempty = false
77 | max_uploads_global.default = throttle:get("max_uploads_global")
78 | max_uploads_global.datatype = "uinteger"
79 | max_uploads_global.write = function(self, section, value)
80 | if value ~= tostring(max_uploads_global.default) then
81 | rtorrent.call("throttle.max_uploads.global.set", "", value)
82 | end
83 | end
84 |
85 | torrent_limits = form:section(SimpleSection, "Torrent limits")
86 |
87 | max_downloads = torrent_limits:option(Value, "max_downloads", "Maximum downloads",
88 | "Maximum number of simultanious downloads per torrent (0: unlimited).throttle.max_downloads.set.")
90 | max_downloads.rmempty = false
91 | max_downloads.default = throttle:get("max_downloads")
92 | max_downloads.datatype = "uinteger"
93 | max_downloads.write = function(self, section, value)
94 | if value ~= tostring(max_downloads.default) then
95 | rtorrent.call("throttle.max_downloads.set", "", value)
96 | end
97 | end
98 |
99 | max_uploads = torrent_limits:option(Value, "max_uploads", "Maximum uploads",
100 | "Maximum number of simultanious uploads per torrent (0: unlimited).throttle.max_uploads.set.")
102 | max_uploads.rmempty = false
103 | max_uploads.default = throttle:get("max_uploads")
104 | max_uploads.datatype = "uinteger"
105 | max_uploads.write = function(self, section, value)
106 | if value ~= tostring(max_uploads.default) then
107 | rtorrent.call("throttle.max_uploads.set", "", value)
108 | end
109 | end
110 |
111 | min_peers = torrent_limits:option(Value, "min_peers", "Minimum peers",
112 | "Minimum number of peers to connect to per torrent.throttle.min_peers.normal.set.")
114 | min_peers.rmempty = false
115 | min_peers.default = throttle:get("min_peers_normal")
116 | min_peers.datatype = "uinteger"
117 | min_peers.write = function(self, section, value)
118 | if value ~= tostring(min_peers.default) then
119 | rtorrent.call("throttle.min_peers.normal.set", "", value)
120 | end
121 | end
122 |
123 | max_peers = torrent_limits:option(Value, "max_peers", "Maximum peers",
124 | "Maximum number of peers to connect to per torrent.throttle.max_peers.normal.set.")
126 | max_peers.rmempty = false
127 | max_peers.default = throttle:get("max_peers_normal")
128 | max_peers.datatype = "uinteger"
129 | max_peers.write = function(self, section, value)
130 | if value ~= tostring(max_peers.default) then
131 | rtorrent.call("throttle.max_peers.normal.set", "", value)
132 | end
133 | end
134 |
135 | min_seeds = torrent_limits:option(Value, "min_seeds", "Minimum seeds",
136 | "Minimum number of seeds for completed torrents (-1: same as peers).throttle.min_peers.seed.set.")
138 | min_seeds.rmempty = false
139 | min_seeds.default = throttle:get("min_peers_seed")
140 | min_seeds.datatype = "integer"
141 | min_seeds.write = function(self, section, value)
142 | if value ~= tostring(min_seeds.default) then
143 | rtorrent.call("throttle.min_peers.seed.set", "", value)
144 | end
145 | end
146 |
147 | max_seeds = torrent_limits:option(Value, "max_seeds", "Maximum seeds",
148 | "Maximum number of seeds for completed torrents (-1: same as peers).throttle.max_peers.seed.set.")
150 | max_seeds.rmempty = false
151 | max_seeds.default = throttle:get("max_peers_seed")
152 | max_seeds.datatype = "integer"
153 | max_seeds.write = function(self, section, value)
154 | if value ~= tostring(max_seeds.default) then
155 | rtorrent.call("throttle.max_peers.seed.set", "", value)
156 | end
157 | end
158 |
159 | peers_numwant = torrent_limits:option(Value, "peers_numwant", "Wished peers",
160 | "Wished number of peers (-1: disable feature).trackers.numwant.set.")
162 | peers_numwant.rmempty = false
163 | peers_numwant.default = trackers:get("numwant")
164 | peers_numwant.datatype = "integer"
165 | peers_numwant.write = function(self, section, value)
166 | if value ~= tostring(peers_numwant.default) then
167 | rtorrent.call("trackers.numwant.set", "", value)
168 | end
169 | end
170 |
171 | network_limits = form:section(SimpleSection, "Network limits")
172 |
173 | max_http_requests = network_limits:option(Value, "max_http_requests", "Maximum http requests",
174 | "Maximum number of simultaneous HTTP request (used by announce / scrape requests).network.http.max_open.set.")
176 | max_http_requests.rmempty = false
177 | max_http_requests.default = network:get("http_max_open")
178 | max_http_requests.datatype = "uinteger"
179 | max_http_requests.write = function(self, section, value)
180 | if value ~= tostring(max_http_requests.default) then
181 | rtorrent.call("network.http.max_open.set", "", value)
182 | end
183 | end
184 |
185 | max_open_files = network_limits:option(Value, "max_open_files", "Maximum open files",
186 | "Maximum number of open files rTorrent can keep open.network.max_open_files.set.")
188 | max_open_files.rmempty = false
189 | max_open_files.default = network:get("max_open_files")
190 | max_open_files.datatype = "uinteger"
191 | max_open_files.write = function(self, section, value)
192 | if value ~= tostring(max_open_files.default) then
193 | rtorrent.call("network.max_open_files.set", "", value)
194 | end
195 | end
196 |
197 | max_open_sockets = network_limits:option(Value, "max_open_sockets", "Maximum open sockets",
198 | "Maximum number of connections rTorrent can accept / make (sockets).network.max_open_sockets.set.")
200 | max_open_sockets.rmempty = false
201 | max_open_sockets.default = network:get("max_open_sockets")
202 | max_open_sockets.datatype = "uinteger"
203 | max_open_sockets.write = function(self, section, value)
204 | if value ~= tostring(max_open_sockets.default) then
205 | rtorrent.call("network.max_open_sockets.set", "", value)
206 | end
207 | end
208 |
209 | max_xmlrpc_size = network_limits:option(Value, "max_xmlrpc_size", "Maximum XML-RPC size",
210 | "Maximum size of any XML-RPC requests in bytes.network.xmlrpc.size_limit.set.")
213 | max_xmlrpc_size.rmempty = false
214 | max_xmlrpc_size.default = network:get("xmlrpc_size_limit")
215 | max_xmlrpc_size.write = function(self, section, value)
216 | if value ~= tostring(max_xmlrpc_size.default) then
217 | rtorrent.call("network.xmlrpc.size_limit.set", "", value)
218 | end
219 | end
220 |
221 | return form
222 |
--------------------------------------------------------------------------------
/src/usr/lib/lua/rss_downloader.lua:
--------------------------------------------------------------------------------
1 | #!/usr/bin/lua
2 | -- Copyright 2014-2021 Sandor Balazsi schedule2 = "
297 | .. "rss_downloader, 60, 300, ((execute.throw, /usr/lib/lua/rss_downloader.lua, --uci))"
298 | end
299 | end
300 |
301 | function set_cookie(name, data, attributes)
302 | attributes = attributes or ""
303 | lhttp.header("Set-Cookie", "%s=%s; Path=%s; SameSite=Strict%s" % {
304 | name, data and util.serialize_data(data):urlencode() or "", build_url("admin", "rtorrent"), attributes
305 | })
306 | end
307 |
308 | function get_cookie(name, default)
309 | local cookie = lhttp.getcookie(name)
310 | return cookie and util.restore_data(cookie) or default
311 | end
312 |
313 | function remove_cookie(name)
314 | set_cookie(name, nil, "; Max-Age=0")
315 | end
316 |
--------------------------------------------------------------------------------
/src/usr/lib/lua/xmlrpc/init.lua:
--------------------------------------------------------------------------------
1 | -- Copyright 2003-2010 Kepler Project
2 | -- XML-RPC implementation for Lua.
3 |
4 | local lxp = require "lxp"
5 | local lom = require "lxp.lom"
6 |
7 | local assert, error, ipairs, pairs, select, type, tonumber, unpack = assert, error, ipairs, pairs, select, type, tonumber, unpack
8 | local format, gsub, strfind, strsub = string.format, string.gsub, string.find, string.sub
9 | local concat, tinsert = table.concat, table.insert
10 | local ceil = math.ceil
11 | local parse = lom.parse
12 |
13 | module (...)
14 |
15 | _COPYRIGHT = "Copyright (C) 2003-2014 Kepler Project"
16 | _DESCRIPTION = "LuaXMLRPC is a library to make remote procedure calls using XML-RPC"
17 | _PKGNAME = "LuaXMLRPC"
18 | _VERSION_MAJOR = 1
19 | _VERSION_MINOR = 2
20 | _VERSION_MICRO = 2
21 | _VERSION = _VERSION_MAJOR .. "." .. _VERSION_MINOR .. "." .. _VERSION_MICRO
22 |
23 | ---------------------------------------------------------------------
24 | -- XML-RPC Parser
25 | ---------------------------------------------------------------------
26 |
27 | ---------------------------------------------------------------------
28 | local function trim (s)
29 | return (type(s) == "string" and gsub (s, "^%s*(.-)%s*$", "%1"))
30 | end
31 |
32 | ---------------------------------------------------------------------
33 | local function is_space (s)
34 | return type(s) == "string" and trim(s) == ""
35 | end
36 |
37 | ---------------------------------------------------------------------
38 | -- Get next non-space element from tab starting from index i.
39 | -- @param tab Table.
40 | -- @param i Numeric index.
41 | -- @return Object and its position on table; nil and an invalid index
42 | -- when there is no more elements.
43 | ---------------------------------------------------------------------
44 | function next_nonspace (tab, i)
45 | if not i then i = 1 end
46 | while is_space (tab[i]) do i = i+1 end
47 | return tab[i], i
48 | end
49 |
50 | ---------------------------------------------------------------------
51 | -- Get next element of tab with the given tag starting from index i.
52 | -- @param tab Table.
53 | -- @param tag String with the name of the tag.
54 | -- @param i Numeric index.
55 | -- @return Object and its position on table; nil and an invalid index
56 | -- when there is no more elements.
57 | ---------------------------------------------------------------------
58 | local function next_tag (tab, tag, i)
59 | if not i then i = 1 end
60 | while tab[i] do
61 | if type (tab[i]) == "table" and tab[i].tag == tag then
62 | return tab[i], i
63 | end
64 | i = i + 1
65 | end
66 | return nil, i
67 | end
68 |
69 | ---------------------------------------------------------------------
70 | local function x2number (tab)
71 | if tab.tag == "int" or tab.tag == "i4" or tab.tag == "i8" or tab.tag == "double" then
72 | return tonumber (next_nonspace (tab, 1), 10)
73 | end
74 | end
75 |
76 | ---------------------------------------------------------------------
77 | local function x2boolean (tab)
78 | if tab.tag == "boolean" then
79 | local v = next_nonspace (tab, 1)
80 | return v == true or v == "true" or tonumber (v) == 1 or false
81 | end
82 | end
83 |
84 | ---------------------------------------------------------------------
85 | local function x2string (tab)
86 | return tab.tag == "string" and (tab[1] or "")
87 | end
88 |
89 | ---------------------------------------------------------------------
90 | local function x2date (tab)
91 | return tab.tag == "dateTime.iso8601" and next_nonspace (tab, 1)
92 | end
93 |
94 | ---------------------------------------------------------------------
95 | local function x2base64 (tab)
96 | return tab.tag == "base64" and next_nonspace (tab, 1)
97 | end
98 |
99 | ---------------------------------------------------------------------
100 | local function x2name (tab)
101 | return tab.tag == "name" and next_nonspace (tab, 1)
102 | end
103 |
104 | local x2value
105 |
106 | ---------------------------------------------------------------------
107 | -- Disassemble a member object in its name and value parts.
108 | -- @param tab Table with a DOM representation.
109 | -- @return String (name) and Object (value).
110 | -- @see x2name, x2value.
111 | ---------------------------------------------------------------------
112 | local function x2member (tab)
113 | return
114 | x2name (next_tag(tab,"name")),
115 | x2value (next_tag(tab,"value"))
116 | end
117 |
118 | ---------------------------------------------------------------------
119 | -- Disassemble a struct object into a Lua table.
120 | -- @param tab Table with DOM representation.
121 | -- @return Table with "name = value" pairs.
122 | ---------------------------------------------------------------------
123 | local function x2struct (tab)
124 | if tab.tag == "struct" then
125 | local res = {}
126 | for i = 1, #tab do
127 | if not is_space (tab[i]) then
128 | local name, val = x2member (tab[i])
129 | res[name] = val
130 | end
131 | end
132 | return res
133 | end
134 | end
135 |
136 | ---------------------------------------------------------------------
137 | -- Disassemble an array object into a Lua table.
138 | -- @param tab Table with DOM representation.
139 | -- @return Table.
140 | ---------------------------------------------------------------------
141 | local function x2array (tab)
142 | if tab.tag == "array" then
143 | local d = next_tag (tab, "data")
144 | local res = {}
145 | for i = 1, #d do
146 | if not is_space (d[i]) then
147 | tinsert (res, x2value (d[i]))
148 | end
149 | end
150 | return res
151 | end
152 | end
153 |
154 | ---------------------------------------------------------------------
155 | local xmlrpc_types = {
156 | int = x2number,
157 | i4 = x2number,
158 | i8 = x2number,
159 | boolean = x2boolean,
160 | string = x2string,
161 | double = x2number,
162 | ["dateTime.iso8601"] = x2date,
163 | base64 = x2base64,
164 | struct = x2struct,
165 | array = x2array,
166 | }
167 |
168 | local x2param, x2fault
169 |
170 | ---------------------------------------------------------------------
171 | -- Disassemble a methodResponse into a Lua object.
172 | -- @param tab Table with DOM representation.
173 | -- @return Boolean (indicating wether the response was successful)
174 | -- and (a Lua object representing the return values OR the fault
175 | -- string and the fault code).
176 | ---------------------------------------------------------------------
177 | local function x2methodResponse (tab)
178 | assert (type(tab) == "table", "Not a table")
179 | assert (tab.tag == "methodResponse",
180 | "Not a `methodResponse' tag: "..tab.tag)
181 | local t = next_nonspace (tab, 1)
182 | if t.tag == "params" then
183 | return true, unpack (x2param (t))
184 | elseif t.tag == "fault" then
185 | local f = x2fault (t)
186 | return false, f.faultString, f.faultCode
187 | else
188 | error ("Couldn't find a