Rewrite mkpodcastplaylist for python3 and cleanup

Buddy Sandidge 6 years ago
parent dd21860151
commit f967107009

@ -1,109 +1,119 @@
#!/usr/bin/env python #!/usr/bin/env python3
"""
This is a program that generates playlists based on the size of the from functools import partial
largest file/directory. It searches directories, getting their size from pathlib import Path
and lists the first file in the largest direcotry.
"""
import errno
import os import os
import sys import sys
class File: def ensure_path(p):
"""A file has a size and a name""" return p if isinstance(p, Path) else Path(p)
def include_all(*args):
return True
class File:
def __init__(self, path): def __init__(self, path):
self.name = path self.path = ensure_path(path)
self.size = os.path.getsize(self.name) self.stat = os.stat(self.path)
def get_size(self): @property
"""Get the size of the current file""" def name(self):
return self.size return self.path.name
def get_name(self): def size(self):
"""Get the name of the current file""" return self.stat.st_size
return self.name
class Directory: def get(values, *, existing=set()):
"""A directory is a list that can contain files and other directories.""" for val in values:
if val in existing:
continue
if val.size() == 0:
continue
yield val
def __init__(self, path): def by_size(x, *, filter=None):
self.path = path return x.size(filter=filter)
self.files = []
def by_name(x):
files = os.listdir(path) return x.name
files.sort()
for fil in files: class Directory:
if type(fil).__name__ == "str": def __init__(self, base_dir):
self.files.append(File("%s/%s" % (path, fil))) self.base = ensure_path(base_dir)
self.files = {}
def get_dir_name(self): self.dirs = {}
"""Get the name of the current directory."""
return self.path @property
def name(self):
def get_dir_size(self): return self.base
"""Get the size of the current directory."""
ret = 0 def list_by_size(self, *, files=None):
for fil in self.files: files = set() if files is None else files
ret += fil.get_size()
return ret while True:
dirs = get(self.dirs.values(), existing=files)
def get_head_file(self): without_file = lambda x: x not in files
"""Get the 'head' file in the directory.""" filtered_by_size = partial(by_size, filter=without_file)
return self.files[0].get_name() dirs_by_size = sorted(dirs, key=filtered_by_size, reverse=True)
if len(dirs_by_size):
def num_files(self): largest_dir = dirs_by_size[0]
"""Get the number of files in the directory.""" current_file = next(largest_dir.list_by_size(files=files))
return len(self.files) files.add(current_file)
yield current_file
def remove_head_file(self): continue
"""Remove the head file from being counted."""
self.files = self.files[1:] files_by_name = sorted(get(self.files.values(), existing=files),
key=by_name)
def sort_dir(direct): if len(files_by_name):
"""Sort the directories by size.""" current_file = files_by_name[0]
return direct.get_dir_size() files.add(current_file)
yield current_file
def main(): continue
"""The main script."""
try:
base_dir = sys.argv[1]
except IndexError:
print "Must enter path of directory to search. Example: %s ./foo" % \
sys.argv[0]
os.abort()
if os.path.exists(base_dir) == False:
print "Could not find path: '%s'" % base_dir
os.abort()
if base_dir[-1] == "/":
base_dir = base_dir[:-1]
base_dir_listing = os.listdir(base_dir)
directories = []
for direct in base_dir_listing:
rel_dir = "%s/%s" % (base_dir, direct)
if os.path.islink(rel_dir) == False and os.path.isdir(rel_dir):
directories.append(Directory(rel_dir))
while directories:
directories.sort(key=sort_dir)
directories.reverse()
headfile = directories[0].get_head_file()
#headfile = headfile.replace('podcasts/', 'podcast/', 1)
#print headfile
try:
sys.stdout.write("%s\n" % headfile)
except IOError as e:
if e.errno == errno.EPIPE:
return return
raise e
directories[0].remove_head_file()
if directories[0].num_files() == 0:
directories = directories[1:]
if __name__ == "__main__": def size(self, *, filter=None):
main() filter = include_all if filter is None else filter
total = 0
for node in self.files.values():
if filter(node):
total += node.size()
for node in self.dirs.values():
total += node.size(filter=filter)
return total
def directory(self, *parts):
if len(parts) == 0:
return self
part, *rest = parts
node = self.dirs.get(part)
if node is None:
node = Directory(part)
self.dirs[part] = node
return node.directory(*rest)
def add_file(self, path):
node = self.directory(*path.parent.parts)
node.files[path.name] = File(path)
return node.files[path.name]
def main(base_dir):
tree = Directory(base_dir)
for root, dirs, files in os.walk(base_dir):
for f in files:
tree.add_file(Path(root) / f)
for f in tree.list_by_size():
print("{}/{}".format(base_dir, f.path))
if __name__ == '__main__':
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('-o', '--output', default='.')
parser.add_argument('-d', '--directory', default=Path('.'), type=Path)
args = parser.parse_args()
main(args.directory)

Loading…
Cancel
Save