Use proper locking, and other minor fixes.
[audio.git] / src / archive / models.py
index 4a1d763..9e92fb8 100644 (file)
@@ -1,9 +1,10 @@
+import json
 import os.path
 
 from django.db import models
 from time import sleep
-from django.utils.encoding import force_bytes
 from django.utils.translation import ugettext_lazy as _
+from django_pglocks import advisory_lock
 from archive.constants import status
 from archive.settings import FILES_SAVE_PATH, ADVERT, LICENSE, ORGANIZATION, PROJECT
 from archive.utils import OverwriteStorage, sha1_file
@@ -81,28 +82,13 @@ class Audiobook(models.Model):
         return self.mp3_published and self.ogg_published
 
     def get_source_sha1(self):
-        source_sha1 = self.source_sha1
-        if self.pk:
-            source_sha1 = type(self).objects.get(pk=self.pk).source_sha1
-            while source_sha1 == 'wait':
-                sleep(10)
-        if not source_sha1:
-            self.source_sha1 = 'wait'
-            if self.pk:
-                type(self).objects.filter(pk=self.pk).update(source_sha1='wait')
-            try:
-                f = open(force_bytes(self.source_file.path))
-                source_sha1 = sha1_file(f)
-                self.source_sha1 = source_sha1
-                if self.pk:
-                    type(self).objects.filter(pk=self.pk).update(source_sha1=source_sha1)
-            except:
-                self.source_sha1 = ''
-                if self.pk:
-                    type(self).objects.filter(pk=self.pk).update(source_sha1='')
-                return None
-        return source_sha1
-
+        assert self.pk or self.source_sha1
+        if not self.source_sha1:
+            with advisory_lock(f'get_source_sha1_{self.pk}'):
+                with open(self.source_file.path, 'rb') as f:
+                    self.source_sha1 = sha1_file(f)
+                self.save(update_fields=['source_sha1'])
+        return self.source_sha1
 
     def new_publish_tags(self):
         title = self.title
@@ -131,11 +117,10 @@ class Audiobook(models.Model):
             'license': LICENSE,
             'organization': ORGANIZATION,
             'title': title,
-            #'flac_sha1': self.get_source_sha1(),
             'project': self.project.name,
             'funded_by': self.project.sponsors,
         }
-        if self.source_sha1 and self.source_sha1 != 'wait':
+        if self.source_sha1:
             tags['flac_sha1'] = self.source_sha1
         return tags