class PollListCreateView(ListCreateAPIView): model = Poll serializer_class = PollSerializer queryset = Poll.objects() permission_classes = [ Or(build_permission_class('dms.can_manage_polls'), And(build_permission_class('dms.can_view_polls'), IsGetRequest)) ] def get_queryset(self): query_params = { key: value or None for key, value in self.request.GET.items() } user_group = self.request.user.group.name if user_group in getattr(settings, 'DISTRICT_GROUPS', []): target_locations = get_user_district_locations(self.request.user) query_params.update({'target_locations__in': target_locations}) if 'ordering' in query_params: ordering_params = query_params['ordering'] del query_params['ordering'] query_set = Poll.objects(**query_params).order_by('%s' % ordering_params) else: query_set = Poll.objects(**query_params).order_by('-created_at') return query_set def post_save(self, obj, created=True): locations = self.get_location(obj) phone_numbers = list( UserProfile.objects(location__in=locations).values_list('phone')) if obj.ptype == 'yesno': text = '%s Reply With: NECOCPoll YES/NO' % obj.question else: text = '%s Reply With: NECOCPoll %s ...' % (obj.question, obj.keyword) send_bulk_sms.delay(obj, phone_numbers, text) def get_location(self, obj): locations = Location.objects(id__in=obj.target_locations) if locations.filter(type='subcounty'): return locations districts_children = [district.children() for district in locations] return flatten(districts_children) def get_location_id(self, user): profile = UserProfile.objects(user=user).first() return profile.location.id if profile else ''
class DisasterListCreateView(ListCreateAPIView): model = Disaster serializer_class = DisasterSerializer queryset = Disaster.objects() permission_classes = [ Or(build_permission_class('dms.can_manage_disasters'), IsGetRequest) ] def get_queryset(self): query_params = Disaster.map_kwargs_to_db_params( self.request.GET.dict()) location_queried = self.request.GET.get('location', None) if not location_queried: if self.request.user.has_perm('dms.can_view_disasters'): user_profile = UserProfile.objects( user=self.request.user).first() user_group = self.request.user.group.name if user_profile and user_group in getattr( settings, 'DISTRICT_GROUPS', []): user_locations = get_user_district_locations( self.request.user) query_params.update({'locations__in': user_locations}) else: if not self.request.user.has_perm( 'dms.can_manage_disasters'): user_location = user_profile.location.id query_params.update({'locations__in': [user_location]}) return Disaster.objects(**query_params)
class DisasterTypeListCreateView(ListCreateAPIView): model = DisasterType serializer_class = DisasterTypeSerializer queryset = DisasterType.objects() permission_classes = [ Or(build_permission_class('dms.can_manage_disasters'), IsGetRequest) ]
class UserProfileView(MongoRetrieveUpdateView): serializer_class = UserProfileSerializer queryset = UserProfile.objects.all() permission_classes = [Or(build_permission_class('dms.can_manage_users'), IsCurrentUsersProfile), ] def list(self, request, *args, **kwargs): user_profile = UserProfile.objects(id=kwargs['id']).first() serializer = UserProfileSerializer(user_profile) return Response(serializer.data) def post(self, request, *args, **kwargs): return self.patch(request, *args, **kwargs) def replace_image(self, obj): try: if self.request.FILES.get('file'): image = image_resizer.ImageResizer(self.request.FILES.get('file')).generate().read() content_type = self.request.FILES.get('file').content_type obj.photo.replace(image, content_type=content_type) obj.save() except: obj.photo.delete() obj.save() def post_save(self, obj, created=False): group_id = self.request.DATA.get('group', None) if(group_id): obj.user.group = Group.objects(id=group_id).first() obj.user.save() self.replace_image(obj)
class CSVUserProfileView(ListCreateAPIView): serializer_class = CSVUserProfileSerializer permission_classes = (build_permission_class('dms.can_manage_users'),) model = UserProfile renderer_classes = [CSVRenderer, ] + api_settings.DEFAULT_RENDERER_CLASSES parser_classes = (CSVParser,) def get_queryset(self): params = self._filter_params(self.request) queryset = UserProfile.objects.filter(**params) return queryset.order_by('-created_at') def _filter_params(self, req): location = req.GET.get('location') params = {} locations = [] if location and not self._undefined(location): locs = location.split(',') for loc in locs: locations += Location.objects(**dict(id=loc)).first().children(include_self=True) params = {'location__in': locations} return params def _undefined(self, strValue): return strValue == u'undefined'
class GroupsEndpointListView(ListAPIView): permission_classes = [ Or(build_permission_class('dms.can_manage_users'), IsGetRequest) ] def list(self, request, *args, **kwargs): queryset = Group.objects() data = [GroupSerializer(query).data for query in queryset] return Response(data)
class SentMessageListCreateView(ListCreateAPIView): model = SentMessage serializer_class = SentMessageSerializer queryset = SentMessage.objects() permission_classes = [ Or(build_permission_class('dms.can_manage_messages'), IsGetRequest) ] def post_save(self, obj, created=True): send_bulk_sms.delay(obj)
class DisasterView(MongoRetrieveUpdateView): model = Disaster serializer_class = DisasterSerializer queryset = Disaster.objects() permission_classes = [ Or(build_permission_class('dms.can_manage_disasters')) ] def post(self, request, *args, **kwargs): return self.patch(request, *args, **kwargs)
class AdminSettingUpdateView(MongoRetrieveUpdateView): serializer_class = AdminSettingSerializer queryset = AdminSetting.objects.all() permission_classes = [Or(build_permission_class('dms.can_manage_settings'), IsGetRequest)] lookup_field = 'name' def list(self, request, *args, **kwargs): setting = AdminSetting.objects(name=kwargs['name']).first() serializer = AdminSettingSerializer(setting) return Response(serializer.data) def post(self, request, *args, **kwargs): return self.patch(request, *args, **kwargs)
class ResponseMessageListCreateView(ListCreateAPIView): model = ResponseMessage serializer_class = ResponseMessageSerializer queryset = ResponseMessage.objects() permission_classes = [Or(build_permission_class('dms.can_manage_messages'), IsGetRequest)] def pre_save(self, obj): in_response_to = self.request.DATA.get('text', '') obj.text = settings.AUTO_RESPONSE_MESSAGE obj.response_to = in_response_to def post_save(self, obj, created=True): auto_response_enabled = AdminSetting.objects(**dict(name='enable_automatic_response', yes_no=True)).first() if auto_response_enabled: send_one_sms.delay(obj)
class ProfileImageView(MongoAPIView): permission_classes = [ Or(build_permission_class('dms.can_manage_users'), IsCurrentUsersProfile), ] DEFAULT_IMAGE_PATH = settings.STATICFILES_DIRS[ 0] + "/img/default_profile.jpg" def get(self, request, *args, **kwargs): try: profile = UserProfile.objects.get(id=kwargs['id']) if profile and hasattr(profile, 'photo'): photo = profile.photo.read() return HttpResponse(photo, content_type=profile.photo.content_type) except: return HttpResponse(open(self.DEFAULT_IMAGE_PATH), content_type='image/jpeg')
class PasswordResetView(UpdateAPIView): serializer_class = UserPasswordResetSerializer queryset = UserProfile.objects() model = UserProfile permission_classes = (build_permission_class('dms.can_manage_users'), ) def get_object(self, queryset=None): profile = super(PasswordResetView, self).get_object() if not profile.user: from django.http import Http404 raise Http404('%s is not a web user.' % profile.name) return profile.user def pre_save(self, obj): profile = super(PasswordResetView, self).get_object() UserProfileService(profile).reset_password() def post(self, request, *args, **kwargs): return self.patch(request, *args, **kwargs)
class UserProfileListCreateView(ListCreateAPIView): serializer_class = UserProfileSerializer queryset = UserProfile.objects() model = UserProfile permission_classes = (build_permission_class('dms.can_manage_users'),) def get_queryset(self): query_params = {key: value or None for key, value in self.request.GET.items()} user_group = self.request.user.group.name if user_group in getattr(settings, 'DISTRICT_GROUPS', []): target_locations = get_user_district_locations(self.request.user) query_params.update({'location__in': target_locations}) if 'ordering' in query_params: ordering_params = query_params['ordering'] del query_params['ordering'] query_set = UserProfile.objects(**query_params).order_by('%s' % ordering_params) else: query_set = UserProfile.objects(**query_params).order_by('-created_at') return query_set def pre_save(self, obj): username = self.request.DATA.get('username', None) group_id = self.request.DATA.get('group', None) if username: user = UserProfileService(obj).setup_new_user(username, group_id) obj.user = user def save_new_image(self, obj): try: if self.request.FILES.get('file'): image = image_resizer.ImageResizer(self.request.FILES.get('file')).generate().read() content_type = self.request.FILES.get('file').content_type obj.photo.put(image, content_type=content_type) obj.save() except: obj.photo.delete() obj.save() def post_save(self, obj, created=False): self.save_new_image(obj)
class CSVDisasterView(ListCreateAPIView): model = Disaster serializer_class = CSVDisasterSerializer queryset = Disaster.objects() permission_classes = [ Or(build_permission_class('dms.can_manage_disasters'), IsGetRequest) ] renderer_classes = [ CSVRenderer, ] + api_settings.DEFAULT_RENDERER_CLASSES def get_queryset(self): params = self._filter_params(self.request) queryset = Disaster.objects.filter(**params) return queryset.order_by('-created_at') def _filter_params(self, req): start_date = req.GET.get('from') end_date = req.GET.get('to') status = req.GET.get('status') params = {} if start_date: if not self._undefined(start_date): params.update({'date__gte': start_date}) if end_date: if not self._undefined(end_date): params.update({'date__lte': end_date}) if status: if not self._undefined(status): params.update({'status': status}) return params def _undefined(self, strValue): return strValue == u'undefined'
class AdminSettingListCreateView(ListCreateAPIView): model = AdminSetting serializer_class = AdminSettingSerializer queryset = AdminSetting.objects() permission_classes = [Or(build_permission_class('dms.can_manage_settings'), IsGetRequest)] lookup_field = 'name'
class BulkUserProfileView(ListBulkCreateUpdateDestroyAPIView): serializer_class = BulkUserProfileSerializer permission_classes = (build_permission_class('dms.can_manage_users'),) model = UserProfile def get_queryset(self): return UserProfile.objects() def post(self, request, *args, **kwargs): request = self._prep_request(request) return self.create(request, *args, **kwargs) if len(request.DATA) else Response('Invalid CSV') def create(self, request, *args, **kwargs): bulk = isinstance(request.DATA, list) midx = len(request.DATA)-1 if not bulk: return super(BulkCreateModelMixin, self).create(request, *args, **kwargs) else: serializer = self.get_serializer(data=request.DATA, many=True) if serializer.is_valid(): objects = [] data_list = request.DATA for obj in serializer.object: self.pre_save(obj) for i, d in enumerate(data_list): request.DATA = data_list[i:i+1] if i<midx else [data_list[midx]] try: resp = super(BulkUserProfileView, self).create(request, *args, **kwargs) if resp.status_code == status.HTTP_201_CREATED: objects.append(resp) except NotUniqueError: profile = get_profile(request.DATA[0]['phone']) request.DATA[0]['id'] = '%s' % profile.id resp = self.patch(request, *args, **kwargs) if resp.status_code == status.HTTP_200_OK: objects.append(resp) self.object = objects for obj in self.object: self.post_save(obj, created=True) if obj.status_code==status.HTTP_201_CREATED else \ self.post_save(obj, created=False) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) def _prep_request(self, request): request._request.DATA = request.DATA request = request._request #drf 2.2.* requests are imutable, use the mutable django request request = self._insert_location(request) request = self._remove_bad_locations(request) return request def _insert_location(self, request): data = request.DATA params = {} for i, dt in enumerate(data): sub_name = dt.get('subcounty', None) dist_name = dt.get('district', None) try: if sub_name and dist_name: parent = Location.objects(name=dist_name, type='district').first() params = dict(name=sub_name, type='subcounty', parent=parent) self.discard_loc_aliases(request.DATA[i]) elif dist_name: params = dict(name=dist_name, type='district') self.discard_loc_aliases(request.DATA[i]) elif sub_name: params = dict(name=sub_name, type='subcounty') self.discard_loc_aliases(request.DATA[i]) else: # print 'no district and subcounty specified for record: %s' % request.DATA[i] continue request.DATA[i]['location'] = Location.objects.get(**params) except Exception as e: # print '%s: something wrong with district name [%s] or subcounty name [%s] \ # specified for record' % (e.__class__.__name__, dist_name, sub_name) continue return request def _remove_bad_locations(self, request): for i, d in enumerate(request.DATA): if not 'location' in d.keys(): request.DATA[i] = {} request.DATA = filter(None, request.DATA) #remove empty dicts return request def discard_loc_aliases(self, loc): del loc['district'] del loc['subcounty']