示例#1
0
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)
示例#2
0
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)
示例#3
0
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)
示例#4
0
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)
示例#5
0
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)
示例#6
0
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)
示例#7
0
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)
示例#8
0
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)
示例#9
0
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)
示例#10
0
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)
示例#11
0
def exported_status(request):
    context = get_default_context(page='status')

    context.update(get_status_context())

    return render(request, "status_for_export.html", context)
示例#12
0
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)
示例#13
0
def exported_status(request):
    context = get_default_context(page="status")

    context.update(get_status_context())

    return render(request, "status_for_export.html", context)
示例#14
0
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)