Example #1
0
def monitoring_organization_export(request, monitoring_id):
    """
    Экспорт организаций в CSV.

    """
    monitoring = get_object_or_404(Monitoring, pk=monitoring_id)
    if not request.user.has_perm('exmo2010.edit_monitoring', monitoring):
        return HttpResponseForbidden(_('Forbidden'))
    organizations = Organization.objects.filter(monitoring=monitoring)
    response = HttpResponse(mimetype='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=monitoring-organization-%s.csv' % monitoring_id
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Name',
        'Url',
        'Email',
        'Phone',
        'Comments',
        'Keywords',
    ])
    for o in organizations:
        out = (
            o.name,
            o.url,
            o.email,
            o.phone,
            o.comments,
        )
        keywords = ", ".join([k.name for k in o.tags])
        out += (keywords,)
        writer.writerow(out)
    return response
Example #2
0
def list(request):
    response, parameters = validate_request(request)

    if response.status_code == 204:
        lista_img = manager.list(parameters['address'], parameters['name'])
        if len(lista_img) > 0:
            response = HttpResponse(simplejson.dumps({'images': lista_img}), mimetype='application/json')
            response.encoding = 'utf-8'
            response.status_code = 200
    return response
Example #3
0
def list(request):
    response, parameters = validate_request(request)

    if response.status_code == 204:
        lista_img = manager.list(parameters['address'], parameters['name'])
        if len(lista_img) > 0:
            response = HttpResponse(simplejson.dumps({'images': lista_img}),
                                    mimetype='application/json')
            response.encoding = 'utf-8'
            response.status_code = 200
    return response
Example #4
0
def representatives_export(request, monitoring_pk):
    monitoring = get_object_or_404(Monitoring, pk=monitoring_pk)
    if not request.user.has_perm('exmo2010.admin_monitoring', monitoring):
        raise PermissionDenied

    orgs = monitoring.organization_set.order_by('name')

    for org in orgs:
        org.users = []
        for user in sorted(org.userprofile_set.all(), key=lambda m: m.full_name):
            scores = Score.objects.filter(task__organization=org).values_list('pk', flat=True)
            user.comments = user.user.comment_comments.filter(object_pk__in=scores)
            org.users.append(user)

    response = HttpResponse(mimetype='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=representatives-%s.csv' % monitoring_pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Verified',
        'Organization',
        'First name',
        'Last name',
        'Email',
        'Phone',
        'Job title',
        'Comments count',
        'Date joined',
        'Last login',
    ])

    for org in orgs:
        for user in org.users:
            row = [
                int(user.user.is_active),
                org.name,
                user.user.first_name,
                user.user.last_name,
                user.user.email,
                user.phone,
                user.position,
                user.comments.count(),
                user.user.date_joined.date().isoformat(),
                user.user.last_login.date().isoformat(),
            ]
            writer.writerow(row)

    license = LicenseTextFragments.objects.filter(pk='license')
    if license:
        writer.writerow([u'#%s' % license[0].csv_footer])

    return response
Example #5
0
    def csv(self):
        response = HttpResponse(mimetype='application/vnd.ms-excel')
        response['Content-Disposition'] = \
            'attachment; filename=monitoring-%s.csv' % self.monitoring.pk
        response.encoding = 'UTF-16'
        writer = UnicodeWriter(response)
        # csv HEAD
        writer.writerow([
            "#Monitoring",
            "Organization",
            "Organization_id",
            "Position",
            "Initial Openness",
            "Openness",
            "Parameter",
            "Parameter_id",
            "Found",
            "Complete",
            "Topical",
            "Accessible",
            "Hypertext",
            "Document",
            "Image",
            "Social",
            "Type",
            "Revision",
            "Links",
            "Recommendations"
        ])

        score_fields = ['name', 'id', 'found'] + Parameter.OPTIONAL_CRITERIA
        score_fields += ['social', 'type', 'revision', 'links', 'recommendations']
        for task in self.tasks.values():
            for score_dict in task['scores']:
                row = [
                    self.monitoring.name,
                    task['name'],
                    task['id'],
                    task['position'],
                    task['openness_initial'],
                    task['openness'],
                ]
                row.extend([unicode(score_dict.get(c, "not relevant")) for c in score_fields])
                writer.writerow(row)
        # csv FOOTER
        license = LicenseTextFragments.objects.filter(pk='license')
        if license:
            writer.writerow([u'#%s' % license[0].csv_footer])

        return response
