admin.py 7.2 KB
Newer Older
1
from django import forms
2
from django.core.exceptions import PermissionDenied
3
from django.contrib import admin
4
from django.contrib.admin import helpers
5
from django.shortcuts import render
6
from django.utils.encoding import force_text
7

8 9 10 11
from stats.models import (
    Statistics, Information, PoFile, Module, Branch, Domain, Category,
    CategoryName, Release,
)
12

13

14 15 16 17 18
class DomainForm(forms.ModelForm):
    class Meta:
        model = Module
        fields = '__all__'

19 20
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
21
        if self.instance.pk:
22 23 24 25 26 27
            self.fields['branch_from'].queryset = self.fields['branch_from'].queryset.filter(
                module=self.instance.module
            )
            self.fields['branch_to'].queryset = self.fields['branch_to'].queryset.filter(
                module=self.instance.module
            )
28 29 30
        else:
            self.fields['branch_from'].queryset = Branch.objects.none()
            self.fields['branch_to'].queryset = Branch.objects.none()
31

32 33 34 35 36 37
    def clean(self):
        cleaned_data = super().clean()
        if cleaned_data['pot_params'] and cleaned_data['pot_method'] not in ('shell', 'url'):
            raise forms.ValidationError("pot_params can only be set for shell or url pot methods.")


38 39 40
class BranchInline(admin.TabularInline):
    model = Branch

41 42

class DomainInline(admin.StackedInline):
43
    model = Domain
44
    form = DomainForm
45 46
    fieldsets = (
        (None, {
47
            'fields': (('name', 'description', 'dtype', 'layout'),)
48 49
        }),
        ('Advanced', {
50 51
            'fields': (('pot_method', 'pot_params'),
                       'extra_its_dirs', 'linguas_location', 'red_filter',
52 53 54 55 56 57 58 59
                       ('branch_from', 'branch_to'),),
            'classes': ('collapse',),
        }),
    )

    def get_formset(self, request, obj=None, **kwargs):
        # Hack! Store parent obj for formfield_for_foreignkey
        self.parent_obj = obj
Claude Paroz's avatar
Claude Paroz committed
60
        return super().get_formset(request, obj, **kwargs)
61

62 63
    def formfield_for_dbfield(self, db_field, **kwargs):
        if db_field.name == 'description':
64
            kwargs['widget'] = forms.Textarea(attrs={'rows':'1', 'cols':'20'})
65
        elif db_field.name in ('name', 'layout'):
66
            kwargs['widget'] = forms.TextInput(attrs={'size':'20'})
67
        elif db_field.name in ('red_filter', 'extra_its_dirs'):
68
            kwargs['widget'] = forms.Textarea(attrs={'rows':'1', 'cols':'40'})
Claude Paroz's avatar
Claude Paroz committed
69
        return super().formfield_for_dbfield(db_field, **kwargs)
70

71 72 73
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name in ('branch_from', 'branch_to') and hasattr(self, 'parent_obj') and self.parent_obj:
            kwargs['queryset'] = self.parent_obj.branch_set.all()
Claude Paroz's avatar
Claude Paroz committed
74
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
75 76


77 78 79 80 81 82 83 84 85 86 87 88
class ModuleForm(forms.ModelForm):
    class Meta:
        model = Module
        fields = '__all__'

    def save(self, **kwargs):
        must_renew_checkout = 'vcs_root' in self.changed_data and not self.instance._state.adding and not self.errors
        if must_renew_checkout:
            old_module = Module.objects.get(pk=self.instance.pk)
            # Delete checkout(s)
            for branch in old_module.get_branches(reverse=True):  # head branch last
                branch.delete_checkout()
Claude Paroz's avatar
Claude Paroz committed
89
        instance = super().save(**kwargs)
90 91 92 93 94 95 96
        if must_renew_checkout:
            for branch in instance.get_branches():
                # Force checkout and updating stats
                branch.save()
        return instance


97
class ModuleAdmin(admin.ModelAdmin):
98
    form = ModuleForm
