{"action":"created","comment":{"url":"https://api.github.com/repos/pulp/pulp/pulls/comments/23637039","id":23637039,"diff_hunk":"@@ -0,0 +1,373 @@\n+import json\n+\n+from django.core.urlresolvers import reverse\n+from django.http import HttpResponseRedirect, HttpResponseBadRequest\n+from django.views.generic import View\n+\n+from pulp.server import exceptions as pulp_exceptions\n+from pulp.server.auth import authorization\n+from pulp.server.db.model.consumer import ConsumerGroup\n+from pulp.server.db.model.criteria import Criteria\n+from pulp.server.managers import factory\n+from pulp.server.managers.consumer.group.cud import bind, unbind\n+from pulp.server.webservices.controllers.decorators import auth_required\n+from pulp.server.webservices.controllers.base import json_encoder as pulp_json_encoder\n+from pulp.server.webservices.views.util import (generate_json_response,\n+                                                generate_json_response_with_pulp_encoder)\n+\n+\n+class ConsumerGroupView(View):\n+    \"\"\"\n+    Views for consumer groups.\n+    \"\"\"\n+\n+    @auth_required(authorization.READ)\n+    def get(self, request):\n+        \"\"\"\n+        List the available consumer groups.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :return: Response containing a list of consumer groups\n+        :rtype: django.http.HttpResponse\n+        \"\"\"\n+        collection = ConsumerGroup.get_collection()\n+        cursor = collection.find({})\n+        groups = []\n+        for group in cursor:\n+            link = {\"_href\": reverse('consumer_group_resource',\n+                    kwargs={'consumer_group_id': group['id']})}\n+            group.update(link)\n+            groups.append(group)\n+        return generate_json_response_with_pulp_encoder(groups)\n+\n+    @auth_required(authorization.CREATE)\n+    def post(self, request):\n+        \"\"\"\n+        Create a consumer group and return a serialized object containing just created group.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :return: Response containing the consumer group\n+        :rtype: HttpResponseRedirect\n+        :raises: MissingValue if group ID is not provided\n+        :raises: InvalidValue if some parameters are invalid\n+        \"\"\"\n+        params = request.body_as_json\n+        group_id = params.pop('id', None)\n+        if group_id is None:\n+            raise pulp_exceptions.MissingValue(['id'])\n+        display_name = params.pop('display_name', None)\n+        description = params.pop('description', None)\n+        consumer_ids = params.pop('consumer_ids', None)\n+        notes = params.pop('notes', None)\n+        if params:\n+            raise pulp_exceptions.InvalidValue(params.keys())\n+        manager = factory.consumer_group_manager()\n+        group = manager.create_consumer_group(group_id, display_name, description, consumer_ids,\n+                                              notes)\n+        link = {\"_href\": reverse('consumer_group_resource',\n+                kwargs={'consumer_group_id': group['id']})}\n+        group.update(link)\n+        # TODO location is shown with domain, should be without\n+        return HttpResponseRedirect(\n+            link[\"_href\"],\n+            json.dumps(group, default=pulp_json_encoder),\n+            content_type=\"application/json\",\n+            status=201,\n+            )\n+\n+\n+class ConsumerGroupResourceView(View):\n+    \"\"\"\n+    Views for a specific consumer group.\n+    \"\"\"\n+\n+    @auth_required(authorization.READ)\n+    def get(self, request, consumer_group_id):\n+        \"\"\"\n+        Return a serialized object representing the requested group.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: id for the requested group\n+        :type consumer_group_id: string\n+        :return: Response containing data for the requested group\n+        :rtype: django.http.HttpResponse\n+        :raises: MissingResource if group ID does not exist\n+        \"\"\"\n+        collection = ConsumerGroup.get_collection()\n+        group = collection.find_one({'id': consumer_group_id})\n+        if group is None:\n+            raise pulp_exceptions.MissingResource(consumer_group=consumer_group_id)\n+        link = {\"_href\": reverse('consumer_group_resource',\n+                kwargs={'consumer_group_id': group['id']})}\n+        group.update(link)\n+        return generate_json_response_with_pulp_encoder(group)\n+\n+    @auth_required(authorization.DELETE)\n+    def delete(self, request, consumer_group_id):\n+        \"\"\"\n+        Delete a specified consumer group.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: id for the requested group\n+        :type consumer_group_id: string\n+        :return: An empty response\n+        :rtype: django.http.HttpResponse\n+        \"\"\"\n+        manager = factory.consumer_group_manager()\n+        result = manager.delete_consumer_group(consumer_group_id)\n+        return generate_json_response(result)\n+\n+    @auth_required(authorization.UPDATE)\n+    def put(self, request, consumer_group_id):\n+        \"\"\"\n+        Update a specified consumer group.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: id for the requested group\n+        :type consumer_group_id: string\n+        :return: Response representing the updated group\n+        :rtype: django.http.HttpResponse\n+        \"\"\"\n+        update_data = request.body_as_json\n+        manager = factory.consumer_group_manager()\n+        group = manager.update_consumer_group(consumer_group_id, **update_data)\n+        link = {\"_href\": reverse('consumer_group_resource',\n+                kwargs={'consumer_group_id': group['id']})}\n+        group.update(link)\n+        return generate_json_response_with_pulp_encoder(group)\n+\n+\n+class ConsumerGroupAssociateActionView(View):\n+    \"\"\"\n+    Views for consumer association to the group.\n+    \"\"\"\n+\n+    @auth_required(authorization.EXECUTE)\n+    def post(self, request, consumer_group_id):\n+        \"\"\"\n+        Associate a consumer to the group.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: id for the requested group\n+        :type consumer_group_id: string\n+        :return: Response containing consumers bound to the group\n+        :rtype: django.http.HttpResponse\n+        \"\"\"\n+        params = request.body_as_json\n+        criteria = Criteria.from_client_input(params.get('criteria', {}))\n+        manager = factory.consumer_group_manager()\n+        manager.associate(consumer_group_id, criteria)\n+        query_manager = factory.consumer_group_query_manager()\n+        group = query_manager.get_group(consumer_group_id)\n+        return generate_json_response_with_pulp_encoder(group['consumer_ids'])\n+\n+\n+class ConsumerGroupUnassociateActionView(View):\n+    \"\"\"\n+    Views for consumer unassociation from the group.\n+    \"\"\"\n+\n+    @auth_required(authorization.EXECUTE)\n+    def post(self, request, consumer_group_id):\n+        \"\"\"\n+        Unassociate a consumer from the group.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: id for the requested group\n+        :type consumer_group_id: string\n+        :return: Response containing consumers bound to the group\n+        :rtype: django.http.HttpResponse\n+        \"\"\"\n+        params = request.body_as_json\n+        criteria = Criteria.from_client_input(params.get('criteria', {}))\n+        manager = factory.consumer_group_manager()\n+        manager.unassociate(consumer_group_id, criteria)\n+        query_manager = factory.consumer_group_query_manager()\n+        group = query_manager.get_group(consumer_group_id)\n+        return generate_json_response_with_pulp_encoder(group['consumer_ids'])\n+\n+\n+class ConsumerGroupContentActionView(View):\n+    \"\"\"\n+    Views for content manipulation on consumer group.\n+    \"\"\"\n+\n+    @auth_required(authorization.CREATE)\n+    def post(self, request, consumer_group_id, action):\n+        \"\"\"\n+        Content actions.\n+        \"\"\"\n+        method = getattr(self, action, None)\n+        if method:\n+            return method(request, consumer_group_id)\n+        else:\n+            return HttpResponseBadRequest('bad request')\n+\n+    def install(self, request, consumer_group_id):\n+        \"\"\"\n+        Install content (units) on the consumers in a consumer group.\n+\n+        Expected body: {units:[], options:<dict>}\n+        where unit is: {type_id:<str>, unit_key={}} and the\n+        options is a dict of install options.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: A consumer group ID.\n+        :type consumer_group_id: str\n+        :raises: OperationPostponed\n+        \"\"\"\n+        body = request.body_as_json\n+        units = body.get('units')\n+        options = body.get('options')\n+        task = factory.consumer_group_manager().install_content(consumer_group_id,\n+                                                                units, options)\n+        raise pulp_exceptions.OperationPostponed(task)\n+\n+    def update(self, request, consumer_group_id):\n+        \"\"\"\n+        Update content (units) on the consumer in a consumer group.\n+\n+        Expected body: {units:[], options:<dict>}\n+        where unit is: {type_id:<str>, unit_key={}} and the\n+        options is a dict of update options.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: A consumer group ID.\n+        :type consumer_group_id: str\n+        :raises: OperationPostponed\n+        \"\"\"\n+        body = request.body_as_json\n+        units = body.get('units')\n+        options = body.get('options')\n+        task = factory.consumer_group_manager().update_content(consumer_group_id,\n+                                                               units, options)\n+        raise pulp_exceptions.OperationPostponed(task)\n+\n+    def uninstall(self, request, consumer_group_id):\n+        \"\"\"\n+        Uninstall content (units) from the consumers in a consumer group.\n+\n+        Expected body: {units:[], options:<dict>}\n+        where unit is: {type_id:<str>, unit_key={}} and the\n+        options is a dict of uninstall options.\n+\n+        :param request: WSGI request object\n+        :type request: django.core.handlers.wsgi.WSGIRequest\n+        :param consumer_group_id: A consumer group ID.\n+        :type consumer_group_id: str\n+        :raises: OperationPostponed\n+        \"\"\"\n+        body = request.body_as_json\n+        units = body.get('units')\n+        options = body.get('options')\n+        task = factory.consumer_group_manager().uninstall_content(consumer_group_id,\n+                                                                  units, options)\n+        raise pulp_exceptions.OperationPostponed(task)\n+\n+\n+class ConsumerGroupBindingsView(View):\n+    \"\"\"\n+    Views for repository binding to the group.\n+    \"\"\"\n+    @auth_required(authorization.CREATE)","path":"server/pulp/server/webservices/views/consumer_groups.py","position":281,"original_position":281,"commit_id":"e5009b0370ff98cb7d629d8b1382d12942a1d4ae","original_commit_id":"e5009b0370ff98cb7d629d8b1382d12942a1d4ae","user":{"login":"bmbouter","id":180319,"avatar_url":"https://avatars.githubusercontent.com/u/180319?v=3","gravatar_id":"","url":"https://api.github.com/users/bmbouter","html_url":"https://github.com/bmbouter","followers_url":"https://api.github.com/users/bmbouter/followers","following_url":"https://api.github.com/users/bmbouter/following{/other_user}","gists_url":"https://api.github.com/users/bmbouter/gists{/gist_id}","starred_url":"https://api.github.com/users/bmbouter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bmbouter/subscriptions","organizations_url":"https://api.github.com/users/bmbouter/orgs","repos_url":"https://api.github.com/users/bmbouter/repos","events_url":"https://api.github.com/users/bmbouter/events{/privacy}","received_events_url":"https://api.github.com/users/bmbouter/received_events","type":"User","site_admin":false},"body":"Maybe add a space above this line?","created_at":"2015-01-27T19:51:57Z","updated_at":"2015-01-27T19:51:57Z","html_url":"https://github.com/pulp/pulp/pull/1549#discussion_r23637039","pull_request_url":"https://api.github.com/repos/pulp/pulp/pulls/1549","_links":{"self":{"href":"https://api.github.com/repos/pulp/pulp/pulls/comments/23637039"},"html":{"href":"https://github.com/pulp/pulp/pull/1549#discussion_r23637039"},"pull_request":{"href":"https://api.github.com/repos/pulp/pulp/pulls/1549"}}},"pull_request":{"url":"https://api.github.com/repos/pulp/pulp/pulls/1549","id":27611880,"html_url":"https://github.com/pulp/pulp/pull/1549","diff_url":"https://github.com/pulp/pulp/pull/1549.diff","patch_url":"https://github.com/pulp/pulp/pull/1549.patch","issue_url":"https://api.github.com/repos/pulp/pulp/issues/1549","number":1549,"state":"open","locked":false,"title":"Introducing Consumer group view","user":{"login":"ipanova","id":4253816,"avatar_url":"https://avatars.githubusercontent.com/u/4253816?v=3","gravatar_id":"","url":"https://api.github.com/users/ipanova","html_url":"https://github.com/ipanova","followers_url":"https://api.github.com/users/ipanova/followers","following_url":"https://api.github.com/users/ipanova/following{/other_user}","gists_url":"https://api.github.com/users/ipanova/gists{/gist_id}","starred_url":"https://api.github.com/users/ipanova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ipanova/subscriptions","organizations_url":"https://api.github.com/users/ipanova/orgs","repos_url":"https://api.github.com/users/ipanova/repos","events_url":"https://api.github.com/users/ipanova/events{/privacy}","received_events_url":"https://api.github.com/users/ipanova/received_events","type":"User","site_admin":false},"body":"~~1 tests should be added( test_urls.py + test_consumer_group.py)~~\r\n~~2 docs for every class and method should be added~~\r\n~~3 add manual testing fpaste~~","created_at":"2015-01-19T14:54:49Z","updated_at":"2015-01-27T19:51:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"655df8f4a976a576e1521a076d74e57121eb1254","assignee":{"login":"bmbouter","id":180319,"avatar_url":"https://avatars.githubusercontent.com/u/180319?v=3","gravatar_id":"","url":"https://api.github.com/users/bmbouter","html_url":"https://github.com/bmbouter","followers_url":"https://api.github.com/users/bmbouter/followers","following_url":"https://api.github.com/users/bmbouter/following{/other_user}","gists_url":"https://api.github.com/users/bmbouter/gists{/gist_id}","starred_url":"https://api.github.com/users/bmbouter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bmbouter/subscriptions","organizations_url":"https://api.github.com/users/bmbouter/orgs","repos_url":"https://api.github.com/users/bmbouter/repos","events_url":"https://api.github.com/users/bmbouter/events{/privacy}","received_events_url":"https://api.github.com/users/bmbouter/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/pulp/pulp/pulls/1549/commits","review_comments_url":"https://api.github.com/repos/pulp/pulp/pulls/1549/comments","review_comment_url":"https://api.github.com/repos/pulp/pulp/pulls/comments/{number}","comments_url":"https://api.github.com/repos/pulp/pulp/issues/1549/comments","statuses_url":"https://api.github.com/repos/pulp/pulp/statuses/e5009b0370ff98cb7d629d8b1382d12942a1d4ae","head":{"label":"ipanova:consumer_groups-view","ref":"consumer_groups-view","sha":"e5009b0370ff98cb7d629d8b1382d12942a1d4ae","user":{"login":"ipanova","id":4253816,"avatar_url":"https://avatars.githubusercontent.com/u/4253816?v=3","gravatar_id":"","url":"https://api.github.com/users/ipanova","html_url":"https://github.com/ipanova","followers_url":"https://api.github.com/users/ipanova/followers","following_url":"https://api.github.com/users/ipanova/following{/other_user}","gists_url":"https://api.github.com/users/ipanova/gists{/gist_id}","starred_url":"https://api.github.com/users/ipanova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ipanova/subscriptions","organizations_url":"https://api.github.com/users/ipanova/orgs","repos_url":"https://api.github.com/users/ipanova/repos","events_url":"https://api.github.com/users/ipanova/events{/privacy}","received_events_url":"https://api.github.com/users/ipanova/received_events","type":"User","site_admin":false},"repo":{"id":17410078,"name":"pulp","full_name":"ipanova/pulp","owner":{"login":"ipanova","id":4253816,"avatar_url":"https://avatars.githubusercontent.com/u/4253816?v=3","gravatar_id":"","url":"https://api.github.com/users/ipanova","html_url":"https://github.com/ipanova","followers_url":"https://api.github.com/users/ipanova/followers","following_url":"https://api.github.com/users/ipanova/following{/other_user}","gists_url":"https://api.github.com/users/ipanova/gists{/gist_id}","starred_url":"https://api.github.com/users/ipanova/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ipanova/subscriptions","organizations_url":"https://api.github.com/users/ipanova/orgs","repos_url":"https://api.github.com/users/ipanova/repos","events_url":"https://api.github.com/users/ipanova/events{/privacy}","received_events_url":"https://api.github.com/users/ipanova/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ipanova/pulp","description":"Repository for Pulp platform code, including the server and base admin and consumer clients","fork":true,"url":"https://api.github.com/repos/ipanova/pulp","forks_url":"https://api.github.com/repos/ipanova/pulp/forks","keys_url":"https://api.github.com/repos/ipanova/pulp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ipanova/pulp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ipanova/pulp/teams","hooks_url":"https://api.github.com/repos/ipanova/pulp/hooks","issue_events_url":"https://api.github.com/repos/ipanova/pulp/issues/events{/number}","events_url":"https://api.github.com/repos/ipanova/pulp/events","assignees_url":"https://api.github.com/repos/ipanova/pulp/assignees{/user}","branches_url":"https://api.github.com/repos/ipanova/pulp/branches{/branch}","tags_url":"https://api.github.com/repos/ipanova/pulp/tags","blobs_url":"https://api.github.com/repos/ipanova/pulp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ipanova/pulp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ipanova/pulp/git/refs{/sha}","trees_url":"https://api.github.com/repos/ipanova/pulp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ipanova/pulp/statuses/{sha}","languages_url":"https://api.github.com/repos/ipanova/pulp/languages","stargazers_url":"https://api.github.com/repos/ipanova/pulp/stargazers","contributors_url":"https://api.github.com/repos/ipanova/pulp/contributors","subscribers_url":"https://api.github.com/repos/ipanova/pulp/subscribers","subscription_url":"https://api.github.com/repos/ipanova/pulp/subscription","commits_url":"https://api.github.com/repos/ipanova/pulp/commits{/sha}","git_commits_url":"https://api.github.com/repos/ipanova/pulp/git/commits{/sha}","comments_url":"https://api.github.com/repos/ipanova/pulp/comments{/number}","issue_comment_url":"https://api.github.com/repos/ipanova/pulp/issues/comments/{number}","contents_url":"https://api.github.com/repos/ipanova/pulp/contents/{+path}","compare_url":"https://api.github.com/repos/ipanova/pulp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ipanova/pulp/merges","archive_url":"https://api.github.com/repos/ipanova/pulp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ipanova/pulp/downloads","issues_url":"https://api.github.com/repos/ipanova/pulp/issues{/number}","pulls_url":"https://api.github.com/repos/ipanova/pulp/pulls{/number}","milestones_url":"https://api.github.com/repos/ipanova/pulp/milestones{/number}","notifications_url":"https://api.github.com/repos/ipanova/pulp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ipanova/pulp/labels{/name}","releases_url":"https://api.github.com/repos/ipanova/pulp/releases{/id}","created_at":"2014-03-04T17:13:28Z","updated_at":"2015-01-06T12:05:33Z","pushed_at":"2015-01-27T17:43:34Z","git_url":"git://github.com/ipanova/pulp.git","ssh_url":"git@github.com:ipanova/pulp.git","clone_url":"https://github.com/ipanova/pulp.git","svn_url":"https://github.com/ipanova/pulp","homepage":"","size":79045,"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":"pulp:introducing-django","ref":"introducing-django","sha":"d5753339f346745d4986126c952b48ee49566df4","user":{"login":"pulp","id":2103606,"avatar_url":"https://avatars.githubusercontent.com/u/2103606?v=3","gravatar_id":"","url":"https://api.github.com/users/pulp","html_url":"https://github.com/pulp","followers_url":"https://api.github.com/users/pulp/followers","following_url":"https://api.github.com/users/pulp/following{/other_user}","gists_url":"https://api.github.com/users/pulp/gists{/gist_id}","starred_url":"https://api.github.com/users/pulp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pulp/subscriptions","organizations_url":"https://api.github.com/users/pulp/orgs","repos_url":"https://api.github.com/users/pulp/repos","events_url":"https://api.github.com/users/pulp/events{/privacy}","received_events_url":"https://api.github.com/users/pulp/received_events","type":"Organization","site_admin":false},"repo":{"id":5314652,"name":"pulp","full_name":"pulp/pulp","owner":{"login":"pulp","id":2103606,"avatar_url":"https://avatars.githubusercontent.com/u/2103606?v=3","gravatar_id":"","url":"https://api.github.com/users/pulp","html_url":"https://github.com/pulp","followers_url":"https://api.github.com/users/pulp/followers","following_url":"https://api.github.com/users/pulp/following{/other_user}","gists_url":"https://api.github.com/users/pulp/gists{/gist_id}","starred_url":"https://api.github.com/users/pulp/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pulp/subscriptions","organizations_url":"https://api.github.com/users/pulp/orgs","repos_url":"https://api.github.com/users/pulp/repos","events_url":"https://api.github.com/users/pulp/events{/privacy}","received_events_url":"https://api.github.com/users/pulp/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pulp/pulp","description":"Repository for Pulp platform code, including the server and base admin and consumer clients","fork":false,"url":"https://api.github.com/repos/pulp/pulp","forks_url":"https://api.github.com/repos/pulp/pulp/forks","keys_url":"https://api.github.com/repos/pulp/pulp/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pulp/pulp/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pulp/pulp/teams","hooks_url":"https://api.github.com/repos/pulp/pulp/hooks","issue_events_url":"https://api.github.com/repos/pulp/pulp/issues/events{/number}","events_url":"https://api.github.com/repos/pulp/pulp/events","assignees_url":"https://api.github.com/repos/pulp/pulp/assignees{/user}","branches_url":"https://api.github.com/repos/pulp/pulp/branches{/branch}","tags_url":"https://api.github.com/repos/pulp/pulp/tags","blobs_url":"https://api.github.com/repos/pulp/pulp/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pulp/pulp/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pulp/pulp/git/refs{/sha}","trees_url":"https://api.github.com/repos/pulp/pulp/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pulp/pulp/statuses/{sha}","languages_url":"https://api.github.com/repos/pulp/pulp/languages","stargazers_url":"https://api.github.com/repos/pulp/pulp/stargazers","contributors_url":"https://api.github.com/repos/pulp/pulp/contributors","subscribers_url":"https://api.github.com/repos/pulp/pulp/subscribers","subscription_url":"https://api.github.com/repos/pulp/pulp/subscription","commits_url":"https://api.github.com/repos/pulp/pulp/commits{/sha}","git_commits_url":"https://api.github.com/repos/pulp/pulp/git/commits{/sha}","comments_url":"https://api.github.com/repos/pulp/pulp/comments{/number}","issue_comment_url":"https://api.github.com/repos/pulp/pulp/issues/comments/{number}","contents_url":"https://api.github.com/repos/pulp/pulp/contents/{+path}","compare_url":"https://api.github.com/repos/pulp/pulp/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pulp/pulp/merges","archive_url":"https://api.github.com/repos/pulp/pulp/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pulp/pulp/downloads","issues_url":"https://api.github.com/repos/pulp/pulp/issues{/number}","pulls_url":"https://api.github.com/repos/pulp/pulp/pulls{/number}","milestones_url":"https://api.github.com/repos/pulp/pulp/milestones{/number}","notifications_url":"https://api.github.com/repos/pulp/pulp/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pulp/pulp/labels{/name}","releases_url":"https://api.github.com/repos/pulp/pulp/releases{/id}","created_at":"2012-08-06T13:49:20Z","updated_at":"2015-01-26T22:15:33Z","pushed_at":"2015-01-26T20:01:31Z","git_url":"git://github.com/pulp/pulp.git","ssh_url":"git@github.com:pulp/pulp.git","clone_url":"https://github.com/pulp/pulp.git","svn_url":"https://github.com/pulp/pulp","homepage":"","size":200004,"stargazers_count":177,"watchers_count":177,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":75,"mirror_url":null,"open_issues_count":25,"forks":75,"open_issues":25,"watchers":177,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pulp/pulp/pulls/1549"},"html":{"href":"https://github.com/pulp/pulp/pull/1549"},"issue":{"href":"https://api.github.com/repos/pulp/pulp/issues/1549"},"comments":{"href":"https://api.github.com/repos/pulp/pulp/issues/1549/comments"},"review_comments":{"href":"https://api.github.com/repos/pulp/pulp/pulls/1549/comments"},"review_comment":{"href":"https://api.github.com/repos/pulp/pulp/pulls/comments/{number}"},"commits":{"href":"https://api.github.com/repos/pulp/pulp/pulls/1549/commits"},"statuses":{"href":"https://api.github.com/repos/pulp/pulp/statuses/e5009b0370ff98cb7d629d8b1382d12942a1d4ae"}}}}