def change_suit_form_tabs(self, obj):
        form_tabs = [
            ('general', _('General')),
            *LangFieldsOnlyMixin.get_translations_tabs(),
            ('file', _('File validation')),
            ('link', _('Link validation')),
            ('data', _('Data validation')),
        ]

        if obj.tabular_data_schema and obj.format != 'shp':
            form_tabs.append(('types', _("Change of type")))

        resource_validation_tab = ('rules', _('Quality verification'),
                                   'disabled')

        if (settings.RESOURCE_VALIDATION_TOOL_ENABLED
                and obj.tabular_data_schema and obj.format != 'shp'
                and obj.has_data):
            resource_validation_tab = ('rules', _('Quality verification'))

        form_tabs.append(resource_validation_tab)

        maps_and_plots_tab = ("maps_and_plots", _("Maps and plots"),
                              'disabled')
        if obj.tabular_data_schema:
            maps_and_plots_tab = ("maps_and_plots", _("Maps and plots"))
        form_tabs.append(maps_and_plots_tab)

        return form_tabs
Esempio n. 2
0
class SpecialSignAdmin(SpecialSignAdminMixin, HistoryMixin,
                       LangFieldsOnlyMixin, SoftDeleteMixin, MCODAdminMixin,
                       admin.ModelAdmin):

    actions_on_top = True
    form = SpecialSignAdminForm
    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_translations_tabs(),
    )

    def has_delete_permission(self, request, obj=None):
        has_delete_permission = super().has_delete_permission(request, obj=obj)
        if obj and obj.special_signs_resources.exists():
            return False
        return has_delete_permission

    def get_fieldsets(self, request, obj=None):
        fieldsets = [
            (
                None,
                {
                    'classes': (
                        'suit-tab',
                        'suit-tab-general',
                    ),
                    'fields': (
                        'symbol',
                        'name',
                        'description',
                    )
                },
            ),
            (
                None,
                {
                    'classes': (
                        'suit-tab',
                        'suit-tab-general',
                    ),
                    'fields': ('status', )
                },
            ),
        ]
        translations_fieldsets = self.get_translations_fieldsets()
        for title, fieldset in translations_fieldsets:
            fieldset['fields'] = [
                x for x in fieldset.get('fields', []) if x != 'slug_en'
            ]
        fieldsets += translations_fieldsets
        return fieldsets

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = super().get_readonly_fields(request, obj=obj)
        if obj:
            readonly_fields += ('symbol', )
        return readonly_fields
Esempio n. 3
0
 def suit_form_tabs(self):
     suit_form_tabs = [
         ('general', _('General')),
         *LangFieldsOnlyMixin.get_traslations_tabs(),
         ('contact', _('Contact')),
     ]
     if self._request.user.is_superuser:
         suit_form_tabs += [('users', _('Users'))]
     suit_form_tabs += [('datasets', _('Datasets'))]
     return suit_form_tabs
Esempio n. 4
0
class CategoryAdmin(LangFieldsOnlyMixin, HistoryMixin, MCODAdminMixin,
                    admin.ModelAdmin):
    prepopulated_fields = {
        "slug": ("title", ),
    }
    is_history_with_unknown_user_rows = True
    actions_on_top = True
    list_display = ['title_i18n', 'code', 'obj_history']

    first_section_fields = ['code', 'title', 'slug', 'description']

    fieldsets = [
        (None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': first_section_fields,
        }),
        (None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': [
                'image',
            ]
        }),
        (None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': [
                'status',
            ]
        }),
    ]

    def get_fieldsets(self, request, obj=None):
        return self.get_translations_fieldsets() + self.fieldsets

    suit_form_tabs = (('general', _('General')),
                      *LangFieldsOnlyMixin.get_translations_tabs())
Esempio n. 5
0
class ArticleAdmin(DynamicAdminListDisplayMixin, CreatedByDisplayAdminMixin,
                   StatusLabelAdminMixin, SoftDeleteMixin, HistoryMixin,
                   LangFieldsOnlyMixin, MCODAdminMixin, admin.ModelAdmin):
    actions_on_top = True
    autocomplete_fields = ['tags']
    prepopulated_fields = {"slug": ("title", )}
    fieldsets = (
        (None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': (
                "preview_link",
                "title",
            )
        }),
        ('url', {
            'classes': (
                'collapse',
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': ("slug", )
        }),
        (None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': ("notes", 'author', 'license', 'status', 'category')
        }),
        (_("Tags"), {
            'classes': (
                'suit-tab',
                'suit-tab-tags',
            ),
            'fields': ('tags_pl', 'tags_en'),
        }),
    )
    readonly_fields = ['preview_link']
    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_translations_tabs(),
        ('tags', _('Tags')),
    )

    list_display = [
        "title", "status", "created_by", 'category', 'preview_link',
        'obj_history'
    ]
    list_filter = [
        'category',
    ]
    search_fields = ["title", "created_by__email"]
    form = ArticleForm

    def get_fieldsets(self, request, obj=None):
        return self.fieldsets + tuple(self.get_translations_fieldsets())

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj, **kwargs)
        form.recreate_tags_widgets(request=request,
                                   db_field=Article.tags.field,
                                   admin_site=self.admin_site)
        return form

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        self.request = request
        return qs

    def preview_link(self, obj):
        return obj.preview_link

    preview_link.allow_tags = True
    preview_link.short_description = _('Preview link')

    def save_model(self, request, obj, form, change):
        if 'slug' in form.cleaned_data:
            if form.cleaned_data['slug'] == "":
                obj.slug = slugify(form.cleaned_data['title'])
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        obj.save()

    class Media:
        js = ("articles/js/hide_license_buttons.js", )
