-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzotero_pub.py
199 lines (159 loc) · 6.42 KB
/
zotero_pub.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#!/usr/local/bin/python3
"""Zotero Publication objects.
Defines publications from Zotero service.
"""
import csv
import sys
import urllib.parse
import publication
# Zotero URLs
#
# In early 2020 or late 2019, Zotero updated how it handles URLS for tags.
# User library
# https://www.zotero.org/tnabtaf/library
#
# Group Library
# https://www.zotero.org/groups/1732893/galaxy/library
#
# Particular tag in a group library
# https://www.zotero.org/groups/1732893/galaxy/tags/%2BTools
#
# Particular Pub in a group library
# https://www.zotero.org/groups/1732893/galaxy/items/KJS7VDEU
#
# AND search for two tags in a user library
# https://www.zotero.org/groups/1732893/galaxy/tags/%2BStellar,%2BTools/library
#
# AND serach for one tag and one term ("analytic") in Title, creator, year only
# https://www.zotero.org/groups/1732893/galaxy/tags/%2BTools/search/analytic/titleCreatorYear/item-list
#
# AND search for one tag and one term in all fields
# https://www.zotero.org/groups/1732893/galaxy/tags/%2BTools/search/analytic/everything/item-list
#
#
# Group library in CSV format
#
SERVICE_NAME = "Zotero"
ZOTERO_BASE_URL = "https://www.zotero.org"
# append after user or group to get all papers with a tag.
ZOTERO_TAG_SUFFIX = ""
class Pub(publication.Pub):
"""A publication defined in a Zotero library.
The definition comes from a CSV export of a library.
"""
def __init__(self, zot_csv_row):
"""Create a Zotero publication object from a Zotero CSV entry."""
super(Pub, self).__init__()
self._zot_csv_row = zot_csv_row
self.title = self._zot_csv_row["Title"]
self.canonical_title = publication.to_canonical(self.title)
self.zotero_id = self._zot_csv_row['\ufeff"Key"'] # BOM won't go away
doi = self._zot_csv_row.get("DOI")
if doi: # should be close to canonical already
doi = publication.to_canonical_doi(doi)
self.canonical_doi = doi
self.url = self._zot_csv_row["Url"] # Can be empty
# Authors is a semicolon separated list of "Last, First I."
authors = self._zot_csv_row.get("Author")
if authors:
self.set_authors(
authors,
self.to_canonical_first_author(authors))
else:
print(
"Warning: Zotero Pub '{0}'".format(self.title),
file=sys.stderr)
print(" Does not have any authors.\n", file=sys.stderr)
self.year = self._zot_csv_row.get("Publication Year")
if not self.year:
self.year = "unknown"
print(
"Warning: Zotero Pub '{0}'".format(self.title),
file=sys.stderr)
print(" Does not have a publication year.\n", file=sys.stderr)
# Tags are a semicolon separated list
self.tags = self._zot_csv_row["Manual Tags"].split("; ")
if self._zot_csv_row["Item Type"] == "journalArticle":
self.journal_name = self._zot_csv_row["Publication Title"]
self.canonical_journal = publication.to_canonical(
self.journal_name)
else:
self.canonical_journal = None
# Entry date in Zotero CSV looks like "date": "2017-09-14 17:48:40"
self.entry_date = self._zot_csv_row.get("Date Added")[0:10]
self.ref = ""
if not self.journal_name:
self.ref = self._zot_csv_row["Publication Title"]
year = self._zot_csv_row.get("Publication Year")
if year:
self.ref += " (" + year + ")"
return None
def to_canonical_first_author(self, zot_author_string):
"""Convert a Zotero author list to a canonical first author name.
A Zotero author list looks like:
Gloaguen, Yoann; Morton, Fraser; Daly, Rónán; Gurden, Ross
Canonical first author is last name of first author.
"""
if zot_author_string:
last_name = zot_author_string.split(",")[0]
canonical_first_author = publication.to_canonical(last_name)
else:
canonical_first_author = None
return canonical_first_author
class PubLibrary(publication.PubLibrary):
"""A collection of publications from Zotero."""
def __init__(self, zot_csv_lib_path, zot_lib_url):
"""Given a file containing a Zotero CSV export of a library,
create a publication library containing all the pubs in that library.
"""
super(PubLibrary, self).__init__()
self.url = zot_lib_url
# URL tell us if user or group library.
self.is_user_lib = False
self.is_group_lib = False
url_parts = urllib.parse.urlparse(self.url)
# /groups/1732893/galaxy/
if url_parts.path.startswith("/groups/"):
self.is_group_lib = True
parts = url_parts.path.split("/")
self._zot_group_id = parts[2]
self._zot_group_name = parts[3]
else: # https://www.zotero.org/tnabtaf/
self.is_user_lib = True
self._zot_username = url_parts.path.split("/")[1]
zot_file = open(zot_csv_lib_path, "r")
zot_reader = csv.DictReader(zot_file)
for zot_pub_csv in zot_reader:
zot_pub = Pub(zot_pub_csv)
self.add_pub(zot_pub)
zot_file.close()
self.num_pubs = len(self.all_pubs)
return None
def gen_tag_url(self, tag, sort_by_add_date=False):
"""Given a tag, generate the URL that shows all papers with that tag.
Used to support sorting by date added, but Zotero dropped that feature
in late 2019/early 2020. (Can still do it, but not via a URL.)
"""
tag_url = self.url + "tags/" + tag
return tag_url
def gen_year_url(self, year):
"""Given a year, generate a URL thot shows all papers published in
that year.
This can't be done in Zotero. Return None
"""
return None
def gen_tag_year_url(self, tag, year):
"""Given a tag and a year, generate a URL thot shows all papers with
that tag published in that year.
This can't be done in Zotero. Return None.
"""
return None
def gen_pub_url_in_lib(self, pub):
"""given a pub in this library, generate a link to it online."""
pub_url = self.url + "/items/" + pub.zotero_id
return pub_url
def gen_add_pub_html_link(pub_url):
"""Given the URL of a publication, generate a link to add that pub to
Zotero.
"""
return None