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

Side by Side Diff: chrome/browser/translate/translate_language_list.cc

Issue 15317007: Translate: split supporting language list handling to TranslateLanguageList (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: for review 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
(Empty)
1 // Copyright 2013 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/translate/translate_language_list.h"
6
7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/lazy_instance.h"
10 #include "base/logging.h"
11 #include "base/string_util.h"
12 #include "base/values.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/translate/translate_url_util.h"
15 #include "chrome/common/chrome_switches.h"
16 #include "googleurl/src/gurl.h"
17 #include "net/base/load_flags.h"
18 #include "net/base/url_util.h"
19 #include "net/http/http_status_code.h"
20 #include "net/url_request/url_fetcher.h"
21 #include "net/url_request/url_request_status.h"
22
23 namespace {
24
25 // The default list of languages the Google translation server supports.
26 // We use this list until we receive the list that the server exposes.
27 // For information, here is the list of languages that Chrome can be run in
28 // but that the translation server does not support:
29 // am Amharic
30 // bn Bengali
31 // gu Gujarati
32 // kn Kannada
33 // ml Malayalam
34 // mr Marathi
35 // ta Tamil
36 // te Telugu
37 const char* const kDefaultSupportedLanguages[] = {
38 "af", // Afrikaans
39 "sq", // Albanian
40 "ar", // Arabic
41 "be", // Belarusian
42 "bg", // Bulgarian
43 "ca", // Catalan
44 "zh-CN", // Chinese (Simplified)
45 "zh-TW", // Chinese (Traditional)
46 "hr", // Croatian
47 "cs", // Czech
48 "da", // Danish
49 "nl", // Dutch
50 "en", // English
51 "eo", // Esperanto
52 "et", // Estonian
53 "tl", // Filipino
54 "fi", // Finnish
55 "fr", // French
56 "gl", // Galician
57 "de", // German
58 "el", // Greek
59 "ht", // Haitian Creole
60 "iw", // Hebrew
61 "hi", // Hindi
62 "hu", // Hungarian
63 "is", // Icelandic
64 "id", // Indonesian
65 "ga", // Irish
66 "it", // Italian
67 "ja", // Japanese
68 "ko", // Korean
69 "lv", // Latvian
70 "lt", // Lithuanian
71 "mk", // Macedonian
72 "ms", // Malay
73 "mt", // Maltese
74 "no", // Norwegian
75 "fa", // Persian
76 "pl", // Polish
77 "pt", // Portuguese
78 "ro", // Romanian
79 "ru", // Russian
80 "sr", // Serbian
81 "sk", // Slovak
82 "sl", // Slovenian
83 "es", // Spanish
84 "sw", // Swahili
85 "sv", // Swedish
86 "th", // Thai
87 "tr", // Turkish
88 "uk", // Ukrainian
89 "vi", // Vietnamese
90 "cy", // Welsh
91 "yi", // Yiddish
92 };
93
94 // Constant URL string to fetch server supporting language list.
95 const char kLanguageListFetchURL[] =
96 "https://translate.googleapis.com/translate_a/l?client=chrome&cb=sl";
97
98 // Used in kTranslateScriptURL to request supporting languages list including
99 // "alpha languages".
100 const char kAlphaLanguageQueryName[] = "alpha";
101 const char kAlphaLanguageQueryValue[] = "1";
102
103 // Retry parameter for fetching supporting language list.
104 const int kMaxRetryLanguageListFetch = 5;
105
106 // The languages supported by the translation server.
107 base::LazyInstance<std::set<std::string> > supported_languages =
108 LAZY_INSTANCE_INITIALIZER;
109
110 // Initializes the list of supported languages if it wasn't initialized before
111 // in case we failed to get them from the server, or didn't get them just yet.
112 void InitSupportedLanguages() {
113 // If our list of supported languages have not been set yet, we default
114 // to our hard coded list of languages in kDefaultSupportedLanguages.
115 std::set<std::string>* set = supported_languages.Pointer();
116 if (set->empty()) {
117 for (size_t i = 0; i < arraysize(kDefaultSupportedLanguages); ++i)
118 set->insert(kDefaultSupportedLanguages[i]);
119 }
120 }
121
122 // Fills supported_languages with the list of languages that the translate
123 // server can translate to and from.
124 void SetSupportedLanguages(const std::string& language_list) {
125 // The format is:
126 // sl({"sl": {"XX": "LanguageName", ...}, "tl": {"XX": "LanguageName", ...}})
127 // Where "sl(" is set in kLanguageListCallbackName
128 // and "tl" is kTargetLanguagesKey
129 if (!StartsWithASCII(language_list,
130 TranslateLanguageList::kLanguageListCallbackName,
131 false) ||
132 !EndsWith(language_list, ")", false)) {
133 // We don't have a NOTREACHED here since this can happen in ui_tests, even
134 // though the the BrowserMain function won't call us with parameters.ui_task
135 // is NULL some tests don't set it, so we must bail here.
136 return;
137 }
138 static const size_t kLanguageListCallbackNameLength =
139 strlen(TranslateLanguageList::kLanguageListCallbackName);
140 std::string languages_json = language_list.substr(
141 kLanguageListCallbackNameLength,
142 language_list.size() - kLanguageListCallbackNameLength - 1);
143 scoped_ptr<Value> json_value(
144 base::JSONReader::Read(languages_json, base::JSON_ALLOW_TRAILING_COMMAS));
145 if (json_value == NULL || !json_value->IsType(Value::TYPE_DICTIONARY)) {
146 NOTREACHED();
147 return;
148 }
149 // The first level dictionary contains two sub-dict, one for source languages
150 // and the other for target languages, we want to use the target languages.
151 DictionaryValue* language_dict =
152 static_cast<DictionaryValue*>(json_value.get());
153 DictionaryValue* target_languages = NULL;
154 if (!language_dict->GetDictionary(TranslateLanguageList::kTargetLanguagesKey,
155 &target_languages) ||
156 target_languages == NULL) {
157 NOTREACHED();
158 return;
159 }
160 // Now we can clear our current state...
161 std::set<std::string>* set = supported_languages.Pointer();
162 set->clear();
163 // ... and replace it with the values we just fetched from the server.
164 for (DictionaryValue::Iterator iter(*target_languages);
165 !iter.IsAtEnd();
166 iter.Advance()) {
167 set->insert(iter.key());
168 }
169 }
170
171 } // namespace
172
173 // This must be kept in sync with the &cb= value in the kLanguageListFetchURL.
174 const char TranslateLanguageList::kLanguageListCallbackName[] = "sl(";
175 const char TranslateLanguageList::kTargetLanguagesKey[] = "tl";
176
177 TranslateLanguageList* TranslateLanguageList::GetInstance() {
178 return Singleton<TranslateLanguageList>::get();
179 }
180
181 TranslateLanguageList::~TranslateLanguageList() {}
182
183 void TranslateLanguageList::OnURLFetchComplete(const net::URLFetcher* source) {
184 DCHECK(url_fetcher_.get() == source);
185
186 scoped_ptr<const net::URLFetcher> delete_ptr(url_fetcher_.release());
187
188 if (source->GetStatus().status() == net::URLRequestStatus::SUCCESS &&
189 source->GetResponseCode() == net::HTTP_OK) {
190 std::string data;
191 source->GetResponseAsString(&data);
192 SetSupportedLanguages(data);
193 } else {
194 VLOG(9) << "Failed to Fetch languages from: " << kLanguageListFetchURL;
195 }
196 }
197
198 // static
199 void TranslateLanguageList::GetSupportedLanguages(
200 std::vector<std::string>* languages) {
201 DCHECK(languages && languages->empty());
202 InitSupportedLanguages();
203 std::set<std::string>* set = supported_languages.Pointer();
204 std::set<std::string>::const_iterator iter = set->begin();
205 for (; iter != set->end(); ++iter)
206 languages->push_back(*iter);
207 }
208
209 // static
210 bool TranslateLanguageList::IsSupportedLanguage(
211 const std::string& page_language) {
212 InitSupportedLanguages();
213 return supported_languages.Pointer()->count(page_language) != 0;
214 }
215
216 // static
217 std::string TranslateLanguageList::GetLanguageCode(
218 const std::string& chrome_locale) {
219 // Only remove the country code for country specific languages we don't
220 // support specifically yet.
221 if (IsSupportedLanguage(chrome_locale))
222 return chrome_locale;
223
224 size_t hypen_index = chrome_locale.find('-');
225 if (hypen_index == std::string::npos)
226 return chrome_locale;
227 return chrome_locale.substr(0, hypen_index);
228 }
229
230 TranslateLanguageList::TranslateLanguageList() {}
231
232 // static
233 void TranslateLanguageList::RequestLanguageList() {
234 GURL language_list_fetch_url = GURL(kLanguageListFetchURL);
235 language_list_fetch_url =
236 TranslateURLUtil::AddHostLocaleToUrl(language_list_fetch_url);
237 language_list_fetch_url =
238 TranslateURLUtil::AddApiKeyToUrl(language_list_fetch_url);
239
240 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
241 if (command_line.HasSwitch(switches::kEnableTranslateAlphaLanguages)) {
242 language_list_fetch_url = net::AppendQueryParameter(
243 language_list_fetch_url,
244 kAlphaLanguageQueryName,
245 kAlphaLanguageQueryValue);
246 }
247
248 VLOG(9) << "Fetch supporting language list from: "
249 << language_list_fetch_url.spec().c_str();
250
251 TranslateLanguageList* instance = GetInstance();
252 DCHECK(instance);
253
254 instance->url_fetcher_.reset(net::URLFetcher::Create(1,
255 language_list_fetch_url,
256 net::URLFetcher::GET,
257 instance));
258 instance->url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
259 net::LOAD_DO_NOT_SAVE_COOKIES);
260 instance->url_fetcher_->SetRequestContext(
261 g_browser_process->system_request_context());
262 instance->url_fetcher_->SetMaxRetriesOn5xx(kMaxRetryLanguageListFetch);
263 instance->url_fetcher_->Start();
264 }
265
266 // static
267 bool TranslateLanguageList::HasPendingRequest() {
268 TranslateLanguageList* instance = GetInstance();
269 DCHECK(instance);
270 return instance->url_fetcher_.get() != NULL;
271 }
272
273 // static
274 void TranslateLanguageList::ResetPendingRequest() {
275 TranslateLanguageList* instance = GetInstance();
276 DCHECK(instance);
277 instance->url_fetcher_.reset();
278 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698