def list(request):
    '''
    calls the methods of the package manager (several images in the folder list)
    and returns List Names Images to the end of the process.
    '''
    response, parameters = validate_request(request)

    if response.status_code == 204:
        lista_img = manager.list(parameters['address'], parameters['name'])
        if len(lista_img) > 0:
            response = HttpResponse(simplejson.dumps({'images': lista_img}), mimetype='application/json')
            response.encoding = 'utf-8'
            response.status_code = 200
    return response
Example #7
0
def connection(request):

    #url = request.path_info
    url = request.META["QUERY_STRING"]

    path = request.path_info
    params = request.META[
        "QUERY_STRING"]  # url.split("?")[0] if (len(url.split("?")) > 1) else ""

    pos = path.index("cubes/")
    path = path[(pos + 6):]

    # Evaluate request
    if (path.find("cube/") == 0):
        cube = path.split("/")[1]

        for acl in settings.CUBESVIEWER_PROXY_ACL:
            if (cube == acl["cube"]):
                groups = [g.name for g in request.user.groups.all()]
                if (not (acl["group"] in groups)):
                    return HttpResponseForbidden(
                        "Wrong permissions for this data cube. User needs to be in group %s."
                        % acl["group"])

    elif (path.find("cubes") == 0):
        pass

    elif (path.find("version") == 0):
        pass

    elif (path.find("info") == 0):
        pass

    else:

        return HttpResponseForbidden("CubesViewer Server proxy unknown path.")

    # Do request
    proxy_url = settings.CUBESVIEWER_CUBES_URL + "/" + path + "?" + params
    if (settings.CUBESVIEWER_CUBES_PROXY_USER == None):
        r = requests.get(proxy_url)
    else:
        r = requests.get(proxy_url, auth=settings.CUBESVIEWER_CUBES_PROXY_USER)

    response = HttpResponse(r.content, content_type=r.headers["content-type"])
    response.status_code = r.status_code
    response.encoding = "utf-8"

    return response
Example #8
0
def answers_export(request, monitoring_pk):
    """
    Экспорт ответов на анкету.

    """
    monitoring = get_object_or_404(Monitoring, pk=monitoring_pk)

    if not request.user.has_perm('exmo2010.admin_monitoring', monitoring):
        raise PermissionDenied

    questionnaire = get_object_or_404(Questionnaire, monitoring=monitoring)
    tasks = Task.approved_tasks.filter(organization__monitoring=monitoring)

    #Нет задач для экспорта
    if not tasks.exists():
        raise Http404

    #Удобнее отлаживать без сохранения
    if hasattr(settings, 'DEBUG_EXPORT') and settings.DEBUG_EXPORT:
        response = HttpResponse(mimetype='text/plain')
    else:
        response = HttpResponse(mimetype='application/vnd.ms-excel')
        response[
            'Content-Disposition'] = 'attachment; filename=anketa-%s.csv' % monitoring.pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)

    header = ['#organization', 'url']
    questions = QQuestion.objects.filter(questionnaire=questionnaire)
    for question in questions:
        header.append(question.question)
    writer.writerow(header)

    #Это работает только если анкета заполнена целиком. Но иного по workflow быть не должно.
    for task in tasks:
        answers = task.qanswer_set.filter(
            question__questionnaire=questionnaire)
        out = [task.organization.name, task.organization.url]

        for answer in answers:
            out.append(answer.answer())

        writer.writerow(out)

    license = LicenseTextFragments.objects.filter(pk='license')
    if license:
        writer.writerow([u'#%s' % license[0].csv_footer])

    return response
