Merge pull request #5581 from felipeboffnunes/fix_post_processing_with_s3

Fix Feed Exporter issue with Post Processing
This commit is contained in:
Andrey Rakhmatullin 2023-04-11 15:06:11 +04:00 committed by GitHub
commit bdb78b9aa5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 60 additions and 2 deletions

View File

@ -383,13 +383,20 @@ class FeedExporter:
return defer.DeferredList(deferred_list) if deferred_list else None
def _close_slot(self, slot, spider):
def get_file(slot_):
if isinstance(slot_.file, PostProcessingManager):
slot_.file.close()
return slot_.file.file
return slot_.file
slot.finish_exporting()
if not slot.itemcount and not slot.store_empty:
# We need to call slot.storage.store nonetheless to get the file
# properly closed.
return defer.maybeDeferred(slot.storage.store, slot.file)
return defer.maybeDeferred(slot.storage.store, get_file(slot))
logmsg = f"{slot.format} feed ({slot.itemcount} items) in: {slot.uri}"
d = defer.maybeDeferred(slot.storage.store, slot.file)
d = defer.maybeDeferred(slot.storage.store, get_file(slot))
d.addCallback(
self._handle_store_success, logmsg, spider, type(slot.storage).__name__

View File

@ -1638,6 +1638,57 @@ class FeedExportTest(FeedExportTestBase):
data = yield self.exported_data(items, settings)
self.assertEqual(row["expected"], data[feed_options["format"]])
@defer.inlineCallbacks
def test_storage_file_no_postprocessing(self):
@implementer(IFeedStorage)
class Storage:
def __init__(self, uri, *, feed_options=None):
pass
def open(self, spider):
Storage.open_file = tempfile.NamedTemporaryFile(prefix="feed-")
return Storage.open_file
def store(self, file):
Storage.store_file = file
file.close()
settings = {
"FEEDS": {self._random_temp_filename(): {"format": "jsonlines"}},
"FEED_STORAGES": {"file": Storage},
}
yield self.exported_no_data(settings)
self.assertIs(Storage.open_file, Storage.store_file)
@defer.inlineCallbacks
def test_storage_file_postprocessing(self):
@implementer(IFeedStorage)
class Storage:
def __init__(self, uri, *, feed_options=None):
pass
def open(self, spider):
Storage.open_file = tempfile.NamedTemporaryFile(prefix="feed-")
return Storage.open_file
def store(self, file):
Storage.store_file = file
file.close()
settings = {
"FEEDS": {
self._random_temp_filename(): {
"format": "jsonlines",
"postprocessing": [
"scrapy.extensions.postprocessing.GzipPlugin",
],
},
},
"FEED_STORAGES": {"file": Storage},
}
yield self.exported_no_data(settings)
self.assertIs(Storage.open_file, Storage.store_file)
class FeedPostProcessedExportsTest(FeedExportTestBase):
__test__ = True