Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 # This file is part of the Adblock Plus web scripts, | |
2 # Copyright (C) 2006-present eyeo GmbH | |
3 # | |
4 # Adblock Plus is free software: you can redistribute it and/or modify | |
5 # it under the terms of the GNU General Public License version 3 as | |
6 # published by the Free Software Foundation. | |
7 # | |
8 # Adblock Plus is distributed in the hope that it will be useful, | |
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 # GNU General Public License for more details. | |
12 # | |
13 # You should have received a copy of the GNU General Public License | |
14 # along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | |
15 import sys | |
Vasily Kuznetsov
2018/09/26 10:43:15
Nit: it's nice to have an empty line after the top
Tudor Avram
2018/10/04 06:48:03
Done.
| |
16 import logging | |
17 import ConfigParser | |
18 import zipfile | |
19 from io import BytesIO | |
20 | |
21 import cms.bin.xtm_translations.constants as const | |
22 from cms.bin.xtm_translations.xtm_api import XTMCloudAPI, XTMCloudException | |
23 from cms.sources import FileSource | |
24 from cms.bin.xtm_translations import utils | |
25 | |
26 __all__ = [ | |
27 'create_project', 'upload_files', 'download_files', 'main', | |
28 ] | |
29 | |
30 | |
31 def create_project(args, api, source): | |
32 """Create a project. | |
33 | |
34 Parameters | |
35 ---------- | |
36 args: argparse.Namespace | |
37 The arguments parsed by the main script. | |
38 api: XTMCloudAPI | |
39 Used for interacting with the project. | |
40 source: FileSource | |
41 Representing the website the project is created for. | |
42 | |
43 """ | |
44 config = source.read_config() | |
45 | |
46 try: | |
47 project_id = config.get(const.Config.XTM_SECTION, | |
48 const.Config.PROJECT_OPTION) | |
49 sys.exit(const.ErrorMessages.PROJECT_EXISTS.format(project_id)) | |
50 except ConfigParser.NoOptionError, ConfigParser.NoSectionError: | |
51 pass | |
52 | |
53 target_langs = utils.map_locales(source) | |
54 | |
55 page_strings = utils.extract_strings(source) | |
56 files = utils.get_local_files(page_strings) | |
57 files_to_upload = utils.get_files_to_upload(files, page_strings) | |
58 | |
59 try: | |
60 name = utils.resolve_naming_conflicts(args.name) | |
61 logging.info(const.InfoMessages.PROJECT_NAME_CREATING.format(name)) | |
62 logging.info(const.InfoMessages.UPLOADING_FILES.format(len(files))) | |
63 | |
64 project_id, resulting_jobs = utils.run_and_wait( | |
65 api.create_project, | |
66 XTMCloudException, | |
67 const.UNDER_ANALYSIS_MESSAGE, | |
68 const.InfoMessages.WAITING_FOR_PROJECT, | |
69 name=name, | |
70 description=args.desc, | |
71 reference_id=args.ref_id, | |
72 target_languages=target_langs, | |
73 customer_id=args.client_id, | |
74 workflow_id=args.workflow_id, | |
75 source_language=args.source_lang, | |
76 files=files_to_upload, | |
77 ) | |
78 except XTMCloudException as err: | |
79 sys.exit(err) | |
80 | |
81 logging.info(const.InfoMessages.PROJECT_CREATED.format(project_id)) | |
82 utils.log_resulting_jobs(resulting_jobs) | |
83 | |
84 if args.save_id: | |
85 source.write_to_config( | |
86 const.Config.XTM_SECTION, | |
87 const.Config.PROJECT_OPTION, | |
88 str(project_id), | |
89 ) | |
90 logging.info(const.InfoMessages.SAVED_PROJECT_ID) | |
91 | |
92 | |
93 def upload_files(args, api, source): | |
94 """Upload files to project. | |
95 | |
96 Parameters | |
97 ---------- | |
98 args: argparse.Namespace | |
99 The arguments parsed by the main script. | |
100 api: XTMCloudAPI | |
101 Used for interacting with the project. | |
102 source: cms.sources.FileSource | |
103 Representing the website the project is created for. | |
104 | |
105 """ | |
106 config = source.read_config() | |
107 try: | |
108 project_id = config.get(const.Config.XTM_SECTION, | |
109 const.Config.PROJECT_OPTION) | |
110 except ConfigParser.NoOptionError, ConfigParser.NoSectionError: | |
111 sys.exit(const.ErrorMessages.NO_PROJECT.format(source.get_path(''))) | |
112 | |
113 utils.resolve_locales(api, source) | |
114 | |
115 page_strings = utils.extract_strings(source) | |
116 files = utils.get_local_files(page_strings) | |
117 files_to_upload = utils.get_files_to_upload(files, page_strings) | |
118 logging.info(const.InfoMessages.UPLOADING_FILES.format(len(files))) | |
119 | |
120 new_jobs = utils.run_and_wait( | |
Vasily Kuznetsov
2018/09/26 10:43:15
What if this fails after all the retries? Above yo
Tudor Avram
2018/10/04 06:48:02
Done.
Tudor Avram
2018/10/04 06:48:02
Nope. I just forgot to add that here :D
| |
121 api.upload_files, | |
122 XTMCloudException, | |
123 const.UNDER_ANALYSIS_MESSAGE, | |
124 const.InfoMessages.WAITING_FOR_PROJECT, | |
125 files=files_to_upload, | |
126 project_id=project_id, | |
127 overwrite=not args.no_overwrite, | |
128 ) | |
129 | |
130 logging.info(const.InfoMessages.FILES_UPLOADED) | |
131 utils.log_resulting_jobs(new_jobs) | |
132 | |
133 | |
134 def download_files(args, api, source): | |
135 """Download the translation files and save them as locales. | |
136 | |
137 Parameters | |
138 ---------- | |
139 args: argparse.Namespace | |
140 The arguments provided when running the script | |
141 api: XTMCloudAPI | |
142 Used for interacting with the project. | |
143 source: FileSource | |
144 Used to write the downloaded translation files locally. | |
145 | |
146 """ | |
147 try: | |
148 raw_bytes = api.download_files( | |
149 source.read_config().get( | |
150 const.Config.XTM_SECTION, const.Config.PROJECT_OPTION, | |
151 ), | |
152 ) | |
153 except ConfigParser.NoOptionError, ConfigParser.NoSectionError: | |
154 sys.exit(const.ErrorMessages.NO_PROJECT.format(source.get_path(''))) | |
155 except XTMCloudException as err: | |
156 sys.exit(err) | |
157 except str as err: | |
158 sys.exit(err) | |
159 | |
160 try: | |
161 with zipfile.ZipFile(BytesIO(raw_bytes)) as zf: | |
162 zip_contents = zf.namelist() | |
163 if len(zip_contents) == 0: | |
164 sys.exit( | |
165 const.InfoMessages.NO_FILES_FOUND.format(args.project_id), | |
166 ) | |
167 | |
168 logging.info(const.InfoMessages.FILES_DOWNLOADED) | |
169 locales_path = source.get_path('locales') | |
170 default_locale = source.read_config().get( | |
171 const.Config.MAIN_SECTION, | |
172 const.Config.DEFAULT_LOCALE_OPTION, | |
173 ) | |
174 valid_locales = utils.get_locales(locales_path, default_locale) | |
Vasily Kuznetsov
2018/09/26 10:43:15
but source.list_locales()?
Tudor Avram
2018/10/04 06:48:03
As we discussed in person, I wrote that method bec
| |
175 utils.clear_files(locales_path, valid_locales) | |
176 | |
177 for name in zip_contents: | |
178 path = utils.resolve_remote_filename(name, locales_path, | |
179 valid_locales) | |
180 utils.write_to_file(zf.read(name), path) | |
181 logging.info(const.InfoMessages.FILE_SAVED.format( | |
182 path, | |
183 zf.getinfo(name).file_size, | |
184 )) | |
185 logging.info(const.InfoMessages.GREETINGS) | |
186 except zipfile.BadZipfile: | |
187 sys.exit(const.ErrorMessages.NO_TARGET_FILES_FOUND) | |
188 except IOError: | |
189 sys.exit(const.ErrorMessages.COULD_NOT_SAVE_FILES) | |
190 | |
191 | |
192 def main(args): | |
Vasily Kuznetsov
2018/09/26 10:43:15
Maybe this function would fit better in translate_
Tudor Avram
2018/10/04 06:48:02
Done.
| |
193 try: | |
194 api = XTMCloudAPI(utils.read_token()) | |
195 except Exception as err: | |
196 sys.exit(err) | |
197 with FileSource(args.source_dir) as fs: | |
198 args.projects_func(args, api, fs) | |
OLD | NEW |