Skip to content

Instantly share code, notes, and snippets.

@pandada8
Created February 10, 2021 07:54
Show Gist options
  • Save pandada8/7c6cbaac218e8f8c42874aaf5fb34775 to your computer and use it in GitHub Desktop.
Save pandada8/7c6cbaac218e8f8c42874aaf5fb34775 to your computer and use it in GitHub Desktop.
reduce torrent filename length
from bcoding import bencode, bdecode
import sys
import time
import os
import pathlib
remapped = {}
rename_list = []
def shorten_filename(name, length):
left = 0
right = len(name)
middle = 0
while right != left and right - 1 != left:
middle = int((left + right)/2)
if len(name[:middle].encode('utf8')) > length:
right = middle
else:
left = middle
# print(left, right, middle, len(name[:middle].encode('utf8')), length)
return name[:middle-1]
bt = None
with open(sys.argv[1], 'rb') as fp:
bt = bdecode(fp)
for file in bt['info']['files']:
changed = False
original = file['path'][:]
for index, part in enumerate(file['path']):
t = tuple(file['path'][:index+1])
if t in remapped:
file['path'][index] = remapped[t]
continue
if len(part.encode('utf-8')) > 255:
name, ext = os.path.splitext(part)
capped = shorten_filename(name, 254 - len(ext.encode('utf8')))
new_name = capped + ext
file['path'][index] = new_name
new_t = tuple(file['path'][:index] + [new_name])
remapped[new_t] = new_name
changed = True
if changed:
rename_list.append(("/".join(original), "/".join(file['path'])))
for l, r in rename_list:
print(l, '->', r)
if rename_list:
original = pathlib.Path(sys.argv[1])
original.rename(original.with_name(original.name + '.bak'))
with open(sys.argv[1], 'wb') as fp:
bencode(bt, fp)
@pandada8
Copy link
Author

Note: infohash is calculated based in info's bencode, changing name in info dictionary resulting in tracker reject modified torrent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment