Generalize Find Available PDF -> Find Full Text (#4397)
This commit is contained in:
parent
297af9b409
commit
7020d60351
11 changed files with 229 additions and 120 deletions
|
@ -12,6 +12,11 @@
|
||||||
style="display: flex;">
|
style="display: flex;">
|
||||||
<script src="include.js"></script>
|
<script src="include.js"></script>
|
||||||
<script src="progressQueueDialog.js"/>
|
<script src="progressQueueDialog.js"/>
|
||||||
|
|
||||||
|
<linkset>
|
||||||
|
<html:link rel="localization" href="zotero.ftl"/>
|
||||||
|
</linkset>
|
||||||
|
|
||||||
<vbox id="progress-queue-root" flex="1">
|
<vbox id="progress-queue-root" flex="1">
|
||||||
<label id="label" control="progress-indicator" value=""/>
|
<label id="label" control="progress-indicator" value=""/>
|
||||||
<hbox align="center">
|
<hbox align="center">
|
||||||
|
|
|
@ -35,8 +35,10 @@ Zotero.Attachments = new function () {
|
||||||
|
|
||||||
this.BASE_PATH_PLACEHOLDER = 'attachments:';
|
this.BASE_PATH_PLACEHOLDER = 'attachments:';
|
||||||
|
|
||||||
var _findPDFQueue = [];
|
this.FIND_AVAILABLE_FILE_TYPES = ['application/pdf', 'application/epub+zip'];
|
||||||
var _findPDFQueuePromise = null;
|
|
||||||
|
var _findFileQueue = [];
|
||||||
|
var _findFileQueuePromise = null;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -605,7 +607,7 @@ Zotero.Attachments = new function () {
|
||||||
{
|
{
|
||||||
cookieSandbox,
|
cookieSandbox,
|
||||||
referrer,
|
referrer,
|
||||||
isPDF: contentType == 'application/pdf',
|
enforceFileType: Zotero.Attachments.FIND_AVAILABLE_FILE_TYPES.includes(contentType),
|
||||||
shouldDisplayCaptcha: true
|
shouldDisplayCaptcha: true
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1090,13 +1092,13 @@ Zotero.Attachments = new function () {
|
||||||
* @param {Object} [options]
|
* @param {Object} [options]
|
||||||
* @param {Object} [options.cookieSandbox]
|
* @param {Object} [options.cookieSandbox]
|
||||||
* @param {String} [options.referrer]
|
* @param {String} [options.referrer]
|
||||||
* @param {Boolean} [options.isPDF] - Delete file if not PDF
|
* @param {Boolean} [options.enforceFileType] - Delete file if not one of SUPPORTED_FILE_TYPES
|
||||||
* @param {Boolean} [options.shouldDisplayCaptcha]
|
* @param {Boolean} [options.shouldDisplayCaptcha]
|
||||||
*/
|
*/
|
||||||
this.downloadFile = async function (url, path, options = {}) {
|
this.downloadFile = async function (url, path, options = {}) {
|
||||||
Zotero.debug(`Downloading file from ${url}`);
|
Zotero.debug(`Downloading file from ${url}`);
|
||||||
|
|
||||||
let enforcingPDF = false;
|
let enforcingFileType = false;
|
||||||
try {
|
try {
|
||||||
await new Zotero.Promise(function (resolve) {
|
await new Zotero.Promise(function (resolve) {
|
||||||
var wbp = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
var wbp = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
|
||||||
|
@ -1113,9 +1115,9 @@ Zotero.Attachments = new function () {
|
||||||
Zotero.Utilities.Internal.saveURI(wbp, url, path, headers);
|
Zotero.Utilities.Internal.saveURI(wbp, url, path, headers);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.isPDF) {
|
if (options.enforceFileType) {
|
||||||
enforcingPDF = true;
|
enforcingFileType = true;
|
||||||
await _enforcePDF(path);
|
await _enforceFileType(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
|
@ -1127,7 +1129,7 @@ Zotero.Attachments = new function () {
|
||||||
}
|
}
|
||||||
// Custom handling for PDFs that are bot-guarded
|
// Custom handling for PDFs that are bot-guarded
|
||||||
// via a JS-redirect
|
// via a JS-redirect
|
||||||
if (enforcingPDF && e instanceof this.InvalidPDFException) {
|
if (enforcingFileType && e instanceof this.InvalidPDFException) {
|
||||||
if (Zotero.BrowserDownload.shouldAttemptDownloadViaBrowser(url)) {
|
if (Zotero.BrowserDownload.shouldAttemptDownloadViaBrowser(url)) {
|
||||||
return Zotero.BrowserDownload.downloadPDF(url, path, options);
|
return Zotero.BrowserDownload.downloadPDF(url, path, options);
|
||||||
}
|
}
|
||||||
|
@ -1137,12 +1139,12 @@ Zotero.Attachments = new function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make sure a file is a PDF
|
* Make sure a file is a type we want
|
||||||
*/
|
*/
|
||||||
async function _enforcePDF(path) {
|
async function _enforceFileType(path) {
|
||||||
var sample = await Zotero.File.getContentsAsync(path, null, 1000);
|
var sample = await Zotero.File.getContentsAsync(path, null, 1000);
|
||||||
if (Zotero.MIME.sniffForMIMEType(sample) != 'application/pdf') {
|
if (!Zotero.Attachments.FIND_AVAILABLE_FILE_TYPES.includes(Zotero.MIME.sniffForMIMEType(sample))) {
|
||||||
Zotero.debug("Downloaded PDF was not a PDF", 2);
|
Zotero.debug("Downloaded file was not a supported type", 2);
|
||||||
if (Zotero.Debug.enabled) {
|
if (Zotero.Debug.enabled) {
|
||||||
Zotero.debug(
|
Zotero.debug(
|
||||||
Zotero.Utilities.ellipsize(
|
Zotero.Utilities.ellipsize(
|
||||||
|
@ -1160,29 +1162,38 @@ Zotero.Attachments = new function () {
|
||||||
|
|
||||||
|
|
||||||
this.InvalidPDFException = function() {
|
this.InvalidPDFException = function() {
|
||||||
this.message = "Downloaded PDF was not a PDF";
|
this.message = "Downloaded file was not a supported type (PDF or EPUB)";
|
||||||
this.stack = new Error().stack;
|
this.stack = new Error().stack;
|
||||||
};
|
};
|
||||||
this.InvalidPDFException.prototype = Object.create(Error.prototype);
|
this.InvalidPDFException.prototype = Object.create(Error.prototype);
|
||||||
|
|
||||||
|
|
||||||
this.canFindPDFForItem = function (item) {
|
this.canFindFileForItem = function (item) {
|
||||||
return item.isRegularItem()
|
return item.isRegularItem()
|
||||||
&& !item.isFeedItem
|
&& !item.isFeedItem
|
||||||
&& (!!item.getField('DOI') || !!item.getField('url') || !!item.getExtraField('DOI'))
|
&& (!!item.getField('DOI') || !!item.getField('url') || !!item.getExtraField('DOI'))
|
||||||
&& item.numPDFAttachments() == 0;
|
&& this.FIND_AVAILABLE_FILE_TYPES.every(type => item.numFileAttachmentsWithContentType(type) == 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use canFindFileForItem()
|
||||||
|
*/
|
||||||
|
this.canFindPDFForItem = function (item) {
|
||||||
|
Zotero.warn('Zotero.Attachments.canFindPDFForItem() is deprecated -- use canFindFileForItem()');
|
||||||
|
return this.canFindFileForItem(item);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the PDF resolvers that can be used for a given item based on the available fields
|
* Get the file resolvers that can be used for a given item based on the available fields
|
||||||
*
|
*
|
||||||
* @param {Zotero.Item} item
|
* @param {Zotero.Item} item
|
||||||
* @param {String[]} [methods=['doi', 'url', 'oa', 'custom']]
|
* @param {String[]} [methods=['doi', 'url', 'oa', 'custom']]
|
||||||
* @param {Boolean} [automatic=false] - Only include custom resolvers with `automatic: true`
|
* @param {Boolean} [automatic=false] - Only include custom resolvers with `automatic: true`
|
||||||
* @return {Object[]} - An array of urlResolvers (see downloadFirstAvailableFile())
|
* @return {Object[]} - An array of urlResolvers (see downloadFirstAvailableFile())
|
||||||
*/
|
*/
|
||||||
this.getPDFResolvers = function (item, methods, automatic) {
|
this.getFileResolvers = function (item, methods, automatic) {
|
||||||
if (!methods) {
|
if (!methods) {
|
||||||
methods = ['doi', 'url', 'oa', 'custom'];
|
methods = ['doi', 'url', 'oa', 'custom'];
|
||||||
}
|
}
|
||||||
|
@ -1242,7 +1253,7 @@ Zotero.Attachments = new function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.debug("Error parsing custom PDF resolvers", 2);
|
Zotero.debug("Error parsing custom file resolvers", 2);
|
||||||
Zotero.debug(e, 2);
|
Zotero.debug(e, 2);
|
||||||
}
|
}
|
||||||
if (customResolvers) {
|
if (customResolvers) {
|
||||||
|
@ -1294,7 +1305,7 @@ Zotero.Attachments = new function () {
|
||||||
url = url.replace(/\{doi}/, doi);
|
url = url.replace(/\{doi}/, doi);
|
||||||
|
|
||||||
resolvers.push(async function () {
|
resolvers.push(async function () {
|
||||||
Zotero.debug(`Looking for PDFs for ${doi} via ${name}`);
|
Zotero.debug(`Looking for files for ${doi} via ${name}`);
|
||||||
|
|
||||||
var req = await Zotero.HTTP.request(
|
var req = await Zotero.HTTP.request(
|
||||||
method.toUpperCase(),
|
method.toUpperCase(),
|
||||||
|
@ -1368,7 +1379,7 @@ Zotero.Attachments = new function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.debug("Error parsing PDF resolver", 2);
|
Zotero.debug("Error parsing file resolver", 2);
|
||||||
Zotero.debug(e, 2);
|
Zotero.debug(e, 2);
|
||||||
Zotero.debug(resolver, 2);
|
Zotero.debug(resolver, 2);
|
||||||
}
|
}
|
||||||
|
@ -1382,16 +1393,25 @@ Zotero.Attachments = new function () {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look for available PDFs for items and add as attachments
|
* @deprecated Use getFileResolvers()
|
||||||
|
*/
|
||||||
|
this.getPDFResolvers = function (item, methods) {
|
||||||
|
Zotero.warn('Zotero.Attachments.getPDFResolvers() is deprecated -- use getFileResolvers()');
|
||||||
|
return this.getFileResolvers(item, methods);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for available files for items and add as attachments
|
||||||
*
|
*
|
||||||
* @param {Zotero.Item[]} items
|
* @param {Zotero.Item[]} items
|
||||||
* @param {Object} [options]
|
* @param {Object} [options]
|
||||||
* @param {String[]} [options.methods] - See getPDFResolvers()
|
* @param {String[]} [options.methods] - See getFileResolvers()
|
||||||
* @param {Number} [options.sameDomainRequestDelay=1000] - Minimum number of milliseconds
|
* @param {Number} [options.sameDomainRequestDelay=1000] - Minimum number of milliseconds
|
||||||
* between requests to the same domain (used in tests)
|
* between requests to the same domain (used in tests)
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
this.addAvailablePDFs = async function (items, options = {}) {
|
this.addAvailableFiles = async function (items, options = {}) {
|
||||||
const MAX_CONSECUTIVE_DOMAIN_FAILURES = 5;
|
const MAX_CONSECUTIVE_DOMAIN_FAILURES = 5;
|
||||||
const SAME_DOMAIN_REQUEST_DELAY = options.sameDomainRequestDelay || 1000;
|
const SAME_DOMAIN_REQUEST_DELAY = options.sameDomainRequestDelay || 1000;
|
||||||
var queue;
|
var queue;
|
||||||
|
@ -1409,33 +1429,33 @@ Zotero.Attachments = new function () {
|
||||||
return domainInfo;
|
return domainInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
var progressQueue = Zotero.ProgressQueues.get('findPDF');
|
var progressQueue = Zotero.ProgressQueues.get('findFile');
|
||||||
if (!progressQueue) {
|
if (!progressQueue) {
|
||||||
progressQueue = Zotero.ProgressQueues.create({
|
progressQueue = Zotero.ProgressQueues.create({
|
||||||
id: 'findPDF',
|
id: 'findFile',
|
||||||
title: 'pane.items.menu.findAvailablePDF.multiple',
|
title: 'pane.items.menu.findAvailableFile',
|
||||||
columns: [
|
columns: [
|
||||||
'general.item',
|
'general.item',
|
||||||
'general.pdf'
|
'attachment.fullText'
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
progressQueue.addListener('cancel', () => queue = []);
|
progressQueue.addListener('cancel', () => queue = []);
|
||||||
}
|
}
|
||||||
|
|
||||||
queue = _findPDFQueue;
|
queue = _findFileQueue;
|
||||||
|
|
||||||
for (let item of items) {
|
for (let item of items) {
|
||||||
// Skip items that aren't eligible. This is sort of weird, because it means some
|
// Skip items that aren't eligible. This is sort of weird, because it means some
|
||||||
// selected items just don't appear in the list, but there are several different reasons
|
// selected items just don't appear in the list, but there are several different reasons
|
||||||
// why items might not be eligible (non-regular items, no URL or DOI, already has a PDF)
|
// why items might not be eligible (non-regular items, no URL or DOI, already has a
|
||||||
// and listing each one seems a little unnecessary.
|
// full-text attachment) and listing each one seems a little unnecessary.
|
||||||
if (!this.canFindPDFForItem(item)) {
|
if (!this.canFindFileForItem(item)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let entry = {
|
let entry = {
|
||||||
item,
|
item,
|
||||||
urlResolvers: this.getPDFResolvers(item, options.methods),
|
urlResolvers: this.getFileResolvers(item, options.methods),
|
||||||
domain: null,
|
domain: null,
|
||||||
continuation: null,
|
continuation: null,
|
||||||
processing: false,
|
processing: false,
|
||||||
|
@ -1460,14 +1480,14 @@ Zotero.Attachments = new function () {
|
||||||
progressQueue.addRow(item);
|
progressQueue.addRow(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no eligible items, just show a popup saying no PDFs were found
|
// If no eligible items, just show a popup saying no files were found
|
||||||
if (!queue.length) {
|
if (!queue.length) {
|
||||||
let progressWin = new Zotero.ProgressWindow();
|
let progressWin = new Zotero.ProgressWindow();
|
||||||
let title = Zotero.getString('pane.items.menu.findAvailablePDF.multiple');
|
let title = Zotero.getString('pane.items.menu.findAvailableFile');
|
||||||
progressWin.changeHeadline(title);
|
progressWin.changeHeadline(title);
|
||||||
let itemProgress = new progressWin.ItemProgress(
|
let itemProgress = new progressWin.ItemProgress(
|
||||||
'attachmentPDF',
|
'attachmentPDF',
|
||||||
Zotero.getString('findPDF.noPDFsFound')
|
Zotero.getString('findPDF.noFilesFound')
|
||||||
);
|
);
|
||||||
progressWin.show();
|
progressWin.show();
|
||||||
itemProgress.setProgress(100);
|
itemProgress.setProgress(100);
|
||||||
|
@ -1480,12 +1500,12 @@ Zotero.Attachments = new function () {
|
||||||
dialog.open();
|
dialog.open();
|
||||||
|
|
||||||
// If queue was already in progress, just wait for it to finish
|
// If queue was already in progress, just wait for it to finish
|
||||||
if (_findPDFQueuePromise) {
|
if (_findFileQueuePromise) {
|
||||||
return _findPDFQueuePromise;
|
return _findFileQueuePromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
var queueResolve;
|
var queueResolve;
|
||||||
_findPDFQueuePromise = new Zotero.Promise((resolve) => {
|
_findFileQueuePromise = new Zotero.Promise((resolve) => {
|
||||||
queueResolve = resolve;
|
queueResolve = resolve;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1537,7 +1557,7 @@ Zotero.Attachments = new function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently filtered out above
|
// Currently filtered out above
|
||||||
/*if (!this.canFindPDFForItem(current.item)) {
|
/*if (!this.canFindFileForItem(current.item)) {
|
||||||
current.result = false;
|
current.result = false;
|
||||||
progressQueue.updateRow(
|
progressQueue.updateRow(
|
||||||
current.item.id,
|
current.item.id,
|
||||||
|
@ -1551,7 +1571,7 @@ Zotero.Attachments = new function () {
|
||||||
current.processing = true;
|
current.processing = true;
|
||||||
|
|
||||||
// Process item
|
// Process item
|
||||||
this.addPDFFromURLs(
|
this.addFileFromURLs(
|
||||||
current.item,
|
current.item,
|
||||||
current.urlResolvers,
|
current.urlResolvers,
|
||||||
{
|
{
|
||||||
|
@ -1664,7 +1684,7 @@ Zotero.Attachments = new function () {
|
||||||
: Zotero.ProgressQueue.ROW_FAILED,
|
: Zotero.ProgressQueue.ROW_FAILED,
|
||||||
attachment
|
attachment
|
||||||
? attachment.getField('title')
|
? attachment.getField('title')
|
||||||
: Zotero.getString('findPDF.noPDFFound')
|
: Zotero.getString('findPDF.noFileFound')
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
|
@ -1687,17 +1707,26 @@ Zotero.Attachments = new function () {
|
||||||
processNextItem();
|
processNextItem();
|
||||||
});
|
});
|
||||||
|
|
||||||
var numPDFs = queue.reduce((accumulator, currentValue) => {
|
var numFiles = queue.reduce((accumulator, currentValue) => {
|
||||||
return accumulator + (currentValue.result ? 1 : 0);
|
return accumulator + (currentValue.result ? 1 : 0);
|
||||||
}, 0);
|
}, 0);
|
||||||
dialog.setStatus(
|
dialog.setStatus(
|
||||||
numPDFs
|
numFiles
|
||||||
? Zotero.getString('findPDF.pdfsAdded', numPDFs, numPDFs)
|
? { l10nId: 'find-pdf-files-added', l10nArgs: { count: numFiles } }
|
||||||
: Zotero.getString('findPDF.noPDFsFound')
|
: Zotero.getString('findPDF.noFilesFound')
|
||||||
);
|
);
|
||||||
_findPDFQueue = [];
|
_findFileQueue = [];
|
||||||
queueResolve();
|
queueResolve();
|
||||||
_findPDFQueuePromise = null;
|
_findFileQueuePromise = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use addAvailableFiles()
|
||||||
|
*/
|
||||||
|
this.addAvailablePDFs = function (items, options) {
|
||||||
|
Zotero.warn('Zotero.Attachments.addAvailablePDFs() is deprecated -- use addAvailableFiles()');
|
||||||
|
return this.addAvailableFiles(items, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1714,14 +1743,23 @@ Zotero.Attachments = new function () {
|
||||||
* @param {String[]} [options.methods] - See getPDFResolvers()
|
* @param {String[]} [options.methods] - See getPDFResolvers()
|
||||||
* @return {Zotero.Item|false} - New Zotero.Item, or false if unsuccessful
|
* @return {Zotero.Item|false} - New Zotero.Item, or false if unsuccessful
|
||||||
*/
|
*/
|
||||||
this.addAvailablePDF = async function (item, options = {}) {
|
this.addAvailableFile = async function (item, options = {}) {
|
||||||
Zotero.debug("Looking for available PDFs");
|
Zotero.debug("Looking for available files");
|
||||||
return this.addPDFFromURLs(item, this.getPDFResolvers(item, options.methods));
|
return this.addFileFromURLs(item, this.getFileResolvers(item, options.methods));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to add a PDF to an item from a set of URL resolvers
|
* @deprecated Use addAvailableFile()
|
||||||
|
*/
|
||||||
|
this.addAvailablePDF = function (item, options) {
|
||||||
|
Zotero.warn('Zotero.Attachments.addAvailablePDF() is deprecated -- use addAvailableFile()');
|
||||||
|
return this.addAvailableFile(item, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to add a file attachment to an item from a set of URL resolvers
|
||||||
*
|
*
|
||||||
* @param {Zotero.Item} item
|
* @param {Zotero.Item} item
|
||||||
* @param {(String|Object|Function)[]} urlResolvers - See downloadFirstAvailableFile()
|
* @param {(String|Object|Function)[]} urlResolvers - See downloadFirstAvailableFile()
|
||||||
|
@ -1730,19 +1768,19 @@ Zotero.Attachments = new function () {
|
||||||
* is started, taking the access method name as an argument
|
* is started, taking the access method name as an argument
|
||||||
* @return {Zotero.Item|false} - New Zotero.Item, or false if unsuccessful
|
* @return {Zotero.Item|false} - New Zotero.Item, or false if unsuccessful
|
||||||
*/
|
*/
|
||||||
this.addPDFFromURLs = async function (item, urlResolvers, options = {}) {
|
this.addFileFromURLs = async function (item, urlResolvers, options = {}) {
|
||||||
var fileBaseName = this.getFileBaseNameFromItem(item);
|
var fileBaseName = this.getFileBaseNameFromItem(item);
|
||||||
var tmpDir;
|
var tmpDir;
|
||||||
var tmpFile;
|
var tmpFile;
|
||||||
var attachmentItem = false;
|
var attachmentItem = false;
|
||||||
try {
|
try {
|
||||||
tmpDir = (await this.createTemporaryStorageDirectory()).path;
|
tmpDir = (await this.createTemporaryStorageDirectory()).path;
|
||||||
tmpFile = OS.Path.join(tmpDir, fileBaseName + '.pdf');
|
tmpFile = OS.Path.join(tmpDir, fileBaseName + '.tmp');
|
||||||
let { title, url, props } = await this.downloadFirstAvailableFile(
|
let { title, mimeType, url, props } = await this.downloadFirstAvailableFile(
|
||||||
urlResolvers,
|
urlResolvers,
|
||||||
tmpFile,
|
tmpFile,
|
||||||
{
|
{
|
||||||
isPDF: true,
|
enforceFileType: true,
|
||||||
shouldDisplayCaptcha: true,
|
shouldDisplayCaptcha: true,
|
||||||
onAccessMethodStart: options.onAccessMethodStart,
|
onAccessMethodStart: options.onAccessMethodStart,
|
||||||
onBeforeRequest: options.onBeforeRequest,
|
onBeforeRequest: options.onBeforeRequest,
|
||||||
|
@ -1750,13 +1788,21 @@ Zotero.Attachments = new function () {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (url) {
|
if (url) {
|
||||||
|
if (!mimeType) {
|
||||||
|
mimeType = await Zotero.MIME.getMIMETypeFromFile(tmpFile);
|
||||||
|
}
|
||||||
|
if (!this.FIND_AVAILABLE_FILE_TYPES.includes(mimeType)) {
|
||||||
|
throw new Error(`Resolved file is unsupported type ${mimeType}`);
|
||||||
|
}
|
||||||
|
let filename = fileBaseName + '.' + (Zotero.MIME.getPrimaryExtension(mimeType) || 'dat');
|
||||||
|
await IOUtils.move(tmpFile, PathUtils.join(tmpDir, filename));
|
||||||
attachmentItem = await this.createURLAttachmentFromTemporaryStorageDirectory({
|
attachmentItem = await this.createURLAttachmentFromTemporaryStorageDirectory({
|
||||||
directory: tmpDir,
|
directory: tmpDir,
|
||||||
libraryID: item.libraryID,
|
libraryID: item.libraryID,
|
||||||
filename: PathUtils.filename(tmpFile),
|
filename,
|
||||||
title: title || _getPDFTitleFromVersion(props.articleVersion),
|
title: title || _getTitleFromVersion(props.articleVersion),
|
||||||
url,
|
url,
|
||||||
contentType: 'application/pdf',
|
contentType: mimeType,
|
||||||
parentItemID: item.id
|
parentItemID: item.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1775,7 +1821,16 @@ Zotero.Attachments = new function () {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function _getPDFTitleFromVersion(version) {
|
/**
|
||||||
|
* @deprecated Use addFileFromURLs()
|
||||||
|
*/
|
||||||
|
this.addPDFFromURLs = function (item, urlResolvers, options) {
|
||||||
|
Zotero.warn('Zotero.Attachments.addPDFFromURLs() is deprecated -- use addFileFromURLs()');
|
||||||
|
return this.addFileFromURLs(item, urlResolvers, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function _getTitleFromVersion(version) {
|
||||||
var str;
|
var str;
|
||||||
|
|
||||||
switch (version) {
|
switch (version) {
|
||||||
|
@ -1805,7 +1860,7 @@ Zotero.Attachments = new function () {
|
||||||
*
|
*
|
||||||
* @param {(String|Object|Function)[]} urlResolvers - An array of URLs, objects, or functions
|
* @param {(String|Object|Function)[]} urlResolvers - An array of URLs, objects, or functions
|
||||||
* that return arrays of objects. Objects should contain 'url' and/or 'pageURL' (the latter
|
* that return arrays of objects. Objects should contain 'url' and/or 'pageURL' (the latter
|
||||||
* being a webpage that might contain a translatable PDF link), 'accessMethod' (which will
|
* being a webpage that might contain a translatable file link), 'accessMethod' (which will
|
||||||
* be displayed in the save popup), and an optional 'articleVersion' ('submittedVersion',
|
* be displayed in the save popup), and an optional 'articleVersion' ('submittedVersion',
|
||||||
* 'acceptedVersion', or 'publishedVersion'). Functions that return promises are waited for,
|
* 'acceptedVersion', or 'publishedVersion'). Functions that return promises are waited for,
|
||||||
* and functions aren't called unless a file hasn't yet been found from an earlier entry.
|
* and functions aren't called unless a file hasn't yet been found from an earlier entry.
|
||||||
|
@ -1815,8 +1870,8 @@ Zotero.Attachments = new function () {
|
||||||
* @param {Function} [options.onAfterRequest] - Function that runs after a request
|
* @param {Function} [options.onAfterRequest] - Function that runs after a request
|
||||||
* @param {Function} [options.onRequestError] - Function that runs when a request fails.
|
* @param {Function} [options.onRequestError] - Function that runs when a request fails.
|
||||||
* Return true to retry request and false to skip.
|
* Return true to retry request and false to skip.
|
||||||
* @return {Object|false} - Object with successful 'title' (when available from translator), 'url', and 'props'
|
* @return {Object|false} - Object with successful 'title' and 'mimeType' (when available from translator), 'url',
|
||||||
* from the associated urlResolver, or false if no file could be downloaded
|
* and 'props' from the associated urlResolver, or false if no file could be downloaded
|
||||||
*/
|
*/
|
||||||
this.downloadFirstAvailableFile = async function (urlResolvers, path, options) {
|
this.downloadFirstAvailableFile = async function (urlResolvers, path, options) {
|
||||||
const maxURLs = 6;
|
const maxURLs = 6;
|
||||||
|
@ -1900,7 +1955,7 @@ Zotero.Attachments = new function () {
|
||||||
|
|
||||||
// Ignore URLs we've already tried
|
// Ignore URLs we've already tried
|
||||||
if (url && isTriedURL(url)) {
|
if (url && isTriedURL(url)) {
|
||||||
Zotero.debug(`PDF at ${url} was already tried -- skipping`);
|
Zotero.debug(`File at ${url} was already tried -- skipping`);
|
||||||
url = null;
|
url = null;
|
||||||
}
|
}
|
||||||
if (pageURL && isTriedURL(pageURL)) {
|
if (pageURL && isTriedURL(pageURL)) {
|
||||||
|
@ -1946,9 +2001,10 @@ Zotero.Attachments = new function () {
|
||||||
if (pageURL) {
|
if (pageURL) {
|
||||||
url = null;
|
url = null;
|
||||||
let title = null;
|
let title = null;
|
||||||
|
let mimeType = null;
|
||||||
let responseURL;
|
let responseURL;
|
||||||
try {
|
try {
|
||||||
Zotero.debug(`Looking for PDF on ${pageURL}`);
|
Zotero.debug(`Looking for file on ${pageURL}`);
|
||||||
|
|
||||||
let redirects = 0;
|
let redirects = 0;
|
||||||
let nextURL = pageURL;
|
let nextURL = pageURL;
|
||||||
|
@ -2060,7 +2116,7 @@ Zotero.Attachments = new function () {
|
||||||
// use redirects plus cookies for IP-based authentication [1]. The downside
|
// use redirects plus cookies for IP-based authentication [1]. The downside
|
||||||
// is that we might follow the same set of redirects more than once, but we
|
// is that we might follow the same set of redirects more than once, but we
|
||||||
// won't process the final page multiple times, and if a publisher URL does
|
// won't process the final page multiple times, and if a publisher URL does
|
||||||
// redirect that's hopefully a decent indication that a PDF will be found
|
// redirect that's hopefully a decent indication that a file will be found
|
||||||
// the first time around.
|
// the first time around.
|
||||||
//
|
//
|
||||||
// [1] https://forums.zotero.org/discussion/81182
|
// [1] https://forums.zotero.org/discussion/81182
|
||||||
|
@ -2072,31 +2128,31 @@ Zotero.Attachments = new function () {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If DOI resolves directly to a PDF, save it to disk
|
// If DOI resolves directly to a file, save it to disk
|
||||||
if (contentType && contentType.startsWith('application/pdf')) {
|
if (contentType && this.FIND_AVAILABLE_FILE_TYPES.some(type => contentType.startsWith(type))) {
|
||||||
Zotero.debug("URL resolves directly to PDF");
|
Zotero.debug("URL resolves directly to file");
|
||||||
await Zotero.File.putContentsAsync(path, blob);
|
await Zotero.File.putContentsAsync(path, blob);
|
||||||
await _enforcePDF(path);
|
await _enforceFileType(path);
|
||||||
return { url: responseURL, props: urlResolver };
|
return { url: responseURL, props: urlResolver };
|
||||||
}
|
}
|
||||||
// Otherwise translate the Document we parsed above
|
// Otherwise translate the Document we parsed above
|
||||||
else if (doc) {
|
else if (doc) {
|
||||||
({ title, url } = await Zotero.Utilities.Internal.getPDFFromDocument(doc));
|
({ title, mimeType, url } = await Zotero.Utilities.Internal.getFileFromDocument(doc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.debug(`Error getting PDF from ${pageURL}: ${e}\n\n${e.stack}`);
|
Zotero.debug(`Error getting file from ${pageURL}: ${e}\n\n${e.stack}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!url) {
|
if (!url) {
|
||||||
Zotero.debug(`No PDF found on ${responseURL || pageURL}`);
|
Zotero.debug(`No file found on ${responseURL || pageURL}`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (isTriedURL(url)) {
|
if (isTriedURL(url)) {
|
||||||
Zotero.debug(`PDF at ${url} was already tried -- skipping`);
|
Zotero.debug(`File at ${url} was already tried -- skipping`);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Don't try this PDF URL again
|
// Don't try this file URL again
|
||||||
addTriedURL(url);
|
addTriedURL(url);
|
||||||
|
|
||||||
// Use the page we loaded as the referrer
|
// Use the page we loaded as the referrer
|
||||||
|
@ -2108,7 +2164,7 @@ Zotero.Attachments = new function () {
|
||||||
await beforeRequest(url);
|
await beforeRequest(url);
|
||||||
await this.downloadFile(url, path, downloadOptions);
|
await this.downloadFile(url, path, downloadOptions);
|
||||||
afterRequest(url);
|
afterRequest(url);
|
||||||
return { title, url, props: urlResolver };
|
return { title, mimeType, url, props: urlResolver };
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
Zotero.debug(`Error downloading ${url}: ${e}\n\n${e.stack}`);
|
Zotero.debug(`Error downloading ${url}: ${e}\n\n${e.stack}`);
|
||||||
|
@ -2128,7 +2184,7 @@ Zotero.Attachments = new function () {
|
||||||
* @deprecated Use Zotero.Utilities.cleanURL instead
|
* @deprecated Use Zotero.Utilities.cleanURL instead
|
||||||
*/
|
*/
|
||||||
this.cleanAttachmentURI = function (uri, tryHttp) {
|
this.cleanAttachmentURI = function (uri, tryHttp) {
|
||||||
Zotero.debug("Zotero.Attachments.cleanAttachmentURI() is deprecated -- use Zotero.Utilities.cleanURL");
|
Zotero.warn("Zotero.Attachments.cleanAttachmentURI() is deprecated -- use Zotero.Utilities.cleanURL");
|
||||||
return Zotero.Utilities.cleanURL(uri, tryHttp);
|
return Zotero.Utilities.cleanURL(uri, tryHttp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,12 @@ Zotero.ProgressQueueDialog = function (progressQueue) {
|
||||||
if (_progressWindow) {
|
if (_progressWindow) {
|
||||||
let label = _progressWindow.document.getElementById("label");
|
let label = _progressWindow.document.getElementById("label");
|
||||||
if (label) {
|
if (label) {
|
||||||
label.value = msg;
|
if (typeof msg === 'object' && 'l10nId' in msg) {
|
||||||
|
_progressWindow.document.l10n.setAttributes(label, msg.l10nId, msg.l10nArgs);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
label.value = msg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -305,7 +305,7 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
// No translated, no OA, just potential custom, so create a status line
|
// No translated, no OA, just potential custom, so create a status line
|
||||||
if (!jsonAttachment) {
|
if (!jsonAttachment) {
|
||||||
jsonAttachment = this._makeJSONAttachment(
|
jsonAttachment = this._makeJSONAttachment(
|
||||||
jsonItem.id, Zotero.getString('findPDF.searchingForAvailablePDFs')
|
jsonItem.id, Zotero.getString('findPDF.searchingForAvailableFiles')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ Zotero.Translate.ItemSaver.prototype = {
|
||||||
|
|
||||||
let attachment;
|
let attachment;
|
||||||
try {
|
try {
|
||||||
attachment = await Zotero.Attachments.addPDFFromURLs(
|
attachment = await Zotero.Attachments.addFileFromURLs(
|
||||||
item,
|
item,
|
||||||
resolvers,
|
resolvers,
|
||||||
{
|
{
|
||||||
|
|
|
@ -1336,7 +1336,7 @@ Zotero.Utilities.Internal = {
|
||||||
* @param {doc} Document
|
* @param {doc} Document
|
||||||
* @return {{ title: string, url: string } | false} - PDF attachment title and URL, or false if none found
|
* @return {{ title: string, url: string } | false} - PDF attachment title and URL, or false if none found
|
||||||
*/
|
*/
|
||||||
getPDFFromDocument: async function (doc) {
|
getFileFromDocument: async function (doc) {
|
||||||
let translate = new Zotero.Translate.Web();
|
let translate = new Zotero.Translate.Web();
|
||||||
translate.setDocument(doc);
|
translate.setDocument(doc);
|
||||||
var translators = await translate.getTranslators();
|
var translators = await translate.getTranslators();
|
||||||
|
@ -1354,14 +1354,24 @@ Zotero.Utilities.Internal = {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (let attachment of newItems[0].attachments) {
|
for (let attachment of newItems[0].attachments) {
|
||||||
if (attachment.mimeType == 'application/pdf') {
|
if (Zotero.Attachments.FIND_AVAILABLE_FILE_TYPES.includes(attachment.mimeType)) {
|
||||||
return { title: attachment.title, url: attachment.url };
|
return {
|
||||||
|
title: attachment.title,
|
||||||
|
mimeType: attachment.mimeType,
|
||||||
|
url: attachment.url
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
getPDFFromDocument(doc) {
|
||||||
|
Zotero.debug('Zotero.Utilities.Internal.getPDFFromDocument() is deprecated -- use getFileFromDocument()');
|
||||||
|
return this.getFileFromDocument(doc);
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hyphenate an ISBN based on the registrant table available from
|
* Hyphenate an ISBN based on the registrant table available from
|
||||||
* https://www.isbn-international.org/range_file_generation
|
* https://www.isbn-international.org/range_file_generation
|
||||||
|
|
|
@ -3499,7 +3499,7 @@ var ZoteroPane = new function()
|
||||||
'createNoteFromAnnotations',
|
'createNoteFromAnnotations',
|
||||||
'addAttachments',
|
'addAttachments',
|
||||||
'sep2',
|
'sep2',
|
||||||
'findPDF',
|
'findFile',
|
||||||
'sep3',
|
'sep3',
|
||||||
'toggleRead',
|
'toggleRead',
|
||||||
'addToCollection',
|
'addToCollection',
|
||||||
|
@ -3659,7 +3659,7 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.some(item => item.isRegularItem())) {
|
if (items.some(item => item.isRegularItem())) {
|
||||||
show.add(m.findPDF);
|
show.add(m.findFile);
|
||||||
show.add(m.sep3);
|
show.add(m.sep3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3747,11 +3747,11 @@ var ZoteroPane = new function()
|
||||||
menuitem.setAttribute('label', Zotero.getString(str));
|
menuitem.setAttribute('label', Zotero.getString(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Zotero.Attachments.canFindPDFForItem(item)) {
|
if (Zotero.Attachments.canFindFileForItem(item)) {
|
||||||
show.add(m.findPDF);
|
show.add(m.findFile);
|
||||||
show.add(m.sep3);
|
show.add(m.sep3);
|
||||||
if (!collectionTreeRow.filesEditable) {
|
if (!collectionTreeRow.filesEditable) {
|
||||||
disable.add(m.findPDF);
|
disable.add(m.findFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3939,7 +3939,7 @@ var ZoteroPane = new function()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set labels, plural if necessary
|
// Set labels, plural if necessary
|
||||||
menu.childNodes[m.findPDF].setAttribute('label', Zotero.getString('pane.items.menu.findAvailablePDF' + multiple));
|
menu.childNodes[m.findFile].setAttribute('label', Zotero.getString('pane.items.menu.findAvailableFile'));
|
||||||
menu.childNodes[m.moveToTrash].setAttribute('label', Zotero.getString('pane.items.menu.moveToTrash' + multiple));
|
menu.childNodes[m.moveToTrash].setAttribute('label', Zotero.getString('pane.items.menu.moveToTrash' + multiple));
|
||||||
menu.childNodes[m.deleteFromLibrary].setAttribute('label', Zotero.getString('pane.items.menu.delete'));
|
menu.childNodes[m.deleteFromLibrary].setAttribute('label', Zotero.getString('pane.items.menu.delete'));
|
||||||
menu.childNodes[m.exportItems].setAttribute('label', Zotero.getString(`pane.items.menu.export${noteExport ? 'Note' : ''}` + multiple));
|
menu.childNodes[m.exportItems].setAttribute('label', Zotero.getString(`pane.items.menu.export${noteExport ? 'Note' : ''}` + multiple));
|
||||||
|
@ -4428,12 +4428,12 @@ var ZoteroPane = new function()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.findPDFForSelectedItems = async function () {
|
this.findFilesForSelectedItems = async function () {
|
||||||
if (!this.canEdit()) {
|
if (!this.canEdit()) {
|
||||||
this.displayCannotEditLibraryMessage();
|
this.displayCannotEditLibraryMessage();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await Zotero.Attachments.addAvailablePDFs(this.getSelectedItems());
|
await Zotero.Attachments.addAvailableFiles(this.getSelectedItems());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -958,7 +958,7 @@
|
||||||
</menupopup>
|
</menupopup>
|
||||||
</menu>
|
</menu>
|
||||||
<menuseparator/>
|
<menuseparator/>
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-find-pdf" oncommand="ZoteroPane.findPDFForSelectedItems()"/>
|
<menuitem class="menuitem-iconic zotero-menuitem-find-pdf" oncommand="ZoteroPane.findFilesForSelectedItems()"/>
|
||||||
<menuseparator/>
|
<menuseparator/>
|
||||||
<menuitem class="menuitem-iconic zotero-menuitem-toggle-read-item" oncommand="ZoteroPane_Local.toggleSelectedItemsRead();"/>
|
<menuitem class="menuitem-iconic zotero-menuitem-toggle-read-item" oncommand="ZoteroPane_Local.toggleSelectedItemsRead();"/>
|
||||||
<menu class="menu-iconic zotero-menuitem-add-to-collection">
|
<menu class="menu-iconic zotero-menuitem-add-to-collection">
|
||||||
|
|
|
@ -651,3 +651,8 @@ advanced-search-operators-menu =
|
||||||
advanced-search-condition-input =
|
advanced-search-condition-input =
|
||||||
.aria-label = Value
|
.aria-label = Value
|
||||||
.label = { $label }
|
.label = { $label }
|
||||||
|
|
||||||
|
find-pdf-files-added = { $count ->
|
||||||
|
[one] { $count } file added
|
||||||
|
*[other] { $count } files added
|
||||||
|
}
|
||||||
|
|
|
@ -343,8 +343,7 @@ pane.items.removeRecursive = Are you sure you want to remove the selected item f
|
||||||
pane.items.removeRecursive.multiple = Are you sure you want to remove the selected items from this collection and all subcollections?
|
pane.items.removeRecursive.multiple = Are you sure you want to remove the selected items from this collection and all subcollections?
|
||||||
pane.items.menu.addNoteFromAnnotations = Add Note from Annotations
|
pane.items.menu.addNoteFromAnnotations = Add Note from Annotations
|
||||||
pane.items.menu.createNoteFromAnnotations = Create Note from Annotations
|
pane.items.menu.createNoteFromAnnotations = Create Note from Annotations
|
||||||
pane.items.menu.findAvailablePDF = Find Available PDF
|
pane.items.menu.findAvailableFile = Find Full Text
|
||||||
pane.items.menu.findAvailablePDF.multiple = Find Available PDFs
|
|
||||||
pane.items.menu.addToCollection = Add to Collection
|
pane.items.menu.addToCollection = Add to Collection
|
||||||
pane.items.menu.remove = Remove Item from Collection…
|
pane.items.menu.remove = Remove Item from Collection…
|
||||||
pane.items.menu.remove.multiple = Remove Items from Collection…
|
pane.items.menu.remove.multiple = Remove Items from Collection…
|
||||||
|
@ -674,13 +673,12 @@ ingester.importFile.intoNewCollection = Import into new collection
|
||||||
ingester.lookup.performing = Performing Lookup…
|
ingester.lookup.performing = Performing Lookup…
|
||||||
ingester.lookup.error = An error occurred while performing lookup for this item.
|
ingester.lookup.error = An error occurred while performing lookup for this item.
|
||||||
|
|
||||||
findPDF.searchingForAvailablePDFs = Searching for available PDFs…
|
findPDF.searchingForAvailableFiles = Searching for available files…
|
||||||
findPDF.checkingItems = Checking %1$S item;Checking %1$S items
|
findPDF.checkingItems = Checking %1$S item;Checking %1$S items
|
||||||
findPDF.pdfsAdded = %1$S PDF added;%1$S PDFs added
|
|
||||||
findPDF.openAccessPDF = Open-Access PDF
|
findPDF.openAccessPDF = Open-Access PDF
|
||||||
findPDF.pdfWithMethod = PDF (%S)
|
findPDF.pdfWithMethod = PDF (%S)
|
||||||
findPDF.noPDFsFound = No PDFs found
|
findPDF.noFilesFound = No files found
|
||||||
findPDF.noPDFFound = No PDF found
|
findPDF.noFileFound = No file found
|
||||||
|
|
||||||
attachment.fullText = Full Text
|
attachment.fullText = Full Text
|
||||||
attachment.acceptedVersion = Accepted Version
|
attachment.acceptedVersion = Accepted Version
|
||||||
|
|
|
@ -5,7 +5,7 @@ $item-type-icons: (
|
||||||
attachments-snapshot: "attachment-snapshot",
|
attachments-snapshot: "attachment-snapshot",
|
||||||
attachments-epub: "attachment-epub",
|
attachments-epub: "attachment-epub",
|
||||||
attach-note: "note",
|
attach-note: "note",
|
||||||
find-pdf: "attachment-pdf",
|
find-file: "attachment-pdf",
|
||||||
convert-to-book-section: "book-section",
|
convert-to-book-section: "book-section",
|
||||||
convert-to-book: "book",
|
convert-to-book: "book",
|
||||||
);
|
);
|
||||||
|
|
|
@ -609,7 +609,7 @@ describe("Zotero.Attachments", function() {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Find Available PDF", function () {
|
describe("Find Full Text", function () {
|
||||||
var doiPrefix = 'https://doi.org/';
|
var doiPrefix = 'https://doi.org/';
|
||||||
var doi1 = '10.1111/abcd';
|
var doi1 = '10.1111/abcd';
|
||||||
var doi2 = '10.2222/bcde';
|
var doi2 = '10.2222/bcde';
|
||||||
|
@ -627,6 +627,7 @@ describe("Zotero.Attachments", function() {
|
||||||
var pageURL8 = 'http://website2/article8';
|
var pageURL8 = 'http://website2/article8';
|
||||||
var pageURL9 = 'http://website/article9';
|
var pageURL9 = 'http://website/article9';
|
||||||
var pageURL10 = 'http://website/refresh';
|
var pageURL10 = 'http://website/refresh';
|
||||||
|
var pageURL11 = 'http://website/book';
|
||||||
|
|
||||||
var httpd;
|
var httpd;
|
||||||
var port = 16213;
|
var port = 16213;
|
||||||
|
@ -634,6 +635,9 @@ describe("Zotero.Attachments", function() {
|
||||||
var pdfPath = OS.Path.join(getTestDataDirectory().path, 'test.pdf');
|
var pdfPath = OS.Path.join(getTestDataDirectory().path, 'test.pdf');
|
||||||
var pdfURL = `${baseURL}article1/pdf`;
|
var pdfURL = `${baseURL}article1/pdf`;
|
||||||
var pdfSize;
|
var pdfSize;
|
||||||
|
var epubPath = OS.Path.join(getTestDataDirectory().path, 'stub.epub');
|
||||||
|
var epubURL = `${baseURL}article11/epub`;
|
||||||
|
var epubSize;
|
||||||
var requestStub;
|
var requestStub;
|
||||||
var requestStubCallTimes = [];
|
var requestStubCallTimes = [];
|
||||||
var return429 = true;
|
var return429 = true;
|
||||||
|
@ -713,6 +717,7 @@ describe("Zotero.Attachments", function() {
|
||||||
// DOI 6 redirects to page 8, which is on a different domain and has a PDF
|
// DOI 6 redirects to page 8, which is on a different domain and has a PDF
|
||||||
[doiPrefix + doi6, pageURL8, true],
|
[doiPrefix + doi6, pageURL8, true],
|
||||||
[pageURL8, pageURL8, true],
|
[pageURL8, pageURL8, true],
|
||||||
|
[pageURL11, epubURL, false],
|
||||||
|
|
||||||
// Redirect loop
|
// Redirect loop
|
||||||
['http://website/redirect_loop1', 'http://website/redirect_loop2', false],
|
['http://website/redirect_loop1', 'http://website/redirect_loop2', false],
|
||||||
|
@ -857,6 +862,7 @@ describe("Zotero.Attachments", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
pdfSize = await OS.File.stat(pdfPath).size;
|
pdfSize = await OS.File.stat(pdfPath).size;
|
||||||
|
epubSize = await OS.File.stat(epubPath).size;
|
||||||
|
|
||||||
Zotero.Prefs.clear('findPDFs.resolvers');
|
Zotero.Prefs.clear('findPDFs.resolvers');
|
||||||
});
|
});
|
||||||
|
@ -864,8 +870,12 @@ describe("Zotero.Attachments", function() {
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
({ httpd } = await startHTTPServer(port));
|
({ httpd } = await startHTTPServer(port));
|
||||||
httpd.registerFile(
|
httpd.registerFile(
|
||||||
pdfURL.substr(baseURL.length - 1),
|
pdfURL.substring(baseURL.length - 1),
|
||||||
Zotero.File.pathToFile(OS.Path.join(getTestDataDirectory().path, 'test.pdf'))
|
Zotero.File.pathToFile(pdfPath)
|
||||||
|
);
|
||||||
|
httpd.registerFile(
|
||||||
|
epubURL.substring(baseURL.length - 1),
|
||||||
|
Zotero.File.pathToFile(epubPath)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Generate a page with a relative PDF URL
|
// Generate a page with a relative PDF URL
|
||||||
|
@ -897,7 +907,7 @@ describe("Zotero.Attachments", function() {
|
||||||
Zotero.Prefs.clear('findPDFs.resolvers');
|
Zotero.Prefs.clear('findPDFs.resolvers');
|
||||||
|
|
||||||
// Close progress dialog after each run
|
// Close progress dialog after each run
|
||||||
var queue = Zotero.ProgressQueues.get('findPDF');
|
var queue = Zotero.ProgressQueues.get('findFile');
|
||||||
if (queue) {
|
if (queue) {
|
||||||
queue.getDialog().close();
|
queue.getDialog().close();
|
||||||
}
|
}
|
||||||
|
@ -913,7 +923,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item.setField('title', 'Test');
|
item.setField('title', 'Test');
|
||||||
item.setField('DOI', doi);
|
item.setField('DOI', doi);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 2);
|
assert.equal(requestStub.callCount, 2);
|
||||||
assert.isTrue(requestStub.getCall(0).calledWith('GET', 'https://doi.org/' + doi));
|
assert.isTrue(requestStub.getCall(0).calledWith('GET', 'https://doi.org/' + doi));
|
||||||
|
@ -931,7 +941,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item.setField('title', 'Test');
|
item.setField('title', 'Test');
|
||||||
item.setField('DOI', doi);
|
item.setField('DOI', doi);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 1);
|
assert.equal(requestStub.callCount, 1);
|
||||||
assert.isTrue(requestStub.calledWith('GET', 'https://doi.org/' + doi));
|
assert.isTrue(requestStub.calledWith('GET', 'https://doi.org/' + doi));
|
||||||
|
@ -949,7 +959,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item.setField('title', 'Test');
|
item.setField('title', 'Test');
|
||||||
item.setField('extra', 'DOI: ' + doi);
|
item.setField('extra', 'DOI: ' + doi);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 2);
|
assert.equal(requestStub.callCount, 2);
|
||||||
assert.isTrue(requestStub.getCall(0).calledWith('GET', 'https://doi.org/' + doi));
|
assert.isTrue(requestStub.getCall(0).calledWith('GET', 'https://doi.org/' + doi));
|
||||||
|
@ -967,7 +977,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item.setField('title', 'Test');
|
item.setField('title', 'Test');
|
||||||
item.setField('url', url);
|
item.setField('url', url);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 1);
|
assert.equal(requestStub.callCount, 1);
|
||||||
assert.isTrue(requestStub.calledWith('GET', url));
|
assert.isTrue(requestStub.calledWith('GET', url));
|
||||||
|
@ -979,13 +989,33 @@ describe("Zotero.Attachments", function() {
|
||||||
assert.equal(await OS.File.stat(attachment.getFilePath()).size, pdfSize);
|
assert.equal(await OS.File.stat(attachment.getFilePath()).size, pdfSize);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should add an EPUB from a URL with a redirect", async function () {
|
||||||
|
var url = pageURL11;
|
||||||
|
var item = createUnsavedDataObject('item', { itemType: 'book' });
|
||||||
|
item.setField('title', 'Test');
|
||||||
|
item.setField('url', url);
|
||||||
|
await item.saveTx();
|
||||||
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
assert.equal(requestStub.callCount, 2);
|
||||||
|
var call = requestStub.getCall(0);
|
||||||
|
assert.isTrue(call.calledWith('GET', url));
|
||||||
|
call = requestStub.getCall(1);
|
||||||
|
assert.isTrue(call.calledWith('GET', epubURL));
|
||||||
|
assert.ok(attachment);
|
||||||
|
var json = attachment.toJSON();
|
||||||
|
assert.equal(json.url, epubURL);
|
||||||
|
assert.equal(json.contentType, 'application/epub+zip');
|
||||||
|
assert.equal(json.filename, 'Test.epub');
|
||||||
|
assert.equal(await OS.File.stat(attachment.getFilePath()).size, epubSize);
|
||||||
|
});
|
||||||
|
|
||||||
it("should add an OA PDF from a direct URL", async function () {
|
it("should add an OA PDF from a direct URL", async function () {
|
||||||
var doi = doi2;
|
var doi = doi2;
|
||||||
var item = createUnsavedDataObject('item', { itemType: 'journalArticle' });
|
var item = createUnsavedDataObject('item', { itemType: 'journalArticle' });
|
||||||
item.setField('title', 'Test');
|
item.setField('title', 'Test');
|
||||||
item.setField('DOI', doi);
|
item.setField('DOI', doi);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 3);
|
assert.equal(requestStub.callCount, 3);
|
||||||
var call1 = requestStub.getCall(0);
|
var call1 = requestStub.getCall(0);
|
||||||
|
@ -1009,7 +1039,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item.setField('title', 'Test');
|
item.setField('title', 'Test');
|
||||||
item.setField('DOI', doi);
|
item.setField('DOI', doi);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 4);
|
assert.equal(requestStub.callCount, 4);
|
||||||
// Check the DOI (and get nothing)
|
// Check the DOI (and get nothing)
|
||||||
|
@ -1039,7 +1069,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item.setField('DOI', doi);
|
item.setField('DOI', doi);
|
||||||
item.setField('url', pageURL4);
|
item.setField('url', pageURL4);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 3);
|
assert.equal(requestStub.callCount, 3);
|
||||||
var call = requestStub.getCall(0);
|
var call = requestStub.getCall(0);
|
||||||
|
@ -1065,7 +1095,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item2.setField('url', url2);
|
item2.setField('url', url2);
|
||||||
await item2.saveTx();
|
await item2.saveTx();
|
||||||
|
|
||||||
var attachments = await Zotero.Attachments.addAvailablePDFs([item1, item2]);
|
var attachments = await Zotero.Attachments.addAvailableFiles([item1, item2]);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 2);
|
assert.equal(requestStub.callCount, 2);
|
||||||
assert.isAbove(requestStubCallTimes[1] - requestStubCallTimes[0], 998);
|
assert.isAbove(requestStubCallTimes[1] - requestStubCallTimes[0], 998);
|
||||||
|
@ -1096,7 +1126,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item3.setField('url', url3);
|
item3.setField('url', url3);
|
||||||
await item3.saveTx();
|
await item3.saveTx();
|
||||||
|
|
||||||
var attachments = await Zotero.Attachments.addAvailablePDFs([item1, item2, item3]);
|
var attachments = await Zotero.Attachments.addAvailableFiles([item1, item2, item3]);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 6);
|
assert.equal(requestStub.callCount, 6);
|
||||||
assert.equal(requestStub.getCall(0).args[1], doiPrefix + doi1);
|
assert.equal(requestStub.getCall(0).args[1], doiPrefix + doi1);
|
||||||
|
@ -1130,7 +1160,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item2.setField('url', url2);
|
item2.setField('url', url2);
|
||||||
await item2.saveTx();
|
await item2.saveTx();
|
||||||
|
|
||||||
var attachments = await Zotero.Attachments.addAvailablePDFs([item1, item2]);
|
var attachments = await Zotero.Attachments.addAvailableFiles([item1, item2]);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 3);
|
assert.equal(requestStub.callCount, 3);
|
||||||
assert.equal(requestStub.getCall(0).args[1], pageURL9);
|
assert.equal(requestStub.getCall(0).args[1], pageURL9);
|
||||||
|
@ -1148,7 +1178,7 @@ describe("Zotero.Attachments", function() {
|
||||||
item.setField('title', 'Test');
|
item.setField('title', 'Test');
|
||||||
item.setField('url', url);
|
item.setField('url', url);
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 2);
|
assert.equal(requestStub.callCount, 2);
|
||||||
assert.equal(requestStub.getCall(0).args[1], pageURL10)
|
assert.equal(requestStub.getCall(0).args[1], pageURL10)
|
||||||
|
@ -1165,7 +1195,7 @@ describe("Zotero.Attachments", function() {
|
||||||
var item = createUnsavedDataObject('item', { itemType: 'journalArticle' });
|
var item = createUnsavedDataObject('item', { itemType: 'journalArticle' });
|
||||||
item.setField('url', 'http://website/redirect_loop1');
|
item.setField('url', 'http://website/redirect_loop1');
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
assert.isFalse(attachment);
|
assert.isFalse(attachment);
|
||||||
assert.equal(requestStub.callCount, 7);
|
assert.equal(requestStub.callCount, 7);
|
||||||
});
|
});
|
||||||
|
@ -1174,7 +1204,7 @@ describe("Zotero.Attachments", function() {
|
||||||
var item = createUnsavedDataObject('item', { itemType: 'journalArticle' });
|
var item = createUnsavedDataObject('item', { itemType: 'journalArticle' });
|
||||||
item.setField('url', 'http://website/too_many_redirects1');
|
item.setField('url', 'http://website/too_many_redirects1');
|
||||||
await item.saveTx();
|
await item.saveTx();
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
assert.isFalse(attachment);
|
assert.isFalse(attachment);
|
||||||
assert.equal(requestStub.callCount, 10);
|
assert.equal(requestStub.callCount, 10);
|
||||||
});
|
});
|
||||||
|
@ -1196,7 +1226,7 @@ describe("Zotero.Attachments", function() {
|
||||||
}];
|
}];
|
||||||
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
||||||
|
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 4);
|
assert.equal(requestStub.callCount, 4);
|
||||||
var call = requestStub.getCall(0);
|
var call = requestStub.getCall(0);
|
||||||
|
@ -1234,7 +1264,7 @@ describe("Zotero.Attachments", function() {
|
||||||
}];
|
}];
|
||||||
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
||||||
|
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 4);
|
assert.equal(requestStub.callCount, 4);
|
||||||
var call = requestStub.getCall(0);
|
var call = requestStub.getCall(0);
|
||||||
|
@ -1270,7 +1300,7 @@ describe("Zotero.Attachments", function() {
|
||||||
}];
|
}];
|
||||||
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
||||||
|
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 4);
|
assert.equal(requestStub.callCount, 4);
|
||||||
var call = requestStub.getCall(0);
|
var call = requestStub.getCall(0);
|
||||||
|
@ -1310,7 +1340,7 @@ describe("Zotero.Attachments", function() {
|
||||||
}];
|
}];
|
||||||
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
Zotero.Prefs.set('findPDFs.resolvers', JSON.stringify(resolvers));
|
||||||
|
|
||||||
var attachment = await Zotero.Attachments.addAvailablePDF(item);
|
var attachment = await Zotero.Attachments.addAvailableFile(item);
|
||||||
|
|
||||||
assert.equal(requestStub.callCount, 5);
|
assert.equal(requestStub.callCount, 5);
|
||||||
var call = requestStub.getCall(0);
|
var call = requestStub.getCall(0);
|
||||||
|
|
Loading…
Reference in a new issue