From 7e3bad7390e681881ebaf7f474da4dcfd9e7187d Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Thu, 8 Mar 2018 03:50:51 -0500 Subject: [PATCH] "Undo Retrieve Metadata" and "Report Inaccurate Metadata" New context menu options for items that were recognized in the last day and that haven't been modified --- chrome/content/zotero/xpcom/recognizePDF.js | 70 ++++++++++++++++++++ chrome/content/zotero/zoteroPane.js | 55 ++++++++++++++- chrome/content/zotero/zoteroPane.xul | 2 + chrome/locale/en-US/zotero/zotero.dtd | 2 + chrome/locale/en-US/zotero/zotero.properties | 2 + 5 files changed, 130 insertions(+), 1 deletion(-) diff --git a/chrome/content/zotero/xpcom/recognizePDF.js b/chrome/content/zotero/xpcom/recognizePDF.js index b691a829bd..87d20794d1 100644 --- a/chrome/content/zotero/xpcom/recognizePDF.js +++ b/chrome/content/zotero/xpcom/recognizePDF.js @@ -26,12 +26,15 @@ Zotero.RecognizePDF = new function () { const OFFLINE_RECHECK_DELAY = 60 * 1000; const MAX_PAGES = 5; + const UNRECOGNIZE_TIMEOUT = 3600 * 1000; this.ROW_QUEUED = 1; this.ROW_PROCESSING = 2; this.ROW_FAILED = 3; this.ROW_SUCCEEDED = 4; + let _newItems = new WeakMap(); + let _listeners = {}; let _rows = []; let _queue = []; @@ -130,6 +133,72 @@ Zotero.RecognizePDF = new function () { } }; + + this.canUnrecognize = function (item) { + var threshold = UNRECOGNIZE_TIMEOUT; + var added = _newItems.get(item); + // Item must have been recognized recently, must not have been modified since it was + // created, and must have only one attachment and no other children + if (!added + || Zotero.Date.sqlToDate(added, true) < new Date() - threshold + || item.dateModified != added + || item.numAttachments(true) != 1 + || item.numChildren(true) != 1) { + _newItems.delete(item); + return false; + } + + // Child attachment must be not be in trash and must be a PDF + var attachments = Zotero.Items.get(item.getAttachments()); + if (!attachments.length || attachments[0].attachmentContentType != 'application/pdf') { + _newItems.delete(item); + return false; + } + + return true; + }; + + + this.unrecognize = async function (item) { + var attachment = Zotero.Items.get(item.getAttachments()[0]); + return Zotero.DB.executeTransaction(async function () { + let collections = item.getCollections(); + attachment.parentItemID = null + attachment.setCollections(collections); + await attachment.save(); + + await item.erase(); + }.bind(this)); + }; + + + this.report = async function (item) { + var attachment = Zotero.Items.get(item.getAttachments()[0]); + var filePath = await attachment.getFilePath(); + if (!filePath || !await OS.File.exists(filePath)) { + throw new Error("File not found when reporting metadata"); + } + + var version = Zotero.version; + var json = await extractJSON(filePath, MAX_PAGES); + var metadata = item.toJSON(); + + var data = { version, json, metadata }; + var uri = ZOTERO_CONFIG.RECOGNIZE_URL + 'report'; + return Zotero.HTTP.request( + "POST", + uri, + { + successCodes: [200, 204], + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(data) + } + ); + }; + + /** * Add item for processing * @param item @@ -301,6 +370,7 @@ Zotero.RecognizePDF = new function () { await attachment.saveTx(); } + _newItems.set(parentItem, parentItem.dateModified); return parentItem; } diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index e41b568558..1bbde4e942 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -2733,6 +2733,8 @@ var ZoteroPane = new function() 'loadReport', 'sep4', 'recognizePDF', + 'unrecognize', + 'reportMetadata', 'createParent', 'renameAttachments', 'reindexItem' @@ -2796,6 +2798,10 @@ var ZoteroPane = new function() canRecognize = false; } + if (canUnrecognize && !Zotero.RecognizePDF.canUnrecognize(item)) { + canUnrecognize = false; + } + // Show rename option only if all items are child attachments if (canRename && (!item.isAttachment() || item.isTopLevelItem() || item.attachmentLinkMode == Zotero.Attachments.LINK_MODE_LINKED_URL)) { canRename = false; @@ -2818,6 +2824,10 @@ var ZoteroPane = new function() show.push(m.recognizePDF); } + if (canUnrecognize) { + show.push(m.unrecognize); + } + if (canMarkRead) { show.push(m.toggleRead); if (markUnread) { @@ -2844,7 +2854,7 @@ var ZoteroPane = new function() } // Add in attachment separator - if (canCreateParent || canRecognize || canRename || canIndex) { + if (canCreateParent || canRecognize || canUnrecognize || canRename || canIndex) { show.push(m.sep4); } @@ -2882,6 +2892,10 @@ var ZoteroPane = new function() show.push(m.addNote, m.addAttachments, m.sep2); } + if (Zotero.RecognizePDF.canUnrecognize(item)) { + show.push(m.sep4, m.unrecognize, m.reportMetadata); + } + if (item.isAttachment()) { var showSep4 = false; @@ -4556,6 +4570,45 @@ var ZoteroPane = new function() }; + this.unrecognizeSelected = async function () { + var items = ZoteroPane.getSelectedItems(); + for (let item of items) { + await Zotero.RecognizePDF.unrecognize(item); + } + }; + + + this.reportMetadataForSelected = async function () { + var success = false; + var items = ZoteroPane.getSelectedItems(); + for (let item of items) { + try { + await Zotero.RecognizePDF.report(item); + // If at least one report was submitted, show as success + success = true; + } + catch (e) { + Zotero.logError(e); + } + } + + if (success) { + Zotero.alert( + window, + Zotero.getString('general.submitted'), + Zotero.getString('general.thanksForHelpingImprove', Zotero.clientName) + ); + } + else { + Zotero.alert( + window, + Zotero.getString('general.error'), + Zotero.getString('general.invalidResponseServer') + ); + } + }; + + this.createParentItemsFromSelected = Zotero.Promise.coroutine(function* () { if (!this.canEdit()) { this.displayCannotEditLibraryMessage(); diff --git a/chrome/content/zotero/zoteroPane.xul b/chrome/content/zotero/zoteroPane.xul index e02d0d6244..5d3734db25 100644 --- a/chrome/content/zotero/zoteroPane.xul +++ b/chrome/content/zotero/zoteroPane.xul @@ -327,6 +327,8 @@