Skip to content

Commit 56f0a7a

Browse files
committed
Many updates:
* add dedicated function to load credentials from a given dictionary, a given file, or a default file * fix issues with abstracts (multilingual...) and ISSN * get HAL ID for document when deposit or existing repo * update example
1 parent c5e7196 commit 56f0a7a

File tree

9 files changed

+75
-27
lines changed

9 files changed

+75
-27
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,5 @@ cython_debug/
161161

162162

163163
## push2HAL
164-
.apihal
164+
.apihal
165+
push2HAL/version.py

.vscode/settings.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"python.testing.pytestArgs": [
3+
"tests"
4+
],
5+
"python.testing.unittestEnabled": false,
6+
"python.testing.pytestEnabled": true
7+
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77

8-
`push2HAL` is a basic Python library dedicated to achieving upload on [HAL](https://hal.science) database. It will use the classical API of HAL to get information and the SWORD one to upload content. Two main executables are provided (for UNIX use only):
8+
`push2HAL` is a basic Python library dedicated to data uploading on [HAL](https://hal.science) database. It will use the classical API of HAL to get information and the SWORD one to upload content. Two main executables are provided (for UNIX use only):
99

1010
- `pdf2hal` is able to upload a PDF file to an existing notice on HAL (only with valid permission to modify it).
1111
- `json2hal` is able to build the necessary data from a JSON file to create a new notice in HAL and upload it directly with or without providing a PDF file.

examples/test.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"lang": "en",
44
"title": {"en":"article", "fr":"article"},
55
"subtitle": "A subtitle",
6+
"abstract": {"en":"a very long abstract", "fr": "un très long résumé"},
67
"authors": [
78
{
89
"firstname": "John",

examples/test_comments.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"type": "article", // specific type id see: https://api.archives-ouvertes.fr/ref/doctype (article only works, other types could reuires improvments on code)
55
"title": {"en":"article", "fr":"article"},
66
"subtitle": "A subtitle",
7+
"abstract": {"en":"a very long abstract", "fr": "un très long résumé"},
78
"authors": [
89
{
910
"firstname": "John",

src/push2HAL/default.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@
6666
DEFAULT_PEER='0'
6767
DEFAULT_PROCEEDINGS='0'
6868
DEFAULT_STRUCT_TYPE='institution'
69+
DEFAULT_LANG_DOC='en'

src/push2HAL/execHAL.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def runJSON2HAL(
112112

113113
# upload to HAL
114114
if credentials:
115-
lib.upload2HAL(file, payload, credentials, server=serverType)
115+
id_hal = lib.upload2HAL(file, payload, credentials, server=serverType)
116+
return id_hal
116117
else:
117118
Logger.error("No provided credentials")
118119
exitStatus = os.EX_CONFIG

src/push2HAL/libHAL.py

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import tempfile
1616
import requests
1717
import difflib
18+
import json
1819
from requests.auth import HTTPBasicAuth
1920
from lxml import etree
2021
import re
@@ -324,15 +325,18 @@ def upload2HAL(file, headers, credentials, server="preprod"):
324325
headers=headers,
325326
auth=HTTPBasicAuth(credentials["login"], credentials["passwd"]),
326327
)
327-
328+
329+
330+
hal_id = None
328331
if res.status_code == 201:
329332
Logger.info("Successfully upload to HAL.")
330333
elif res.status_code == 202:
331334
Logger.info("Note accepted by HAL.")
332335
# read return message
333336
xmlResponse = etree.fromstring(res.text.encode("utf-8"))
334337
elem = xmlResponse.findall("id", xmlResponse.nsmap)
335-
Logger.info("HAL ID: {}".format(elem[0].text))
338+
hal_id = elem[0].text
339+
Logger.debug("HAL ID: {}".format(elem[0].text))
336340
elif res.status_code == 401:
337341
Logger.info("Authentification refused - check credentials")
338342
else:
@@ -343,14 +347,22 @@ def upload2HAL(file, headers, credentials, server="preprod"):
343347
)
344348
Logger.error("Failed to upload. Status code: {}".format(res.status_code))
345349
if len(elem) > 0:
350+
json_ret = list()
346351
for i in elem:
352+
json_ret.append(json.loads(i.text))
347353
Logger.warning("Error: {}".format(i.text))
348-
354+
# extract hal_id
355+
for j in json_ret:
356+
if j.get('duplicate-entry'):
357+
hal_id = list(j.get('duplicate-entry').keys())[0]
358+
return hal_id
349359

350360
def setTitles(nInTree, titles, subTitles=None):
351361
"""Add title(s) and subtitle(s) in XML (and specified language)"""
352362
if subTitles:
353363
listTitles = {"titles": titles, "subtitles": subTitles}
364+
else:
365+
listTitles = {"titles": titles}
354366
nTitle = list()
355367
for k, n in listTitles.items():
356368
if type(n) == dict:
@@ -634,19 +646,20 @@ def setAbstract(inTree, abstracts):
634646
if not abstracts:
635647
Logger.warning("No provided abstract")
636648
return None
637-
if type(abstracts) != list():
638-
abstracts = [abstracts]
639649
nAbstract = list()
640-
for a in abstracts:
641-
if type(a) == dict:
642-
nAbstract.append(etree.SubElement(inTree, TEI + "abstract"))
643-
nAbstract[-1].set(dflt.DEFAULT_XML_LANG + "lang", a["lang"])
644-
nAbstract[-1].text = a["text"]
645-
else:
646-
Logger.warning("No language for abstract: force english")
650+
if type(abstracts) == str():
651+
Logger.warning("No language for abstract: force english")
652+
nAbstract.append(etree.SubElement(inTree, TEI + "abstract"))
653+
nAbstract[-1].set(dflt.DEFAULT_XML_LANG + "lang", "en")
654+
nAbstract[-1].text = abstracts
655+
else:
656+
nKeywords = list()
657+
for lk, vk in abstracts.items():
647658
nAbstract.append(etree.SubElement(inTree, TEI + "abstract"))
648-
nAbstract[-1].set(dflt.DEFAULT_XML_LANG + "lang", "en")
649-
nAbstract[-1].text = a
659+
nAbstract[-1].set(dflt.DEFAULT_XML_LANG + "lang", lk)
660+
nAbstract[-1].text = vk
661+
return nAbstract
662+
650663
return nAbstract
651664

652665

@@ -709,7 +722,7 @@ def setIDS(inTree, data):
709722
Logger.warning("ISSN not valid: {}, continue...".format(data.get("issn")))
710723
lID.append(setID(inTree, data.get("issn"), "issn"))
711724
if data.get("eissn", None):
712-
if not isbn.validate(data.get("eissn")):
725+
if not issn.validate(data.get("eissn")):
713726
Logger.warning("eISSN not valid: {}, continue...".format(data.get("eissn")))
714727
lID.append(setID(inTree, data.get("eissn"), "eissn"))
715728
if data.get("j", None):
@@ -771,8 +784,8 @@ def setLanguage(inTree, language):
771784
"""Set main language in XML"""
772785
langUsage = etree.SubElement(inTree, TEI + "langUsage")
773786
if not language:
774-
Logger.warning("No language provided - force {}".format(dflt.DEFAULT_XML_LANG))
775-
language = dflt.DEFAULT_XML_LANG
787+
Logger.warning("No language provided - force {}".format(dflt.DEFAULT_LANG_DOC))
788+
language = dflt.DEFAULT_LANG_DOC
776789
idL = etree.SubElement(langUsage, TEI + "language")
777790
idL.set("ident", language)
778791

src/push2HAL/misc.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,23 +61,46 @@ def showPDFcontent(pdf_path, number=dflt.DEFAULT_NB_CHAR):
6161
Logger.error(f"Error: {e}")
6262

6363

64-
def load_credentials(args):
64+
def load_credentials(args=None):
6565
"""Load credentials from different sources"""
6666
cred = dict()
6767
# if args.hash:
6868
# Logger.debug('Load credentials from hash')
6969
# cred['hash']=args.hash
70-
if args.login and args.passwd:
70+
# load input arguments depending on cases
71+
login = None
72+
passwd = None
73+
inputfile = None
74+
if args:
75+
if type(args) is dict:
76+
Logger.debug("Load credentials from dictionary")
77+
login = args.get("login",None)
78+
passwd = args.get("passwd",None)
79+
inputfile = args.get("file",None)
80+
elif type(args) is str():
81+
Logger.debug("Load credentials from string (file path)")
82+
inputfile = args
83+
elif type(args) is list():
84+
Logger.debug("Load credentials from list (login, passwd)")
85+
if len(args)>1:
86+
login = args[0]
87+
passwd = args[1]
88+
else:
89+
login = args.login
90+
passwd = args.passwd
91+
inputfile = args.credentials
92+
93+
if login and passwd:
7194
Logger.debug("Load credentials from arguments")
7295
cred["login"] = args.login
7396
cred["passwd"] = args.passwd
74-
elif args.credentials:
75-
Logger.debug("Load credentials from file {}".format(args.credentials))
76-
if os.path.isfile(args.credentials):
77-
with open(args.credentials) as f:
97+
elif inputfile:
98+
Logger.debug("Load credentials from file {}".format(inputfile))
99+
if os.path.isfile(inputfile):
100+
with open(inputfile) as f:
78101
cred = json.load(f)
79102
else:
80-
Logger.debug("Load credentials from file")
103+
Logger.debug("Load credentials from root default file {}".format(dflt.DEFAULT_CREDENTIALS_FILE))
81104
if os.path.isfile(dflt.DEFAULT_CREDENTIALS_FILE):
82105
with open(dflt.DEFAULT_CREDENTIALS_FILE) as f:
83106
cred = json.load(f)

0 commit comments

Comments
 (0)