Esempio n. 1
0
def simple_slideshow(display, question, request_GET, css):
    id = "slideshow_%d_%d" % (display.order, question.id)
    out = [
        '<h2 class="chart_title">%s</h2>' % display.annotation,
        '<ul class="%s" id="%s">' % (css, id),
        '<script type="text/javascript">',
        '$(function() {',
        "  $('#%s').jcarousel();" % id,
        '});',
        '</script>']
    caption_fieldnames = display.get_caption_fieldnames()
    caption_lookup = {}
    if caption_fieldnames:
        captions = Answer.objects.filter(
            question__fieldname__in=caption_fieldnames,
            question__survey=display.report.survey,
            submission__is_public=True)
        for caption in captions:
            if not caption.submission_id in caption_lookup:
                caption_lookup[caption.submission_id] = []
            append = "<div class='caption'>%s</div>" % str(caption.value)
            caption_lookup[caption.submission_id].append(append)
    answers = extra_from_filters(
        question.answer_set.all(),
        "submission_id",
        display.report.survey,
        request_GET)
    for answer in answers:
        try:
            image = answer.image_answer.thumbnail_tag
        except ThumbnailException:
            image = "Can't find %s" % answer.image_answer.url
        out.extend([
            '<li>',
            image,
            "\n".join(caption_lookup.get(answer.submission_id, [])),
            '</li>'])
    out.append("</ul>")
    return mark_safe("\n".join(out))
Esempio n. 2
0
def location_question_results(
        request,
        question_id,
        limit_map_answers,
        survey_report_slug=""):
    question = get_object_or_404(Question.objects.select_related("survey"),
                                 pk=question_id,
                                 answer_is_public=True)
    is_staff = request.user.is_staff
    if not question.survey.can_have_public_submissions() and not is_staff:
        raise Http404
    featured = limit_results_to = False
    if survey_report_slug:
        survey_report = get_object_or_404(SurveyReport.objects,
                                          survey=question.survey,
                                          slug=survey_report_slug)
        featured = survey_report.featured
        limit_results_to = survey_report.limit_results_to
    icon_lookup = {}
    icon_questions = question.survey.icon_questions()
    for icon_question in icon_questions:
        icon_by_answer = {}
        for (option, icon) in icon_question.parsed_option_icon_pairs():
            if icon:
                icon_by_answer[option] = icon
        answer_set = icon_question.answer_set.all()
        for answer in answer_set.select_related("question"):
            if answer.value in icon_by_answer:
                icon = icon_by_answer[answer.value]
                icon_lookup[answer.submission_id] = icon

    answers = question.answer_set.filter(
        ~Q(latitude=None),
        ~Q(longitude=None)).order_by("-submission__submitted_at")
    if not is_staff:
        answers = answers.filter(submission__is_public=True)
    if featured:
        answers = answers.filter(submission__featured=True)
    answers = extra_from_filters(
        answers,
        "submission_id",
        question.survey,
        request.GET)
    limit_map_answers = int(limit_map_answers) if limit_map_answers else 0
    if limit_map_answers or limit_results_to:
        answers = answers[:min(filter(None, [limit_map_answers,
                                             limit_results_to, ]))]
    entries = []
    view = "survey.views.submission_for_map"
    for answer in answers:
        kwargs = {"id": answer.submission_id}
        d = {
            "lat": answer.latitude,
            "lng": answer.longitude,
            "url": reverse(view, kwargs=kwargs)}
        if answer.submission_id in icon_lookup:
            d["icon"] = icon_lookup[answer.submission_id]
        entries.append(d)
    response = HttpResponse(mimetype='application/json')
    dump({"entries": entries}, response)
    return response
Esempio n. 3
0
def _survey_report(request, slug, report, page, templates):
    """ Show a report for the survey. As rating is done in a separate
    application we don't directly check request.GET["sort"] here.
    crowdsourcing_settings.PRE_REPORT is the place for that. """
    if page is None:
        page = 1
    else:
        try:
            page = int(page)
        except ValueError:
            raise Http404
    survey = _get_survey_or_404(slug, request)
    # is the survey anything we can actually have a report on?
    is_public = survey.is_live and survey.can_have_public_submissions()
    if not is_public and not request.user.is_staff:
        raise Http404
    reports = survey.surveyreport_set.all()
    if report:
        report_obj = get_object_or_404(reports, slug=report)
    elif survey.default_report:
        args = {"slug": survey.slug, "report": survey.default_report.slug}
        url = reverse("survey_report_page_1", kwargs=args)
        return HttpResponseRedirect(url)
    else:
        report_obj = _default_report(survey)

    archive_fields = list(survey.get_public_archive_fields())
    is_staff = request.user.is_staff
    if is_staff:
        submissions_ = survey.submission_set.all()
        fields = list(survey.get_fields())
    else:
        submissions_ = survey.public_submissions()
        fields = list(survey.get_public_fields())
    filters = get_filters(survey, request.GET)

    id_field = "survey_submission.id"
    if not report_obj.display_individual_results:
        submissions_ = submissions_.none()
    else:
        submissions_ = extra_from_filters(submissions_,
                                         id_field,
                                         survey,
                                         request.GET)

        # If you want to sort based on rating, wire it up here.
        if crowdsourcing_settings.PRE_REPORT:
            pre_report = get_function(crowdsourcing_settings.PRE_REPORT)
            submissions_ = pre_report(
                submissions=submissions_,
                report=report_obj,
                request=request)
        if report_obj.featured:
            submissions_ = submissions_.filter(featured=True)
        if report_obj.limit_results_to:
            submissions_ = submissions_[:report_obj.limit_results_to]

    paginator, page_obj = paginate_or_404(submissions_, page)

    page_answers = get_all_answers(
        page_obj.object_list,
        include_private_questions=is_staff)

    pages_to_link = pages_to_link_from_paginator(page, paginator)

    display_individual_results = all([
        report_obj.display_individual_results,
        archive_fields or (is_staff and fields)])
    context = dict(
        survey=survey,
        submissions=submissions_,
        paginator=paginator,
        page_obj=page_obj,
        pages_to_link=pages_to_link,
        fields=fields,
        archive_fields=archive_fields,
        filters=filters,
        report=report_obj,
        page_answers=page_answers,
        is_public=is_public,
        display_individual_results=display_individual_results,
        request=request)

    return render_to_string(templates, context, _rc(request))
Esempio n. 4
0
def submissions(request, format):
    """ Use this view to make arbitrary queries on submissions. If the user is
    a logged in staff member, ignore submission.is_public,
    question.answer_is_public, and survey.can_have_public_submissions. Use the
    query string to pass keys and values. For example,
    /crowdsourcing/submissions/?survey=my-survey will return all submissions
    for the survey with slug my-survey.
    survey - the slug for the survey
    user - the username of the submittor. Leave blank for submissions without
        a logged in user.
    submitted_from and submitted_to - strings in the format YYYY-mm-ddThh:mm:ss
        For example, 2010-04-05T13:02:03
    featured - A blank value, 'f', 'false', 0, 'n', and 'no' all mean ignore
        the featured flag. Everything else means display only featured.
    You can also use filters in the survey report sense. Rather than document
    exactly what parameters you would pass, follow these steps to figure it
    out:
    1. Enable filters on your survey and the questions you want to filter on.
    2. Go to the report page and fill out the filters you want.
    3. Click Submit.
    4. Examine the query string of the page you end up on and note which
        parameters are filled out. Use those same parameters here. """
    format = format.lower()
    if format not in FORMAT_CHOICES:
        msg = ("%s is an unrecognized format. Crowdsourcing recognizes "
               "these: %s") % (format, ", ".join(FORMAT_CHOICES))
        return HttpResponse(msg)
    is_staff = request.user.is_authenticated() and request.user.is_staff
    if is_staff:
        results = Submission.objects.all(status=Submission.COMPLETED)
    else:
        # survey.can_have_public_submissions is complicated enough that
        # we'll check it in Python, not the database.
        results = Submission.objects.filter(is_public=True, status=Submission.COMPLETED)
    results = results.select_related("survey", "user")
    get = request.GET.copy()
    limit = int(get.pop("limit", [0])[0])
    keys = get.keys()
    basic_filters = (
        'survey',
        'user',
        'submitted_from',
        'submitted_to',
        'featured',
        'is_public')
    if is_staff:
        basic_filters += BALLOT_STUFFING_FIELDS
    survey_slug = ""
    for field in [f for f in keys if f in basic_filters]:
        value = get[field]
        search_field = field
        if 'survey' == field:
            search_field = 'survey__slug'
            survey_slug = value
        elif 'user' == field:
            if '' == value:
                value = None
            else:
                search_field = 'user__username'
        elif field in ('submitted_from', 'submitted_to'):
            date_format = "%Y-%m-%dT%H:%M:%S"
            try:
                value = datetime.strptime(value, date_format)
            except ValueError:
                return HttpResponse(
                    ("Invalid %s format. Try, for example, "
                     "%s") % (field, datetime.now().strftime(date_format),))
            if 'submitted_from' == field:
                search_field = 'submitted_at__gte'
            else:
                search_field = 'submitted_at__lte'
        elif field in ('featured', 'is_public',):
            falses = ('f', 'false', 'no', 'n', '0',)
            value = len(value) and not value.lower() in falses
        # search_field is unicode but needs to be ascii.
        results = results.filter(**{str(search_field): value})
        get.pop(field)

    def get_survey():
        survey = Survey.objects.get(slug=survey_slug)
        get_survey = lambda: survey
        return survey

    if get:
        if survey_slug:
            results = extra_from_filters(
                results,
                "survey_submission.id",
                get_survey(),
                get)
        else:
            message = (
                "You've got a couple of extra filters here, and we "
                "aren't sure what to do with them. You may have just "
                "misspelled one of the basic filters (%s). You may have a "
                "filter from a particular survey in mind. In that case, just "
                "include survey=my-survey-slug in the query string. You may "
                "also be trying to pull some hotshot move like, \"Get me all "
                "submissions that belong to a survey with a filter named '%s' "
                "that match '%s'.\" Crowdsourcing could support this, but it "
                "would be pretty inefficient and, we're guessing, pretty "
                "rare. If that's what you're trying to do I'm afraid you'll "
                "have to do something more complicated like iterating through "
                "all your surveys.")
            item = get.items()[0]
            message = message % (", ".join(basic_filters), item[0], item[1])
            return HttpResponse(message)
    if not is_staff:
        if survey_slug:
            if not get_survey().can_have_public_submissions():
                results = []
        else:
            rs = [r for r in results if r.survey.can_have_public_submissions()]
            results = rs
    if limit:
        results = results[:limit]
    answer_lookup = get_all_answers(results,
                                    include_private_questions=is_staff)
    result_data = []
    for r in results:
        data = r.to_jsondata(answer_lookup, include_private_questions=is_staff)
        result_data.append(data)

    for data in result_data:
        data.update(data["data"])
        data.pop("data")

    def get_keys():
        key_lookup = {}
        for data in result_data:
            for key in data.keys():
                key_lookup[key] = True
        return sorted(key_lookup.keys())

    if format == 'json':
        response = HttpResponse(mimetype='application/json')
        dump(result_data, response)
    elif format == 'csv':
        response = HttpResponse(mimetype='text/csv')
        writer = csv.writer(response)
        keys = get_keys()
        writer.writerow(keys)
        for data in result_data:
            row = []
            for k in keys:
                row.append((u"%s" % _encode(data.get(k, ""))).encode("utf-8"))
            writer.writerow(row)
    elif format == 'xml':
        doc = Document()
        submissions = doc.createElement("submissions")
        doc.appendChild(submissions)
        for data in result_data:
            submission = doc.createElement("submission")
            submissions.appendChild(submission)
            for key, value in data.items():
                if value:
                    cell = doc.createElement(key)
                    submission.appendChild(cell)
                    cell.appendChild(doc.createTextNode(u"%s" % value))
        response = HttpResponse(doc.toxml(), mimetype='text/xml')
    elif format == 'html':  # mostly for debugging.
        keys = get_keys()
        results = [
            "<html><body><table>",
            "<tr>%s</tr>" % "".join(["<th>%s</th>" % k for k in keys])]
        for data in result_data:
            cell = "<td>%s</td>"
            cells = [cell % _encode(data.get(key, "")) for key in keys]
            results.append("<tr>%s</tr>" % "".join(cells))
        results.append("</table></body></html>")
        response = HttpResponse("\n".join(results))
    else:
        return HttpResponse("Unsure how to handle %s format" % format)
    return response