scc_access/scc_access.py

changeset 38
1b6786e9865d
parent 36
b51ba2647b41
child 40
8acea12976c4
equal deleted inserted replaced
37:3d46ac5cba31 38:1b6786e9865d
64 self.delete_measurement_pattern = urlparse.urljoin(self.base_url, 'admin/database/measurements/{0}/delete/') 64 self.delete_measurement_pattern = urlparse.urljoin(self.base_url, 'admin/database/measurements/{0}/delete/')
65 65
66 self.api_base_url = urlparse.urljoin(self.base_url, 'api/v1/') 66 self.api_base_url = urlparse.urljoin(self.base_url, 'api/v1/')
67 self.api_measurement_pattern = urlparse.urljoin(self.api_base_url, 'measurements/{0}/') 67 self.api_measurement_pattern = urlparse.urljoin(self.api_base_url, 'measurements/{0}/')
68 self.api_measurements_url = urlparse.urljoin(self.api_base_url, 'measurements') 68 self.api_measurements_url = urlparse.urljoin(self.api_base_url, 'measurements')
69 self.api_sounding_search_pattern = urlparse.urljoin(self.api_base_url, 'sounding_files/?filename={0}')
70 self.api_lidarratio_search_pattern = urlparse.urljoin(self.api_base_url, 'lidarratio_files/?filename={0}')
71 self.api_overlap_search_pattern = urlparse.urljoin(self.api_base_url, 'overlap_files/?filename={0}')
69 72
70 def login(self, credentials): 73 def login(self, credentials):
71 """ Login to SCC. """ 74 """ Login to SCC. """
72 logger.debug("Attempting to login to SCC, username %s." % credentials[0]) 75 logger.debug("Attempting to login to SCC, username %s." % credentials[0])
73 login_credentials = {'username': credentials[0], 76 login_credentials = {'username': credentials[0],
102 # Submit the data 105 # Submit the data
103 upload_data = {'system': system_id} 106 upload_data = {'system': system_id}
104 files = {'data': open(filename, 'rb')} 107 files = {'data': open(filename, 'rb')}
105 108
106 if rs_filename is not None: 109 if rs_filename is not None:
107 logger.debug('Adding sounding file %s' % rs_filename) 110 ancillary_file, _ = self.get_ancillary(rs_filename, 'sounding')
108 files['sounding_file'] = open(rs_filename, 'rb') 111
112 if ancillary_file.already_on_scc:
113 logger.warning("Sounding file {0.filename} already on the SCC with id {0.id}. Ignoring it.".format(ancillary_file))
114 else:
115 logger.debug('Adding sounding file %s' % rs_filename)
116 files['sounding_file'] = open(rs_filename, 'rb')
109 117
110 if ov_filename is not None: 118 if ov_filename is not None:
111 logger.debug('Adding overlap file %s' % ov_filename) 119 ancillary_file, _ = self.get_ancillary(ov_filename, 'overlap')
112 files['overlap_file'] = open(ov_filename, 'rb') 120
121 if ancillary_file.already_on_scc:
122 logger.warning("Overlap file {0.filename} already on the SCC with id {0.id}. Ignoring it.".format(ancillary_file))
123 else:
124 logger.debug('Adding overlap file %s' % ov_filename)
125 files['overlap_file'] = open(ov_filename, 'rb')
113 126
114 if lr_filename is not None: 127 if lr_filename is not None:
115 logger.debug('Adding lidar ratio file %s' % lr_filename) 128 ancillary_file, _ = self.get_ancillary(lr_filename, 'lidarratio')
116 files['lidar_ratio_file'] = open(lr_filename, 'rb') 129
130 if ancillary_file.already_on_scc:
131 logger.warning(
132 "Lidar ratio file {0.filename} already on the SCC with id {0.id}. Ignoring it.".format(ancillary_file))
133 else:
134 logger.debug('Adding lidar ratio file %s' % lr_filename)
135 files['lidar_ratio_file'] = open(lr_filename, 'rb')
117 136
118 logger.info("Uploading of file(s) %s started." % filename) 137 logger.info("Uploading of file(s) %s started." % filename)
119 138
120 upload_submit = self.session.post(self.upload_url, 139 upload_submit = self.session.post(self.upload_url,
121 data=upload_data, 140 data=upload_data,
451 measurement_number = measurement_number + 1 470 measurement_number = measurement_number + 1
452 measurement_id = "%s%02i" % (base_id, measurement_number) 471 measurement_id = "%s%02i" % (base_id, measurement_number)
453 472
454 return measurement_id 473 return measurement_id
455 474
475 def get_ancillary(self, filename, file_type):
476 """
477 Try to get the ancillary file data from the SCC API.
478
479 The result will always be an API object. If the file does not exist, the .exists property is set to False.
480
481 Parameters
482 ----------
483 filename : str
484 Filename of the uploaded file.
485 file_type : str
486 Type of ancillary file. One of 'sounding', 'overlap', 'lidarratio'.
487
488 Returns
489 : AncillaryFile
490 The api object.
491 """
492 assert file_type in ['sounding', 'overlap', 'lidarratio']
493
494 if file_type == 'sounding':
495 file_url = self.api_sounding_search_pattern.format(filename)
496 elif file_type == 'overlap':
497 file_url = self.api_overlap_search_pattern.format(filename)
498 else:
499 file_url = self.api_lidarratio_search_pattern.format(filename)
500
501 response = self.session.get(file_url)
502
503 if not response.ok:
504 logger.error('Could not access API. Status code %s.' % response.status_code)
505 return None, response.status_code
506
507 response_dict = response.json()
508 object_list = response_dict['objects']
509
510 logger.debug("Ancillary file JSON: {0}".format(object_list))
511
512 if object_list:
513 ancillary_file = AncillaryFile(self.api_base_url, object_list[0]) # Assume only one file is returned
514 else:
515 ancillary_file = AncillaryFile(self.api_base_url, None) # Create an empty object
516
517 return ancillary_file, response.status_code
518
456 class PageNotAccessibleError(RuntimeError): 519 class PageNotAccessibleError(RuntimeError):
457 pass 520 pass
458 521
459 522
460 class ApiObject(object): 523 class ApiObject(object):
493 def __str__(self): 556 def __str__(self):
494 return "%s: %s, %s, %s" % (self.id, 557 return "%s: %s, %s, %s" % (self.id,
495 self.upload, 558 self.upload,
496 self.pre_processing, 559 self.pre_processing,
497 self.processing) 560 self.processing)
561
562
563 class AncillaryFile(ApiObject):
564 """ This class represents the ancilalry file object as returned in the SCC API.
565 """
566 @property
567 def already_on_scc(self):
568 if self.exists is False:
569 return False
570
571 return not self.status == 'missing'
572
573 def __str__(self):
574 return "%s: %s, %s" % (self.id,
575 self.filename,
576 self.status)
498 577
499 578
500 def process_file(filename, system_id, settings, monitor=True, rs_filename=None, lr_filename=None, ov_filename=None): 579 def process_file(filename, system_id, settings, monitor=True, rs_filename=None, lr_filename=None, ov_filename=None):
501 """ Shortcut function to process a file to the SCC. """ 580 """ Shortcut function to process a file to the SCC. """
502 logger.info("Processing file %s, using system %s" % (filename, system_id)) 581 logger.info("Processing file %s, using system %s" % (filename, system_id))

mercurial