Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to restore broken blobs when exporting content. #230

Merged
merged 2 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ Changelog
1.11 (unreleased)
-----------------

- Try to restore broken blobs when exporting content.
[thet]

- When exporting into separate JSON files write also the error in a separate errors.json file.
This fixes an error at the end of the export and no errors being written.
[thet]
Expand Down
53 changes: 26 additions & 27 deletions src/collective/exportimport/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,29 +75,6 @@ def get_blob_path(blob):

# Custom Serializers for Dexterity

@adapter(INamedImageField, IDexterityContent, IBase64BlobsMarker)
class ImageFieldSerializerWithBlobs(DefaultFieldSerializer):
def __call__(self):
try:
image = self.field.get(self.context)
except AttributeError:
image = None
if not image:
return None

if "built-in function id" in image.filename:
filename = self.context.id
else:
filename = image.filename

result = {
"filename": filename,
"content-type": image.contentType,
"data": base64.b64encode(image.data),
"encoding": "base64",
}
return json_compatible(result)


@adapter(INamedFileField, IDexterityContent, IBase64BlobsMarker)
class FileFieldSerializerWithBlobs(DefaultFieldSerializer):
Expand All @@ -109,10 +86,27 @@ def __call__(self):
if namedfile is None:
return None

if "built-in function id" in namedfile.filename:
filename = self.context.id
else:
filename = namedfile.filename
try:
if "built-in function id" in namedfile.filename:
filename = self.context.id
else:
filename = namedfile.filename
except AttributeError:
# Try to recover broken namedfile
# Related to: WARNING OFS.Uninstalled Could not import class 'NamedBlobFile' from module 'zope.app.file.file'
from ZODB.broken import Broken

if isinstance(namedfile, Broken):
broken_namedfile = namedfile.__Broken_state__
file = broken_namedfile["_blob"].open()
result = {
"filename": broken_namedfile["filename"],
"content-type": broken_namedfile["contentType"],
"data": base64.b64encode(file.read()),
"encoding": "base64",
}
file.close()
return result

result = {
"filename": filename,
Expand All @@ -123,6 +117,11 @@ def __call__(self):
return json_compatible(result)


@adapter(INamedImageField, IDexterityContent, IBase64BlobsMarker)
class ImageFieldSerializerWithBlobs(FileFieldSerializerWithBlobs):
pass


@adapter(IRichText, IDexterityContent, IRawRichTextMarker)
class RichttextFieldSerializerWithRawText(DefaultFieldSerializer):
def __call__(self):
Expand Down