class ResourceAdmin(DynamicAdminListDisplayMixin, AddChangeMixin,
                    StatusLabelAdminMixin, AdminListMixin, SoftDeleteMixin,
                    HistoryMixin, ExportCsvMixin, LangFieldsOnlyMixin,
                    MCODAdminMixin, admin.ModelAdmin):
    actions_on_top = True

    TYPE_FILTER = TypeFilter
    TYPE_DISPLAY_FIELD = 'type_as_str'

    def change_suit_form_tabs(self, obj):
        form_tabs = [
            ('general', _('General')),
            *LangFieldsOnlyMixin.get_translations_tabs(),
            ('file', _('File validation')),
            ('link', _('Link validation')),
            ('data', _('Data validation')),
        ]

        if obj.tabular_data_schema and obj.format != 'shp':
            form_tabs.append(('types', _("Change of type")))

        resource_validation_tab = ('rules', _('Quality verification'),
                                   'disabled')

        if (settings.RESOURCE_VALIDATION_TOOL_ENABLED
                and obj.tabular_data_schema and obj.format != 'shp'
                and obj.has_data):
            resource_validation_tab = ('rules', _('Quality verification'))

        form_tabs.append(resource_validation_tab)

        maps_and_plots_tab = ("maps_and_plots", _("Maps and plots"),
                              'disabled')
        if obj.tabular_data_schema:
            maps_and_plots_tab = ("maps_and_plots", _("Maps and plots"))
        form_tabs.append(maps_and_plots_tab)

        return form_tabs

    add_suit_form_tabs = (('general', _('General')),
                          *LangFieldsOnlyMixin.get_translations_tabs())
    has_high_value_data_fieldset = [(None, {
        'classes': ('suit-tab', 'suit-tab-general'),
        'fields': ('has_high_value_data', ),
    })] if is_enabled('S41_resource_has_high_value_data.be') else []

    add_fieldsets = [(None, {
        'classes': ('suit-tab', 'suit-tab-general'),
        'fields': ('switcher', 'file', 'link'),
    }),
                     (None, {
                         'classes': ('suit-tab', 'suit-tab-general'),
                         'fields': ('title', 'description'),
                     }),
                     (None, {
                         'classes': ('suit-tab', 'suit-tab-general'),
                         'fields': ('dataset', ),
                     }),
                     (None, {
                         'classes': ('suit-tab', 'suit-tab-general'),
                         'fields': ('data_date', ),
                     }), *has_high_value_data_fieldset,
                     (None, {
                         'classes': ('suit-tab', 'suit-tab-general'),
                         'fields': ('status', 'from_resource'),
                     }),
                     (None, {
                         'classes': ('suit-tab', 'suit-tab-general'),
                         'fields': ('special_signs', ),
                     })]

    change_readonly_fields = (
        'formats',
        'file',
        'csv_file',
        'jsonld_file',
        'packed_file',
        'link',
        'modified',
        'created',
        'verified',
        'type',
        'file_info',
        'file_encoding',
        'special_signs_symbols',
        'link_tasks',
        'file_tasks',
        'data_tasks',
    )

    add_readonly_fields = ()

    list_display = [
        'title',
        'uuid',
        'formats',
        'dataset',
        'status',
        TYPE_DISPLAY_FIELD,
        'link_status',
        'file_status',
        'tabular_view',
        'created',
    ]

    list_filter = [
        DatasetFilter, FormatFilter, TYPE_FILTER, "status", LinkStatusFilter,
        FileStatusFilter, TabularViewFilter
    ]
    search_fields = ['title', 'uuid']
    autocomplete_fields = ['dataset']
    add_form = AddResourceForm
    form = ChangeResourceForm

    inlines = [
        FileTaskResultInline,
        DataTaskResultInline,
        LinkTaskResultInline,
    ]
    suit_form_includes = (
        ('widgets/resource_data_types_actions.html', 'bottom', 'types'),
        ('widgets/resource_data_rules_actions.html', 'bottom', 'rules'),
        ('widgets/resource_maps_and_plots_actions.html', 'bottom',
         'maps_and_plots'),
    )

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'dataset':
            kwargs[
                'queryset'] = db_field.remote_field.model._default_manager.filter(
                    source__isnull=True)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

    def has_change_permission(self, request, obj=None):
        if obj and obj.is_imported:
            return True  # required to display content in "data validation tabs" properly.
        return super().has_change_permission(request, obj=obj)

    def tabular_data_rules_fieldset(self, obj):
        fieldsets = []
        if obj.has_data:
            fieldsets = [
                (None, {
                    'classes': ('suit-tab', 'suit-tab-rules', 'full-width'),
                    'fields': ('data_rules', )
                }),
            ]
        return fieldsets

    def tabular_data_schema_fieldset(self, obj):
        fieldsets = []
        if obj.tabular_data_schema:
            fieldsets = [
                (None, {
                    'classes': ('suit-tab', 'suit-tab-types', 'full-width'),
                    'fields': ('tabular_data_schema', )
                }),
            ]
        return fieldsets

    def maps_and_plots_fieldset(self, obj):
        fields = (
            'maps_and_plots',
            'is_chart_creation_blocked',
        )
        fieldsets = [
            (None, {
                'classes':
                ('suit-tab', 'suit-tab-maps_and_plots', 'full-width'),
                'fields': fields,
            }),
        ]
        return fieldsets if obj.tabular_data_schema else []

    def get_fieldsets(self, request, obj=None):
        if obj:
            jsonld_file = ['jsonld_file'] if obj.jsonld_converted_file else []
            jsonld_file = ['jsonld_converted_file'
                           ] if jsonld_file and is_enabled(
                               'S40_new_file_model.be') else jsonld_file
            csv_file = [
                'csv_converted_file'
            ] if is_enabled('S40_new_file_model.be') else ['csv_file']
            file = ['main_file'
                    ] if is_enabled('S40_new_file_model.be') else ['file']
            special_signs = ['special_signs'] if not obj.is_imported else [
                'special_signs_symbols'
            ]
            file_info = [
                'main_file_info'
            ] if is_enabled('S40_new_file_model.be') else ['file_info']
            file_encoding = [
                'main_file_encoding'
            ] if is_enabled('S40_new_file_model.be') else ['file_encoding']
            regions = ['regions'
                       ] if is_enabled('S37_resources_admin_region_data.be'
                                       ) and not obj.is_imported else []
            if is_enabled('S41_resource_has_high_value_data.be'):
                has_high_value_data = [
                    'has_high_value_data'
                ] if not obj.is_imported else ['has_high_value_data_info']
            else:
                has_high_value_data = []
            extra_fields = []
            if obj.type == RESOURCE_TYPE_WEBSITE or obj.forced_api_type:
                extra_fields = ['forced_api_type']
            elif not obj.forced_api_type and (
                    obj.type == RESOURCE_TYPE_API or obj.forced_file_type or
                (obj.type == RESOURCE_TYPE_FILE
                 and obj.tracker.has_changed('forced_file_type'))):
                extra_fields = ['forced_file_type']

            extra_fields = extra_fields if not obj.is_imported else []
            tab_general_fields = (
                'link',
                *extra_fields,
                *file,
                *csv_file,
                *jsonld_file,
                'packed_file',
                'title',
                'description',
                'formats',
                'dataset',
                *regions,
                'data_date',
                *has_high_value_data,
                'status',
                *special_signs,
                'show_tabular_view',
                'modified',
                'created',
                'verified',
                'type',
                *file_info,
                *file_encoding,
            )
            if not obj.csv_converted_file:
                tab_general_fields = (x for x in tab_general_fields
                                      if x != csv_file[0])
            change_fieldsets = [
                (None, {
                    'classes': (
                        'suit-tab',
                        'suit-tab-general',
                    ),
                    'fields': tab_general_fields,
                }),
            ]
            fieldsets = (change_fieldsets +
                         self.tabular_data_rules_fieldset(obj) +
                         self.tabular_data_schema_fieldset(obj) +
                         self.maps_and_plots_fieldset(obj))
        else:
            fieldsets = self.add_fieldsets
            fieldsets[2][1]['fields'] = ('dataset', 'regions') if is_enabled(
                'S37_resources_admin_region_data.be') else ('dataset', )
            fieldsets = tuple(fieldsets)

        fieldsets += tuple(self.get_translations_fieldsets())

        return fieldsets

    def get_form(self, request, obj=None, **kwargs):
        """
        Use special form during user creation
        """
        defaults = {}
        if obj is None:
            defaults['form'] = self.add_form
        defaults.update(kwargs)
        return super().get_form(request, obj=obj, **defaults)

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = self.change_readonly_fields if obj and obj.id else self.add_readonly_fields
        if is_enabled('S40_new_file_model.be'):
            new_fields_mapping = {
                'file': 'main_file',
                'file_info': 'main_file_info',
                'file_encoding': 'main_file_encoding',
                'csv_file': 'csv_converted_file',
                'jsonld_file': 'jsonld_converted_file'
            }
            readonly_fields =\
                [field if field not in new_fields_mapping else new_fields_mapping[field] for field in readonly_fields]
        if obj and not obj.data_is_valid:
            readonly_fields = (*readonly_fields, 'show_tabular_view')
        if obj and obj.type != "file":
            readonly_fields = (*readonly_fields, 'data_date')
        if obj and obj.is_imported:
            readonly_fields = (*readonly_fields, 'dataset', 'data_date',
                               'description', 'description_en',
                               'show_tabular_view', 'slug_en', 'status',
                               'title', 'title_en',
                               'is_chart_creation_blocked',
                               'has_high_value_data_info')
        return tuple(set(readonly_fields))

    def render_change_form(self,
                           request,
                           context,
                           add=False,
                           change=False,
                           form_url='',
                           obj=None):
        extra = {
            'suit_form_tabs':
            self.change_suit_form_tabs(obj)
            if obj else self.add_suit_form_tabs,
        }
        if obj and obj.is_imported:
            extra['show_save'] = False
            extra['show_save_and_continue'] = False
        context.update(extra)
        return super().render_change_form(request,
                                          context,
                                          add=add,
                                          change=change,
                                          form_url=form_url,
                                          obj=obj)

    def get_queryset(self, request):
        qs = super().get_queryset(request)

        if request.user.is_staff and not request.user.is_superuser:
            qs = qs.filter(dataset__organization__in=request.user.
                           organizations.iterator())
        if not is_enabled('S41_resource_AP_optimization.be'):
            link_tasks = TaskResult.objects.filter(
                link_task_resources=OuterRef('pk')).order_by('-date_done')
            qs = qs.annotate(
                _link_status=Subquery(link_tasks.values('status')[:1]))
            file_tasks = TaskResult.objects.filter(
                file_task_resources=OuterRef('pk')).order_by('-date_done')
            qs = qs.annotate(
                _file_status=Subquery(file_tasks.values('status')[:1]))

            data_tasks = TaskResult.objects.filter(
                data_task_resources=OuterRef('pk')).order_by('-date_done')
            qs = qs.annotate(
                _data_status=Subquery(data_tasks.values('status')[:1]))
        return qs

    def link_status(self, obj):
        return self._format_list_status(
            obj.link_tasks_last_status if is_enabled(
                'S41_resource_AP_optimization.be') else obj._link_status)

    link_status.admin_order_field = 'link_tasks_last_status' if\
        is_enabled('S41_resource_AP_optimization.be') else '_link_status'

    def file_status(self, obj):
        return self._format_list_status(
            obj.file_tasks_last_status if is_enabled(
                'S41_resource_AP_optimization.be') else obj._file_status)

    file_status.admin_order_field = 'file_tasks_last_status' if\
        is_enabled('S41_resource_AP_optimization.be') else '_file_status'

    def formats(self, obj):
        return obj.formats or '-'

    formats.admin_order_field = 'format'
    formats.short_description = 'Format'

    def has_high_value_data_info(self, obj):
        return obj.has_high_value_data or False

    has_high_value_data_info.short_description = _('has high value data')
    has_high_value_data_info.boolean = True

    def special_signs_symbols(self, obj):
        return obj.special_signs_symbols or '-'

    special_signs_symbols.short_description = _('Special Signs')

    def tabular_view(self, obj):
        return self._format_list_status(
            obj.data_tasks_last_status if is_enabled(
                'S41_resource_AP_optimization.be') else obj._data_status)

    tabular_view.admin_order_field = 'data_tasks_last_status' if\
        is_enabled('S41_resource_AP_optimization.be') else '_data_status'

    tabular_view.short_description = format_html(
        '<i class="fas fa-table" title="{}"></i>'.format(
            _('Tabular data validation status')))
    file_status.short_description = format_html(
        '<i class="fas fa-file" title="{}"></i>'.format(
            _('File validation status')))
    link_status.short_description = format_html(
        '<i class="fas fa-link" title="{}"></i>'.format(
            _('Link validation status')))

    def save_model(self, request, obj, form, change):
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        if is_enabled('S40_new_file_model.be') and obj.file:
            obj.file = None
        obj.save()
        if is_enabled('S40_new_file_model.be') and form.cleaned_data.get(
                'file'):
            ResourceFile.objects.update_or_create(
                resource=obj,
                is_main=True,
                defaults={'file': form.cleaned_data['file']})

    def get_changeform_initial_data(self, request):
        """
        Get the initial form data from the request's GET params.
        """

        obj_id = request.GET.get('from_id')
        initial = {}
        if obj_id:
            try:
                origin = Resource.objects.get(pk=obj_id)
            except Resource.DoesNotExist:
                origin = None
            if origin and not origin.is_imported:  # making a copy of resource is disabled for imported resources.
                data = model_to_dict(origin)
                initial['title'] = data.get('title')
                initial['description'] = data.get('description')
                initial['status'] = data.get('status')
                initial['dataset'] = data.get('dataset')
                initial['from_resource'] = origin
                initial['title_en'] = data.get('title_en')
                initial['description_en'] = data.get('description_en')
                initial['slug_en'] = data.get('slug_en')
        return initial

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('<path:resource_id>/revalidate/',
                 self.revalidate,
                 name='resource-revalidate')
        ]
        return custom_urls + urls

    def revalidate(self, request, resource_id, *args, **kwargs):
        if not self.has_change_permission(request):
            raise PermissionDenied
        try:
            resource = self.model.objects.get(pk=resource_id)
        except self.model.DoesNotExist:
            messages.add_message(request, messages.WARNING,
                                 _('Resource with this id does not exists'))
            return HttpResponseRedirect(self.model.admin_list_url())

        resource.revalidate()
        messages.add_message(request, messages.SUCCESS,
                             _('Task for resource revalidation queued'))
        return HttpResponseRedirect(resource.admin_change_url)

    def response_change(self, request, obj):

        if '_verify_rules' in request.POST:
            rules = get_paremeters_from_post(request.POST)
            results = obj.verify_rules(rules)
            for col, res in results.items():
                res, msg_class = process_verification_results(
                    col, res, obj.tabular_data_schema, rules)
                self.message_user(request, res, msg_class)
            return HttpResponseRedirect(".")
        elif '_change_type' in request.POST:
            obj.save()
            messages.add_message(request, messages.SUCCESS,
                                 _('Data type changed'))
            self.revalidate(request, obj.id)
        elif '_map_save' in request.POST:
            obj.save()
            messages.add_message(request, messages.SUCCESS,
                                 _('Map definition saved'))
            self.revalidate(request, obj.id)
        elif '_continue' in request.POST or\
             (is_enabled('S41_resource_revalidate.be') and '_save' in request.POST):
            if is_enabled('S41_resource_revalidate.be'):
                obj.save()
            self.revalidate(request, obj.id)
        return super().response_change(request, obj)

    def _changeform_view(self, request, object_id, form_url, extra_context):
        if '_verify_rules' in request.POST:
            obj = self.model.objects.get(pk=object_id)
            return self.response_change(request, obj)
        else:
            return super()._changeform_view(request, object_id, form_url,
                                            extra_context)
