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

Side by Side Diff: chrome/browser/importer/firefox_importer_utils.cc

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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/importer/firefox_importer_utils.h"
6
7 #include <algorithm>
8 #include <map>
9 #include <string>
10
11 #include "base/file_util.h"
12 #include "base/ini_parser.h"
13 #include "base/logging.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_split.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/values.h"
19 #include "grit/generated_resources.h"
20 #include "ui/base/l10n/l10n_util.h"
21 #include "url/gurl.h"
22
23 base::FilePath GetFirefoxProfilePath() {
24 base::FilePath ini_file = GetProfilesINI();
25 std::string content;
26 file_util::ReadFileToString(ini_file, &content);
27 base::DictionaryValueINIParser ini_parser;
28 ini_parser.Parse(content);
29 const DictionaryValue& root = ini_parser.root();
30
31 base::FilePath source_path;
32 for (int i = 0; ; ++i) {
33 std::string current_profile = base::StringPrintf("Profile%d", i);
34 if (!root.HasKey(current_profile)) {
35 // Profiles are continuously numbered. So we exit when we can't
36 // find the i-th one.
37 break;
38 }
39 std::string is_relative;
40 string16 path16;
41 if (root.GetStringASCII(current_profile + ".IsRelative", &is_relative) &&
42 root.GetString(current_profile + ".Path", &path16)) {
43 #if defined(OS_WIN)
44 ReplaceSubstringsAfterOffset(
45 &path16, 0, ASCIIToUTF16("/"), ASCIIToUTF16("\\"));
46 #endif
47 base::FilePath path =
48 base::FilePath::FromWStringHack(UTF16ToWide(path16));
49
50 // IsRelative=1 means the folder path would be relative to the
51 // path of profiles.ini. IsRelative=0 refers to a custom profile
52 // location.
53 if (is_relative == "1") {
54 path = ini_file.DirName().Append(path);
55 }
56
57 // We only import the default profile when multiple profiles exist,
58 // since the other profiles are used mostly by developers for testing.
59 // Otherwise, Profile0 will be imported.
60 std::string is_default;
61 if ((root.GetStringASCII(current_profile + ".Default", &is_default) &&
62 is_default == "1") || i == 0) {
63 // We have found the default profile.
64 return path;
65 }
66 }
67 }
68 return base::FilePath();
69 }
70
71
72 bool GetFirefoxVersionAndPathFromProfile(const base::FilePath& profile_path,
73 int* version,
74 base::FilePath* app_path) {
75 bool ret = false;
76 base::FilePath compatibility_file =
77 profile_path.AppendASCII("compatibility.ini");
78 std::string content;
79 file_util::ReadFileToString(compatibility_file, &content);
80 ReplaceSubstringsAfterOffset(&content, 0, "\r\n", "\n");
81 std::vector<std::string> lines;
82 base::SplitString(content, '\n', &lines);
83
84 for (size_t i = 0; i < lines.size(); ++i) {
85 const std::string& line = lines[i];
86 if (line.empty() || line[0] == '#' || line[0] == ';')
87 continue;
88 size_t equal = line.find('=');
89 if (equal != std::string::npos) {
90 std::string key = line.substr(0, equal);
91 if (key == "LastVersion") {
92 base::StringToInt(line.substr(equal + 1), version);
93 ret = true;
94 } else if (key == "LastAppDir") {
95 // TODO(evanm): If the path in question isn't convertible to
96 // UTF-8, what does Firefox do? If it puts raw bytes in the
97 // file, we could go straight from bytes -> filepath;
98 // otherwise, we're out of luck here.
99 *app_path = base::FilePath::FromWStringHack(
100 UTF8ToWide(line.substr(equal + 1)));
101 }
102 }
103 }
104 return ret;
105 }
106
107 bool CanImportURL(const GURL& url) {
108 const char* kInvalidSchemes[] = {"wyciwyg", "place", "about", "chrome"};
109
110 // The URL is not valid.
111 if (!url.is_valid())
112 return false;
113
114 // Filter out the URLs with unsupported schemes.
115 for (size_t i = 0; i < arraysize(kInvalidSchemes); ++i) {
116 if (url.SchemeIs(kInvalidSchemes[i]))
117 return false;
118 }
119
120 return true;
121 }
122
123 bool ReadPrefFile(const base::FilePath& path, std::string* content) {
124 if (content == NULL)
125 return false;
126
127 file_util::ReadFileToString(path, content);
128
129 if (content->empty()) {
130 LOG(WARNING) << "Firefox preference file " << path.value() << " is empty.";
131 return false;
132 }
133
134 return true;
135 }
136
137 std::string ReadBrowserConfigProp(const base::FilePath& app_path,
138 const std::string& pref_key) {
139 std::string content;
140 if (!ReadPrefFile(app_path.AppendASCII("browserconfig.properties"), &content))
141 return std::string();
142
143 // This file has the syntax: key=value.
144 size_t prop_index = content.find(pref_key + "=");
145 if (prop_index == std::string::npos)
146 return std::string();
147
148 size_t start = prop_index + pref_key.length();
149 size_t stop = std::string::npos;
150 if (start != std::string::npos)
151 stop = content.find("\n", start + 1);
152
153 if (start == std::string::npos ||
154 stop == std::string::npos || (start == stop)) {
155 LOG(WARNING) << "Firefox property " << pref_key << " could not be parsed.";
156 return std::string();
157 }
158
159 return content.substr(start + 1, stop - start - 1);
160 }
161
162 std::string ReadPrefsJsValue(const base::FilePath& profile_path,
163 const std::string& pref_key) {
164 std::string content;
165 if (!ReadPrefFile(profile_path.AppendASCII("prefs.js"), &content))
166 return std::string();
167
168 return GetPrefsJsValue(content, pref_key);
169 }
170
171 GURL GetHomepage(const base::FilePath& profile_path) {
172 std::string home_page_list =
173 ReadPrefsJsValue(profile_path, "browser.startup.homepage");
174
175 size_t seperator = home_page_list.find_first_of('|');
176 if (seperator == std::string::npos)
177 return GURL(home_page_list);
178
179 return GURL(home_page_list.substr(0, seperator));
180 }
181
182 bool IsDefaultHomepage(const GURL& homepage, const base::FilePath& app_path) {
183 if (!homepage.is_valid())
184 return false;
185
186 std::string default_homepages =
187 ReadBrowserConfigProp(app_path, "browser.startup.homepage");
188
189 size_t seperator = default_homepages.find_first_of('|');
190 if (seperator == std::string::npos)
191 return homepage.spec() == GURL(default_homepages).spec();
192
193 // Crack the string into separate homepage urls.
194 std::vector<std::string> urls;
195 base::SplitString(default_homepages, '|', &urls);
196
197 for (size_t i = 0; i < urls.size(); ++i) {
198 if (homepage.spec() == GURL(urls[i]).spec())
199 return true;
200 }
201
202 return false;
203 }
204
205 bool ParsePrefFile(const base::FilePath& pref_file, DictionaryValue* prefs) {
206 // The string that is before a pref key.
207 const std::string kUserPrefString = "user_pref(\"";
208 std::string contents;
209 if (!file_util::ReadFileToString(pref_file, &contents))
210 return false;
211
212 std::vector<std::string> lines;
213 Tokenize(contents, "\n", &lines);
214
215 for (std::vector<std::string>::const_iterator iter = lines.begin();
216 iter != lines.end(); ++iter) {
217 const std::string& line = *iter;
218 size_t start_key = line.find(kUserPrefString);
219 if (start_key == std::string::npos)
220 continue; // Could be a comment or a blank line.
221 start_key += kUserPrefString.length();
222 size_t stop_key = line.find('"', start_key);
223 if (stop_key == std::string::npos) {
224 LOG(ERROR) << "Invalid key found in Firefox pref file '" <<
225 pref_file.value() << "' line is '" << line << "'.";
226 continue;
227 }
228 std::string key = line.substr(start_key, stop_key - start_key);
229 size_t start_value = line.find(',', stop_key + 1);
230 if (start_value == std::string::npos) {
231 LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
232 pref_file.value() << "' line is '" << line << "'.";
233 continue;
234 }
235 size_t stop_value = line.find(");", start_value + 1);
236 if (stop_value == std::string::npos) {
237 LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
238 pref_file.value() << "' line is '" << line << "'.";
239 continue;
240 }
241 std::string value = line.substr(start_value + 1,
242 stop_value - start_value - 1);
243 TrimWhitespace(value, TRIM_ALL, &value);
244 // Value could be a boolean.
245 bool is_value_true = LowerCaseEqualsASCII(value, "true");
246 if (is_value_true || LowerCaseEqualsASCII(value, "false")) {
247 prefs->SetBoolean(key, is_value_true);
248 continue;
249 }
250
251 // Value could be a string.
252 if (value.size() >= 2U &&
253 value[0] == '"' && value[value.size() - 1] == '"') {
254 value = value.substr(1, value.size() - 2);
255 // ValueString only accept valid UTF-8. Simply ignore that entry if it is
256 // not UTF-8.
257 if (IsStringUTF8(value))
258 prefs->SetString(key, value);
259 else
260 VLOG(1) << "Non UTF8 value for key " << key << ", ignored.";
261 continue;
262 }
263
264 // Or value could be an integer.
265 int int_value = 0;
266 if (base::StringToInt(value, &int_value)) {
267 prefs->SetInteger(key, int_value);
268 continue;
269 }
270
271 LOG(ERROR) << "Invalid value found in Firefox pref file '"
272 << pref_file.value() << "' value is '" << value << "'.";
273 }
274 return true;
275 }
276
277 std::string GetPrefsJsValue(const std::string& content,
278 const std::string& pref_key) {
279 // This file has the syntax: user_pref("key", value);
280 std::string search_for = std::string("user_pref(\"") + pref_key +
281 std::string("\", ");
282 size_t prop_index = content.find(search_for);
283 if (prop_index == std::string::npos)
284 return std::string();
285
286 size_t start = prop_index + search_for.length();
287 size_t stop = std::string::npos;
288 if (start != std::string::npos) {
289 // Stop at the last ')' on this line.
290 stop = content.find("\n", start + 1);
291 stop = content.rfind(")", stop);
292 }
293
294 if (start == std::string::npos || stop == std::string::npos ||
295 stop < start) {
296 LOG(WARNING) << "Firefox property " << pref_key << " could not be parsed.";
297 return std::string();
298 }
299
300 // String values have double quotes we don't need to return to the caller.
301 if (content[start] == '\"' && content[stop - 1] == '\"') {
302 ++start;
303 --stop;
304 }
305
306 return content.substr(start, stop - start);
307 }
308
309 // The branding name is obtained from the application.ini file from the Firefox
310 // application directory. A sample application.ini file is the following:
311 // [App]
312 // Vendor=Mozilla
313 // Name=Iceweasel
314 // Profile=mozilla/firefox
315 // Version=3.5.16
316 // BuildID=20120421070307
317 // Copyright=Copyright (c) 1998 - 2010 mozilla.org
318 // ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
319 // .........................................
320 // In this example the function returns "Iceweasel" (or a localized equivalent).
321 string16 GetFirefoxImporterName(const base::FilePath& app_path) {
322 const base::FilePath app_ini_file = app_path.AppendASCII("application.ini");
323 std::string branding_name;
324 if (base::PathExists(app_ini_file)) {
325 std::string content;
326 file_util::ReadFileToString(app_ini_file, &content);
327 std::vector<std::string> lines;
328 base::SplitString(content, '\n', &lines);
329 const std::string name_attr("Name=");
330 bool in_app_section = false;
331 for (size_t i = 0; i < lines.size(); ++i) {
332 TrimWhitespace(lines[i], TRIM_ALL, &lines[i]);
333 if (lines[i] == "[App]") {
334 in_app_section = true;
335 } else if (in_app_section) {
336 if (lines[i].find(name_attr) == 0) {
337 branding_name = lines[i].substr(name_attr.size());
338 break;
339 } else if (lines[i].length() > 0 && lines[i][0] == '[') {
340 // No longer in the [App] section.
341 break;
342 }
343 }
344 }
345 }
346
347 StringToLowerASCII(&branding_name);
348 if (branding_name.find("iceweasel") != std::string::npos)
349 return l10n_util::GetStringUTF16(IDS_IMPORT_FROM_ICEWEASEL);
350 return l10n_util::GetStringUTF16(IDS_IMPORT_FROM_FIREFOX);
351 }
OLDNEW
« no previous file with comments | « chrome/browser/importer/firefox_importer_utils.h ('k') | chrome/browser/importer/firefox_importer_utils_linux.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698