summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2010-01-01 03:14:11 +0200
committerLars Wirzenius <liw@liw.fi>2010-01-01 03:14:11 +0200
commit2220cc038941de88a26b981e797c091f7869e8d5 (patch)
tree20a1d542df720572ea20771fee85da3657d2bd0f
parent37810eaf498b82c8fb54bcf22c0861ad2c370d69 (diff)
downloadsummain-2220cc038941de88a26b981e797c091f7869e8d5.tar.gz
Add support for computing SHA-1 of files. Currently assumes it is
a regular file.
-rw-r--r--summainlib.py19
-rw-r--r--summainlib_tests.py31
2 files changed, 47 insertions, 3 deletions
diff --git a/summainlib.py b/summainlib.py
index 4d0a89c..509bc50 100644
--- a/summainlib.py
+++ b/summainlib.py
@@ -15,6 +15,7 @@
import grp
+import hashlib
import os
import pwd
import time
@@ -28,12 +29,15 @@ class FilesystemObject(object):
Responsible for gathering information and formatting it for
reporting.
- The optional stat_result argument is intended for unit tests.
+ The optional arguments are intended for unit tests.
'''
- def __init__(self, filename, stat_result=None):
+ def __init__(self, filename, stat_result=None, sha1=None,
+ open_file=None):
stat_result = stat_result or os.lstat(filename)
+ sha1 = sha1 or hashlib.sha1()
+ self.open_file = open_file or self.open_file
self.values = dict()
self['Name'] = filename
self['Mtime'] = self.format_time(stat_result.st_mtime)
@@ -46,6 +50,7 @@ class FilesystemObject(object):
self['Username'] = self.lookup_username(stat_result.st_uid)
self['Gid'] = '%d' % stat_result.st_gid
self['Group'] = self.lookup_group(stat_result.st_gid)
+ self['Sha-1'] = self.compute_sha1(filename, sha1)
def format_time(self, timestamp):
return time.strftime('%Y-%m-%d %H:%M:%S +0000',
@@ -57,6 +62,16 @@ class FilesystemObject(object):
def lookup_group(self, gid):
return grp.getgrgid(gid).gr_name
+ def compute_sha1(self, filename, sha1):
+ f = self.open_file(filename)
+ while True:
+ data = f.read(64*1024) # 64 KiB seems reasonable.
+ if not data:
+ break
+ sha1.update(data)
+ f.close()
+ return sha1.hexdigest()
+
def hook_name(self, value):
return urllib.quote(value)
diff --git a/summainlib_tests.py b/summainlib_tests.py
index b88f7b8..a3553ca 100644
--- a/summainlib_tests.py
+++ b/summainlib_tests.py
@@ -27,6 +27,30 @@ class FakeStatResult(object):
setattr(self, name, value)
+class FakeSha1(object):
+
+ def update(self, data):
+ pass
+
+ def hexdigest(self):
+ return 'abc'
+
+
+class FakeOpenFile(object):
+
+ def __call__(self, filename):
+ self.data = 'some data'
+ return self
+
+ def read(self, amount):
+ data = self.data[:amount]
+ self.data = self.data[len(data):]
+ return data
+
+ def close(self):
+ pass
+
+
class FilesystemObjectTests(unittest.TestCase):
def setUp(self):
@@ -40,7 +64,9 @@ class FilesystemObjectTests(unittest.TestCase):
st_gid=0)
def new(self, name):
- return summainlib.FilesystemObject(name, stat_result=self.st)
+ return summainlib.FilesystemObject(name, stat_result=self.st,
+ sha1=FakeSha1(),
+ open_file=FakeOpenFile())
def test_formats_simple_name_identically(self):
self.assertEqual(self.new('foo')['Name'], 'foo')
@@ -79,3 +105,6 @@ class FilesystemObjectTests(unittest.TestCase):
def test_formats_group_correctly(self):
self.assertEqual(self.new('foo')['Group'], 'root')
+ def test_formats_sha1_correctly_for_regular_file(self):
+ self.assertEqual(self.new('foo')['Sha-1'], 'abc')
+