-
Notifications
You must be signed in to change notification settings - Fork 12
/
rtorrent-ps.rc
450 lines (343 loc) · 33.6 KB
/
rtorrent-ps.rc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
# Standard PyroScope rTorrent Configuration slightly rewrited. Contains mainly UI enhacements and some useful commands.
# Set "pyro.extended" and "pyro.extended.ch" to 1 in main config to activate rTorrent-PS, rTorrent-PS-CH features, but ONLY if you actually run it!
##### begin: Defining and including color themes #####
# COMMAND: Defining selectable color theme configs
method.insert = cfg.theme.0, string|const|private, (cat,"color_scheme256-happy_pastel.rc")
method.insert = cfg.theme.1, string|const|private, (cat,"color_scheme256-solarized_yellow.rc")
method.insert = cfg.theme.2, string|const|private, (cat,"color_scheme256-solarized_blue.rc")
# COMMAND: Setting default theme config
method.insert = pyro.theme.selected, string|private, (cat,(cfg.theme.0))
# IMPORT: Import default color theme from external config
pyro.import = (pyro.theme.selected)
##### end: Defining and including color themes #####
##### begin: Useful command extensions #####
# LOG: Log extension switch setting
branch=pyro.extended=,print=rTorrent-PS\\\ features\\\ active!,print=rTorrent-PS\\\ features\\\ NOT\\\ active!
# COMMAND: To gracefully exit rtorrent
method.insert = quit, simple, "execute.throw=kill,-INT,(system.pid)"
# COMMAND: Provide dummy multi-methods for plain rTorrent
branch=(not, (pyro.extended)), ((method.insert, ui.column.render, multi|rlookup|static))
# COMMAND: Return startup time (can be used to calculate uptime)
method.insert = startup_time,value|const,$system.time=
# COMMAND: Returns elapsed time between 2 timestamps in the form of "6 years, 5 months, 18 days, 02:40:00" (year/month info isn't shown if their value is 0)
method.insert = get_elapsed_time, simple, "execute.capture=(cat,(pyro.bin_dir),getElapsedTime.sh), (argument.0), (argument.1)"
# COMMAND: Returns uptime (with the help of getElapsedTime.sh script) in the form of "Up: 6 years, 5 months, 18 days, 02:39:57" (year/month info isn't shown if their value is 0)
method.insert = uptime, simple, "print=\"Up: \", (cat, (get_elapsed_time,(system.time),(startup_time)))"
# COMMAND: Returns d.ratio as float formatted string
method.insert = d.get_ratio_float.front, private|simple, "math.div=(d.ratio),1000"
method.insert = d.get_ratio_float.back, private|simple, "math.div=(math.sub,(d.ratio),(math.mul,(math.div,(d.ratio),1000),1000)),10"
method.insert = d.get_ratio_float, simple, "cat=(chars.pad, (d.get_ratio_float.front), 3, \" \", 0 ) ,., (chars.pad, (chars.chop, (d.get_ratio_float.back), 2), 2, 0, 0)"
# EVENTS: Timestamps: 'tm_loaded' (time loaded into client), 'tm_started' (time of *first* start), 'tm_completed' (time of completion)
method.set_key = event.download.inserted_new, 00tm_loaded, ((d.custom.set, tm_loaded, ((cat,((system.time)))) ))
method.set_key = event.download.resumed, 00tm_started, {(branch, ((not,((d.custom,tm_started)))), ((d.custom.set, tm_started, (cat,(system.time)))) )}
method.set_key = event.download.finished, !tm_completed,((d.custom.set, tm_completed, ((cat,((system.time)))) ))
method.set_key = event.download.hash_done, !tm_completed,{(branch, ((and,((d.complete)),((not,((d.custom,tm_completed)))))), ((d.custom.set, tm_completed, (cat,(system.time)))) )}
# EVENTS: Timestamp 'tm_downloaded' (time when meta (torrent) file was downloaded)
method.insert = d.tm_downloaded, simple|private, "execute.capture=sh,-c,\"echo -n \$(stat -c %Y \\\"$1\\\")\",getDownloadedDate,(d.tied_to_file)"
method.set_key = event.download.inserted_new, 00tm_downloaded, ((d.custom.set, tm_downloaded, ((cat,((d.tm_downloaded)))) ))
# COMMAND/EVENTS/SCHEDULE: Timestamp 'last_active' for items that have peers
method.set_key = event.download.finished, !tm_last_active, ((d.custom.set, last_active, ((cat,((system.time)))) ))
method.set_key = event.download.resumed, !tm_last_active, {(branch, ((or,((d.peers_connected)),((not,((d.custom,last_active)))))), ((d.custom.set, last_active, (cat,(system.time)))) )}
schedule2 = pyro_update_last_active, 24, 42, ((d.multicall2, started, "branch=((d.peers_connected)),((d.custom.set, last_active, (cat,(system.time))))" ))
method.insert = d.last_active, simple, "if=(d.peers_connected), (cat,(system.time)), (d.custom,last_active)"
# COMMAND/SCHEDULE: Timestamp 'last_xfer' for items that transfer data
method.insert = pyro_last_xfer_check_min_rate, simple|private, "greater=((argument.0)),((pyro.last_xfer.min_rate))"
method.insert = d.last_xfer.is_active, simple, "or=(pyro_last_xfer_check_min_rate,(d.up.rate)), (pyro_last_xfer_check_min_rate,(d.down.rate))"
schedule2 = pyro_update_last_xfer, 33, 17, ((d.multicall2, active, "branch=((d.last_xfer.is_active)),((d.custom.set, last_xfer, (cat,(system.time))))" ))
method.insert = d.last_xfer, simple, "if=(d.last_xfer.is_active), (cat,(system.time)), (d.custom,last_xfer)"
# EVENTS: Activation intervals
method.insert = pyro.activations.append, simple|private, "d.custom.set=activations,(cat,(d.custom,activations),(argument.0),(system.time)); d.save_resume="
method.set_key = event.download.paused, ~activations, "pyro.activations.append=P"
method.set_key = event.download.resumed, ~activations, "pyro.activations.append=R"
# COMMAND: Wrapper methods for key binds (hide technical complications)
method.insert = pyro._bind_schedule, private|simple, "schedule2=(argument.0), 1, 0, (argument.1)"
method.insert = pyro._bind_key_command, private|simple, "cat=\"ui.bind_key=download_list,\",$argument.0=,\",\\\"\",$argument.1=, \"\\\"\""
method.insert = pyro.bind_key, private|simple, "branch=(pyro.extended), ((pyro._bind_schedule,(argument.0), (pyro._bind_key_command,(argument.1),(argument.2))))"
# COMMAND: Wrapper methods for safely toggle collapsed state of views
method.insert = pyro.view.collapsed.toggle, private|simple, "branch=(pyro.extended), ((view.collapsed.toggle,(argument.0)))"
method.insert = pyro.collapsed_view.add, private|simple, "view.add=(argument.0); pyro.view.collapsed.toggle=(argument.0)"
### begin: Logging, Log Rotation, Archival, and Pruning ###
# Log messages into file: this type of log is being dealt differently, 'rtorrent-messages' logrotate conf is responsible for this (requires rtorrent-PS-CH >= v1.7.0)
branch=(pyro.extended),((log.messages, (cat, (cfg.dir.logs), messages.log) ))
# Set archival and retention delay in days for log rotation
method.insert = pyro.log_archival.days, value, 2
method.insert = pyro.log_retention.days, value, 7
# String value for the currently used time stamp, changed on rotation
method.insert = pyro.log_stamp.current, string
# helper method: creates a "YYYY-mm-dd-HHMMSS" time stamp
method.insert = pyro.date_iso.log_stamp, simple|private, "execute.capture_nothrow = bash, -c, \"echo -n $(date +%Y-%m-%d-%H%M%S)\""
# helper method: creates a full logfile path using the current stamp
method.insert = pyro.logfile_path, simple|private, "cat = (cfg.dir.logs), (argument.0), \"-\", (pyro.log_stamp.current), .log"
# helper method: log file archival and pruning
method.insert = pyro._logfile_find_cmd, simple|private, "cat=\"find \", (cfg.dir.logs), \" -daystart -type f ! -name 'messages*.log*' -name '*.\", (argument.0), \"'\", \" -mtime +\", (argument.1), \" -exec nice \", (argument.2), \" '{}' ';'\""
# (Re-)open all logs with a current time stamp (command group); the main log file is just opened, you need to add some logging scopes yourself!
# Disabled: enable any of the actual logging ([execute|xmlrpc|~main]) if it's desired
method.insert = pyro.log_rotate, multi|rlookup|static
method.set_key = pyro.log_rotate, !stamp, "pyro.log_stamp.current.set = (cat, (pyro.date_iso.log_stamp))"
#method.set_key = pyro.log_rotate, execute, "log.execute = (pyro.logfile_path, execute)"
#method.set_key = pyro.log_rotate, xmlrpc, "log.xmlrpc = (pyro.logfile_path, xmlrpc)"
#method.set_key = pyro.log_rotate, ~main, "log.open_file = log, (pyro.logfile_path, rtorrent)"
## Scheduling is Disabled: enable all of them if any of the logging ([execute|xmlrpc|~main]) in 'pyro.log_rotate' command group is enabled
# Logrotate schedule (rotating shortly after 1AM, so DST shenanigans are taken care of, and rotation is always near the next day's begin)
#schedule2 = pyro_daily_log_rotate, 01:05:00, 24:00:00, ((pyro.log_rotate))
# Log file archival schedule
#schedule2 = pyro_logfile_archival, 01:10:00, 24:00:00, "execute.nothrow = bash, -c, (pyro._logfile_find_cmd, log, (pyro.log_archival.days), gzip)"
# Log file pruning schedule
#schedule2 = pyro_logfile_pruning, 01:20:00, 24:00:00, "execute.nothrow = bash, -c, (pyro._logfile_find_cmd, log.gz, (pyro.log_retention.days), rm)"
# Open logs initially on startup
# Disabled: enable it if any of the logging ([execute|xmlrpc|~main]) in 'pyro.log_rotate' command group is enabled
#pyro.log_rotate=
# Enables logging. Levels=[critical|error|warn|notice|info|debug] Groups=[connection_*|dht_*|peer_*|rpc_*|storage_*|thread_*|tracker_*|torrent_*]
# Disabled: enable any/all of them if it's desired (requires '~main' command in 'pyro.log_rotate' command group to be enabled)
#log.add_output = "info", "log"
#log.add_output = "debug", "log"
#log.add_output = "tracker_debug", "log"
### end: Logging, Log Rotation, Archival, and Pruning ###
##### end: Useful command extensions #####
##### begin: UI related commands and enhancements #####
### begin: UI commands ###
# UI/CMD: Use rtcontrol filter (^X s=KEYWORD, ^X t=TRACKER, ^X f="FILTER")
method.insert = s,simple|private,"execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",--detach,-qV,[,\"$cat=*,$argument.0=,*\",OR,\"$cat=custom_displayname=,*,$argument.0=,*\",]"
method.insert = t,simple|private,"execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",--detach,-qV,\"$cat=\\\"alias=\\\",$argument.0=\""
method.insert = f,simple|private,"execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",--detach,-qV,$argument.0="
# UI/CMD: Add, remove, and show tags
method.insert = tag.add, simple|private, "execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",--detach,-qV,-otag_show,--flush,--yes,--from-view,$d.hash=,//,--tag,$argument.0="
method.insert = tag.rm, simple|private, "execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",--detach,-qV,-otag_show,--flush,--yes,--from-view,$d.hash=,//,--tag,\"$cat=-,$argument.0=\""
method.insert = tag.show, simple|private, "execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",--detach,-qV,-otag_show,--from-view,$d.hash=,//,--flush"
# UI/CMD: Displays quick help resources
method.insert = pyro.print_help, multi|rlookup|static
method.set_key = pyro.print_help, !!intro1, ((print, ((cat, "rTorrent QUICK HELP RESOURCES" )) ))
method.set_key = pyro.print_help, !!intro2, ((print, ((cat, "=============================" )) ))
method.set_key = pyro.print_help, !10handbook, ((print, ((cat, "rTorrent Handbook http://rtorrent-docs.readthedocs.io/" )) ))
method.set_key = pyro.print_help, !10wiki, ((print, ((cat, "rTorrent Wiki https://github.com/rakshasa/rtorrent/wiki" )) ))
method.set_key = pyro.print_help, !20pyrocore, ((print, ((cat, "pyrocore Manual (rtcontrol) https://pyrocore.readthedocs.io/" )) ))
method.set_key = pyro.print_help, !90ps-ch, ((print, ((cat, "rTorrent-PS-CH Setup Wiki https://github.com/chros73/rtorrent-ps-ch_setup/wiki" )) ))
# UI/CMD/LOG/SCHEDULE/EVENTS: Log various data of download items during different events and startup time
method.insert = d.print.status, simple|private, "print=(argument.0),\
\" \", (chars.pad, (chars.chop, (d.name), 68, 1), 68),\
\" \", (convert.human_size, (d.selected_size_bytes), (value, 0) ),\
\" U:\", (convert.human_size, (d.up.total), (value, 0) ),\
\" R:\", (convert.magnitude, (d.get_ratio_float.front)) ,., (chars.pad, (chars.chop, (d.get_ratio_float.back), 2), 2, 0, 0),\
\" S:\", (convert.magnitude, (d.tracker_scrape.complete)), \"/L:\", (convert.magnitude, (d.tracker_scrape.incomplete)),\
\" \", (hrf_time, (d.custom,tm_loaded)),\
\" \(\", (convert.human_size, (d.free_diskspace), (value, 0) ), \"\)\",\
\" \", (d.tracker_domain)"
method.set_key = event.download.inserted_new, ~log, ((d.print.status, "LOADED "))
method.set_key = event.download.resumed, 00log, {(branch, ((not,((d.custom,tm_started)))), ((d.print.status, "STARTED ")) )}
method.set_key = event.download.finished, ~log, ((d.print.status, "COMPLETED"))
method.set_key = event.download.hash_done, !log, {(branch, ((and,((d.complete)),((not,((d.custom,tm_completed)))))), ((d.print.status, "HASHCHKED")) )}
method.set_key = event.download.partially_restarted, ~log, ((d.print.status, "RESTARTED"))
method.set_key = event.download.erased, ~log, ((d.print.status, "DELETED "))
schedule2 = log_startup_time, 1, 0, ((print, "Startup time: ", ((hrf_time, ((cat, (startup_time) )) )) ))
### end: UI commands ###
### begin: Extra column definitions ###
# Override Throttle column (⊘)
method.set_key = ui.column.render, "200:1:⊘", ((string.map, ((d.throttle_name)), {"", " "}, {NULL, "∞"}, {slowup, "⊼"}, {tardyup, "⊻"}))
# Add Unsafe data column (◎)
method.set_key = ui.column.render, "230:1:◎", ((string.map, ((cat, ((d.custom,unsafe_data)))), {0, " "}, {1, "⊘"}, {2, "⊗"}))
# Add Data directory column (⊕) (first character of parent directory)
method.set_key = ui.column.render, "250:1:⊕", ((d.parent_dir))
### end: Extra column definitions ###
### begin: Modifications for default views ###
# Set default view to STARTED on startup
schedule2 = set_default_view,0,0,((ui.current_view.set,started))
# UI/VIEW: SORT the collapsed MAIN view (view #1) by DOWNLOADED TIME desc and update it in every 20 seconds
pyro.view.collapsed.toggle = main
branch=pyro.extended=,"view.sort_new = main,\"compare=-,d.custom=tm_downloaded\"","view.sort_new = main,greater=d.custom=tm_downloaded"
branch=pyro.extended=,"view.sort_current = main,\"compare=-,d.custom=tm_downloaded\"","view.sort_current = main,greater=d.custom=tm_downloaded"
# overrides the default scheduling in main.cc to run the command in every 20 seconds instead of 10, the effect will be the same. Note: we have to use the same schedule-name!
schedule2 = view.main,10,20,((view.sort,main))
# UI/VIEW: SORT the collapsed NAME view (view #2) by NAME and update it in every 20 seconds
pyro.view.collapsed.toggle = name
branch=pyro.extended=,"view.sort_new = name,\"compare=+,d.name=\"","view.sort_new = name,less=d.name="
branch=pyro.extended=,"view.sort_current = name,\"compare=+,d.name=\"","view.sort_current = name,less=d.name="
# overrides the default scheduling in main.cc to run the command in every 20 seconds instead of 10, the effect will be the same. Note: we have to use the same schedule-name!
schedule2 = view.name,10,20,((view.sort,name))
# UI/VIEW: SORT the collapsed STARTED view (view #3) by LAST ACTIVE desc, group by COMPLETE, THROTTLE, DOWNLOAD, UPLOAD SPEED desc, update it in every 20 seconds (Note: do NOT SCHEDULE sorting/filtering on STARTED view until this bug gets fixed: https://github.com/rakshasa/rtorrent/issues/449)
# Items are grouped into incomplete, complete in that order. Each group is sorted by last_active field desc.
pyro.view.collapsed.toggle = started
branch=pyro.extended=,"view.sort_new = started,\"compare=+-+--,d.complete=,d.last_active=,d.throttle_name=,d.down.rate=,d.up.rate=\"","view.sort_new = started,greater=d.last_active="
branch=pyro.extended=,"view.sort_current = started,\"compare=+-+--,d.complete=,d.last_active=,d.throttle_name=,d.down.rate=,d.up.rate=\"","view.sort_current = started,greater=d.last_active="
# !!! Sorting on Started view requires rtorrent-PS-CH >= v1.3 or rtorrent/rtorrent-PS with the fix !!!
schedule2 = sort_started,12,20,((view.sort,started))
# UI/VIEW: SORT the collapsed STOPPED view (view #4) by DOWNLOADED TIME desc, group by COMPLETE, THROTTLE (Note: do NOT SCHEDULE sorting/filtering on STOPPED view until this bug gets fixed: https://github.com/rakshasa/rtorrent/issues/449)
# Items are grouped into complete, incomplete in that order. Each group is devided again into subgroups special, slowup group in that order. Each subgroup is sorted by tm_downloaded field desc.
pyro.view.collapsed.toggle = stopped
branch=pyro.extended=,"view.sort_new = stopped,\"compare=++-,d.complete=,d.throttle_name=,d.custom=tm_downloaded\"","view.sort_new = stopped,greater=d.custom=tm_downloaded"
branch=pyro.extended=,"view.sort_current = stopped,\"compare=++-,d.complete=,d.throttle_name=,d.custom=tm_downloaded\"","view.sort_current = stopped,greater=d.custom=tm_downloaded"
# UI/VIEW: SORT the collapsed COMPLETE view (view #5) by COMPLETED TIME desc
pyro.view.collapsed.toggle = complete
branch=pyro.extended=,"view.sort_new = complete,\"compare=-,d.custom=tm_completed\"","view.sort_new = complete,greater=d.custom=tm_completed"
branch=pyro.extended=,"view.sort_current = complete,\"compare=-,d.custom=tm_completed\"","view.sort_current = complete,greater=d.custom=tm_completed"
# UI/VIEW: SORT the collapsed INCOMPLETE view (view #6) by DOWNLOAD, UPLOAD SPEED desc, group by OPEN desc, THROTTLE
# Items are grouped into started, stopped group in that order. Each group is devided again into subgroups special, slowup group in that order. Each subgroup is sorted by download and then upload speed desc.
pyro.view.collapsed.toggle = incomplete
branch=pyro.extended=,"view.sort_new = incomplete,\"compare=-+--,d.is_open=,d.throttle_name=,d.down.rate=,d.up.rate=\"","view.sort_new = incomplete,greater=d.down.rate="
branch=pyro.extended=,"view.sort_current = incomplete,\"compare=-+--,d.is_open=,d.throttle_name=,d.down.rate=,d.up.rate=\"","view.sort_current = incomplete,greater=d.down.rate="
# UI/VIEW: SORT the HASHING view (view #7) by LOADED TIME, group by THROTTLE
# Items are grouped into special, slowup group in that order. Each group is sorted by tm_loaded field desc.
branch=pyro.extended=,"view.sort_new = hashing,\"compare=++,d.throttle_name=,d.custom=tm_loaded\"","view.sort_new = hashing,less=d.custom=tm_loaded"
branch=pyro.extended=,"view.sort_current = hashing,\"compare=++,d.throttle_name=,d.custom=tm_loaded\"","view.sort_current = hashing,less=d.custom=tm_loaded"
# UI/VIEW: SORT the collapsed SEEDING view (view #8) by the UPLOAD SPEED desc, group by THROTTLE and only show torrents with peers and update it in every 20 seconds
# Items are grouped into special, slowup group in that order. Each group is sorted by upload speed desc.
pyro.view.collapsed.toggle = seeding
view.filter = seeding,"and={d.complete=,d.peers_connected=}"
branch=pyro.extended=,"view.sort_new = seeding,\"compare=+-,d.throttle_name=,d.up.rate=\"","view.sort_new = seeding,greater=d.up.rate="
branch=pyro.extended=,"view.sort_current = seeding,\"compare=+-,d.throttle_name=,d.up.rate=\"","view.sort_current = seeding,greater=d.up.rate="
schedule2 = sort_filter_seeding,12,20,((view.sort,seeding))
# UI/VIEW: SORT the LEECHING view (view #9) by DOWNLOAD, UPLOAD SPEED desc, group by THROTTLE and only show torrents with peers and update it in every 20 seconds
# Items are grouped into special, slowup group in that order. Each group is sorted by download and then upload speed desc.
view.filter = leeching,"and={not=$d.complete=,d.peers_connected=}"
branch=pyro.extended=,"view.sort_new = leeching,\"compare=+--,d.throttle_name=,d.down.rate=,d.up.rate=\"","view.sort_new = leeching,greater=d.down.rate="
branch=pyro.extended=,"view.sort_current = leeching,\"compare=+--,d.throttle_name=,d.down.rate=,d.up.rate=\"","view.sort_current = leeching,greater=d.down.rate="
schedule2 = sort_filter_leeching,12,20,((view.sort,leeching))
# UI/VIEW: SORT the collapsed ACTIVE view (view #0) by DOWNLOAD, UPLOAD SPEED desc, group by OPEN desc, THROTTLE, COMPLETE desc. Show active, incomplete torrents and update it in every 20 seconds
# Items are grouped by whether they are open and throttle (e.g. slowup). Each group is devided again into subgroups complete, incomplete, in that order. Each subgroup is sorted by download and then upload speed desc.
pyro.view.collapsed.toggle = active
view.filter = active,"or={d.up.rate=,d.down.rate=,not=$d.complete=}"
branch=pyro.extended=,"view.sort_new = active,\"compare=-+---,d.is_open=,d.throttle_name=,d.complete=,d.down.rate=,d.up.rate=\"","view.sort_new = active,greater=d.up.rate="
branch=pyro.extended=,"view.sort_current = active,\"compare=-+---,d.is_open=,d.throttle_name=,d.complete=,d.down.rate=,d.up.rate=\"","view.sort_current = active,greater=d.up.rate="
schedule2 = sort_filter_active,12,20,((view.sort,active))
### end: Modifications for default views ###
### begin: Adding new useful views ###
# UI/VIEW: ADD collapsed RTCONTROL view for filtering results (bound to '^' in rT-PS)
pyro.collapsed_view.add = rtcontrol
view.filter = rtcontrol,false=
pyro.bind_key = rtcontrol_view, ^, "ui.current_view.set=rtcontrol"
# UI/VIEW: ADD collapsed MESSAGES view for tracker messages (bound to '!' in rT-PS) SORT it by DOWNLOADED TIME, group by THROTTLE, MESSAGE desc
pyro.collapsed_view.add = messages
view.filter = messages,d.message=
branch=pyro.extended=,"view.sort_new = messages,\"compare=+-+,d.throttle_name=,d.message=,d.custom=tm_downloaded\"","view.sort_new = messages,greater=d.message="
branch=pyro.extended=,"view.sort_current = messages,\"compare=+-+,d.throttle_name=,d.message=,d.custom=tm_downloaded\"","view.sort_current = messages,greater=d.message="
method.insert = pyro.ui.messages.show, simple, "ui.current_view.set=messages ;view.sort=messages ;print=$view.size=messages,\" message(s)!\""
pyro.bind_key = messages_view, !, "pyro.ui.messages.show="
# UI/VIEW: ADD collapsed TRACKERS view (bound to 't' in rT-PS) SORT it by DOWNLOADED TIME desc, group by DOMAIN
pyro.collapsed_view.add = trackers
branch=pyro.extended=,"view.sort_new = trackers,\"compare=+-,d.tracker_domain=,d.custom=tm_downloaded\""
branch=pyro.extended=,"view.sort_current = trackers,\"compare=+-,d.tracker_domain=,d.custom=tm_downloaded\""
pyro.bind_key = trackers_view, t, "ui.current_view.set=trackers"
# UI/VIEW: ADD collapsed TAGGED view for manually tag/select items (bound to ':' in rT-PS) ('.' = toggle focused item between tagged and untagged , 'T' = clear all tags)
pyro.collapsed_view.add = tagged
view.persistent = tagged
method.insert = pyro.view.toggle_visible, simple, "branch=d.views.has=$argument.0=,view.set_not_visible=$argument.0=,view.set_visible=$argument.0="
method.insert = pyro.view_tagged_clear, simple|private, "view.filter=tagged,false= ;d.multicall2=default,d.views.remove=tagged"
pyro.bind_key = tagged_toggle, ., "pyro.view.toggle_visible=tagged"
pyro.bind_key = tagged_clear, T, "pyro.view_tagged_clear="
pyro.bind_key = tagged_view, :, "ui.current_view.set=tagged"
# UI/VIEW: ADD collapsed DATASIZE view (bound to '<' in rT-PS) SORT it by DATASIZE desc
pyro.collapsed_view.add = datasize
branch=pyro.extended=,"view.sort_new = datasize,\"compare=-,d.selected_size_bytes=\"","view.sort_new = datasize,greater=d.selected_size_bytes="
branch=pyro.extended=,"view.sort_current = datasize,\"compare=-,d.selected_size_bytes=\"","view.sort_current = datasize,greater=d.selected_size_bytes="
pyro.bind_key = datasize_view, <, "ui.current_view.set=datasize"
# UI/VIEW: ADD collapsed UPLOADED DATA view (bound to '>' in rT-PS) SORT it by UPLOADED DATA desc, DOWNLOADED TIME desc
pyro.collapsed_view.add = uploadeddata
branch=pyro.extended=,"view.sort_new = uploadeddata,\"compare=--,d.up.total=,d.custom=tm_downloaded\"","view.sort_new = uploadeddata,greater=d.up.total="
branch=pyro.extended=,"view.sort_current = uploadeddata,\"compare=--,d.up.total=,d.custom=tm_downloaded\"","view.sort_current = uploadeddata,greater=d.up.total="
pyro.bind_key = uploadeddata_view, >, "ui.current_view.set=uploadeddata"
# UI/VIEW: ADD collapsed RATIO view (bound to '%' in rT-PS) SORT it by RATIO desc, UPLOADED DATA desc, DOWNLOADED TIME desc
pyro.collapsed_view.add = ratio
branch=pyro.extended=,"view.sort_new = ratio,\"compare=---,d.ratio=,d.up.total=,d.custom=tm_downloaded\"","view.sort_new = ratio,greater=d.ratio="
branch=pyro.extended=,"view.sort_current = ratio,\"compare=---,d.ratio=,d.up.total=,d.custom=tm_downloaded\"","view.sort_current = ratio,greater=d.ratio="
pyro.bind_key = ratio_view, %, "ui.current_view.set=ratio"
# UI/VIEW: ADD collapsed CATEGORY view (bound to '@' in rT-PS) SORT it by CATEGORY (full path means NAME as well)
pyro.collapsed_view.add = category
branch=pyro.extended=,"view.sort_new = category,\"compare=+,d.data_path=\"","view.sort_new = category,less=d.data_path="
branch=pyro.extended=,"view.sort_current = category,\"compare=+,d.data_path=\"","view.sort_current = category,less=d.data_path="
pyro.bind_key = category_view, @, "ui.current_view.set=category"
# UI/VIEW: ADD collapsed DELETABLE view (bound to '?' in rT-PS) SORT it by DOWNLOADED TIME, group by 'unsafe_data' desc, THROTTLE desc . Show deletable torrents.
pyro.collapsed_view.add = deletable
view.filter = deletable,d.custom=unsafe_data
branch=pyro.extended=,"view.sort_new = deletable,\"compare=--+,d.custom=unsafe_data,d.throttle_name=,d.custom=tm_downloaded\"","view.sort_new = deletable,greater=d.custom=unsafe_data"
branch=pyro.extended=,"view.sort_current = deletable,\"compare=--+,d.custom=unsafe_data,d.throttle_name=,d.custom=tm_downloaded\"","view.sort_current = deletable,greater=d.custom=unsafe_data"
pyro.bind_key = deletable_view, ?, "ui.current_view.set=deletable ;view.sort=deletable"
### end: Adding new useful views ###
### begin: Other UI enhancements ###
# UI/MONITOR: Show traffic of the last hour (bound to '=' key in rT-PS)
branch=pyro.extended=,"network.history.depth.set=112"
branch=pyro.extended=,"schedule2 = network_history_sampling,1,32,network.history.sample="
method.insert = network.history.auto_scale.toggle, simple|private, "branch=network.history.auto_scale=,\"network.history.auto_scale.set=0\",\"network.history.auto_scale.set=1\""
method.insert = network.history.auto_scale.ui_toggle, simple|private, "network.history.auto_scale.toggle= ;network.history.refresh="
pyro.bind_key = toggle_network_auto_scale, =, "network.history.auto_scale.ui_toggle="
# UI/STATUS: Display additional throttle up info in status bar (it needs rT-PS-CH)
branch=pyro.extended=,"branch=pyro.extended.ch=,\"ui.status.throttle.up.set = slowup,tardyup\""
# UI/DOMAIN: Display tracker domain aliases
pyro.import=(cat,"tracker_aliases.rc")
### end: Other UI enhancements ###
### begin: Generic keybindings and attributes ###
# UI/KEY: Bind '*' to TOGGLE between COLLAPSED and EXPANDED display
pyro.bind_key = collapsed_view_toggle, *, "view.collapsed.toggle="
# UI/KEY: Key bindings for special keys: HOME, END, PGUP, PGDN
pyro.bind_key = navigation_home, 0406, "ui.focus.home="
pyro.bind_key = navigation_end, 0550, "ui.focus.end="
pyro.bind_key = navigation_pgup, 0523, "ui.focus.pgup="
pyro.bind_key = navigation_pgdn, 0522, "ui.focus.pgdn="
# UI/ATTRIB: Sets the number of items to skip on pgdn / pgup, default is: 50.
branch=pyro.extended=,"ui.focus.page_size.set = \"30\""
# UI/KEY: Bind '#' to SEND SCRAPE REQUEST manually (with the help of custom method in main config)
pyro.bind_key = send_scrape, #, "d.last_scrape.send_set="
# UI/KEY: Bind '}' to TOGGLE "unsafe_data" ATTRIBUTE: "", "1", "2" ("2" means in delqueue)
method.insert = d.toggle_delqueue, simple|private, "branch=\"equal={d.custom=unsafe_data,cat=2}\",d.remove_from_delqueue=,\"branch=d.custom=unsafe_data,d.add_to_delqueue=,d.unsafe_data.set=1\""
pyro.bind_key = toggle_delqueue, \}, "d.toggle_delqueue="
# UI/KEY: Bind '|' to TOGGLE selectable THEMES defined at the top of this config file (Note: if a new theme is added to / removed from the available selection then this logic has to be modified as well!)
method.insert = pyro.theme.store_set, simple|private, "pyro.import=$cat=$argument.0= ;pyro.theme.selected.set=$argument.0="
method.insert = pyro.theme.toggle1, simple|private, "branch=\"equal={pyro.theme.selected=,cfg.theme.1=}\",pyro.theme.store_set=$cfg.theme.2=,pyro.theme.store_set=$cfg.theme.0="
method.insert = pyro.theme.toggle0, simple|private, "branch=\"equal={pyro.theme.selected=,cfg.theme.0=}\",pyro.theme.store_set=$cfg.theme.1=,pyro.theme.toggle1="
pyro.bind_key = toggle_theme, |, "pyro.theme.toggle0="
# UI/KEY: Bind '^g' to DISPLAY the TAGS of the current download
pyro.bind_key = show_tags, ^G, "tag.show="
# UI/KEY: Bind 'F2' to DISPLAY quick HELP resources
pyro.bind_key = show_quick_help, 0412, "pyro.print_help="
# UI/KEY: Disable '^q' from exit
method.insert = pyro._print_noquit, simple|private, "print=\"^Q is disabled, use '^X quit='\""
pyro.bind_key = no_quit, ^q, "pyro._print_noquit="
# UI/KEY: Bind '/' to TOGGLE visibility of certain COLUMNS
method.insert = ui.columns.enable, multi|rlookup|static
method.set_key = ui.columns.enable, 05state, "method.set_key = ui.column.render, \"100:1:☢\", ((string.map, ((cat, ((d.is_open)), ((d.is_active)))), {00, \"▪\"}, {01, \"▪\"}, {10, \"╍\"}, {11, \"▹\"}))"
method.set_key = ui.columns.enable, 10tied, "method.set_key = ui.column.render, \"110:1:☍\", ((if, ((d.tied_to_file)), ((cat, \"⚯\")), ((cat, \" \"))))"
method.set_key = ui.columns.enable, 15cmd, "method.set_key = ui.column.render, \"120:1:⌘\", ((if, ((d.ignore_commands)), ((cat, \"◌\")), ((cat, \"⚒\"))))"
method.set_key = ui.columns.enable, 20transf, "method.set_key = ui.column.render, \"310:1:⋮\", ((if, ((d.down.rate)), ((if,((d.up.rate)),((cat, \"⇅\")),((cat, \"↡\")))), ((if,((d.up.rate)),((cat, \"↟\")),((cat, \" \")))) ))"
method.set_key = ui.columns.enable, 25scrap1, "method.set_key = ui.column.render, \"400:2: ↺\", ((convert.magnitude, ((d.tracker_scrape.downloaded)) ))"
method.set_key = ui.columns.enable, 30scrap2, "method.set_key = ui.column.render, \"410:2: ⤴\", ((convert.magnitude, ((d.tracker_scrape.complete)) ))"
method.set_key = ui.columns.enable, 35scrap3, "method.set_key = ui.column.render, \"420:2: ⤵\", ((convert.magnitude, ((d.tracker_scrape.incomplete)) ))"
method.set_key = ui.columns.enable, 40peers, "method.set_key = ui.column.render, \"430:2: ↻\", ((convert.magnitude, ((d.peers_connected)) ))"
method.set_key = ui.columns.enable, 45uptota, "method.set_key = ui.column.render, \"700:6: ⊼ \", ((if, ((d.up.total)), ((convert.human_size, ((d.up.total)), (value, 0) )), ((cat, \" · \"))))"
method.set_key = ui.columns.enable, 99status, "ui.columns.state.set=1"
method.insert = ui.columns.disable, multi|rlookup|static
method.set_key = ui.columns.disable, 05state, "method.set_key = ui.column.render, \"100:1:☢\""
method.set_key = ui.columns.disable, 10tied, "method.set_key = ui.column.render, \"110:1:☍\""
method.set_key = ui.columns.disable, 15cmd, "method.set_key = ui.column.render, \"120:1:⌘\""
method.set_key = ui.columns.disable, 20transf, "method.set_key = ui.column.render, \"310:1:⋮\""
method.set_key = ui.columns.disable, 25scrap1, "method.set_key = ui.column.render, \"400:2: ↺\""
method.set_key = ui.columns.disable, 30scrap2, "method.set_key = ui.column.render, \"410:2: ⤴\""
method.set_key = ui.columns.disable, 35scrap3, "method.set_key = ui.column.render, \"420:2: ⤵\""
method.set_key = ui.columns.disable, 40peers, "method.set_key = ui.column.render, \"430:2: ↻\""
method.set_key = ui.columns.disable, 45uptota, "method.set_key = ui.column.render, \"700:6: ⊼ \""
method.set_key = ui.columns.disable, 99status, "ui.columns.state.set=0"
method.insert = ui.columns.state, value|private, 1
method.insert = ui.columns.toggle, simple, "branch=ui.columns.state=, ui.columns.disable=, ui.columns.enable="
pyro.bind_key = ui_columns_toggle, /, "ui.columns.toggle="
### end: Generic keybindings and attributes ###
##### end: UI related commands and enhancements #####
##### begin: Unused pyroscope features #####
## UI/CMD: Housekeeping (delete item + data)
#method.insert = purge,simple|private,"execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",-q,--detach,--purge,--yes,--from-view,$d.hash=,//"
#method.insert = cull,simple|private,"execute.nothrow=\"$cat=$pyro.bin_dir=,rtcontrol\",-q,--detach,--cull,--yes,--from-view,$d.hash=,//"
## TORQUE/CMD: Daemon watchdog
#method.insert = pyro.watchdog,simple|private,"execute.nothrow=bash,-c,\"$cat=\\\"test ! -f \\\",$argument.0=,\\\"/run/pyrotorque || \\\",$pyro.bin_dir=,\\\"pyrotorque --cron \\\",$argument.1=\""
## TORQUE/SCHEDULE: Schedule daemon watchdog. Must be activated by touching the "~/.pyroscope/run/pyrotorque" file! Set the second argument to "-v" or "-q" to change log verbosity.
#schedule2 = pyro_watchdog,30,300,"pyro.watchdog=~/.pyroscope,"
## TORQUE/UI/VIEW: ADD collapsed PYROTORQUE view for queue manager job (bound to 'Q' key in rT-PS) SORT it by UPLOAD SPEED desc, group by OPEN desc, THROTTLE, COMPLETE desc, DOWNLOAD SPEED desc. Show active, incomplete torrents and update it in every 15 seconds.
#pyro.collapsed_view.add = pyrotorque
#view.filter = pyrotorque,"or={d.up.rate=,d.down.rate=,d.peers_connected=,not=$d.complete=}"
#branch=pyro.extended=,"view.sort_new = pyrotorque,\"compare=-+---,d.is_open=,d.throttle_name=,d.complete=,d.down.rate=,d.up.rate=\"","view.sort_new = pyrotorque,greater=d.up.rate="
#branch=pyro.extended=,"view.sort_current = pyrotorque,\"compare=-+---,d.is_open=,d.throttle_name=,d.complete=,d.down.rate=,d.up.rate=\"","view.sort_current = pyrotorque,greater=d.up.rate="
#schedule2 = sort_filter_pyrotorque,1,15,"view.sort=pyrotorque"
#pyro.bind_key = pyrotorque_view, Q, "ui.current_view.set=pyrotorque"
## UI/VIEW: ADD collapsed INDEMAND view to show items sorted by activity
#pyro.collapsed_view.add = indemand
#view.filter = indemand, ((d.is_open))
#view.filter_on = indemand,event.download.closed,event.download.opened
#view.sort_current = indemand, greater=d.last_active=
#schedule2 = sort_indemand, 22, 33, "view.filter = indemand,d.is_open= ;view.sort=indemand"
#pyro.bind_key = indemand_view, ?, "ui.current_view.set=indemand"
##### end: Unused pyroscope features #####