Skip to content

Instantly share code, notes, and snippets.

@samhocevar
Created January 12, 2016 19:01
Show Gist options
  • Save samhocevar/e392363909e4561ec5b7 to your computer and use it in GitHub Desktop.
Save samhocevar/e392363909e4561ec5b7 to your computer and use it in GitHub Desktop.
def make_meta_file_from_list(loc_list, url, params=None, flag=None,
progress=lambda x: None, progress_percent=True):
"""Make a single .torrent file for a given list of items"""
if params is None:
params = {}
if flag is None:
flag = threading.Event()
tree = bttree_from_list(loc_list)
# Extract target from parameters
if 'target' not in params or params['target'] == '':
fname, ext = os.path.split(loc)
if ext == '':
target = fname + '.torrent'
else:
target = os.path.join(fname, ext + '.torrent')
params['target'] = target
info = tree.makeInfo(flag=flag, progress=progress,
progress_percent=progress_percent, **params)
if flag is not None and flag.is_set():
return
newparams = { key:val for key, val in params.items() \
if key in MetaInfo.typemap }
metainfo = MetaInfo(announce=url, info=info, **newparams)
metainfo.write(params['target'])
def bttree_from_list(loc_list):
def splitpath(path):
d, f = os.path.split(path)
return splitpath(d) + [f] if d else [f]
has_files = False
# Parse the item list and build a recursive directory tree whose
# leaves are BTTrees.
tree = {}
for loc in loc_list:
path_elems = splitpath(loc)
if os.path.isdir(loc):
filename = None
elif os.path.isfile(loc):
has_files = True
filename = path_elems[-1]
path_elems = path_elems[:-1]
else:
raise IOError("Entry is neither file nor directory: " + loc)
n = tree
for e in path_elems:
if e not in n:
n[e] = {}
n = n[e]
if filename:
try:
n[filename] = BTTree(loc, path_elems + [filename])
except IOError as problem:
print(problem)
# Parse that tree and make each of the non-leaf nodes BTTrees, too
def fix_bttree(node, path):
# If already a BTTree, do nothing
if isinstance(node, BTTree):
return node
# If empty, it’s a directory, create a BTTree from its contents
if not node:
return BTTree(os.sep.join(path), path)
# Otherwise, create a new BTTree from the children
n = BTTree.__new__(BTTree)
n.loc = os.sep.join(path) if path else '.'
n.path = path
n.subs = []
for k, v in node.items():
if v or not has_files:
n.subs.append(fix_bttree(v, path + [k]))
n.size = sum(sub.size for sub in n.subs)
return n
return fix_bttree(tree, [])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment