def _check_config(self): if not self.config_path.exists(): logger.info("No config file found so creating empty config file.") template_path = self.root_path.joinpath( "datalight/config_template.txt") with open(template_path) as input_file: config_text = input_file.read() with open(self.config_path, 'w') as output_file: output_file.write(config_text)
def read_schema_from_file() -> dict: """Method to read the schema. Reads schema from self.schema_path Stores schema dictionary in self.schema""" logger.info(f'Reading schema from: {SCHEMA_FILE}') try: with open(SCHEMA_FILE) as input_file: return json.load(input_file) except FileNotFoundError: raise ZenodoMetadataException(f'Schema file: {SCHEMA_FILE} not found.')
def load_yaml(metadata_path: str) -> dict: """Method to read metadata from a file. :param metadata_path: A path to a file which contains zenodo metadata (yaml format). """ logger.info(f'Metadata read from file: {metadata_path}') try: with open(metadata_path) as input_file: return yaml.load(input_file, Loader=yaml.FullLoader) except FileNotFoundError: raise FileNotFoundError(f'Metadata file {metadata_path} not found.')
def _get_local_open_licenses(): """Get open license definitions from a local file. :returns open_licenses: (dict) details of open licenses. """ license_path = SCHEMAS_DIR / pathlib.Path( 'zenodo/opendefinition-licenses.json') try: with open(license_path) as input_file: open_licenses = json.load(input_file) logger.info(f'Using file: {license_path} to validate license') return open_licenses except FileNotFoundError: error = f"Could not get open license definitions from local file {license_path}." logger.error(error) raise ZenodoMetadataException(error)
def _get_internet_open_licenses(): """Download the definition file for open source licenses accepted by Zenodo. :returns licenses: (dict) Information about the different license types. if licenses cannot be accessed, returns none. """ url = 'https://licenses.opendefinition.org/licenses/groups/all.json' try: with urllib.request.urlopen(url) as input_file: licenses = json.load(input_file) logger.info(f'open licenses file use for validation: {url}') return licenses except urllib.error.URLError: logger.warning( f'Not possible to access open license list from: {url}') return None
def delete_record(deposition_url: str, deposition_id: int, token: str) -> UploadStatus: """Method to delete an unpublished deposition. If id not provided, use deposition_id, else use provided id :param deposition_url: URL to make the Zenodo API request. :param deposition_id: Deposition id of the record to delete. Record can only be deleted if it was not published. :param token: API token for connecting to Zenodo. """ # Create the request url request_url = f'{deposition_url}/{deposition_id}' logger.info('Delete url: {}'.format(request_url)) request = requests.delete(request_url, params={'access_token': token}) return _check_request_response(request)
def _upload_metadata(deposition_url: str, deposition_id: int, token: str, metadata: dict) -> UploadStatus: """Upload metadata to Zenodo repository. After creating the request and uploading the file(s) we need to update the metadata needed by Zenodo related to the record. """ # Create the url to upload with the deposition_id url = f'{deposition_url}/{deposition_id}' logger.info(f'url: {url}') headers = {"Content-Type": "application/json"} request = requests.put(url, params={'access_token': token}, data=json.dumps(metadata), headers=headers) return _check_request_response(request)
def _upload_files(upload_url: int, token: str, filepaths: List[str]) -> UploadStatus: """Method to upload a file to Zenodo :param filepaths: Paths of one or more files to upload. """ for filepath in filepaths: filepath = pathlib.Path(filepath) logger.info(f'Uploading file "{filepath.name}" from {filepath.parent}') url = f'{upload_url}/{filepath.name}' # Open the file to upload in binary mode and upload it. with open(filepath, 'rb') as input_file: request = requests.put(url, data=input_file, params={'access_token': token}) status = _check_request_response(request) if status.code not in STATUS_SUCCESS: return status return UploadStatus(200, "All files uploaded successfully.")
def validate_metadata(metadata: dict, schema: dict) -> dict: """Method which verifies that the metadata have the correct type and that dependencies are respected.""" # Validate metadata before license to be sure that the "license" and "access_right" # keys are present. try: jsonschema.validate(metadata, schema) except jsonschema.exceptions.ValidationError as err: raise ZenodoMetadataException(f'ValidationError: {err.message}') # Check validity of the license (if open or embargoed) license_checker = _LicenseStatus(metadata["license"], metadata["access_right"]) license_checker.validate_license() if license_checker.license_valid is False: logger.error( "Invalid licence type. access_right is 'open' or 'embargoed' and {}" "is not a valid Open License.".format(license_checker.license)) raise ZenodoMetadataException logger.info('Metadata have been validated successfully.') metadata = remove_extra_properties(metadata) return metadata
def validate_license(self): """Method to verify the status of the metadata license.""" if not (self.access_right in ['open', 'embargoed']): logger.info('No need to check license for Zenodo upload.') self.license_valid = True else: metadata_license = self.license.upper() logger.info(f'Specified license type is: {self.license}') logger.info(f'access_right: "{self.access_right}"') for lic in self.open_licenses.keys(): if lic.startswith(metadata_license): logger.info(f'license: "{lic}" validated.') self.license_valid = True break