|
1 | 1 | import json
|
2 | 2 | from urllib.request import Request, urlopen
|
3 | 3 | from util import *
|
4 |
| -from manubot.cite.handlers import prefix_to_handler as manubot_prefixes |
| 4 | +from manubot.cite.handlers import prefix_to_handler as manubot_citable |
5 | 5 |
|
6 | 6 |
|
7 | 7 | def main(entry):
|
@@ -33,36 +33,66 @@ def query(_id):
|
33 | 33 | # list of sources to return
|
34 | 34 | sources = []
|
35 | 35 |
|
36 |
| - # go through response structure and pull out ids e.g. doi:1234/56789 |
| 36 | + # filter id by some criteria. return true to accept, false to reject. |
| 37 | + def filter_id(_id): |
| 38 | + # is id of certain "relationship" type |
| 39 | + relationships = ["self", "version-of", "part-of"] |
| 40 | + if not get_safe(_id, "external-id-relationship", "") in relationships: |
| 41 | + return False |
| 42 | + |
| 43 | + id_type = get_safe(_id, "external-id-type", "") |
| 44 | + |
| 45 | + # is id of certain type |
| 46 | + # types = ["doi"] |
| 47 | + # if id_type not in types: |
| 48 | + # return False |
| 49 | + |
| 50 | + # is id citable by manubot |
| 51 | + if id_type not in manubot_citable: |
| 52 | + return False |
| 53 | + |
| 54 | + return True |
| 55 | + |
| 56 | + # prefer some ids over others by some criteria. return lower number to prefer more. |
| 57 | + def sort_id(_id): |
| 58 | + types = [ |
| 59 | + "doi", |
| 60 | + # "arxiv", |
| 61 | + # "url", |
| 62 | + ] |
| 63 | + return index_of(types, get_safe(_id, "external-id-type", "")) |
| 64 | + |
| 65 | + # go through each source |
37 | 66 | for work in response:
|
38 |
| - # get list of ids |
| 67 | + # list of ids in work |
39 | 68 | ids = []
|
| 69 | + |
| 70 | + # use "work-summary" field instead of top-level "external-ids" to reflect author-selected preferred sources |
40 | 71 | for summary in get_safe(work, "work-summary", []):
|
41 | 72 | ids = ids + get_safe(summary, "external-ids.external-id", [])
|
42 | 73 |
|
43 |
| - # find first id of particular "relationship" type |
44 |
| - _id = next( |
45 |
| - ( |
46 |
| - id |
47 |
| - for id in ids |
48 |
| - if get_safe(id, "external-id-relationship", "") |
49 |
| - in ["self", "version-of", "part-of"] |
50 |
| - ), |
51 |
| - ids[0] if len(ids) > 0 else None, |
52 |
| - ) |
53 |
| - |
54 |
| - if _id == None: |
55 |
| - continue |
56 |
| - |
57 |
| - # get id and id-type from response |
| 74 | + # filter ids by criteria |
| 75 | + ids = list(filter(filter_id, ids)) |
| 76 | + # sort ids by criteria |
| 77 | + ids.sort(key=sort_id) |
| 78 | + |
| 79 | + # pick first id |
| 80 | + _id = ids[0] if len(ids) > 0 else None |
| 81 | + |
| 82 | + # id parts |
58 | 83 | id_type = get_safe(_id, "external-id-type", "")
|
59 | 84 | id_value = get_safe(_id, "external-id-value", "")
|
60 | 85 |
|
61 | 86 | # create source
|
62 |
| - source = {"id": f"{id_type}:{id_value}"} |
| 87 | + source = {} |
63 | 88 |
|
64 |
| - # if not an id type that Manubot can cite, keep citation details |
65 |
| - if id_type not in manubot_prefixes: |
| 89 | + # if id citable by manubot |
| 90 | + if id_type and id_value and id_type in manubot_citable: |
| 91 | + # id to cite with manubot |
| 92 | + source = {"id": f"{id_type}:{id_value}"} |
| 93 | + |
| 94 | + # if not citable by manubot, keep citation details from orcid |
| 95 | + else: |
66 | 96 | # get summaries
|
67 | 97 | summaries = get_safe(work, "work-summary", [])
|
68 | 98 |
|
@@ -107,3 +137,11 @@ def first(get_func):
|
107 | 137 | sources.append(source)
|
108 | 138 |
|
109 | 139 | return sources
|
| 140 | + |
| 141 | + |
| 142 | +# index of, with fallback |
| 143 | +def index_of(_list, value): |
| 144 | + try: |
| 145 | + return _list.index(value) |
| 146 | + except ValueError: |
| 147 | + return float("inf") |
0 commit comments