class ShowcaseAdmin(DynamicAdminListDisplayMixin, CreatedByDisplayAdminMixin,
                    CRUDMessageMixin, SoftDeleteMixin, HistoryMixin,
                    LangFieldsOnlyMixin, MCODAdminMixin, admin.ModelAdmin):
    actions_on_top = True
    prepopulated_fields = {'slug': ('title', )}
    autocomplete_fields = ['tags']
    readonly_fields = [
        'application_logo', 'illustrative_graphics_img', 'preview_link'
    ]
    list_display = [
        'category', 'title', 'created_by', 'application_logo', 'modified',
        'main_page_position', 'status', 'obj_history'
    ]
    list_display_links = ('title', )
    obj_gender = 'n'
    search_fields = ['title', 'created_by__email', 'url']
    list_filter = ['status', 'main_page_position']
    list_editable = ['status']

    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_translations_tabs(),
        ('tags', _('Tags')),
        ('datasets', _('Datasets')),
    )

    form = ShowcaseForm
    is_history_with_unknown_user_rows = True

    def get_translations_fieldsets(self):
        i18n_field = get_i18n_field(self.model)
        fieldsets = []
        for lang_code in settings.MODELTRANS_AVAILABLE_LANGUAGES:
            fields = [
                f'{f.name}' for f in i18n_field.get_translated_fields()
                if f.name.endswith(lang_code)
            ]
            if lang_code == settings.LANGUAGE_CODE:
                continue
            tab_name = 'general' if lang_code == settings.LANGUAGE_CODE else f'lang-{lang_code}'
            fieldset = (None, {
                'classes': (
                    'suit-tab',
                    f'suit-tab-{tab_name}',
                ),
                'fields': fields
            })
            fieldsets.append(fieldset)
        return fieldsets

    def get_form(self, request, obj=None, **kwargs):
        form = super().get_form(request, obj=obj, **kwargs)
        form.recreate_tags_widgets(request=request,
                                   db_field=Showcase.tags.field,
                                   admin_site=self.admin_site)
        return form

    def get_fieldsets(self, request, obj=None):
        return [(None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': (
                'preview_link',
                'category',
                'title',
                'slug',
            )
        }),
                (None, {
                    'classes': (
                        'collapse',
                        'suit-tab',
                        'suit-tab-general',
                    ),
                    'fields': (
                        'is_mobile_app',
                        'mobile_apple_url',
                        'mobile_google_url',
                        'is_desktop_app',
                        'desktop_windows_url',
                        'desktop_linux_url',
                        'desktop_macos_url',
                        'license_type',
                    )
                }),
                (None, {
                    'classes': (
                        'suit-tab',
                        'suit-tab-general',
                    ),
                    'fields': (
                        'notes',
                        'author',
                        'external_datasets',
                        'url',
                        'image',
                        'image_alt',
                        'application_logo',
                        'illustrative_graphics',
                        'illustrative_graphics_alt',
                        'illustrative_graphics_img',
                        'main_page_position',
                        'status',
                    ),
                }),
                (_('Datasets'), {
                    'classes': (
                        'suit-tab',
                        'suit-tab-datasets',
                    ),
                    'fields': ('datasets', )
                }),
                (None, {
                    'classes': (
                        'suit-tab',
                        'suit-tab-tags',
                    ),
                    'fields': (
                        'tags_pl',
                        'tags_en',
                    )
                })] + self.get_translations_fieldsets()

    def application_logo(self, obj):
        return obj.application_logo or '-'

    application_logo.short_description = _('Logo')

    def illustrative_graphics_img(self, obj):
        return obj.illustrative_graphics_img or '-'

    illustrative_graphics_img.short_description = _('Illustrative graphics')

    def preview_link(self, obj):
        return obj.preview_link

    preview_link.allow_tags = True
    preview_link.short_description = _('Preview link')

    def save_model(self, request, obj, form, change):
        if 'slug' in form.cleaned_data:
            if form.cleaned_data['slug'] == '':
                obj.slug = slugify(form.cleaned_data['title'])
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        if 'external_datasets' in form.cleaned_data:
            obj.external_datasets = form.cleaned_data['external_datasets']
        super().save_model(request, obj, form, change)