Example #9
0
def monitoring_parameter_export(request, monitoring_pk):
    """
    Экспорт параметров в CSV
    """
    monitoring = get_object_or_404(Monitoring, pk=monitoring_pk)
    if not request.user.has_perm('exmo2010.edit_monitoring', monitoring):
        raise PermissionDenied

    parameters = Parameter.objects.filter(monitoring=monitoring)
    response = HttpResponse(mimetype='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=monitoring-parameters-%s.csv' % monitoring_pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Code',
        'Name',
        'Grounds',
        'Rating procedure',
        'Notes',
        'Complete',
        'Topical',
        'Accessible',
        'Hypertext',
        'Document',
        'Image',
        'Weight',
    ])
    for p in parameters:
        out = (
            p.code,
            p.name,
            p.grounds,
            p.rating_procedure,
            p.notes,
            int(p.complete),
            int(p.topical),
            int(p.accessible),
            int(p.hypertext),
            int(p.document),
            int(p.image),
            p.weight
        )
        writer.writerow(out)
    license = LicenseTextFragments.objects.filter(pk='license')
    if license:
        writer.writerow([u'#%s' % license[0].csv_footer])

    return response
Example #10
0
def connection(request):

    #url = request.path_info
    url = request.META["QUERY_STRING"]

    path = request.path_info
    params = request.META["QUERY_STRING"] # url.split("?")[0] if (len(url.split("?")) > 1) else ""


    pos = path.index("cubes/")
    path = path [(pos + 6) :]

    # Evaluate request
    if (path.find("cube/") == 0):
        cube = path.split("/")[1]

        for acl in settings.CUBESVIEWER_PROXY_ACL:
            if (cube == acl["cube"]):
                groups = [g.name for g in request.user.groups.all()]
                if (not (acl["group"] in groups)):
                    return HttpResponseForbidden("Wrong permissions for this data cube. User needs to be in group %s." % acl["group"])

    elif (path.find("cubes") == 0):
        pass

    elif (path.find("version") == 0):
        pass

    elif (path.find("info") == 0):
        pass

    else:

        return HttpResponseForbidden("CubesViewer Server proxy unknown path.")

    # Do request
    proxy_url = settings.CUBESVIEWER_CUBES_URL + "/" + path + "?" + params
    if (settings.CUBESVIEWER_CUBES_PROXY_USER == None):
        r = requests.get( proxy_url)
    else:
        r = requests.get( proxy_url, auth=settings.CUBESVIEWER_CUBES_PROXY_USER)

    response = HttpResponse(r.content, content_type = r.headers["content-type"])
    response.status_code = r.status_code
    response.encoding = "utf-8"


    return response
Example #11
0
def task_export(request, task_pk):
    task = get_object_or_404(Task, pk=task_pk)
    if not request.user.has_perm('exmo2010.view_task', task):
        raise PermissionDenied
    parameters = Parameter.objects.filter(monitoring=task.organization.monitoring).exclude(exclude=task.organization)
    scores = Score.objects.filter(task=task_pk, revision=Score.REVISION_DEFAULT)
    response = HttpResponse(mimetype='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=task-%s.csv' % task_pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Code',
        'Name',
        'Found',
        'Complete',
        'Topical',
        'Accessible',
        'Hypertext',
        'Document',
        'Image',
        'Links',
        'Recommendations'
    ])
    for p in parameters:
        out = (
            p.code,
            p.name,
        )
        try:
            s = scores.get(parameter=p)
        except Score.DoesNotExist:
            out += ('',)*8
        else:
            out += (s.found,)
            out += (s.complete,) if p.complete else ('',)
            out += (s.topical,) if p.topical else ('',)
            out += (s.accessible,) if p.accessible else ('',)
            out += (s.hypertext,) if p.hypertext else ('',)
            out += (s.document,) if p.document else ('',)
            out += (s.image,) if p.image else ('',)
            out += (s.links,)
            out += (s.recommendations,)
        writer.writerow(out)
    license = LicenseTextFragments.objects.filter(pk='license')
    if license:
        writer.writerow([u'#%s' % license[0].csv_footer])

    return response
