Skip to content

Commit

Permalink
Merge pull request #86 from con/enh-orcid
Browse files Browse the repository at this point in the history
Various little enhancements while dealing with interactive ORCID entry + add final empty line in pretty json dump
  • Loading branch information
yarikoptic authored May 24, 2024
2 parents 98f3eac + 1b5cda9 commit a973e67
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 55 deletions.
28 changes: 23 additions & 5 deletions tributors/main/orcid.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"""

from tributors.utils.file import write_file, get_tmpfile
from tributors.utils.prompt import choice_prompt
from tributors.utils.prompt import choice_prompt, entry_prompt
import logging
import os
import requests
Expand Down Expand Up @@ -193,16 +193,34 @@ def record_search(url, email, interactive=False, search_type=""):

# If interactive, ask for choice prompt
if interactive:
choices = [str(i) for i, _ in enumerate(results, 1)] + ["s", "S", "skip"]
prefix = "1:%s or s to skip" % min(10, len(results))
skip_choices = ["s", "S", "skip"]
enter_choices = ["e", "E", "enter"]
quit_choices = ["q"]
choices = (
[str(i) for i, _ in enumerate(results, 1)]
+ skip_choices
+ enter_choices
+ quit_choices
)
prefix = "1:%s or s to skip, e to enter, q to quit the loop" % min(
10, len(results)
)
choice = choice_prompt(
"Please enter a choice, or s to skip.",
"Please enter a choice, or s to skip, e to enter.",
choices=choices,
choice_prefix=prefix,
multiple=False,
)
if choice in quit_choices:
raise StopIteration("Requested by user")

if choice in enter_choices:
return entry_prompt(
f"Please enter the ORCID for {email}.",
regex="[0-9]{4}-[0-9]{4}-[0-9]{4}-[0-9]{3}[0-9X]$",
)

if not choice or choice in ["s", "S", "skip"]:
if not choice or choice in skip_choices:
return

# Return the orcid identifier
Expand Down
43 changes: 23 additions & 20 deletions tributors/main/parsers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,23 +142,26 @@ def update_cache(self, update_lookup=True):

# Then add an Orcid lookup
for login, entry in self.cache.items():
# If we have an email, and orcid isn't defined
if "orcid" not in entry:
orcid = get_orcid(
entry.get("email"), entry.get("name"), interactive=interactive
)
if orcid:
entry["orcid"] = orcid
cli = OrcidIdentifier(orcid)

# If we found the record, update metadata
if (
cli.found
and not entry.get("name")
or entry.get("name") == login
):
entry["name"] = "%s %s" % (cli.firstName, cli.lastName)
if cli.affiliation and not entry.get("affiliation"):
entry["affiliation"] = cli.affiliation

self.cache[login] = entry
try:
# If we have an email, and orcid isn't defined
if "orcid" not in entry:
orcid = get_orcid(
entry.get("email"), entry.get("name"), interactive=interactive
)
if orcid:
entry["orcid"] = orcid
cli = OrcidIdentifier(orcid)

# If we found the record, update metadata
if (
cli.found
and not entry.get("name")
or entry.get("name") == login
):
entry["name"] = "%s %s" % (cli.firstName, cli.lastName)
if cli.affiliation and not entry.get("affiliation"):
entry["affiliation"] = cli.affiliation

self.cache[login] = entry
except StopIteration:
break
14 changes: 6 additions & 8 deletions tributors/utils/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@ def write_json(json_obj, filename, pretty=True):
- json_obj (dict) : the dict to print to json
- filename (str) : the output file to write to
"""
kw = dict(indent=4, separators=(",", ": ")) if pretty else {}
with open(filename, "w", encoding="utf8") as filey:
if pretty:
filey.writelines(
json.dumps(
json_obj, indent=4, ensure_ascii=False, separators=(",", ": ")
)
)
else:
filey.writelines(json.dumps(json_obj), ensure_ascii=False)
dump = json.dumps(json_obj, ensure_ascii=False, **kw)
if pretty and not dump.endswith(os.linesep):
# Add newline as it is typically desired
dump += os.linesep
filey.write(dump)
return filename


Expand Down
44 changes: 22 additions & 22 deletions tributors/utils/prompt.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,15 @@
"""
Copyright (C) 2020-2022 Vanessa Sochat.
2024 Yaroslav O. Halchenko
This Source Code Form is subject to the terms of the
Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed
with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
"""


enter_input = getattr(__builtins__, "raw_input", input)


def request_input():
"""Wait for the user to input some string, optionally with multiple lines."""
lines = []

# The message can be multiple lines
while True:
try:
line = enter_input()
except EOFError:
break
if line:
lines.append(line)

return "\n".join(lines)
import re


def choice_prompt(prompt, choices, choice_prefix=None, multiple=False):
Expand All @@ -41,15 +25,12 @@ def choice_prompt(prompt, choices, choice_prefix=None, multiple=False):
choice = None
print(prompt)

# Support for Python 2 (raw_input)
get_input = getattr(__builtins__, "raw_input", input)

if not choice_prefix:
choice_prefix = "/".join(choices)
message = "[%s] : " % (choice_prefix)

while choice not in choices:
choice = get_input(message).strip()
choice = input(message).strip()

# If multiple allowed, add selection to choices if includes all valid
if multiple is True:
Expand All @@ -58,3 +39,22 @@ def choice_prompt(prompt, choices, choice_prefix=None, multiple=False):
choices.append(choice)
message = "Please enter a valid option in [%s]" % choice_prefix
return choice


def entry_prompt(prompt, regex=None):
"""Ask the user for a prompt, and only return when a valid entry is provided.
Parameters
==========
prompt: the prompt to ask the user
regex: a regular expression to match the entry
"""
entry = None
print(prompt)
message = "Please enter a value. Empty to skip: "
while not entry:
entry = input(message).strip()
if entry and regex is not None and not re.match(regex, entry):
entry = None
message = r"Please enter a valid response. Should match regex {regex!r}"
return entry

0 comments on commit a973e67

Please sign in to comment.