@@ -99,21 +99,39 @@ def _activate_form(self, response, form_index=0, inputs={}, cache=True,
9999 elif tag_name == 'select' :
100100 if form_elem .get ('multiple' ) is not None :
101101 value = []
102- for option in form_elem .select ('option[value]' ):
103- if option .get ('selected' ) is not None :
104- value .append (option .get ('value' ))
102+ if form_elem .select ('option[value]' ):
103+ for option in form_elem .select ('option[value]' ):
104+ if option .get ('selected' ) is not None :
105+ value .append (option .get ('value' ))
106+ else :
107+ for option in form_elem .select ('option' ):
108+ if option .get ('selected' ) is not None :
109+ value .append (option .string )
105110 else :
106- for option in form_elem .select ('option[value]' ):
107- if option .get ('selected' ) is not None :
108- value = option .get ('value' )
109- # select the first option field if none is selected
110- if value is None :
111- value = form_elem .select (
112- 'option[value]' )[0 ].get ('value' )
111+ if form_elem .select ('option[value]' ):
112+ for option in form_elem .select ('option[value]' ):
113+ if option .get ('selected' ) is not None :
114+ value = option .get ('value' )
115+ # select the first option field if none is selected
116+ if value is None :
117+ value = form_elem .select (
118+ 'option[value]' )[0 ].get ('value' )
119+ else :
120+ # survey form just uses text, not value
121+ for option in form_elem .select ('option' ):
122+ if option .get ('selected' ) is not None :
123+ value = option .string
124+ # select the first option field if none is selected
125+ if value is None :
126+ value = form_elem .select ('option' )[0 ].string
113127
114128 if key in inputs :
115- value = str (inputs [key ])
116- if (key is not None ) and (value is not None ):
129+ if isinstance (inputs [key ], list ):
130+ # list input is accepted (for array uploads)
131+ value = inputs [key ]
132+ else :
133+ value = str (inputs [key ])
134+ if (key is not None ):# and (value is not None):
117135 if fmt == 'multipart/form-data' :
118136 if is_file :
119137 payload .append (
@@ -122,6 +140,8 @@ def _activate_form(self, response, form_index=0, inputs={}, cache=True,
122140 if type (value ) is list :
123141 for v in value :
124142 payload .append ((key , ('' , v )))
143+ elif value is None :
144+ payload .append ((key , ('' , '' )))
125145 else :
126146 payload .append ((key , ('' , value )))
127147 else :
@@ -138,6 +158,8 @@ def _activate_form(self, response, form_index=0, inputs={}, cache=True,
138158 if method is not None :
139159 fmt = method
140160
161+ log .debug ("Method/format = {0}" .format (fmt ))
162+
141163 # Send payload
142164 if fmt == 'get' :
143165 response = self ._request ("GET" , url , params = payload , cache = cache )
@@ -148,16 +170,37 @@ def _activate_form(self, response, form_index=0, inputs={}, cache=True,
148170
149171 return response
150172
151- def _login (self , username = None , store_password = False ):
173+ def _login (self , username = None , store_password = False ,
174+ retype_password = False ):
175+ """
176+ Login to the ESO User Portal.
177+
178+ Parameters
179+ ----------
180+ username : str, optional
181+ Username to the ESO Public Portal. If not given, it should be
182+ specified in the config file.
183+ store_password : bool, optional
184+ Stores the password securely in your keyring. Default is False.
185+ retype_password : bool, optional
186+ Asks for the password even if it is already stored in the
187+ keyring. This is the way to overwrite an already stored passwork
188+ on the keyring. Default is False.
189+ """
152190 if username is None :
153191 if self .USERNAME == "" :
154192 raise LoginError ("If you do not pass a username to login(), "
155193 "you should configure a default one!" )
156194 else :
157195 username = self .USERNAME
196+
158197 # Get password from keyring or prompt
159- password_from_keyring = keyring .get_password ("astroquery:www.eso.org" ,
160- username )
198+ if retype_password is False :
199+ password_from_keyring = keyring .get_password (
200+ "astroquery:www.eso.org" , username )
201+ else :
202+ password_from_keyring = None
203+
161204 if password_from_keyring is None :
162205 if system_tools .in_ipynb ():
163206 log .warn ("You may be using an ipython notebook:"
@@ -207,8 +250,6 @@ def list_instruments(self, cache=True):
207250 if instrument not in self ._instrument_list :
208251 self ._instrument_list .append (instrument )
209252 self ._instrument_list .append (u'harps' )
210- self ._instrument_list .append (u'ambient_paranal' )
211- self ._instrument_list .append (u'meteo_paranal' )
212253 return self ._instrument_list
213254
214255 def list_surveys (self , cache = True ):
@@ -219,30 +260,34 @@ def list_surveys(self, cache=True):
219260 survey_list : list of strings
220261 cache : bool
221262 Cache the response for faster subsequent retrieval
222-
223263 """
224264 if self ._survey_list is None :
225265 survey_list_response = self ._request (
226266 "GET" , "http://archive.eso.org/wdb/wdb/adp/phase3_main/form" ,
227267 cache = cache )
228- root = BeautifulSoup (survey_list_response .content , 'html5lib' )
268+ root = BeautifulSoup (survey_list_response .content , 'html5lib' )
229269 self ._survey_list = []
230- for select in root .select ("select[name=phase3_program]" ):
231- for element in select .select ('option' ):
232- survey = element .text .strip ()
233- if survey not in self ._survey_list and 'Any' not in survey :
270+ collections_table = root .find ('table' , id = 'collections_table' )
271+ other_collections = root .find ('select' , id = 'collection_name_option' )
272+ for element in (collections_table .findAll ('input' , type = 'checkbox' ) +
273+ other_collections .findAll ('option' )):
274+ if 'value' in element .attrs :
275+ survey = element .attrs ['value' ]
276+ if survey and survey not in self ._survey_list and 'Any' not in survey :
234277 self ._survey_list .append (survey )
235278 return self ._survey_list
236279
237- def query_survey (self , survey , cache = True , ** kwargs ):
280+ def query_surveys (self , surveys = '' , cache = True ,
281+ help = False , open_form = False , ** kwargs ):
238282 """
239283 Query survey Phase 3 data contained in the ESO archive.
240284
241285 Parameters
242286 ----------
243- survey : string
244- Name of the survey to query, one of the names returned by
245- `list_surveys()`.
287+ survey : string or list
288+ Name of the survey(s) to query. Should beone or more of the names
289+ returned by `list_surveys()`. If specified as a string, should be
290+ a comma-separated list of survey names.
246291 cache : bool
247292 Cache the response for faster subsequent retrieval
248293
@@ -257,30 +302,37 @@ def query_survey(self, survey, cache=True, **kwargs):
257302
258303 """
259304
260- if survey not in self .list_surveys ():
261- raise ValueError ("Survey %s is not in the survey list." % survey )
262305 url = "http://archive.eso.org/wdb/wdb/adp/phase3_main/form"
263- survey_form = self ._request ("GET" , url , cache = cache )
264- query_dict = kwargs
265- query_dict ["wdbo" ] = "csv/download"
266- query_dict ['phase3_program' ] = survey
267- if self .ROW_LIMIT >= 0 :
268- query_dict ["max_rows_returned" ] = self .ROW_LIMIT
269- else :
270- query_dict ["max_rows_returned" ] = 10000
271- survey_response = self ._activate_form (survey_form , form_index = 0 ,
272- inputs = query_dict , cache = cache )
273-
274- content = survey_response .content
275- # First line is always garbage
276- content = content .split (b'\n ' , 1 )[1 ]
277- log .debug ("Response content:\n {0}" .format (content ))
278- if _check_response (content ):
279- table = Table .read (BytesIO (content ), format = "ascii.csv" ,
280- comment = "^#" )
281- return table
306+ if open_form :
307+ webbrowser .open (url )
308+ elif help :
309+ self ._print_surveys_help (url , cache = cache )
282310 else :
283- warnings .warn ("Query returned no results" , NoResultsWarning )
311+ survey_form = self ._request ("GET" , url , cache = cache )
312+ query_dict = kwargs
313+ query_dict ["wdbo" ] = "csv/download"
314+ if isinstance (surveys , six .string_types ):
315+ surveys = surveys .split ("," )
316+ query_dict ['collection_name' ] = surveys
317+ if self .ROW_LIMIT >= 0 :
318+ query_dict ["max_rows_returned" ] = self .ROW_LIMIT
319+ else :
320+ query_dict ["max_rows_returned" ] = 10000
321+
322+ survey_response = self ._activate_form (survey_form , form_index = 0 ,
323+ inputs = query_dict , cache = cache )
324+
325+ content = survey_response .content
326+ # First line is always garbage
327+ content = content .split (b'\n ' , 1 )[1 ]
328+ log .debug ("Response content:\n {0}" .format (content ))
329+ if _check_response (content ):
330+ table = Table .read (BytesIO (content ), format = "ascii.csv" ,
331+ comment = "^#" )
332+ return table
333+ else :
334+ warnings .warn ("Query returned no results" , NoResultsWarning )
335+
284336
285337 def query_instrument (self , instrument , column_filters = {}, columns = [],
286338 open_form = False , help = False , cache = True , ** kwargs ):
@@ -326,7 +378,7 @@ def query_instrument(self, instrument, column_filters={}, columns=[],
326378 if open_form :
327379 webbrowser .open (url )
328380 elif help :
329- self ._print_help (url , instrument )
381+ self ._print_instrument_help (url , instrument )
330382 else :
331383 instrument_form = self ._request ("GET" , url , cache = cache )
332384 query_dict = {}
@@ -599,7 +651,7 @@ def query_apex_quicklooks(self, project_id=None, help=False,
599651 if open_form :
600652 webbrowser .open (apex_query_url )
601653 elif help :
602- return self ._print_help (apex_query_url , 'apex' )
654+ return self ._print_instrument_help (apex_query_url , 'apex' )
603655 else :
604656
605657 payload = {'wdbo' : 'csv/download' }
@@ -624,7 +676,7 @@ def query_apex_quicklooks(self, project_id=None, help=False,
624676
625677 return table
626678
627- def _print_help (self , url , instrument , cache = True ):
679+ def _print_instrument_help (self , url , instrument , cache = True ):
628680 """
629681 Download a form and print it in a quasi-human-readable way
630682 """
@@ -681,4 +733,86 @@ def _print_help(self, url, instrument, cache=True):
681733 print ("\n " .join (result_string ))
682734 return result_string
683735
736+ def query_survey (self , ** kwargs ):
737+ raise DeprecationWarning ("query_survey is deprecated; use "
738+ "query_surveys instead. It should "
739+ "accept the same arguments." )
740+
741+ def _print_surveys_help (self , url , cache = True ):
742+ """
743+ Download a form and print it in a quasi-human-readable way
744+ """
745+ log .info ("List of the parameters accepted by the "
746+ "surveys query." )
747+ log .info ("The presence of a column in the result table can be "
748+ "controlled if prefixed with a [ ] checkbox." )
749+ log .info ("The default columns in the result table are shown as "
750+ "already ticked: [x]." )
751+
752+ result_string = []
753+
754+ resp = self ._request ("GET" , url , cache = cache )
755+ doc = BeautifulSoup (resp .content , 'html5lib' )
756+ form = doc .select ("html body form" )[0 ]
757+
758+ # hovertext from different labels are used to give more info on forms
759+ helptext_dict = {abbr ['title' ].split (":" )[0 ].strip ():
760+ ":" .join (abbr ['title' ].split (":" )[1 :])
761+ for abbr in form .findAll ('abbr' )
762+ if 'title' in abbr .attrs and ":" in abbr ['title' ]}
763+
764+ for fieldset in form .select ('fieldset' ):
765+ legend = fieldset .select ('legend' )
766+ if len (legend ) > 1 :
767+ raise ValueError ("Form parsing error: too many legends." )
768+ elif len (legend ) == 0 :
769+ continue
770+ section_title = "\n \n " + "" .join (legend [0 ].stripped_strings )+ "\n "
771+
772+ result_string .append (section_title )
773+
774+ for section in fieldset .select ('table' ):
775+
776+ checkbox_name = ""
777+ checkbox_value = ""
778+ for tag in section .next_elements :
779+ if tag .name == u"table" :
780+ break
781+ elif tag .name == u"input" :
782+ if tag .get (u'type' ) == u"checkbox" :
783+ checkbox_name = tag ['name' ]
784+ checkbox_value = (u"[x]"
785+ if ('checked' in tag .attrs )
786+ else u"[ ]" )
787+ name = ""
788+ value = ""
789+ else :
790+ name = tag ['name' ]
791+ value = ""
792+ elif tag .name == u"select" :
793+ options = []
794+ for option in tag .select ("option" ):
795+ options += ["{0} ({1})"
796+ .format (option ['value' ]
797+ if 'value' in option
798+ else "" ,
799+ "" .join (option .stripped_strings ))]
800+ name = tag [u"name" ]
801+ value = ", " .join (options )
802+ else :
803+ name = ""
804+ value = ""
805+ if u"tab_" + name == checkbox_name :
806+ checkbox = checkbox_value
807+ else :
808+ checkbox = " "
809+ if name != u"" :
810+ result_string .append ("{0} {1}: {2}"
811+ .format (checkbox , name , value ))
812+ if name .strip () in helptext_dict :
813+ result_string .append (helptext_dict [name .strip ()])
814+
815+ print ("\n " .join (result_string ))
816+ return result_string
817+
684818Eso = EsoClass ()
0 commit comments