diff options
author | Bjorn Bringert <bringert@android.com> | 2010-09-13 14:06:41 +0100 |
---|---|---|
committer | Bjorn Bringert <bringert@android.com> | 2010-09-13 17:56:31 +0100 |
commit | d26706538834e0ed58bf28f08d9a2885c0e7efcb (patch) | |
tree | 13438ea88016cbbbec1543b4927065c3f2841f07 /tools | |
parent | 88ec7e4870391af9a193957222fd6ded16b9c546 (diff) | |
download | packages_apps_Browser-d26706538834e0ed58bf28f08d9a2885c0e7efcb.zip packages_apps_Browser-d26706538834e0ed58bf28f08d9a2885c0e7efcb.tar.gz packages_apps_Browser-d26706538834e0ed58bf28f08d9a2885c0e7efcb.tar.bz2 |
Add user-selected search providers to browser
The lists of search providers are taken from Chrome.
Change-Id: I7af6dc1258950d1fc5cf86013f8be9f3c5db0f1a
Diffstat (limited to 'tools')
-rw-r--r-- | tools/all_search_engines.template.xml | 40 | ||||
-rwxr-xr-x | tools/get_search_engines.py | 258 | ||||
-rwxr-xr-x | tools/search_engines.template.xml | 24 |
3 files changed, 322 insertions, 0 deletions
diff --git a/tools/all_search_engines.template.xml b/tools/all_search_engines.template.xml new file mode 100644 index 0000000..a8d0c89 --- /dev/null +++ b/tools/all_search_engines.template.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + + +<!-- +**** +**** THIS FILE WAS GENERATED BY tools/get_search_engines.py +**** + +Each string-array item below refers to one search engine in a specific locale, and the name of the +item is referred to by the <engine_X_name> items in the locale specific search_engines.xml file. + +Format: + - Human readable label + - Keyword: empty string if the engine has no keyword. (currently unused) + - Favicon URL + - Search URL + - Encoding + - Suggest URL: empty string if this engine has no suggest feature + +The parameters enclosed in curly braces come from the OpenSearch specification, see +http://www.opensearch.org/Specifications/OpenSearch/1.1/Draft_4#OpenSearch_1.1_parameters +--> + +<resources> +</resources> + diff --git a/tools/get_search_engines.py b/tools/get_search_engines.py new file mode 100755 index 0000000..2eecec3 --- /dev/null +++ b/tools/get_search_engines.py @@ -0,0 +1,258 @@ +#!/usr/bin/python2.4 +# +# Copyright (C) 2010 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +""" +Creates the list of search engines + +The created list is placed in the res/values-<locale> directory. Also updates +res/values/all_search_engines.xml if required with new data. + +Usage: get_search_engines.py + +Copyright (C) 2010 The Android Open Source Project +""" + +import os +import re +import sys +import urllib +from xml.dom import minidom + +# Locales to generate search engine lists for +locales = ["cs-CZ", "da-DK", "de-AT", "de-CH", "de-DE", "el-GR", "en-AU", + "en-GB", "en-IE", "en-NZ", "en-SG", "en-ZA", "es-ES", "fr-BE", "fr-FR", + "it-IT", "ja-JP", "ko-KR", "nb-NO", "nl-BE", "nl-NL", "pl-PL", "pt-PT", + "pt-BR", "ru-RU", "sv-SE", "tr-TR", "zh-CN", "zh-HK", "zh-MO", "zh-TW"] + +class SearchEngineManager(object): + """Manages list of search engines and creates locale specific lists. + + The main method useful for the caller is generateListForLocale(), which + creates a locale specific search_engines.xml file suitable for use by the + Android WebSearchProvider implementation. + """ + + def __init__(self): + """Inits SearchEngineManager with relevant search engine data. + + The search engine data is downloaded from the Chrome source repository. + """ + self.chrome_data = urllib.urlopen( + 'http://src.chromium.org/viewvc/chrome/trunk/src/chrome/' + 'browser/search_engines/template_url_prepopulate_data.cc').read() + if self.chrome_data.lower().find('repository not found') != -1: + print 'Unable to get Chrome source data for search engine list.\nExiting.' + sys.exit(2) + + self.resdir = os.path.normpath(os.path.join(sys.path[0], '../res')) + + self.all_engines = set() + + def getXmlString(self, str): + """Returns an XML-safe string for the given string. + + Given a string from the search engine data structure, convert it to a + string suitable to write to our XML data file by stripping away NULLs, + unwanted quotes, wide-string declarations (L"") and replacing C-style + unicode characters with XML equivalents. + """ + str = str.strip() + if str.upper() == 'NULL': + return '' + + if str.startswith('L"'): + str = str[2:] + if str.startswith('@') or str.startswith('?'): + str = '\\' + str + + str = str.strip('"') + str = str.replace('&', '&').replace('<', '<').replace('>', '>') + str = str.replace('"', '"').replace('\'', ''') + str = re.sub(r'\\x([a-fA-F0-9]+)', r'&#x\1;', str) + + return str + + def getEngineData(self, name): + """Returns an array of strings describing the specified search engine. + + The returned strings are in the same order as in the Chrome source data file + except that the internal name of the search engine is inserted at the + beginning of the list. + """ + # Find the first occurance of this search engine name in the form + # " <name> =" in the chrome data file. + re_exp = '\s' + name + '\s*=' + search_obj = re.search(re_exp, self.chrome_data) + if not search_obj: + print ('Unable to find data for search engine ' + name + + '. Please check the chrome data file for format changes.') + return None + + # Extract the struct declaration between the curly braces. + start_pos = self.chrome_data.find('{', search_obj.start()) + 1; + end_pos = self.chrome_data.find('};', start_pos); + engine_data_str = self.chrome_data[start_pos:end_pos] + + # Remove c++ style '//' comments at the ends of each line + engine_data_lines = engine_data_str.split('\n') + engine_data_str = "" + for line in engine_data_lines: + start_pos = line.find(' // ') + if start_pos != -1: + line = line[:start_pos] + engine_data_str = engine_data_str + line + '\n' + + # Join multiple line strings into a single string. + engine_data_str = re.sub('\"\s+\"', '', engine_data_str) + engine_data_str = re.sub('\"\s+L\"', '', engine_data_str) + engine_data_str = engine_data_str.replace('"L"', '') + + engine_data = engine_data_str.split(',') + for i in range(len(engine_data)): + engine_data[i] = self.getXmlString(engine_data[i]) + + # If the last element was an empty string (due to an extra comma at the + # end), ignore it. + if not engine_data[len(engine_data) - 1]: + engine_data.pop() + + engine_data.insert(0, name) + + return engine_data + + def getSearchEnginesForCountry(self, country): + """Returns the list of search engine names for the given country. + + The data comes from the Chrome data file. + """ + # The Chrome data file has an array defined with the name 'engines_XX' + # where XX = country. + pos = self.chrome_data.find('engines_' + country) + if pos == -1: + print ('Unable to find search engine data for country ' + country + '.') + return + + # Extract the text between the curly braces for this array declaration + engines_start = self.chrome_data.find('{', pos) + 1; + engines_end = self.chrome_data.find('}', engines_start); + engines_str = self.chrome_data[engines_start:engines_end] + + # Remove embedded /**/ style comments, white spaces, address-of operators + # and the trailing comma if any. + engines_str = re.sub('\/\*.+\*\/', '', engines_str) + engines_str = re.sub('\s+', '', engines_str) + engines_str = engines_str.replace('&','') + engines_str = engines_str.rstrip(',') + + # Split the array into it's elements + engines = engines_str.split(',') + + return engines + + def writeAllEngines(self): + """Writes all search engines to the all_search_engines.xml file. + """ + + all_search_engines_path = os.path.join(self.resdir, 'values/all_search_engines.xml') + + text = [] + + for engine_name in self.all_engines: + engine_data = self.getEngineData(engine_name) + text.append(' <string-array name="%s" translatable="false">\n' % (engine_data[0])) + for i in range(1, 7): + text.append(' <item>%s</item>\n' % (engine_data[i])) + text.append(' </string-array>\n') + print engine_data[1] + " added to all_search_engines.xml" + + self.generateXmlFromTemplate(os.path.join(sys.path[0], 'all_search_engines.template.xml'), + all_search_engines_path, text) + + def generateDefaultList(self): + self.writeEngineList(os.path.join(self.resdir, 'values'), "default") + + def generateListForLocale(self, locale): + """Creates a new locale specific search_engines.xml file. + + The new file contains search engines specific to that country. If required + this function updates all_search_engines.xml file with any new search + engine data necessary. + """ + separator_pos = locale.find('-') + if separator_pos == -1: + print ('Locale must be of format <language>-<country>. For e.g.' + ' "es-US" or "en-GB"') + return + + language = locale[0:separator_pos] + country = locale[separator_pos + 1:].upper() + dir_path = os.path.join(self.resdir, 'values-' + language + '-r' + country) + + self.writeEngineList(dir_path, country) + + def writeEngineList(self, dir_path, country): + if os.path.exists(dir_path) and not os.path.isdir(dir_path): + print "File exists in output directory path " + dir_path + ". Please remove it and try again." + return + + engines = self.getSearchEnginesForCountry(country) + if not engines: + return + for engine in engines: + self.all_engines.add(engine) + + # Create the locale specific search_engines.xml file. Each + # search_engines.xml file has a hardcoded list of 7 items. If there are less + # than 7 search engines for this country, the remaining items are marked as + # enabled=false. + text = [] + text.append(' <string-array name="search_engines" translatable="false">\n'); + for engine in engines: + engine_data = self.getEngineData(engine) + name = engine_data[0] + text.append(' <item>%s</item>\n' % (name)) + text.append(' </string-array>\n'); + + self.generateXmlFromTemplate(os.path.join(sys.path[0], 'search_engines.template.xml'), + os.path.join(dir_path, 'search_engines.xml'), + text) + + def generateXmlFromTemplate(self, template_path, out_path, text): + # Load the template file and insert the new contents before the last line. + template_text = open(template_path).read() + pos = template_text.rfind('\n', 0, -2) + 1 + contents = template_text[0:pos] + ''.join(text) + template_text[pos:] + + # Make sure what we have created is valid XML :) No need to check for errors + # as the script will terminate with an exception if the XML was malformed. + engines_dom = minidom.parseString(contents) + + dir_path = os.path.dirname(out_path) + if not os.path.exists(dir_path): + os.makedirs(dir_path) + print 'Created directory ' + dir_path + file = open(out_path, 'w') + file.write(contents) + file.close() + print 'Wrote ' + out_path + +if __name__ == "__main__": + manager = SearchEngineManager() + manager.generateDefaultList() + for locale in locales: + manager.generateListForLocale(locale) + manager.writeAllEngines() + diff --git a/tools/search_engines.template.xml b/tools/search_engines.template.xml new file mode 100755 index 0000000..553d333 --- /dev/null +++ b/tools/search_engines.template.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<!-- +**** +**** THIS FILE WAS GENERATED BY tools/get_search_engines.py +**** + +Each value in the string-array is the name of a value in all_search_engines.xml +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> +</resources> |