{"action":"created","comment":{"url":"https://api.github.com/repos/AuburnACM/auacm/pulls/comments/49780334","id":49780334,"diff_hunk":"@@ -181,3 +202,149 @@ def get_competition_data(cid):\n         'compProblems': comp_problems,\n         'teams': scoreboard\n     })\n+\n+\n+@app.route('/api/competitions/<int:cid>/register', methods=['POST'])\n+@login_required\n+def register_for_competition(cid):\n+    \"\"\" Called when a user wants to register for a competition.\n+\n+    All the user has to do is submit a post to this url with no form data.\n+    From their logged-in status, we'll go ahead and add them to the competiton\n+    as an individual (team name is default their display name). A 400 error will\n+    be returned if the user is already registered for the competition.\n+\n+    If the user that is submitting this is an admin, they can optionally\n+    supply a json array of usernames to register for the competition. Specifying\n+    this will not register the admin, but it will register all users that are\n+    listed. A 400 error will be returned if any of the users are already\n+    registered for the competition.\n+    \"\"\"\n+    if session.query(Competition).filter(Competition.cid == cid).first() \\\n+            is None:\n+        return serve_error('Competition does not exist', response_code=404)\n+\n+    if current_user.admin == 1 and 'users' in request.data:\n+        registrants = loads(request.data['users'])\n+    else:\n+        registrants = list()\n+        registrants.append(current_user.username)\n+\n+    for user in registrants:\n+        if session.query(CompUser).filter(CompUser.cid == cid,\n+            CompUser.username == user).first() is not None:\n+            return serve_error('User ' + user + ' already registered for '\n+                    'competition', response_code=400)\n+\n+    for username in registrants:\n+        user = session.query(User).filter(User.username == user).first()\n+        session.add(CompUser(\n+            cid=cid,\n+            username=user.username,\n+            team=user.display\n+        ))\n+        socketio.emit('new_user', {\n+            'cid': cid,\n+            'user': {\n+                'display': user.display,\n+                'username': user.username\n+            }\n+        },\n+        namespace='/register')\n+    session.flush()\n+    session.commit()\n+\n+    return serve_response({})\n+\n+\n+@app.route('/api/competitions/<int:cid>/unregister', methods=['POST'])\n+@login_required\n+def unregister_for_competition(cid):\n+    \"\"\" Called when a user wants to register for a competition.\n+\n+    All the user has to do is submit a post to this url with no form data.\n+    From their logged-in status, we'll go ahead and remove them from the\n+    competiton.\n+\n+    Similar to the <code>/register</code> endpoint, an admin can post a list of\n+    users to unregister from the competition.\n+    \"\"\"\n+    if session.query(Competition).filter(Competition.cid == cid).first() \\\n+            is None:\n+        return serve_error('Competition does not exist', response_code=404)\n+\n+    if current_user.admin == 1 and 'users' in request.data:\n+        registrants = loads(request.data['users'])\n+    else:\n+        registrants = list()\n+        registrants.append(current_user.username)\n+\n+    for user in registrants:\n+        (session.query(CompUser)\n+                .filter(CompUser.username == user, CompUser.cid == cid)\n+                .delete())\n+    session.flush()\n+    session.commit()\n+\n+    return serve_response({})\n+\n+\n+@app.route('/api/competitions/<int:cid>/teams', methods=['GET'])\n+@login_required\n+def get_competition_teams(cid):\n+    \"\"\" Get all of the teams in a competition.\n+\n+    Returns all of the teams, their users, and those users' display names.\n+    \"\"\"\n+    comp_users = session.query(CompUser, User).join(User,\n+            User.username == CompUser.username).filter(CompUser.cid == cid)\\\n+            .all()\n+\n+    teams = dict()\n+    for user in comp_users:\n+        if user.CompUser.team not in teams:\n+            teams[user.CompUser.team] = list()\n+        teams[user.CompUser.team].append({\n+            'username': user.User.username,\n+            'display': user.User.display\n+        })\n+\n+    return serve_response(teams)\n+\n+\n+@app.route('/api/competitions/<int:cid>/teams', methods=['PUT'])\n+@login_required\n+def put_competition_teams(cid):\n+    \"\"\" Update the teams for a competition\n+\n+    If a user is an admin, they can update the competition's users, doing a PUT.\n+    This will take the JSON data in the 'teams' part of the request form and\n+    store it to the database. Any teams or users not included int the JSON data\n+    will not be a part of the competition and will have to re-register; however\n+    it should not be used for the solely purpose of de-registering participants.\n+    \"\"\"\n+    if current_user.admin == 0:\n+        return serve_error('You must be an admin to update teams',\n+                response_code=401)\n+\n+    try:\n+        teams = loads(request.form['teams'])\n+    except KeyError as err:","path":"auacm/app/modules/competition_manager/views.py","position":223,"original_position":201,"commit_id":"0dea053388f2125c6b9fc4a250ce8386d689870f","original_commit_id":"b78f5b76946a2ea56c65d44de141b42d36db7236","user":{"login":"WilliamHester","id":933429,"avatar_url":"https://avatars.githubusercontent.com/u/933429?v=3","gravatar_id":"","url":"https://api.github.com/users/WilliamHester","html_url":"https://github.com/WilliamHester","followers_url":"https://api.github.com/users/WilliamHester/followers","following_url":"https://api.github.com/users/WilliamHester/following{/other_user}","gists_url":"https://api.github.com/users/WilliamHester/gists{/gist_id}","starred_url":"https://api.github.com/users/WilliamHester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WilliamHester/subscriptions","organizations_url":"https://api.github.com/users/WilliamHester/orgs","repos_url":"https://api.github.com/users/WilliamHester/repos","events_url":"https://api.github.com/users/WilliamHester/events{/privacy}","received_events_url":"https://api.github.com/users/WilliamHester/received_events","type":"User","site_admin":false},"body":"Done. I went ahead and added this check everywhere in this file where we used `loads()`.","created_at":"2016-01-14T20:26:30Z","updated_at":"2016-01-14T20:26:30Z","html_url":"https://github.com/AuburnACM/auacm/pull/54#discussion_r49780334","pull_request_url":"https://api.github.com/repos/AuburnACM/auacm/pulls/54","_links":{"self":{"href":"https://api.github.com/repos/AuburnACM/auacm/pulls/comments/49780334"},"html":{"href":"https://github.com/AuburnACM/auacm/pull/54#discussion_r49780334"},"pull_request":{"href":"https://api.github.com/repos/AuburnACM/auacm/pulls/54"}}},"pull_request":{"url":"https://api.github.com/repos/AuburnACM/auacm/pulls/54","id":54912358,"html_url":"https://github.com/AuburnACM/auacm/pull/54","diff_url":"https://github.com/AuburnACM/auacm/pull/54.diff","patch_url":"https://github.com/AuburnACM/auacm/pull/54.patch","issue_url":"https://api.github.com/repos/AuburnACM/auacm/issues/54","number":54,"state":"open","locked":false,"title":"Competition teams","user":{"login":"WilliamHester","id":933429,"avatar_url":"https://avatars.githubusercontent.com/u/933429?v=3","gravatar_id":"","url":"https://api.github.com/users/WilliamHester","html_url":"https://github.com/WilliamHester","followers_url":"https://api.github.com/users/WilliamHester/followers","following_url":"https://api.github.com/users/WilliamHester/following{/other_user}","gists_url":"https://api.github.com/users/WilliamHester/gists{/gist_id}","starred_url":"https://api.github.com/users/WilliamHester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WilliamHester/subscriptions","organizations_url":"https://api.github.com/users/WilliamHester/orgs","repos_url":"https://api.github.com/users/WilliamHester/repos","events_url":"https://api.github.com/users/WilliamHester/events{/privacy}","received_events_url":"https://api.github.com/users/WilliamHester/received_events","type":"User","site_admin":false},"body":"Allows creation/modification of teams for competitions. Fixes #24 and fixes #25 when combined with #49.  Merge #49 first, as this is based off of that.","created_at":"2016-01-02T20:51:07Z","updated_at":"2016-01-14T20:26:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"66898789d352b1045eed30b83374bb72238192ce","assignee":{"login":"BrandonLMorris","id":7709128,"avatar_url":"https://avatars.githubusercontent.com/u/7709128?v=3","gravatar_id":"","url":"https://api.github.com/users/BrandonLMorris","html_url":"https://github.com/BrandonLMorris","followers_url":"https://api.github.com/users/BrandonLMorris/followers","following_url":"https://api.github.com/users/BrandonLMorris/following{/other_user}","gists_url":"https://api.github.com/users/BrandonLMorris/gists{/gist_id}","starred_url":"https://api.github.com/users/BrandonLMorris/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/BrandonLMorris/subscriptions","organizations_url":"https://api.github.com/users/BrandonLMorris/orgs","repos_url":"https://api.github.com/users/BrandonLMorris/repos","events_url":"https://api.github.com/users/BrandonLMorris/events{/privacy}","received_events_url":"https://api.github.com/users/BrandonLMorris/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/AuburnACM/auacm/milestones/2","html_url":"https://github.com/AuburnACM/auacm/milestones/beta","labels_url":"https://api.github.com/repos/AuburnACM/auacm/milestones/2/labels","id":1431417,"number":2,"title":"beta","description":"For beta, all systems should be **mostly** working. Users should be able to perform basic functions and admins should be able to create problems and competitions.","creator":{"login":"WilliamHester","id":933429,"avatar_url":"https://avatars.githubusercontent.com/u/933429?v=3","gravatar_id":"","url":"https://api.github.com/users/WilliamHester","html_url":"https://github.com/WilliamHester","followers_url":"https://api.github.com/users/WilliamHester/followers","following_url":"https://api.github.com/users/WilliamHester/following{/other_user}","gists_url":"https://api.github.com/users/WilliamHester/gists{/gist_id}","starred_url":"https://api.github.com/users/WilliamHester/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WilliamHester/subscriptions","organizations_url":"https://api.github.com/users/WilliamHester/orgs","repos_url":"https://api.github.com/users/WilliamHester/repos","events_url":"https://api.github.com/users/WilliamHester/events{/privacy}","received_events_url":"https://api.github.com/users/WilliamHester/received_events","type":"User","site_admin":false},"open_issues":3,"closed_issues":4,"state":"open","created_at":"2015-11-26T16:32:56Z","updated_at":"2016-01-03T03:15:28Z","due_on":"2015-12-26T06:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/AuburnACM/auacm/pulls/54/commits","review_comments_url":"https://api.github.com/repos/AuburnACM/auacm/pulls/54/comments","review_comment_url":"https://api.github.com/repos/AuburnACM/auacm/pulls/comments{/number}","comments_url":"https://api.github.com/repos/AuburnACM/auacm/issues/54/comments","statuses_url":"https://api.github.com/repos/AuburnACM/auacm/statuses/0dea053388f2125c6b9fc4a250ce8386d689870f","head":{"label":"AuburnACM:competition-teams","ref":"competition-teams","sha":"0dea053388f2125c6b9fc4a250ce8386d689870f","user":{"login":"AuburnACM","id":13837893,"avatar_url":"https://avatars.githubusercontent.com/u/13837893?v=3","gravatar_id":"","url":"https://api.github.com/users/AuburnACM","html_url":"https://github.com/AuburnACM","followers_url":"https://api.github.com/users/AuburnACM/followers","following_url":"https://api.github.com/users/AuburnACM/following{/other_user}","gists_url":"https://api.github.com/users/AuburnACM/gists{/gist_id}","starred_url":"https://api.github.com/users/AuburnACM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AuburnACM/subscriptions","organizations_url":"https://api.github.com/users/AuburnACM/orgs","repos_url":"https://api.github.com/users/AuburnACM/repos","events_url":"https://api.github.com/users/AuburnACM/events{/privacy}","received_events_url":"https://api.github.com/users/AuburnACM/received_events","type":"Organization","site_admin":false},"repo":{"id":41262723,"name":"auacm","full_name":"AuburnACM/auacm","owner":{"login":"AuburnACM","id":13837893,"avatar_url":"https://avatars.githubusercontent.com/u/13837893?v=3","gravatar_id":"","url":"https://api.github.com/users/AuburnACM","html_url":"https://github.com/AuburnACM","followers_url":"https://api.github.com/users/AuburnACM/followers","following_url":"https://api.github.com/users/AuburnACM/following{/other_user}","gists_url":"https://api.github.com/users/AuburnACM/gists{/gist_id}","starred_url":"https://api.github.com/users/AuburnACM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AuburnACM/subscriptions","organizations_url":"https://api.github.com/users/AuburnACM/orgs","repos_url":"https://api.github.com/users/AuburnACM/repos","events_url":"https://api.github.com/users/AuburnACM/events{/privacy}","received_events_url":"https://api.github.com/users/AuburnACM/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/AuburnACM/auacm","description":"The Auburn ACM Website","fork":false,"url":"https://api.github.com/repos/AuburnACM/auacm","forks_url":"https://api.github.com/repos/AuburnACM/auacm/forks","keys_url":"https://api.github.com/repos/AuburnACM/auacm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/AuburnACM/auacm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/AuburnACM/auacm/teams","hooks_url":"https://api.github.com/repos/AuburnACM/auacm/hooks","issue_events_url":"https://api.github.com/repos/AuburnACM/auacm/issues/events{/number}","events_url":"https://api.github.com/repos/AuburnACM/auacm/events","assignees_url":"https://api.github.com/repos/AuburnACM/auacm/assignees{/user}","branches_url":"https://api.github.com/repos/AuburnACM/auacm/branches{/branch}","tags_url":"https://api.github.com/repos/AuburnACM/auacm/tags","blobs_url":"https://api.github.com/repos/AuburnACM/auacm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/AuburnACM/auacm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/AuburnACM/auacm/git/refs{/sha}","trees_url":"https://api.github.com/repos/AuburnACM/auacm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/AuburnACM/auacm/statuses/{sha}","languages_url":"https://api.github.com/repos/AuburnACM/auacm/languages","stargazers_url":"https://api.github.com/repos/AuburnACM/auacm/stargazers","contributors_url":"https://api.github.com/repos/AuburnACM/auacm/contributors","subscribers_url":"https://api.github.com/repos/AuburnACM/auacm/subscribers","subscription_url":"https://api.github.com/repos/AuburnACM/auacm/subscription","commits_url":"https://api.github.com/repos/AuburnACM/auacm/commits{/sha}","git_commits_url":"https://api.github.com/repos/AuburnACM/auacm/git/commits{/sha}","comments_url":"https://api.github.com/repos/AuburnACM/auacm/comments{/number}","issue_comment_url":"https://api.github.com/repos/AuburnACM/auacm/issues/comments{/number}","contents_url":"https://api.github.com/repos/AuburnACM/auacm/contents/{+path}","compare_url":"https://api.github.com/repos/AuburnACM/auacm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/AuburnACM/auacm/merges","archive_url":"https://api.github.com/repos/AuburnACM/auacm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/AuburnACM/auacm/downloads","issues_url":"https://api.github.com/repos/AuburnACM/auacm/issues{/number}","pulls_url":"https://api.github.com/repos/AuburnACM/auacm/pulls{/number}","milestones_url":"https://api.github.com/repos/AuburnACM/auacm/milestones{/number}","notifications_url":"https://api.github.com/repos/AuburnACM/auacm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/AuburnACM/auacm/labels{/name}","releases_url":"https://api.github.com/repos/AuburnACM/auacm/releases{/id}","created_at":"2015-08-23T18:56:47Z","updated_at":"2015-12-08T22:42:31Z","pushed_at":"2016-01-14T20:24:57Z","git_url":"git://github.com/AuburnACM/auacm.git","ssh_url":"git@github.com:AuburnACM/auacm.git","clone_url":"https://github.com/AuburnACM/auacm.git","svn_url":"https://github.com/AuburnACM/auacm","homepage":"","size":6881,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":30,"forks":3,"open_issues":30,"watchers":6,"default_branch":"master"}},"base":{"label":"AuburnACM:master","ref":"master","sha":"f702ba8dd7cda5d3989f492770c19b0598610dba","user":{"login":"AuburnACM","id":13837893,"avatar_url":"https://avatars.githubusercontent.com/u/13837893?v=3","gravatar_id":"","url":"https://api.github.com/users/AuburnACM","html_url":"https://github.com/AuburnACM","followers_url":"https://api.github.com/users/AuburnACM/followers","following_url":"https://api.github.com/users/AuburnACM/following{/other_user}","gists_url":"https://api.github.com/users/AuburnACM/gists{/gist_id}","starred_url":"https://api.github.com/users/AuburnACM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AuburnACM/subscriptions","organizations_url":"https://api.github.com/users/AuburnACM/orgs","repos_url":"https://api.github.com/users/AuburnACM/repos","events_url":"https://api.github.com/users/AuburnACM/events{/privacy}","received_events_url":"https://api.github.com/users/AuburnACM/received_events","type":"Organization","site_admin":false},"repo":{"id":41262723,"name":"auacm","full_name":"AuburnACM/auacm","owner":{"login":"AuburnACM","id":13837893,"avatar_url":"https://avatars.githubusercontent.com/u/13837893?v=3","gravatar_id":"","url":"https://api.github.com/users/AuburnACM","html_url":"https://github.com/AuburnACM","followers_url":"https://api.github.com/users/AuburnACM/followers","following_url":"https://api.github.com/users/AuburnACM/following{/other_user}","gists_url":"https://api.github.com/users/AuburnACM/gists{/gist_id}","starred_url":"https://api.github.com/users/AuburnACM/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/AuburnACM/subscriptions","organizations_url":"https://api.github.com/users/AuburnACM/orgs","repos_url":"https://api.github.com/users/AuburnACM/repos","events_url":"https://api.github.com/users/AuburnACM/events{/privacy}","received_events_url":"https://api.github.com/users/AuburnACM/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/AuburnACM/auacm","description":"The Auburn ACM Website","fork":false,"url":"https://api.github.com/repos/AuburnACM/auacm","forks_url":"https://api.github.com/repos/AuburnACM/auacm/forks","keys_url":"https://api.github.com/repos/AuburnACM/auacm/keys{/key_id}","collaborators_url":"https://api.github.com/repos/AuburnACM/auacm/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/AuburnACM/auacm/teams","hooks_url":"https://api.github.com/repos/AuburnACM/auacm/hooks","issue_events_url":"https://api.github.com/repos/AuburnACM/auacm/issues/events{/number}","events_url":"https://api.github.com/repos/AuburnACM/auacm/events","assignees_url":"https://api.github.com/repos/AuburnACM/auacm/assignees{/user}","branches_url":"https://api.github.com/repos/AuburnACM/auacm/branches{/branch}","tags_url":"https://api.github.com/repos/AuburnACM/auacm/tags","blobs_url":"https://api.github.com/repos/AuburnACM/auacm/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/AuburnACM/auacm/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/AuburnACM/auacm/git/refs{/sha}","trees_url":"https://api.github.com/repos/AuburnACM/auacm/git/trees{/sha}","statuses_url":"https://api.github.com/repos/AuburnACM/auacm/statuses/{sha}","languages_url":"https://api.github.com/repos/AuburnACM/auacm/languages","stargazers_url":"https://api.github.com/repos/AuburnACM/auacm/stargazers","contributors_url":"https://api.github.com/repos/AuburnACM/auacm/contributors","subscribers_url":"https://api.github.com/repos/AuburnACM/auacm/subscribers","subscription_url":"https://api.github.com/repos/AuburnACM/auacm/subscription","commits_url":"https://api.github.com/repos/AuburnACM/auacm/commits{/sha}","git_commits_url":"https://api.github.com/repos/AuburnACM/auacm/git/commits{/sha}","comments_url":"https://api.github.com/repos/AuburnACM/auacm/comments{/number}","issue_comment_url":"https://api.github.com/repos/AuburnACM/auacm/issues/comments{/number}","contents_url":"https://api.github.com/repos/AuburnACM/auacm/contents/{+path}","compare_url":"https://api.github.com/repos/AuburnACM/auacm/compare/{base}...{head}","merges_url":"https://api.github.com/repos/AuburnACM/auacm/merges","archive_url":"https://api.github.com/repos/AuburnACM/auacm/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/AuburnACM/auacm/downloads","issues_url":"https://api.github.com/repos/AuburnACM/auacm/issues{/number}","pulls_url":"https://api.github.com/repos/AuburnACM/auacm/pulls{/number}","milestones_url":"https://api.github.com/repos/AuburnACM/auacm/milestones{/number}","notifications_url":"https://api.github.com/repos/AuburnACM/auacm/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/AuburnACM/auacm/labels{/name}","releases_url":"https://api.github.com/repos/AuburnACM/auacm/releases{/id}","created_at":"2015-08-23T18:56:47Z","updated_at":"2015-12-08T22:42:31Z","pushed_at":"2016-01-14T20:24:57Z","git_url":"git://github.com/AuburnACM/auacm.git","ssh_url":"git@github.com:AuburnACM/auacm.git","clone_url":"https://github.com/AuburnACM/auacm.git","svn_url":"https://github.com/AuburnACM/auacm","homepage":"","size":6881,"stargazers_count":6,"watchers_count":6,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":30,"forks":3,"open_issues":30,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/AuburnACM/auacm/pulls/54"},"html":{"href":"https://github.com/AuburnACM/auacm/pull/54"},"issue":{"href":"https://api.github.com/repos/AuburnACM/auacm/issues/54"},"comments":{"href":"https://api.github.com/repos/AuburnACM/auacm/issues/54/comments"},"review_comments":{"href":"https://api.github.com/repos/AuburnACM/auacm/pulls/54/comments"},"review_comment":{"href":"https://api.github.com/repos/AuburnACM/auacm/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/AuburnACM/auacm/pulls/54/commits"},"statuses":{"href":"https://api.github.com/repos/AuburnACM/auacm/statuses/0dea053388f2125c6b9fc4a250ce8386d689870f"}}}}