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

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

6
import os
7
import json
8 9
import argparse
from distutils.util import strtobool
Enrique Garcia's avatar
Enrique Garcia committed
10
from zenodoapi import ZenodoAPI
Enrique Garcia's avatar
Enrique Garcia committed
11 12 13
from utils_zenodoci import (parse_codemeta_and_write_zenodo_metadata_file,
                            find_root_directory
                            )
14 15


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

Enrique Garcia's avatar
Enrique Garcia committed
20 21 22 23 24
    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.
    """
    root_dir = find_root_directory()
25

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

Enrique Garcia's avatar
Enrique Garcia committed
29 30
    zenodo_metadata_filename = metadata_filename
    codemeta_file = 'codemeta.json'
31

Enrique Garcia's avatar
Enrique Garcia committed
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

Enrique Garcia's avatar
Enrique Garcia committed
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

Enrique Garcia's avatar
Enrique Garcia committed
46 47 48 49 50 51 52 53 54

if __name__ == '__main__':
    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',
Enrique Garcia's avatar
Enrique Garcia committed
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',
Enrique Garcia's avatar
Enrique Garcia committed
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
                        default=False)

    parser.add_argument('--input-directory', '-i', type=str,
                        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(
Enrique Garcia's avatar
Enrique Garcia committed
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 86 87 88 89
    else:
        print(new_version.json())

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

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

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

102
        new_upload = zenodo.upload_file_entry(
Enrique Garcia's avatar
Enrique Garcia committed
103 104 105 106
            new_deposition_id,
            name_file=file,
            path_file=full_path_file
        )
107

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

Enrique Garcia's avatar
Enrique Garcia committed
110 111 112
    # 3 - Look for a zenodo metadata file, otherwise try to create one
    zenodo_metadata_filename = '.zenodo.json'
    create_zenodo_metadata(zenodo_metadata_filename)
113

Enrique Garcia's avatar
Enrique Garcia committed
114 115
    with open(zenodo_metadata_filename) as json_file:
        update_entry_metadata = json.load(json_file)
116

Enrique Garcia's avatar
Enrique Garcia committed
117
    # update_entry_info['metadata']['doi'] = doi  # In the new version of the API the doi is updated automatically.
118
    update_entry = zenodo.update_metadata_entry(
Enrique Garcia's avatar
Enrique Garcia committed
119 120 121
        new_deposition_id,
        data=update_entry_metadata
    )
122

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

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

133
    print("New version of the old deposition correctly published !")
Enrique Garcia's avatar
Enrique Garcia committed
134 135
    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")
136
    print(f" ** Check the upload at {zenodo.zenodo_api_url[:-4]}/deposit/{new_deposition_id}  **")