-
Notifications
You must be signed in to change notification settings - Fork 104
/
Copy pathupdate_codemeta.py
105 lines (87 loc) · 3.69 KB
/
update_codemeta.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#! /usr/bin/env python3
# Copyright (C) 2019-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
#
# SPDX-License-Identifier: LGPL-3.0-or-later
import argparse
import json
import re
from collections import OrderedDict
class CodeMetaManipulator(object):
def load(self, filename='codemeta.json'):
with open(filename, 'rb') as fp:
self.data = json.load(fp, object_pairs_hook=OrderedDict)
@staticmethod
def _dict_entry_cmp(dict1, dict2, field):
if (field in dict1) and (field in dict2):
return dict1[field] == dict2[field]
else:
return False
@classmethod
def find_person_entry(cls, person_list, matchdict):
for entry in person_list:
if cls._dict_entry_cmp(entry, matchdict, 'email'):
return entry
if cls._dict_entry_cmp(entry, matchdict, 'familyName') \
and cls._dict_entry_cmp(entry, matchdict, 'givenName'):
return entry
return None
@staticmethod
def update_person_entry(entry, matchdict):
if entry is None:
entry = OrderedDict()
entry['@type'] = 'Person'
# Aquí se cambian los nombres de los campos
for field in ('givenName', 'familyName', 'email', 'affiliation'):
val = matchdict.get(field, None)
if val is not None:
entry[field] = val
# Cambiar 'orcid' a 'identifier' y asignarlo
if matchdict.get('orcid'):
entry['identifier'] = matchdict['orcid']
return entry
@staticmethod
def is_valid_email(email):
""" Verifica si el correo electrónico tiene un formato válido. """
email_regex = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)"
return bool(re.match(email_regex, email))
def handle_person_list_file(self, filename, cm_field_name):
with open(filename, 'r', encoding='utf8') as fp:
findregex = re.compile(
r'^(?P<familyName>[-\w\s]*[-\w]),\s*'
r'(?P<givenName>[-\w\s]*[-\w])\s*'
r'(?:\[(?P<email>[^\]]+)\])?\s*'
r'(?:\[(?P<orcid>https?://orcid.org/[^\]]+)\])?\s*'
r'(?:\[(?P<affiliation>[^\]]+)\])?$'
)
person_list = self.data.setdefault(cm_field_name, [])
for line in fp:
line = line.strip()
m = findregex.match(line)
if m is None:
raise RuntimeError(f"Could not analyze line: {line!r}")
matchdict = m.groupdict()
# Verificar si el email es válido
if matchdict.get('email'):
if not self.is_valid_email(matchdict['email']):
matchdict['email'] = None # Asignar None si el correo es inválido
found_entry = self.find_person_entry(person_list, matchdict)
entry = self.update_person_entry(found_entry, matchdict)
if found_entry is None:
person_list.append(entry)
def save(self, filename='codemeta.json'):
with open(filename, 'w', encoding='utf8') as fp:
json.dump(self.data, fp, indent=2)
fp.write('\n')
def main():
parser = argparse.ArgumentParser(description='Update codemeta.json')
parser.add_argument('--set-version', dest='newversion')
args = parser.parse_args()
cm = CodeMetaManipulator()
cm.load()
if args.newversion is not None:
cm.data['softwareVersion'] = args.newversion
cm.handle_person_list_file('AUTHORS', 'author')
cm.handle_person_list_file('CONTRIBUTORS', 'contributor')
cm.save()
if __name__ == '__main__':
main()