def sms_check(request, event_filter=HotlineEvent.TYPE_SMS_UNKNOWN): context = get_default_context(page='sms') if not event_filter in HotlineEvent.SMS_TYPES: event_filter = HotlineEvent.TYPE_SMS_UNKNOWN try: nb_numbers = int(request.POST.get('nb_numbers', NB_NUMBERS)) except ValueError: nb_numbers = NB_NUMBERS events = HotlineEvent.objects.filter(processed=False, event_type=event_filter) \ .order_by('-received_on')[:nb_numbers] context.update({ 'events': events, 'filter': event_filter, 'filters': [(HotlineEvent.TYPE_SMS_UNKNOWN, "À Trier"), (HotlineEvent.TYPE_SMS_HOTLINE, "Hotline"), (HotlineEvent.TYPE_SMS_USHAHIDI, "Ushahidi"), (HotlineEvent.TYPE_CHARGE_ME, "Peux-tu recharger mon compte?"), (HotlineEvent.TYPE_SMS_SPAM, "SPAM")], 'requested': True, 'nb_numbers': nb_numbers }) return render(request, "sms_check.html", context)
def import_event(request): context = get_default_context(page='import_event') def handle_uploaded_file(f): """ stores temporary file as a real file for form upload """ fname = '/tmp/form_%s.xls' % datetime.datetime.now().strftime('%s') destination = open(fname, 'wb+') for chunk in f.chunks(): destination.write(chunk) destination.close() return fname context.update(get_status_context()) if request.method == "POST": if 'csv_file' in request.FILES: filepath = handle_uploaded_file(request.FILES['csv_file']) try: result = import_hotine_events(filepath) context.update(result) except UnboundLocalError: context.update({ 'error_message': 'Aucun fichier sélectionné', 'nbok': 0 }) context.update({"result": True}) return render(request, "import_event.html", context)
def import_event(request): context = get_default_context(page="import_event") def handle_uploaded_file(f): """ stores temporary file as a real file for form upload """ fname = "/tmp/form_%s.xls" % datetime.datetime.now().strftime("%s") destination = open(fname, "wb+") for chunk in f.chunks(): destination.write(chunk) destination.close() return fname context.update(get_status_context()) if request.method == "POST": if "csv_file" in request.FILES: filepath = handle_uploaded_file(request.FILES["csv_file"]) try: result = import_hotine_events(filepath) context.update(result) except UnboundLocalError: context.update({"error_message": "Aucun fichier sélectionné", "nbok": 0}) context.update({"result": True}) return render(request, "import_event.html", context)
def sms_check(request, event_filter=HotlineEvent.TYPE_SMS_UNKNOWN): context = get_default_context(page="sms") if not event_filter in HotlineEvent.SMS_TYPES: event_filter = HotlineEvent.TYPE_SMS_UNKNOWN try: nb_numbers = int(request.POST.get("nb_numbers", NB_NUMBERS)) except ValueError: nb_numbers = NB_NUMBERS events = HotlineEvent.objects.filter(processed=False, event_type=event_filter).order_by("-received_on")[:nb_numbers] context.update( { "events": events, "filter": event_filter, "filters": [ (HotlineEvent.TYPE_SMS_UNKNOWN, "À Trier"), (HotlineEvent.TYPE_SMS_HOTLINE, "Hotline"), (HotlineEvent.TYPE_SMS_USHAHIDI, "Ushahidi"), (HotlineEvent.TYPE_CHARGE_ME, "Peux-tu recharger mon compte?"), (HotlineEvent.TYPE_SMS_SPAM, "SPAM"), ], "requested": True, "nb_numbers": nb_numbers, } ) return render(request, "sms_check.html", context)
def dashboard(request): context = get_default_context(page="dashboard") context.update( { "operators": [ ( operator, HotlineEvent.objects.filter( operator=operator, processed=False, event_type__in=HotlineEvent.HOTLINE_TYPES ).count(), ) for operator in operators() ] } ) if request.method == "POST": try: nb_numbers = int(request.POST.get("nb_numbers", NB_NUMBERS)) except ValueError: nb_numbers = NB_NUMBERS operator = request.POST.get("operator_request") if not operator in operators(): context.update({"error": "L'opérateur demandé (%s) " "n'est pas correct" % operator}) events = HotlineEvent.objects.filter( operator=operator, processed=False, event_type__in=HotlineEvent.HOTLINE_TYPES ).order_by("received_on")[:nb_numbers] for event in events: event.processed = True event.volunteer = request.user event.save() context.update( { "events": events, "requested": True, "operator": operator, # 'user_number': user_number, "nb_numbers": nb_numbers, } ) return render(request, "dashboard.html", context)
def dashboard(request): context = get_default_context(page='dashboard') context.update({ 'operators': [(operator, HotlineEvent.objects.filter( operator=operator, processed=False, event_type__in=HotlineEvent.HOTLINE_TYPES).count()) for operator in operators()] }) if request.method == 'POST': try: nb_numbers = int(request.POST.get('nb_numbers', NB_NUMBERS)) except ValueError: nb_numbers = NB_NUMBERS operator = request.POST.get('operator_request') if not operator in operators(): context.update({ 'error': "L'opérateur demandé (%s) " "n'est pas correct" % operator }) events = HotlineEvent.objects.filter(operator=operator, processed=False, event_type__in=HotlineEvent.HOTLINE_TYPES) \ .order_by('received_on')[:nb_numbers] for event in events: event.processed = True event.volunteer = request.user event.save() context.update({ 'events': events, 'requested': True, 'operator': operator, # 'user_number': user_number, 'nb_numbers': nb_numbers }) return render(request, "dashboard.html", context)
def change_password(request): context = get_default_context(page='password') class ChangePasswordForm(forms.Form): old_password = forms.CharField(label="Mot de passe actuel", max_length=100, widget=forms.PasswordInput) new_password = forms.CharField(label="Nouveau mot de passe", max_length=100, widget=forms.PasswordInput) new_password_verify = forms.CharField( label="Nouveau mot de passe (vérification)", max_length=100, widget=forms.PasswordInput) def clean(self): cleaned_data = super(ChangePasswordForm, self).clean() new_password = cleaned_data.get('new_password') new_password_verify = cleaned_data.get('new_password_verify') if new_password != new_password_verify: raise forms.ValidationError( "Les nouveaux mot de passe ne sont pas identiques") return cleaned_data def clean_old_password(self): old_password = self.cleaned_data.get('old_password') if not request.user.check_password(old_password): raise forms.ValidationError("Mot de passe incorrect.") if request.method == 'POST': form = ChangePasswordForm(request.POST) if form.is_valid(): request.user.set_password(form.cleaned_data['new_password']) request.user.save() messages.success(request, "Le mot de passe a été changé.") return redirect('home') else: form = ChangePasswordForm() context.update({'form': form}) return render(request, "change_password.html", context)
def blacklist(request): context = get_default_context(page="blacklist") if request.method == "POST": identity = request.POST.get("identity").strip() ind, number = clean_phone_number(identity) identity = join_phone_number(ind, number) if not BlackList.objects.filter(identity=identity).count(): BlackList.objects.create(identity=identity) else: b = BlackList.objects.get(identity=identity) b.call_count += 1 b.save() messages.success(request, "%s ajouté dans la liste noire" % b.identity) context.update({"blacknums": BlackList.objects.all()}) return render(request, "blacklist.html", context)
def blacklist(request): context = get_default_context(page='blacklist') if request.method == 'POST': identity = request.POST.get('identity').strip() ind, number = clean_phone_number(identity) identity = join_phone_number(ind, number) if not BlackList.objects.filter(identity=identity).count(): BlackList.objects.create(identity=identity) else: b = BlackList.objects.get(identity=identity) b.call_count += 1 b.save() messages.success(request, "%s ajouté dans la liste noire" % b.identity) context.update({'blacknums': BlackList.objects.all()}) return render(request, "blacklist.html", context)
def change_password(request): context = get_default_context(page="password") class ChangePasswordForm(forms.Form): old_password = forms.CharField(label="Mot de passe actuel", max_length=100, widget=forms.PasswordInput) new_password = forms.CharField(label="Nouveau mot de passe", max_length=100, widget=forms.PasswordInput) new_password_verify = forms.CharField( label="Nouveau mot de passe (vérification)", max_length=100, widget=forms.PasswordInput ) def clean(self): cleaned_data = super(ChangePasswordForm, self).clean() new_password = cleaned_data.get("new_password") new_password_verify = cleaned_data.get("new_password_verify") if new_password != new_password_verify: raise forms.ValidationError("Les nouveaux mot de passe ne sont pas identiques") return cleaned_data def clean_old_password(self): old_password = self.cleaned_data.get("old_password") if not request.user.check_password(old_password): raise forms.ValidationError("Mot de passe incorrect.") if request.method == "POST": form = ChangePasswordForm(request.POST) if form.is_valid(): request.user.set_password(form.cleaned_data["new_password"]) request.user.save() messages.success(request, "Le mot de passe a été changé.") return redirect("home") else: form = ChangePasswordForm() context.update({"form": form}) return render(request, "change_password.html", context)
def exported_status(request): context = get_default_context(page='status') context.update(get_status_context()) return render(request, "status_for_export.html", context)
def data_entry(request): ''' Enter Data for calls made by the volunteers Step 1: Pick a volunteer to enter data for. Step 2: List all calls made by the chosen volunteer Step 3: Enter data for a specific call. This creates a HotlineResponse object. ''' class HotlineResponseForm(forms.Form): ''' Used to easily enter data for calls made by volunteers. ''' request_id = forms.IntegerField(widget=forms.HiddenInput) response_date = forms.DateTimeField(label="Date de l'appel", help_text="Format: JJ/MM/AAAA", widget=forms.SplitDateTimeWidget) duration = forms.IntegerField( label="Durée (approx.)", help_text="En nombre de minutes arrondis " "(ex. 2 pour 1min:35s et 1 pour 1min:29s)") topics = forms.MultipleChoiceField( label="Questions", choices=[(t.slug, t.display_name()) for t in Topics.objects.order_by('slug')], widget=forms.CheckboxSelectMultiple) age = forms.IntegerField(label="Age", required=False) sex = forms.ChoiceField(label="Sexe", choices=HotlineResponse.SEXES.items(), required=False, initial=HotlineResponse.SEX_UNKNOWN) region = forms.ChoiceField( label="Région", choices=[(EMPTY_ENTITY, "INCONNUE")] + [(e.slug, e.name) for e in Entity.objects.filter(type=Entity.TYPE_REGION)]) cercle = forms.CharField(label="Cercle", widget=forms.Select, required=False) commune = forms.CharField(label="Commune", widget=forms.Select, required=False) village = forms.CharField(label="Village", widget=forms.Select, required=False) def clean_village(self): ''' Returns a Village Entity from the multiple selects ''' is_empty = lambda l: l is None or l == EMPTY_ENTITY location = None levels = ['region', 'cercle', 'commune', 'village'] while len(levels) and is_empty(location): location = self.cleaned_data.get(levels.pop()) or None if is_empty(location): return None try: return Entity.objects.get(slug=location) except Entity.DoesNotExist: raise forms.ValidationError("Localité incorrecte.") def clean_request_id(self): ''' Return a HotlineEvent from the id ''' try: return HotlineEvent.objects.get( id=int(self.cleaned_data.get('request_id'))) except HotlineEvent.DoesNotExist: raise forms.ValidationError("Évennement incorrect") context = get_default_context(page='data_entry') context.update({ 'volunteers': [(vol, HotlineEvent.objects.filter(volunteer=vol, processed=True, answer__isnull=True).count()) for vol in HotlineVolunteer.objects.filter(is_active=True)] }) volunteer = None events = [] # Send volunteer to template if it's in GET if request.GET.get('volunteer'): volunteer = get_object_or_404(HotlineVolunteer, username=request.GET.get('volunteer')) if volunteer: events = HotlineEvent.objects.filter(volunteer=volunteer, processed=True, answer__isnull=True) # If POST, we received data for a HotlineResponse if request.method == 'POST': form = HotlineResponseForm(request.POST) if form.is_valid(): event_request = form.cleaned_data.get('request_id') event_response = HotlineResponse.objects \ .create(request=event_request, response_date=form.cleaned_data.get('response_date'), age=form.cleaned_data.get('age'), sex=form.cleaned_data.get('sex'), duration=form.cleaned_data.get('duration'), location=form.cleaned_data.get('village')) # topics event_response.save() for topic_slug in form.cleaned_data.get('topics'): event_response.topics.add(Topics.objects.get(slug=topic_slug)) event_response.save() event_request.save() messages.success(request, "Appel %s enregistré" % event_request) # redirect to the page with the volunteer GET param response = redirect('data_entry') response[ 'Location'] += '?volunteer=%s' % event_request.volunteer.username return response else: form = HotlineResponseForm() context.update({'volunteer': volunteer, 'events': events, 'form': form}) return render(request, "data_entry.html", context)
def exported_status(request): context = get_default_context(page="status") context.update(get_status_context()) return render(request, "status_for_export.html", context)
def data_entry(request): """ Enter Data for calls made by the volunteers Step 1: Pick a volunteer to enter data for. Step 2: List all calls made by the chosen volunteer Step 3: Enter data for a specific call. This creates a HotlineResponse object. """ class HotlineResponseForm(forms.Form): """ Used to easily enter data for calls made by volunteers. """ request_id = forms.IntegerField(widget=forms.HiddenInput) response_date = forms.DateTimeField( label="Date de l'appel", help_text="Format: JJ/MM/AAAA", widget=forms.SplitDateTimeWidget ) duration = forms.IntegerField( label="Durée (approx.)", help_text="En nombre de minutes arrondis " "(ex. 2 pour 1min:35s et 1 pour 1min:29s)", ) topics = forms.MultipleChoiceField( label="Questions", choices=[(t.slug, t.display_name()) for t in Topics.objects.order_by("slug")], widget=forms.CheckboxSelectMultiple, ) age = forms.IntegerField(label="Age", required=False) sex = forms.ChoiceField( label="Sexe", choices=HotlineResponse.SEXES.items(), required=False, initial=HotlineResponse.SEX_UNKNOWN ) region = forms.ChoiceField( label="Région", choices=[(EMPTY_ENTITY, "INCONNUE")] + [(e.slug, e.name) for e in Entity.objects.filter(type=Entity.TYPE_REGION)], ) cercle = forms.CharField(label="Cercle", widget=forms.Select, required=False) commune = forms.CharField(label="Commune", widget=forms.Select, required=False) village = forms.CharField(label="Village", widget=forms.Select, required=False) def clean_village(self): """ Returns a Village Entity from the multiple selects """ is_empty = lambda l: l is None or l == EMPTY_ENTITY location = None levels = ["region", "cercle", "commune", "village"] while len(levels) and is_empty(location): location = self.cleaned_data.get(levels.pop()) or None if is_empty(location): return None try: return Entity.objects.get(slug=location) except Entity.DoesNotExist: raise forms.ValidationError("Localité incorrecte.") def clean_request_id(self): """ Return a HotlineEvent from the id """ try: return HotlineEvent.objects.get(id=int(self.cleaned_data.get("request_id"))) except HotlineEvent.DoesNotExist: raise forms.ValidationError("Évennement incorrect") context = get_default_context(page="data_entry") context.update( { "volunteers": [ (vol, HotlineEvent.objects.filter(volunteer=vol, processed=True, answer__isnull=True).count()) for vol in HotlineVolunteer.objects.filter(is_active=True) ] } ) volunteer = None events = [] # Send volunteer to template if it's in GET if request.GET.get("volunteer"): volunteer = get_object_or_404(HotlineVolunteer, username=request.GET.get("volunteer")) if volunteer: events = HotlineEvent.objects.filter(volunteer=volunteer, processed=True, answer__isnull=True) # If POST, we received data for a HotlineResponse if request.method == "POST": form = HotlineResponseForm(request.POST) if form.is_valid(): event_request = form.cleaned_data.get("request_id") event_response = HotlineResponse.objects.create( request=event_request, response_date=form.cleaned_data.get("response_date"), age=form.cleaned_data.get("age"), sex=form.cleaned_data.get("sex"), duration=form.cleaned_data.get("duration"), location=form.cleaned_data.get("village"), ) # topics event_response.save() for topic_slug in form.cleaned_data.get("topics"): event_response.topics.add(Topics.objects.get(slug=topic_slug)) event_response.save() event_request.save() messages.success(request, "Appel %s enregistré" % event_request) # redirect to the page with the volunteer GET param response = redirect("data_entry") response["Location"] += "?volunteer=%s" % event_request.volunteer.username return response else: form = HotlineResponseForm() context.update({"volunteer": volunteer, "events": events, "form": form}) return render(request, "data_entry.html", context)