0001-general-enhance-import-export-cmdline-commands-15665.patch
combo/data/management/commands/export_site.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import json |
18 |
from optparse import make_option |
|
18 | 19 |
import sys |
19 | 20 | |
20 | 21 |
from django.core.management.base import BaseCommand |
21 | 22 | |
22 |
from combo.data.models import Page
|
|
23 |
from combo.data.utils import export_site
|
|
23 | 24 | |
24 | 25 |
class Command(BaseCommand): |
25 |
args = ['...'] |
|
26 |
args = '' |
|
27 |
help = 'Export the site' |
|
28 |
option_list = BaseCommand.option_list + ( |
|
29 |
make_option('--output', metavar='FILE', default=None, |
|
30 |
help='name of a file to write output to'), |
|
31 |
) |
|
26 | 32 | |
27 |
def handle(self, json_file='-', *args, **kwargs):
|
|
28 |
if json_file == '-':
|
|
29 |
output = sys.stdout
|
|
33 |
def handle(self, *args, **options):
|
|
34 |
if options['output'] and options['output'] != '-':
|
|
35 |
output = open(options['output'], 'w')
|
|
30 | 36 |
else: |
31 |
output = open(json_file, 'w') |
|
32 |
json.dump(Page.export_all_for_json(), output, indent=2) |
|
37 |
output = sys.stdout |
|
38 |
json.dump(export_site(), output, indent=4) |
combo/data/management/commands/import_site.py | ||
---|---|---|
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 | 17 |
import json |
18 |
from optparse import make_option |
|
19 |
import sys |
|
18 | 20 | |
19 | 21 |
from django.core.management.base import BaseCommand |
20 | 22 | |
21 |
from combo.data.models import Page
|
|
23 |
from combo.data.utils import import_site
|
|
22 | 24 | |
23 | 25 |
class Command(BaseCommand): |
24 |
args = ['...'] |
|
26 |
args = '<filename>' |
|
27 |
help = 'Import an exported site' |
|
28 |
option_list = BaseCommand.option_list + ( |
|
29 |
make_option('--clean', action='store_true', default=False, |
|
30 |
help='Clean site before importing'), |
|
31 |
make_option('--if-empty', action='store_true', default=False, |
|
32 |
help='Import only if site is empty'), |
|
33 |
) |
|
25 | 34 | |
26 |
def handle(self, json_file, *args, **kwargs): |
|
27 |
Page.load_serialized_pages(json.load(open(json_file))) |
|
35 |
def handle(self, filename, *args, **options): |
|
36 |
if filename == '-': |
|
37 |
fd = sys.stdin |
|
38 |
else: |
|
39 |
fd = open(filename) |
|
40 |
import_site(json.load(fd), |
|
41 |
if_empty=options['if_empty'], |
|
42 |
clean=options['clean']) |
combo/data/utils.py | ||
---|---|---|
1 |
# combo - content management system |
|
2 |
# Copyright (C) 2017 Entr'ouvert |
|
3 |
# |
|
4 |
# This program is free software: you can redistribute it and/or modify it |
|
5 |
# under the terms of the GNU Affero General Public License as published |
|
6 |
# by the Free Software Foundation, either version 3 of the License, or |
|
7 |
# (at your option) any later version. |
|
8 |
# |
|
9 |
# This program is distributed in the hope that it will be useful, |
|
10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
# GNU Affero General Public License for more details. |
|
13 |
# |
|
14 |
# You should have received a copy of the GNU Affero General Public License |
|
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | ||
17 |
from django.db import transaction |
|
18 | ||
19 |
from .models import Page |
|
20 | ||
21 |
def export_site(): |
|
22 |
'''Dump site objects to JSON-dumpable dictionnary''' |
|
23 |
return Page.export_all_for_json() |
|
24 | ||
25 | ||
26 |
def import_site(data, if_empty=False, clean=False): |
|
27 |
if if_empty and Page.objects.count(): |
|
28 |
return |
|
29 | ||
30 |
if clean: |
|
31 |
Page.objects.all().delete() |
|
32 | ||
33 |
with transaction.atomic(): |
|
34 |
Page.load_serialized_pages(data) |
combo/manager/views.py | ||
---|---|---|
33 | 33 | |
34 | 34 |
from combo.data.models import Page, CellBase, ParentContentCell |
35 | 35 |
from combo.data.library import get_cell_class |
36 |
from combo.data.utils import export_site, import_site |
|
36 | 37 |
from combo import plugins |
37 | 38 | |
38 | 39 |
from .forms import (PageEditTitleForm, PageVisibilityForm, SiteImportForm, |
... | ... | |
58 | 59 | |
59 | 60 |
def render_to_response(self, context, **response_kwargs): |
60 | 61 |
response = HttpResponse(content_type='application/json') |
61 |
json.dump(Page.export_all_for_json(), response, indent=2)
|
|
62 |
json.dump(export_site(), response, indent=2)
|
|
62 | 63 |
return response |
63 | 64 | |
64 | 65 |
site_export = SiteExportView.as_view() |
... | ... | |
71 | 72 | |
72 | 73 |
def form_valid(self, form): |
73 | 74 |
json_site = json.load(self.request.FILES['site_json']) |
74 |
Page.load_serialized_pages(json_site)
|
|
75 |
import_site(json_site)
|
|
75 | 76 |
return super(SiteImportView, self).form_valid(form) |
76 | 77 | |
77 | 78 |
site_import = SiteImportView.as_view() |
tests/test_pages.py | ||
---|---|---|
224 | 224 |
os.unlink(export_filename) |
225 | 225 | |
226 | 226 |
cmd = ExportSiteCommand() |
227 |
cmd.handle(export_filename) |
|
227 |
cmd.handle(output=export_filename)
|
|
228 | 228 |
assert os.path.exists(export_filename) |
229 | 229 | |
230 | 230 |
stdout = sys.stdout |
231 | 231 |
try: |
232 | 232 |
sys.stdout = StringIO() |
233 |
cmd.handle('-') |
|
233 |
cmd.handle(output='-')
|
|
234 | 234 |
assert sys.stdout.getvalue() == open(export_filename).read() |
235 | 235 |
finally: |
236 | 236 |
sys.stdout = stdout |
... | ... | |
238 | 238 |
Page.objects.all().delete() |
239 | 239 | |
240 | 240 |
cmd = ImportSiteCommand() |
241 |
cmd.handle(export_filename)
|
|
241 |
cmd.handle(filename=export_filename, if_empty=False, clean=False)
|
|
242 | 242 | |
243 | 243 |
new_page_1 = Page.objects.all().order_by('order')[0] |
244 | 244 |
new_page_2 = Page.objects.all().order_by('order')[1] |
245 |
- |