Esempio n. 8
0
class DatasetAdmin(DynamicAdminListDisplayMixin, CreatedByDisplayAdminMixin,
                   StatusLabelAdminMixin, AddChangeMixin, SoftDeleteMixin,
                   HistoryMixin, ExportCsvMixin, LangFieldsOnlyMixin,
                   MCODAdminMixin, admin.ModelAdmin):
    actions_on_top = True
    autocomplete_fields = ['tags', 'organization']
    list_display = [
        'title', 'organization', 'created', 'created_by', 'status',
        'obj_history'
    ]
    readonly_fields = [
        'created_by', 'created', 'modified', 'verified', 'dataset_logo'
    ]
    inlines = [
        ChangeResourceStacked,
        AddResourceStacked,
    ]
    search_fields = [
        "title",
    ]
    prepopulated_fields = {
        "slug": ("title", ),
    }

    list_filter = ['categories', OrganizationFilter, 'status']

    form = DatasetForm

    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_translations_tabs(),
        ('licenses', _('Conditions')),
        ('tags', _('Tags')),
        ('resources', _('Resources')),
    )

    suit_form_includes = (('admin/datasets/licences/custom_include.html',
                           'top', 'licenses'), )

    def has_high_value_data_info(self, obj):
        return obj.has_high_value_data

    has_high_value_data_info.short_description = _('has high value data')
    has_high_value_data_info.boolean = True

    def update_frequency_display(self, obj):
        return obj.frequency_display

    update_frequency_display.short_description = _('Update frequency')

    def get_fieldsets(self, request, obj=None):
        tags_tab_fields = ('tags_list_pl',
                           'tags_list_en') if obj and obj.is_imported else (
                               'tags_pl', 'tags_en')
        update_frequency_field = 'update_frequency_display' if obj and obj.is_imported else 'update_frequency'
        category_field = 'categories_list' if obj and obj.is_imported else 'categories'
        frequency_fields = []
        if not (obj and obj.is_imported):
            frequency_fields = [
                'is_update_notification_enabled',
                'update_notification_frequency',
                'update_notification_recipient_email',
            ]
        has_high_value_data = []
        if is_enabled('S35_high_value_data.be'):
            has_high_value_data = [
                'has_high_value_data_info'
            ] if obj and obj.is_imported else ['has_high_value_data']
        general_fields = [
            'notes',
            'url',
            'image',
            'image_alt',
            'dataset_logo',
            'customfields',
            update_frequency_field,
            *frequency_fields,
            'organization',
            category_field,
            *has_high_value_data,
        ]
        if is_enabled('S41_resource_bulk_download.be'):
            general_fields += ['archived_resources_files']
        general_fields += [
            'status', 'created_by', 'created', 'modified', 'verified'
        ]

        return [(None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': (
                'title',
                'slug',
            )
        }),
                (None, {
                    'classes': (
                        'suit-tab',
                        'suit-tab-tags',
                    ),
                    'fields': tags_tab_fields,
                }),
                (None, {
                    'classes': (
                        'suit-tab',
                        'suit-tab-general',
                    ),
                    'fields': general_fields
                }),
                (None, {
                    'classes': (
                        'suit-tab',
                        'suit-tab-licenses',
                    ),
                    'fields': (
                        'license_condition_source',
                        'license_condition_modification',
                        'license_condition_responsibilities',
                        'license_condition_db_or_copyrighted',
                        'license_chosen',
                        'license_condition_personal_data',
                    ),
                })] + self.get_translations_fieldsets()

    def get_readonly_fields(self, request, obj=None):
        read_only_fields = super(DatasetAdmin,
                                 self).get_readonly_fields(request, obj)
        archived_resources = [
            'archived_resources_files'
        ] if is_enabled('S41_resource_bulk_download.be') else []
        read_only_fields = archived_resources + read_only_fields
        return read_only_fields

    def categories_list(self, instance):
        return instance.categories_list_as_html

    categories_list.short_description = _('Categories')

    def tags_list_pl(self, instance):
        return instance.tags_as_str(lang='pl')

    tags_list_pl.short_description = _('Tags') + ' (PL)'

    def tags_list_en(self, instance):
        return instance.tags_as_str(lang='en')

    tags_list_en.short_description = _('Tags') + ' (EN)'

    def get_search_results(self, request, queryset, search_term):
        if request.path == '/datasets/dataset/autocomplete/':
            queryset = queryset.filter(source__isnull=True)
        return super().get_search_results(request, queryset, search_term)

    def render_change_form(self, request, context, **kwargs):
        obj = kwargs.get('obj')
        if obj and obj.source:
            context.update({
                'show_save': False,
                'show_save_and_continue': False,
            })
        return super().render_change_form(request, context, **kwargs)

    def save_model(self, request, obj, form, change):
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        if not request.user.is_superuser:
            obj.update_notification_recipient_email = request.user.email
            if obj.tracker.has_changed('update_frequency'):
                obj.update_notification_frequency = UPDATE_NOTIFICATION_FREQUENCY_DEFAULT_VALUES.get(
                    obj.update_frequency)

        super().save_model(request, obj, form, change)

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            if not instance.id:
                instance.created_by = request.user
            instance.modified_by = request.user
        super().save_formset(request, form, formset, change)

    def get_form(self, request, obj=None, **kwargs):
        self._request = request
        form = super().get_form(request, obj, **kwargs)
        form.recreate_tags_widgets(request=request,
                                   db_field=Dataset.tags.field,
                                   admin_site=self.admin_site)
        return form

    def get_queryset(self, request):
        queryset = super().get_queryset(request)
        if request.user.is_superuser:
            return queryset
        return queryset.filter(
            organization_id__in=request.user.organizations.all())

    def has_history_permission(self, request, obj):
        return request.user.is_superuser or request.user.is_editor_of_organization(
            obj.organization)

    def dataset_logo(self, obj):
        return obj.dataset_logo or '-'

    dataset_logo.short_description = _('Logo')

    class Media:  # Empty media class is required if you are using autocomplete filter
        pass  # If you know better solution for altering admin.media from filter instance

    def formfield_for_manytomany(self, db_field, request, **kwargs):
        formfield = super().formfield_for_manytomany(db_field, request,
                                                     **kwargs)

        if db_field.name == "categories":
            attrs = {
                'data-from-box-label': _('Available categories'),
                'data-to-box-label': _('Selected categories'),
            }
            formfield.widget = admin.widgets.RelatedFieldWidgetWrapper(
                FilteredSelectMultipleCustom(formfield.label.lower(),
                                             False,
                                             attrs=attrs),
                db_field.remote_field,
                self.admin_site,
                can_add_related=False,
            )

        return formfield
