Automatic PDF tool upgrading

If automatic translator/style updates are enabled, at least one of the
PDF tools is installed, and the repo returns a more recent version
number than what's installed, automatically upgrade the tools. (Version
3.02 counts as lower, since Poppler's version numbers are lower.)

If an error occurs, wait increasing amounts of time to try the downloads
again, up to one week.
This commit is contained in:
Dan Stillman 2015-03-28 18:37:55 -04:00
parent 4b83b1a630
commit d6e19a9f25
3 changed files with 200 additions and 134 deletions

View File

@ -177,14 +177,18 @@ Zotero_Preferences.Search = {
var converterVersion = xmlhttp.responseText.split(/\s/)[0];
var infoVersion = xmlhttp.responseText.split(/\s/)[1];
// Install if not installed, version unknown, Xpdf 3.02 (to upgrade to Poppler),
// or outdated
var converterVersionAvailable = converterVersion &&
(!converterIsRegistered ||
Zotero.Fulltext.pdfConverterVersion == 'UNKNOWN' ||
converterVersion > Zotero.Fulltext.pdfConverterVersion);
Zotero.Fulltext.pdfConverterVersion == 'UNKNOWN'
|| (converterVersion != '3.02' && Zotero.Fulltext.pdfConverterVersion == '3.02')
|| converterVersion > Zotero.Fulltext.pdfConverterVersion);
var infoVersionAvailable = infoVersion &&
(!infoIsRegistered ||
Zotero.Fulltext.pdfInfoVersion == 'UNKNOWN' ||
infoVersion > Zotero.Fulltext.pdfInfoVersion);
Zotero.Fulltext.pdfInfoVersion == 'UNKNOWN'
|| (infoVersion != '3.02' && Zotero.Fulltext.pdfInfoVersion == '3.02')
|| infoVersion > Zotero.Fulltext.pdfInfoVersion);
var bothAvailable = converterVersionAvailable && infoVersionAvailable;
/*
@ -246,7 +250,44 @@ Zotero_Preferences.Search = {
info: infoVersionAvailable ?
infoVersion : null
};
self.installPDFTools(installVersions);
document.getElementById('pdftools-update-button').disabled = true;
var str = Zotero.getString('zotero.preferences.search.pdf.downloading');
document.getElementById('pdftools-update-button').setAttribute('label', str);
if (converterVersionAvailable && infoVersionAvailable) {
Zotero.Fulltext.downloadPDFTool('converter', converterVersion, function (success) {
if (!success) {
self.onPDFToolsDownloadError("Error downloading pdftotext");
return;
}
Zotero.Fulltext.downloadPDFTool('info', infoVersion, function (success) {
if (!success) {
self.onPDFToolsDownloadError("Error downloading pdfinfo");
return;
}
self.updatePDFToolsStatus();
});
});
}
else if (converterVersionAvailable) {
Zotero.Fulltext.downloadPDFTool('converter', converterVersion, function (success) {
if (!success) {
self.onPDFToolsDownloadError("Error downloading pdftotext");
return;
}
self.updatePDFToolsStatus();
});
}
else {
Zotero.Fulltext.downloadPDFTool('info', infoVersion, function (success) {
if (!success) {
self.onPDFToolsDownloadError("Error downloading pdfinfo");
return;
}
self.updatePDFToolsStatus();
});
}
}
}
}
@ -267,135 +308,6 @@ Zotero_Preferences.Search = {
},
/*
* Begin installation of specified PDF tools from server -- does a HEAD call to
* make sure file exists and then calls downloadPDFTool() if so
*/
installPDFTools: function (installVersions) {
if (!installVersions) {
installVersions = {
converter: true,
info: true
};
}
// We install the converter first if it's available
var url = Zotero.Fulltext.pdfToolsDownloadBaseURL;
if (installVersions.converter) {
var tool = 'converter';
var version = installVersions.converter;
url += Zotero.Fulltext.pdfConverterFileName + '-' + installVersions.converter;
}
else if (installVersions.info) {
var tool = 'info';
var version = installVersions.info;
url += Zotero.Fulltext.pdfInfoFileName + '-' + installVersions.info;
}
else {
return;
}
// Find latest version for this platform
var self = this;
var sent = Zotero.HTTP.doHead(url, function (xmlhttp) {
try {
if (xmlhttp.status == 200) {
// If doing both and on converter, chain pdfinfo
if (installVersions.converter && installVersions.info) {
self.downloadPDFTool(tool, version, function () {
return self.installPDFTools({ info: installVersions.info });
});
}
else {
self.downloadPDFTool(tool, version);
}
}
// Version not found for platform
else if (xmlhttp.status == 404) {
self.onPDFToolsDownloadError(404);
}
}
catch (e) {
self.onPDFToolsDownloadError(e);
}
});
// Browser is offline
if (!sent) {
self.onPDFToolsDownloadError();
}
},
/*
* Download and install specified PDF tool
*/
downloadPDFTool: function (tool, version, callback) {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
if (tool == 'converter') {
var fileName = Zotero.Fulltext.pdfConverterFileName;
}
else {
var fileName = Zotero.Fulltext.pdfInfoFileName;
}
var url = Zotero.Fulltext.pdfToolsDownloadBaseURL + fileName + '-' + version;
var uri = ioService.newURI(url, null, null);
var file = Zotero.getZoteroDirectory();
file.append(fileName);
var fileURL = ioService.newFileURI(file);
const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
var wbp = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
.createInstance(nsIWBP);
var self = this;
var progressListener = new Zotero.WebProgressFinishListener(function () {
// Set permissions to 755
if (Zotero.isMac) {
file.permissions = 33261;
}
else if (Zotero.isLinux) {
file.permissions = 493;
}
// Write the version number to a file
var versionFile = Zotero.getZoteroDirectory();
versionFile.append(fileName + '.version');
Zotero.File.putContents(versionFile, version + '');
Zotero.Fulltext.registerPDFTool(tool);
// Used to install info tool after converter
if (callback) {
callback();
}
// If done
else {
self.updatePDFToolsStatus();
}
});
/*
var tr = Components.classes["@mozilla.org/transfer;1"].
createInstance(Components.interfaces.nsITransfer);
tr.init(uri, fileURL, "", null, null, null, wbp);
*/
document.getElementById('pdftools-update-button').disabled = true;
var str = Zotero.getString('zotero.preferences.search.pdf.downloading');
document.getElementById('pdftools-update-button').setAttribute('label', str);
wbp.progressListener = progressListener;
Zotero.debug("Saving " + uri.spec + " to " + fileURL.spec);
Zotero.Utilities.Internal.saveURI(wbp, uri, fileURL);
},
onPDFToolsDownloadError: function (e) {
if (e == 404) {
var str = Zotero.getString('zotero.preferences.search.pdf.toolDownloadsNotAvailable',

View File

@ -164,6 +164,78 @@ Zotero.Fulltext = new function(){
}
/*
* Download and install latest PDF tool
*/
this.downloadPDFTool = function (tool, version, callback) {
try {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
if (tool == 'converter') {
var fileName = this.pdfConverterFileName;
}
else {
var fileName = this.pdfInfoFileName;
}
var spec = this.pdfToolsDownloadBaseURL + fileName + '-' + version;
var uri = ioService.newURI(spec, null, null);
var file = Zotero.getTempDirectory();
file.append(fileName);
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Zotero.debug("Saving " + uri.spec + " to " + file.path);
var output = FileUtils.openSafeFileOutputStream(file);
NetUtil.asyncFetch(uri, function (is, status) {
if (!Components.isSuccessCode(status)) {
Zotero.debug(status, 1);
Components.utils.reportError(status);
if (callback) {
callback(false);
}
return;
}
Zotero.File.putContentsAsync(file, is)
.then(function () {
// Set permissions to 755
if (Zotero.isMac) {
file.permissions = 33261;
}
else if (Zotero.isLinux) {
file.permissions = 493;
}
var destDir = Zotero.getZoteroDirectory()
file.moveTo(destDir, null);
// Write the version number to a file
var versionFile = destDir.clone();
versionFile.append(fileName + '.version');
Zotero.File.putContents(versionFile, version + '');
Zotero.Fulltext.registerPDFTool(tool);
if (callback) {
callback(true);
}
});
});
}
catch (e) {
Zotero.debug(e, 1);
Components.utils.reportError(e);
if (callback) {
callback(false);
}
}
};
/*
* Looks for pdftotext-{platform}[.exe] in the Zotero data directory
*

View File

@ -1589,6 +1589,78 @@ Zotero.Schema = new function(){
var translatorUpdates = xmlhttp.responseXML.getElementsByTagName('translator');
var styleUpdates = xmlhttp.responseXML.getElementsByTagName('style');
var updatePDFTools = function () {
let pdfToolsUpdates = xmlhttp.responseXML.getElementsByTagName('pdftools');
if (pdfToolsUpdates.length) {
let availableVersion = pdfToolsUpdates[0].getAttribute('version');
let installInfo = false;
let installConverter = false;
// Don't auto-install if not installed
if (!Zotero.Fulltext.pdfInfoIsRegistered() && !Zotero.Fulltext.pdfConverterIsRegistered()) {
return;
}
if (Zotero.Fulltext.pdfInfoIsRegistered()) {
let currentVersion = Zotero.Fulltext.pdfInfoVersion;
if (currentVersion < availableVersion || currentVersion == '3.02'
|| currentVersion == 'UNKNOWN') {
installInfo = true;
}
}
if (Zotero.Fulltext.pdfConverterIsRegistered()) {
let currentVersion = Zotero.Fulltext.pdfConverterVersion;
if (currentVersion < availableVersion || currentVersion == '3.02'
|| currentVersion == 'UNKNOWN') {
installConverter = true;
}
}
let prefKey = 'pdfToolsInstallError';
let lastTry = 0, delay = 43200000; // half a day, so doubles to a day initially
try {
[lastTry, delay] = Zotero.Prefs.get(prefKey).split(';');
}
catch (e) {}
// Allow an additional minute, since repo updates might not be exact
if (Date.now() < (parseInt(lastTry) + parseInt(delay) - 60000)) {
Zotero.debug("Now enough time since last PDF tools installation failure -- skipping", 2);
return;
}
var checkResult = function (success) {
if (success) {
try {
Zotero.Prefs.clear(prefKey);
}
catch (e) {}
}
else {
// Keep doubling delay, to a max of 1 week
Zotero.Prefs.set(prefKey, Date.now() + ";" + Math.min(delay * 2, 7*24*60*60*1000));
let msg = "Error downloading PDF tool";
Zotero.debug(msg, 1);
throw new Error(msg);
}
};
if (installConverter && installInfo) {
Zotero.Fulltext.downloadPDFTool('converter', availableVersion, function (success) {
checkResult(success);
Zotero.Fulltext.downloadPDFTool('info', availableVersion, checkResult);
});
}
else if (installConverter) {
Zotero.Fulltext.downloadPDFTool('converter', availableVersion, checkResult);
}
else {
Zotero.Fulltext.downloadPDFTool('info', availableVersion, checkResult);
}
}
};
Zotero.DB.beginTransaction();
// TODO: clear DB version 'sync' from removed _updateDBVersion()
@ -1609,6 +1681,11 @@ Zotero.Schema = new function(){
_setRepositoryTimer(ZOTERO_CONFIG['REPOSITORY_CHECK_INTERVAL']);
}
_remoteUpdateInProgress = false;
setTimeout(function () {
updatePDFTools();
});
return -1;
}
@ -1640,6 +1717,11 @@ Zotero.Schema = new function(){
_setRepositoryTimer(ZOTERO_CONFIG['REPOSITORY_CHECK_INTERVAL']);
}
_remoteUpdateInProgress = false;
setTimeout(function () {
updatePDFTools();
});
return true;
}