Skip to content

Instantly share code, notes, and snippets.

@jezuk
Last active November 1, 2020 02:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jezuk/4534414 to your computer and use it in GitHub Desktop.
Save jezuk/4534414 to your computer and use it in GitHub Desktop.
Sequential file priority python script for transmission bit torrent client
#!/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')
@antivirtel
Copy link

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:[]```

@jezuk
Copy link
Author

jezuk commented Aug 16, 2016

@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