from io import StringIO
import csv

from django.db.models import Q

from Bio import SeqIO

from lims.inventory.models import Item


class DesignFileParser:

    GENBANK_FEATURE_TYPES = (
        'primer_bind',
        'cds',
        '5\'_utr',
        'promoter',
        '3\'_utr',
        'terminator',
        'unknown',
        'structual',  # Support EGF imports
    )

    def __init__(self, data):
        self.file_data = StringIO(initial_value=data)

    def get_inventory_item(self, name):
        """
        Get an item matching the name/identifier from the inventory
        """
        try:
            item = Item.objects.get(Q(name=name) | Q(identifier=name))
            return item
        except Item.DoesNotExist:
            return False

    def parse_gb(self):
        record = SeqIO.read(self.file_data, 'genbank')
        items = []
        for feat in record.features:
            # The file sometimes has lowercase and sometimes uppercase
            # types so normalise to lowercase.
            if feat.type.lower() in self.GENBANK_FEATURE_TYPES:
                name = ''
                # Look for the label key. Other keys can be set but
                # most software simply sets the label key and nothing
                # else.
                for key, value in feat.qualifiers.items():
                    if key == 'label':
                        name = value[0]
                if name:
                    item = self.get_inventory_item(name)
                    if item:
                        items.append(item)
        return items

    def parse_csv(self):
        reader = csv.DictReader(self.file_data)
        items = []
        for line in reader:
            # Using the EGF style CSV file with the following
            # headers:
            # Name, Description, Role, Color, Sequence, @metadata
            # Ignoring all but the name fields for now as we don't
            # need the others.
            if 'Name' in line and line['Name'] != '':
                item = self.get_inventory_item(line['Name'])
                if item:
                    items.append(item)
        return items

@@ -769,32 +769,68 @@
 parse_gb(self):%0A
+        items = %5B%5D%0A        try:%0A    
         record =
@@ -868,39 +868,24 @@
 nbank')%0A    
-    items = %5B%5D%0A
         for 
@@ -921,16 +921,20 @@
         
+  
+  
 # The fi
@@ -996,16 +996,20 @@
         
+    
 # types 
@@ -1047,16 +1047,20 @@
         
+   
+ 
 if feat.
@@ -1115,24 +1115,28 @@
             
+    
 name = ''%0A  
@@ -1149,16 +1149,20 @@
         
+   
+ 
 # Look f
@@ -1205,16 +1205,20 @@
 set but%0A
+    
         
@@ -1275,24 +1275,28 @@
 and nothing%0A
+    
             
@@ -1319,24 +1319,28 @@
             
+    
 for key, val
@@ -1390,16 +1390,20 @@
         
+    
 if key =
@@ -1433,24 +1433,28 @@
             
+ 
+   
 name = value
@@ -1473,16 +1473,20 @@
         
+    
 if name:
@@ -1486,16 +1486,20 @@
 f name:%0A
+    
         
@@ -1559,32 +1559,36 @@
                 
+    
 if item:%0A       
@@ -1596,32 +1596,36 @@
                 
+  
+  
 items.append(ite
@@ -1619,32 +1619,65 @@
 ms.append(item)%0A
+        except:%0A            pass%0A
         return i

Fix issue with genbank unable to be interpreted