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()
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')]
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
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