360seMigrationUtils.sys.mjs (5352B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 import { MigrationUtils } from "resource:///modules/MigrationUtils.sys.mjs"; 6 7 const lazy = {}; 8 9 ChromeUtils.defineESModuleGetters(lazy, { 10 PlacesUtils: "resource://gre/modules/PlacesUtils.sys.mjs", 11 Sqlite: "resource://gre/modules/Sqlite.sys.mjs", 12 }); 13 14 ChromeUtils.defineLazyGetter( 15 lazy, 16 "filenamesRegex", 17 () => /^360(?:default_ori|sefav)_([0-9_]+)\.favdb$/i 18 ); 19 20 const kBookmarksFileName = "360sefav.dat"; 21 22 function Bookmarks(aProfileFolder) { 23 let file = aProfileFolder.clone(); 24 file.append(kBookmarksFileName); 25 26 this._file = file; 27 } 28 Bookmarks.prototype = { 29 type: MigrationUtils.resourceTypes.BOOKMARKS, 30 31 get exists() { 32 return this._file.exists() && this._file.isReadable(); 33 }, 34 35 migrate(aCallback) { 36 return (async () => { 37 let folderMap = new Map(); 38 let toolbarBMs = []; 39 40 let connection = await lazy.Sqlite.openConnection({ 41 path: this._file.path, 42 }); 43 44 try { 45 let rows = await connection.execute( 46 `WITH RECURSIVE 47 bookmark(id, parent_id, is_folder, title, url, pos) AS ( 48 VALUES(0, -1, 1, '', '', 0) 49 UNION 50 SELECT f.id, f.parent_id, f.is_folder, f.title, f.url, f.pos 51 FROM tb_fav AS f 52 JOIN bookmark AS b ON f.parent_id = b.id 53 ORDER BY f.pos ASC 54 ) 55 SELECT id, parent_id, is_folder, title, url FROM bookmark WHERE id` 56 ); 57 58 for (let row of rows) { 59 let id = parseInt(row.getResultByName("id"), 10); 60 let parent_id = parseInt(row.getResultByName("parent_id"), 10); 61 let is_folder = parseInt(row.getResultByName("is_folder"), 10); 62 let title = row.getResultByName("title"); 63 let url = row.getResultByName("url"); 64 65 let bmToInsert; 66 67 if (is_folder) { 68 bmToInsert = { 69 children: [], 70 title, 71 type: lazy.PlacesUtils.bookmarks.TYPE_FOLDER, 72 }; 73 folderMap.set(id, bmToInsert); 74 } else { 75 if (!URL.canParse(url)) { 76 console.error( 77 `Ignoring ${url} when importing from 360se because it is not a valid URL.` 78 ); 79 continue; 80 } 81 82 bmToInsert = { 83 title, 84 url, 85 }; 86 } 87 88 if (folderMap.has(parent_id)) { 89 folderMap.get(parent_id).children.push(bmToInsert); 90 } else if (parent_id === 0) { 91 toolbarBMs.push(bmToInsert); 92 } 93 } 94 } finally { 95 await connection.close(); 96 } 97 98 if (toolbarBMs.length) { 99 let parentGuid = lazy.PlacesUtils.bookmarks.toolbarGuid; 100 await MigrationUtils.insertManyBookmarksWrapper(toolbarBMs, parentGuid); 101 } 102 })().then( 103 () => aCallback(true), 104 e => { 105 console.error(e); 106 aCallback(false); 107 } 108 ); 109 }, 110 }; 111 112 export var Qihoo360seMigrationUtils = { 113 async getAlternativeBookmarks({ bookmarksPath, localState }) { 114 let lastModificationDate = new Date(0); 115 let path = bookmarksPath; 116 let profileFolder = PathUtils.parent(bookmarksPath); 117 118 if (await IOUtils.exists(bookmarksPath)) { 119 try { 120 let { lastModified } = await IOUtils.stat(bookmarksPath); 121 lastModificationDate = new Date(lastModified); 122 } catch (ex) { 123 console.error(ex); 124 } 125 } 126 127 // Somewhat similar to source profiles, but for bookmarks only 128 let subDir = 129 (localState.sync_login_info && localState.sync_login_info.filepath) || ""; 130 131 if (subDir) { 132 let legacyBookmarksPath = PathUtils.join( 133 profileFolder, 134 subDir, 135 kBookmarksFileName 136 ); 137 if (await IOUtils.exists(legacyBookmarksPath)) { 138 try { 139 let { lastModified } = await IOUtils.stat(legacyBookmarksPath); 140 lastModificationDate = new Date(lastModified); 141 path = legacyBookmarksPath; 142 } catch (ex) { 143 console.error(ex); 144 } 145 } 146 } 147 148 let dailyBackupPath = PathUtils.join(profileFolder, subDir, "DailyBackup"); 149 for (const entry of await IOUtils.getChildren(dailyBackupPath, { 150 ignoreAbsent: true, 151 })) { 152 let filename = PathUtils.filename(entry); 153 let matches = lazy.filenamesRegex.exec(filename); 154 if (!matches) { 155 continue; 156 } 157 158 let entryDate = new Date(matches[1].replace(/_/g, "-")); 159 if (entryDate < lastModificationDate) { 160 continue; 161 } 162 163 lastModificationDate = entryDate; 164 path = entry; 165 } 166 167 if (PathUtils.filename(path) === kBookmarksFileName) { 168 let resource = this.getLegacyBookmarksResource(PathUtils.parent(path)); 169 return { resource }; 170 } 171 return { path }; 172 }, 173 174 getLegacyBookmarksResource(aParentFolder) { 175 let parentFolder; 176 try { 177 parentFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); 178 parentFolder.initWithPath(aParentFolder); 179 } catch (ex) { 180 console.error(ex); 181 return null; 182 } 183 184 let bookmarks = new Bookmarks(parentFolder); 185 return bookmarks.exists ? bookmarks : null; 186 }, 187 };