Esempio n. 9
0
class DatasetAdmin(HistoryMixin, ExportCsvMixin, LangFieldsOnlyMixin,
                   admin.ModelAdmin):
    actions_on_top = True
    autocomplete_fields = ['tags', 'organization']
    # prepopulated_fields = {"slug": ("title",)}
    list_display = [
        'title', 'organization', 'created', 'created_by', 'status',
        'obj_history'
    ]
    readonly_fields = [
        'slug',
        'created_by',
        'created',
        'modified',
        'verified',
    ]
    fieldsets = [(None, {
        'classes': (
            'suit-tab',
            'suit-tab-general',
        ),
        'fields': ("title", "slug")
    }),
                 (None, {
                     'classes': (
                         'suit-tab',
                         'suit-tab-tags',
                     ),
                     'fields': ("tags", )
                 }),
                 (None, {
                     'classes': (
                         'suit-tab',
                         'suit-tab-general',
                     ),
                     'fields': (
                         "notes",
                         "url",
                         "customfields",
                         "update_frequency",
                         'organization',
                         'category',
                         'status',
                         'created_by',
                         'created',
                         'modified',
                         'verified',
                     )
                 }),
                 (None, {
                     'classes': (
                         'suit-tab',
                         'suit-tab-licenses',
                     ),
                     'fields': (
                         "license_condition_source",
                         "license_condition_modification",
                         "license_condition_responsibilities",
                         "license_condition_db_or_copyrighted",
                     )
                 })]

    inlines = [
        ChangeResourceStacked,
        AddResourceStacked,
    ]
    search_fields = [
        "title",
    ]

    list_filter = ['category', OrganizationFilter, 'status']
    form = DatasetForm

    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_traslations_tabs(),
        ('licenses', _('Conditions')),
        ('tags', _('Tags')),
        ('resources', _('Resources')),
    )

    suit_form_includes = (('admin/datasets/licences/custom_include.html',
                           'top', 'licenses'), )

    def get_fieldsets(self, request, obj=None):
        return self.fieldsets + self.get_translations_fieldsets()

    def save_model(self, request, obj, form, change):
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        super(DatasetAdmin, self).save_model(request, obj, form, change)
        # obj.save()

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            if not instance.id:
                instance.created_by = request.user
            instance.modified_by = request.user
        super(DatasetAdmin, self).save_formset(request, form, formset, change)

    def get_form(self, request, obj=None, **kwargs):
        self._request = request
        return super(DatasetAdmin, self).get_form(request, obj, **kwargs)

    def get_queryset(self, request):
        qs = Dataset.objects.all()

        if request.user.is_superuser:
            return qs
        return qs.filter(organization_id__in=request.user.organizations.all())

    class Media:  # Empty media class is required if you are using autocomplete filter
        pass  # If you know better solution for altering admin.media from filter instance