Example #12
0
def answers_export(request, monitoring_pk):
    """
    Экспорт ответов на анкету.

    """
    monitoring = get_object_or_404(Monitoring, pk=monitoring_pk)

    if not request.user.has_perm('exmo2010.admin_monitoring', monitoring):
        raise PermissionDenied

    questionnaire = get_object_or_404(Questionnaire, monitoring=monitoring)
    tasks = Task.approved_tasks.filter(organization__monitoring=monitoring)

    #Нет задач для экспорта
    if not tasks.exists():
        raise Http404

    #Удобнее отлаживать без сохранения
    if hasattr(settings, 'DEBUG_EXPORT') and settings.DEBUG_EXPORT:
        response = HttpResponse(mimetype='text/plain')
    else:
        response = HttpResponse(mimetype='application/vnd.ms-excel')
        response['Content-Disposition'] = 'attachment; filename=anketa-%s.csv' % monitoring.pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)

    header = ['#organization', 'url']
    questions = QQuestion.objects.filter(questionnaire=questionnaire)
    for question in questions:
        header.append(question.question)
    writer.writerow(header)

    #Это работает только если анкета заполнена целиком. Но иного по workflow быть не должно.
    for task in tasks:
        answers = task.qanswer_set.filter(question__questionnaire=questionnaire)
        out = [task.organization.name, task.organization.url]

        for answer in answers:
            out.append(answer.answer())

        writer.writerow(out)

    license = LicenseTextFragments.objects.filter(pk='license')
    if license:
        writer.writerow([u'#%s' % license[0].csv_footer])

    return response
Example #13
0
def task_export(request, task_pk):
    task = get_object_or_404(Task, pk=task_pk)
    if not request.user.has_perm('exmo2010.view_task', task):
        raise PermissionDenied
    parameters = Parameter.objects.filter(
        monitoring=task.organization.monitoring).exclude(
            exclude=task.organization)
    scores = Score.objects.filter(task=task_pk,
                                  revision=Score.REVISION_DEFAULT)
    response = HttpResponse(mimetype='application/vnd.ms-excel')
    response[
        'Content-Disposition'] = 'attachment; filename=task-%s.csv' % task_pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Code', 'Name', 'Found', 'Complete', 'Topical', 'Accessible',
        'Hypertext', 'Document', 'Image', 'Links', 'Recommendations'
    ])
    for p in parameters:
        out = (
            p.code,
            p.name,
        )
        try:
            s = scores.get(parameter=p)
        except Score.DoesNotExist:
            out += ('', ) * 8
        else:
            out += (s.found, )
            out += (s.complete, ) if p.complete else ('', )
            out += (s.topical, ) if p.topical else ('', )
            out += (s.accessible, ) if p.accessible else ('', )
            out += (s.hypertext, ) if p.hypertext else ('', )
            out += (s.document, ) if p.document else ('', )
            out += (s.image, ) if p.image else ('', )
            out += (s.links, )
            out += (s.recommendations, )
        writer.writerow(out)
    license = LicenseTextFragments.objects.filter(pk='license')
    if license:
        writer.writerow([u'#%s' % license[0].csv_footer])

    return response
Example #14
0
def monitoring_parameter_export(request, id):
    """
    Экспорт параметров в CSV
    """
    monitoring = get_object_or_404(Monitoring, pk = id)
    if not request.user.has_perm('exmo2010.edit_monitoring', monitoring):
        return HttpResponseForbidden(_('Forbidden'))
    parameters = Parameter.objects.filter(monitoring = monitoring)
    response = HttpResponse(mimetype = 'application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=monitoring-parameters-%s.csv' % id
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Code',
        'Name',
        'Description',
        'Complete',
        'Topical',
        'Accessible',
        'Hypertext',
        'Document',
        'Image',
        'Weight',
        'Keywords',
    ])
    for p in parameters:
        out = (
            p.code,
            p.name,
            p.description,
            int(p.complete),
            int(p.topical),
            int(p.accessible),
            int(p.hypertext),
            int(p.document),
            int(p.image),
            p.weight
        )
        keywords = ", ".join([k.name for k in p.tags])
        out += (keywords,)
        writer.writerow(out)
    return response
