{"action":"created","comment":{"url":"https://api.github.com/repos/mitodl/micromasters/pulls/comments/59779668","id":59779668,"diff_hunk":"@@ -0,0 +1,227 @@\n+\"\"\"\n+Apis for the dashboard\n+\"\"\"\n+import datetime\n+import logging\n+\n+log = logging.getLogger(__name__)\n+\n+\n+class CourseStatus(object):\n+    \"\"\"\n+    Possible statuses for a course for a user\n+    \"\"\"\n+    PASSED = 'passed'\n+    NOT_PASSED = 'not-passed'\n+    CURRENT_GRADE = 'verified-not-completed'\n+    UPGRADE = 'enrolled-not-verified'\n+    NOT_OFFERED = 'not-offered'\n+    OFFERED = 'offered-not-enrolled'\n+\n+    @classmethod\n+    def all_statuses(cls):\n+        \"\"\"Helper to get all the statuses\"\"\"\n+        return [cls.PASSED, cls.NOT_PASSED, cls.CURRENT_GRADE,\n+                cls.UPGRADE, cls.NOT_OFFERED, cls.OFFERED]\n+\n+\n+class CourseRunStatus(object):\n+    \"\"\"\n+    Possible statuses for a course run for a user\n+    \"\"\"\n+    NOT_ENROLLED = 'not-enrolled'\n+    GRADE = 'grade'\n+    READ_CERT = 'read-cert'\n+    WILL_ATTEND = 'will-attend'\n+    UPGRADE = 'upgrade'\n+    NOT_PASSED = 'not-passed'\n+\n+\n+class CourseFormatConditionalFields(object):\n+    \"\"\"\n+    The formatting of a course run is dependent\n+    on the CourseStatus status passed on the function.\n+    There are some fields that are common and others\n+    that depend on the status. Also the name of the fields changes.\n+\n+    This class contains the association between the CourseStatus status\n+    that need specific fields, the field associated correspondent\n+    to a course run and the new name they need to have.\n+    \"\"\"\n+    ASSOCIATED_FIELDS = {\n+        CourseStatus.OFFERED: [\n+            {\n+                'course_run_field': 'enrollment_start',\n+                'format_field': 'enrollment_start_date'\n+            },\n+            {\n+                'course_run_field': 'fuzzy_enrollment_start_date',\n+                'format_field': 'fuzzy_enrollment_start_date'\n+            },\n+        ],\n+        CourseStatus.CURRENT_GRADE: [\n+            {\n+                'course_run_field': 'start_date',\n+                'format_field': 'course_start_date'\n+            },\n+        ]\n+    }\n+\n+    @classmethod\n+    def get_assoc_field(cls, course_status):\n+        \"\"\"\n+        Method to get from the ASSOCIATED_FIELDS dict\n+        \"\"\"\n+        return cls.ASSOCIATED_FIELDS.get(course_status, [])\n+\n+\n+class CourseRunUserStatus(object):\n+    \"\"\"\n+    Representation of a course run status for a specific user\n+    \"\"\"\n+    def __init__(self, status, course_run=None, enrollment_for_course=None):\n+        self.status = status\n+        self.course_run = course_run\n+        self.enrollment_for_course = enrollment_for_course\n+\n+\n+def get_info_for_course(user, course, user_enrollments, user_certificates):\n+    \"\"\"\n+    Checks the status of a course given the status of all its runs\n+\n+    Args:\n+        user (User): an user object\n+        course (Course): a course object\n+        user_enrollments (Enrollments): the user enrollments object\n+        user_certificates (Certificates): the user certificates objects\n+\n+    Returns:\n+        dict: dictionary representing the course status for the user\n+    \"\"\"\n+    # pylint: disable=unused-argument, too-many-return-statements\n+    if not course.courserun_set.count():\n+        return format_course_for_dashboard(None, CourseStatus.NOT_OFFERED, course)\n+    # get all the run statuses\n+    run_statuses = []\n+    for course_run in course.courserun_set.all():\n+        run_statuses.append(get_status_for_courserun(course_run, user_enrollments))\n+    # sort them by end date\n+    run_statuses.sort(key=lambda x: x.course_run.end_date or datetime.datetime(datetime.MAXYEAR, 1, 1), reverse=True)\n+    # pick the first `not enrolled` or the first\n+    for run_status in run_statuses:\n+        if run_status.status != CourseRunStatus.NOT_ENROLLED:\n+            break\n+    else:\n+        run_status = run_statuses[0]\n+\n+    if run_status.status in (CourseRunStatus.NOT_ENROLLED, CourseRunStatus.NOT_PASSED):\n+        return format_course_for_dashboard(\n+            course.get_next_run(),\n+            CourseStatus.OFFERED if course.get_next_run() is not None else CourseStatus.NOT_OFFERED,\n+            course\n+        )\n+    elif run_status.status == CourseRunStatus.GRADE:\n+        return format_course_for_dashboard(run_status.course_run, CourseStatus.CURRENT_GRADE, course)\n+    # check if we need to check the certificate\n+    elif run_status.status == CourseRunStatus.READ_CERT:\n+        # TODO: here should go the logic to check the actual certificate  # pylint: disable=fixme\n+        #       for now just assume not passed and return the next available course run\n+        # this is the case when the certificate says the user did not pass the course\n+        return format_course_for_dashboard(\n+            course.get_next_run(),\n+            CourseStatus.OFFERED if course.get_next_run() is not None else CourseStatus.NOT_OFFERED,\n+            course\n+        )\n+    elif run_status.status == CourseRunStatus.WILL_ATTEND:\n+        return format_course_for_dashboard(run_status.course_run, CourseStatus.CURRENT_GRADE, course)\n+    elif run_status.status == CourseRunStatus.UPGRADE:\n+        return format_course_for_dashboard(run_status.course_run, CourseStatus.UPGRADE, course)\n+    # this should never happen, but put a default behavior just in case\n+    log.critical(\n+        'course %s for user %s has status %s',\n+        run_status.course_run.edx_course_key,\n+        user.username,\n+        run_status.status\n+    )\n+    return format_course_for_dashboard(\n+        course.get_next_run(),\n+        CourseStatus.OFFERED if course.get_next_run() is not None else CourseStatus.NOT_OFFERED,\n+        course\n+    )\n+\n+\n+def get_status_for_courserun(course_run, user_enrollments):\n+    \"\"\"\n+    Checks the status of a course run for a user given her enrollments\n+\n+    Args:\n+        course_run (CourseRun): a course run\n+        user_enrollments (Enrollments): the user enrollments\n+\n+    Returns:\n+        CourseRunStatus: an object representing the run status for the user\n+    \"\"\"\n+    if not user_enrollments.is_enrolled_in(course_run.edx_course_key):\n+        return CourseRunUserStatus(CourseRunStatus.NOT_ENROLLED, course_run)\n+    course_enrollment = user_enrollments.get_enrollment_for_course(course_run.edx_course_key)\n+    if course_enrollment.is_verified:\n+        if course_run.is_current:\n+            status = CourseRunStatus.GRADE\n+        elif course_run.is_past:\n+            status = CourseRunStatus.READ_CERT\n+        elif course_run.is_future:\n+            status = CourseRunStatus.WILL_ATTEND\n+    else:\n+        if course_run.is_current or course_run.is_future:\n+            status = CourseRunStatus.UPGRADE\n+        elif course_run.is_past:\n+            status = CourseRunStatus.NOT_PASSED\n+    return CourseRunUserStatus(\n+        status=status,","path":"dashboard/api.py","position":180,"original_position":180,"commit_id":"16ecf44348bb6dbc51f8e636fc76ab50fda66a62","original_commit_id":"16ecf44348bb6dbc51f8e636fc76ab50fda66a62","user":{"login":"noisecapella","id":863262,"avatar_url":"https://avatars.githubusercontent.com/u/863262?v=3","gravatar_id":"","url":"https://api.github.com/users/noisecapella","html_url":"https://github.com/noisecapella","followers_url":"https://api.github.com/users/noisecapella/followers","following_url":"https://api.github.com/users/noisecapella/following{/other_user}","gists_url":"https://api.github.com/users/noisecapella/gists{/gist_id}","starred_url":"https://api.github.com/users/noisecapella/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/noisecapella/subscriptions","organizations_url":"https://api.github.com/users/noisecapella/orgs","repos_url":"https://api.github.com/users/noisecapella/repos","events_url":"https://api.github.com/users/noisecapella/events{/privacy}","received_events_url":"https://api.github.com/users/noisecapella/received_events","type":"User","site_admin":false},"body":"Can you define `status = None` above? My IDE is complaining that `status` might not be defined in all cases","created_at":"2016-04-14T19:50:56Z","updated_at":"2016-04-14T19:50:56Z","html_url":"https://github.com/mitodl/micromasters/pull/164#discussion_r59779668","pull_request_url":"https://api.github.com/repos/mitodl/micromasters/pulls/164","_links":{"self":{"href":"https://api.github.com/repos/mitodl/micromasters/pulls/comments/59779668"},"html":{"href":"https://github.com/mitodl/micromasters/pull/164#discussion_r59779668"},"pull_request":{"href":"https://api.github.com/repos/mitodl/micromasters/pulls/164"}}},"pull_request":{"url":"https://api.github.com/repos/mitodl/micromasters/pulls/164","id":66064015,"html_url":"https://github.com/mitodl/micromasters/pull/164","diff_url":"https://github.com/mitodl/micromasters/pull/164.diff","patch_url":"https://github.com/mitodl/micromasters/pull/164.patch","issue_url":"https://api.github.com/repos/mitodl/micromasters/issues/164","number":164,"state":"open","locked":false,"title":"Dashboard REST API","user":{"login":"giocalitri","id":1005204,"avatar_url":"https://avatars.githubusercontent.com/u/1005204?v=3","gravatar_id":"","url":"https://api.github.com/users/giocalitri","html_url":"https://github.com/giocalitri","followers_url":"https://api.github.com/users/giocalitri/followers","following_url":"https://api.github.com/users/giocalitri/following{/other_user}","gists_url":"https://api.github.com/users/giocalitri/gists{/gist_id}","starred_url":"https://api.github.com/users/giocalitri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/giocalitri/subscriptions","organizations_url":"https://api.github.com/users/giocalitri/orgs","repos_url":"https://api.github.com/users/giocalitri/repos","events_url":"https://api.github.com/users/giocalitri/events{/privacy}","received_events_url":"https://api.github.com/users/giocalitri/received_events","type":"User","site_admin":false},"body":"#### What are the relevant tickets?\r\nfixes #125 \r\n\r\n#### What's this PR do?\r\nIntroduces the dashboard api\r\n\r\n#### Where should the reviewer start?\r\ncourse models, then dashboard api, then dashboard view\r\n\r\n#### How should this be manually tested?\r\nAdd some course runs for your courses with dates in a way to have past present and future run.\r\nYou may want to make those run correspondent to real course on edX where the user you are using has enrolled/not enrolled\r\n\r\n#### What GIF best describes this PR or how it makes you feel?\r\n![](http://www.sharegif.com/wp-content/uploads/2014/04/baby-gifconfused-gifidkgood-luck-charlie.gif)","created_at":"2016-04-11T21:17:23Z","updated_at":"2016-04-14T19:50:56Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e2e87b77e6d1c2d2849986fcd640122ac4c04044","assignee":{"login":"noisecapella","id":863262,"avatar_url":"https://avatars.githubusercontent.com/u/863262?v=3","gravatar_id":"","url":"https://api.github.com/users/noisecapella","html_url":"https://github.com/noisecapella","followers_url":"https://api.github.com/users/noisecapella/followers","following_url":"https://api.github.com/users/noisecapella/following{/other_user}","gists_url":"https://api.github.com/users/noisecapella/gists{/gist_id}","starred_url":"https://api.github.com/users/noisecapella/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/noisecapella/subscriptions","organizations_url":"https://api.github.com/users/noisecapella/orgs","repos_url":"https://api.github.com/users/noisecapella/repos","events_url":"https://api.github.com/users/noisecapella/events{/privacy}","received_events_url":"https://api.github.com/users/noisecapella/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/mitodl/micromasters/pulls/164/commits","review_comments_url":"https://api.github.com/repos/mitodl/micromasters/pulls/164/comments","review_comment_url":"https://api.github.com/repos/mitodl/micromasters/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mitodl/micromasters/issues/164/comments","statuses_url":"https://api.github.com/repos/mitodl/micromasters/statuses/16ecf44348bb6dbc51f8e636fc76ab50fda66a62","head":{"label":"mitodl:gdm_enrollments_#74","ref":"gdm_enrollments_#74","sha":"16ecf44348bb6dbc51f8e636fc76ab50fda66a62","user":{"login":"mitodl","id":7918516,"avatar_url":"https://avatars.githubusercontent.com/u/7918516?v=3","gravatar_id":"","url":"https://api.github.com/users/mitodl","html_url":"https://github.com/mitodl","followers_url":"https://api.github.com/users/mitodl/followers","following_url":"https://api.github.com/users/mitodl/following{/other_user}","gists_url":"https://api.github.com/users/mitodl/gists{/gist_id}","starred_url":"https://api.github.com/users/mitodl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mitodl/subscriptions","organizations_url":"https://api.github.com/users/mitodl/orgs","repos_url":"https://api.github.com/users/mitodl/repos","events_url":"https://api.github.com/users/mitodl/events{/privacy}","received_events_url":"https://api.github.com/users/mitodl/received_events","type":"Organization","site_admin":false},"repo":{"id":52919185,"name":"micromasters","full_name":"mitodl/micromasters","owner":{"login":"mitodl","id":7918516,"avatar_url":"https://avatars.githubusercontent.com/u/7918516?v=3","gravatar_id":"","url":"https://api.github.com/users/mitodl","html_url":"https://github.com/mitodl","followers_url":"https://api.github.com/users/mitodl/followers","following_url":"https://api.github.com/users/mitodl/following{/other_user}","gists_url":"https://api.github.com/users/mitodl/gists{/gist_id}","starred_url":"https://api.github.com/users/mitodl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mitodl/subscriptions","organizations_url":"https://api.github.com/users/mitodl/orgs","repos_url":"https://api.github.com/users/mitodl/repos","events_url":"https://api.github.com/users/mitodl/events{/privacy}","received_events_url":"https://api.github.com/users/mitodl/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mitodl/micromasters","description":"Portal for learners and course teams to access MITx micromasters programs: https://goo.gl/tsUTSO","fork":false,"url":"https://api.github.com/repos/mitodl/micromasters","forks_url":"https://api.github.com/repos/mitodl/micromasters/forks","keys_url":"https://api.github.com/repos/mitodl/micromasters/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mitodl/micromasters/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mitodl/micromasters/teams","hooks_url":"https://api.github.com/repos/mitodl/micromasters/hooks","issue_events_url":"https://api.github.com/repos/mitodl/micromasters/issues/events{/number}","events_url":"https://api.github.com/repos/mitodl/micromasters/events","assignees_url":"https://api.github.com/repos/mitodl/micromasters/assignees{/user}","branches_url":"https://api.github.com/repos/mitodl/micromasters/branches{/branch}","tags_url":"https://api.github.com/repos/mitodl/micromasters/tags","blobs_url":"https://api.github.com/repos/mitodl/micromasters/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mitodl/micromasters/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mitodl/micromasters/git/refs{/sha}","trees_url":"https://api.github.com/repos/mitodl/micromasters/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mitodl/micromasters/statuses/{sha}","languages_url":"https://api.github.com/repos/mitodl/micromasters/languages","stargazers_url":"https://api.github.com/repos/mitodl/micromasters/stargazers","contributors_url":"https://api.github.com/repos/mitodl/micromasters/contributors","subscribers_url":"https://api.github.com/repos/mitodl/micromasters/subscribers","subscription_url":"https://api.github.com/repos/mitodl/micromasters/subscription","commits_url":"https://api.github.com/repos/mitodl/micromasters/commits{/sha}","git_commits_url":"https://api.github.com/repos/mitodl/micromasters/git/commits{/sha}","comments_url":"https://api.github.com/repos/mitodl/micromasters/comments{/number}","issue_comment_url":"https://api.github.com/repos/mitodl/micromasters/issues/comments{/number}","contents_url":"https://api.github.com/repos/mitodl/micromasters/contents/{+path}","compare_url":"https://api.github.com/repos/mitodl/micromasters/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mitodl/micromasters/merges","archive_url":"https://api.github.com/repos/mitodl/micromasters/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mitodl/micromasters/downloads","issues_url":"https://api.github.com/repos/mitodl/micromasters/issues{/number}","pulls_url":"https://api.github.com/repos/mitodl/micromasters/pulls{/number}","milestones_url":"https://api.github.com/repos/mitodl/micromasters/milestones{/number}","notifications_url":"https://api.github.com/repos/mitodl/micromasters/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mitodl/micromasters/labels{/name}","releases_url":"https://api.github.com/repos/mitodl/micromasters/releases{/id}","deployments_url":"https://api.github.com/repos/mitodl/micromasters/deployments","created_at":"2016-03-01T23:53:17Z","updated_at":"2016-04-10T02:09:21Z","pushed_at":"2016-04-14T19:49:28Z","git_url":"git://github.com/mitodl/micromasters.git","ssh_url":"git@github.com:mitodl/micromasters.git","clone_url":"https://github.com/mitodl/micromasters.git","svn_url":"https://github.com/mitodl/micromasters","homepage":"","size":529,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":46,"forks":0,"open_issues":46,"watchers":2,"default_branch":"master"}},"base":{"label":"mitodl:master","ref":"master","sha":"3a7540f84a5abeaca68ce856881908257e7b2a60","user":{"login":"mitodl","id":7918516,"avatar_url":"https://avatars.githubusercontent.com/u/7918516?v=3","gravatar_id":"","url":"https://api.github.com/users/mitodl","html_url":"https://github.com/mitodl","followers_url":"https://api.github.com/users/mitodl/followers","following_url":"https://api.github.com/users/mitodl/following{/other_user}","gists_url":"https://api.github.com/users/mitodl/gists{/gist_id}","starred_url":"https://api.github.com/users/mitodl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mitodl/subscriptions","organizations_url":"https://api.github.com/users/mitodl/orgs","repos_url":"https://api.github.com/users/mitodl/repos","events_url":"https://api.github.com/users/mitodl/events{/privacy}","received_events_url":"https://api.github.com/users/mitodl/received_events","type":"Organization","site_admin":false},"repo":{"id":52919185,"name":"micromasters","full_name":"mitodl/micromasters","owner":{"login":"mitodl","id":7918516,"avatar_url":"https://avatars.githubusercontent.com/u/7918516?v=3","gravatar_id":"","url":"https://api.github.com/users/mitodl","html_url":"https://github.com/mitodl","followers_url":"https://api.github.com/users/mitodl/followers","following_url":"https://api.github.com/users/mitodl/following{/other_user}","gists_url":"https://api.github.com/users/mitodl/gists{/gist_id}","starred_url":"https://api.github.com/users/mitodl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mitodl/subscriptions","organizations_url":"https://api.github.com/users/mitodl/orgs","repos_url":"https://api.github.com/users/mitodl/repos","events_url":"https://api.github.com/users/mitodl/events{/privacy}","received_events_url":"https://api.github.com/users/mitodl/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mitodl/micromasters","description":"Portal for learners and course teams to access MITx micromasters programs: https://goo.gl/tsUTSO","fork":false,"url":"https://api.github.com/repos/mitodl/micromasters","forks_url":"https://api.github.com/repos/mitodl/micromasters/forks","keys_url":"https://api.github.com/repos/mitodl/micromasters/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mitodl/micromasters/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mitodl/micromasters/teams","hooks_url":"https://api.github.com/repos/mitodl/micromasters/hooks","issue_events_url":"https://api.github.com/repos/mitodl/micromasters/issues/events{/number}","events_url":"https://api.github.com/repos/mitodl/micromasters/events","assignees_url":"https://api.github.com/repos/mitodl/micromasters/assignees{/user}","branches_url":"https://api.github.com/repos/mitodl/micromasters/branches{/branch}","tags_url":"https://api.github.com/repos/mitodl/micromasters/tags","blobs_url":"https://api.github.com/repos/mitodl/micromasters/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mitodl/micromasters/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mitodl/micromasters/git/refs{/sha}","trees_url":"https://api.github.com/repos/mitodl/micromasters/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mitodl/micromasters/statuses/{sha}","languages_url":"https://api.github.com/repos/mitodl/micromasters/languages","stargazers_url":"https://api.github.com/repos/mitodl/micromasters/stargazers","contributors_url":"https://api.github.com/repos/mitodl/micromasters/contributors","subscribers_url":"https://api.github.com/repos/mitodl/micromasters/subscribers","subscription_url":"https://api.github.com/repos/mitodl/micromasters/subscription","commits_url":"https://api.github.com/repos/mitodl/micromasters/commits{/sha}","git_commits_url":"https://api.github.com/repos/mitodl/micromasters/git/commits{/sha}","comments_url":"https://api.github.com/repos/mitodl/micromasters/comments{/number}","issue_comment_url":"https://api.github.com/repos/mitodl/micromasters/issues/comments{/number}","contents_url":"https://api.github.com/repos/mitodl/micromasters/contents/{+path}","compare_url":"https://api.github.com/repos/mitodl/micromasters/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mitodl/micromasters/merges","archive_url":"https://api.github.com/repos/mitodl/micromasters/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mitodl/micromasters/downloads","issues_url":"https://api.github.com/repos/mitodl/micromasters/issues{/number}","pulls_url":"https://api.github.com/repos/mitodl/micromasters/pulls{/number}","milestones_url":"https://api.github.com/repos/mitodl/micromasters/milestones{/number}","notifications_url":"https://api.github.com/repos/mitodl/micromasters/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mitodl/micromasters/labels{/name}","releases_url":"https://api.github.com/repos/mitodl/micromasters/releases{/id}","deployments_url":"https://api.github.com/repos/mitodl/micromasters/deployments","created_at":"2016-03-01T23:53:17Z","updated_at":"2016-04-10T02:09:21Z","pushed_at":"2016-04-14T19:49:28Z","git_url":"git://github.com/mitodl/micromasters.git","ssh_url":"git@github.com:mitodl/micromasters.git","clone_url":"https://github.com/mitodl/micromasters.git","svn_url":"https://github.com/mitodl/micromasters","homepage":"","size":529,"stargazers_count":2,"watchers_count":2,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":46,"forks":0,"open_issues":46,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mitodl/micromasters/pulls/164"},"html":{"href":"https://github.com/mitodl/micromasters/pull/164"},"issue":{"href":"https://api.github.com/repos/mitodl/micromasters/issues/164"},"comments":{"href":"https://api.github.com/repos/mitodl/micromasters/issues/164/comments"},"review_comments":{"href":"https://api.github.com/repos/mitodl/micromasters/pulls/164/comments"},"review_comment":{"href":"https://api.github.com/repos/mitodl/micromasters/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mitodl/micromasters/pulls/164/commits"},"statuses":{"href":"https://api.github.com/repos/mitodl/micromasters/statuses/16ecf44348bb6dbc51f8e636fc76ab50fda66a62"}}}}