Skip to content

Commit 1ead42d

Browse files
committed
Attempt at new LoC translator
1 parent 60a7cb7 commit 1ead42d

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

Library of Congress.js

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
{
2+
"translatorID": "86c090c5-ad3f-4c54-a1f3-9870942014ac",
3+
"label": "Library of Congress",
4+
"creator": "Sebastian Karcher",
5+
"target": "^https?://search\\.catalog\\.loc\\.gov/",
6+
"minVersion": "5.0",
7+
"maxVersion": "",
8+
"priority": 100,
9+
"inRepository": true,
10+
"translatorType": 4,
11+
"browserSupport": "gcsibv",
12+
"lastUpdated": "2025-08-23 18:51:50"
13+
}
14+
15+
/*
16+
***** BEGIN LICENSE BLOCK *****
17+
18+
Copyright © 2025 Sebastian Karcher
19+
20+
This file is part of Zotero.
21+
22+
Zotero is free software: you can redistribute it and/or modify
23+
it under the terms of the GNU Affero General Public License as published by
24+
the Free Software Foundation, either version 3 of the License, or
25+
(at your option) any later version.
26+
27+
Zotero is distributed in the hope that it will be useful,
28+
but WITHOUT ANY WARRANTY; without even the implied warranty of
29+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30+
GNU Affero General Public License for more details.
31+
32+
You should have received a copy of the GNU Affero General Public License
33+
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
34+
35+
***** END LICENSE BLOCK *****
36+
*/
37+
38+
39+
function detectWeb(doc, url) {
40+
if (url.includes('/instances/')) {
41+
let type = text(doc, 'div[class*="__metadata-type"]')
42+
Z.debug(type)
43+
switch (type) {
44+
case "Book":
45+
return "book";
46+
case "Cartographic Material":
47+
return "map";
48+
case "Audio":
49+
return "audioRecording";
50+
default:
51+
return "book";
52+
}
53+
}
54+
else if (getSearchResults(doc, true)) {
55+
return 'multiple';
56+
}
57+
return false;
58+
}
59+
60+
function getSearchResults(doc, checkOnly) {
61+
var items = {};
62+
var found = false;
63+
var rows = doc.querySelectorAll('h2 > a[href*="/instances/"]');
64+
for (let row of rows) {
65+
let href = row.href;
66+
let title = ZU.trimInternal(row.textContent);
67+
if (!href || !title) continue;
68+
if (checkOnly) return true;
69+
found = true;
70+
items[href] = title;
71+
}
72+
return found ? items : false;
73+
}
74+
75+
76+
function getLCCN(doc){
77+
let lccn = text(doc, '[data-auto="record-lccn-content"]');
78+
return lccn;
79+
}
80+
81+
async function doWeb(doc, url) {
82+
if (detectWeb(doc, url) == 'multiple') {
83+
let items = await Zotero.selectItems(getSearchResults(doc, false));
84+
if (!items) return;
85+
for (let url of Object.keys(items)) {
86+
// There's an internal API, but I'm getting consistent 401 responses
87+
// url = url.replace("/instances/", "/api/opac-inventory/instances/").replace(/\?.*/, "");
88+
// Z.debug(url)
89+
await scrape(await requestDocument(url));
90+
}
91+
}
92+
else {
93+
let lccn = getLCCN(doc);
94+
let marcxmlurl = "https://lccn.loc.gov/" + lccn + "/marcxml"
95+
await scrapeMARC(marcxmlurl);
96+
}
97+
}
98+
99+
async function scrapeMARC(marcxmlurl) {
100+
let marcxml = await requestText(marcxmlurl);
101+
Z.debug(marcxml)
102+
let translate = Zotero.loadTranslator('import');
103+
translate.setTranslator('edd87d07-9194-42f8-b2ad-997c4c7deefd');
104+
translate.setString(marcxml);
105+
translate.setHandler('itemDone', (_, item) => {});
106+
[item] = await translate.translate();
107+
// item.itemType = detectWeb(doc, url);
108+
item.complete();
109+
}
110+
111+
async function scrape(doc) {
112+
let lccn = getLCCN(doc);
113+
let marcxmlurl = "https://lccn.loc.gov/" + lccn + "/marcxml"
114+
await scrapeMARC(marcxmlurl);
115+
}
116+
117+
/** BEGIN TEST CASES **/
118+
var testCases = [
119+
{
120+
"type": "web",
121+
"url": "https://search.catalog.loc.gov/instances/5f9c256e-151d-5615-ad15-3d2749318cac?option=keyword&query=karcher",
122+
"defer": true,
123+
"items": [
124+
{
125+
"itemType": "book",
126+
"title": "Praxis des Beton- und Stahlbetonbaus: Wissensgrundlagen für die Baustelle und das Ingenieurbüro",
127+
"creators": [
128+
{
129+
"firstName": "Gustav",
130+
"lastName": "Kärcher",
131+
"creatorType": "author"
132+
}
133+
],
134+
"date": "1952",
135+
"callNumber": "TA681 .K25",
136+
"libraryCatalog": "Library of Congress",
137+
"numPages": "200",
138+
"place": "Stuttgart",
139+
"publisher": "Franckh",
140+
"shortTitle": "Praxis des Beton- und Stahlbetonbaus",
141+
"attachments": [],
142+
"tags": [
143+
{
144+
"tag": "Concrete construction"
145+
},
146+
{
147+
"tag": "Reinforced concrete construction"
148+
}
149+
],
150+
"notes": [],
151+
"seeAlso": []
152+
}
153+
]
154+
}
155+
]
156+
/** END TEST CASES **/

0 commit comments

Comments
 (0)