Esempio n. 10
0
class AlertAdmin(DynamicAdminListDisplayMixin, CreatedByDisplayAdminMixin,
                 StatusLabelAdminMixin, LangFieldsOnlyMixin, MCODAdminMixin, admin.ModelAdmin):
    list_display = ('title_i18n', 'display_status_str', 'created_by',
                    'start_date', 'finish_date', 'status')
    search_fields = ("title_i18n",)
    list_filter = (
        ('start_date', admin.DateFieldListFilter),
        ('finish_date', admin.DateFieldListFilter),
        DisplayStatusFilter
    )
    form = AlertForm
    actions_on_top = True

    fieldsets = [
        (None, {
            'classes': ('suit-tab', 'suit-tab-general',),
            'fields': [
                'title_pl',
            ]
        }),
        (None, {
            'classes': ('suit-tab', 'suit-tab-general',),
            'fields': [
                'start_date',
                'finish_date',
            ]
        }),
        (None, {
            'classes': ('suit-tab', 'suit-tab-general',),
            'fields': [
                'description_pl',
            ]
        }),
        (None, {
            'classes': ('suit-tab', 'suit-tab-general',),
            'fields': [
                'status'
            ]
        }),
    ]

    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_translations_tabs()
    )

    def get_fieldsets(self, request, obj=None):
        return self.fieldsets + self.get_translations_fieldsets()

    def display_status_str(self, obj):
        css_class, label = DISPLAY_STATUS[obj.display_status]
        return format_html(
            '<span class="label label-{}">{}</i>'.format(css_class, label.lower())
        )

    display_status_str.short_description = _('Display')
    display_status_str.admin_order_field = 'display_status'

    def save_model(self, request, obj, form, change):
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        obj.save()

    def get_queryset(self, request):
        now = timezone.now()
        qs = super().get_queryset(request)

        qs = qs.annotate(display_status=Case(
            When(status='draft', then=Value('n/a')),
            When(finish_date__lt=now, then=Value('finished')),
            When(start_date__gt=now, then=Value('waiting')),
            default=Value('ongoing'),
            output_field=CharField()
        ))
        return qs