Example #15
0
def monitoring_organization_export(request, monitoring_pk):
    """
    Экспорт организаций в CSV.

    """
    monitoring = get_object_or_404(Monitoring, pk=monitoring_pk)
    if not request.user.has_perm('exmo2010.edit_monitoring', monitoring):
        raise PermissionDenied

    organizations = Organization.objects.filter(monitoring=monitoring)
    response = HttpResponse(mimetype='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=monitoring-organization-%s.csv' % monitoring_pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Name',
        'Url',
        'Email',
        'Phone',
        'recommendations_hidden',
        'Code',
        'Invitation link',
    ])
    for o in organizations:
        out = (
            o.name,
            o.url,
            o.email,
            o.phone,
            str(o.recommendations_hidden),
            o.inv_code,
            request.build_absolute_uri(reverse('exmo2010:auth_orguser') + '?code={}'.format(o.inv_code)),
        )
        writer.writerow(out)
    license = LicenseTextFragments.objects.filter(pk='license')
    if license:
        writer.writerow([u'#%s' % license[0].csv_footer])

    return response
Example #16
0
 def json(self):
     ret = {
         'monitoring': {
             'name': self.monitoring.name,
             'tasks': self.tasks.values(),
         },
     }
     license = LicenseTextFragments.objects.filter(pk='license')
     json_license = license[0].json_license if license else {}
     if json_license:
         ret.update({'license': json_license})
     json_dump_args = {}
     if settings.DEBUG:
         json_dump_args = {'indent': 2}
     response = HttpResponse(mimetype='application/json')
     response.encoding = 'UTF-8'
     response['Content-Disposition'] = 'attachment; filename=monitoring-%s.json' % self.monitoring.pk
     response.write(
         simplejson.dumps(
             ret, **json_dump_args
         ).decode("unicode_escape").encode("utf8"))
     return response
Example #17
0
def bookmark_view(request):
    # 获取链接的详细信息
    if request.method == 'GET':

        link = request.GET.get('url')
        link = parse.unquote(link)

        if len(link) > 2048:
            res = HttpResponse()
            res.status_code = 414
            return res

        try:
            # 获取页面编码格式
            res = requests.get(url=link,
                               headers={
                                   'User-Agent':
                                   'Mozilla/5.0 (X11; Linux x86_64) '
                                   'AppleWebKit/537.36 (KHTML, like Gecko) '
                                   'Chrome/73.0.3683.75 Safari/537.36'
                               },
                               timeout=5)
            ecd_html = res.text

            try:
                parsing_html = etree.HTML(ecd_html)
                chs_list_xp = parsing_html.xpath('//meta[1]/@charset')
                pattern = re.compile(r'charset=(.*?)"', re.S)
                chs_list_re = pattern.findall(ecd_html)

                if (not chs_list_xp) and (not chs_list_re):
                    res = {'code': 30100, 'error': 'get no encoding'}
                    return JsonResponse(res)

                ecd = 'utf-8'
                if chs_list_xp:
                    ecd = chs_list_xp[0].strip()
                if chs_list_re:
                    ecd = chs_list_re[0].strip()
            # xpath错误,因为不是html页面,是二进制的数据
            except Exception as e:
                print('--not html--', e)
                res = {'code': 30102, 'error': 'not html'}
                return JsonResponse(res)

            # 请求页面
            res = requests.get(url=link,
                               headers={
                                   'User-Agent':
                                   'Mozilla/5.0 (X11; Linux x86_64) '
                                   'AppleWebKit/537.36 (KHTML, like Gecko) '
                                   'Chrome/73.0.3683.75 Safari/537.36'
                               },
                               timeout=5)
        # 请求超时
        except Exception as e:
            print('--get link detail timeout--', e)
            res = {'code': 30101, 'error': 'request timeout'}
            return JsonResponse(res)

        # 响应的编码
        res.encoding = ecd
        html = res.text

        parsing_html = etree.HTML(html)
        title_list = parsing_html.xpath('//title/text()')
        if title_list:
            title = title_list[0].strip()
        else:
            title = ''
        description_list = parsing_html.xpath(
            '//meta[@name="description"]/@content')
        if description_list:
            description = description_list[0].strip()
        else:
            description = ''
        res_json = {
            'code': '200',
            'data': {
                'title': title,
                'description': description,
            }
        }
        res_str = json.dumps(res_json, ensure_ascii=False)
        return HttpResponse(res_str)

    # 添加书签
    if request.method == 'POST':
        data_json = request.body
        data = json.loads(data_json)
        link = data.get('link', '')
        title = data.get('title', '')
        description = data.get('description', '')
        tags = data.get('tags', '')
        collection = data.get('collection', '')

        if not link:
            res = {'code': 50100, 'error': 'link empty'}
            return JsonResponse(res)
        if not title:
            res = {'code': 50101, 'error': 'title empty'}
            return JsonResponse(res)
        if not collection:
            res = {'code': 50102, 'error': 'collection empty'}
            return JsonResponse(res)

        # 将书签存入bookmark表中
        bookmark = BookMark.objects.create(link=link,
                                           title=title,
                                           description=description,
                                           collector=request.user)

        # 收藏集
        try:
            collection = Collection.objects.get(name=collection,
                                                creator=request.user)
        except Exception as e:
            print('collection not exist------', e)
            res = {'code': 50104, 'error': 'collection not exist'}
            return JsonResponse(res)
        collection.bookmark_set.add(bookmark)

        # 标签
        for t in tags:
            try:
                tag = Tag.objects.get(name=t, creator=request.user)
            except Exception as e:
                # 标签不存在
                print('tag not exist------', e)
                tag = Tag.objects.create(name=t, creator=request.user)
            tag.bookmark_set.add(bookmark)

        res = {
            'code': 200,
            'data': {
                'username': request.user.username,
                'created_time': bookmark.created_time
            }
        }
        return JsonResponse(res)
