Merge lp:~cjwatson/launchpad/ttb-from-disk into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18362
Proposed branch: lp:~cjwatson/launchpad/ttb-from-disk
Merge into: lp:launchpad
Diff against target: 541 lines (+94/-78)
16 files modified
lib/lp/translations/doc/poexport-language-pack.txt (+3/-3)
lib/lp/translations/interfaces/translationimporter.py (+7/-6)
lib/lp/translations/interfaces/translationimportqueue.py (+5/-3)
lib/lp/translations/model/translationimportqueue.py (+24/-14)
lib/lp/translations/model/translationtemplatesbuildbehaviour.py (+7/-16)
lib/lp/translations/scripts/upload_translations.py (+6/-6)
lib/lp/translations/tests/test_translationimportqueue.py (+5/-5)
lib/lp/translations/utilities/kde_po_importer.py (+12/-6)
lib/lp/translations/utilities/tests/helpers.py (+3/-2)
lib/lp/translations/utilities/tests/test_gettext_po_importer.py (+3/-2)
lib/lp/translations/utilities/tests/test_kde_po_importer.py (+3/-2)
lib/lp/translations/utilities/tests/test_mozilla_xpi_importer.py (+3/-2)
lib/lp/translations/utilities/tests/test_translation_importer.py (+6/-4)
lib/lp/translations/utilities/tests/test_xpi_import.py (+3/-3)
lib/lp/translations/utilities/tests/test_xpi_po_exporter.py (+2/-2)
lib/lp/translations/utilities/tests/test_xpi_search.py (+2/-2)
To merge this branch: bzr merge lp:~cjwatson/launchpad/ttb-from-disk
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+322759@code.launchpad.net

Commit message

