data: export/import of page picture content (#86870)
gitea/combo/pipeline/head This commit looks good Details

This commit is contained in:
Lauréline Guérin 2024-02-13 12:16:06 +01:00 committed by Lauréline Guérin
parent f05be333cb
commit 7913efd0ab
2 changed files with 35 additions and 1 deletions

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import base64
import copy
import datetime
import hashlib
@ -38,6 +39,8 @@ from django.contrib.contenttypes.models import ContentType
from django.core import serializers
from django.core.cache import cache
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied, ValidationError
from django.core.files.base import ContentFile
from django.core.files.storage import default_storage
from django.db import models, transaction
from django.db.models import JSONField, Max, Q
from django.db.models.base import ModelBase
@ -57,7 +60,7 @@ from django.template.defaultfilters import yesno
from django.test.client import RequestFactory
from django.urls import reverse
from django.utils import timezone
from django.utils.encoding import force_str, smart_bytes
from django.utils.encoding import force_bytes, force_str, smart_bytes
from django.utils.html import strip_tags
from django.utils.safestring import mark_safe
from django.utils.text import slugify
@ -597,6 +600,9 @@ class Page(models.Model):
for key in list(cell['fields'].keys()):
if key.startswith('cached_'):
del cell['fields'][key]
if self.picture:
with self.picture.open() as f:
serialized_page['fields']['picture:base64'] = force_str(base64.encodebytes(f.read()))
return serialized_page
@classmethod
@ -625,12 +631,25 @@ class Page(models.Model):
)
% json_page['fields']['title'],
)
decoded_picture = None
if json_page['fields'].get('picture:base64'):
decoded_picture = base64.decodebytes(force_bytes(json_page['fields']['picture:base64']))
del json_page['fields']['picture:base64']
page_uuid = page.uuid
page = next(serializers.deserialize('json', json.dumps([json_page]), ignorenonexistent=True))
page.object.snapshot = snapshot
if snapshot:
# keep the generated uuid
page.object.uuid = page_uuid
if decoded_picture and page.object.picture:
original_path = page.object.picture.path
original_name = page.object.picture.name
name = original_name
if name.startswith('page-pictures/'):
name = name[len('page-pictures/') :]
page.object.picture.save(name, ContentFile(decoded_picture))
os.rename(default_storage.path(page.object.picture.name), original_path)
page.object.picture.name = original_name
page.save()
for cell in json_page.get('cells'):
cell['fields']['groups'] = [[x] for x in cell['fields']['groups'] if isinstance(x, str)]

View File

@ -142,6 +142,21 @@ def test_import_export_with_nested_parents():
assert two.parent.slug == 'two'
def test_import_export_page_with_picture():
Page(title='One', slug='one', picture=File(BytesIO(b'picture'), 'picture.png')).save()
output = get_output_of_command('export_site')
data = json.loads(output)
assert data['pages'][0]['fields']['picture:base64']
Page.objects.all().delete()
import_site(data=data)
assert Page.objects.count() == 1
assert Page.objects.first().picture.name == 'page-pictures/picture.png'
with open('%s/page-pictures/picture.png' % default_storage.path('')) as fd:
assert fd.read() == 'picture'
def test_import_export_map_layers(app, some_map_layers):
output = get_output_of_command('export_site')
assert len(json.loads(output)['map-layers']) == 2