Thu, 19 Dec 2019 18:02:57 +0200
Checking if ancillary files are already on the DB before starting upload.
scc_access/__init__.py | file | annotate | diff | comparison | revisions | |
scc_access/scc_access.py | file | annotate | diff | comparison | revisions |
--- a/scc_access/__init__.py Thu Dec 05 18:27:28 2019 +0200 +++ b/scc_access/__init__.py Thu Dec 19 18:02:57 2019 +0200 @@ -1,1 +1,1 @@ -__version__ = "0.7.1" \ No newline at end of file +__version__ = "0.8.0" \ No newline at end of file
--- a/scc_access/scc_access.py Thu Dec 05 18:27:28 2019 +0200 +++ b/scc_access/scc_access.py Thu Dec 19 18:02:57 2019 +0200 @@ -66,6 +66,9 @@ self.api_base_url = urlparse.urljoin(self.base_url, 'api/v1/') self.api_measurement_pattern = urlparse.urljoin(self.api_base_url, 'measurements/{0}/') self.api_measurements_url = urlparse.urljoin(self.api_base_url, 'measurements') + self.api_sounding_search_pattern = urlparse.urljoin(self.api_base_url, 'sounding_files/?filename={0}') + self.api_lidarratio_search_pattern = urlparse.urljoin(self.api_base_url, 'lidarratio_files/?filename={0}') + self.api_overlap_search_pattern = urlparse.urljoin(self.api_base_url, 'overlap_files/?filename={0}') def login(self, credentials): """ Login to SCC. """ @@ -104,16 +107,32 @@ files = {'data': open(filename, 'rb')} if rs_filename is not None: - logger.debug('Adding sounding file %s' % rs_filename) - files['sounding_file'] = open(rs_filename, 'rb') + ancillary_file, _ = self.get_ancillary(rs_filename, 'sounding') + + if ancillary_file.already_on_scc: + logger.warning("Sounding file {0.filename} already on the SCC with id {0.id}. Ignoring it.".format(ancillary_file)) + else: + logger.debug('Adding sounding file %s' % rs_filename) + files['sounding_file'] = open(rs_filename, 'rb') if ov_filename is not None: - logger.debug('Adding overlap file %s' % ov_filename) - files['overlap_file'] = open(ov_filename, 'rb') + ancillary_file, _ = self.get_ancillary(ov_filename, 'overlap') + + if ancillary_file.already_on_scc: + logger.warning("Overlap file {0.filename} already on the SCC with id {0.id}. Ignoring it.".format(ancillary_file)) + else: + logger.debug('Adding overlap file %s' % ov_filename) + files['overlap_file'] = open(ov_filename, 'rb') if lr_filename is not None: - logger.debug('Adding lidar ratio file %s' % lr_filename) - files['lidar_ratio_file'] = open(lr_filename, 'rb') + ancillary_file, _ = self.get_ancillary(lr_filename, 'lidarratio') + + if ancillary_file.already_on_scc: + logger.warning( + "Lidar ratio file {0.filename} already on the SCC with id {0.id}. Ignoring it.".format(ancillary_file)) + else: + logger.debug('Adding lidar ratio file %s' % lr_filename) + files['lidar_ratio_file'] = open(lr_filename, 'rb') logger.info("Uploading of file(s) %s started." % filename) @@ -453,6 +472,50 @@ return measurement_id + def get_ancillary(self, filename, file_type): + """ + Try to get the ancillary file data from the SCC API. + + The result will always be an API object. If the file does not exist, the .exists property is set to False. + + Parameters + ---------- + filename : str + Filename of the uploaded file. + file_type : str + Type of ancillary file. One of 'sounding', 'overlap', 'lidarratio'. + + Returns + : AncillaryFile + The api object. + """ + assert file_type in ['sounding', 'overlap', 'lidarratio'] + + if file_type == 'sounding': + file_url = self.api_sounding_search_pattern.format(filename) + elif file_type == 'overlap': + file_url = self.api_overlap_search_pattern.format(filename) + else: + file_url = self.api_lidarratio_search_pattern.format(filename) + + response = self.session.get(file_url) + + if not response.ok: + logger.error('Could not access API. Status code %s.' % response.status_code) + return None, response.status_code + + response_dict = response.json() + object_list = response_dict['objects'] + + logger.debug("Ancillary file JSON: {0}".format(object_list)) + + if object_list: + ancillary_file = AncillaryFile(self.api_base_url, object_list[0]) # Assume only one file is returned + else: + ancillary_file = AncillaryFile(self.api_base_url, None) # Create an empty object + + return ancillary_file, response.status_code + class PageNotAccessibleError(RuntimeError): pass @@ -497,6 +560,22 @@ self.processing) +class AncillaryFile(ApiObject): + """ This class represents the ancilalry file object as returned in the SCC API. + """ + @property + def already_on_scc(self): + if self.exists is False: + return False + + return not self.status == 'missing' + + def __str__(self): + return "%s: %s, %s" % (self.id, + self.filename, + self.status) + + def process_file(filename, system_id, settings, monitor=True, rs_filename=None, lr_filename=None, ov_filename=None): """ Shortcut function to process a file to the SCC. """ logger.info("Processing file %s, using system %s" % (filename, system_id))