Commits

Lars Yencken  committed 92768ab

Adds a basic checksum app using code from FOKS.

  • Participants

Comments (0)

Files changed (4)

+syntax: glob
+*.pyc
+*.pyo
+*.swp
+build
+dist
+checksum
+# -*- coding: utf-8 -*-
+#
+#  __init__.py
+#  checksum
+# 
+#  Created by Lars Yencken on 09-11-2008.
+#  Copyright 2008 Lars Yencken. All rights reserved.
+#
+
+"""
+A simple app which stores checksums for files. It is particularly useful for
+avoiding repeated build steps for large objects.
+
+To do this, save a checksum of the object's dependencies after creating it
+the first time. The object remains "clean" as long as the dependencies haven't
+changed.
+"""
+
+# vim: ts=4 sw=4 sts=4 et tw=78:
+
+# -*- coding: utf-8 -*-
+#
+#  models.py
+#  checksum
+# 
+#  Created by Lars Yencken on 09-11-2008.
+#  Copyright 2008 Lars Yencken. All rights reserved.
+#
+
+"""
+Models for the checksum app.
+"""
+
+from zlib import crc32
+
+from django.db import models
+
+class Checksum(models.Model):
+    """
+    A checksum of the input files required to build part of the database.
+
+    >>> Checksum.objects.all().delete()
+    >>> Checksum.needs_update('models', [__file__])
+    True
+    >>> Checksum.store('models', [__file__])
+    >>> Checksum.needs_update('models', [__file__])
+    False
+    """
+    tag = models.CharField(max_length=50)
+    value = models.CharField(max_length=15)
+
+    def __unicode__(self):
+        return u'%s' % self.tag
+
+    @staticmethod
+    def checksum(files):
+        result = 0
+        for filename in files:
+            i_stream = open(filename, 'r')
+            result = crc32(i_stream.read(), result)
+            i_stream.close()
+
+        return str(result)
+
+    @staticmethod
+    def needs_update(tag, files, delete_if_old=True):
+        """
+        Returns True if the database stored checksum doesn't exist or is
+        different to that calculated by storing the files.
+        """
+        if not files:
+            raise ValueError, "Need at least one file to checksum"
+
+        result = Checksum.checksum(files)
+        try:
+            existing = Checksum.objects.get(tag=tag)
+            if existing.value == result:
+                return False
+            else:
+                if delete_if_old:
+                    existing.delete()
+
+        except ObjectDoesNotExist:
+            pass
+
+        return True
+
+    @staticmethod
+    def store(tag, files):
+        "Store the given checksum."
+        Checksum.objects.filter(tag=tag).delete()
+        obj = Checksum(tag=tag, value=Checksum.checksum(files))
+        obj.save()
+        return
+
+# vim: ts=4 sw=4 sts=4 et tw=78: