Source code for fobi.form_importers

import json

from django.core.serializers.json import DjangoJSONEncoder
from django.urls import reverse
from six import text_type

from .base import BaseRegistry
from .discover import autodiscover

__title__ = "fobi.form_importers"
__author__ = "Artur Barseghyan <artur.barseghyan@gmail.com>"
__copyright__ = "2014-2019 Artur Barseghyan"
__license__ = "GPL 2.0/LGPL 2.1"
__all__ = (
    "BaseFormImporter",
    "FormImporterPluginRegistry",
    "form_importer_plugin_registry",
    "ensure_autodiscover",
    "get_form_importer_plugin_uids",
    "get_form_importer_plugin_urls",
)


[docs]class BaseFormImporter(object): """Base importer.""" uid = None name = None description = None # field_type (MailChimp): uid (Fobi) fields_mapping = None # Django standard: remote field_properties_mapping = None # Position is stored in a model (field) field_type_prop_name = None position_prop_name = None wizard = None templates = None def __init__( self, form_entry_cls, form_element_entry_cls, form_properties=None, form_data=None, ): """Constructor. :param django.contrib.auth.models.User user: User importing the form. :param dict form_properties: Properties of the form, that user provides (such as name, is_public, etc.) """ assert self.uid assert self.name assert self.fields_mapping is not None assert self.field_properties_mapping is not None assert self.wizard is not None assert self.templates is not None assert form_entry_cls is not None assert form_element_entry_cls is not None for prop in ("name", "label", "help_text", "initial", "required"): assert prop in self.field_properties_mapping self.form_data = form_data self.form_properties = form_properties self.form_entry_cls = form_entry_cls self.form_element_entry_cls = form_element_entry_cls
[docs] def get_form_data(self): """Get form data.""" return self.form_data
[docs] def extract_field_properties(self, field_data): """Extract field properties.""" field_properties = {} for prop, val in self.field_properties_mapping.items(): if val in field_data: field_properties[prop] = field_data[val] return field_properties
[docs] def import_data(self, form_properties, form_data): """Import data.""" self.form_properties = form_properties self.form_data = form_data assert "name" in self.form_properties form_entry = self.form_entry_cls() for prop, val in self.form_properties.items(): setattr(form_entry, prop, val) form_entry.save() data = self.get_form_data() for field_data in data: # Skip non-existing if field_data[self.field_type_prop_name] not in self.fields_mapping: continue form_element_entry = self.form_element_entry_cls() form_element_entry.form_entry = form_entry form_element_entry.plugin_uid = self.fields_mapping[ field_data[self.field_type_prop_name] ] # Assign form data form_element_entry.plugin_data = json.dumps( self.extract_field_properties(field_data), cls=DjangoJSONEncoder ) # Assign position in form if self.position_prop_name in field_data: form_element_entry.position = field_data[ self.position_prop_name ] form_element_entry.save() return form_entry
[docs] def get_template_names(self): """Get template names.""" return {text_type(idx): tpl for idx, tpl in enumerate(self.templates)}
[docs] def get_wizard(self, request, *args, **kwargs): """Get wizard.""" template_names = self.get_template_names() class FormImporterWizard(self.wizard): """Constructing the importer class dynamically.""" _form_importer = self def get_template_names(self): """Get template names.""" return [template_names[self.steps.current]] wizard = FormImporterWizard.as_view() return wizard(request, *args, **kwargs)
[docs]class FormImporterPluginRegistry(BaseRegistry): """Form importer plugins registry.""" type = BaseFormImporter
# Register form field plugins by calling form_field_plugin_registry.register() form_importer_plugin_registry = FormImporterPluginRegistry()
[docs]def ensure_autodiscover(): """Ensure that form importer plugins are auto-discovered.""" if not form_importer_plugin_registry._registry: autodiscover()
[docs]def get_form_importer_plugin_uids(): """Get form importer plugin uids.""" ensure_autodiscover() return list(form_importer_plugin_registry._registry.keys())
[docs]def get_form_importer_plugin_urls(): """Gets the form importer plugin URLs as a list of tuples.""" urls = [] ensure_autodiscover() for uid, plugin in form_importer_plugin_registry._registry.items(): urls.append( ( uid, plugin.name, reverse( "fobi.form_importer", kwargs={"form_importer_plugin_uid": uid}, ), ) ) return urls