Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: cms/bin/xtm_translations/projects_handler.py

Issue 29886648: Issue #6942 - Add XTM integration in CMS (Closed)
Patch Set: Addressed initial comments Created Sept. 25, 2018, 12:24 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
(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)
OLDNEW

Powered by Google App Engine
This is Rietveld