Example #18
0
def task_export(request, task_pk):
    task = get_object_or_404(Task, pk=task_pk)
    if not request.user.has_perm('exmo2010.view_task', task):
        return HttpResponseForbidden(_('Forbidden'))
    parameters = Parameter.objects.filter(monitoring=task.organization.monitoring).exclude(exclude=task.organization)
    scores = Score.objects.filter(task=task_pk, revision=Score.REVISION_DEFAULT)
    response = HttpResponse(mimetype='application/vnd.ms-excel')
    response['Content-Disposition'] = 'attachment; filename=task-%s.csv' % task_pk
    response.encoding = 'UTF-16'
    writer = UnicodeWriter(response)
    writer.writerow([
        '#Code',
        'Name',
        'Found',
        'Complete',
        'CompleteComment',
        'Topical',
        'TopicalComment',
        'Accessible',
        'AccessibleComment',
        'Hypertext',
        'HypertextComment',
        'Document',
        'DocumentComment',
        'Image',
        'ImageComment',
        'Comment'
    ])
    category = None
    subcategory = None
    for p in parameters:
        out = (
            p.code,
            p.name,
        )
        try:
            s = scores.get(parameter=p)
        except:
            out += (
                '',
                '',
                '',
                '',
                '',
                '',
                '',
                '',
                '',
                '',
                '',
                '',
                '',
                ''
            )
        else:
            out += (s.found,)
            if p.complete:
                out += (
                    s.complete,
                    s.completeComment
                )
            else:
                out += ('', '')
            if p.topical:
                out += (
                    s.topical,
                    s.topicalComment
                )
            else:
                out += ('', '')
            if p.accessible:
                out += (
                    s.accessible,
                    s.accessibleComment
                )
            else:
                out += ('', '')
            if p.hypertext:
                out += (
                    s.hypertext,
                    s.hypertextComment
                )
            else:
                out += ('', '')
            if p.document:
                out += (
                    s.document,
                    s.documentComment
                )
            else:
                out += ('', '')
            if p.image:
                out += (
                    s.image,
                    s.imageComment
                )
            else:
                out += ('','')
            out += (s.comment,)
        writer.writerow(out)
    return response