Test htsworkflow under several different django & python versions
[htsworkflow.git] / scripts / htsw-record-runfolder
1 #!/usr/bin/env python
2
3 from optparse import OptionParser
4 import os
5 import re
6 import sys
7 from six.moves import urllib
8
9 from django.conf import settings
10
11 from htsworkflow.util.hdquery import get_hd_serial_num
12
13 runfolder_pattern = re.compile(r'[0-9]{6}_[-A-Za-z\d]+_\d+_(?P<flowcell>[A-Z\d]+)\.tgz')
14
15 def extract_flowcell(runfolder_name):
16     path, basename = os.path.split(runfolder_name)
17     match = runfolder_pattern.match(basename)
18     if match is not None:
19         return match.group('flowcell')
20     else:
21         return None
22
23 def construct_parser():
24     """
25     """
26     msg = "usage: %prog [-d </dev/sdX> | -s <serial_number] [-f <flowcell>] [archived dirs]"
27     parser = OptionParser()
28     parser.add_option('-u', '--url', default=None,
29                       help="Alternate url for marking archived flowcells")
30     parser.add_option("-f", "--flowcell",  type="string", help="flowcell being archived")
31     parser.add_option("-d", "--device", type="string",
32                       help="device flowcell is being archived to")
33     parser.add_option("-s", "--serial", type="string", help="serial num. of archive device")
34     parser.add_option("-v", "--verbose", action="store_true", default=False)
35
36     return parser
37
38
39 def update_db(root_url, flowcells, serial, debug=False):
40     """
41     Creates link between flowcell and storage device over http
42     """
43     for fc in flowcells:
44         url = urllib.parse.urljoin(root_url, '%s/%s/' % (fc, serial))
45
46         req = urllib.request.Request(url)
47         try:
48             response = urllib2.urlopen(req)
49         except urllib.error.HTTPError, e:
50             print 'ERROR - HTTP OUTPUT (Return Code: %s); use -v/--verbose for more details.' % (e.code)
51             if debug:
52                 print e.read()
53             sys.exit(e.code)
54
55         print "DB Update of %s & %s succeeded" % (fc, serial)
56         print response.read()
57
58
59 def process_args(parser):
60     """
61     returns flowcell and serial#
62     """
63     options, args = parser.parse_args()
64
65     msg = []
66
67     # Only provide device or serial
68     if options.device is not None and options.serial is not None:
69         parser.error("Please provide only --device or --serial.\n"\
70                      "The serial number is extracted automatically if the"\
71                      "device is provided.")
72
73     # allow user to override the default destination URL
74     if options.url is not None:
75         root_url = options.url
76     else:
77         root_url = settings.LINK_FLOWCELL_STORAGE_DEVICE_URL
78
79     if root_url is None:
80         parser.error("Please set path to flowcell storage url")
81
82     # if device and serial missing:
83     if options.device is None and options.serial is None:
84         parser.error('One of --device or --serial is required')
85
86     flowcells = []
87
88     # sanitize args
89     for runfolder in args:
90         flowcell_id = extract_flowcell(runfolder)
91         if flowcell_id is None:
92             parser.error('archive names must look like YYMMDD_MACHINE_RUN_FLOWCELLID.tgz\n'\
93                          '(got %s)' % (runfolder,))
94         else:
95             flowcells.append(flowcell_id)
96
97     if options.flowcell is not None:
98         flowcells.append(options.flowcell)
99
100     if len(flowcells) == 0:
101         parser.error('please specify a  --flowcell or list of runfolder archives\n'\
102                      'for archival. I need something to do.')
103
104     # Update db records
105     if options.device is not None:
106         serial = get_hd_serial_num(options.device)
107         update_db(root_url, flowcells, serial=serial, debug=options.verbose)
108     elif options.serial is not None:
109         update_db(root_url, flowcells, serial=options.serial, debug=options.verbose)
110     else:
111         msg ="FATAL should not happen error occured; i.e. the best kind!"
112         raise ValueError, msg
113
114
115
116 def main():
117     """
118     """
119     parser = construct_parser()
120     process_args(parser)
121
122     #print "Database Updated."
123     sys.exit(0)
124
125 if __name__ == '__main__':
126     main()