예제 #1
0
    class RemoteDcatForm(forms.ModelForm):
        class Meta(object):
            model = RemoteDcat
            fields = (
                'url',
                'sync_with',
                'sync_frequency',
            )
            mapping = tuple()

        url = forms.URLField(
            label="URL du catalogue DCAT*",
            required=True,
            max_length=200,
            error_messages={
                'invalid': "L'adresse URL est erronée.",
            },
            widget=forms.TextInput(attrs={
                'placeholder': "",
            }, ),
        )

        sync_with = forms.MultipleChoiceField(
            label="Organisations à synchroniser*",
            required=False,
            choices=(),
            widget=CustomCheckboxSelectMultiple(attrs={
                'class': 'list-group-checkbox',
            }, ),
        )

        sync_frequency = forms.ChoiceField(
            label="Fréquence de synchronisation*",
            required=True,
            choices=Meta.model.FREQUENCY_CHOICES,
            initial='never',
        )

        def __init__(self, *args, **kwargs):
            self.cleaned_data = {}
            super().__init__(*args, **kwargs)

            instance = kwargs.get('instance', None)
            if instance and instance.url:
                self.fields['url'].widget.attrs['readonly'] = True
                # Récupérer la liste des organisations
                try:
                    with DcatBaseHandler(instance.url) as dcat:
                        organisations = dcat.get_all_publishers(
                            include_dataset_count=True)
                except (DcatError, DcatTimeoutError) as e:
                    self.add_error('url', e.message)
                else:
                    self.fields['sync_with'].choices = tuple(
                        (m['name'], '%s (%d)' % (m['name'], m['count']))
                        for m in organisations)

            else:
                self.fields['sync_with'].widget = forms.HiddenInput()
                self.fields['sync_frequency'].widget = forms.HiddenInput()
예제 #2
0
class RemoteCkanForm(forms.ModelForm):
    class Meta(object):
        model = RemoteCkan
        fields = (
            'url',
            'sync_with',
            'sync_frequency',
        )
        mapping = tuple()

    url = forms.URLField(
        label="URL du catalogue CKAN*",
        required=True,
        max_length=200,
        error_messages={
            'invalid': "L'adresse URL est erronée.",
        },
        widget=forms.TextInput(attrs={
            'placeholder': "https://demo.ckan.org",
        }, ),
    )

    sync_with = forms.MultipleChoiceField(
        label="Organisations à synchroniser*",
        required=False,
        choices=(),  # ckan api -> list_organisations
        widget=CustomCheckboxSelectMultiple(attrs={
            'class': 'list-group-checkbox',
        }, ),
    )

    sync_frequency = forms.ChoiceField(
        label="Fréquence de synchronisation*",
        required=True,
        choices=Meta.model.FREQUENCY_CHOICES,
        initial='never',
    )

    def __init__(self, *args, **kwargs):
        self.cleaned_data = {}
        super().__init__(*args, **kwargs)

        instance = kwargs.get('instance', None)
        if instance and instance.url:
            self.fields['url'].widget.attrs['readonly'] = True
            # Récupérer la liste des organisations
            try:
                with CkanBaseHandler(instance.url) as ckan:
                    organisations = ckan.get_all_organisations(
                        all_fields=True, include_dataset_count=True)
            except CkanBaseError as e:
                self.add_error('url', e.message)
            else:
                self.fields['sync_with'].choices = (
                    (organisation['name'], '{} ({})'.format(
                        organisation['display_name'],
                        organisation.get('package_count',
                                         organisation.get('packages', None))))
                    for organisation in organisations)

            mapping = []

            # Initialize categories mapping
            # =============================
            try:
                with CkanBaseHandler(instance.url) as ckan:
                    remote_categories = ckan.get_all_categories(
                        all_fields=True)
            except CkanBaseError as e:
                logger.error(e)
            else:
                fields_name = []
                for remote_category in remote_categories:
                    field_name = ''.join(['cat_', remote_category['name']])
                    fields_name.append(field_name)
                    try:
                        filter = {
                            'remote_ckan': instance,
                            'slug': field_name[4:]
                        }
                        initial = MappingCategory.objects.filter(
                            **filter).first().category
                    except Exception as e:
                        logger.warning(e)
                        try:
                            initial = Category.objects.get(slug=field_name[4:])
                        except Exception as e:
                            logger.warning(e)
                            initial = None

                    self.fields[field_name] = forms.ModelChoiceField(
                        label=remote_category['title'],
                        empty_label="Sélectionnez une valeur",
                        required=False,
                        queryset=Category.objects.all(),
                        initial=initial,
                    )

                mapping.append({
                    'name': 'Category',
                    'title': 'Categories',
                    'fields_name': fields_name,
                })

            # Initialize licences mapping
            # ===========================
            try:
                with CkanBaseHandler(instance.url) as ckan:
                    remote_licenses = ckan.get_all_licenses(all_fields=True)
            except CkanBaseError as e:
                logger.error(e)
            else:
                fields_name = []
                for remote_license in remote_licenses:
                    field_name = ''.join(['lic_', remote_license['id']])
                    fields_name.append(field_name)
                    try:
                        filter = {
                            'remote_ckan': instance,
                            'slug': field_name[4:]
                        }
                        initial = MappingLicence.objects.filter(
                            **filter).first().licence
                    except Exception as e:
                        logger.warning(e)
                        try:
                            initial = License.objects.get(slug=field_name[4:])
                        except Exception as e:
                            logger.warning(e)
                            initial = None

                    self.fields[field_name] = forms.ModelChoiceField(
                        label=remote_license['title'],
                        empty_label="Sélectionnez une valeur",
                        required=False,
                        queryset=License.objects.all(),
                        initial=initial,
                    )

                mapping.append({
                    'name': 'License',
                    'title': 'Licences',
                    'fields_name': fields_name,
                })

        else:
            self.fields['sync_with'].widget = forms.HiddenInput()
            self.fields['sync_frequency'].widget = forms.HiddenInput()

    def get_category_fields(self):
        return [self[val] for val in self.fields if val.startswith('cat')]

    def get_licence_fields(self):
        return [self[val] for val in self.fields if val.startswith('lic')]
예제 #3
0
class JurisdictionForm(forms.ModelForm):
    class Meta(object):
        model = Jurisdiction
        property_fields = (
            'name',
            'code',
        )
        fields = property_fields + ('communes', )

    name = forms.CharField(label="Nom*",
                           widget=forms.TextInput(attrs={
                               'placeholder':
                               "Le nom du territoire",
                           }, ))

    code = forms.CharField(label="Code d'identification*",
                           widget=forms.TextInput(attrs={
                               'placeholder':
                               "Par exemple le code INSEE",
                           }, ))

    communes = forms.ModelMultipleChoiceField(
        label="Communes",
        queryset=Commune.objects.all(),
        required=False,
        to_field_name='code',
        widget=CustomCheckboxSelectMultiple(attrs={
            'class': 'list-group-checkbox',
        }, ))

    jurisdiction = forms.ModelChoiceField(
        label="Rechercher un territoire existant",
        queryset=Jurisdiction.objects.all(),
        required=False,
        empty_label=None,
        widget=InputTypeahead(attrs={
            'placeholder': "Aucun",
        }),
    )

    prefill = forms.BooleanField(
        label=None,
        initial=False,
        required=False,
        widget=forms.HiddenInput(),
    )

    def __init__(self, *args, **kwargs):
        include = kwargs.pop('include', {})
        super().__init__(*args, **kwargs)

        if self.instance.pk:
            del self.fields['jurisdiction']
            del self.fields['prefill']
        else:
            self.fields['name'].required = False
            self.fields['code'].required = False

    def clean(self):
        if self.cleaned_data.get('jurisdiction'):
            self.cleaned_data['prefill'] = True
        return self.cleaned_data
예제 #4
0
class ResourceForm(forms.ModelForm):
    class Meta(object):
        model = Resource
        fields = (
            'crs',
            'data_type',
            'description',
            'dl_url',
            'encoding',
            'extractable',
            'format_type',
            'ftp_file',
            'geo_restriction',
            'lang',
            'title',
            'ogc_services',
            'organisations_allowed',
            'profiles_allowed',
            'referenced_url',
            'restricted_level',
            'sync_frequency',
            'synchronisation',
            'up_file',
        )
        fake = (
            'sync_frequency_dl',
            'sync_frequency_ftp',
            'synchronisation_dl',
            'synchronisation_ftp',
        )

    class CustomClearableFileInput(forms.ClearableFileInput):
        template_name = 'idgo_admin/widgets/file_drop_zone.html'

    up_file = forms.FileField(
        required=False,
        validators=[file_size],
        widget=CustomClearableFileInput(
            attrs={
                'value': '',  # IMPORTANT
                'max_size_info': DOWNLOAD_SIZE_LIMIT,
            }, ),
    )

    dl_url = forms.CharField(
        label="Veuillez indiquer l'URL d'un fichier à télécharger :",
        required=False,
        widget=forms.TextInput(
            attrs={
                'value': '',  # IMPORTANT
                'placeholder': "https://...",
            }, ),
    )

    referenced_url = forms.CharField(
        label="Veuillez indiquer l'URL d'un jeu de données à référencer :",
        required=False,
        widget=forms.TextInput(
            attrs={
                'value': '',  # IMPORTANT
                'placeholder': "https://...",
            }, ),
    )

    ftp_file = forms.ChoiceField(
        label=
        "Les fichiers que vous avez déposés sur votre compte FTP apparaîssent dans la liste ci-dessous :",
        required=False,
        choices=[],
    )

    synchronisation_dl = forms.BooleanField(
        label="Synchroniser les données",
        required=False,
        initial=False,
    )

    sync_frequency_dl = forms.ChoiceField(
        label="Fréquence de synchronisation",
        required=False,
        initial='never',
        choices=Meta.model.FREQUENCY_CHOICES,
        widget=forms.Select(attrs={
            'class': 'disabled',
            'disabled': True,
        }, ),
    )

    synchronisation_ftp = forms.BooleanField(
        label="Synchroniser les données",
        required=False,
        initial=False,
    )

    sync_frequency_ftp = forms.ChoiceField(
        label="Fréquence de synchronisation",
        required=False,
        initial='never',
        choices=Meta.model.FREQUENCY_CHOICES,
        widget=forms.Select(attrs={
            'class': 'disabled',
            'disabled': True,
        }, ),
    )

    title = forms.CharField(
        label='Titre*',
        required=True,
        widget=forms.TextInput(attrs={
            'placeholder': "Titre",
        }, ),
    )

    description = forms.CharField(
        label="Description",
        required=False,
        widget=forms.Textarea(attrs={
            'placeholder':
            "Vous pouvez utiliser le langage Markdown ici",
        }, ),
    )

    data_type = forms.ChoiceField(
        label="Type",
        required=True,
        choices=Meta.model.TYPE_CHOICES,
    )

    format_type = ModelFormatTypeField(
        label="Format*",
        empty_label="Sélectionnez un format",
        required=True,
        queryset=ResourceFormats.objects.all().order_by('extension'),
        widget=FormatTypeSelect(),
    )

    crs = forms.ModelChoiceField(
        label="Système de coordonnées du jeu de données géographiques",
        required=False,
        queryset=SupportedCrs.objects.all(),
        to_field_name='auth_code',
    )

    encoding = forms.CharField(
        label="Encodage des données (« UTF-8 » par défaut)",
        required=False,
        widget=forms.TextInput(attrs={
            'placeholder':
            "Par exemple: Latin1, ISO_8859-1, etc.",
        }, ),
    )

    restricted_level = forms.ChoiceField(
        label="Restriction d'accès",
        required=True,
        choices=Meta.model.LEVEL_CHOICES,
    )

    profiles_allowed = forms.ModelMultipleChoiceField(
        label="Utilisateurs autorisés",
        required=False,
        queryset=Profile.objects.filter(
            is_active=True).order_by('user__last_name'),
        to_field_name='pk',
        widget=CustomCheckboxSelectMultiple(attrs={
            'class': "list-group-checkbox",
        }, ),
    )

    organisations_allowed = forms.ModelMultipleChoiceField(
        label="Organisations autorisées",
        required=False,
        queryset=Organisation.objects.filter(is_active=True).order_by('slug'),
        to_field_name='pk',
        widget=CustomCheckboxSelectMultiple(attrs={
            'class': "list-group-checkbox",
        }, ),
    )

    geo_restriction = forms.BooleanField(
        label="Restreindre l'accès au territoire de compétence",
        required=False,
        # initial=False,
    )

    extractable = forms.BooleanField(
        label="Activer le service d'extraction des données géographiques",
        required=False,
        # initial=True,
    )

    ogc_services = forms.BooleanField(
        label="Activer les services OGC associés",
        required=False,
        # initial=True,
    )

    def __init__(self, *args, **kwargs):
        self.include_args = kwargs.pop('include', {})
        self._dataset = kwargs.pop('dataset', None)
        instance = kwargs.get('instance', None)
        user = kwargs.pop('user', None)
        super().__init__(*args, **kwargs)

        dir = os.path.join(FTP_DIR, user.username, FTP_UPLOADS_DIR)
        choices = [(None, 'Veuillez sélectionner un fichier')]
        for path, subdirs, files in os.walk(dir):
            for name in files:
                filename = os.path.join(path, name)
                choices.append((filename, filename[len(dir) + 1:]))
        self.fields['ftp_file'].choices = choices

        if user.profile.is_admin:
            choices = self.Meta.model.EXTRA_FREQUENCY_CHOICES + self.Meta.model.FREQUENCY_CHOICES
            self.fields['sync_frequency_ftp'].choices = choices
            self.fields['sync_frequency_dl'].choices = choices

        if instance:

            related_profiles = Case(
                When(pk__in=[m.pk for m in instance.profiles_allowed.all()],
                     then=Value(True)),
                default=Value(False),
                output_field=BooleanField(),
            )
            self.fields['profiles_allowed'].queryset = \
                Profile.objects.annotate(related=related_profiles).order_by('-related', 'user__username')

            related_organisations = Case(
                When(pk__in=[
                    m.pk for m in instance.organisations_allowed.all()
                ],
                     then=Value(True)),
                default=Value(False),
                output_field=BooleanField(),
            )
            self.fields['organisations_allowed'].queryset = \
                Organisation.objects.annotate(related=related_organisations).order_by('-related', 'slug')

            if instance.up_file:
                self.fields['up_file'].widget.attrs['value'] = instance.up_file
            elif instance.ftp_file:
                self.fields[
                    'synchronisation_ftp'].initial = instance.synchronisation
                self.fields[
                    'sync_frequency_ftp'].initial = instance.sync_frequency
                try:
                    instance.ftp_file.file
                except FileNotFoundError:
                    self.fields['ftp_file'] = forms.CharField(
                        label=
                        "Fichier initialement déposé sur votre compte FTP (ce fichier n'est plus détecté) :",
                        required=False,
                        widget=forms.TextInput(attrs={
                            'class': 'disabled',
                            'disabled': True,
                        }, ),
                    )
            elif instance.dl_url:
                self.fields[
                    'synchronisation_dl'].initial = instance.synchronisation
                self.fields[
                    'sync_frequency_dl'].initial = instance.sync_frequency

    def clean(self):

        res_l = {
            'up_file': self.cleaned_data.get('up_file') or None,
            'dl_url': self.cleaned_data.get('dl_url') or None,
            'referenced_url': self.cleaned_data.get('referenced_url') or None,
            'ftp_file': self.cleaned_data.get('ftp_file') or None,
        }

        self.cleaned_data['synchronisation'] = \
            self.cleaned_data.get('synchronisation_ftp') or self.cleaned_data['synchronisation_dl']
        self.cleaned_data['sync_frequency'] = \
            self.cleaned_data['sync_frequency_ftp'] or self.cleaned_data['sync_frequency_dl']
        del self.cleaned_data['synchronisation_dl']
        del self.cleaned_data['synchronisation_ftp']
        del self.cleaned_data['sync_frequency_dl']
        del self.cleaned_data['sync_frequency_ftp']

        if all(v is None for v in list(res_l.values())):
            for field in list(res_l.keys()):
                self.add_error(field, 'Ce champ est obligatoire.')

        if sum(v is not None for v in list(res_l.values())) > 1:
            error_msg = "Un seul type de ressource n'est autorisé."
            for k, v in res_l.items():
                if v:
                    self.add_error(k, error_msg)

        return self.cleaned_data