OLD | NEW |
---|---|
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 import json | 5 import json |
6 import re | 6 import re |
7 | 7 |
8 class SamplesDataSource(object): | 8 class SamplesDataSource(object): |
9 """Constructs a list of samples and their respective files and api calls. | 9 """ Constructs a list of samples and their respective files and api calls. |
not at google - send to devlin
2012/07/23 13:25:37
Heh, I think these leading spaces are just me bein
cduvall
2012/07/23 18:10:37
Done.
| |
10 """ | 10 """ |
11 def __init__(self, fetcher, cache_builder, samples_path): | 11 |
12 self._fetcher = fetcher | 12 class Factory(object): |
13 self._cache = cache_builder.build(self._MakeSamplesList) | 13 """ A factory to create SamplesDataSource instances bound to individual |
14 Requests. | |
15 """ | |
16 def __init__(self, file_system, cache_builder, samples_path): | |
17 self._file_system = file_system | |
18 self._cache = cache_builder.build(self._MakeSamplesList) | |
19 self._samples_path = samples_path | |
20 | |
21 def Create(self, request): | |
22 """ Returns a new SamplesDataSource bound to |request|. | |
23 """ | |
24 return SamplesDataSource(self._cache, | |
25 self._samples_path, | |
26 request) | |
27 | |
28 def _GetApiItems(self, js_file): | |
29 return set(re.findall('(chrome\.[a-zA-Z0-9\.]+)', js_file)) | |
30 | |
31 def _MakeApiLink(self, prefix, item): | |
32 api, name = item.replace('chrome.', '').split('.', 1) | |
33 return api + '.html#' + prefix + '-' + name | |
34 | |
35 def _GetDataFromManifest(self, path): | |
36 manifest = self._file_system.ReadSingleFile(path + '/manifest.json') | |
37 manifest_json = json.loads(manifest) | |
38 l10n_data = { | |
39 'name': manifest_json.get('name', ''), | |
40 'description': manifest_json.get('description', ''), | |
41 'default_locale': manifest_json.get('default_locale', None), | |
42 'locales': {} | |
43 } | |
44 if not l10n_data['default_locale']: | |
45 return l10n_data | |
46 locales_path = path + '/_locales/' | |
47 locales_dir = self._file_system.ReadSingleFile(locales_path) | |
48 if locales_dir: | |
49 locales_files = self._file_system.Read( | |
50 [locales_path + f + 'messages.json' for f in locales_dir]).Get() | |
51 locales_json = [(path, json.loads(unicode(contents, 'latin-1'))) | |
52 for path, contents in locales_files.iteritems()] | |
53 for path, json_ in locales_json: | |
54 l10n_data['locales'][path[len(locales_path):].split('/')[0]] = json_ | |
55 return l10n_data | |
56 | |
57 def _MakeSamplesList(self, files): | |
58 samples_list = [] | |
59 for filename in sorted(files): | |
60 if filename.rsplit('/')[-1] != 'manifest.json': | |
61 continue | |
62 # This is a little hacky, but it makes a sample page. | |
63 sample_path = filename.rsplit('/', 1)[-2] | |
64 sample_files = filter(lambda x: x.startswith(sample_path + '/'), files) | |
not at google - send to devlin
2012/07/23 13:25:37
randomly browsing code here, but maybe this should
cduvall
2012/07/23 18:10:37
Done.
| |
65 js_files = filter(lambda x: x.endswith('.js'), sample_files) | |
66 js_contents = self._file_system.Read(js_files).Get() | |
67 api_items = set() | |
68 for js in js_contents.values(): | |
69 api_items.update(self._GetApiItems(js)) | |
70 | |
71 api_calls = [] | |
72 for item in api_items: | |
73 if len(item.split('.')) < 3: | |
74 continue | |
75 if item.endswith('.addListener'): | |
76 item = item.replace('.addListener', '') | |
77 api_calls.append({ | |
78 'name': item, | |
79 'link': self._MakeApiLink('event', item) | |
80 }) | |
81 else: | |
82 api_calls.append({ | |
83 'name': item, | |
84 'link': self._MakeApiLink('method', item) | |
85 }) | |
86 l10n_data = self._GetDataFromManifest(sample_path) | |
87 l10n_data.update({ | |
88 'path': sample_path.split('/', 1)[1], | |
89 'files': [f.replace(sample_path + '/', '') for f in sample_files], | |
90 'api_calls': api_calls | |
91 }) | |
92 samples_list.append(l10n_data) | |
93 | |
94 return samples_list | |
95 | |
96 def __init__(self, cache, samples_path, request): | |
97 self._cache = cache | |
14 self._samples_path = samples_path | 98 self._samples_path = samples_path |
99 self._request = request | |
15 | 100 |
16 def _GetApiItems(self, js_file): | 101 def _GetAcceptedLanguages(self): |
17 return set(re.findall('(chrome\.[a-zA-Z0-9\.]+)', js_file)) | 102 languages = [] |
18 | 103 if 'Accept-Language' in self._request.headers: |
19 def _MakeApiLink(self, prefix, item): | 104 languages = filter(lambda x: x != 'q', |
20 api, name = item.replace('chrome.', '').split('.', 1) | 105 re.findall('([a-zA-Z]+\-[a-zA-Z]+|[a-zA-Z]+)', |
21 return api + '.html#' + prefix + '-' + name | 106 self._request.headers['Accept-Language'])) |
not at google - send to devlin
2012/07/23 13:25:37
Using regex is kind of unnecessary here? And almos
cduvall
2012/07/23 18:10:37
Done.
| |
22 | 107 languages = [lang.replace('-', '_') for lang in languages] |
23 def _GetDataFromManifest(self, path): | 108 return languages |
24 manifest_path = path + '/manifest.json' | |
25 manifest = self._fetcher.Read([manifest_path]).Get()[manifest_path] | |
26 manifest_json = json.loads(manifest) | |
27 return (manifest_json.get('name'), manifest_json.get('description')) | |
28 | |
29 def _MakeSamplesList(self, files): | |
30 samples_list = [] | |
31 for filename in sorted(files): | |
32 if filename.rsplit('/')[-1] != 'manifest.json': | |
33 continue | |
34 # This is a little hacky, but it makes a sample page. | |
35 sample_path = filename.rsplit('/', 1)[-2] | |
36 sample_files = filter(lambda x: x.startswith(sample_path + '/'), files) | |
37 js_files = filter(lambda x: x.endswith('.js'), sample_files) | |
38 js_contents = self._fetcher.Read(js_files).Get() | |
39 api_items = set() | |
40 for js in js_contents.values(): | |
41 api_items.update(self._GetApiItems(js)) | |
42 | |
43 api_calls = [] | |
44 for item in api_items: | |
45 if len(item.split('.')) < 3: | |
46 continue | |
47 if item.endswith('.addListener'): | |
48 item = item.replace('.addListener', '') | |
49 api_calls.append({ | |
50 'name': item, | |
51 'link': self._MakeApiLink('event', item) | |
52 }) | |
53 else: | |
54 api_calls.append({ | |
55 'name': item, | |
56 'link': self._MakeApiLink('method', item) | |
57 }) | |
58 name, description = self._GetDataFromManifest(sample_path) | |
59 samples_list.append({ | |
60 'name': name, | |
61 'description': description, | |
62 'path': sample_path.split('/', 1)[1], | |
63 'files': [f.replace(sample_path + '/', '') for f in sample_files], | |
64 'api_calls': api_calls | |
65 }) | |
66 return samples_list | |
67 | 109 |
68 def __getitem__(self, key): | 110 def __getitem__(self, key): |
69 return self.get(key) | 111 return self.get(key) |
70 | 112 |
71 def get(self, key): | 113 def get(self, key): |
72 return self._cache.GetFromFileListing(self._samples_path + '/') | 114 samples_list = self._cache.GetFromFileListing(self._samples_path + '/') |
115 return_list = [] | |
116 accepted_languages = self._GetAcceptedLanguages() | |
not at google - send to devlin
2012/07/23 13:25:37
small optimisation: inline this where it's used (d
cduvall
2012/07/23 18:10:37
Done.
| |
117 for dict_ in samples_list: | |
118 # Copy the sample dict so we don't change the dict in the cache. | |
119 sample_data = dict_.copy() | |
not at google - send to devlin
2012/07/23 13:25:37
small optimisation: can avoid copying this dict un
cduvall
2012/07/23 18:10:37
Done.
| |
120 name = sample_data['name'] | |
121 description = sample_data['description'] | |
122 if name.startswith('__MSG_') or description.startswith('__MSG_'): | |
123 name_key = name[len('__MSG_'):-2] | |
not at google - send to devlin
2012/07/23 13:25:37
nit: instead of -2 have -len('__') perhaps? Makes
cduvall
2012/07/23 18:10:37
Done.
| |
124 description_key = description[len('__MSG_'):-2] | |
125 locale = sample_data['default_locale'] | |
126 for lang in accepted_languages: | |
127 if lang in sample_data['locales']: | |
128 locale = lang | |
129 break | |
130 sample_data['name'] = ( | |
131 sample_data['locales'][locale][name_key]['message']) | |
132 sample_data['description'] = ( | |
133 sample_data['locales'][locale][description_key]['message']) | |
not at google - send to devlin
2012/07/23 13:25:37
nit:
locale_data = sample_data['locales'][locale]
cduvall
2012/07/23 18:10:37
Done.
| |
134 return_list.append(sample_data) | |
not at google - send to devlin
2012/07/23 13:25:37
This is all super cool.
However, there seems to b
cduvall
2012/07/23 18:10:37
Done. I just caught an exception and reverted the
| |
135 return return_list | |
OLD | NEW |