fune/browser/components/migration/EdgeProfileMigrator.js
Gijs Kruitbosch 0f4df510d0 Bug 1225798 - part 2: move reading list import to its own bookmarks migrator source, r=MattN
--HG--
extra : commitid : JXiSqZFo7ix
extra : rebase_source : 527e26c9464fd20c722a9934afff2064fb3b751b
extra : histedit_source : 728b626d261619df65829d7df155213d3d2034af
2015-11-18 11:56:02 +00:00

223 lines
7.8 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource:///modules/MigrationUtils.jsm");
Cu.import("resource:///modules/MSMigrationUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
"resource://gre/modules/PlacesUtils.jsm");
const kEdgeRegistryRoot = "SOFTWARE\\Classes\\Local Settings\\Software\\" +
"Microsoft\\Windows\\CurrentVersion\\AppContainer\\Storage\\" +
"microsoft.microsoftedge_8wekyb3d8bbwe\\MicrosoftEdge";
const kEdgeReadingListPath = "AC\\MicrosoftEdge\\User\\Default\\DataStore\\Data\\";
function EdgeTypedURLMigrator() {
}
EdgeTypedURLMigrator.prototype = {
type: MigrationUtils.resourceTypes.HISTORY,
get _typedURLs() {
if (!this.__typedURLs) {
this.__typedURLs = MSMigrationUtils.getTypedURLs(kEdgeRegistryRoot);
}
return this.__typedURLs;
},
get exists() {
return this._typedURLs.size > 0;
},
migrate: function(aCallback) {
let rv = true;
let typedURLs = this._typedURLs;
let places = [];
for (let [urlString, time] of typedURLs) {
let uri;
try {
uri = Services.io.newURI(urlString, null, null);
if (["http", "https", "ftp"].indexOf(uri.scheme) == -1) {
continue;
}
} catch (ex) {
Cu.reportError(ex);
continue;
}
// Note that the time will be in microseconds (PRTime),
// and Date.now() returns milliseconds. Places expects PRTime,
// so we multiply the Date.now return value to make up the difference.
let visitDate = time || (Date.now() * 1000);
places.push({
uri,
visits: [{ transitionType: Ci.nsINavHistoryService.TRANSITION_TYPED,
visitDate}]
});
}
if (places.length == 0) {
aCallback(typedURLs.size == 0);
return;
}
PlacesUtils.asyncHistory.updatePlaces(places, {
_success: false,
handleResult: function() {
// Importing any entry is considered a successful import.
this._success = true;
},
handleError: function() {},
handleCompletion: function() {
aCallback(this._success);
}
});
},
}
function EdgeReadingListMigrator() {
}
EdgeReadingListMigrator.prototype = {
type: MigrationUtils.resourceTypes.BOOKMARKS,
get exists() {
return !!MSMigrationUtils.getEdgeLocalDataFolder();
},
migrate(callback) {
this._migrateReadingList(PlacesUtils.bookmarks.menuGuid).then(
() => callback(true),
ex => {
Cu.reportError(ex);
callback(false);
}
);
},
_migrateReadingList: Task.async(function*(parentGuid) {
let edgeDir = MSMigrationUtils.getEdgeLocalDataFolder();
if (!edgeDir) {
return;
}
this._readingListExtractor = Cc["@mozilla.org/profile/migrator/edgereadinglistextractor;1"].
createInstance(Ci.nsIEdgeReadingListExtractor);
edgeDir.appendRelativePath(kEdgeReadingListPath);
let errorProduced = null;
if (edgeDir.exists() && edgeDir.isReadable() && edgeDir.isDirectory()) {
let expectedDir = edgeDir.clone();
expectedDir.appendRelativePath("nouser1\\120712-0049");
if (expectedDir.exists() && expectedDir.isReadable() && expectedDir.isDirectory()) {
yield this._migrateReadingListDB(expectedDir, parentGuid).catch(ex => {
if (!errorProduced)
errorProduced = ex;
});
} else {
let getSubdirs = someDir => {
let subdirs = someDir.directoryEntries;
let rv = [];
while (subdirs.hasMoreElements()) {
let subdir = subdirs.getNext().QueryInterface(Ci.nsIFile);
if (subdir.isDirectory() && subdir.isReadable()) {
rv.push(subdir);
}
}
return rv;
};
let dirs = getSubdirs(edgeDir).map(getSubdirs);
for (let dir of dirs) {
yield this._migrateReadingListDB(dir, parentGuid).catch(ex => {
if (!errorProduced)
errorProduced = ex;
});
}
}
}
if (errorProduced) {
throw errorProduced;
}
}),
_migrateReadingListDB: Task.async(function*(dbFile, parentGuid) {
dbFile.appendRelativePath("DBStore\\spartan.edb");
if (!dbFile.exists() || !dbFile.isReadable() || !dbFile.isFile()) {
return;
}
let readingListItems;
try {
readingListItems = this._readingListExtractor.extract(dbFile.path);
} catch (ex) {
Cu.reportError("Failed to extract Edge reading list information from " +
"the database at " + dbFile.path + " due to the following error: " + ex);
// Deliberately make this fail so we expose failure in the UI:
throw ex;
return;
}
if (!readingListItems.length) {
return;
}
let destFolderGuid = yield this._ensureReadingListFolder(parentGuid);
for (let i = 0; i < readingListItems.length; i++) {
let readingListItem = readingListItems.queryElementAt(i, Ci.nsIPropertyBag2);
let url = readingListItem.get("uri");
let title = readingListItem.get("title");
let time = readingListItem.get("time");
// time is a PRTime, which is microseconds (since unix epoch), or null.
// We need milliseconds for the date constructor, so divide by 1000:
let dateAdded = time ? new Date(time / 1000) : new Date();
yield PlacesUtils.bookmarks.insert({
parentGuid: destFolderGuid, url: url, title, dateAdded
});
}
}),
_ensureReadingListFolder: Task.async(function*(parentGuid) {
if (!this.__readingListFolderGuid) {
let folderTitle = MigrationUtils.getLocalizedString("importedEdgeReadingList");
let folderSpec = {type: PlacesUtils.bookmarks.TYPE_FOLDER, parentGuid, title: folderTitle};
this.__readingListFolderGuid = (yield PlacesUtils.bookmarks.insert(folderSpec)).guid;
}
return this.__readingListFolderGuid;
}),
};
function EdgeProfileMigrator() {
}
EdgeProfileMigrator.prototype = Object.create(MigratorPrototype);
EdgeProfileMigrator.prototype.getResources = function() {
let resources = [
MSMigrationUtils.getBookmarksMigrator(MSMigrationUtils.MIGRATION_TYPE_EDGE),
MSMigrationUtils.getCookiesMigrator(MSMigrationUtils.MIGRATION_TYPE_EDGE),
new EdgeTypedURLMigrator(),
new EdgeReadingListMigrator(),
];
let windowsVaultFormPasswordsMigrator =
MSMigrationUtils.getWindowsVaultFormPasswordsMigrator();
windowsVaultFormPasswordsMigrator.name = "EdgeVaultFormPasswords";
resources.push(windowsVaultFormPasswordsMigrator);
return resources.filter(r => r.exists);
};
/* Somewhat counterintuitively, this returns:
* - |null| to indicate "There is only 1 (default) profile" (on win10+)
* - |[]| to indicate "There are no profiles" (on <=win8.1) which will avoid using this migrator.
* See MigrationUtils.jsm for slightly more info on how sourceProfiles is used.
*/
EdgeProfileMigrator.prototype.__defineGetter__("sourceProfiles", function() {
let isWin10OrHigher = AppConstants.isPlatformAndVersionAtLeast("win", "10");
return isWin10OrHigher ? null : [];
});
EdgeProfileMigrator.prototype.classDescription = "Edge Profile Migrator";
EdgeProfileMigrator.prototype.contractID = "@mozilla.org/profile/migrator;1?app=browser&type=edge";
EdgeProfileMigrator.prototype.classID = Components.ID("{62e8834b-2d17-49f5-96ff-56344903a2ae}");
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EdgeProfileMigrator]);