Skip to content

Commit 05c73c0

Browse files
committed
Initial
1 parent 2d562e3 commit 05c73c0

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

README.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,26 @@
11
# transmission-trackers
2-
Script to automatically add trackers from a list to all torrents in Transmission
2+
Script to automatically add trackers from a list to all torrents in Transmission.
3+
This allows to get more peers to download/upload from/to.
4+
5+
Logic:
6+
* Download & cache a list of trackers from a specified URL - currently tested only with [ngosang/trackerslist](https://github.com/ngosang/trackerslist). The cache will only be updated after the specified time passes (e.g. once a day)
7+
* Fetch the tracker list of each torrent in Transmission and add all trackers from a downloaded list to each of the torrents.
8+
* Optionally filter by torrent status (seeding, stopped etc)
9+
* If the tracker list of the torrent is already up-to-date then nothing is done.
10+
11+
Tracker list format:
12+
* One tracker URL per line
13+
* Empty lines are ignored
14+
* Only HTTP(S) and UDP trackers are loaded (Transmission does not support WebSocket trackers AFAIK)
15+
16+
Requirements:
17+
* Should work with both Python 2 and 3, although there may be problems with logging in Python2 due to different unicode handling.
18+
* *transmissionrpc* Python module.
19+
20+
Usage:
21+
* Install *transmissionrpc*: ```pip[3] install transmissionrpc```
22+
* Put the *transmission-trackers.py* script somewhere
23+
* Make sure that the right Python interpreter is used (it's *python3* by default)
24+
* Adjust the host/port/credentials to access the Transmission RPC inside the script
25+
* Make the script run by cron e.g. every minute
26+
* You're done

transmission-trackers.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
3+
import transmissionrpc, sys, os, time
4+
5+
# Host, port, username and password to connect to Transmission
6+
# Set user and pw to None if auth is not required
7+
host, port, user, pw = 'localhost', 9091, 'admin', 'pwd'
8+
9+
# Work with torrents having only these statuses.
10+
# Can be any combination of: 'check pending', 'checking', 'downloading', 'seeding', 'stopped'
11+
# If empty - will affect all torrents
12+
status_filter = ()
13+
14+
# How frequently to update trackers cache
15+
update_freq = 86400
16+
17+
# Path to trackers URL and local cache
18+
trackers_url = 'https://raw.githubusercontent.com/ngosang/trackerslist/master/trackers_all.txt'
19+
trackers_file = '/tmp/trackers_all.txt'
20+
21+
# Don't print anything (unless an error occures)
22+
silent = False
23+
# Debug output
24+
debug = False
25+
26+
###
27+
if silent: debug = False
28+
trackers = None
29+
30+
def readTrackers():
31+
f = open(trackers_file, 'r')
32+
trackers = set(())
33+
34+
for t in f.readlines():
35+
t = t.strip()
36+
if not t.startswith('http') or not t.startswith('udp'):
37+
continue
38+
trackers.add(t)
39+
40+
f.close()
41+
if debug: print('{} trackers loaded from {}'.format(len(trackers), trackers_file))
42+
return trackers
43+
44+
def downloadTrackers():
45+
update = False
46+
47+
try:
48+
mt = os.stat(trackers_file).st_mtime
49+
if time.time() - mt > update_freq:
50+
update = True
51+
except:
52+
update = True
53+
54+
if not update:
55+
return
56+
57+
if sys.version_info[0] == 2:
58+
import urllib
59+
urllib.urlretrieve(trackers_url, trackers_file)
60+
else:
61+
import urllib.request
62+
urllib.request.urlretrieve(trackers_url, trackers_file)
63+
64+
trackers = readTrackers()
65+
if not silent: print('Trackers list updated ({} loaded)'.format(len(trackers)))
66+
67+
downloadTrackers()
68+
if not trackers: trackers = readTrackers()
69+
70+
tc = transmissionrpc.Client(host, port=port, user=user, password=pw)
71+
torrents = tc.get_torrents()
72+
73+
if debug: print('{} torrents total'.format(len(torrents)))
74+
75+
for t in torrents:
76+
if status_filter and not t.status in status_filter:
77+
if debug: print('{}: skipping due to status filter'.format(t.name))
78+
continue
79+
80+
ttrk = set(())
81+
for trk in t.trackers:
82+
ttrk.add(trk['announce'])
83+
84+
diff = trackers - ttrk
85+
86+
if diff:
87+
if not silent: print('{}: Adding {} trackers (before: {})'.format(t.name, len(diff)), len(ttrk))
88+
tc.change_torrent(t.id, trackerAdd=list(diff))
89+
else:
90+
if debug: print('{}: update not needed'.format(t.name))

0 commit comments

Comments
 (0)