Esempio n. 11
0
class ArticleAdmin(HistoryMixin, LangFieldsOnlyMixin, admin.ModelAdmin):
    actions_on_top = True
    autocomplete_fields = ['tags', 'license']
    prepopulated_fields = {"slug": ("title", )}
    fieldsets = (
        (None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': (
                "preview_link",
                "title",
            )
        }),
        ('url', {
            'classes': (
                'collapse',
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': ("slug", )
        }),
        (None, {
            'classes': (
                'suit-tab',
                'suit-tab-general',
            ),
            'fields': ("notes", 'author', 'license', 'status', 'category')
        }),
        (_("Tags"), {
            'classes': (
                'suit-tab',
                'suit-tab-tags',
            ),
            'fields': ("tags", )
        }),
    )
    readonly_fields = ['preview_link']
    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_traslations_tabs(),
        ('tags', _('Tags')),
    )

    list_display = [
        "title", "status", "created_by", 'category', 'preview_link',
        'obj_history'
    ]
    list_filter = [
        'category',
    ]
    search_fields = ["title", "created_by__email"]
    form = ArticleForm

    def get_fieldsets(self, request, obj=None):
        return self.fieldsets + tuple(self.get_translations_fieldsets())

    def get_queryset(self, request):
        qs = Article.objects.all()
        self.request = request
        return qs

    def preview_link(self, obj):
        url = f"{settings.BASE_URL}/knowledge-base/preview/{obj.id}"
        return mark_safe('<a href="%s" class="btn" target="_blank">%s</a>' %
                         (url, _("Preview")))

    preview_link.allow_tags = True
    preview_link.short_description = _("Preview link")

    def save_model(self, request, obj, form, change):
        if 'slug' in form.cleaned_data:
            if form.cleaned_data['slug'] == "":
                obj.slug = slugify(form.cleaned_data['title'])
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        obj.save()

    class Media:
        js = ("articles/js/hide_license_buttons.js", )
Esempio n. 12
0
 def __init__(self, model, admin_site):
     super().__init__(model, admin_site)
     self.suit_form_tabs = (('general', _('General')),
                            *LangFieldsOnlyMixin.get_translations_tabs())
Esempio n. 13
0
class ApplicationAdmin(HistoryMixin, LangFieldsOnlyMixin, admin.ModelAdmin):
    actions_on_top = True
    prepopulated_fields = {"slug": ("title", )}
    autocomplete_fields = ['tags']
    readonly_fields = ['application_logo']
    fieldsets = [(None, {
        'classes': (
            'suit-tab',
            'suit-tab-general',
        ),
        'fields': ("title", )
    }),
                 ('url', {
                     'classes': (
                         'collapse',
                         'suit-tab',
                         'suit-tab-general',
                     ),
                     'fields': ("slug", )
                 }),
                 (None, {
                     'classes': (
                         'suit-tab',
                         'suit-tab-general',
                     ),
                     'fields': (
                         "notes",
                         'author',
                         "url",
                         "image",
                         'application_logo',
                         "status",
                     )
                 }),
                 (_("Datasets"), {
                     'classes': (
                         'suit-tab',
                         'suit-tab-datasets',
                     ),
                     'fields': ("datasets", )
                 }),
                 ('Tags', {
                     'classes': (
                         'suit-tab',
                         'suit-tab-tags',
                     ),
                     'fields': ("tags", )
                 })]

    list_display = [
        "title", "created_by", 'application_logo', 'modified', "status",
        'obj_history'
    ]
    search_fields = ["title", "created_by__email", "url"]
    list_filter = ["status"]
    list_editable = ["status"]

    suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_traslations_tabs(),
        ('tags', _('Tags')),
        ('datasets', _('Datasets')),
    )

    form = ApplicationForm

    def get_fieldsets(self, request, obj=None):
        return self.fieldsets + self.get_translations_fieldsets()

    def application_logo(self, obj):
        try:
            product_url = reverse("admin:%s_%s_change" %
                                  (obj._meta.app_label, obj._meta.model_name),
                                  args=(obj.id, ))
        except NoReverseMatch:
            product_url = ''

        html = ''
        if obj.image_thumb or obj.image:
            html = mark_safe(
                '<a href="%s" target="_blank"><img src="%s" width="%d" alt="" /></a>'
                % (
                    product_url,
                    obj.image_thumb.url if obj.image_thumb else obj.image.url,
                    settings.THUMB_SIZE[0],
                ))

        return html

    application_logo.short_description = _("Logo")

    def save_model(self, request, obj, form, change):
        if 'slug' in form.cleaned_data:
            if form.cleaned_data['slug'] == "":
                obj.slug = slugify(form.cleaned_data['title'])
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        super().save_model(request, obj, form, change)
        # obj.save()

    def get_queryset(self, request):
        qs = Application.objects.all()
        return qs