99 100 101
    fieldsets = (
        (None, {
            'fields': (('name','description'),
102
                        'homepage', 'comment', 'archived',
103
                       ('bugs_base',),
104
                       ('vcs_type', 'vcs_root', 'vcs_web'),
105
                       'ext_platform', 'maintainers')
106 107 108
        }),
    )
    inlines = [ BranchInline, DomainInline ]
109
    search_fields = ('name', 'homepage', 'comment', 'vcs_web')
110
    list_filter = ('archived',)
111 112

    def formfield_for_dbfield(self, db_field, **kwargs):
Claude Paroz's avatar
Claude Paroz committed
113
        field = super().formfield_for_dbfield(db_field, **kwargs)
114 115 116 117 118 119 120 121 122 123 124
        if db_field.name == 'description':
            field.widget.attrs['rows'] = '1'
        elif db_field.name == 'comment':
            field.widget.attrs['rows'] = '4'

        return field

class BranchAdmin(admin.ModelAdmin):
    search_fields = ('name', 'module__name')

class DomainAdmin(admin.ModelAdmin):
125
    form = DomainForm
126
    list_display = ('__str__', 'layout', 'pot_method')
127
    list_filter = ('dtype', 'pot_method')
128
    search_fields = ('name', 'module__name', 'layout', 'pot_method')
129 130 131 132 133 134 135

class CategoryInline(admin.TabularInline):
    model = Category
    raw_id_fields = ('branch',) # Too costly otherwise
    extra = 1

class CategoryAdmin(admin.ModelAdmin):
136
    search_fields = ('name__name', 'branch__module__name')
137 138

class ReleaseAdmin(admin.ModelAdmin):
139 140
    list_display = ('name', 'status', 'weight', 'string_frozen')
    list_editable = ('weight',)
141
    inlines = [ CategoryInline ]
142 143 144 145 146 147 148 149 150
    actions = ['delete_release']

    def delete_release(self, request, queryset):
        """ Admin action to delete releases *with* branches which are not linked to another release """
        if not self.has_delete_permission(request):
            raise PermissionDenied
        if request.POST.get('post'):
            # Already confirmed
            for obj in queryset:
151
                self.log_deletion(request, obj, force_text(obj))
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
            n = queryset.count()
            b = 0
            for release in queryset:
                branches = Branch.objects.filter(category__release=release)
                for branch in branches:
                    if branch.releases.count() < 2 and not branch.is_head():
                        branch.delete()
                        b += 1
            queryset.delete()
            self.message_user(request, "Successfully deleted %(countr)d release(s) and %(countb)d branch(es)." % {
                "countr": n, "countb": b,
            })
            # Return None to display the change list page again.
            return None
        context = {
            "title": "Are you sure?",
            "queryset": queryset,
            "app_label": self.model._meta.app_label,
            "model_label": self.model._meta.verbose_name_plural,
            "action_checkbox_name": helpers.ACTION_CHECKBOX_NAME,
        }
173
        return render(request, 'admin/delete_release_confirmation.html', context)
174
    delete_release.short_description = "Delete release (and associated branches)"
175

176 177 178 179
class InformationInline(admin.TabularInline):
    model = Information
    extra = 0

180 181
class StatisticsAdmin(admin.ModelAdmin):
    search_fields = ('language__name', 'branch__module__name')
182
    raw_id_fields = ('branch', 'domain', 'language', 'full_po', 'part_po')
183
    inlines = [ InformationInline ]
184

Claude Paroz's avatar
Claude Paroz committed
185 186 187
class PoFileAdmin(admin.ModelAdmin):
    search_fields = ('path',)

188
admin.site.register(Statistics, StatisticsAdmin)
Claude Paroz's avatar
Claude Paroz committed
189
admin.site.register(PoFile, PoFileAdmin)
190 191
admin.site.register(Branch, BranchAdmin)
admin.site.register(Domain, DomainAdmin)
192
admin.site.register(CategoryName)
193 194 195
admin.site.register(Category, CategoryAdmin)
admin.site.register(Module, ModuleAdmin)
admin.site.register(Release, ReleaseAdmin)