Пример #1
0
def submissions(object_list, fields):
    out = []
    page_answers = get_all_answers(object_list)
    for submission in object_list:
        out.append('<div class="submission">')
        out.append(submission_fields(submission, fields, page_answers))
        D = link_detail_survey_none = DETAIL_SURVEY_NONE.DETAIL
        out.append(submission_link(submission, D))
        out.append('</div>')
    return mark_safe("\n".join(out))
Пример #2
0
def submission_fields(submission,
                      fields=None,
                      page_answers=None,
                      request=None,
                      video_height=360,
                      video_width=288):
    is_staff = request and request.user.is_staff
    if not page_answers:
        page_answers = get_all_answers(
            [submission],
            include_private_questions=is_staff)
    if not fields:
        if is_staff:
            fields = list(submission.survey.get_fields())
        else:
            fields = list(submission.survey.get_public_fields())
    out = []
    answer_list = page_answers.get(submission.id, [])
    answers = {}
    when = submission.submitted_at.strftime("%B %d, %Y %I:%M:%S %p")
    out.append('<div class="date">%s</div>' % when)
    for answer in answer_list:
        answers[answer.question] = answer
    for question in fields:
        answer = answers.get(question, None)
        if answer and answer.value:
            out.append('<div class="field">')
            out.append('<label>%s</label>: ' % question.label)
            if answer.image_answer:
                valid = True
                try:
                    thmb = answer.image_answer.thumbnail.absolute_url
                    args = (thmb, answer.id,)
                    out.append('<img src="%s" id="img_%d" />' % args)
                    x_y = get_image_dimensions(answer.image_answer.file)
                except ThumbnailException as ex:
                    valid = False
                    out.append('<div class="error">%s</div>' % str(ex))
                thumb_width = Answer.image_answer_thumbnail_meta["size"][0]
                # This extra hidden input is in case you want to enlarge
                # images. Don't bother enlarging images unless we'll increase
                # their dimensions by at least 10%.
                if valid and x_y and float(x_y[0]) / thumb_width > 1.1:
                    format = ('<input type="hidden" id="img_%d_full_url" '
                              'value="%s" class="enlargeable" />')
                    enlarge = answer.image_answer
                    enlarge = enlarge.extra_thumbnails["max_enlarge"]
                    enlarge = enlarge.absolute_url
                    args = (answer.id, enlarge)
                    out.append(format % args)
            else:
                out.append(linebreaks(escape(answer.value)))
            out.append('</div>')
    return mark_safe("\n".join(out))
Пример #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))
Пример #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