{"action":"created","comment":{"url":"https://api.github.com/repos/swcarpentry/amy/pulls/comments/22759114","id":22759114,"diff_hunk":"@@ -136,6 +140,58 @@ def person_details(request, person_id):\n     return render(request, 'workshops/person.html', context)\n \n \n+def person_bulk_add(request):\n+    if request.method == 'POST':\n+        form = PersonBulkAddForm(request.POST, request.FILES)\n+        if form.is_valid():\n+            try:\n+                persons_tasks = _upload_person_task_csv(request, request.FILES['file'])\n+            except csv.Error as e:\n+                messages.add_message(request, messages.ERROR, \"Error processing uploaded .CSV file: {}\".format(e))\n+            else:\n+                for entry in persons_tasks:","path":"workshops/views.py","position":45,"original_position":45,"commit_id":"57c9dc5aac43a6dcae8e70dfe5b2806867e1642e","original_commit_id":"57c9dc5aac43a6dcae8e70dfe5b2806867e1642e","user":{"login":"gvwilson","id":911566,"avatar_url":"https://avatars.githubusercontent.com/u/911566?v=3","gravatar_id":"","url":"https://api.github.com/users/gvwilson","html_url":"https://github.com/gvwilson","followers_url":"https://api.github.com/users/gvwilson/followers","following_url":"https://api.github.com/users/gvwilson/following{/other_user}","gists_url":"https://api.github.com/users/gvwilson/gists{/gist_id}","starred_url":"https://api.github.com/users/gvwilson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gvwilson/subscriptions","organizations_url":"https://api.github.com/users/gvwilson/orgs","repos_url":"https://api.github.com/users/gvwilson/repos","events_url":"https://api.github.com/users/gvwilson/events{/privacy}","received_events_url":"https://api.github.com/users/gvwilson/received_events","type":"User","site_admin":false},"body":"There should definitely be a transaction here, and adding People and \nTask records to the DB should only happen after they've been validated \nand the user has pressed 'yes' on the confirmation form.","created_at":"2015-01-10T14:01:12Z","updated_at":"2015-01-10T14:01:12Z","html_url":"https://github.com/swcarpentry/amy/pull/131#discussion_r22759114","pull_request_url":"https://api.github.com/repos/swcarpentry/amy/pulls/131","_links":{"self":{"href":"https://api.github.com/repos/swcarpentry/amy/pulls/comments/22759114"},"html":{"href":"https://github.com/swcarpentry/amy/pull/131#discussion_r22759114"},"pull_request":{"href":"https://api.github.com/repos/swcarpentry/amy/pulls/131"}}},"pull_request":{"url":"https://api.github.com/repos/swcarpentry/amy/pulls/131","id":27140264,"html_url":"https://github.com/swcarpentry/amy/pull/131","diff_url":"https://github.com/swcarpentry/amy/pull/131.diff","patch_url":"https://github.com/swcarpentry/amy/pull/131.patch","issue_url":"https://api.github.com/repos/swcarpentry/amy/issues/131","number":131,"state":"open","locked":false,"title":"Bulk addition of people from CSV files","user":{"login":"gvwilson","id":911566,"avatar_url":"https://avatars.githubusercontent.com/u/911566?v=3","gravatar_id":"","url":"https://api.github.com/users/gvwilson","html_url":"https://github.com/gvwilson","followers_url":"https://api.github.com/users/gvwilson/followers","following_url":"https://api.github.com/users/gvwilson/following{/other_user}","gists_url":"https://api.github.com/users/gvwilson/gists{/gist_id}","starred_url":"https://api.github.com/users/gvwilson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gvwilson/subscriptions","organizations_url":"https://api.github.com/users/gvwilson/orgs","repos_url":"https://api.github.com/users/gvwilson/repos","events_url":"https://api.github.com/users/gvwilson/events{/privacy}","received_events_url":"https://api.github.com/users/gvwilson/received_events","type":"User","site_admin":false},"body":"This incorporates @cudevmaxwell's work in #106 in order to fix #27:\r\n\r\n1.  Form for uploading CSV files containing people (and tasks) from workshops.\r\n2.  Some test data (but no unit tests as yet - those need to be added).\r\n3.  Some lessons learned about Django's ORM.","created_at":"2015-01-10T00:38:01Z","updated_at":"2015-01-10T14:01:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"b72e94355258d8dfefbe4cbc52bd30e78fcc24e0","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/swcarpentry/amy/pulls/131/commits","review_comments_url":"https://api.github.com/repos/swcarpentry/amy/pulls/131/comments","review_comment_url":"https://api.github.com/repos/swcarpentry/amy/pulls/comments/{number}","comments_url":"https://api.github.com/repos/swcarpentry/amy/issues/131/comments","statuses_url":"https://api.github.com/repos/swcarpentry/amy/statuses/57c9dc5aac43a6dcae8e70dfe5b2806867e1642e","head":{"label":"gvwilson:27-csv-bulk-add-people","ref":"27-csv-bulk-add-people","sha":"57c9dc5aac43a6dcae8e70dfe5b2806867e1642e","user":{"login":"gvwilson","id":911566,"avatar_url":"https://avatars.githubusercontent.com/u/911566?v=3","gravatar_id":"","url":"https://api.github.com/users/gvwilson","html_url":"https://github.com/gvwilson","followers_url":"https://api.github.com/users/gvwilson/followers","following_url":"https://api.github.com/users/gvwilson/following{/other_user}","gists_url":"https://api.github.com/users/gvwilson/gists{/gist_id}","starred_url":"https://api.github.com/users/gvwilson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gvwilson/subscriptions","organizations_url":"https://api.github.com/users/gvwilson/orgs","repos_url":"https://api.github.com/users/gvwilson/repos","events_url":"https://api.github.com/users/gvwilson/events{/privacy}","received_events_url":"https://api.github.com/users/gvwilson/received_events","type":"User","site_admin":false},"repo":{"id":27387341,"name":"amy","full_name":"gvwilson/amy","owner":{"login":"gvwilson","id":911566,"avatar_url":"https://avatars.githubusercontent.com/u/911566?v=3","gravatar_id":"","url":"https://api.github.com/users/gvwilson","html_url":"https://github.com/gvwilson","followers_url":"https://api.github.com/users/gvwilson/followers","following_url":"https://api.github.com/users/gvwilson/following{/other_user}","gists_url":"https://api.github.com/users/gvwilson/gists{/gist_id}","starred_url":"https://api.github.com/users/gvwilson/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gvwilson/subscriptions","organizations_url":"https://api.github.com/users/gvwilson/orgs","repos_url":"https://api.github.com/users/gvwilson/repos","events_url":"https://api.github.com/users/gvwilson/events{/privacy}","received_events_url":"https://api.github.com/users/gvwilson/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/gvwilson/amy","description":"A web-based workshop administration application built using Django.","fork":true,"url":"https://api.github.com/repos/gvwilson/amy","forks_url":"https://api.github.com/repos/gvwilson/amy/forks","keys_url":"https://api.github.com/repos/gvwilson/amy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/gvwilson/amy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/gvwilson/amy/teams","hooks_url":"https://api.github.com/repos/gvwilson/amy/hooks","issue_events_url":"https://api.github.com/repos/gvwilson/amy/issues/events{/number}","events_url":"https://api.github.com/repos/gvwilson/amy/events","assignees_url":"https://api.github.com/repos/gvwilson/amy/assignees{/user}","branches_url":"https://api.github.com/repos/gvwilson/amy/branches{/branch}","tags_url":"https://api.github.com/repos/gvwilson/amy/tags","blobs_url":"https://api.github.com/repos/gvwilson/amy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/gvwilson/amy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/gvwilson/amy/git/refs{/sha}","trees_url":"https://api.github.com/repos/gvwilson/amy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/gvwilson/amy/statuses/{sha}","languages_url":"https://api.github.com/repos/gvwilson/amy/languages","stargazers_url":"https://api.github.com/repos/gvwilson/amy/stargazers","contributors_url":"https://api.github.com/repos/gvwilson/amy/contributors","subscribers_url":"https://api.github.com/repos/gvwilson/amy/subscribers","subscription_url":"https://api.github.com/repos/gvwilson/amy/subscription","commits_url":"https://api.github.com/repos/gvwilson/amy/commits{/sha}","git_commits_url":"https://api.github.com/repos/gvwilson/amy/git/commits{/sha}","comments_url":"https://api.github.com/repos/gvwilson/amy/comments{/number}","issue_comment_url":"https://api.github.com/repos/gvwilson/amy/issues/comments/{number}","contents_url":"https://api.github.com/repos/gvwilson/amy/contents/{+path}","compare_url":"https://api.github.com/repos/gvwilson/amy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/gvwilson/amy/merges","archive_url":"https://api.github.com/repos/gvwilson/amy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/gvwilson/amy/downloads","issues_url":"https://api.github.com/repos/gvwilson/amy/issues{/number}","pulls_url":"https://api.github.com/repos/gvwilson/amy/pulls{/number}","milestones_url":"https://api.github.com/repos/gvwilson/amy/milestones{/number}","notifications_url":"https://api.github.com/repos/gvwilson/amy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/gvwilson/amy/labels{/name}","releases_url":"https://api.github.com/repos/gvwilson/amy/releases{/id}","created_at":"2014-12-01T16:08:33Z","updated_at":"2015-01-07T06:03:43Z","pushed_at":"2015-01-10T00:36:09Z","git_url":"git://github.com/gvwilson/amy.git","ssh_url":"git@github.com:gvwilson/amy.git","clone_url":"https://github.com/gvwilson/amy.git","svn_url":"https://github.com/gvwilson/amy","homepage":null,"size":3567,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"swcarpentry:master","ref":"master","sha":"6ea64aa03099b81f1ba1b8becd8263a10b63d72b","user":{"login":"swcarpentry","id":2238358,"avatar_url":"https://avatars.githubusercontent.com/u/2238358?v=3","gravatar_id":"","url":"https://api.github.com/users/swcarpentry","html_url":"https://github.com/swcarpentry","followers_url":"https://api.github.com/users/swcarpentry/followers","following_url":"https://api.github.com/users/swcarpentry/following{/other_user}","gists_url":"https://api.github.com/users/swcarpentry/gists{/gist_id}","starred_url":"https://api.github.com/users/swcarpentry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swcarpentry/subscriptions","organizations_url":"https://api.github.com/users/swcarpentry/orgs","repos_url":"https://api.github.com/users/swcarpentry/repos","events_url":"https://api.github.com/users/swcarpentry/events{/privacy}","received_events_url":"https://api.github.com/users/swcarpentry/received_events","type":"Organization","site_admin":false},"repo":{"id":27387287,"name":"amy","full_name":"swcarpentry/amy","owner":{"login":"swcarpentry","id":2238358,"avatar_url":"https://avatars.githubusercontent.com/u/2238358?v=3","gravatar_id":"","url":"https://api.github.com/users/swcarpentry","html_url":"https://github.com/swcarpentry","followers_url":"https://api.github.com/users/swcarpentry/followers","following_url":"https://api.github.com/users/swcarpentry/following{/other_user}","gists_url":"https://api.github.com/users/swcarpentry/gists{/gist_id}","starred_url":"https://api.github.com/users/swcarpentry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/swcarpentry/subscriptions","organizations_url":"https://api.github.com/users/swcarpentry/orgs","repos_url":"https://api.github.com/users/swcarpentry/repos","events_url":"https://api.github.com/users/swcarpentry/events{/privacy}","received_events_url":"https://api.github.com/users/swcarpentry/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/swcarpentry/amy","description":"A web-based workshop administration application built using Django.","fork":false,"url":"https://api.github.com/repos/swcarpentry/amy","forks_url":"https://api.github.com/repos/swcarpentry/amy/forks","keys_url":"https://api.github.com/repos/swcarpentry/amy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/swcarpentry/amy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/swcarpentry/amy/teams","hooks_url":"https://api.github.com/repos/swcarpentry/amy/hooks","issue_events_url":"https://api.github.com/repos/swcarpentry/amy/issues/events{/number}","events_url":"https://api.github.com/repos/swcarpentry/amy/events","assignees_url":"https://api.github.com/repos/swcarpentry/amy/assignees{/user}","branches_url":"https://api.github.com/repos/swcarpentry/amy/branches{/branch}","tags_url":"https://api.github.com/repos/swcarpentry/amy/tags","blobs_url":"https://api.github.com/repos/swcarpentry/amy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/swcarpentry/amy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/swcarpentry/amy/git/refs{/sha}","trees_url":"https://api.github.com/repos/swcarpentry/amy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/swcarpentry/amy/statuses/{sha}","languages_url":"https://api.github.com/repos/swcarpentry/amy/languages","stargazers_url":"https://api.github.com/repos/swcarpentry/amy/stargazers","contributors_url":"https://api.github.com/repos/swcarpentry/amy/contributors","subscribers_url":"https://api.github.com/repos/swcarpentry/amy/subscribers","subscription_url":"https://api.github.com/repos/swcarpentry/amy/subscription","commits_url":"https://api.github.com/repos/swcarpentry/amy/commits{/sha}","git_commits_url":"https://api.github.com/repos/swcarpentry/amy/git/commits{/sha}","comments_url":"https://api.github.com/repos/swcarpentry/amy/comments{/number}","issue_comment_url":"https://api.github.com/repos/swcarpentry/amy/issues/comments/{number}","contents_url":"https://api.github.com/repos/swcarpentry/amy/contents/{+path}","compare_url":"https://api.github.com/repos/swcarpentry/amy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/swcarpentry/amy/merges","archive_url":"https://api.github.com/repos/swcarpentry/amy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/swcarpentry/amy/downloads","issues_url":"https://api.github.com/repos/swcarpentry/amy/issues{/number}","pulls_url":"https://api.github.com/repos/swcarpentry/amy/pulls{/number}","milestones_url":"https://api.github.com/repos/swcarpentry/amy/milestones{/number}","notifications_url":"https://api.github.com/repos/swcarpentry/amy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/swcarpentry/amy/labels{/name}","releases_url":"https://api.github.com/repos/swcarpentry/amy/releases{/id}","created_at":"2014-12-01T16:07:14Z","updated_at":"2015-01-09T04:48:17Z","pushed_at":"2015-01-09T04:48:17Z","git_url":"git://github.com/swcarpentry/amy.git","ssh_url":"git@github.com:swcarpentry/amy.git","clone_url":"https://github.com/swcarpentry/amy.git","svn_url":"https://github.com/swcarpentry/amy","homepage":null,"size":4200,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":20,"mirror_url":null,"open_issues_count":38,"forks":20,"open_issues":38,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/swcarpentry/amy/pulls/131"},"html":{"href":"https://github.com/swcarpentry/amy/pull/131"},"issue":{"href":"https://api.github.com/repos/swcarpentry/amy/issues/131"},"comments":{"href":"https://api.github.com/repos/swcarpentry/amy/issues/131/comments"},"review_comments":{"href":"https://api.github.com/repos/swcarpentry/amy/pulls/131/comments"},"review_comment":{"href":"https://api.github.com/repos/swcarpentry/amy/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/swcarpentry/amy/pulls/131/commits"},"statuses":{"href":"https://api.github.com/repos/swcarpentry/amy/statuses/57c9dc5aac43a6dcae8e70dfe5b2806867e1642e"}}}}