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

Unified Diff: chrome/browser/importer/safari_importer.mm

Issue 18501013: Move most importer code to chrome/utility/importer (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: another gyp attempt Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/importer/safari_importer.h ('k') | chrome/browser/importer/safari_importer_unittest.mm » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/importer/safari_importer.mm
diff --git a/chrome/browser/importer/safari_importer.mm b/chrome/browser/importer/safari_importer.mm
deleted file mode 100644
index 4a5de0dba616fceaab1159d65de88af3612ba0d4..0000000000000000000000000000000000000000
--- a/chrome/browser/importer/safari_importer.mm
+++ /dev/null
@@ -1,399 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <Cocoa/Cocoa.h>
-
-#include "chrome/browser/importer/safari_importer.h"
-
-#include <map>
-#include <vector>
-
-#include "base/file_util.h"
-#include "base/mac/mac_util.h"
-#include "base/strings/string16.h"
-#include "base/strings/sys_string_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/time/time.h"
-#include "chrome/browser/importer/importer_bridge.h"
-#include "chrome/browser/importer/reencode_favicon.h"
-#include "chrome/common/importer/imported_bookmark_entry.h"
-#include "chrome/common/importer/imported_favicon_usage.h"
-#include "chrome/common/url_constants.h"
-#include "grit/generated_resources.h"
-#include "net/base/data_url.h"
-#include "sql/statement.h"
-#include "url/gurl.h"
-
-namespace {
-
-// A function like this is used by other importers in order to filter out
-// URLS we don't want to import.
-// For now it's pretty basic, but I've split it out so it's easy to slot
-// in necessary logic for filtering URLS, should we need it.
-bool CanImportSafariURL(const GURL& url) {
- // The URL is not valid.
- if (!url.is_valid())
- return false;
-
- return true;
-}
-
-} // namespace
-
-SafariImporter::SafariImporter(const base::FilePath& library_dir)
- : library_dir_(library_dir) {
-}
-
-SafariImporter::~SafariImporter() {
-}
-
-// static
-bool SafariImporter::CanImport(const base::FilePath& library_dir,
- uint16* services_supported) {
- DCHECK(services_supported);
- *services_supported = importer::NONE;
-
- // Import features are toggled by the following:
- // bookmarks import: existence of ~/Library/Safari/Bookmarks.plist file.
- // history import: existence of ~/Library/Safari/History.plist file.
- base::FilePath safari_dir = library_dir.Append("Safari");
- base::FilePath bookmarks_path = safari_dir.Append("Bookmarks.plist");
- base::FilePath history_path = safari_dir.Append("History.plist");
-
- if (base::PathExists(bookmarks_path))
- *services_supported |= importer::FAVORITES;
- if (base::PathExists(history_path))
- *services_supported |= importer::HISTORY;
-
- return *services_supported != importer::NONE;
-}
-
-void SafariImporter::StartImport(const importer::SourceProfile& source_profile,
- uint16 items,
- ImporterBridge* bridge) {
- bridge_ = bridge;
- // The order here is important!
- bridge_->NotifyStarted();
-
- // In keeping with import on other platforms (and for other browsers), we
- // don't import the home page (since it may lead to a useless homepage); see
- // crbug.com/25603.
- if ((items & importer::HISTORY) && !cancelled()) {
- bridge_->NotifyItemStarted(importer::HISTORY);
- ImportHistory();
- bridge_->NotifyItemEnded(importer::HISTORY);
- }
- if ((items & importer::FAVORITES) && !cancelled()) {
- bridge_->NotifyItemStarted(importer::FAVORITES);
- ImportBookmarks();
- bridge_->NotifyItemEnded(importer::FAVORITES);
- }
- if ((items & importer::PASSWORDS) && !cancelled()) {
- bridge_->NotifyItemStarted(importer::PASSWORDS);
- ImportPasswords();
- bridge_->NotifyItemEnded(importer::PASSWORDS);
- }
- bridge_->NotifyEnded();
-}
-
-void SafariImporter::ImportBookmarks() {
- string16 toolbar_name =
- bridge_->GetLocalizedString(IDS_BOOKMARK_BAR_FOLDER_NAME);
- std::vector<ImportedBookmarkEntry> bookmarks;
- ParseBookmarks(toolbar_name, &bookmarks);
-
- // Write bookmarks into profile.
- if (!bookmarks.empty() && !cancelled()) {
- const string16& first_folder_name =
- bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_SAFARI);
- bridge_->AddBookmarks(bookmarks, first_folder_name);
- }
-
- // Import favicons.
- sql::Connection db;
- if (!OpenDatabase(&db))
- return;
-
- FaviconMap favicon_map;
- ImportFaviconURLs(&db, &favicon_map);
- // Write favicons into profile.
- if (!favicon_map.empty() && !cancelled()) {
- std::vector<ImportedFaviconUsage> favicons;
- LoadFaviconData(&db, favicon_map, &favicons);
- bridge_->SetFavicons(favicons);
- }
-}
-
-bool SafariImporter::OpenDatabase(sql::Connection* db) {
- // Construct ~/Library/Safari/WebIcons.db path.
- NSString* library_dir = [NSString
- stringWithUTF8String:library_dir_.value().c_str()];
- NSString* safari_dir = [library_dir
- stringByAppendingPathComponent:@"Safari"];
- NSString* favicons_db_path = [safari_dir
- stringByAppendingPathComponent:@"WebpageIcons.db"];
-
- const char* db_path = [favicons_db_path fileSystemRepresentation];
- return db->Open(base::FilePath(db_path));
-}
-
-void SafariImporter::ImportFaviconURLs(sql::Connection* db,
- FaviconMap* favicon_map) {
- const char* query = "SELECT iconID, url FROM PageURL;";
- sql::Statement s(db->GetUniqueStatement(query));
-
- while (s.Step() && !cancelled()) {
- int64 icon_id = s.ColumnInt64(0);
- GURL url = GURL(s.ColumnString(1));
- (*favicon_map)[icon_id].insert(url);
- }
-}
-
-void SafariImporter::LoadFaviconData(
- sql::Connection* db,
- const FaviconMap& favicon_map,
- std::vector<ImportedFaviconUsage>* favicons) {
- const char* query = "SELECT i.url, d.data "
- "FROM IconInfo i JOIN IconData d "
- "ON i.iconID = d.iconID "
- "WHERE i.iconID = ?;";
- sql::Statement s(db->GetUniqueStatement(query));
-
- for (FaviconMap::const_iterator i = favicon_map.begin();
- i != favicon_map.end(); ++i) {
- s.Reset(true);
- s.BindInt64(0, i->first);
- if (s.Step()) {
- ImportedFaviconUsage usage;
-
- usage.favicon_url = GURL(s.ColumnString(0));
- if (!usage.favicon_url.is_valid())
- continue; // Don't bother importing favicons with invalid URLs.
-
- std::vector<unsigned char> data;
- s.ColumnBlobAsVector(1, &data);
- if (data.empty())
- continue; // Data definitely invalid.
-
- if (!ReencodeFavicon(&data[0], data.size(), &usage.png_data))
- continue; // Unable to decode.
-
- usage.urls = i->second;
- favicons->push_back(usage);
- }
- }
-}
-
-void SafariImporter::RecursiveReadBookmarksFolder(
- NSDictionary* bookmark_folder,
- const std::vector<string16>& parent_path_elements,
- bool is_in_toolbar,
- const string16& toolbar_name,
- std::vector<ImportedBookmarkEntry>* out_bookmarks) {
- DCHECK(bookmark_folder);
-
- NSString* type = [bookmark_folder objectForKey:@"WebBookmarkType"];
- NSString* title = [bookmark_folder objectForKey:@"Title"];
-
- // Are we the dictionary that contains all other bookmarks?
- // We need to know this so we don't add it to the path.
- bool is_top_level_bookmarks_container = [bookmark_folder
- objectForKey:@"WebBookmarkFileVersion"] != nil;
-
- // We're expecting a list of bookmarks here, if that isn't what we got, fail.
- if (!is_top_level_bookmarks_container) {
- // Top level containers sometimes don't have title attributes.
- if (![type isEqualToString:@"WebBookmarkTypeList"] || !title) {
- NOTREACHED() << "Type=("
- << (type ? base::SysNSStringToUTF8(type) : "Null type")
- << ") Title=("
- << (title ? base::SysNSStringToUTF8(title) : "Null title")
- << ")";
- return;
- }
- }
-
- NSArray* elements = [bookmark_folder objectForKey:@"Children"];
- if (!elements && (!parent_path_elements.empty() || !is_in_toolbar)) {
- // This is an empty folder, so add it explicitly; but don't add the toolbar
- // folder if it is empty. Note that all non-empty folders are added
- // implicitly when their children are added.
- ImportedBookmarkEntry entry;
- // Safari doesn't specify a creation time for the folder.
- entry.creation_time = base::Time::Now();
- entry.title = base::SysNSStringToUTF16(title);
- entry.path = parent_path_elements;
- entry.in_toolbar = is_in_toolbar;
- entry.is_folder = true;
-
- out_bookmarks->push_back(entry);
- return;
- }
-
- std::vector<string16> path_elements(parent_path_elements);
- // Create a folder for the toolbar, but not for the bookmarks menu.
- if (path_elements.empty() && [title isEqualToString:@"BookmarksBar"]) {
- is_in_toolbar = true;
- path_elements.push_back(toolbar_name);
- } else if (!is_top_level_bookmarks_container &&
- !(path_elements.empty() &&
- [title isEqualToString:@"BookmarksMenu"])) {
- if (title)
- path_elements.push_back(base::SysNSStringToUTF16(title));
- }
-
- // Iterate over individual bookmarks.
- for (NSDictionary* bookmark in elements) {
- NSString* type = [bookmark objectForKey:@"WebBookmarkType"];
- if (!type)
- continue;
-
- // If this is a folder, recurse.
- if ([type isEqualToString:@"WebBookmarkTypeList"]) {
- RecursiveReadBookmarksFolder(bookmark,
- path_elements,
- is_in_toolbar,
- toolbar_name,
- out_bookmarks);
- }
-
- // If we didn't see a bookmark folder, then we're expecting a bookmark
- // item. If that's not what we got then ignore it.
- if (![type isEqualToString:@"WebBookmarkTypeLeaf"])
- continue;
-
- NSString* url = [bookmark objectForKey:@"URLString"];
- NSString* title = [[bookmark objectForKey:@"URIDictionary"]
- objectForKey:@"title"];
-
- if (!url || !title)
- continue;
-
- // Output Bookmark.
- ImportedBookmarkEntry entry;
- // Safari doesn't specify a creation time for the bookmark.
- entry.creation_time = base::Time::Now();
- entry.title = base::SysNSStringToUTF16(title);
- entry.url = GURL(base::SysNSStringToUTF8(url));
- entry.path = path_elements;
- entry.in_toolbar = is_in_toolbar;
-
- out_bookmarks->push_back(entry);
- }
-}
-
-void SafariImporter::ParseBookmarks(
- const string16& toolbar_name,
- std::vector<ImportedBookmarkEntry>* bookmarks) {
- DCHECK(bookmarks);
-
- // Construct ~/Library/Safari/Bookmarks.plist path
- NSString* library_dir = [NSString
- stringWithUTF8String:library_dir_.value().c_str()];
- NSString* safari_dir = [library_dir
- stringByAppendingPathComponent:@"Safari"];
- NSString* bookmarks_plist = [safari_dir
- stringByAppendingPathComponent:@"Bookmarks.plist"];
-
- // Load the plist file.
- NSDictionary* bookmarks_dict = [NSDictionary
- dictionaryWithContentsOfFile:bookmarks_plist];
- if (!bookmarks_dict)
- return;
-
- // Recursively read in bookmarks.
- std::vector<string16> parent_path_elements;
- RecursiveReadBookmarksFolder(bookmarks_dict, parent_path_elements, false,
- toolbar_name, bookmarks);
-}
-
-void SafariImporter::ImportPasswords() {
- // Safari stores it's passwords in the Keychain, same as us so we don't need
- // to import them.
- // Note: that we don't automatically pick them up, there is some logic around
- // the user needing to explicitly input his username in a page and blurring
- // the field before we pick it up, but the details of that are beyond the
- // scope of this comment.
-}
-
-void SafariImporter::ImportHistory() {
- std::vector<ImporterURLRow> rows;
- ParseHistoryItems(&rows);
-
- if (!rows.empty() && !cancelled()) {
- bridge_->SetHistoryItems(rows, importer::VISIT_SOURCE_SAFARI_IMPORTED);
- }
-}
-
-double SafariImporter::HistoryTimeToEpochTime(NSString* history_time) {
- DCHECK(history_time);
- // Add Difference between Unix epoch and CFAbsoluteTime epoch in seconds.
- // Unix epoch is 1970-01-01 00:00:00.0 UTC,
- // CF epoch is 2001-01-01 00:00:00.0 UTC.
- return CFStringGetDoubleValue(base::mac::NSToCFCast(history_time)) +
- kCFAbsoluteTimeIntervalSince1970;
-}
-
-void SafariImporter::ParseHistoryItems(
- std::vector<ImporterURLRow>* history_items) {
- DCHECK(history_items);
-
- // Construct ~/Library/Safari/History.plist path
- NSString* library_dir = [NSString
- stringWithUTF8String:library_dir_.value().c_str()];
- NSString* safari_dir = [library_dir
- stringByAppendingPathComponent:@"Safari"];
- NSString* history_plist = [safari_dir
- stringByAppendingPathComponent:@"History.plist"];
-
- // Load the plist file.
- NSDictionary* history_dict = [NSDictionary
- dictionaryWithContentsOfFile:history_plist];
- if (!history_dict)
- return;
-
- NSArray* safari_history_items = [history_dict
- objectForKey:@"WebHistoryDates"];
-
- for (NSDictionary* history_item in safari_history_items) {
- NSString* url_ns = [history_item objectForKey:@""];
- if (!url_ns)
- continue;
-
- GURL url(base::SysNSStringToUTF8(url_ns));
-
- if (!CanImportSafariURL(url))
- continue;
-
- ImporterURLRow row(url);
- NSString* title_ns = [history_item objectForKey:@"title"];
-
- // Sometimes items don't have a title, in which case we just substitue
- // the url.
- if (!title_ns)
- title_ns = url_ns;
-
- row.title = base::SysNSStringToUTF16(title_ns);
- int visit_count = [[history_item objectForKey:@"visitCount"]
- intValue];
- row.visit_count = visit_count;
- // Include imported URLs in autocompletion - don't hide them.
- row.hidden = 0;
- // Item was never typed before in the omnibox.
- row.typed_count = 0;
-
- NSString* last_visit_str = [history_item objectForKey:@"lastVisitedDate"];
- // The last visit time should always be in the history item, but if not
- /// just continue without this item.
- DCHECK(last_visit_str);
- if (!last_visit_str)
- continue;
-
- // Convert Safari's last visit time to Unix Epoch time.
- double seconds_since_unix_epoch = HistoryTimeToEpochTime(last_visit_str);
- row.last_visit = base::Time::FromDoubleT(seconds_since_unix_epoch);
-
- history_items->push_back(row);
- }
-}
« no previous file with comments | « chrome/browser/importer/safari_importer.h ('k') | chrome/browser/importer/safari_importer_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698