Esempio n. 14
0
class ResourceAdmin(HistoryMixin, ExportCsvMixin, LangFieldsOnlyMixin, admin.ModelAdmin):
    actions_on_top = True
    change_suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_traslations_tabs(),
        ('file', _('File validation')),
        ('link', _('Link validation')),
        ('data', _('Data validation'))
    )

    add_suit_form_tabs = (
        ('general', _('General')),
        *LangFieldsOnlyMixin.get_traslations_tabs()
    )

    change_fieldsets = [
        (
            None,
            {
                'classes': ('suit-tab', 'suit-tab-general'),
                'fields': (
                    'link',
                    'file',
                    'packed_file',
                    'title',
                    'description',
                    'format',
                    'dataset',
                    'data_date',
                    'status',
                    'show_tabular_view',
                    'modified',
                    'created',
                    'verified',
                    'type',
                    'file_info',
                    'file_encoding',

                )
            }
        ),
    ]

    add_fieldsets = [
        (None, {
            'classes': ('suit-tab', 'suit-tab-general'),
            'fields': ('switcher', 'file', 'link'),
        }),
        (None, {
            'classes': ('suit-tab', 'suit-tab-general'),
            'fields': ('title', 'description'),
        }),
        (None, {
            'classes': ('suit-tab', 'suit-tab-general'),
            'fields': ('dataset',),
        }),
        (None, {
            'classes': ('suit-tab', 'suit-tab-general'),
            'fields': ('data_date',),
        }),
        (None, {
            'classes': ('suit-tab', 'suit-tab-general'),
            'fields': ('status',),
        }),
    ]

    change_readonly_fields = (
        'format',
        'file',
        'packed_file',
        'link',
        'modified',
        'created',
        'verified',
        'type',
        'file_info',
        'file_encoding',
        'link_tasks',
        'file_tasks',
        'data_tasks',
    )

    add_readonly_fields = ()

    list_display = [
        'title',
        'uuid',
        'format',
        'dataset',
        'status',
        'type',
        'link_status',
        'file_status',
        'tabular_view',
        'created'
        # 'obj_history'
    ]

    list_filter = [
        DatasetFilter,
        "format",
        "type",
        "status",
        LinkStatusFilter,
        FileStatusFilter,
        TabularViewFilter
    ]
    search_fields = ['title', 'uuid']
    autocomplete_fields = ['dataset']
    add_form = AddResourceForm
    form = ChangeResourceForm

    inlines = [
        FileTaskResultInline,
        DataTaskResultInline,
        LinkTaskResultInline
    ]

    def get_fieldsets(self, request, obj=None):
        return (self.change_fieldsets if obj else self.add_fieldsets) + self.get_translations_fieldsets()

    def get_form(self, request, obj=None, **kwargs):
        """
        Use special form during user creation
        """
        defaults = {}
        if obj is None:
            defaults['form'] = self.add_form
        defaults.update(kwargs)
        return super().get_form(request, obj=obj, **defaults)

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = self.change_readonly_fields if obj and obj.id else self.add_readonly_fields
        if obj and obj.data_is_valid != 'SUCCESS':
            readonly_fields = (*readonly_fields, 'show_tabular_view')
        if obj and obj.type != "file":
            readonly_fields = (*readonly_fields, 'data_date')
        return readonly_fields

    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
        context.update(
            {
                'suit_form_tabs': self.change_suit_form_tabs if obj else self.add_suit_form_tabs
            }
        )
        return super().render_change_form(request, context, add=add, change=change, form_url=form_url, obj=obj)

    def get_queryset(self, request):
        qs = super().get_queryset(request)

        if request.user.is_staff and not request.user.is_superuser:
            qs = qs.filter(dataset__organization__in=request.user.organizations.iterator())

        link_tasks = TaskResult.objects.filter(link_task_resources=OuterRef('pk')).order_by('-date_done')
        qs = qs.annotate(
            _link_status=Subquery(
                link_tasks.values('status')[:1])
        )
        file_tasks = TaskResult.objects.filter(file_task_resources=OuterRef('pk')).order_by('-date_done')
        qs = qs.annotate(
            _file_status=Subquery(
                file_tasks.values('status')[:1])
        )

        data_tasks = TaskResult.objects.filter(data_task_resources=OuterRef('pk')).order_by('-date_done')
        qs = qs.annotate(
            _data_status=Subquery(
                data_tasks.values('status')[:1])
        )

        return qs

    def get_field_queryset(self, db, db_field, request):
        if 'object_id' in request.resolver_match.kwargs:
            resource_id = int(request.resolver_match.kwargs['object_id'])
            if db_field.name == 'link_tasks':
                return db_field.remote_field.model._default_manager.filter(
                    link_task_resources__id=resource_id,
                )
            if db_field.name == 'file_tasks':
                return db_field.remote_field.model._default_manager.filter(
                    file_task_resources__id=resource_id,
                )
            if db_field.name == 'data_tasks':
                return db_field.remote_field.model._default_manager.filter(
                    data_task_resources__id=resource_id,
                )

        super().get_field_queryset(db, db_field, request)

    def _format_list_status(self, val):
        return format_html('<i class="%s"></i>' % task_status_to_css_class[val])

    def link_status(self, obj):
        return self._format_list_status(obj._link_status)

    link_status.admin_order_field = '_link_status'
    link_status.short_description = format_html('<i class="fas fa-link"></i>')

    def file_status(self, obj):
        return self._format_list_status(obj._file_status)

    file_status.admin_order_field = '_file_status'
    file_status.short_description = format_html('<i class="fas fa-file"></i>')

    def tabular_view(self, obj):
        return self._format_list_status(obj._data_status)

    tabular_view.admin_order_field = '_data_status'
    tabular_view.short_description = format_html('<i class="fas fa-table"></i>')

    def actualized_date(self, obj):
        if obj._actualized:
            return formats.date_format(obj._actualized, format="DATETIME_FORMAT", use_l10n=True)

    actualized_date.short_description = _('Actualization date')
    actualized_date.admin_order_field = '_actualized'

    def save_model(self, request, obj, form, change):
        if not obj.id:
            obj.created_by = request.user
        obj.modified_by = request.user
        obj.save()

    def get_changeform_initial_data(self, request):
        """
        Get the initial form data from the request's GET params.
        """

        obj_id = request.GET.get('from_id')
        initial = {}
        if obj_id:
            data = model_to_dict(Resource.objects.get(pk=obj_id))
            initial['title'] = data.get('title')
            initial['description'] = data.get('description')
            initial['status'] = data.get('status')
            initial['dataset'] = data.get('dataset')

        for k in initial:
            try:
                f = self.model._meta.get_field(k)
            except FieldDoesNotExist:
                continue
            # We have to special-case M2Ms as a list of comma-separated PKs.
            if isinstance(f, ManyToManyField):
                initial[k] = initial[k].split(",")
        return initial

    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('<path:resource_id>/revalidate/', self.revalidate, name='resource-revalidate')
        ]
        return custom_urls + urls

    def revalidate(self, request, resource_id, *args, **kwargs):
        if not self.has_change_permission(request):
            raise PermissionDenied

        try:
            resource = self.model.objects.get(pk=resource_id)
        except self.model.DoesNotExist:
            return Http404(_('Resource with this id does not exists'))

        resource.revalidate()
        messages.add_message(request, messages.SUCCESS, _('Task for resource revalidation queued'))

        url = reverse(
            'admin:resources_resource_change',
            args=[resource_id],
            current_app=self.admin_site.name,
        )
        return HttpResponseRedirect(url)

    class Media:
        css = {
            'all': ('./fontawesome/css/all.min.css',)
        }