Track which flowcells are archived on which long term storage devices
authorBrandon King <kingb@caltech.edu>
Wed, 10 Jun 2009 17:44:47 +0000 (17:44 +0000)
committerBrandon King <kingb@caltech.edu>
Wed, 10 Jun 2009 17:44:47 +0000 (17:44 +0000)
 * Added a command_line script called mark_archived_data
   * Storage Device must be in DB as well as flowcell before using
   * If you supply a device (i.e. /dev/sda), it will extract the serial number of the drive for you.
   * Uses HTTP REST request to link Flowcell, Libraries and Storage Devices.
   * Supports archives across storage devices.
   * device query requires py_sg python package (easy_install py_sg)

htsworkflow/frontend/inventory/urls.py [new file with mode: 0644]
htsworkflow/frontend/inventory/views.py
htsworkflow/frontend/urls.py
scripts/mark_archived_data [new file with mode: 0755]

diff --git a/htsworkflow/frontend/inventory/urls.py b/htsworkflow/frontend/inventory/urls.py
new file mode 100644 (file)
index 0000000..844208e
--- /dev/null
@@ -0,0 +1,5 @@
+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('',
+     (r'^lts/link/(?P<flowcell>.+)/(?P<serial>.+)/$', 'htsworkflow.frontend.inventory.views.link_flowcell_and_device'),                                                                                                 
+    )
index 60f00ef0ef347811e7b0c0921b7fda097acd9fcc..aa106961c7580ec69690d24ebf7952fad2ef32d4 100644 (file)
@@ -1 +1,87 @@
-# Create your views here.
+from htsworkflow.frontend.inventory.models import Item, LongTermStorage
+from htsworkflow.frontend.experiments.models import FlowCell
+
+from django.core.exceptions import ObjectDoesNotExist
+from django.http import HttpResponse
+
+
+def link_flowcell_and_device(request, flowcell, serial):
+    """
+    Updates database records of a flowcell being archived on a device with a particular serial #
+    """
+    assert flowcell is not None
+    assert serial is not None
+        
+    ###########################################
+    # Retrieve Storage Device
+    try:
+        sd = Item.objects.get(barcode_id=serial)
+    except ObjectDoesNotExist, e:
+        msg = "Item with barcode_id of %s not found." % (serial)
+        raise ObjectDoesNotExist(msg)
+    
+    ###########################################
+    # Retrieve FlowCell
+    try:    
+        fc = FlowCell.objects.get(flowcell_id=flowcell)
+    except ObjectDoesNotExist, e:
+        msg = "FlowCell with flowcell_id of %s not found." % (flowcell)
+        raise ObjectDoesNotExist(msg)
+    
+    ###########################################
+    # Retrieve or create LongTermStorage Object
+    count = fc.longtermstorage_set.count()
+    lts = None
+    if count > 1:
+        msg = "There really should only be one longtermstorage object per flowcell"
+        raise ValueError, msg
+    elif count == 1:
+        # lts already attached to flowcell
+        lts = fc.longtermstorage_set.all()[0]
+    else:
+        lts = LongTermStorage()
+        # Attach flowcell
+        lts.flowcell = fc
+        # Need a primary keey before linking to storage devices
+        lts.save()
+        
+        
+    ############################################
+    # Link Storage to Flowcell
+    
+    # Add a link to this storage device if it is not already linked.
+    if sd not in lts.storage_devices.values():
+        lts.storage_devices.add(sd)
+    
+    ###########################################
+    # Add Library Links to LTS
+    
+    if fc.lane_1_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_1_library)
+    
+    if fc.lane_2_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_2_library)
+    
+    if fc.lane_3_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_3_library)
+    
+    if fc.lane_4_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_4_library)
+    
+    
+    if fc.lane_5_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_5_library)
+    
+    if fc.lane_6_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_6_library)
+    
+    if fc.lane_7_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_7_library)
+    
+    if fc.lane_8_library not in lts.storage_devices.values():
+        lts.libraries.add(fc.lane_8_library)
+        
+    # Save Changes
+    lts.save()
+    
+    return HttpResponse("Success")
\ No newline at end of file
index 0e5ca52979694bf24f1f2b3fd4e4e7bfaaa8f8f0..8a558d182e066107c71040fc1ddbb5c2a9332a54 100644 (file)
@@ -20,6 +20,7 @@ urlpatterns = patterns('',
     # AnalysTrack:
     #(r'^analysis/', include('htsworkflow.frontend.analysis.urls')),
     # Report Views:
+    (r'^inventory/', include('htsworkflow.frontend.inventory.urls')),
     (r'^reports/', include('htsworkflow.frontend.reports.urls')),
     # Library browser
     (r'^library/$', 'htsworkflow.frontend.samples.views.library'),
diff --git a/scripts/mark_archived_data b/scripts/mark_archived_data
new file mode 100755 (executable)
index 0000000..e760318
--- /dev/null
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+
+#import os
+#os.environ['DJANGO_SETTINGS_MODULE'] = 'htsworkflow.frontend.settings'
+
+from htsworkflow.util.hdquery import get_hd_serial_num
+
+#from django.conf import settings
+from optparse import OptionParser
+
+import sys
+import urllib
+
+#FIXME: Remove hard coded URL
+HTSW_URL = "http://localhost:8000/inventory/lts/link/"
+
+def construct_parser():
+    """
+    """
+    parser = OptionParser("usage: %prog -f <flowcell> -d </dev/sdX> OR\n\t %prog -f <flowcell> -s <dev_serial_num>")
+    parser.add_option("-f", "--flowcell", action="store", type="string", dest="flowcell",
+                      help="flowcell being archived")
+    parser.add_option("-d", "--device", action="store", type="string", dest="device",
+                      help="device flowcell is being archived to")
+    parser.add_option("-s", "--serial", action="store", type="string", dest="serial",
+                      help="serial num. of archive device")
+    
+    return parser
+
+
+def update_db(flowcell, serial):
+    """
+    Creates link between flowcell and storage device over http
+    """
+    www = urllib.urlopen(HTSW_URL+'%s/%s/' % (flowcell, serial))
+    httpcode = www.getcode()
+    if httpcode != 200:
+        print 'ERROR - HTTP OUTPUT:'
+        print www.read()
+        sys.exit(httpcode)
+    
+    print "DB Update of %s & %s succeeded" % (flowcell, serial)
+
+
+def process_args(parser):
+    """
+    returns flowcell and serial#
+    """
+    options, args = parser.parse_args()
+    
+    msg = []
+    
+    # Only provide device or serial
+    if options.device is not None and options.serial is not None:
+        print "ERROR: Please only provide --device or --serial.\n" \
+              "  The serial number is extracted automatically if the device is provided."
+        sys.exit(2)
+    
+    print options.flowcell
+    print options.device
+    print options.serial
+    
+    if options.flowcell is None:
+        msg.append("  --flowcell required")
+    
+    # if device and serial missing:
+    if options.device is None and options.serial is None:
+        msg.append("  --device OR --serial required")
+    
+    if len(msg) > 0:
+        print '\n'.join(msg)
+        sys.exit(3)
+    
+    # Update db records
+    if options.device is not None:
+        serial = get_hd_serial_num(options.device)
+        update_db(flowcell=options.flowcell, serial=serial)
+    elif options.serial is not None:
+        update_db(flowcell=options.flowcell, serial=options.serial)
+    else:
+        msg ="FATAL should not happen error occured; i.e. the best kind!"
+        raise ValueError, msg
+    
+    
+
+def main():
+    """
+    """
+    parser = construct_parser()
+    process_args(parser)
+    
+    #print "Database Updated."
+    sys.exit(0)
+
+if __name__ == '__main__':
+    main()
\ No newline at end of file