Last active
November 1, 2020 02:38
-
-
Save jezuk/4534414 to your computer and use it in GitHub Desktop.
Sequential file priority python script for transmission bit torrent client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
''' | |
Transmission Automatic File Prioritiser V2 | |
Less evil version of sequential downloading, only prioritises files sequentially | |
Keeps other files in the torrent on normal priority (if set to download) | |
Enter path to .netrc file below containing login details in format (without <>): | |
machine localhost login <transmission-username> password <transmission-password> | |
You need to run this from cron regularly for it to be useful | |
Requires transmission-remote | |
Inspired by: https://gist.github.com/2944062 | |
V2: Sort by name | |
''' | |
authfile = '/path/to/.netrc' | |
#Import things we need | |
import re | |
from subprocess import Popen, PIPE | |
import logging | |
logging.basicConfig(level=logging.DEBUG) | |
logger = logging.getLogger() | |
#Get list of all the torrents | |
output = Popen(['transmission-remote', | |
'-N', authfile, | |
'--list'], stdout=PIPE).communicate()[0] | |
logger.debug('Got list of torrents') | |
#Clean up newlines | |
eol_re = re.compile(r'\r?\n') | |
#Split into lines | |
torrent_lines = eol_re.split(output) | |
#Regex for torrent list format | |
torrent_re = re.compile(r'^\s*(?P<ID>\d+)\*?' + | |
'\s+(?P<Done>\d+%|n/a)' + | |
'\s+(?P<Have>\d+\.\d+ \w+|None)' + | |
'\s+(?P<ETA>\d+ \w+|\w+)' + | |
'\s+(?P<Up>\d+\.\d+)' + | |
'\s+(?P<Down>\d+\.\d+)' + | |
'\s+(?P<Ratio>\d+\.\d+|None)' + | |
'\s+(?P<Status>\w+)' + | |
'\s+(?P<Name>.*)$') | |
#Parse the torrent list, drop malformed lines | |
torrents = [] | |
for line in torrent_lines: | |
mo = torrent_re.match(line) | |
if not mo: | |
logger.debug('Ignored torrent line %s' % line) | |
continue | |
torrent_dict = mo.groupdict() | |
torrents.append(torrent_dict) | |
#Filter the list to only active torrents | |
downloading_torrents = [x for x in torrents if x['Status'] in ('Downloading', 'Up')] | |
logger.debug('Downloading torrents:') | |
logger.debug(downloading_torrents) | |
#Regex for file list format | |
file_re = re.compile(r'^\s*(?P<ID>\d+):' + | |
'\s+(?P<Done>\d+%|-nan%)' + | |
'\s+(?P<Priority>\w+)' + | |
'\s+(?P<Get>\w+)' + | |
'\s+(?P<Size>[0-9.]+ \w+|None)' + | |
'\s+(?P<Name>.*)$') | |
#Loop through each active torrent | |
for torrent in downloading_torrents: | |
torrent_id = torrent['ID'] | |
#Get list of files in this torrent | |
output = Popen(['transmission-remote', | |
'-N', authfile, | |
'--torrent', torrent_id, | |
'--files'], stdout=PIPE).communicate()[0] | |
#Clean up newlines, split and parse file list | |
file_lines = eol_re.split(output) | |
files = [] | |
for line in file_lines: | |
mo = file_re.match(line) | |
if not mo: | |
logger.debug('Ignored file line %s' % line) | |
continue | |
filedict = mo.groupdict() | |
files.append(filedict) | |
#Filter the list for files marked to be downloaded | |
in_download = [x for x in files if x['Get'] == 'Yes'] | |
#Get a CSV list of the file IDs marked to download | |
download_ids = [x['ID'] for x in in_download] | |
download_ids_str = ','.join(str(x) for x in download_ids) | |
logger.debug('File IDs to set normal: ' + download_ids_str) | |
#Sort file list | |
in_download.sort(cmp=lambda x, y: cmp(x['Name'], y['Name'])) | |
logger.debug('Sorted') | |
#Search for the first incomplete file | |
for file in in_download: | |
if file['Done'] != '100%': | |
file_id = file['ID'] | |
logger.debug('File ID to set high: ' + file_id) | |
break | |
#Set priority of all downloading files to normal | |
output = Popen(['transmission-remote', | |
'-N', authfile, | |
'--torrent', torrent_id, | |
'-pn' + download_ids_str], stdout=PIPE).communicate()[0] | |
logger.debug('Set normal files') | |
#Set priority of first incomplete file to high | |
output = Popen(['transmission-remote', | |
'-N', authfile, | |
'--torrent', torrent_id, | |
'-ph' + file_id], stdout=PIPE).communicate()[0] | |
logger.debug('Set high file') | |
Doesn't seems to be working for me on Windows, debug lines:
DEBUG:root:Got list of torrents
DEBUG:root:Ignored torrent line ID Done Have ETA Up Down Ratio Status
DEBUG:root:Ignored torrent line Sum: # GiB #.0 0.0
DEBUG:root:Ignored torrent line
DEBUG:root:Downloading torrents:
DEBUG:root:[]```
@antivirtel Sorry I've not seen your comment for over year! I've not tested on Windows, however I plan to rewrite this using the proper API which should make it platform independent. Cheers
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Downloads for Win: https://github.com/cfpp2p/transmission/tree/Windows_Daemon_%26_Clients/transmission-executables/transmission