From 24b9a01001fc232baea6ad152446f0c9b6ddd2d8 Mon Sep 17 00:00:00 2001 From: Brandon King Date: Wed, 10 Jun 2009 17:44:47 +0000 Subject: [PATCH] Track which flowcells are archived on which long term storage devices * 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 | 5 ++ htsworkflow/frontend/inventory/views.py | 88 ++++++++++++++++++++++- htsworkflow/frontend/urls.py | 1 + scripts/mark_archived_data | 96 +++++++++++++++++++++++++ 4 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 htsworkflow/frontend/inventory/urls.py create mode 100755 scripts/mark_archived_data diff --git a/htsworkflow/frontend/inventory/urls.py b/htsworkflow/frontend/inventory/urls.py new file mode 100644 index 0000000..844208e --- /dev/null +++ b/htsworkflow/frontend/inventory/urls.py @@ -0,0 +1,5 @@ +from django.conf.urls.defaults import * + +urlpatterns = patterns('', + (r'^lts/link/(?P.+)/(?P.+)/$', 'htsworkflow.frontend.inventory.views.link_flowcell_and_device'), + ) diff --git a/htsworkflow/frontend/inventory/views.py b/htsworkflow/frontend/inventory/views.py index 60f00ef..aa10696 100644 --- a/htsworkflow/frontend/inventory/views.py +++ b/htsworkflow/frontend/inventory/views.py @@ -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 diff --git a/htsworkflow/frontend/urls.py b/htsworkflow/frontend/urls.py index 0e5ca52..8a558d1 100644 --- a/htsworkflow/frontend/urls.py +++ b/htsworkflow/frontend/urls.py @@ -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 index 0000000..e760318 --- /dev/null +++ b/scripts/mark_archived_data @@ -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 -d OR\n\t %prog -f -s ") + 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 -- 2.30.2