rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
Här ligger de utförliga instruktionerna vi kan tänkas behöva. Leta här om du tex behöver installera nåt program eller sätta upp någon funktion. Starta inte trådar utan att ha ett svar.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
1. Inledning
Inställningsmöjligheterna i rtorrent är egentligen ingen hemlighet även om informationen av någon anledning tycks vara höljd i dunkel. Det går faktiskt att få till betydligt mer sofistikerade och avancerade lösningar i ~/.rtorrent.rc än vad manualbladet ger sken av.
Här tänker jag ta upp sådant som egentligen inte finns ordentligt dokumenterat, varken i manualbladet eller på rtorrents wiki-sidor. Jag har istället studerat källkoden till rtorrent-0.8.4 för att ta reda på hur det hela hänger ihop. Förmodligen gäller mycket av detta även andra versioner, men det är långt ifrån säkert.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
2. Grundläggande syntax
Varje enskild rad i ~/.rtorrent.rc är ett helt eget separat rtorrent-kommando. Dessa inleds alltid med själva kommandonamnet följt av ett likhetstecken och därefter en argumentlista med noll eller flera kommaseparerade argument.
Kod: Markera allt
kommando_namn = argument_0, argument_1, argument_2, argument_3
Det mest komplicerade kommandot som vanligtvis används är schedule som tar exakt fyra argument där det fjärde inte är något mindre än ett fullständigt rtorrent-kommando med en helt egen argumentlista. Här uppstår genast problemet att rtorrent måste kunna förstå vilka argument som hör till vilken argumentlista. Detta innebär att det inre kommandot måste escape:as på ett eller annat sätt. Det är nu det börjar bli intressant.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
3. Fnuttologi
För att detta inte ska bli alltför förvirrande så inför jag begreppet escape-nivåer, där nivå-A är kommandon som inte behöver escape:as, nivå-B kommandon som behöver escape:as en gång, osv.
I en vanlig simpel ~/.rtorrent.rc är det mesta nivå-A och en del nivå-B. I undantagsfall förekommer även nivå-C, men i princip aldrig djupare än så. Här kommer vi dock att nosa oss ända in till som mest nivå-G.
Den grundläggande escape-varianten är att sätta ett backslash framför varje enskilt tecken som rtorrent tolkar som något annat än som en del av en sträng. Det stora problemet är även backslash måste escape:as på detta sätt, vilket medför att antalet backslash-tecken som behövs växer exponentiellt med escape-nivån. I nivå-C behövs t.ex. tre backslash för varje tecken som ska escape:as. Det första escape:ar det andra som i sin tur följer med ut en nivå, och det tredje escape:ar själva tecknet som egentligen skulle escape:as. Den exakta formeln för antalet backslash som behövs är 2^(escape-nivån)-1:
- A: 2^0 - 1 = 0
B: 2^1 - 1 = 1
C: 2^2 - 1 = 3
D: 2^3 - 1 = 7
E: 2^4 - 1 = 15
F: 2^5 - 1 = 31
G: 2^6 - 1 = 63
Nu har det blivit läge för ett illustrerande exempel. I följande o-escape:ade rtorrent-kommando indikeras den önskade nivån av bokstäverna och argumentnumren av siffrorna:
Kod: Markera allt
A = a0, B = b0, C = c0, c1, D = d0, d1, d2, d3, c3, b2, a2
Kod: Markera allt
A=a0,B=b0\,C=c0\\\,c1\\\,D=d0\\\\\\\,d1\\\\\\\,d2\\\\\\\,d3\\\,c3\,b2,a2
Kod: Markera allt
A = a0, "B = b0, \"C = c0, c1, \\\"D = d0, d1, d2, d3\\\", c3\", b2", a2
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
4. Fördjupad fnuttologi
Vilken escape-metod som resulterar i flest backslash och därför bör undvikas varierar helt beroende på hur kommandot ser ut, nivån och antalet argument. För nivå-B är det ganska likvärdigt oavsett argumentantalet:
Kod: Markera allt
B=
B=b0
B=b0\,b1
B=b0\,b1\,b2
B=b0\,b1\,b2\,b3
Kod: Markera allt
"B ="
"B = b0"
"B = b0, b1"
"B = b0, b1, b2"
"B = b0, b1, b2, b3"
Kod: Markera allt
E=
E=e0
E=e0\\\\\\\\\\\\\\\,e1
E=e0\\\\\\\\\\\\\\\,e1\\\\\\\\\\\\\\\,e2
E=e0\\\\\\\\\\\\\\\,e1\\\\\\\\\\\\\\\,e2\\\\\\\\\\\\\\\,e3
Kod: Markera allt
\\\\\\\"E =\\\\\\\"
\\\\\\\"E = e0\\\\\\\"
\\\\\\\"E = e0, e1\\\\\\\"
\\\\\\\"E = e0, e1, e2\\\\\\\"
\\\\\\\"E = e0, e1, e2, e3\\\\\\\"
Kod: Markera allt
G=
G=g0
G=g0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\,g1
Kod: Markera allt
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"G =\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"G = g0\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"G = g0, g1\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
5. Övrig syntax
Det finns egentligen bara ytterligare en viktig sak att känna till. I vanliga fall skickas den inre nivån vidare som en oförändrad sträng till den yttre nivåns argument. Det är sedan upp till det yttre kommandot att avgöra om strängen ska tolkas som ett rtorrent-kommando som ska köras eller som en helt vanlig sträng. Det finns dock ett viktigt undantag. Om det absolut första tecknet i strängen som utgör en nivå är ett dollartecken så kommer nivån alltid att köras som ett kommando och det blir istället resultatet av det kommandot som skickas vidare till den yttre nivåns argument.
Kommandon kan dessutom separeras med semikolon och grupperas med krullparanteser. Det fungerar dock inte överallt, vilket egentligen inte är något problem eftersom det i princip aldrig varken är nödvändigt att kunna separera eller gruppera kommandon.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
6. Att definiera egna rtorrent-kommandon
Det ännu odokumenterade rtorrent-kommandot system.method.insert används för att skapa helt egna rtorrent-kommandon. Det första argumentet anger kommando-namnet som man kan välja helt själv. Det andra argumentet avgör vilken typ av kommando det rör sig om. Det finns flera olika varianter, men de mest intressanta är value och const_simple.
Kod: Markera allt
system.method.insert = return , value
Nu tar vi istället en närmare titt på typen const_simple. De resterande argumenten är fullständiga rtorrent-kommandon som körs när det egenvalda kommandonamnet anropas.
Kod: Markera allt
system.method.insert = \
d.stop_and_close \
, const_simple \
, d.stop= \
, d.set_ignore_commands=1 \
, d.close=
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
7. Villkor och argument
Ett av de för oss mest användbara rtorrent-kommandona är branch, vars första argument är ett villkor som avgör om det andra eller tredje argumentet ska köras. Finns det fler än tre argument så avgör det tredje argumentet om det fjärde eller femte ska köras, osv. Men för att verkligen kunna få till riktigt användbara villkor så vill man först kunna ta reda på vilka argument som det egna kommandot har tagit emot. För att göra det så använder man sig av rtorrent-kommandona argument.0, argument.1 osv. Det kan se ut ungefär så här:
Kod: Markera allt
system.method.insert = \
try_run_arg \
, const_simple \
, " branch = \
\" \
or = \
\\\" \
less = \
argument.0= \
, cat=placeholder \
\\\" \
, \\\" \
less = \
cat=placeholder \
, argument.0= \
\\\" \
\" \
, $argument.0= \
"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
8. Returvärden
För att kunna få tillbaka returvärden kan vi använda oss av return som vi redan skapat tidigare. Men för att det inte ska bli så mycket strul varje gång det behövs ett returvärde så ordnar vi ett separat kommando som hanterar den biten:
Kod: Markera allt
system.method.insert = \
evaluate \
, const_simple \
, " branch = \
$argument.1= \
, return.set=false \
, return.set=true \
" \
, " branch = \
$argument.0= \
, return.set=$not=$return= \
" \
, " branch = \
return= \
, try_run_arg=$argument.2= \
, try_run_arg=$argument.3= \
"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
9. Wrapper-kommandon
Det har blivit dags att börja dra lite nytta av alla mödor med evaluate-kommandot. Först ett relativt enkelt wrapper-kommando runt kommandot less, vilket egentligen inte är något märkvärdigare än att slå in less-kommandot i lite kod som ser till så att less alltid får vettig indata och ger vettig utdata tillbaka.
Kod: Markera allt
system.method.insert = \
require \
, const_simple \
, " branch = \
not=$argument.1= \
, require=0\\\,0 \
, not=$argument.0= \
, require=0 \
, \" \
evaluate = \
, \\\"$ \
less = \
return.set=$argument.0= \
, return.set=$argument.1= \
\\\" \
\" \
"
Nu går det t.ex. att köra require=$d.get_ratio=,1000,d.close= för att stänga en torrent om den har en ratio på minst 1. Och nu tänker du genast att det ju redan finns speciella kommandon för att göra just det. Det stämmer bra, men det här är betydligt smidigare eftersom vi även kan anropa require med andra argument än d.get_ratio och d.close utan några svårigheter.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
10. Externa villkor
Nu har vi kommit fram till en punkt där rtorrents interna kommandon inte längre räcker till för det jag vill åstadkomma. I det här fallet handlar det om sträng-matchning, vilket kan vara mycket användbart, men som sagt kräver ett externt kommando:
Kod: Markera allt
system.method.insert = \
match \
, const_simple \
, " evaluate = \
, \"$ execute_raw_nothrow = \
sh \
, -c \
, \\\" \
printf %s \\\\\\\"$0\\\\\\\" | \
grep -qE \\\\\\\"$1\\\\\\\" \
\\\" \
, $argument.0= \
, $argument.1= \
\" \
"
Kod: Markera allt
#!/bin/sh
printf %s "$0" | grep -qE "$1"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
11. En första tillämpning
Nu har vi kommit fram till ett läge där det faktiskt går att få till något som är fullt användbart. Tanken är att använda det nya match-kommandot för att testa om om en ny torrent hör till en viss speciell tracker, och utifrån den informationen sätta vilken katalog torrenten sedan laddas ner till.
Kommandot för att ta reda på tracker-adresssen är t.get_url, vilket som tidigare nämnts kräver att kommandot associeras med en tracker. För att lyckas med det använder vi oss av kommandot t.multicall som kör kommandon associerade med var och varje tracker för en given torrent.
Kod: Markera allt
system.method.insert = \
d.match_tracker \
, const_simple \
, " match = \
\"$ t.multicall = \
, t.get_url= \
\" \
, $argument.0= \
, $argument.1= \
, $argument.2= \
"
Kod: Markera allt
system.method.set_key = event.download.inserted_new , filter_ubuntu \
, " d.match_tracker = (torrent\\\\\\\.ubuntu\\\\\\\.com) \
, d.set_directory_base=/media/linux-images/ \
"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
12. Mer avancerade villkor
Det har blivit dags att använda match-kommandot till sin fulla potential. Låt oss börja med ett kommando som vi kallar d.require_seeds där vi helt enkelt kräver att torrenten har ett visst antal seeders samt att antalet seeders är minst lika stort som antalet leechers. Vi använder oss även denna gång av t.multicall-kommandot, samt return.set för att konvertera sträng till tal.
Kod: Markera allt
system.method.insert = \
d.require_seeds \
, const_simple \
, " match = \
\"$ t.multicall = \
, \\\" \
or = \
\\\\\\\" \
less = \
t.get_scrape_complete= \
, t.get_scrape_incomplete= \
\\\\\\\" \
, \\\\\\\" \
less = \
t.get_scrape_complete= \
, return.set=$argument.0= \
\\\\\\\" \
\\\" \
\" \
, 0 \
, $argument.1= \
, $argument.2= \
"
Kod: Markera allt
system.method.insert = \
d.completed \
, const_simple \
, " match = \
\"$ f.multicall = \
, \\\" \
and = \
f.get_priority= \
, \\\\\\\" \
less = \
f.get_completed_chunks= \
, f.get_size_chunks= \
\\\\\\\" \
\\\" \
\" \
, 1 \
, \
, \
" \
, " evaluate = \
, $return= \
, $argument.0= \
, $argument.1= \
" \
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
13. Köra kommandon på flera olika torrents
Vi har redan tidigare använt oss av kommandona t.multicall och f.multicall för att kunna köra tracker- respektive fil-associerade kommandon för flera trackers och filer på en gång. Motsvarande kommando för torrents är d.multicall, men eftersom varje torrent har en individuell inställning som indikerar om torrenten i fråga verkligen vill lyda kommandon eller inte så vill vi inte köra d.multicall rakt av utan att ta hänsyn till just detta.
Kod: Markera allt
system.method.insert = \
select_heed \
, const_simple \
, " d.multicall = \
$argument.0= \
, \" \
branch = \
d.get_ignore_commands= \
, return.set=false \
, \\\" \
evaluate = \
not= \
, \\\\\\\"$ \
branch = \
argument.1= \
, argument.1= \
, not= \
\\\\\\\" \
\\\" \
\" \
"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
14. Faktisk användning av det vi hittills gjort
Tanken är att få till ett kommando som stänger färdiga torrenter så fort de får minst 1 i ratio, men bara om det finns minst lika många seeders som leechers och minst 3 seeders. Vi vill däremot inte att torrenter som är satta till ignore_commands ska stängas av, varför det nya select_heed-kommandot nu kommer väl till pass. Här räcker det dock inte med att skicka med resultatet av vårt förutsatta kombinerade villkor. Anledningen är att testet måste utföras för varje torrent som d.multicall väljer ut. Det är egentligen inte mer komplicerat än vad vi gjort innan, men det kräver fler escape-nivåer, och vi kommer få nytta av den inledande fnuttologin:
Kod: Markera allt
system.method.insert = \
completed_dual_filter \
, const_simple \
, " select_heed = \
$argument.0= \
, \"$ cat = \
\\\" \
and = \
\\\\\\\" \
return = \
\\\\\\\\\\\\\\\"$ \
\\\" \
, $argument.1= \
, \\\" \
, \
, \
\\\\\\\\\\\\\\\" \
\\\\\\\" \
, \\\\\\\" \
return = \
\\\\\\\\\\\\\\\"$ \
\\\" \
, $argument.2= \
, \\\" \
, \
, \
\\\\\\\\\\\\\\\" \
\\\\\\\" \
, \\\\\\\" \
return = \
\\\\\\\\\\\\\\\"$ \
d.completed = \
, \
\\\\\\\\\\\\\\\" \
\\\\\\\" \
\\\" \
\" \
, $argument.3= \
, \
"
Kod: Markera allt
system.method.insert = \
on_ratio_and_seeds \
, const_simple \
, " completed_dual_filter = \
$argument.0= \
, \"$ cat = \
require=$d.get_ratio= \
, \\\\\\\, \
, $argument.1= \
\" \
, \"$ cat = \
d.require_seeds= \
, $argument.2= \
\" \
"
Kod: Markera allt
schedule = close_on_ratio_and_seeds , 10 , 60 \
, " on_ratio_and_seeds = \
started \
, 1000 \
, 3 \
, d.stop_and_close= \
"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
15. Räkneoperationer
Det finns inget inbyggt kommando som kan räkna så vi behöver precis som med match-kommandot använda oss av extern hjälp. Den här gången blir det dock betydligt mer komplicerat eftersom vi faktiskt vill kunna ta till var på resultatet och inte bara göra ett simpelt test. Jag har valt att använda mig av ett filrör, en så kallad fifo. Det är ett utmärkt tillfälle att introducera ytterligare en kommando-typ, nämligen static_const_string. Eftersom den är static_const så måste vi initiera värdet direkt när vi deklarerar den genom det tredje argumentet.
Kod: Markera allt
system.method.insert = fifo , static_const_string \
, "$ cat = /var/run/rtorrent. , $system.pid= , .fifo"
Kod: Markera allt
system.method.insert = \
arithmetic \
, const_simple \
, " execute_raw_nothrow = \
sh \
, -c \
, \"$ cat = \
\\\" \
mkfifo \\\\\\\"$0\\\\\\\"; \
echo return.set= | awk '{print$0( \
\\\" \
, $argument.0= \
, \\\" \
)}' >\\\\\\\"$0\\\\\\\" && \
rm -f \\\\\\\"$0\\\\\\\" & \
\\\" \
\" \
, $fifo= \
" \
, import=$fifo=
Kod: Markera allt
system.method.insert = \
diff \
, const_simple \
, " arithmetic = \
\"$ cat = \
$argument.0= \
, - \
, $argument.1= \
\" \
"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
16. Hålla reda på hur länge varje torrent seedats
Att ta reda på hur länge en torrent faktiskt har seedat är ett delikat problem, speciellt om datorn inte är igång dygnet runt. Nu ska vi försöka göra saken betydligt enklare genom att registrera den verkliga seed-tiden. Jag väljer att använda kommandona d.set_custom5 och d.get_custom5 för att hålla reda på värdet som måste uppdateras varje gång torrenten stoppas eller startas. För att göra det hela någorlunda hanterbart så skapar vi ett kommando som har hand om den saken.
Kod: Markera allt
system.method.insert = \
d.register_seed_time \
, const_simple \
, " branch = \
d.get_custom5= \
, \" \
d.set_custom5 = \
\\\"$ \
cat = \
\\\\\\\"$ \
return = \
\\\\\\\\\\\\\\\"$ \
diff = \
$system.time= \
, $d.get_custom5= \
\\\\\\\\\\\\\\\" \
\\\\\\\" \
\\\" \
\" \
, d.is_active= \
, d.set_custom5=$cat=$system.time= \
" \
, " require = \
$d.get_custom5= \
, $argument.0= \
, \
, \"$ cat = \
d.set_custom5= \
, $argument.0= \
\" \
" \
, " d.completed = \
, d.set_custom5= \
"
Kod: Markera allt
schedule = monitor_seed_time , 60 , 60 \
, " d.multicall = incomplete , d.register_seed_time=$d.get_custom5= "
Kod: Markera allt
system.method.set_key = event.download.finished , initialize_seed_time \
, d.register_seed_time=$system.time=
Kod: Markera allt
system.method.set_key = event.download.paused , save_seed_time \
, d.register_seed_time=
Kod: Markera allt
system.method.set_key = event.download.resumed , restore_seed_time \
, d.register_seed_time=$d.get_custom5=
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
17. Ytterligare en faktiskt användning av det vi hittills gjort
Det är åter igen dags att få till något mer direkt användbart. Men först behöver vi ett kommando som plockar fram seed-tiden vi redan har registrerat. Exakt hur vi får fram den avgörs av om torrenten är startad eller stoppad. I övrigt ska det inte vara några konstigeheter alls.
Kod: Markera allt
system.method.insert = \
d.get_seed_time \
, const_simple \
, " branch = \
not=$d.get_custom5= \
, return.set=0 \
, d.is_active= \
, \" \
diff = \
$system.time= \
, $d.get_custom5= \
\" \
, return.set=$d.get_custom5= \
"
Kod: Markera allt
system.method.insert = \
on_tracker_and_time \
, const_simple \
, " completed_dual_filter = \
$argument.0= \
, \"$ cat = \
d.match_tracker= \
, $argument.1= \
\" \
, \"$ cat = \
require=$return=$d.get_seed_time= \
, \\\\\\\, \
, $argument.2= \
\" \
"
Kod: Markera allt
schedule = close_on_tracker_and_time , 600 , 600 \
, " on_tracker_and_time = \
started \
, thepiratebay\\\\\\\\\\\\\\\\.org \
, 1000000 \
, d.stop_and_close= \
"
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28
rTorrent: En avancerad djupgående guide till ~/.rtorrent.rc
19. Efterord
Det här var egentligen tänkt som en julkalender, men jag fick aldrig riktigt tid att avsluta den helt. I de sista delarna skulle jag ha tagit upp lite om hur torrent-grupper fungerar. Vi får se om jag får tid och inspiration att fylla på med den biten senare.
- Konservburk
- Inlägg: 5919
- Blev medlem: 07 apr 2007, 22:28