Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# (c) 2018-2020 

2# MPIB <https://www.mpib-berlin.mpg.de/>, 

3# MPI-CBS <https://www.cbs.mpg.de/>, 

4# MPIP <http://www.psych.mpg.de/> 

5# 

6# This file is part of Castellum. 

7# 

8# Castellum is free software; you can redistribute it and/or modify it 

9# under the terms of the GNU Affero General Public License as published 

10# by the Free Software Foundation; either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# Castellum is distributed in the hope that it will be useful, but 

14# WITHOUT ANY WARRANTY; without even the implied warranty of 

15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 

16# Affero General Public License for more details. 

17# 

18# You should have received a copy of the GNU Affero General Public 

19# License along with Castellum. If not, see 

20# <http://www.gnu.org/licenses/>. 

21 

22from django.contrib import admin 

23from django.contrib import messages 

24from django.contrib.admin.views.decorators import staff_member_required 

25from django.http import JsonResponse 

26from django.urls import path 

27from django.utils.translation import gettext_lazy as _ 

28from django.views.generic import FormView 

29 

30from parler.admin import TranslatableAdmin 

31from parler.admin import TranslatableTabularInline 

32 

33from castellum.castellum_auth.mixins import PermissionRequiredMixin 

34 

35from .forms import CategoryImportForm 

36from .forms import DescriptionImportForm 

37from .models import Appointment 

38from .models import AttributeCategory 

39from .models import AttributeChoice 

40from .models import AttributeDescription 

41from .models import AttributeSet 

42from .models import ParticipationRequest 

43from .models import ParticipationRequestRevision 

44from .models import SubjectFilter 

45from .models import SubjectFilterGroup 

46 

47 

48class CategoryImportView(PermissionRequiredMixin, FormView): 

49 template_name = 'admin/recruitment/attributedescription_import.html' 

50 permission_required = [ 

51 'recruitment.view_attributecategory', 

52 'recruitment.add_attributecategory', 

53 ] 

54 model = AttributeCategory 

55 form_class = CategoryImportForm 

56 

57 def get_context_data(self, **kwargs): 

58 context = super().get_context_data(**kwargs) 

59 context['opts'] = self.model._meta 

60 context['title'] = _('Import') 

61 return context 

62 

63 def form_valid(self, form): 

64 json = form.cleaned_data['json'] 

65 for data in json['categories']: 

66 AttributeCategory._import(data) 

67 messages.success( 

68 self.request, 

69 _('Successfully imported %i attribute categories.' % len(json['categories'])) 

70 ) 

71 return self.form_invalid(form) 

72 

73 

74class DescriptionImportView(PermissionRequiredMixin, FormView): 

75 template_name = 'admin/recruitment/attributedescription_import.html' 

76 permission_required = [ 

77 'recruitment.view_attributedescription', 

78 'recruitment.add_attributedescription', 

79 ] 

80 schema_ref = '#/definitions/AttributeDescriptionExport' 

81 model = AttributeDescription 

82 form_class = DescriptionImportForm 

83 

84 def get_context_data(self, **kwargs): 

85 context = super().get_context_data(**kwargs) 

86 context['opts'] = self.model._meta 

87 context['title'] = _('Import') 

88 return context 

89 

90 def form_valid(self, form): 

91 json = form.cleaned_data['json'] 

92 for data in json['descriptions']: 

93 AttributeDescription._import(data) 

94 messages.success( 

95 self.request, 

96 _('Successfully imported %i attribute descriptions.' % len(json['descriptions'])) 

97 ) 

98 return self.form_invalid(form) 

99 

100 

101class AttributeCategoryAdmin(TranslatableAdmin): 

102 model = AttributeCategory 

103 actions = ['export_json'] 

104 

105 def export_json(self, request, queryset): 

106 response = JsonResponse({ 

107 'categories': [category.export() for category in queryset.all()], 

108 }) 

109 response['Content-Disposition'] = 'attachment; filename="castellum_categories.json"' 

110 return response 

111 export_json.short_description = _('Export as JSON') 

112 

113 def get_urls(self): 

114 return [ 

115 path( 

116 'import/', 

117 staff_member_required(CategoryImportView.as_view()), 

118 name='recruitment_attributecategory_import', 

119 ), 

120 ] + super().get_urls() 

121 

122 

123class AttributeChoiceInline(TranslatableTabularInline): 

124 model = AttributeChoice 

125 

126 

127class AttributeDescriptionAdmin(TranslatableAdmin): 

128 inlines = [ 

129 AttributeChoiceInline, 

130 ] 

131 actions = ['export_json'] 

132 

133 def export_json(self, request, queryset): 

134 response = JsonResponse({ 

135 'descriptions': [description.export() for description in queryset.all()], 

136 }) 

137 response['Content-Disposition'] = 'attachment; filename="castellum_attributes.json"' 

138 return response 

139 export_json.short_description = _('Export as JSON') 

140 

141 def get_urls(self): 

142 return [ 

143 path( 

144 'import/', 

145 staff_member_required(DescriptionImportView.as_view()), 

146 name='recruitment_attributedescription_import', 

147 ), 

148 ] + super().get_urls() 

149 

150 

151admin.site.register(Appointment) 

152admin.site.register(AttributeCategory, AttributeCategoryAdmin) 

153admin.site.register(AttributeDescription, AttributeDescriptionAdmin) 

154admin.site.register(AttributeSet) 

155admin.site.register(ParticipationRequest) 

156admin.site.register(ParticipationRequestRevision) 

157admin.site.register(SubjectFilter) 

158admin.site.register(SubjectFilterGroup)