Projet

Général

Profil

0001-general-add-import-export-of-map-layers-16706.patch

Frédéric Péters, 19 juin 2017 16:25

Télécharger (5,23 ko)

Voir les différences:

Subject: [PATCH] general: add import/export of map layers (#16706)

 combo/apps/maps/models.py   | 28 ++++++++++++++++++++++++++++
 combo/data/utils.py         | 10 ++++++++--
 tests/test_import_export.py | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 2 deletions(-)
combo/apps/maps/models.py
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17
import json
17 18

  
19
from django.core import serializers
18 20
from django.db import models
19 21
from django.utils.text import slugify
20 22
from django.utils.translation import ugettext_lazy as _
......
86 88
    def __unicode__(self):
87 89
        return self.label
88 90

  
91
    def natural_key(self):
92
        return (self.slug, )
93

  
94
    @classmethod
95
    def export_all_for_json(cls):
96
        return [x.get_as_serialized_object() for x in MapLayer.objects.all()]
97

  
98
    def get_as_serialized_object(self):
99
        serialized_layer = json.loads(serializers.serialize('json', [self],
100
            use_natural_foreign_keys=True, use_natural_primary_keys=True))[0]
101
        del serialized_layer['model']
102
        return serialized_layer
103

  
104
    @classmethod
105
    def load_serialized_objects(cls, json_site):
106
        for json_layer in json_site:
107
            cls.load_serialized_object(json_layer)
108

  
109
    @classmethod
110
    def load_serialized_object(cls, json_layer):
111
        json_layer['model'] = 'maps.maplayer'
112
        layer, created = MapLayer.objects.get_or_create(slug=json_layer['fields']['slug'])
113
        json_layer['pk'] = layer.id
114
        layer = [x for x in serializers.deserialize('json', json.dumps([json_layer]))][0]
115
        layer.save()
116

  
89 117
    def get_geojson(self, request):
90 118
        response = requests.get(self.geojson_url,
91 119
                            remote_service='auto',
combo/data/utils.py
16 16

  
17 17
from django.db import transaction
18 18

  
19
from combo.apps.maps.models import MapLayer
19 20
from .models import Page
20 21

  
21 22
def export_site():
22 23
    '''Dump site objects to JSON-dumpable dictionnary'''
23
    return {'pages': Page.export_all_for_json()}
24
    return {'pages': Page.export_all_for_json(),
25
            'map-layers': MapLayer.export_all_for_json()}
24 26

  
25 27

  
26 28
def import_site(data, if_empty=False, clean=False):
27
    if if_empty and Page.objects.count():
29
    if if_empty and (Page.objects.count() or MapLayer.objects.count()):
28 30
        return
29 31

  
30 32
    if clean:
33
        MapLayer.objects.all().delete()
31 34
        Page.objects.all().delete()
32 35

  
33 36
    if isinstance(data, list):
......
36 39
        data = {'pages': data}
37 40

  
38 41
    with transaction.atomic():
42
        MapLayer.load_serialized_objects(data.get('map-layers') or [])
43

  
44
    with transaction.atomic():
39 45
        Page.load_serialized_pages(data.get('pages') or [])
tests/test_import_export.py
9 9
import pytest
10 10
from django.core.management import call_command
11 11

  
12
from combo.apps.maps.models import MapLayer
12 13
from combo.data.models import Page, TextCell
13 14
from combo.data.utils import export_site, import_site
14 15

  
......
26 27
    cell = TextCell(page=page, order=0, text='hello world')
27 28
    cell.save()
28 29

  
30
@pytest.fixture
31
def some_map_layers():
32
    MapLayer(label='Foo', slug='foo', geojson_url='http://example.net/foo/').save()
33
    MapLayer(label='Bar', slug='bar', geojson_url='http://example.net/bar/').save()
29 34

  
30 35
def get_output_of_command(command, *args, **kwargs):
31 36
    old_stdout = sys.stdout
......
76 81
    Page.objects.all().delete()
77 82
    import_site(data=old_export)
78 83
    assert Page.objects.count() == 3
84

  
85
def test_import_export_map_layers(app, some_map_layers):
86
    output = get_output_of_command('export_site')
87
    assert len(json.loads(output)['map-layers']) == 2
88
    import_site(data={}, clean=True)
89
    assert MapLayer.objects.all().count() == 0
90
    empty_output = get_output_of_command('export_site')
91
    assert len(json.loads(empty_output)['map-layers']) == 0
92

  
93
    MapLayer(label='Baz', slug='baz', geojson_url='http://example.net/baz/').save()
94
    old_stdin = sys.stdin
95
    sys.stdin = StringIO(json.dumps({}))
96
    assert MapLayer.objects.count() == 1
97
    try:
98
        call_command('import_site', '-', clean=True)
99
    finally:
100
        sys.stdin = old_stdin
101
    assert MapLayer.objects.count() == 0
102

  
103
    with tempfile.NamedTemporaryFile() as f:
104
        f.write(output)
105
        f.flush()
106
        call_command('import_site', f.name)
107

  
108
    assert MapLayer.objects.count() == 2
109

  
110
    import_site(data={}, if_empty=True)
111
    assert MapLayer.objects.count() == 2
79
-