import os
import shutil
import sys
try:
from hashlib import md5
from hashlib import sha1
from hashlib import sha512
except ImportError:
from md5 import md5
from sha import sha as sha1
class Digester(object):
BUFFER_SIZE = 1024*1024
def __init__(self, factory):
self.factory = factory
self.digest_size = factory().digest_size
self.hashfunc = None
def reset(self):
self.hashfunc = self.factory()
def write(self, data):
return self.hashfunc.update(data)
def hexdigest(self):
return self.hashfunc.hexdigest()
def main(manipath):
basedir, manifest = os.path.split(manipath)
if manifest == 'md5sums':
sink = Digester(md5)
elif manifest == 'sha1sums':
sink = Digester(sha1)
elif manifest == 'sha512sums':
sink = Digester(sha512)
else:
raise ValueError('The name of the digest manifest must be '
"'md5sums', 'sha1sums', or 'sha512sums', not '%s'" % manifest)
stream = None
try:
stream = open(manipath, 'r')
for line in stream:
sink.reset()
parse_digest(basedir, line.rstrip(), sink)
finally:
if stream is not None:
stream.close()
def parse_digest(basedir, entry, sink):
length = 2 * sink.digest_size
expected = entry[:length].lower()
filename = entry[length + 2:]
source = None
try:
source = open(os.path.join(basedir, filename), 'rb')
shutil.copyfileobj(source, sink, sink.BUFFER_SIZE)
actual = sink.hexdigest().lower()
finally:
if source is not None:
source.close()
if expected != actual:
raise ValueError('Mismatch: expected %s, actual %s: %s'
% (expected, actual, filename))
print('ok: %s %s' % (actual, filename))
if __name__ == '__main__':
main(sys.argv[1])