rename pipeline to pipelines to imply that we can process more than just illumina.
[htsworkflow.git] / htsworkflow / pipelines / retrieve_config.py
1 #!/usr/bin/env python
2
3 from optparse import OptionParser, IndentedHelpFormatter
4 from ConfigParser import SafeConfigParser
5
6 import logging
7 import os
8 import sys
9 import urllib2
10
11 CONFIG_SYSTEM = '/etc/hts_frontend/hts_frontend.conf'
12 CONFIG_USER = os.path.expanduser('~/.hts_frontend.conf')
13
14 #Disable or enable commandline arg parsing; disabled by default.
15 DISABLE_CMDLINE = True
16
17 class FlowCellNotFound(Exception): pass
18 class WebError404(Exception): pass
19
20 class DummyOptions:
21   """
22   Used when command line parsing is disabled; default
23   """
24   def __init__(self):
25     self.url = None
26     self.output_filepath = None
27     self.flowcell = None
28     self.genome_dir = None
29
30 class PreformattedDescriptionFormatter(IndentedHelpFormatter):
31   
32   #def format_description(self, description):
33   #  
34   #  if description:
35   #      return description + "\n"
36   #  else:
37   #     return ""
38       
39   def format_epilog(self, epilog):
40     """
41     It was removing my preformated epilog, so this should override
42     that behavior! Muhahaha!
43     """
44     if epilog:
45         return "\n" + epilog + "\n"
46     else:
47         return ""
48
49
50 def constructOptionParser():
51   """
52   returns a pre-setup optparser
53   """
54   global DISABLE_CMDLINE
55   
56   if DISABLE_CMDLINE:
57     return None
58   
59   parser = OptionParser(formatter=PreformattedDescriptionFormatter())
60
61   parser.set_description('Retrieves eland config file from hts_frontend web frontend.')
62   
63   parser.epilog = """
64 Config File:
65   * %s (System wide)
66   * %s (User specific; overrides system)
67   * command line overrides all config file options
68   
69   Example Config File:
70   
71     [config_file_server]
72     base_host_url=http://somewhere.domain:port
73 """ % (CONFIG_SYSTEM, CONFIG_USER)
74   
75   #Special formatter for allowing preformatted description.
76   ##parser.format_epilog(PreformattedDescriptionFormatter())
77
78   parser.add_option("-u", "--url",
79                     action="store", type="string", dest="url")
80   
81   parser.add_option("-o", "--output",
82                     action="store", type="string", dest="output_filepath")
83   
84   parser.add_option("-f", "--flowcell",
85                     action="store", type="string", dest="flowcell")
86
87   parser.add_option("-g", "--genome_dir",
88                     action="store", type="string", dest="genome_dir")
89   
90   #parser.set_default("url", "default")
91   
92   return parser
93
94 def constructConfigParser():
95   """
96   returns a pre-setup config parser
97   """
98   parser = SafeConfigParser()
99   parser.read([CONFIG_SYSTEM, CONFIG_USER])
100   if not parser.has_section('config_file_server'):
101     parser.add_section('config_file_server')
102   if not parser.has_section('local_setup'):
103     parser.add_section('local_setup')
104   
105   return parser
106
107
108 def getCombinedOptions():
109   """
110   Returns optparse options after it has be updated with ConfigParser
111   config files and merged with parsed commandline options.
112   """
113   cl_parser = constructOptionParser()
114   conf_parser = constructConfigParser()
115   
116   if cl_parser is None:
117     options = DummyOptions()
118   else:
119     options, args = cl_parser.parse_args()
120   
121   if options.url is None:
122     if conf_parser.has_option('config_file_server', 'base_host_url'):
123       options.url = conf_parser.get('config_file_server', 'base_host_url')
124
125   if options.genome_dir is None:
126     if conf_parser.has_option('local_setup', 'genome_dir'):
127       options.genome_dir = conf_parser.get('local_setup', 'genome_dir')
128   
129   print 'USING OPTIONS:'
130   print ' URL:', options.url
131   print ' OUT:', options.output_filepath
132   print '  FC:', options.flowcell
133   print 'GDIR:', options.genome_dir
134   print ''
135   
136   return options
137
138
139 def saveConfigFile(flowcell, base_host_url, output_filepath):
140   """
141   retrieves the flowcell eland config file, give the base_host_url
142   (i.e. http://sub.domain.edu:port)
143   """
144   url = base_host_url + '/eland_config/%s/' % (flowcell)
145   
146   f = open(output_filepath, 'w')
147   #try:
148   try:
149     web = urllib2.urlopen(url)
150   except urllib2.URLError, e:
151     errmsg = 'URLError: %d' % (e.code,)
152     logging.error(errmsg)
153     logging.error('opened %s' % (url,))
154     logging.error('%s' % ( e.read(),))
155     raise IOError(errmsg)
156
157   #except IOError, msg:
158   #  if str(msg).find("Connection refused") >= 0:
159   #    print 'Error: Connection refused for: %s' % (url)
160   #    f.close()
161   #    sys.exit(1)
162   #  elif str(msg).find("Name or service not known") >= 0:
163   #    print 'Error: Invalid domain or ip address for: %s' % (url)
164   #    f.close()
165   #    sys.exit(2)
166   #  else:
167   #    raise IOError, msg
168
169   data = web.read()
170
171   if data.find('Hmm, config file for') >= 0:
172     msg = "Flowcell (%s) not found in DB; full url(%s)" % (flowcell, url)
173     raise FlowCellNotFound, msg
174
175   if data.find('404 - Not Found') >= 0:
176     msg = "404 - Not Found: Flowcell (%s); base_host_url (%s);\n full url(%s)\n " \
177           "Did you get right port #?" % (flowcell, base_host_url, url)
178     raise FlowCellNotFound, msg
179   
180   f.write(data)
181   web.close()
182   f.close()
183   logging.info('Wrote config file to %s' % (output_filepath,))
184
185