Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: chrome/browser/importer/safari_importer.mm

Issue 14575004: Extract BookmarksFileImporter from Firefox2Importer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: test cleanup Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <Cocoa/Cocoa.h> 5 #include <Cocoa/Cocoa.h>
6 6
7 #include "chrome/browser/importer/safari_importer.h" 7 #include "chrome/browser/importer/safari_importer.h"
8 8
9 #include <map> 9 #include <map>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/file_util.h" 12 #include "base/file_util.h"
13 #include "base/mac/mac_util.h" 13 #include "base/mac/mac_util.h"
14 #include "base/memory/scoped_nsobject.h" 14 #include "base/memory/scoped_nsobject.h"
15 #include "base/string16.h" 15 #include "base/string16.h"
16 #include "base/strings/sys_string_conversions.h" 16 #include "base/strings/sys_string_conversions.h"
17 #include "base/time.h" 17 #include "base/time.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "chrome/browser/history/history_types.h" 19 #include "chrome/browser/bookmarks/imported_bookmark_entry.h"
20 #include "chrome/browser/favicon/favicon_util.h"
21 #include "chrome/browser/favicon/imported_favicon_usage.h"
20 #include "chrome/browser/importer/importer_bridge.h" 22 #include "chrome/browser/importer/importer_bridge.h"
21 #include "chrome/browser/importer/importer_util.h"
22 #include "chrome/common/url_constants.h" 23 #include "chrome/common/url_constants.h"
23 #include "googleurl/src/gurl.h" 24 #include "googleurl/src/gurl.h"
24 #include "grit/generated_resources.h" 25 #include "grit/generated_resources.h"
25 #include "net/base/data_url.h" 26 #include "net/base/data_url.h"
26 #include "sql/statement.h" 27 #include "sql/statement.h"
27 28
28 namespace { 29 namespace {
29 30
30 // A function like this is used by other importers in order to filter out 31 // A function like this is used by other importers in order to filter out
31 // URLS we don't want to import. 32 // URLS we don't want to import.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 bridge_->NotifyItemStarted(importer::PASSWORDS); 94 bridge_->NotifyItemStarted(importer::PASSWORDS);
94 ImportPasswords(); 95 ImportPasswords();
95 bridge_->NotifyItemEnded(importer::PASSWORDS); 96 bridge_->NotifyItemEnded(importer::PASSWORDS);
96 } 97 }
97 bridge_->NotifyEnded(); 98 bridge_->NotifyEnded();
98 } 99 }
99 100
100 void SafariImporter::ImportBookmarks() { 101 void SafariImporter::ImportBookmarks() {
101 string16 toolbar_name = 102 string16 toolbar_name =
102 bridge_->GetLocalizedString(IDS_BOOKMARK_BAR_FOLDER_NAME); 103 bridge_->GetLocalizedString(IDS_BOOKMARK_BAR_FOLDER_NAME);
103 std::vector<ProfileWriter::BookmarkEntry> bookmarks; 104 std::vector<ImportedBookmarkEntry> bookmarks;
104 ParseBookmarks(toolbar_name, &bookmarks); 105 ParseBookmarks(toolbar_name, &bookmarks);
105 106
106 // Write bookmarks into profile. 107 // Write bookmarks into profile.
107 if (!bookmarks.empty() && !cancelled()) { 108 if (!bookmarks.empty() && !cancelled()) {
108 const string16& first_folder_name = 109 const string16& first_folder_name =
109 bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_SAFARI); 110 bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_SAFARI);
110 bridge_->AddBookmarks(bookmarks, first_folder_name); 111 bridge_->AddBookmarks(bookmarks, first_folder_name);
111 } 112 }
112 113
113 // Import favicons. 114 // Import favicons.
114 sql::Connection db; 115 sql::Connection db;
115 if (!OpenDatabase(&db)) 116 if (!OpenDatabase(&db))
116 return; 117 return;
117 118
118 FaviconMap favicon_map; 119 FaviconMap favicon_map;
119 ImportFaviconURLs(&db, &favicon_map); 120 ImportFaviconURLs(&db, &favicon_map);
120 // Write favicons into profile. 121 // Write favicons into profile.
121 if (!favicon_map.empty() && !cancelled()) { 122 if (!favicon_map.empty() && !cancelled()) {
122 std::vector<history::ImportedFaviconUsage> favicons; 123 std::vector<ImportedFaviconUsage> favicons;
123 LoadFaviconData(&db, favicon_map, &favicons); 124 LoadFaviconData(&db, favicon_map, &favicons);
124 bridge_->SetFavicons(favicons); 125 bridge_->SetFavicons(favicons);
125 } 126 }
126 } 127 }
127 128
128 bool SafariImporter::OpenDatabase(sql::Connection* db) { 129 bool SafariImporter::OpenDatabase(sql::Connection* db) {
129 // Construct ~/Library/Safari/WebIcons.db path. 130 // Construct ~/Library/Safari/WebIcons.db path.
130 NSString* library_dir = [NSString 131 NSString* library_dir = [NSString
131 stringWithUTF8String:library_dir_.value().c_str()]; 132 stringWithUTF8String:library_dir_.value().c_str()];
132 NSString* safari_dir = [library_dir 133 NSString* safari_dir = [library_dir
(...skipping 13 matching lines...) Expand all
146 while (s.Step() && !cancelled()) { 147 while (s.Step() && !cancelled()) {
147 int64 icon_id = s.ColumnInt64(0); 148 int64 icon_id = s.ColumnInt64(0);
148 GURL url = GURL(s.ColumnString(1)); 149 GURL url = GURL(s.ColumnString(1));
149 (*favicon_map)[icon_id].insert(url); 150 (*favicon_map)[icon_id].insert(url);
150 } 151 }
151 } 152 }
152 153
153 void SafariImporter::LoadFaviconData( 154 void SafariImporter::LoadFaviconData(
154 sql::Connection* db, 155 sql::Connection* db,
155 const FaviconMap& favicon_map, 156 const FaviconMap& favicon_map,
156 std::vector<history::ImportedFaviconUsage>* favicons) { 157 std::vector<ImportedFaviconUsage>* favicons) {
157 const char* query = "SELECT i.url, d.data " 158 const char* query = "SELECT i.url, d.data "
158 "FROM IconInfo i JOIN IconData d " 159 "FROM IconInfo i JOIN IconData d "
159 "ON i.iconID = d.iconID " 160 "ON i.iconID = d.iconID "
160 "WHERE i.iconID = ?;"; 161 "WHERE i.iconID = ?;";
161 sql::Statement s(db->GetUniqueStatement(query)); 162 sql::Statement s(db->GetUniqueStatement(query));
162 163
163 for (FaviconMap::const_iterator i = favicon_map.begin(); 164 for (FaviconMap::const_iterator i = favicon_map.begin();
164 i != favicon_map.end(); ++i) { 165 i != favicon_map.end(); ++i) {
165 s.Reset(true); 166 s.Reset(true);
166 s.BindInt64(0, i->first); 167 s.BindInt64(0, i->first);
167 if (s.Step()) { 168 if (s.Step()) {
168 history::ImportedFaviconUsage usage; 169 ImportedFaviconUsage usage;
169 170
170 usage.favicon_url = GURL(s.ColumnString(0)); 171 usage.favicon_url = GURL(s.ColumnString(0));
171 if (!usage.favicon_url.is_valid()) 172 if (!usage.favicon_url.is_valid())
172 continue; // Don't bother importing favicons with invalid URLs. 173 continue; // Don't bother importing favicons with invalid URLs.
173 174
174 std::vector<unsigned char> data; 175 std::vector<unsigned char> data;
175 s.ColumnBlobAsVector(1, &data); 176 s.ColumnBlobAsVector(1, &data);
176 if (data.empty()) 177 if (data.empty())
177 continue; // Data definitely invalid. 178 continue; // Data definitely invalid.
178 179
179 if (!importer::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) 180 if (!FaviconUtil::ReencodeFavicon(&data[0], data.size(), &usage.png_data))
180 continue; // Unable to decode. 181 continue; // Unable to decode.
181 182
182 usage.urls = i->second; 183 usage.urls = i->second;
183 favicons->push_back(usage); 184 favicons->push_back(usage);
184 } 185 }
185 } 186 }
186 } 187 }
187 188
188 void SafariImporter::RecursiveReadBookmarksFolder( 189 void SafariImporter::RecursiveReadBookmarksFolder(
189 NSDictionary* bookmark_folder, 190 NSDictionary* bookmark_folder,
190 const std::vector<string16>& parent_path_elements, 191 const std::vector<string16>& parent_path_elements,
191 bool is_in_toolbar, 192 bool is_in_toolbar,
192 const string16& toolbar_name, 193 const string16& toolbar_name,
193 std::vector<ProfileWriter::BookmarkEntry>* out_bookmarks) { 194 std::vector<ImportedBookmarkEntry>* out_bookmarks) {
194 DCHECK(bookmark_folder); 195 DCHECK(bookmark_folder);
195 196
196 NSString* type = [bookmark_folder objectForKey:@"WebBookmarkType"]; 197 NSString* type = [bookmark_folder objectForKey:@"WebBookmarkType"];
197 NSString* title = [bookmark_folder objectForKey:@"Title"]; 198 NSString* title = [bookmark_folder objectForKey:@"Title"];
198 199
199 // Are we the dictionary that contains all other bookmarks? 200 // Are we the dictionary that contains all other bookmarks?
200 // We need to know this so we don't add it to the path. 201 // We need to know this so we don't add it to the path.
201 bool is_top_level_bookmarks_container = [bookmark_folder 202 bool is_top_level_bookmarks_container = [bookmark_folder
202 objectForKey:@"WebBookmarkFileVersion"] != nil; 203 objectForKey:@"WebBookmarkFileVersion"] != nil;
203 204
204 // We're expecting a list of bookmarks here, if that isn't what we got, fail. 205 // We're expecting a list of bookmarks here, if that isn't what we got, fail.
205 if (!is_top_level_bookmarks_container) { 206 if (!is_top_level_bookmarks_container) {
206 // Top level containers sometimes don't have title attributes. 207 // Top level containers sometimes don't have title attributes.
207 if (![type isEqualToString:@"WebBookmarkTypeList"] || !title) { 208 if (![type isEqualToString:@"WebBookmarkTypeList"] || !title) {
208 NOTREACHED() << "Type=(" 209 NOTREACHED() << "Type=("
209 << (type ? base::SysNSStringToUTF8(type) : "Null type") 210 << (type ? base::SysNSStringToUTF8(type) : "Null type")
210 << ") Title=(" 211 << ") Title=("
211 << (title ? base::SysNSStringToUTF8(title) : "Null title") 212 << (title ? base::SysNSStringToUTF8(title) : "Null title")
212 << ")"; 213 << ")";
213 return; 214 return;
214 } 215 }
215 } 216 }
216 217
217 NSArray* elements = [bookmark_folder objectForKey:@"Children"]; 218 NSArray* elements = [bookmark_folder objectForKey:@"Children"];
218 if (!elements && (!parent_path_elements.empty() || !is_in_toolbar)) { 219 if (!elements && (!parent_path_elements.empty() || !is_in_toolbar)) {
219 // This is an empty folder, so add it explicitly; but don't add the toolbar 220 // This is an empty folder, so add it explicitly; but don't add the toolbar
220 // folder if it is empty. Note that all non-empty folders are added 221 // folder if it is empty. Note that all non-empty folders are added
221 // implicitly when their children are added. 222 // implicitly when their children are added.
222 ProfileWriter::BookmarkEntry entry; 223 ImportedBookmarkEntry entry;
223 // Safari doesn't specify a creation time for the folder. 224 // Safari doesn't specify a creation time for the folder.
224 entry.creation_time = base::Time::Now(); 225 entry.creation_time = base::Time::Now();
225 entry.title = base::SysNSStringToUTF16(title); 226 entry.title = base::SysNSStringToUTF16(title);
226 entry.path = parent_path_elements; 227 entry.path = parent_path_elements;
227 entry.in_toolbar = is_in_toolbar; 228 entry.in_toolbar = is_in_toolbar;
228 entry.is_folder = true; 229 entry.is_folder = true;
229 230
230 out_bookmarks->push_back(entry); 231 out_bookmarks->push_back(entry);
231 return; 232 return;
232 } 233 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 continue; 265 continue;
265 266
266 NSString* url = [bookmark objectForKey:@"URLString"]; 267 NSString* url = [bookmark objectForKey:@"URLString"];
267 NSString* title = [[bookmark objectForKey:@"URIDictionary"] 268 NSString* title = [[bookmark objectForKey:@"URIDictionary"]
268 objectForKey:@"title"]; 269 objectForKey:@"title"];
269 270
270 if (!url || !title) 271 if (!url || !title)
271 continue; 272 continue;
272 273
273 // Output Bookmark. 274 // Output Bookmark.
274 ProfileWriter::BookmarkEntry entry; 275 ImportedBookmarkEntry entry;
275 // Safari doesn't specify a creation time for the bookmark. 276 // Safari doesn't specify a creation time for the bookmark.
276 entry.creation_time = base::Time::Now(); 277 entry.creation_time = base::Time::Now();
277 entry.title = base::SysNSStringToUTF16(title); 278 entry.title = base::SysNSStringToUTF16(title);
278 entry.url = GURL(base::SysNSStringToUTF8(url)); 279 entry.url = GURL(base::SysNSStringToUTF8(url));
279 entry.path = path_elements; 280 entry.path = path_elements;
280 entry.in_toolbar = is_in_toolbar; 281 entry.in_toolbar = is_in_toolbar;
281 282
282 out_bookmarks->push_back(entry); 283 out_bookmarks->push_back(entry);
283 } 284 }
284 } 285 }
285 286
286 void SafariImporter::ParseBookmarks( 287 void SafariImporter::ParseBookmarks(
287 const string16& toolbar_name, 288 const string16& toolbar_name,
288 std::vector<ProfileWriter::BookmarkEntry>* bookmarks) { 289 std::vector<ImportedBookmarkEntry>* bookmarks) {
289 DCHECK(bookmarks); 290 DCHECK(bookmarks);
290 291
291 // Construct ~/Library/Safari/Bookmarks.plist path 292 // Construct ~/Library/Safari/Bookmarks.plist path
292 NSString* library_dir = [NSString 293 NSString* library_dir = [NSString
293 stringWithUTF8String:library_dir_.value().c_str()]; 294 stringWithUTF8String:library_dir_.value().c_str()];
294 NSString* safari_dir = [library_dir 295 NSString* safari_dir = [library_dir
295 stringByAppendingPathComponent:@"Safari"]; 296 stringByAppendingPathComponent:@"Safari"];
296 NSString* bookmarks_plist = [safari_dir 297 NSString* bookmarks_plist = [safari_dir
297 stringByAppendingPathComponent:@"Bookmarks.plist"]; 298 stringByAppendingPathComponent:@"Bookmarks.plist"];
298 299
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 if (!last_visit_str) 390 if (!last_visit_str)
390 continue; 391 continue;
391 392
392 // Convert Safari's last visit time to Unix Epoch time. 393 // Convert Safari's last visit time to Unix Epoch time.
393 double seconds_since_unix_epoch = HistoryTimeToEpochTime(last_visit_str); 394 double seconds_since_unix_epoch = HistoryTimeToEpochTime(last_visit_str);
394 row.set_last_visit(base::Time::FromDoubleT(seconds_since_unix_epoch)); 395 row.set_last_visit(base::Time::FromDoubleT(seconds_since_unix_epoch));
395 396
396 history_items->push_back(row); 397 history_items->push_back(row);
397 } 398 }
398 } 399 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698