summaryrefslogtreecommitdiff
path: root/ishtar_common/admin.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/admin.py')
-rw-r--r--ishtar_common/admin.py111
1 files changed, 106 insertions, 5 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index 71dc2cbdc..e606a81e7 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -67,6 +67,9 @@ from ishtar_common.apps import admin_site
from ishtar_common.utils import get_cache, create_slug
from ishtar_common import forms as common_forms
+from ishtar_common.serializers import restore_serialized, IMPORT_MODEL_LIST
+from ishtar_common.serializers_utils import generic_get_results, \
+ serialization_info
from archaeological_files import forms as file_forms
from archaeological_files_pdl import forms as file_pdl_forms
from archaeological_operations import forms as operation_forms
@@ -113,7 +116,7 @@ def change_value(attribute, value, description):
return _change_value
-def export_as_csv_action(description=_(u"Export selected as CSV file"),
+def export_as_csv_action(description=_("Export selected as CSV file"),
fields=None, exclude=None, header=True):
"""
This function returns an export csv action
@@ -206,6 +209,44 @@ def export_as_geojson_action(
return export_as_geojson
+def serialize_action(dir_name, model_list):
+ def _serialize_action(modeladmin, request, queryset):
+ if model_list:
+ modellist = model_list[:]
+ else:
+ modellist = [modeladmin.model]
+ opts = modeladmin.model._meta
+ result = generic_get_results(
+ modellist, dir_name,
+ result_queryset={opts.object_name: queryset})
+ basename = str(opts).replace('.', '_')
+ in_memory = BytesIO()
+ zip = zipfile.ZipFile(in_memory, "a")
+ for key in result.keys():
+ __, model_name = key
+ zip.writestr(dir_name + os.sep + model_name + ".json", result[key])
+
+ # info
+ zip.writestr("info.json", json.dumps(serialization_info(), indent=2))
+
+ # fix for Linux zip files read in Windows
+ for file in zip.filelist:
+ file.create_system = 0
+ zip.close()
+ response = HttpResponse(content_type='application/zip')
+ response['Content-Disposition'] = 'attachment; filename={}.zip'.format(
+ basename
+ )
+ in_memory.seek(0)
+ response.write(in_memory.read())
+ return response
+ return _serialize_action
+
+
+SERIALIZE_DESC = _("Export selected as Ishtar (zipped JSON)")
+serialize_type_action = serialize_action("types", None)
+serialize_type_action.short_description = SERIALIZE_DESC
+
TokenAdmin.raw_id_fields = ('user',)
admin_site.register(Token, TokenAdmin)
@@ -693,6 +734,61 @@ class ImportGEOJSONActionAdmin(object):
{'file_form': form, 'current_action': 'import_geojson'})
+class ImportJSONForm(forms.Form):
+ json_file = forms.FileField(
+ _("Zipped JSON file"),
+ help_text=_("Import from a zipped JSON file generated by Ishtar")
+ )
+
+
+class ImportJSONActionAdmin(admin.ModelAdmin):
+ change_list_template = "admin/json_change_list.html"
+ import_keys = ['slug', 'txt_idx']
+
+ def get_urls(self):
+ urls = super(ImportJSONActionAdmin, self).get_urls()
+ my_urls = [
+ url(r'^import-from-json/$', self.import_json),
+ ]
+ return my_urls + urls
+
+ def import_json(self, request):
+ form = None
+
+ if 'apply' in request.POST:
+ form = ImportJSONForm(request.POST, request.FILES)
+ if form.is_valid():
+ with tempfile.TemporaryDirectory() as tmpdirname:
+ filename = tmpdirname + os.sep + "export.zip"
+ with open(filename, "wb+") as zipped_file:
+ for chunk in request.FILES['json_file'].chunks():
+ zipped_file.write(chunk)
+ result = None
+ result = restore_serialized(filename)
+ try:
+ result = restore_serialized(filename)
+ except ValueError as e:
+ self.message_user(request, str(e),
+ level=messages.ERROR)
+ if result:
+ for model, count in result:
+ self.message_user(
+ request,
+ str(_("{} {}(s) created/updated.")).format(
+ count, model))
+ url = reverse(
+ 'admin:%s_%s_changelist' % (
+ self.model._meta.app_label, self.model._meta.model_name)
+ )
+ return HttpResponseRedirect(url)
+ if not form:
+ form = ImportJSONForm()
+ return render(
+ request, 'admin/import_from_file.html',
+ {'file_form': form, 'current_action': 'import_json'}
+ )
+
+
class AdminRelatedTownForm(forms.ModelForm):
class Meta:
model = models.Town.children.through
@@ -744,12 +840,12 @@ class TownAdmin(ImportGEOJSONActionAdmin, ImportActionAdmin):
admin_site.register(models.Town, TownAdmin)
-class GeneralTypeAdmin(ImportActionAdmin):
+class GeneralTypeAdmin(ImportActionAdmin, ImportJSONActionAdmin):
list_display = ['label', 'txt_idx', 'available', 'comment']
search_fields = ('label', 'txt_idx', 'comment',)
list_filter = ('available',)
save_on_top = True
- actions = [export_as_csv_action()]
+ actions = [export_as_csv_action(), serialize_type_action]
prepopulated_fields = {"txt_idx": ("label",)}
@csrf_protect_m
@@ -995,9 +1091,14 @@ if settings.USE_LIBREOFFICE:
importer_type_actions.append(generate_libreoffice_template)
-class ImporterTypeAdmin(admin.ModelAdmin):
+serialize_importer_action = serialize_action("common_imports",
+ IMPORT_MODEL_LIST)
+serialize_importer_action.short_description = SERIALIZE_DESC
+
+
+class ImporterTypeAdmin(ImportJSONActionAdmin):
list_display = ('name', 'associated_models', 'available')
- actions = importer_type_actions
+ actions = importer_type_actions + [serialize_importer_action]
admin_site.register(models.ImporterType, ImporterTypeAdmin)