Initial port to python3
[htsworkflow.git] / htsworkflow / frontend / experiments / models.py
index 20131e41bb22170cd720e4b93e934b4a9787e786..c29026883f3bf8c59512e42d0c54fd24f0945ec4 100644 (file)
@@ -20,7 +20,7 @@ LOGGER = logging.getLogger(__name__)
 default_pM = 5
 try:
     default_pM = int(settings.DEFAULT_PM)
-except ValueError, e:
+except ValueError as e:
     LOGGER.error("invalid value for frontend.default_pm")
 
 # how many days to wait before trying to re-import a runfolder
@@ -54,7 +54,7 @@ class ClusterStation(models.Model):
         ordering = ["-isdefault", "name"]
 
     def __unicode__(self):
-        return unicode(self.name)
+        return str(self.name)
 
     @classmethod
     def default(cls):
@@ -71,7 +71,7 @@ class ClusterStation(models.Model):
         """Clear default if needed
         """
         if instance.isdefault:
-            for c in ClusterStation.objects.all():
+            for c in ClusterStation.objects.filter(isdefault=True).all():
                 if c.id != instance.id:
                     c.isdefault = False
                     c.save()
@@ -93,9 +93,9 @@ class Sequencer(models.Model):
         ordering = ["-isdefault", "-active", "name"]
 
     def __unicode__(self):
-        name = [unicode(self.name)]
+        name = [str(self.name)]
         if self.instrument_name is not None:
-            name.append("(%s)" % (unicode(self.instrument_name),))
+            name.append("(%s)" % (str(self.instrument_name),))
         return " ".join(name)
 
     @models.permalink
@@ -118,7 +118,7 @@ class Sequencer(models.Model):
         """Clear default if needed
         """
         if instance.isdefault:
-            for s in Sequencer.objects.all():
+            for s in Sequencer.objects.filter(isdefault=True).all():
                 if s.id != instance.id:
                     s.isdefault = False
                     s.save()
@@ -150,7 +150,7 @@ class FlowCell(models.Model):
     notes = models.TextField(blank=True)
 
     def __unicode__(self):
-        return unicode(self.flowcell_id)
+        return str(self.flowcell_id)
 
     def Lanes(self):
         html = ['<table>']
@@ -184,9 +184,9 @@ class FlowCell(models.Model):
         """Convert our boolean 'is paired' flag to a name
         """
         if self.paired_end:
-            return u"Paired"
+            return "Paired"
         else:
-            return u"Single"
+            return "Single"
 
     @models.permalink
     def get_absolute_url(self):
@@ -209,32 +209,34 @@ class FlowCell(models.Model):
         result_home_dir = os.path.join(settings.RESULT_HOME_DIR, '')
         run_xml_re = re.compile(glob.fnmatch.translate('run*.xml'))
 
-        dataruns = dict([(x.result_dir, x) for x in self.datarun_set.all()])
-
         result_dirs = []
         for dirpath, dirnames, filenames in os.walk(result_root):
             for filename in filenames:
                 if run_xml_re.match(filename):
                     # we have a run directory
                     relative_pathname = get_relative_pathname(dirpath)
-                    cached_run = dataruns.get(relative_pathname, None)
-                    now = datetime.datetime.now()
-                    if (cached_run is None):
-                        self.import_data_run(relative_pathname, filename)
-                    elif (now - cached_run.last_update_time).days > \
-                             RESCAN_DELAY:
-                        self.import_data_run(relative_pathname,
-                                             filename, cached_run)
-
-    def import_data_run(self, relative_pathname, run_xml_name, run=None):
+                    self.import_data_run(relative_pathname, filename)
+
+    def import_data_run(self, relative_pathname, run_xml_name, force=False):
         """Given a result directory import files"""
+        now = datetime.datetime.now()
         run_dir = get_absolute_pathname(relative_pathname)
         run_xml_path = os.path.join(run_dir, run_xml_name)
-        run_xml_data = runfolder.load_pipeline_run_xml(run_xml_path)
-        LOGGER.debug("Importing run from %s" % (relative_pathname,))
 
-        if run is None:
+        runs = DataRun.objects.filter(result_dir = relative_pathname)
+        if len(runs) == 0:
             run = DataRun()
+            created = True
+        elif len(runs) > 1:
+            raise RuntimeError("Too many data runs for %s" % (
+                relative_pathname,))
+        else:
+            run = runs[0]
+            created = False
+
+        if created or force or (now-run.last_update_time).days > RESCAN_DELAY:
+            LOGGER.debug("Importing run from %s" % (relative_pathname,))
+            run_xml_data = runfolder.load_pipeline_run_xml(run_xml_path)
             run.flowcell = self
             run.status = RUN_STATUS_REVERSE_MAP['DONE']
             run.result_dir = relative_pathname
@@ -249,10 +251,10 @@ class FlowCell(models.Model):
             run.alignment_software = run_xml_data.gerald.software
             run.alignment_version = run_xml_data.gerald.version
 
-        run.last_update_time = datetime.datetime.now()
-        run.save()
+            run.last_update_time = datetime.datetime.now()
+            run.save()
 
-        run.update_result_files()
+            run.update_result_files()
 
 
 # FIXME: should we automatically update dataruns?
@@ -302,7 +304,7 @@ class Lane(models.Model):
                 [str(self.id)])
 
     def __unicode__(self):
-        return self.flowcell.flowcell_id + ':' + unicode(self.lane_number)
+        return self.flowcell.flowcell_id + ':' + str(self.lane_number)
 
 
 class DataRun(models.Model):