From 10a5d8d02e39b61159508118dc7c979f0eb69f25 Mon Sep 17 00:00:00 2001 From: Dan Stillman Date: Fri, 17 Nov 2017 22:36:50 -0500 Subject: [PATCH] Check for Firefox profile access at startup and show warning f40b7ae6ac didn't help with people who've already upgraded, so check at startup and show a warning if the profile is inaccessible until 1) the profile has been accessed once or 2) the user checks "Don't show again" in the warning dialog. Also fix Zotero.Profile.getDefaultInProfilesDir() to properly throw an error if it can't access the default directory. --- chrome/content/zotero/xpcom/dataDirectory.js | 4 +- chrome/content/zotero/xpcom/profile.js | 50 +++++++++++++++++++- chrome/content/zotero/zoteroPane.js | 32 +++++++++++-- test/runtests.sh | 1 + 4 files changed, 79 insertions(+), 8 deletions(-) diff --git a/chrome/content/zotero/xpcom/dataDirectory.js b/chrome/content/zotero/xpcom/dataDirectory.js index d68d447f2..6bbfde146 100644 --- a/chrome/content/zotero/xpcom/dataDirectory.js +++ b/chrome/content/zotero/xpcom/dataDirectory.js @@ -178,6 +178,8 @@ Zotero.DataDirectory = { // New installation of 5.0+ with no data directory specified, so check all the places the data // could be else { + Zotero.fxProfileAccessError = false; + dataDir = this.defaultDir; // Check for ~/Zotero/zotero.sqlite @@ -719,7 +721,7 @@ Zotero.DataDirectory = { let dontAskAgain = {}; let index = ps.confirmEx(null, "Other Data Directory Found", - "Zotero found a previous data directory within your Firefox profile directory, " + "Zotero found a previous data directory within your Firefox profile, " + `last modified on ${mtime.toLocaleDateString()}. ` + "If items or files are missing from Zotero that were present in Zotero for Firefox, " + "your previous data directory may not have been properly migrated to the new default location " diff --git a/chrome/content/zotero/xpcom/profile.js b/chrome/content/zotero/xpcom/profile.js index ba88e52e8..0bce99af2 100644 --- a/chrome/content/zotero/xpcom/profile.js +++ b/chrome/content/zotero/xpcom/profile.js @@ -70,8 +70,17 @@ Zotero.Profile = { ? OS.Path.join(profilesDir, ...defaultSection.Path.split("/")) : defaultSection.Path; - if (!(yield OS.File.exists(defaultProfile))) { - return false; + try { + // Note: exists() returns false on no access, so use stat() instead + yield OS.File.stat(defaultProfile); + } + catch (e) { + if (e instanceof OS.File.Error) { + if (e.becauseNoSuchFile) { + return false; + } + throw e; + } } return [defaultProfile, nSections > 1]; }), @@ -189,6 +198,43 @@ Zotero.Profile = { }), + /** + * @return {Boolean} - True if accessible or skipped, false if not + */ + checkFirefoxProfileAccess: async function () { + try { + let profilesParent = OS.Path.dirname(Zotero.Profile.getOtherAppProfilesDir()); + Zotero.debug("Looking for Firefox profile in " + profilesParent); + let defProfile = await this.getDefaultInProfilesDir(profilesParent); + if (defProfile) { + let profileDir = defProfile[0]; + Zotero.debug("Found default profile at " + profileDir); + let prefsFile = OS.Path.join(profileDir, "prefs.js"); + await Zotero.File.getContentsAsync(prefsFile); + let dir = OS.Path.join(profileDir, Zotero.DataDirectory.legacyDirName); + Zotero.debug("Checking for 'zotero' subdirectory"); + if (await OS.File.exists(dir)) { + let dbFilename = Zotero.DataDirectory.getDatabaseFilename(); + let dbFile = OS.Path.join(dir, dbFilename); + Zotero.debug("Checking database access within 'zotero' subdirectory"); + (await OS.File.stat(dbFile)).lastModificationDate; + } + else { + Zotero.debug("'zotero' subdirectory not found"); + } + } + else { + Zotero.debug("No default profile found"); + } + } + catch (e) { + Zotero.debug(e, 2) + return false + } + return true; + }, + + // // Private methods // diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js index f6c946383..352ca7206 100644 --- a/chrome/content/zotero/zoteroPane.js +++ b/chrome/content/zotero/zoteroPane.js @@ -414,30 +414,52 @@ var ZoteroPane = new function() searchBar.inputField.select(); }, 1); - if (Zotero.fxProfileAccessError) { + // + // TEMP: Remove after people are no longer upgrading from Zotero for Firefox + // + var showFxProfileWarning = false; + var pref = 'firstRun.skipFirefoxProfileAccessCheck'; + if (Zotero.fxProfileAccessError != undefined && Zotero.fxProfileAccessError) { + showFxProfileWarning = true; + } + else if (!Zotero.Prefs.get(pref)) { + showFxProfileWarning = !(yield Zotero.Profile.checkFirefoxProfileAccess()); + } + if (showFxProfileWarning) { Zotero.uiReadyPromise.delay(2000).then(function () { var ps = Services.prompt; var buttonFlags = ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING + ps.BUTTON_POS_1 * ps.BUTTON_TITLE_IS_STRING; - var text = "Zotero was unable to access your Firefox profile directory.\n\n" - + "If you’re upgrading from Zotero 4.0 for Firefox and don’t see the data " + var text = "Zotero was unable to access your Firefox profile to check for " + + "existing Zotero data.\n\n" + + "If you’ve upgraded from Zotero 4.0 for Firefox and don’t see the data " + "you expect, it may be located elsewhere on your computer. " + "Click “More Information” for help restoring your previous data.\n\n" + "If you’re new to Zotero, you can ignore this message."; var url = 'https://www.zotero.org/support/kb/data_missing_after_zotero_5_upgrade'; + var dontShowAgain = {}; let index = ps.confirmEx(null, Zotero.getString('general.warning'), text, buttonFlags, Zotero.getString('general.moreInformation'), "Ignore", - null, null, {} + null, + Zotero.getString('general.dontShowAgain'), + dontShowAgain ); + if (dontShowAgain.value) { + Zotero.Prefs.set(pref, true) + } if (index == 0) { this.loadURI(url); } }.bind(this)); } + // Once we successfully find it once, don't bother checking again + else { + Zotero.Prefs.set(pref, true); + } // Auto-sync on pane open or if new account if (Zotero.Prefs.get('sync.autoSync') || Zotero.initAutoSync) { @@ -453,7 +475,7 @@ var ZoteroPane = new function() else if (Zotero.Sync.Server.manualSyncRequired) { Zotero.debug('Manual sync required -- skipping auto-sync', 4); } - else if (Zotero.fxProfileAccessError) { + else if (showFxProfileWarning) { Zotero.debug('Firefox profile access error -- skipping initial auto-sync', 4); } else { diff --git a/test/runtests.sh b/test/runtests.sh index cdcfc9821..0f8f28ef1 100755 --- a/test/runtests.sh +++ b/test/runtests.sh @@ -136,6 +136,7 @@ user_pref("dom.max_chrome_script_run_time", 0); user_pref("extensions.zotero.debug.log", $DEBUG); user_pref("extensions.zotero.debug.level", $DEBUG_LEVEL); user_pref("extensions.zotero.debug.time", $DEBUG); +user_pref("extensions.zotero.firstRun.skipFirefoxProfileAccessCheck", true); user_pref("extensions.zotero.firstRunGuidance", false); user_pref("extensions.zotero.firstRun2", false); user_pref("extensions.zotero.reportTranslationFailure", false);