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