Allow TranslationImportQueue to import entries from file objects rather than having to read arbitrarily-large files into memory.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/translations/doc/poexport-language-pack.txt'
2--- lib/lp/translations/doc/poexport-language-pack.txt 2016-02-05 16:51:12 +0000
3+++ lib/lp/translations/doc/poexport-language-pack.txt 2017-04-24 14:03:06 +0000
4@@ -153,11 +153,11 @@
5
6 Attach the en-US.xpi (the template) file.
7
8- >>> en_US_xpi = get_en_US_xpi_file_to_import('en-US')
9+ >>> en_US_xpi = get_en_US_xpi_file_to_import('en-US')
10 >>> translation_import_queue = getUtility(ITranslationImportQueue)
11 >>> by_maintainer = True
12 >>> template_entry = translation_import_queue.addOrUpdateEntry(
13- ... firefox_template.path, en_US_xpi.read(), by_maintainer,
14+ ... firefox_template.path, en_US_xpi, by_maintainer,
15 ... mark, distroseries=series, sourcepackagename=spn,
16 ... potemplate=firefox_template)
17
18@@ -166,7 +166,7 @@
19 >>> es_xpi = get_en_US_xpi_file_to_import('en-US')
20 >>> firefox_es_translation = firefox_template.newPOFile('es')
21 >>> translation_entry = translation_import_queue.addOrUpdateEntry(
22- ... 'es.xpi', es_xpi.read(), by_maintainer,
23+ ... 'es.xpi', es_xpi, by_maintainer,
24 ... mark, distroseries=series, sourcepackagename=spn,
25 ... potemplate=firefox_template,
26 ... pofile=firefox_es_translation)
27
28=== modified file 'lib/lp/translations/interfaces/translationimporter.py'
29--- lib/lp/translations/interfaces/translationimporter.py 2013-01-07 02:40:55 +0000
30+++ lib/lp/translations/interfaces/translationimporter.py 2017-04-24 14:03:06 +0000
31@@ -1,4 +1,4 @@
32-# Copyright 2009 Canonical Ltd. This software is licensed under the
33+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
34 # GNU Affero General Public License version 3 (see the file LICENSE).
35
36 """Interfaces to handle translation files imports."""
37@@ -141,7 +141,7 @@
38 """Return the translation file format for the given file extension.
39
40 :param file_extension: File extension including the dot.
41- :param file_contents: File contents.
42+ :param file_contents: File contents (a seekable file object).
43 :return: A `TranslationFileFormat` for the given file extension
44 and file contents or None if it's not supported format.
45 """
46@@ -182,10 +182,11 @@
47 def getFormat(file_contents):
48 """The file format of the import.
49
50- :param file_contents: A unicode string with the contents of the file
51- being imported. A returned format may sometimes be different
52- from the base format of the `ITranslationFormatImporter`, and
53- that is determined based on the `contents`.
54+ :param file_contents: A seekable file object with the contents of
55+ the file being imported. A returned format may sometimes be
56+ different from the base format of the
57+ `ITranslationFormatImporter`, and that is determined based on
58+ the `contents`.
59 :return: A `TranslationFileFormat` value.
60 """
61
62
63=== modified file 'lib/lp/translations/interfaces/translationimportqueue.py'
64--- lib/lp/translations/interfaces/translationimportqueue.py 2014-08-20 06:59:52 +0000
65+++ lib/lp/translations/interfaces/translationimportqueue.py 2017-04-24 14:03:06 +0000
66@@ -1,4 +1,4 @@
67-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
68+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
69 # GNU Affero General Public License version 3 (see the file LICENSE).
70
71 from datetime import timedelta
72@@ -313,7 +313,8 @@
73 """Return a new or updated entry of the import queue.
74
75 :arg path: is the path, with the filename, of the uploaded file.
76- :arg content: is the file content.
77+ :arg content: is the file content, or a seekable file object open on
78+ the file content.
79 :arg by_maintainer: indicates if the file was uploaded by the
80 maintainer of the project or package.
81 :arg importer: is the person that did the import.
82@@ -336,7 +337,8 @@
83 only_templates=False):
84 """Add all .po or .pot files from the tarball at :content:.
85
86- :arg content: is a tarball stream.
87+ :arg content: is the tarball content, or a seekable file object open
88+ on the tarball.
89 :arg by_maintainer: indicates if the file was uploaded by the
90 maintainer of the project or package.
91 :arg importer: is the person that did the import.
92
93=== modified file 'lib/lp/translations/model/translationimportqueue.py'
94--- lib/lp/translations/model/translationimportqueue.py 2015-07-08 16:05:11 +0000
95+++ lib/lp/translations/model/translationimportqueue.py 2017-04-24 14:03:06 +0000
96@@ -1,4 +1,4 @@
97-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
98+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
99 # GNU Affero General Public License version 3 (see the file LICENSE).
100
101 __metaclass__ = type
102@@ -8,8 +8,8 @@
103 'TranslationImportQueue',
104 ]
105
106-from cStringIO import StringIO
107 import datetime
108+from io import BytesIO
109 import logging
110 from operator import attrgetter
111 import os.path
112@@ -1030,6 +1030,19 @@
113 return (
114 format, translation_importer.getTranslationFormatImporter(format))
115
116+ def _getFileObjectAndSize(self, file_or_data):
117+ """Get the size of a seekable file object."""
118+ if (isinstance(file_or_data, basestring)):
119+ file_obj = BytesIO(file_or_data)
120+ file_size = len(file_or_data)
121+ else:
122+ file_obj = file_or_data
123+ start = file_obj.tell()
124+ file_obj.seek(0, os.SEEK_END)
125+ file_size = file_obj.tell()
126+ file_obj.seek(start)
127+ return file_obj, file_size
128+
129 def addOrUpdateEntry(self, path, content, by_maintainer, importer,
130 sourcepackagename=None, distroseries=None,
131 productseries=None, potemplate=None, pofile=None,
132@@ -1040,16 +1053,18 @@
133 "This one has either neither or both.")
134 assert productseries is None or sourcepackagename is None, (
135 "Can't upload to a sourcepackagename in a productseries.")
136- assert content is not None and content != '', "Upload has no content."
137+ assert content is not None, "Upload has no content."
138 assert path is not None and path != '', "Upload has no path."
139
140+ file, size = self._getFileObjectAndSize(content)
141+ assert size is not None and size != 0, "Upload has empty content."
142+
143 filename = os.path.basename(path)
144 format, format_importer = self._getFormatAndImporter(
145- filename, content, format=format)
146+ filename, file, format=format)
147+ file.seek(0)
148
149 # Upload the file into librarian.
150- size = len(content)
151- file = StringIO(content)
152 client = getUtility(ILibrarianClient)
153 alias = client.addFile(
154 name=filename, size=size, file=file,
155@@ -1144,9 +1159,9 @@
156 num_files = 0
157 conflict_files = []
158
159- tarball_io = StringIO(content)
160+ tarball_io, _ = self._getFileObjectAndSize(content)
161 try:
162- tarball = tarfile.open('', 'r|*', tarball_io)
163+ tarball = tarfile.open('', 'r:*', tarball_io)
164 except (tarfile.CompressionError, tarfile.ReadError):
165 # If something went wrong with the tarfile, assume it's
166 # busted and let the user deal with it.
167@@ -1158,7 +1173,6 @@
168 path = self._makePath(name, filename_filter)
169 if self._isTranslationFile(path, only_templates):
170 upload_files[name] = path
171- tarball.close()
172
173 if approver_factory is None:
174 approver_factory = TranslationNullApprover
175@@ -1167,14 +1181,10 @@
176 productseries=productseries,
177 distroseries=distroseries, sourcepackagename=sourcepackagename)
178
179- # Re-opening because we are using sequential access ("r|*") which is
180- # so much faster.
181- tarball_io.seek(0)
182- tarball = tarfile.open('', 'r|*', tarball_io)
183 for tarinfo in tarball:
184 if tarinfo.name not in upload_files:
185 continue
186- file_content = tarball.extractfile(tarinfo).read()
187+ file_content = tarball.extractfile(tarinfo)
188
189 path = upload_files[tarinfo.name]
190 entry = approver.approve(self.addOrUpdateEntry(
191
192=== modified file 'lib/lp/translations/model/translationtemplatesbuildbehaviour.py'
193--- lib/lp/translations/model/translationtemplatesbuildbehaviour.py 2016-03-31 14:58:46 +0000
194+++ lib/lp/translations/model/translationtemplatesbuildbehaviour.py 2017-04-24 14:03:06 +0000
195@@ -1,4 +1,4 @@
196-# Copyright 2010-2014 Canonical Ltd. This software is licensed under the
197+# Copyright 2010-2017 Canonical Ltd. This software is licensed under the
198 # GNU Affero General Public License version 3 (see the file LICENSE).
199
200 """An `IBuildFarmJobBehaviour` for `TranslationTemplatesBuild`.
201@@ -110,26 +110,17 @@
202 filename = yield self._readTarball(
203 self.build.buildqueue_record, filemap, logger)
204
205- # XXX 2010-11-12 bug=674575
206- # Please make addOrUpdateEntriesFromTarball() take files on
207- # disk; reading arbitrarily sized files into memory is
208- # dangerous.
209 if filename is None:
210 logger.error("Build produced no tarball.")
211 else:
212 tarball_file = open(filename)
213 try:
214- tarball = tarball_file.read()
215- if tarball is None:
216- logger.error("Build produced empty tarball.")
217- else:
218- logger.debug(
219- "Uploading translation templates tarball.")
220- self._uploadTarball(
221- self.build.buildqueue_record.specific_build.branch,
222- tarball, logger)
223- transaction.commit()
224- logger.debug("Upload complete.")
225+ logger.debug("Uploading translation templates tarball.")
226+ self._uploadTarball(
227+ self.build.buildqueue_record.specific_build.branch,
228+ tarball_file, logger)
229+ transaction.commit()
230+ logger.debug("Upload complete.")
231 finally:
232 tarball_file.close()
233 os.remove(filename)
234
235=== modified file 'lib/lp/translations/scripts/upload_translations.py'
236--- lib/lp/translations/scripts/upload_translations.py 2015-10-14 16:23:18 +0000
237+++ lib/lp/translations/scripts/upload_translations.py 2017-04-24 14:03:06 +0000
238@@ -1,4 +1,4 @@
239-# Copyright 2011 Canonical Ltd. This software is licensed under the
240+# Copyright 2011-2017 Canonical Ltd. This software is licensed under the
241 # GNU Affero General Public License version 3 (see the file LICENSE).
242
243 __metaclass__ = type
244@@ -55,11 +55,11 @@
245 raise LaunchpadScriptFailure(
246 "File not readable: %s" % filename)
247 self.logger.info("Uploading: %s." % filename)
248- content = open(filename).read()
249- queue.addOrUpdateEntry(
250- filename, content, True, rosetta_team,
251- sourcepackagename=self.sourcepackagename,
252- distroseries=self.distroseries)
253+ with open(filename) as content:
254+ queue.addOrUpdateEntry(
255+ filename, content, True, rosetta_team,
256+ sourcepackagename=self.sourcepackagename,
257+ distroseries=self.distroseries)
258 self._commit()
259
260 self.logger.info("Done.")
261
262=== modified file 'lib/lp/translations/tests/test_translationimportqueue.py'
263--- lib/lp/translations/tests/test_translationimportqueue.py 2013-07-26 12:48:37 +0000
264+++ lib/lp/translations/tests/test_translationimportqueue.py 2017-04-24 14:03:06 +0000
265@@ -1,4 +1,4 @@
266-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
267+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
268 # GNU Affero General Public License version 3 (see the file LICENSE).
269
270 __metaclass__ = type
271@@ -409,7 +409,7 @@
272 self._makeFile('po'),
273 self._makeFile('xpi'),
274 ))
275- tarfile_content = LaunchpadWriteTarFile.files_to_string(files)
276+ tarfile_content = LaunchpadWriteTarFile.files_to_stream(files)
277 self.import_queue.addOrUpdateEntriesFromTarball(
278 tarfile_content, True, self.importer,
279 productseries=self.productseries)
280@@ -420,7 +420,7 @@
281 files = dict((
282 self._makeFile(),
283 ))
284- tarfile_content = LaunchpadWriteTarFile.files_to_string(files)
285+ tarfile_content = LaunchpadWriteTarFile.files_to_stream(files)
286 self.import_queue.addOrUpdateEntriesFromTarball(
287 tarfile_content, True, self.importer,
288 productseries=self.productseries)
289@@ -431,7 +431,7 @@
290 files = dict((
291 self._makeFile('pot', 'directory'),
292 ))
293- tarfile_content = LaunchpadWriteTarFile.files_to_string(files)
294+ tarfile_content = LaunchpadWriteTarFile.files_to_stream(files)
295 self.import_queue.addOrUpdateEntriesFromTarball(
296 tarfile_content, True, self.importer,
297 productseries=self.productseries)
298@@ -441,7 +441,7 @@
299 # Leading slashes are stripped from path names.
300 path, content = self._makeFile('pot', '/directory')
301 files = dict(((path, content),))
302- tarfile_content = LaunchpadWriteTarFile.files_to_string(files)
303+ tarfile_content = LaunchpadWriteTarFile.files_to_stream(files)
304 self.import_queue.addOrUpdateEntriesFromTarball(
305 tarfile_content, True, self.importer,
306 productseries=self.productseries)
307
308=== modified file 'lib/lp/translations/utilities/kde_po_importer.py'
309--- lib/lp/translations/utilities/kde_po_importer.py 2015-07-08 16:05:11 +0000
310+++ lib/lp/translations/utilities/kde_po_importer.py 2017-04-24 14:03:06 +0000
311@@ -1,4 +1,4 @@
312-# Copyright 2009 Canonical Ltd. This software is licensed under the
313+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
314 # GNU Affero General Public License version 3 (see the file LICENSE).
315
316 """Import module for legacy KDE .po files.
317@@ -41,11 +41,17 @@
318 # and with extremely big PO files, this will be too slow). Thus,
319 # a heuristic verified to be correct on all PO files from
320 # Ubuntu language packs.
321- if ('msgid "_n: ' in file_contents or
322- 'msgid ""\n"_n: ' in file_contents or
323- 'msgid "_: ' in file_contents or
324- 'msgid ""\n"_: ' in file_contents):
325- return TranslationFileFormat.KDEPO
326+ msgid_start = False
327+ for line in file_contents:
328+ if line == b'msgid ""\n':
329+ msgid_start = True
330+ elif (line.startswith(b'msgid "_n: ') or
331+ (msgid_start and line.startswith(b'"_n: ')) or
332+ line.startswith(b'msgid "_: ') or
333+ (msgid_start and line.startswith(b'"_: '))):
334+ return TranslationFileFormat.KDEPO
335+ else:
336+ msgid_start = False
337 else:
338 return TranslationFileFormat.PO
339
340
341=== modified file 'lib/lp/translations/utilities/tests/helpers.py'
342--- lib/lp/translations/utilities/tests/helpers.py 2011-09-18 08:39:01 +0000
343+++ lib/lp/translations/utilities/tests/helpers.py 2017-04-24 14:03:06 +0000
344@@ -1,4 +1,4 @@
345-# Copyright 2009 Canonical Ltd. This software is licensed under the
346+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
347 # GNU Affero General Public License version 3 (see the file LICENSE).
348
349 """Helper module reused in different tests."""
350@@ -25,7 +25,8 @@
351 pofile=None, potemplate=None, by_maintainer=True):
352 """Import a `POFile` or `POTemplate` from the given string.
353
354- :param file_contents: text of "file" to import.
355+ :param file_contents: text of "file" to import, or a seekable file
356+ object containing the text.
357 :param person: party requesting the import.
358 :param pofile: if uploading a `POFile`, file to import to; None otherwise.
359 :param potemplate: if uploading a `POTemplate`, file to import to; None
360
361=== modified file 'lib/lp/translations/utilities/tests/test_gettext_po_importer.py'
362--- lib/lp/translations/utilities/tests/test_gettext_po_importer.py 2012-01-01 02:58:52 +0000
363+++ lib/lp/translations/utilities/tests/test_gettext_po_importer.py 2017-04-24 14:03:06 +0000
364@@ -1,10 +1,11 @@
365-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
366+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
367 # GNU Affero General Public License version 3 (see the file LICENSE).
368
369 """Gettext PO importer tests."""
370
371 __metaclass__ = type
372
373+from io import BytesIO
374 import unittest
375
376 import transaction
377@@ -89,7 +90,7 @@
378
379 def testFormat(self):
380 # GettextPOImporter reports that it handles the PO file format.
381- format = self.template_importer.getFormat(test_template)
382+ format = self.template_importer.getFormat(BytesIO(test_template))
383 self.failUnless(
384 format == TranslationFileFormat.PO,
385 'GettextPOImporter format expected PO but got %s' % format.name)
386
387=== modified file 'lib/lp/translations/utilities/tests/test_kde_po_importer.py'
388--- lib/lp/translations/utilities/tests/test_kde_po_importer.py 2012-01-01 02:58:52 +0000
389+++ lib/lp/translations/utilities/tests/test_kde_po_importer.py 2017-04-24 14:03:06 +0000
390@@ -1,10 +1,11 @@
391-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
392+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
393 # GNU Affero General Public License version 3 (see the file LICENSE).
394
395 """KDE PO importer tests."""
396
397 __metaclass__ = type
398
399+from io import BytesIO
400 import unittest
401
402 import transaction
403@@ -114,7 +115,7 @@
404
405 def testFormat(self):
406 """Check whether KdePOImporter can handle the KDEPO file format."""
407- format = self.template_importer.getFormat(test_kde_template)
408+ format = self.template_importer.getFormat(BytesIO(test_kde_template))
409 self.failUnless(
410 format == TranslationFileFormat.KDEPO,
411 'KdePOImporter format expected KDEPO but got %s' % format.name)
412
413=== modified file 'lib/lp/translations/utilities/tests/test_mozilla_xpi_importer.py'
414--- lib/lp/translations/utilities/tests/test_mozilla_xpi_importer.py 2011-12-28 17:03:06 +0000
415+++ lib/lp/translations/utilities/tests/test_mozilla_xpi_importer.py 2017-04-24 14:03:06 +0000
416@@ -1,10 +1,11 @@
417-# Copyright 2009 Canonical Ltd. This software is licensed under the
418+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
419 # GNU Affero General Public License version 3 (see the file LICENSE).
420
421 """Mozilla XPI importer tests."""
422
423 __metaclass__ = type
424
425+from io import BytesIO
426 import unittest
427
428 from zope.interface.verify import verifyObject
429@@ -34,7 +35,7 @@
430
431 def testFormat(self):
432 """Check that MozillaXpiImporter handles the XPI file format."""
433- format = self.importer.getFormat(u'')
434+ format = self.importer.getFormat(BytesIO(b''))
435 self.failUnless(
436 format == TranslationFileFormat.XPI,
437 'MozillaXpiImporter format expected XPI but got %s' % format.name)
438
439=== modified file 'lib/lp/translations/utilities/tests/test_translation_importer.py'
440--- lib/lp/translations/utilities/tests/test_translation_importer.py 2012-01-01 02:58:52 +0000
441+++ lib/lp/translations/utilities/tests/test_translation_importer.py 2017-04-24 14:03:06 +0000
442@@ -1,10 +1,12 @@
443-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
444+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
445 # GNU Affero General Public License version 3 (see the file LICENSE).
446
447 """Translation Importer tests."""
448
449 __metaclass__ = type
450
451+from io import BytesIO
452+
453 import transaction
454
455 from lp.services.log.logger import DevNullLogger
456@@ -84,17 +86,17 @@
457 self.assertEqual(
458 TranslationFileFormat.PO,
459 importer.getTranslationFileFormat(
460- ".po", u'msgid "message"\nmsgstr ""'))
461+ ".po", BytesIO(b'msgid "message"\nmsgstr ""')))
462
463 # And PO file with KDE-style messages is recognised as KDEPO file.
464 self.assertEqual(
465 TranslationFileFormat.KDEPO,
466 importer.getTranslationFileFormat(
467- ".po", u'msgid "_: kde context\nmessage"\nmsgstr ""'))
468+ ".po", BytesIO(b'msgid "_: kde context\nmessage"\nmsgstr ""')))
469
470 self.assertEqual(
471 TranslationFileFormat.XPI,
472- importer.getTranslationFileFormat(".xpi", u""))
473+ importer.getTranslationFileFormat(".xpi", BytesIO(b"")))
474
475 def testNoConflictingPriorities(self):
476 """Check that no two importers for the same file extension have
477
478=== modified file 'lib/lp/translations/utilities/tests/test_xpi_import.py'
479--- lib/lp/translations/utilities/tests/test_xpi_import.py 2012-01-01 02:58:52 +0000
480+++ lib/lp/translations/utilities/tests/test_xpi_import.py 2017-04-24 14:03:06 +0000
481@@ -1,4 +1,4 @@
482-# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
483+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
484 # GNU Affero General Public License version 3 (see the file LICENSE).
485
486 """Functional tests for XPI file format"""
487@@ -61,7 +61,7 @@
488 # Get the file to import.
489 en_US_xpi = get_en_US_xpi_file_to_import(subdir)
490 return import_pofile_or_potemplate(
491- file_contents=en_US_xpi.read(),
492+ file_contents=en_US_xpi,
493 person=self.importer,
494 potemplate=self.firefox_template)
495
496@@ -74,7 +74,7 @@
497 # just use the same template file like a translation one.
498 es_xpi = get_en_US_xpi_file_to_import(subdir)
499 return import_pofile_or_potemplate(
500- file_contents=es_xpi.read(),
501+ file_contents=es_xpi,
502 person=self.importer,
503 pofile=self.spanish_firefox,
504 by_maintainer=True)
505
506=== modified file 'lib/lp/translations/utilities/tests/test_xpi_po_exporter.py'
507--- lib/lp/translations/utilities/tests/test_xpi_po_exporter.py 2012-03-27 13:41:38 +0000
508+++ lib/lp/translations/utilities/tests/test_xpi_po_exporter.py 2017-04-24 14:03:06 +0000
509@@ -1,4 +1,4 @@
510-# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
511+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
512 # GNU Affero General Public License version 3 (see the file LICENSE).
513
514 __metaclass__ = type
515@@ -82,7 +82,7 @@
516 translation_import_queue = getUtility(ITranslationImportQueue)
517 by_maintainer = True
518 entry = translation_import_queue.addOrUpdateEntry(
519- self.firefox_template.path, en_US_xpi.read(), by_maintainer,
520+ self.firefox_template.path, en_US_xpi, by_maintainer,
521 self.importer, productseries=self.firefox_template.productseries,
522 potemplate=self.firefox_template)
523
524
525=== modified file 'lib/lp/translations/utilities/tests/test_xpi_search.py'
526--- lib/lp/translations/utilities/tests/test_xpi_search.py 2012-01-01 02:58:52 +0000
527+++ lib/lp/translations/utilities/tests/test_xpi_search.py 2017-04-24 14:03:06 +0000
528@@ -1,4 +1,4 @@
529-# Copyright 2009 Canonical Ltd. This software is licensed under the
530+# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
531 # GNU Affero General Public License version 3 (see the file LICENSE).
532
533 """Functional tests for searching through XPI POTemplates"""
534@@ -51,7 +51,7 @@
535 # Get the file to import.
536 en_US_xpi = get_en_US_xpi_file_to_import(subdir)
537 return import_pofile_or_potemplate(
538- file_contents=en_US_xpi.read(),
539+ file_contents=en_US_xpi,
540 person=self.importer,
541 potemplate=self.firefox_template)
542