{"action":"created","comment":{"url":"https://api.github.com/repos/indico/indico/pulls/comments/37507647","id":37507647,"diff_hunk":"@@ -59,3 +67,46 @@ def was_survey_submitted(survey):\n     if submission_id is None:\n         return False\n     return bool(SurveySubmission.find(id=submission_id).count())\n+\n+\n+def generate_csv_from_survey(survey, submitter_ids):\n+    \"\"\"Generates a CSV file from a given survey.\n+\n+    :param submitter_ids: The list of `User` ids. Generated file includes only submissions made by those users\n+    \"\"\"\n+    fieldnames = {'submitter', 'submission_date'}\n+    fieldnames |= {'{}_{}'.format(question.title, question.id) for question in survey.questions\n+                   if not isinstance(question.field, StaticTextField)}\n+\n+    with NamedTemporaryFile(suffix='indico.tmp', dir=Config.getInstance().getTempDir(), delete=False) as temp_file:\n+        submissions = _filter_submissions(survey, submitter_ids)\n+        writer = csv.DictWriter(temp_file, fieldnames=fieldnames)\n+        writer.writeheader()\n+        for submission in submissions:\n+            submission_dict = {\n+                'submitter': (submission.user.full_name.encode('utf-8')\n+                              if submission.user else 'Anonymous'),\n+                'submission_date': format_datetime(submission.submitted_dt),\n+            }\n+\n+            for answer in submission.answers:\n+                key = '{}_{}'.format(answer.question.title, answer.question.id)\n+                submission_dict[key] = _prepare_data(answer.answer_data)\n+            writer.writerow(submission_dict)\n+        return temp_file\n+\n+\n+def _filter_submissions(survey, submitter_ids):\n+    submissions = SurveySubmission.find(SurveySubmission.survey == survey)\n+    if not -1 in submitter_ids:\n+        return submissions.filter(SurveySubmission.user_id.in_(submitter_ids))\n+    else:\n+        submitter_ids.discard(-1)\n+        return submissions.filter(or_(SurveySubmission.user_id.in_(submitter_ids),\n+                                                 SurveySubmission.user == None))\n+\n+\n+def _prepare_data(data):\n+    if isinstance(data, list):\n+        return encode_if_unicode(to_unicode(','.join(data)))","path":"indico/modules/events/surveys/util.py","position":64,"original_position":64,"commit_id":"0654fcceffc12e961bda93d17ad41b52939607c4","original_commit_id":"0654fcceffc12e961bda93d17ad41b52939607c4","user":{"login":"ThiefMaster","id":179599,"avatar_url":"https://avatars.githubusercontent.com/u/179599?v=3","gravatar_id":"","url":"https://api.github.com/users/ThiefMaster","html_url":"https://github.com/ThiefMaster","followers_url":"https://api.github.com/users/ThiefMaster/followers","following_url":"https://api.github.com/users/ThiefMaster/following{/other_user}","gists_url":"https://api.github.com/users/ThiefMaster/gists{/gist_id}","starred_url":"https://api.github.com/users/ThiefMaster/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ThiefMaster/subscriptions","organizations_url":"https://api.github.com/users/ThiefMaster/orgs","repos_url":"https://api.github.com/users/ThiefMaster/repos","events_url":"https://api.github.com/users/ThiefMaster/events{/privacy}","received_events_url":"https://api.github.com/users/ThiefMaster/received_events","type":"User","site_admin":false},"body":"as mentioned before, data is already unicode since it comes from sqlalchemy. so you just need `', '.join(data).encode('utf-8')`","created_at":"2015-08-20T08:52:10Z","updated_at":"2015-08-20T08:52:10Z","html_url":"https://github.com/indico/indico/pull/2011#discussion_r37507647","pull_request_url":"https://api.github.com/repos/indico/indico/pulls/2011","_links":{"self":{"href":"https://api.github.com/repos/indico/indico/pulls/comments/37507647"},"html":{"href":"https://github.com/indico/indico/pull/2011#discussion_r37507647"},"pull_request":{"href":"https://api.github.com/repos/indico/indico/pulls/2011"}}},"pull_request":{"url":"https://api.github.com/repos/indico/indico/pulls/2011","id":42808623,"html_url":"https://github.com/indico/indico/pull/2011","diff_url":"https://github.com/indico/indico/pull/2011.diff","patch_url":"https://github.com/indico/indico/pull/2011.patch","issue_url":"https://api.github.com/repos/indico/indico/issues/2011","number":2011,"state":"open","locked":false,"title":"Improvements for the surveys module","user":{"login":"mic4ael","id":3616940,"avatar_url":"https://avatars.githubusercontent.com/u/3616940?v=3","gravatar_id":"","url":"https://api.github.com/users/mic4ael","html_url":"https://github.com/mic4ael","followers_url":"https://api.github.com/users/mic4ael/followers","following_url":"https://api.github.com/users/mic4ael/following{/other_user}","gists_url":"https://api.github.com/users/mic4ael/gists{/gist_id}","starred_url":"https://api.github.com/users/mic4ael/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mic4ael/subscriptions","organizations_url":"https://api.github.com/users/mic4ael/orgs","repos_url":"https://api.github.com/users/mic4ael/repos","events_url":"https://api.github.com/users/mic4ael/events{/privacy}","received_events_url":"https://api.github.com/users/mic4ael/received_events","type":"User","site_admin":false},"body":"- exporting a list of all the submissions within a survey\r\n- button to remove a submission\r\n- single submission preview","created_at":"2015-08-19T12:33:01Z","updated_at":"2015-08-20T08:52:10Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e49f461eed3ff31d37de47094f149f5c9a92ea43","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/indico/indico/pulls/2011/commits","review_comments_url":"https://api.github.com/repos/indico/indico/pulls/2011/comments","review_comment_url":"https://api.github.com/repos/indico/indico/pulls/comments{/number}","comments_url":"https://api.github.com/repos/indico/indico/issues/2011/comments","statuses_url":"https://api.github.com/repos/indico/indico/statuses/0654fcceffc12e961bda93d17ad41b52939607c4","head":{"label":"mic4ael:wip/evaluation","ref":"wip/evaluation","sha":"0654fcceffc12e961bda93d17ad41b52939607c4","user":{"login":"mic4ael","id":3616940,"avatar_url":"https://avatars.githubusercontent.com/u/3616940?v=3","gravatar_id":"","url":"https://api.github.com/users/mic4ael","html_url":"https://github.com/mic4ael","followers_url":"https://api.github.com/users/mic4ael/followers","following_url":"https://api.github.com/users/mic4ael/following{/other_user}","gists_url":"https://api.github.com/users/mic4ael/gists{/gist_id}","starred_url":"https://api.github.com/users/mic4ael/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mic4ael/subscriptions","organizations_url":"https://api.github.com/users/mic4ael/orgs","repos_url":"https://api.github.com/users/mic4ael/repos","events_url":"https://api.github.com/users/mic4ael/events{/privacy}","received_events_url":"https://api.github.com/users/mic4ael/received_events","type":"User","site_admin":false},"repo":{"id":36723985,"name":"indico","full_name":"mic4ael/indico","owner":{"login":"mic4ael","id":3616940,"avatar_url":"https://avatars.githubusercontent.com/u/3616940?v=3","gravatar_id":"","url":"https://api.github.com/users/mic4ael","html_url":"https://github.com/mic4ael","followers_url":"https://api.github.com/users/mic4ael/followers","following_url":"https://api.github.com/users/mic4ael/following{/other_user}","gists_url":"https://api.github.com/users/mic4ael/gists{/gist_id}","starred_url":"https://api.github.com/users/mic4ael/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mic4ael/subscriptions","organizations_url":"https://api.github.com/users/mic4ael/orgs","repos_url":"https://api.github.com/users/mic4ael/repos","events_url":"https://api.github.com/users/mic4ael/events{/privacy}","received_events_url":"https://api.github.com/users/mic4ael/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/mic4ael/indico","description":"The Indico Project","fork":true,"url":"https://api.github.com/repos/mic4ael/indico","forks_url":"https://api.github.com/repos/mic4ael/indico/forks","keys_url":"https://api.github.com/repos/mic4ael/indico/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mic4ael/indico/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mic4ael/indico/teams","hooks_url":"https://api.github.com/repos/mic4ael/indico/hooks","issue_events_url":"https://api.github.com/repos/mic4ael/indico/issues/events{/number}","events_url":"https://api.github.com/repos/mic4ael/indico/events","assignees_url":"https://api.github.com/repos/mic4ael/indico/assignees{/user}","branches_url":"https://api.github.com/repos/mic4ael/indico/branches{/branch}","tags_url":"https://api.github.com/repos/mic4ael/indico/tags","blobs_url":"https://api.github.com/repos/mic4ael/indico/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mic4ael/indico/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mic4ael/indico/git/refs{/sha}","trees_url":"https://api.github.com/repos/mic4ael/indico/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mic4ael/indico/statuses/{sha}","languages_url":"https://api.github.com/repos/mic4ael/indico/languages","stargazers_url":"https://api.github.com/repos/mic4ael/indico/stargazers","contributors_url":"https://api.github.com/repos/mic4ael/indico/contributors","subscribers_url":"https://api.github.com/repos/mic4ael/indico/subscribers","subscription_url":"https://api.github.com/repos/mic4ael/indico/subscription","commits_url":"https://api.github.com/repos/mic4ael/indico/commits{/sha}","git_commits_url":"https://api.github.com/repos/mic4ael/indico/git/commits{/sha}","comments_url":"https://api.github.com/repos/mic4ael/indico/comments{/number}","issue_comment_url":"https://api.github.com/repos/mic4ael/indico/issues/comments{/number}","contents_url":"https://api.github.com/repos/mic4ael/indico/contents/{+path}","compare_url":"https://api.github.com/repos/mic4ael/indico/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mic4ael/indico/merges","archive_url":"https://api.github.com/repos/mic4ael/indico/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mic4ael/indico/downloads","issues_url":"https://api.github.com/repos/mic4ael/indico/issues{/number}","pulls_url":"https://api.github.com/repos/mic4ael/indico/pulls{/number}","milestones_url":"https://api.github.com/repos/mic4ael/indico/milestones{/number}","notifications_url":"https://api.github.com/repos/mic4ael/indico/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mic4ael/indico/labels{/name}","releases_url":"https://api.github.com/repos/mic4ael/indico/releases{/id}","created_at":"2015-06-02T09:51:56Z","updated_at":"2015-06-02T09:52:02Z","pushed_at":"2015-08-20T08:29:08Z","git_url":"git://github.com/mic4ael/indico.git","ssh_url":"git@github.com:mic4ael/indico.git","clone_url":"https://github.com/mic4ael/indico.git","svn_url":"https://github.com/mic4ael/indico","homepage":"http://indico-software.org","size":182836,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"indico:wip/evaluation","ref":"wip/evaluation","sha":"e989cd9fd089fead5823752268b1554892fc98f6","user":{"login":"indico","id":715236,"avatar_url":"https://avatars.githubusercontent.com/u/715236?v=3","gravatar_id":"","url":"https://api.github.com/users/indico","html_url":"https://github.com/indico","followers_url":"https://api.github.com/users/indico/followers","following_url":"https://api.github.com/users/indico/following{/other_user}","gists_url":"https://api.github.com/users/indico/gists{/gist_id}","starred_url":"https://api.github.com/users/indico/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/indico/subscriptions","organizations_url":"https://api.github.com/users/indico/orgs","repos_url":"https://api.github.com/users/indico/repos","events_url":"https://api.github.com/users/indico/events{/privacy}","received_events_url":"https://api.github.com/users/indico/received_events","type":"Organization","site_admin":false},"repo":{"id":2113067,"name":"indico","full_name":"indico/indico","owner":{"login":"indico","id":715236,"avatar_url":"https://avatars.githubusercontent.com/u/715236?v=3","gravatar_id":"","url":"https://api.github.com/users/indico","html_url":"https://github.com/indico","followers_url":"https://api.github.com/users/indico/followers","following_url":"https://api.github.com/users/indico/following{/other_user}","gists_url":"https://api.github.com/users/indico/gists{/gist_id}","starred_url":"https://api.github.com/users/indico/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/indico/subscriptions","organizations_url":"https://api.github.com/users/indico/orgs","repos_url":"https://api.github.com/users/indico/repos","events_url":"https://api.github.com/users/indico/events{/privacy}","received_events_url":"https://api.github.com/users/indico/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/indico/indico","description":"The Indico Project","fork":false,"url":"https://api.github.com/repos/indico/indico","forks_url":"https://api.github.com/repos/indico/indico/forks","keys_url":"https://api.github.com/repos/indico/indico/keys{/key_id}","collaborators_url":"https://api.github.com/repos/indico/indico/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/indico/indico/teams","hooks_url":"https://api.github.com/repos/indico/indico/hooks","issue_events_url":"https://api.github.com/repos/indico/indico/issues/events{/number}","events_url":"https://api.github.com/repos/indico/indico/events","assignees_url":"https://api.github.com/repos/indico/indico/assignees{/user}","branches_url":"https://api.github.com/repos/indico/indico/branches{/branch}","tags_url":"https://api.github.com/repos/indico/indico/tags","blobs_url":"https://api.github.com/repos/indico/indico/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/indico/indico/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/indico/indico/git/refs{/sha}","trees_url":"https://api.github.com/repos/indico/indico/git/trees{/sha}","statuses_url":"https://api.github.com/repos/indico/indico/statuses/{sha}","languages_url":"https://api.github.com/repos/indico/indico/languages","stargazers_url":"https://api.github.com/repos/indico/indico/stargazers","contributors_url":"https://api.github.com/repos/indico/indico/contributors","subscribers_url":"https://api.github.com/repos/indico/indico/subscribers","subscription_url":"https://api.github.com/repos/indico/indico/subscription","commits_url":"https://api.github.com/repos/indico/indico/commits{/sha}","git_commits_url":"https://api.github.com/repos/indico/indico/git/commits{/sha}","comments_url":"https://api.github.com/repos/indico/indico/comments{/number}","issue_comment_url":"https://api.github.com/repos/indico/indico/issues/comments{/number}","contents_url":"https://api.github.com/repos/indico/indico/contents/{+path}","compare_url":"https://api.github.com/repos/indico/indico/compare/{base}...{head}","merges_url":"https://api.github.com/repos/indico/indico/merges","archive_url":"https://api.github.com/repos/indico/indico/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/indico/indico/downloads","issues_url":"https://api.github.com/repos/indico/indico/issues{/number}","pulls_url":"https://api.github.com/repos/indico/indico/pulls{/number}","milestones_url":"https://api.github.com/repos/indico/indico/milestones{/number}","notifications_url":"https://api.github.com/repos/indico/indico/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/indico/indico/labels{/name}","releases_url":"https://api.github.com/repos/indico/indico/releases{/id}","created_at":"2011-07-27T13:56:30Z","updated_at":"2015-08-17T16:16:09Z","pushed_at":"2015-08-20T08:29:08Z","git_url":"git://github.com/indico/indico.git","ssh_url":"git@github.com:indico/indico.git","clone_url":"https://github.com/indico/indico.git","svn_url":"https://github.com/indico/indico","homepage":"http://indico-software.org","size":207899,"stargazers_count":99,"watchers_count":99,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":56,"mirror_url":null,"open_issues_count":512,"forks":56,"open_issues":512,"watchers":99,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/indico/indico/pulls/2011"},"html":{"href":"https://github.com/indico/indico/pull/2011"},"issue":{"href":"https://api.github.com/repos/indico/indico/issues/2011"},"comments":{"href":"https://api.github.com/repos/indico/indico/issues/2011/comments"},"review_comments":{"href":"https://api.github.com/repos/indico/indico/pulls/2011/comments"},"review_comment":{"href":"https://api.github.com/repos/indico/indico/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/indico/indico/pulls/2011/commits"},"statuses":{"href":"https://api.github.com/repos/indico/indico/statuses/0654fcceffc12e961bda93d17ad41b52939607c4"}}}}