def subdir_recurse(listing, path, depth=1): # XXX add a knob for this if depth > 256: _out.die('reached max recursion depth') for idx in range(len(listing)): d_or_f, fname = (listing[idx]['type'], listing[idx]['name']) this_path = ''.join([path, '/', fname]) if d_or_f == 'directory': listing[idx] = subdir_recurse(listing[idx]['contents'], this_path, depth+1) elif d_or_f == 'file': title = Struct() title.basename = path title.name = fname title.path = this_path listing[idx] = title else: # sanity check _out.die('BUG: unsupported file type `{}`'.format(d_or_f)) if depth != 1: return listing return _util.flatten_sublists(listing)
def rem_subdir_recurse(listing, path, depth=1): # XXX add a knob for this if depth > 256: _out.die('reached max recursion depth') for idx in range(len(listing)): # madokami's FTP LIST format is long ls, [{}/ are meta tokens]: # {d,-}rwxrwxrwx 1 u g sz mon day y/time fname # | | # |=> directory or regular file |=> filename # # XXX: while highly unlikely that whitespace gives any significant # distinction beyond one space, the split() module splits by any amount # of wspace; thus, when re-join()ed, any extra wspace is truncated to # one space. fields = listing[idx].split() d_or_f, fname = (fields[0][:1], ' '.join(fields[8:])) this_path = ''.join([path, '/', fname]) if d_or_f == 'd': listing[idx] = rem_subdir_recurse(search_exact(this_path, True) .getvalue() .decode() .splitlines(), this_path, depth+1) elif d_or_f == '-': # is reg file title = Struct() title.basename = path title.name = fname title.path = this_path listing[idx] = title else: # sanity check _out.die('BUG: unsupported file type `{}`'.format(d_or_f)) if depth != 1: return listing return _util.flatten_sublists(listing)