diff --git a/.gitignore b/.gitignore
index c795b05..a36501c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
-build
\ No newline at end of file
+build
+.gitignore
+.DS_Store
+*.xpi
diff --git a/src/bootstrap.js b/src/bootstrap.js
index ae6db73..e5ab686 100644
--- a/src/bootstrap.js
+++ b/src/bootstrap.js
@@ -16,6 +16,7 @@ async function startup({ id, version, rootURI }) {
Services.scriptloader.loadSubScript(rootURI + 'chrome/content/threadpool.js');
Services.scriptloader.loadSubScript(rootURI + 'chrome/content/journal.js');
Services.scriptloader.loadSubScript(rootURI + 'chrome/content/book.js');
+ Services.scriptloader.loadSubScript(rootURI + 'chrome/content/arxiv.js');
Services.scriptloader.loadSubScript(rootURI + 'chrome/content/zotmeta.js');
ZotMeta.init({ id, version, rootURI });
ZotMeta.addToAllWindows();
diff --git a/src/chrome/content/arxiv.js b/src/chrome/content/arxiv.js
new file mode 100644
index 0000000..e48215a
--- /dev/null
+++ b/src/chrome/content/arxiv.js
@@ -0,0 +1,87 @@
+Arxiv = {
+ generateAuthors(authors) {
+ var newAuthorList = [];
+ if (authors) {
+ authors.forEach(author => {
+ newAuthorList.push(
+ {
+ "firstName": author["given"] || "",
+ "lastName": author["family"] || "",
+ "creatorType": "author"
+ }
+ );
+ });
+ }
+ return newAuthorList;
+ },
+
+ generateDate(date) {
+ if (!date) {
+ return null;
+ }
+ return date.split("T")[0]; // 提取日期部分 (YYYY-MM-DD 格式)
+ },
+
+ getMetaData(item) {
+ var arxivID = item.getField('archiveID').split(":")[1];
+ if (!arxivID) {
+ return null; // ArXiv ID 是必需的
+ }
+
+ var url = `https://export.arxiv.org/api/query?id_list=${arxivID}`;
+ return Utilities.fetchWithTimeout(url, { method: 'GET' }, 3000)
+ .then(response => {
+ if (!response.ok) {
+ Utilities.publishError("Error retrieving metadata",
+ "Please check if the ArXiv ID is correct and if you have network access to arxiv.org.");
+ return null;
+ }
+ return response.text();
+ })
+ .then(data => {
+ try {
+ // 解析 ArXiv API 返回的 XML 数据
+ let parser = new DOMParser();
+ let xmlDoc = parser.parseFromString(data, "application/xml");
+
+ let title = xmlDoc.querySelector("entry > title")?.textContent.trim();
+ let authors = Array.from(xmlDoc.querySelectorAll("entry > author")).map(author => ({
+ given: author.querySelector("name").textContent.split(" ").slice(0, -1).join(" "),
+ family: author.querySelector("name").textContent.split(" ").slice(-1).join(" ")
+ }));
+ let published = xmlDoc.querySelector("entry > published")?.textContent.trim();
+ let summary = xmlDoc.querySelector("entry > summary")?.textContent.trim();
+ let journalRef = xmlDoc.querySelector("entry > arxiv\\:journal_ref")?.textContent.trim();
+ let doi = xmlDoc.querySelector("entry > arxiv\\:doi")?.textContent.trim();
+
+ return {
+ "Title": title || "",
+ "Authors": this.generateAuthors(authors),
+ "PublishDate": this.generateDate(published),
+ "Abstract": summary || "",
+ "JournalRef": journalRef || "",
+ "DOI": doi || ""
+ };
+ } catch (error) {
+ Utilities.publishError("Error parsing metadata", "Unable to parse metadata from ArXiv.");
+ return null;
+ }
+ });
+ },
+
+ async updateMetadata(item) {
+ var metaData = await this.getMetaData(item);
+ if (!metaData) {
+ return 1;
+ }
+
+ if (!Utilities.isEmpty(metaData["Title"])) item.setField('title', metaData["Title"]);
+ if (!Utilities.isEmpty(metaData["Authors"])) item.setCreators(metaData["Authors"]);
+ if (!Utilities.isEmpty(metaData["PublishDate"])) item.setField('date', metaData["PublishDate"]);
+ if (!Utilities.isEmpty(metaData["Abstract"])) item.setField('abstractNote', metaData["Abstract"]);
+ if (!Utilities.isEmpty(metaData["JournalRef"])) item.setField('publicationTitle', metaData["JournalRef"]);
+ if (!Utilities.isEmpty(metaData["DOI"])) item.setField('DOI', metaData["DOI"]);
+ await item.saveTx();
+ return 0;
+ }
+};
\ No newline at end of file
diff --git a/src/chrome/content/overlay.xul b/src/chrome/content/overlay.xul
index 04550cd..beb2294 100644
--- a/src/chrome/content/overlay.xul
+++ b/src/chrome/content/overlay.xul
@@ -6,6 +6,7 @@
+
diff --git a/src/chrome/content/zotmeta.js b/src/chrome/content/zotmeta.js
index 5ed65dd..e3757ab 100644
--- a/src/chrome/content/zotmeta.js
+++ b/src/chrome/content/zotmeta.js
@@ -102,6 +102,8 @@ ZotMeta = {
status = await Book.updateMetadata(item);
} else if (item.itemTypeID === Zotero.ItemTypes.getID('journalArticle')) {
status = await Journal.updateMetadata(item);
+ } else if (item.itemTypeID === Zotero.ItemTypes.getID('preprint') && item.repository == 'arXiv') {
+ status = await Arxiv.updateMetadata(item);
} else {
status = 1;
}