mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-20 05:28:04 +00:00
pyfec: more progress indicators, handling of already-existent outfile
This commit is contained in:
parent
554be1ba6a
commit
049d8d1576
@ -19,11 +19,11 @@ if '-V' in sys.argv or '--version' in sys.argv:
|
|||||||
parser = argparse.ArgumentParser(description="Encode a file into a set of share files, a subset of which can later be used to recover the original file.")
|
parser = argparse.ArgumentParser(description="Encode a file into a set of share files, a subset of which can later be used to recover the original file.")
|
||||||
|
|
||||||
parser.add_argument('inputfile', help='file to encode or "-" for stdin', type=argparse.FileType('rb'), metavar='INF')
|
parser.add_argument('inputfile', help='file to encode or "-" for stdin', type=argparse.FileType('rb'), metavar='INF')
|
||||||
parser.add_argument('-d', '--output-dir', help='directory in which share file names will be created', default='.', metavar='D')
|
parser.add_argument('-d', '--output-dir', help='directory in which share file names will be created (default ".")', default='.', metavar='D')
|
||||||
parser.add_argument('-p', '--prefix', help='prefix for share file names; If omitted, the name of the input file will be used.', metavar='P')
|
parser.add_argument('-p', '--prefix', help='prefix for share file names; If omitted, the name of the input file will be used.', metavar='P')
|
||||||
parser.add_argument('-s', '--suffix', help='suffix for share file names', default='.fec', metavar='S')
|
parser.add_argument('-s', '--suffix', help='suffix for share file names (default ".fec")', default='.fec', metavar='S')
|
||||||
parser.add_argument('-m', '--totalshares', help='the total number of share files created', default=16, metavar='M')
|
parser.add_argument('-m', '--totalshares', help='the total number of share files created (default 16)', default=16, metavar='M')
|
||||||
parser.add_argument('-k', '--requiredshares', help='the number of share files required to reconstruct', default=4, metavar='K')
|
parser.add_argument('-k', '--requiredshares', help='the number of share files required to reconstruct (default 4)', default=4, metavar='K')
|
||||||
parser.add_argument('-v', '--verbose', help='print out messages about progress', action='store_true')
|
parser.add_argument('-v', '--verbose', help='print out messages about progress', action='store_true')
|
||||||
parser.add_argument('-V', '--version', help='print out version number and exit', action='store_true')
|
parser.add_argument('-V', '--version', help='print out version number and exit', action='store_true')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
# import bindann
|
# import bindann
|
||||||
# import bindann.monkeypatch.all
|
# import bindann.monkeypatch.all
|
||||||
|
|
||||||
import sys
|
import os, sys
|
||||||
|
|
||||||
from fec.util import argparse
|
from fec.util import argparse
|
||||||
|
|
||||||
@ -19,9 +19,10 @@ if '-V' in sys.argv or '--version' in sys.argv:
|
|||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Decode data from share files.")
|
parser = argparse.ArgumentParser(description="Decode data from share files.")
|
||||||
|
|
||||||
parser.add_argument('outputfile', help='file to write the resulting data to, or "-" for stdout', type=argparse.FileType('wb'), metavar='OUTF')
|
parser.add_argument('-o', '--outputfile', required=True, help='file to write the resulting data to, or "-" for stdout', type=str, metavar='OUTF')
|
||||||
parser.add_argument('sharefiles', nargs='+', help='shares file to read the encoded data from', type=argparse.FileType('rb'), metavar='SHAREFILE')
|
parser.add_argument('sharefiles', nargs='*', help='shares file to read the encoded data from', type=argparse.FileType('rb'), metavar='SHAREFILE')
|
||||||
parser.add_argument('-v', '--verbose', help='print out messages about progress', action='store_true')
|
parser.add_argument('-v', '--verbose', help='print out messages about progress', action='store_true')
|
||||||
|
parser.add_argument('-f', '--force', help='overwrite any file which already in place of the output file', action='store_true')
|
||||||
parser.add_argument('-V', '--version', help='print out version number and exit', action='store_true')
|
parser.add_argument('-V', '--version', help='print out version number and exit', action='store_true')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@ -29,6 +30,16 @@ if len(args.sharefiles) < 2:
|
|||||||
print "At least two sharefiles are required."
|
print "At least two sharefiles are required."
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
ret = filefec.decode_from_files(args.outputfile, args.sharefiles, args.verbose)
|
if args.force:
|
||||||
|
outf = open(args.outputfile, 'wb')
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
outfd = os.open(args.outputfile, os.O_WRONLY|os.O_CREAT|os.O_EXCL)
|
||||||
|
except OSError:
|
||||||
|
print "There is already a file named %r -- aborting. Use --force to overwrite." % (args.outputfile,)
|
||||||
|
sys.exit(2)
|
||||||
|
outf = os.fdopen(outfd, "wb")
|
||||||
|
|
||||||
|
ret = filefec.decode_from_files(outf, args.sharefiles, args.verbose)
|
||||||
|
|
||||||
sys.exit(ret)
|
sys.exit(ret)
|
||||||
|
@ -188,10 +188,13 @@ def encode_to_files(inf, fsize, dirname, prefix, k, m, suffix=".fec", verbose=Fa
|
|||||||
fns.append(fn)
|
fns.append(fn)
|
||||||
sumlen = [0]
|
sumlen = [0]
|
||||||
def cb(blocks, length):
|
def cb(blocks, length):
|
||||||
if verbose:
|
|
||||||
print "Writing %d bytes into share files..." % (length,)
|
|
||||||
assert len(blocks) == len(fs)
|
assert len(blocks) == len(fs)
|
||||||
|
oldsumlen = sumlen[0]
|
||||||
sumlen[0] += length
|
sumlen[0] += length
|
||||||
|
if verbose:
|
||||||
|
if int((float(oldsumlen) / fsize) * 10) != int((float(sumlen[0]) / fsize) * 10):
|
||||||
|
print str(int((float(sumlen[0]) / fsize) * 10) * 10) + "% ...",
|
||||||
|
|
||||||
if sumlen[0] > fsize:
|
if sumlen[0] > fsize:
|
||||||
raise IOError("Wrong file size -- possibly the size of the file changed during encoding. Original size: %d, observed size at least: %s" % (fsize, sumlen[0],))
|
raise IOError("Wrong file size -- possibly the size of the file changed during encoding. Original size: %d, observed size at least: %s" % (fsize, sumlen[0],))
|
||||||
for i in range(len(blocks)):
|
for i in range(len(blocks)):
|
||||||
@ -214,9 +217,16 @@ def encode_to_files(inf, fsize, dirname, prefix, k, m, suffix=".fec", verbose=Fa
|
|||||||
fileutil.remove_if_possible(fn)
|
fileutil.remove_if_possible(fn)
|
||||||
return 1
|
return 1
|
||||||
if verbose:
|
if verbose:
|
||||||
|
print
|
||||||
print "Done!"
|
print "Done!"
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
# Note: if you really prefer base-2 and you change this code, then please
|
||||||
|
# denote 2^20 as "MiB" instead of "MB" in order to avoid ambiguity.
|
||||||
|
# Thanks.
|
||||||
|
# http://en.wikipedia.org/wiki/Megabyte
|
||||||
|
MILLION_BYTES=10**6
|
||||||
|
|
||||||
def decode_from_files(outf, infiles, verbose=False):
|
def decode_from_files(outf, infiles, verbose=False):
|
||||||
"""
|
"""
|
||||||
Decode from the first k files in infiles, writing the results to outf.
|
Decode from the first k files in infiles, writing the results to outf.
|
||||||
@ -228,6 +238,7 @@ def decode_from_files(outf, infiles, verbose=False):
|
|||||||
k = None
|
k = None
|
||||||
padlen = None
|
padlen = None
|
||||||
|
|
||||||
|
byteswritten = 0
|
||||||
for f in infiles:
|
for f in infiles:
|
||||||
(nm, nk, npadlen, shnum,) = _parse_header(f)
|
(nm, nk, npadlen, shnum,) = _parse_header(f)
|
||||||
if not (m is None or m == nm):
|
if not (m is None or m == nm):
|
||||||
@ -257,11 +268,18 @@ def decode_from_files(outf, infiles, verbose=False):
|
|||||||
# Then this was a full read, so we're still in the sharefiles.
|
# Then this was a full read, so we're still in the sharefiles.
|
||||||
resultdata = dec.decode(chunks, shnums, padlen=0)
|
resultdata = dec.decode(chunks, shnums, padlen=0)
|
||||||
outf.write(resultdata)
|
outf.write(resultdata)
|
||||||
|
byteswritten += len(resultdata)
|
||||||
|
if verbose:
|
||||||
|
if ((byteswritten - len(resultdata)) / (10*MILLION_BYTES)) != (byteswritten / (10*MILLION_BYTES)):
|
||||||
|
print str(byteswritten / MILLION_BYTES) + " MB ...",
|
||||||
else:
|
else:
|
||||||
# Then this was a short read, so we've reached the end of the sharefiles.
|
# Then this was a short read, so we've reached the end of the sharefiles.
|
||||||
resultdata = dec.decode(chunks, shnums, padlen)
|
resultdata = dec.decode(chunks, shnums, padlen)
|
||||||
outf.write(resultdata)
|
outf.write(resultdata)
|
||||||
return # Done.
|
return # Done.
|
||||||
|
if verbose:
|
||||||
|
print
|
||||||
|
print "Done!"
|
||||||
|
|
||||||
def encode_file(inf, cb, k, m, chunksize=4096):
|
def encode_file(inf, cb, k, m, chunksize=4096):
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user