upload_new_version_deposit.py 5.55 KB
Newer Older
1 2 3 4 5
#!/usr/bin/env python

# Enrique Garcia. Aug '20
# email garcia 'at' lapp.in2p3.fr

6 7 8
import os
import json
import argparse
Enrique Garcia's avatar
Enrique Garcia committed
9
from pathlib import Path
10
from distutils.util import strtobool
Enrique Garcia's avatar
Enrique Garcia committed
11 12
from zenodoci.zenodoapi import ZenodoAPI
from codemeta2zenodo_crosswalk.codemeta2zenodo import parse_codemeta_and_write_zenodo_metadata_file
13 14


Enrique Garcia's avatar
Enrique Garcia committed
15
def create_zenodo_metadata(metadata_filename, repo_root_dir='./'):
16 17
    """
    Checks for a zenodo metadata file, otherwise it looks for a codemeta.json file to create a the .zenodo.json file
18

19 20 21 22
    param metadata_filename: str
        path and name to the zenodo metada json file
        NOT TO BE CHANGED. The file must be named `.zenodo.json` and be stored in the root directory of the library.
    """
Enrique Garcia's avatar
Enrique Garcia committed
23 24
    # root_dir = find_root_directory()
    root_dir = Path(repo_root_dir)
25

26
    files_json = [file for file in os.listdir(root_dir) if file.endswith('.json')]
Enrique Garcia's avatar
Enrique Garcia committed
27
    print(f'JSON files : {files_json}')
28

29 30
    zenodo_metadata_filename = metadata_filename
    codemeta_file = 'codemeta.json'
31

32 33
    if codemeta_file in files_json and zenodo_metadata_filename not in files_json:
        print(f"\nCreating {zenodo_metadata_filename} automatically at the CI pipeline.\n")
34
        parse_codemeta_and_write_zenodo_metadata_file(codemeta_file, zenodo_metadata_filename)
35

36 37 38 39 40 41 42 43 44
    elif os.path.isfile(zenodo_metadata_filename):
        print(f"\n{zenodo_metadata_filename} metadata file found in the root directory of the library ! \n")
        pass

    else:
        print(f"\n{codemeta_file} not found, thus any zenodo_metadata file `{zenodo_metadata_filename}` was"
              f" created during the CI pipeline."
              f"Please provide one so that the CI can run correctly (examples in the 'codemeta_utils' directory)")
        exit(-1)
45

46

Enrique Garcia's avatar
Enrique Garcia committed
47
def main():
48 49 50 51 52 53 54
    parser = argparse.ArgumentParser(description="Upload a new version of an existing deposit to Zenodo")

    parser.add_argument('--token', '-t', type=str,
                        dest='zenodo_token',
                        help='Personal access token to (sandbox)Zenodo',
                        required=True)

55
    parser.add_argument('--sandbox', '-s', action='store',
56 57 58
                        type=lambda x: bool(strtobool(x)),
                        dest='sandbox_flag',
                        help='Set the Zenodo environment.'
59
                             'If True connects with Zenodo. If False with Sandbox Zenodo',
60 61
                        default=False)

Enrique Garcia's avatar
Enrique Garcia committed
62
    parser.add_argument('--input-dir', '-i', type=str,
63 64 65 66 67 68 69 70 71 72 73 74
                        dest='input_directory',
                        help='Path to the directory containing the files to upload.'
                             'ALL files will be uploaded.',
                        required=True)

    parser.add_argument('--deposit_id', '-id', type=str,
                        dest='deposit_id',
                        help='deposit_id of the deposit that is going to be updated by a new version',
                        required=True)

    args = parser.parse_args()

75
    zenodo = ZenodoAPI(
76 77 78
        access_token=args.zenodo_token,
        sandbox=args.sandbox_flag  # True for sandbox.zenodo.org !! False for zenodo.org
    )
79 80

    # 1 - request a new version of an existing deposit
81
    new_version = zenodo.new_version_entry(args.deposit_id)
82 83

    if new_version.status_code < 399:
Enrique Garcia's avatar
Enrique Garcia committed
84
        print(f" * Status {new_version.status_code}. New version of the {args.deposit_id} entry correctly created !")
85
    else:
Enrique Garcia's avatar
Enrique Garcia committed
86
        print(f" ! ERROR; new version of the {args.deposit_id} entry COULD NOT be created.")
87 88 89 90
        print(new_version.json())

    new_deposition_id = new_version.json()['links']['latest_draft'].rsplit('/')[-1]

91
    # PRE-2 - If you DO NOT want to erase the old files, comment the following lines
92 93
    old_files_ids = [file['id'] for file in new_version.json()['files']]
    for file_id in old_files_ids:
94
        zenodo.erase_file_entry(
95 96 97
            new_deposition_id,
            file_id
        )
98 99 100 101 102

    # 2 - Upload new version of file(s)
    for file in os.listdir(args.input_directory):
        full_path_file = args.input_directory + '/' + file

103
        new_upload = zenodo.upload_file_entry(
104 105 106 107
            new_deposition_id,
            name_file=file,
            path_file=full_path_file
        )
108

Enrique Garcia's avatar
Enrique Garcia committed
109
        print(f" * File {file} correctly uploaded !\n", new_upload)
110

111 112 113
    # 3 - Look for a zenodo metadata file, otherwise try to create one
    zenodo_metadata_filename = '.zenodo.json'
    create_zenodo_metadata(zenodo_metadata_filename)
114

115 116
    with open(zenodo_metadata_filename) as json_file:
        update_entry_metadata = json.load(json_file)
117

118
    # update_entry_info['metadata']['doi'] = doi  # In the new version of the API the doi is updated automatically.
119
    update_entry = zenodo.update_metadata_entry(
120
        new_deposition_id,
121
        json_metadata=update_entry_metadata
122
    )
123 124

    if update_entry.status_code < 399:
Enrique Garcia's avatar
Enrique Garcia committed
125
        print(f" * Status {update_entry.status_code}. Repository information correctly uploaded !\n")
126
    else:
Enrique Garcia's avatar
Enrique Garcia committed
127
        print(f" ! Repository information NOT correctly uploaded ! Status {update_entry.status_code}\n",
128 129 130
              update_entry.json())

    # 4 - publish entry - to publish the entry, uncomment the two lone below
131
    # publish = zenodo.publish_entry(new_deposition_id)
132 133
    # print(publish.json())

Enrique Garcia's avatar
Enrique Garcia committed
134
    print(" * New version of the old deposition correctly published !\n")
135 136
    print(f"Old deposition id {args.deposit_id}, new deposition id {new_deposition_id}")
    print(f"The new doi should look like 10.5281/{new_deposition_id}. However please")
137
    print(f" ** Check the upload at {zenodo.zenodo_api_url[:-4]}/deposit/{new_deposition_id}  **")
Enrique Garcia's avatar
Enrique Garcia committed
138 139 140 141


if __name__ == '__main__':
    main()