[file_utils] dirpacker: refactoring (class Bin)
This commit is contained in:
parent
61e115c4b9
commit
83e5bfddeb
|
@ -36,6 +36,29 @@ from collections import defaultdict
|
||||||
import math
|
import math
|
||||||
|
|
||||||
|
|
||||||
|
class Bin:
|
||||||
|
""" Represents a bin (a volume) containing files and directories.
|
||||||
|
"""
|
||||||
|
def __init__(self, bin_id, total_size, files):
|
||||||
|
"""bin_id is the bin's identifier, total_size the sum of the sizes of
|
||||||
|
all the files it contains, and files is a dictionary with file names
|
||||||
|
as the keys and sizes as values.
|
||||||
|
"""
|
||||||
|
self.id = bin_id
|
||||||
|
self.size = total_size
|
||||||
|
self.files = files
|
||||||
|
|
||||||
|
def print(self):
|
||||||
|
"""Displays the contents of the bin.
|
||||||
|
"""
|
||||||
|
print("\n### Bin #{} ###\n# List of files:".format(self.id))
|
||||||
|
for filename, size in sorted(self.files.items()):
|
||||||
|
print("{} # {:.2f} MiB".format(filename, size))
|
||||||
|
print("# This bin's size: {:.2f} MiB".format(self.size))
|
||||||
|
sizefree = options.maxbinsize - self.size
|
||||||
|
print("# Free space: {:.2f} MiB".format(sizefree))
|
||||||
|
|
||||||
|
|
||||||
def du(basepath):
|
def du(basepath):
|
||||||
""" Returns the size of the file of directory `basepath`, in MiB.
|
""" Returns the size of the file of directory `basepath`, in MiB.
|
||||||
"""
|
"""
|
||||||
|
@ -51,10 +74,10 @@ def du(basepath):
|
||||||
|
|
||||||
def create_bin(binnumber):
|
def create_bin(binnumber):
|
||||||
"""Creates a bin numbered `binnumber` from the global list of files and
|
"""Creates a bin numbered `binnumber` from the global list of files and
|
||||||
sizes.
|
sizes, and returns it.
|
||||||
"""
|
"""
|
||||||
print("\n### Bin #{} ###\n# List of files:".format(binnumber))
|
|
||||||
binsize = 0
|
binsize = 0
|
||||||
|
files = {}
|
||||||
for size in reversed(sorted(sizes.keys())):
|
for size in reversed(sorted(sizes.keys())):
|
||||||
newbinsize = binsize + size
|
newbinsize = binsize + size
|
||||||
# Try the next, smaller file if we would exceed the bin's maximum size
|
# Try the next, smaller file if we would exceed the bin's maximum size
|
||||||
|
@ -62,8 +85,7 @@ def create_bin(binnumber):
|
||||||
if newbinsize > options.maxbinsize:
|
if newbinsize > options.maxbinsize:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
filename = sizes[size].pop()
|
files[sizes[size].pop()] = size
|
||||||
print("{} # {:.2f} MiB".format(filename, size))
|
|
||||||
# Delete the size from the dictionary if its last file name was just
|
# Delete the size from the dictionary if its last file name was just
|
||||||
# popped:
|
# popped:
|
||||||
if not len(sizes[size]):
|
if not len(sizes[size]):
|
||||||
|
@ -71,22 +93,23 @@ def create_bin(binnumber):
|
||||||
|
|
||||||
binsize = newbinsize
|
binsize = newbinsize
|
||||||
|
|
||||||
print("# This bin's size: {:.2f} MiB".format(binsize))
|
return Bin(binnumber, binsize, files)
|
||||||
sizefree = options.maxbinsize - binsize
|
|
||||||
print("# Free space: {:.2f} MiB".format(sizefree))
|
|
||||||
|
|
||||||
|
|
||||||
### Parse command-line arguments ###
|
### Parse command-line arguments ###
|
||||||
|
|
||||||
arg_parser = argparse.ArgumentParser(
|
arg_parser = argparse.ArgumentParser(
|
||||||
description="Packs files and directories into fixed-size volumes",
|
description="Packs files and directories into fixed-size volumes",
|
||||||
epilog="For more information about this program, see the README file \
|
epilog="For more information about this program, see the README file"
|
||||||
provided with the distribution.")
|
"provided with the distribution.")
|
||||||
arg_parser.add_argument("-s", "--size", action="store", dest="maxbinsize",
|
arg_parser.add_argument("-s", "--size", action="store", dest="maxbinsize",
|
||||||
type=float, default=703,
|
type=float, default=703,
|
||||||
help="maximal size of each volume (bin), in MiB; the "
|
help="maximal size of each volume (bin), in MiB; the "
|
||||||
+"default is 703 MiB, i.e. the size of a 80-minute "
|
"default is 703 MiB, i.e. the size of a 80-minute "
|
||||||
+"CD-ROM")
|
"CD-ROM")
|
||||||
|
arg_parser.add_argument("-a", "--action", action="store", default="list",
|
||||||
|
help='action to be taken; can be "list" (default)'
|
||||||
|
' or "move" (move input to per-volume directories)')
|
||||||
arg_parser.add_argument("filenames", metavar="file", nargs="+",
|
arg_parser.add_argument("filenames", metavar="file", nargs="+",
|
||||||
help="files or directories to pack")
|
help="files or directories to pack")
|
||||||
options = arg_parser.parse_args()
|
options = arg_parser.parse_args()
|
||||||
|
@ -115,14 +138,16 @@ print("# Total size of the input files: {:.2f} MiB".format(totalsize))
|
||||||
minbins = math.ceil(totalsize / options.maxbinsize)
|
minbins = math.ceil(totalsize / options.maxbinsize)
|
||||||
print("# Minimal (optimal) number of bins required: ", minbins)
|
print("# Minimal (optimal) number of bins required: ", minbins)
|
||||||
sizefree = minbins * options.maxbinsize - totalsize
|
sizefree = minbins * options.maxbinsize - totalsize
|
||||||
print("# Total unused space with {} bins: {:.2f} MiB".format(minbins, sizefree))
|
print("# Theoretical unused space with {} bins: {:.2f} MiB"
|
||||||
|
.format(minbins, sizefree))
|
||||||
|
|
||||||
|
|
||||||
### Assemble the bins ###
|
### Assemble the bins ###
|
||||||
|
|
||||||
|
bins = []
|
||||||
binnumber = 1
|
binnumber = 1
|
||||||
while len(sizes):
|
while len(sizes):
|
||||||
create_bin(binnumber)
|
bins.append(create_bin(binnumber))
|
||||||
binnumber += 1
|
binnumber += 1
|
||||||
binscreated = binnumber - 1
|
binscreated = binnumber - 1
|
||||||
|
|
||||||
|
@ -130,8 +155,26 @@ binscreated = binnumber - 1
|
||||||
### Final statistics ###
|
### Final statistics ###
|
||||||
|
|
||||||
sizefree = binscreated * options.maxbinsize - totalsize
|
sizefree = binscreated * options.maxbinsize - totalsize
|
||||||
print("\n# Total unused space over the {} bins created: {:.2f} MiB"
|
print("""\
|
||||||
.format(binscreated, sizefree))
|
# {} bins created.
|
||||||
|
# Actual unused space over the {} bins created: {:.2f} MiB"""
|
||||||
|
.format(binscreated, binscreated, sizefree))
|
||||||
|
|
||||||
|
|
||||||
|
### Execute the requested action ###
|
||||||
|
|
||||||
|
if options.action == "list":
|
||||||
|
for b in bins:
|
||||||
|
b.print()
|
||||||
|
elif options.action == "move":
|
||||||
|
print('Action "move" is not implemented yet.')
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
print('ERROR! Action "{}" is unknown.'.format(options.action))
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
### Wrapping-up ###
|
||||||
|
|
||||||
if (ignored_files):
|
if (ignored_files):
|
||||||
print("\n# WARNING! There were ignored files, see at the top of this log.")
|
print("\n# WARNING! There were ignored files, see at the top of this log.")
|
||||||
|
|
Loading…
Reference in New Issue