Skip to content

Instantly share code, notes, and snippets.

@apuignav
Last active August 29, 2015 14:03
Show Gist options
  • Select an option

  • Save apuignav/c6360782f6c8fa1d9407 to your computer and use it in GitHub Desktop.

Select an option

Save apuignav/c6360782f6c8fa1d9407 to your computer and use it in GitHub Desktop.
Torrent file analyzer
#!/usr/bin/env python
# =============================================================================
# @file torrent.py
# @author Albert Puig (albert.puig@epfl.ch)
# @date 05.07.2014
# =============================================================================
"""Torrent file-info decoder, extracted from
http://effbot.org/zone/bencode.htm
"""
import re
def tokenize(text, match=re.compile("([idel])|(\d+):|(-?\d+)").match):
i = 0
while i < len(text):
m = match(text, i)
s = m.group(m.lastindex)
i = m.end()
if m.lastindex == 2:
yield "s"
yield text[i:i+int(s)]
i = i + int(s)
else:
yield s
def decode_item(next, token):
if token == "i":
# integer: "i" value "e"
data = int(next())
if next() != "e":
raise ValueError
elif token == "s":
# string: "s" value (virtual tokens)
data = next()
elif token == "l" or token == "d":
# container: "l" (or "d") values "e"
data = []
tok = next()
while tok != "e":
data.append(decode_item(next, tok))
tok = next()
if token == "d":
data = dict(zip(data[0::2], data[1::2]))
else:
raise ValueError
return data
def decode(text):
try:
src = tokenize(text)
data = decode_item(src.next, src.next())
for token in src: # look for more tokens
raise SyntaxError("trailing junk")
except (AttributeError, ValueError, StopIteration):
raise SyntaxError("syntax error")
return data
if __name__ == '__main__':
import sys
import os
# Check args
if len(sys.argv) < 2:
print "Specify at least one torrent file!"
sys.exit(0)
for file_name in sys.argv[1:]:
if not os.path.exists(file_name):
print "File doesn't exist, skipping -> %s" % file_name
continue
torrent_data = decode(open(file_name, 'rb').read())
print "Torrent name:", torrent_data["info"]["name"]
if 'files' in torrent_data["info"]:
for file_ in torrent_data["info"]["files"]:
print " *%r - %d bytes" % ("/".join(file_["path"]), file_["length"])
else:
print " *No file info available"
# EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment