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

Delta Between Two Patch Sets: cms/translations/xtm/projects_handler.py

Issue 29886648: Issue #6942 - Add XTM integration in CMS (Closed)
Left Patch Set: Addressed initial comments Created Sept. 25, 2018, 12:24 p.m.
Right Patch Set: Addressed comments from Patch Set #4 Created Oct. 5, 2018, 4:23 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Right: Side by side diff | Download
LEFTRIGHT
(no file at all)
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
16 import sys
17 import logging
18 import ConfigParser
19 import zipfile
20 from io import BytesIO
21
22 import cms.translations.xtm.constants as const
23 from cms.translations.xtm.xtm_api import XTMCloudException
24 from cms.translations.xtm import utils
25
26 __all__ = [
27 'create_project', 'upload_files', 'download_files',
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 files_to_upload = utils.get_files_to_upload(source)
56
57 try:
58 name = utils.sanitize_project_name(args.name)
59 logging.info(const.InfoMessages.PROJECT_NAME_CREATING.format(name))
60 logging.info(
61 const.InfoMessages.UPLOADING_FILES.format(len(files_to_upload)),
62 )
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 files_to_upload = utils.get_files_to_upload(source)
114 logging.info(
115 const.InfoMessages.UPLOADING_FILES.format(len(files_to_upload)),
116 )
117 try:
118 utils.resolve_locales(api, source)
119
120 new_jobs = utils.run_and_wait(
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 except XTMCloudException as err:
133 sys.exit(err)
134
135
136 def download_files(args, api, source):
137 """Download the translation files and save them as locales.
138
139 Parameters
140 ----------
141 args: argparse.Namespace
142 The arguments provided when running the script
143 api: XTMCloudAPI
144 Used for interacting with the project.
145 source: FileSource
146 Used to write the downloaded translation files locally.
147
148 """
149 try:
150 raw_bytes = api.download_files(
151 source.read_config().get(
152 const.Config.XTM_SECTION, const.Config.PROJECT_OPTION,
153 ),
154 )
155 except ConfigParser.NoOptionError, ConfigParser.NoSectionError:
156 sys.exit(const.ErrorMessages.NO_PROJECT.format(source.get_path('')))
157 except XTMCloudException as err:
158 sys.exit(err)
159 except str as err:
160 sys.exit(err)
161
162 try:
163 with zipfile.ZipFile(BytesIO(raw_bytes)) as zf:
164 zip_contents = zf.namelist()
165 if len(zip_contents) == 0:
166 sys.exit(
167 const.InfoMessages.NO_FILES_FOUND.format(args.project_id),
168 )
169
170 logging.info(const.InfoMessages.FILES_DOWNLOADED)
171 locales_path = source.get_path('locales')
172 default_locale = source.read_config().get(
173 const.Config.MAIN_SECTION,
174 const.Config.DEFAULT_LOCALE_OPTION,
175 )
176 valid_locales = utils.get_locales(locales_path, default_locale)
177 utils.clear_files(locales_path, valid_locales)
178
179 for name in zip_contents:
180 path = utils.remote_to_local(name, locales_path, valid_locales)
181 utils.write_to_file(zf.read(name), path)
182 logging.info(const.InfoMessages.FILE_SAVED.format(
183 path,
184 zf.getinfo(name).file_size,
185 ))
186 logging.info(const.InfoMessages.GREETINGS)
187 except zipfile.BadZipfile:
188 sys.exit(const.ErrorMessages.NO_TARGET_FILES_FOUND)
189 except IOError:
190 sys.exit(const.ErrorMessages.COULD_NOT_SAVE_FILES)
LEFTRIGHT

Powered by Google App Engine
This is Rietveld