{"action":"created","comment":{"url":"https://api.github.com/repos/zooniverse/Panoptes/pulls/comments/63541942","id":63541942,"diff_hunk":"@@ -6,34 +6,100 @@ class AnnotationForCsv\n       def initialize(classification, annotation, cache)\n         @classification = classification\n         @annotation = annotation.dup.with_indifferent_access\n+        @current = @annotation.dup\n         @cache = cache\n       end\n \n       def to_h\n-        annotation.merge! \"task_label\" => task_label\n-\n-        case task[\"type\"]\n+        case task['type']\n         when \"drawing\"\n-          value_with_tool = (annotation[\"value\"] || []).map do |drawn_item|\n-            drawn_item.merge \"tool_label\" => tool_label(drawn_item)\n-          end\n-          annotation.merge!(\"value\" => value_with_tool)\n-        when /single/i\n-          annotation.merge!(\"value\" => answer_label)\n-        when /multiple/i\n-          annotation.merge!(\"value\" => answer_labels)\n+          drawing\n+        when \"single\", \"multiple\"\n+          simple\n+        when \"text\"\n+          text\n+        when \"combo\"\n+          combo\n+        when \"dropdown\"\n+          dropdown\n+        else\n+         { error: \"task cannot be exported\" }\n         end\n-        annotation\n       end\n \n       private\n \n-      def task_label\n-        translate(task[\"question\"] || task[\"instruction\"])\n+      def drawing(task_info=task)\n+        {}.tap do |new_anno|\n+          new_anno['task'] = @current['task']\n+          new_anno['task_label'] = task_label(task_info)\n+          value_with_tool = (@current[\"value\"] || []).map do |drawn_item|\n+           drawn_item.merge \"tool_label\" => tool_label(task_info, drawn_item)\n+          end\n+          new_anno[\"value\"] = value_with_tool\n+        end\n+      end\n+\n+      def simple(task_info=task)\n+        {}.tap do |new_anno|\n+          new_anno['task'] = @current['task']\n+          new_anno['task_label'] = task_label(task_info)\n+          new_anno['value'] = task['type'] == 'multiple' ? answer_labels : answer_label\n+        end\n+      end\n+\n+      alias_method :single, :simple\n+      alias_method :multiple, :simple\n+\n+      def text(task_info=task)\n+        {}.tap do |new_anno|\n+          new_anno['task'] = @current['task']\n+          new_anno['value'] = @current['value']\n+          new_anno['task_label'] = task_label(task_info)\n+        end\n+      end\n+\n+      def combo\n+        {}.tap do |new_anno|\n+          new_anno['task'] = annotation['task']\n+          new_anno['task_label'] = nil\n+          new_anno['value'] ||= []\n+          annotation['value'].each do |subtask|\n+            @current = subtask\n+            task_info = get_task_info(subtask)\n+            new_anno['value'].push send(task_info['type'], task_info)\n+          end\n+        end\n       end\n \n-      def tool_label(drawn_item)\n-        tool = task[\"tools\"] && task[\"tools\"][drawn_item[\"tool\"]]\n+      def dropdown\n+        {}.tap do |new_anno|\n+          new_anno['task'] = @current['task']\n+          new_anno['value'] = []\n+          task['selects'].each_with_index do |sel, idx|\n+            {}.tap do |tmp|\n+              tmp['select_label'] = sel['title']\n+              tmp['option'] = sel['allowCreate']\n+              sel['options'].each do |key, arr|","path":"lib/formatter/csv/annotation_for_csv.rb","position":94,"original_position":94,"commit_id":"0a8d293ba6f8d7f80a7923898958766cac1ac7e4","original_commit_id":"0a8d293ba6f8d7f80a7923898958766cac1ac7e4","user":{"login":"camallen","id":295329,"avatar_url":"https://avatars.githubusercontent.com/u/295329?v=3","gravatar_id":"","url":"https://api.github.com/users/camallen","html_url":"https://github.com/camallen","followers_url":"https://api.github.com/users/camallen/followers","following_url":"https://api.github.com/users/camallen/following{/other_user}","gists_url":"https://api.github.com/users/camallen/gists{/gist_id}","starred_url":"https://api.github.com/users/camallen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/camallen/subscriptions","organizations_url":"https://api.github.com/users/camallen/orgs","repos_url":"https://api.github.com/users/camallen/repos","events_url":"https://api.github.com/users/camallen/events{/privacy}","received_events_url":"https://api.github.com/users/camallen/received_events","type":"User","site_admin":false},"body":"i'd rather refactor now so we don't just get this merged and forget about it. Also we can test this on a production (replica) / staging db manually if needed.","created_at":"2016-05-17T15:16:40Z","updated_at":"2016-05-17T15:16:40Z","html_url":"https://github.com/zooniverse/Panoptes/pull/1797#discussion_r63541942","pull_request_url":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797","_links":{"self":{"href":"https://api.github.com/repos/zooniverse/Panoptes/pulls/comments/63541942"},"html":{"href":"https://github.com/zooniverse/Panoptes/pull/1797#discussion_r63541942"},"pull_request":{"href":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797"}}},"pull_request":{"url":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797","id":69521410,"html_url":"https://github.com/zooniverse/Panoptes/pull/1797","diff_url":"https://github.com/zooniverse/Panoptes/pull/1797.diff","patch_url":"https://github.com/zooniverse/Panoptes/pull/1797.patch","issue_url":"https://api.github.com/repos/zooniverse/Panoptes/issues/1797","number":1797,"state":"open","locked":false,"title":"CSV export to allow new tasks","user":{"login":"zwolf","id":374835,"avatar_url":"https://avatars.githubusercontent.com/u/374835?v=3","gravatar_id":"","url":"https://api.github.com/users/zwolf","html_url":"https://github.com/zwolf","followers_url":"https://api.github.com/users/zwolf/followers","following_url":"https://api.github.com/users/zwolf/following{/other_user}","gists_url":"https://api.github.com/users/zwolf/gists{/gist_id}","starred_url":"https://api.github.com/users/zwolf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zwolf/subscriptions","organizations_url":"https://api.github.com/users/zwolf/orgs","repos_url":"https://api.github.com/users/zwolf/repos","events_url":"https://api.github.com/users/zwolf/events{/privacy}","received_events_url":"https://api.github.com/users/zwolf/received_events","type":"User","site_admin":false},"body":"In order to allow the more complex Combo and Dropdown tasks to be correctly exported, I did some refactoring of Formatter::Csv::AnnotationForCsv. Hopefully this will make it easier to add new tasks in the future. \r\n\r\n~~This is a Work In Progress PR, and while it should all currently be working, not all the upstream specs are passing, it could be prettier/DRYer, and Hound is going to throw a fit. Please let me know, @marten or @camallen, about changes that you'd like to see. I anticipate there will be many, but I wanted to get this into your hands ASAP.~~\r\n\r\nUpdate: ready to be reviewed.\r\n\r\n# Review checklist\r\n\r\n- [x] First, the most important one: is this PR small enough that you can actually review it? Feel free to just reject a branch if the changes are hard to review due to the length of the diff.\r\n- [x] If there are any migrations, will they the previous version of the app work correctly after they've been run (e.g. the don't remove columns still known about by ActiveRecord).\r\n- [ ] If anything changed with regards to the public API, are those changes also documented in the `apiary.apib` file?\r\n- [x] Are all the changes covered by tests? Think about any possible edge cases that might be left untested.\r\n","created_at":"2016-05-10T14:59:16Z","updated_at":"2016-05-17T15:16:40Z","closed_at":null,"merged_at":null,"merge_commit_sha":"83b7bea72754c8498e81a51666b3674220760b2d","assignee":{"login":"marten","id":277,"avatar_url":"https://avatars.githubusercontent.com/u/277?v=3","gravatar_id":"","url":"https://api.github.com/users/marten","html_url":"https://github.com/marten","followers_url":"https://api.github.com/users/marten/followers","following_url":"https://api.github.com/users/marten/following{/other_user}","gists_url":"https://api.github.com/users/marten/gists{/gist_id}","starred_url":"https://api.github.com/users/marten/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marten/subscriptions","organizations_url":"https://api.github.com/users/marten/orgs","repos_url":"https://api.github.com/users/marten/repos","events_url":"https://api.github.com/users/marten/events{/privacy}","received_events_url":"https://api.github.com/users/marten/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797/commits","review_comments_url":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797/comments","review_comment_url":"https://api.github.com/repos/zooniverse/Panoptes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/zooniverse/Panoptes/issues/1797/comments","statuses_url":"https://api.github.com/repos/zooniverse/Panoptes/statuses/0a8d293ba6f8d7f80a7923898958766cac1ac7e4","head":{"label":"zwolf:new-tasks","ref":"new-tasks","sha":"0a8d293ba6f8d7f80a7923898958766cac1ac7e4","user":{"login":"zwolf","id":374835,"avatar_url":"https://avatars.githubusercontent.com/u/374835?v=3","gravatar_id":"","url":"https://api.github.com/users/zwolf","html_url":"https://github.com/zwolf","followers_url":"https://api.github.com/users/zwolf/followers","following_url":"https://api.github.com/users/zwolf/following{/other_user}","gists_url":"https://api.github.com/users/zwolf/gists{/gist_id}","starred_url":"https://api.github.com/users/zwolf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zwolf/subscriptions","organizations_url":"https://api.github.com/users/zwolf/orgs","repos_url":"https://api.github.com/users/zwolf/repos","events_url":"https://api.github.com/users/zwolf/events{/privacy}","received_events_url":"https://api.github.com/users/zwolf/received_events","type":"User","site_admin":false},"repo":{"id":56798240,"name":"Panoptes","full_name":"zwolf/Panoptes","owner":{"login":"zwolf","id":374835,"avatar_url":"https://avatars.githubusercontent.com/u/374835?v=3","gravatar_id":"","url":"https://api.github.com/users/zwolf","html_url":"https://github.com/zwolf","followers_url":"https://api.github.com/users/zwolf/followers","following_url":"https://api.github.com/users/zwolf/following{/other_user}","gists_url":"https://api.github.com/users/zwolf/gists{/gist_id}","starred_url":"https://api.github.com/users/zwolf/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zwolf/subscriptions","organizations_url":"https://api.github.com/users/zwolf/orgs","repos_url":"https://api.github.com/users/zwolf/repos","events_url":"https://api.github.com/users/zwolf/events{/privacy}","received_events_url":"https://api.github.com/users/zwolf/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/zwolf/Panoptes","description":"It sees everything","fork":true,"url":"https://api.github.com/repos/zwolf/Panoptes","forks_url":"https://api.github.com/repos/zwolf/Panoptes/forks","keys_url":"https://api.github.com/repos/zwolf/Panoptes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zwolf/Panoptes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zwolf/Panoptes/teams","hooks_url":"https://api.github.com/repos/zwolf/Panoptes/hooks","issue_events_url":"https://api.github.com/repos/zwolf/Panoptes/issues/events{/number}","events_url":"https://api.github.com/repos/zwolf/Panoptes/events","assignees_url":"https://api.github.com/repos/zwolf/Panoptes/assignees{/user}","branches_url":"https://api.github.com/repos/zwolf/Panoptes/branches{/branch}","tags_url":"https://api.github.com/repos/zwolf/Panoptes/tags","blobs_url":"https://api.github.com/repos/zwolf/Panoptes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zwolf/Panoptes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zwolf/Panoptes/git/refs{/sha}","trees_url":"https://api.github.com/repos/zwolf/Panoptes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zwolf/Panoptes/statuses/{sha}","languages_url":"https://api.github.com/repos/zwolf/Panoptes/languages","stargazers_url":"https://api.github.com/repos/zwolf/Panoptes/stargazers","contributors_url":"https://api.github.com/repos/zwolf/Panoptes/contributors","subscribers_url":"https://api.github.com/repos/zwolf/Panoptes/subscribers","subscription_url":"https://api.github.com/repos/zwolf/Panoptes/subscription","commits_url":"https://api.github.com/repos/zwolf/Panoptes/commits{/sha}","git_commits_url":"https://api.github.com/repos/zwolf/Panoptes/git/commits{/sha}","comments_url":"https://api.github.com/repos/zwolf/Panoptes/comments{/number}","issue_comment_url":"https://api.github.com/repos/zwolf/Panoptes/issues/comments{/number}","contents_url":"https://api.github.com/repos/zwolf/Panoptes/contents/{+path}","compare_url":"https://api.github.com/repos/zwolf/Panoptes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zwolf/Panoptes/merges","archive_url":"https://api.github.com/repos/zwolf/Panoptes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zwolf/Panoptes/downloads","issues_url":"https://api.github.com/repos/zwolf/Panoptes/issues{/number}","pulls_url":"https://api.github.com/repos/zwolf/Panoptes/pulls{/number}","milestones_url":"https://api.github.com/repos/zwolf/Panoptes/milestones{/number}","notifications_url":"https://api.github.com/repos/zwolf/Panoptes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zwolf/Panoptes/labels{/name}","releases_url":"https://api.github.com/repos/zwolf/Panoptes/releases{/id}","deployments_url":"https://api.github.com/repos/zwolf/Panoptes/deployments","created_at":"2016-04-21T18:54:29Z","updated_at":"2016-04-21T18:54:31Z","pushed_at":"2016-05-17T14:44:16Z","git_url":"git://github.com/zwolf/Panoptes.git","ssh_url":"git@github.com:zwolf/Panoptes.git","clone_url":"https://github.com/zwolf/Panoptes.git","svn_url":"https://github.com/zwolf/Panoptes","homepage":"","size":5511,"stargazers_count":0,"watchers_count":0,"language":"Ruby","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":"zooniverse:master","ref":"master","sha":"0e78970de8fb904919361c4f4a1fb7b83df1f2bf","user":{"login":"zooniverse","id":106856,"avatar_url":"https://avatars.githubusercontent.com/u/106856?v=3","gravatar_id":"","url":"https://api.github.com/users/zooniverse","html_url":"https://github.com/zooniverse","followers_url":"https://api.github.com/users/zooniverse/followers","following_url":"https://api.github.com/users/zooniverse/following{/other_user}","gists_url":"https://api.github.com/users/zooniverse/gists{/gist_id}","starred_url":"https://api.github.com/users/zooniverse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zooniverse/subscriptions","organizations_url":"https://api.github.com/users/zooniverse/orgs","repos_url":"https://api.github.com/users/zooniverse/repos","events_url":"https://api.github.com/users/zooniverse/events{/privacy}","received_events_url":"https://api.github.com/users/zooniverse/received_events","type":"Organization","site_admin":false},"repo":{"id":19036577,"name":"Panoptes","full_name":"zooniverse/Panoptes","owner":{"login":"zooniverse","id":106856,"avatar_url":"https://avatars.githubusercontent.com/u/106856?v=3","gravatar_id":"","url":"https://api.github.com/users/zooniverse","html_url":"https://github.com/zooniverse","followers_url":"https://api.github.com/users/zooniverse/followers","following_url":"https://api.github.com/users/zooniverse/following{/other_user}","gists_url":"https://api.github.com/users/zooniverse/gists{/gist_id}","starred_url":"https://api.github.com/users/zooniverse/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zooniverse/subscriptions","organizations_url":"https://api.github.com/users/zooniverse/orgs","repos_url":"https://api.github.com/users/zooniverse/repos","events_url":"https://api.github.com/users/zooniverse/events{/privacy}","received_events_url":"https://api.github.com/users/zooniverse/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/zooniverse/Panoptes","description":"It sees everything","fork":false,"url":"https://api.github.com/repos/zooniverse/Panoptes","forks_url":"https://api.github.com/repos/zooniverse/Panoptes/forks","keys_url":"https://api.github.com/repos/zooniverse/Panoptes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zooniverse/Panoptes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zooniverse/Panoptes/teams","hooks_url":"https://api.github.com/repos/zooniverse/Panoptes/hooks","issue_events_url":"https://api.github.com/repos/zooniverse/Panoptes/issues/events{/number}","events_url":"https://api.github.com/repos/zooniverse/Panoptes/events","assignees_url":"https://api.github.com/repos/zooniverse/Panoptes/assignees{/user}","branches_url":"https://api.github.com/repos/zooniverse/Panoptes/branches{/branch}","tags_url":"https://api.github.com/repos/zooniverse/Panoptes/tags","blobs_url":"https://api.github.com/repos/zooniverse/Panoptes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zooniverse/Panoptes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zooniverse/Panoptes/git/refs{/sha}","trees_url":"https://api.github.com/repos/zooniverse/Panoptes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zooniverse/Panoptes/statuses/{sha}","languages_url":"https://api.github.com/repos/zooniverse/Panoptes/languages","stargazers_url":"https://api.github.com/repos/zooniverse/Panoptes/stargazers","contributors_url":"https://api.github.com/repos/zooniverse/Panoptes/contributors","subscribers_url":"https://api.github.com/repos/zooniverse/Panoptes/subscribers","subscription_url":"https://api.github.com/repos/zooniverse/Panoptes/subscription","commits_url":"https://api.github.com/repos/zooniverse/Panoptes/commits{/sha}","git_commits_url":"https://api.github.com/repos/zooniverse/Panoptes/git/commits{/sha}","comments_url":"https://api.github.com/repos/zooniverse/Panoptes/comments{/number}","issue_comment_url":"https://api.github.com/repos/zooniverse/Panoptes/issues/comments{/number}","contents_url":"https://api.github.com/repos/zooniverse/Panoptes/contents/{+path}","compare_url":"https://api.github.com/repos/zooniverse/Panoptes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zooniverse/Panoptes/merges","archive_url":"https://api.github.com/repos/zooniverse/Panoptes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zooniverse/Panoptes/downloads","issues_url":"https://api.github.com/repos/zooniverse/Panoptes/issues{/number}","pulls_url":"https://api.github.com/repos/zooniverse/Panoptes/pulls{/number}","milestones_url":"https://api.github.com/repos/zooniverse/Panoptes/milestones{/number}","notifications_url":"https://api.github.com/repos/zooniverse/Panoptes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zooniverse/Panoptes/labels{/name}","releases_url":"https://api.github.com/repos/zooniverse/Panoptes/releases{/id}","deployments_url":"https://api.github.com/repos/zooniverse/Panoptes/deployments","created_at":"2014-04-22T16:16:02Z","updated_at":"2016-05-05T18:05:23Z","pushed_at":"2016-05-17T15:14:48Z","git_url":"git://github.com/zooniverse/Panoptes.git","ssh_url":"git@github.com:zooniverse/Panoptes.git","clone_url":"https://github.com/zooniverse/Panoptes.git","svn_url":"https://github.com/zooniverse/Panoptes","homepage":"","size":5809,"stargazers_count":44,"watchers_count":44,"language":"Ruby","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":22,"mirror_url":null,"open_issues_count":96,"forks":22,"open_issues":96,"watchers":44,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797"},"html":{"href":"https://github.com/zooniverse/Panoptes/pull/1797"},"issue":{"href":"https://api.github.com/repos/zooniverse/Panoptes/issues/1797"},"comments":{"href":"https://api.github.com/repos/zooniverse/Panoptes/issues/1797/comments"},"review_comments":{"href":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797/comments"},"review_comment":{"href":"https://api.github.com/repos/zooniverse/Panoptes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/zooniverse/Panoptes/pulls/1797/commits"},"statuses":{"href":"https://api.github.com/repos/zooniverse/Panoptes/statuses/0a8d293ba6f8d7f80a7923898958766cac1ac7e4"}}}}