From 90d737ad2451afec7e49a5cf3b6d49113e2e73af Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Wed, 27 Dec 2017 20:17:39 -0600 Subject: [PATCH 01/56] Update Email class for attributes and docs Re-record GitHub.add_email_addreses test for correctness --- github3/users.py | 30 +++++++++++++------ .../cassettes/GitHub_add_email_addresses.json | 2 +- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/github3/users.py b/github3/users.py index 0a6c32748..a5b6a9c3a 100644 --- a/github3/users.py +++ b/github3/users.py @@ -104,23 +104,35 @@ def is_free(self): class Email(models.GitHubCore): - """The :class:`Email` object. + """The object used to represent an AuthenticatedUser's email. Please see GitHub's `Emails documentation`_ for more information. .. _Emails documentation: https://developer.github.com/v3/users/emails/ - """ - def _update_attributes(self, email): - #: Email address - self.email = self._get_attribute(email, 'email') + The attributes represented on this object include: + + .. attribute:: email + + The email address as a string + + .. attribute:: verified - #: Whether the address has been verified - self.verified = self._get_attribute(email, 'verified') + A boolean value representing whether the address has been verified or + not - #: Whether the address is the primary address - self.primary = self._get_attribute(email, 'primary') + .. attribute:: primary + + A boolean value representing whether the address is the primary + address for the user or not + """ + + def _update_attributes(self, email): + self.email = email['email'] + self.verified = email['verified'] + self.primary = email['primary'] + self.visibility = email['visibility'] def _repr(self): return ''.format(self.email) diff --git a/tests/cassettes/GitHub_add_email_addresses.json b/tests/cassettes/GitHub_add_email_addresses.json index 0e52fe413..ff0550694 100644 --- a/tests/cassettes/GitHub_add_email_addresses.json +++ b/tests/cassettes/GitHub_add_email_addresses.json @@ -1 +1 @@ -{"recorded_with": "betamax/0.5.1", "http_interactions": [{"recorded_at": "2015-12-20T18:56:05", "response": {"url": "https://api.github.com/user/emails", "status": {"code": 201, "message": "Created"}, "headers": {"Server": "GitHub.com", "Date": "Sun, 20 Dec 2015 18:56:05 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "ETag": "\"b4fdbf10626c0cffe2eb8fe3ad230ec1\"", "X-Content-Type-Options": "nosniff", "X-RateLimit-Limit": "5000", "Content-Security-Policy": "default-src 'none'", "Content-Type": "application/json; charset=utf-8", "X-GitHub-Request-Id": "451DE1EB:14B57:380B98F:5676F9C5", "Content-Length": "206", "Access-Control-Allow-Credentials": "true", "X-RateLimit-Remaining": "4997", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Cache-Control": "private, max-age=60, s-maxage=60", "Access-Control-Allow-Origin": "*", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "X-RateLimit-Reset": "1450639603", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Served-By": "2c18a09f3ac5e4dd1e004af7c5a94769", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "Status": "201 Created"}, "body": {"encoding": "utf-8", "string": "[{\"email\":\"gr.aff.at.colmingov@gmail.com\",\"primary\":true,\"verified\":true},{\"email\":\"example1@example.com\",\"primary\":false,\"verified\":false},{\"email\":\"example2@example.com\",\"primary\":false,\"verified\":false}]"}}, "request": {"method": "POST", "uri": "https://api.github.com/user/emails", "headers": {"Authorization": "Basic ", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json", "Content-Length": "48", "Accept-Charset": "utf-8", "Accept-Encoding": "gzip, deflate", "User-Agent": "github3.py/1.0.0a2", "Connection": "keep-alive"}, "body": {"encoding": "utf-8", "string": "[\"example1@example.com\", \"example2@example.com\"]"}}}]} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": "[\"example1@example.com\", \"example2@example.com\"]"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "48", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/user/emails"}, "response": {"body": {"encoding": "utf-8", "string": "[{\"email\":\"gr.aff.at.colmingov@gmail.com\",\"primary\":true,\"verified\":true,\"visibility\":\"public\"},{\"email\":\"example1@example.com\",\"primary\":false,\"verified\":false,\"visibility\":null},{\"email\":\"example2@example.com\",\"primary\":false,\"verified\":false,\"visibility\":null}]"}, "headers": {"Server": "GitHub.com", "Date": "Thu, 28 Dec 2017 02:16:08 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "264", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4999", "X-RateLimit-Reset": "1514430968", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"f35adb2995e0c3b8463dfdd65a8f5e6b\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.071538", "X-GitHub-Request-Id": "CB60:8326:86D1CD8:F4A9819:5A4453E8"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/user/emails"}, "recorded_at": "2017-12-28T02:16:08"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file From ea9c834655dd88481858cc00839e25b8c976d16c Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Wed, 10 Jan 2018 22:24:42 -0600 Subject: [PATCH 02/56] Re-organize attribute documentation for *User objects Add a Contributor object for the Repository.contributors method and update usage and tests. --- github3/repos/repo.py | 2 +- github3/users.py | 256 ++++++++++++++++++--------- tests/integration/test_repos_repo.py | 2 +- 3 files changed, 179 insertions(+), 81 deletions(-) diff --git a/github3/repos/repo.py b/github3/repos/repo.py index fede6e7d2..675a544bb 100644 --- a/github3/repos/repo.py +++ b/github3/repos/repo.py @@ -403,7 +403,7 @@ def contributors(self, anon=False, number=-1, etag=None): params = {} if anon: params = {'anon': 'true'} - return self._iter(int(number), url, users.ShortUser, params, etag) + return self._iter(int(number), url, users.Contributor, params, etag) @requires_auth def create_blob(self, content, encoding): diff --git a/github3/users.py b/github3/users.py index a5b6a9c3a..7dcb4ce3f 100644 --- a/github3/users.py +++ b/github3/users.py @@ -162,55 +162,23 @@ class _User(models.GitHubCore): class_name = '_User' def _update_attributes(self, user): - #: URL of the avatar at gravatar self.avatar_url = user['avatar_url'] - - #: Events URL Template. Expands with ``privacy`` self.events_urlt = URITemplate(user['events_url']) - - #: Followers URL (not a template) self.followers_url = user['followers_url'] - - #: Following URL Template. Expands with ``other_user`` self.following_urlt = URITemplate(user['following_url']) - - #: Gists URL Template. Expands with ``gist_id`` self.gists_urlt = URITemplate(user['gists_url']) - - #: ID of the user's image on Gravatar self.gravatar_id = user['gravatar_id'] - - # e.g. https://github.com/self._login - #: URL of the user/org's profile self.html_url = user['html_url'] - - #: Unique ID of the account self.id = user['id'] - - #: User name of the user self.login = user['login'] - - #: Organizations URL (not a template) self.organizations_url = user['organizations_url'] - - #: Received Events URL (not a template) self.received_events_url = user['received_events_url'] - - #: Repostories URL (not a template) self.repos_url = user['repos_url'] - self.site_admin = user.get('site_admin') - - #: Starred URL Template. Expands with ``owner`` and ``repo`` self.starred_urlt = URITemplate(user['starred_url']) - - #: Subscriptions URL (not a template) self.subscriptions_url = user['subscriptions_url'] - self.type = user['type'] - self.url = self._api = user['url'] - self._uniq = self.id def __str__(self): @@ -521,11 +489,113 @@ class ShortUser(_User): with different sets of attributes. .. versionadded:: 1.0.0 + + + .. attribute:: avatar_url + + The URL of the avatar (possibly from Gravatar) + + .. attribute:: events_urlt + + A URITemplate object from ``uritemplate`` that can be used to generate + an events URL + + .. attribute:: followers_url + + A string representing the resource to retrieve a User's followers + + .. attribute:: following_urlt + + A URITemplate object from ``uritemplate`` that can be used to generate + the URL to check if this user is following ``other_user`` + + .. attribute:: gists_urlt + + A URITemplate object from ``uritemplate`` that can be used to generate + the URL to retrieve a Gist by its id + + .. attribute:: gravatar_id + + The identifier for the user's gravatar + + .. attribute:: html_url + + The URL of the user's publicly visible profile. For example, + ``https://github.com/sigmavirus24`` + + .. attribute:: id + + The unique ID of the account + + .. attribute:: login + + The username of the user, e.g., ``sigmavirus24`` + + .. attribute:: organizations_url + + A string representing the resource to retrieve the organizations to + which a user belongs + + .. attribute:: received_events_url + + A string representing the resource to retrieve the events a user + received + + .. attribute:: repos_url + + A string representing the resource to list a user's repositories + + .. attribute:: site_admin + + A boolean attribute indicating whether the user is a member of + GitHub's staff + + .. attribute:: starred_urlt + + A URITemplate object from ``uritemplate`` that can be used to generate + a URL to retrieve whether the user has starred a repository. + + .. attribute:: subscriptions_url + + A string representing the resource to list a user's subscriptions + + .. attribute:: type + + A string representing the type of User account this. In all cases + should be "User" + + .. attribute:: url + + A string of this exact resource retrievable from GitHub's API """ class_name = 'ShortUser' +class Contributor(_User): + """Object for the specialized representation of a contributor. + + When retrieving a repository's contributors, GitHub returns the same + information as a :class:`~github3.users.ShortUser` with an additional + attribute: + + .. versionadded:: 1.0.0 + + This class was added in version 1.0.0 + + .. attribute:: contributions_count + + The number of contributions a contributor has made to the repository + + """ + + class_name = 'Contributor' + + def _update_attributes(self, contributor): + super(Contributor, self)._update_attributes(contributor) + self.contributions = contributor['contributions'] + + class User(_User): """Object for the full representation of a User. @@ -541,53 +611,81 @@ class User(_User): authenticated user (e.g., :meth:`~github3.github.GitHub.me`). .. versionchanged:: 1.0.0 + + This object contains all of the attributes available on + :class:`~github3.users.ShortUser` as well as the following: + + .. attribute:: bio + + The markdown formatted User's biography + + .. attribute:: blog + + The URL of the user's blog + + .. attribute:: company + + The name or GitHub handle of the user's company + + .. attribute:: created_at + + A parsed :class:`~datetime.datetime` object representing the date the + user was created + + .. attribute:: email + + The email address the user has on their public profile page + + .. attribute:: followers_count + + The number of followers of this user + + .. attribute:: following_count + + The number of users this user follows + + .. attribute:: hireable + + Whether or not the user has opted into GitHub jobs advertising + + .. attribute:: location + + The location specified by the user on their public profile + + .. attribute:: name + + The name specified by their user on their public profile + + .. attribute:: public_gists_count + + The number of public gists owned by this user + + .. attribute: public_repos_count + + The number of public repositories owned by this user + + .. attribute:: updated_at + + A parsed :class:`~datetime.datetime` object representing the date + the user was last updated """ class_name = 'User' def _update_attributes(self, user): super(User, self)._update_attributes(user) - #: Markdown formatted biography self.bio = user['bio'] - - #: URL of the blog self.blog = user['blog'] - - #: Name of the company self.company = user['company'] - - #: datetime object representing the date the account was created self.created_at = self._strptime(user['created_at']) - - #: E-mail address of the user/org self.email = user['email'] - - # The number of people following this user - #: Number of followers self.followers_count = user['followers'] - - # The number of people this user follows - #: Number of people the user is following self.following_count = user['following'] - - #: True -- for hire, False -- not for hire self.hireable = user['hireable'] - - #: Location of the user/org self.location = user['location'] - - # e.g. first_name last_name - #: Real name of the user/org self.name = user['name'] - - # The number of public_gists - #: Number of public gists self.public_gists_count = user['public_gists'] - - # The number of public_repos - #: Number of public repos owned by the user/org self.public_repos_count = user['public_repos'] - self.updated_at = self._strptime(user['updated_at']) @@ -604,29 +702,29 @@ class AuthenticatedUser(User): The ``total_private_gists`` attribute is no longer returned by GitHub's API and so is removed. + + This object has all of the same attribute as the + :class:`~github3.users.ShortUser` and :class:`~github3.users.User` objects + as well as: + + .. attribute:: disk_usage + + The amount of repository space that has been used by you, the user + + .. attribute:: owned_private_repos_count + + The number of private repositories owned by you, the user + + .. attribute:: plan + + The name of the plan that you, the user, have purchased """ class_name = 'AuthenticatedUser' def _update_attributes(self, user): super(AuthenticatedUser, self)._update_attributes(user) - #: How much disk consumed by the user self.disk_usage = user['disk_usage'] - - #: Number of private repos owned by this user - self.owned_private_repos = user['owned_private_repos'] - - #: Total number of private repos - self.total_private_repos = user['total_private_repos'] - - #: Which plan this user is on + self.owned_private_repos_count = user['owned_private_repos'] + self.total_private_repos_count = user['total_private_repos'] self.plan = Plan(user['plan']) - - #: Number of repo contributions. Only appears in ``repo.contributors`` - contributions = user.get('contributions') - # The refresh method uses __init__ to replace the attributes on the - # instance with what it receives from the /users/:username endpoint. - # What that means is that contributions is no longer returned and as - # such is changed because it doesn't exist. This guards against that. - if contributions is not None: - self.contributions = contributions diff --git a/tests/integration/test_repos_repo.py b/tests/integration/test_repos_repo.py index 76fe9a9da..be13bb48c 100644 --- a/tests/integration/test_repos_repo.py +++ b/tests/integration/test_repos_repo.py @@ -175,7 +175,7 @@ def test_contributors(self): repository = self.gh.repository('sigmavirus24', 'github3.py') assert repository is not None for contributor in repository.contributors(): - assert isinstance(contributor, github3.users.ShortUser) + assert isinstance(contributor, github3.users.Contributor) assert isinstance(contributor.contributions, int) def test_create_blob(self): From 9722e2ce90a1bb429a2385dcf8dc694210ff0b6a Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Thu, 11 Jan 2018 08:55:12 -0600 Subject: [PATCH 03/56] Fix-up docstrings and add GitHubException --- github3/exceptions.py | 86 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 7 deletions(-) diff --git a/github3/exceptions.py b/github3/exceptions.py index 5484d709c..735a7eb06 100644 --- a/github3/exceptions.py +++ b/github3/exceptions.py @@ -2,10 +2,40 @@ """All exceptions for the github3 library.""" -class GitHubError(Exception): - """The base exception class.""" +class GitHubException(Exception): + """The base exception class. + + .. versionadded:: 1.0.0 + + Necessary to handle pre-response exceptions + + """ + + pass + + +class GitHubError(GitHubException): + """The base exception class for all response-related exceptions. + + .. versionchanged:: 1.0.0 + + This now inherits from :class:`~github3.exceptions.GitHubException` + + .. attribute:: response + + The response object that triggered the exception + + .. attribute:: code + + The response's status code + + .. attribute:: errors + + The list of errors (if present) returned by GitHub's API + """ def __init__(self, resp): + """Initialize our exception class.""" super(GitHubError, self).__init__(resp) #: Response code that triggered the error self.response = resp @@ -35,9 +65,18 @@ def message(self): class IncompleteResponse(GitHubError): - """Exception for a response that doesn't have everything it should.""" + """Exception for a response that doesn't have everything it should. + + This has the same attributes as :class:`~github3.exceptions.GitHubError` + as well as + + .. attribute:: exception + + The original exception causing the IncompleteResponse exception + """ def __init__(self, json, exception): + """Initialize our IncompleteResponse.""" self.response = None self.code = None self.json = json @@ -50,20 +89,40 @@ def __init__(self, json, exception): ) % (exception,) +class NotRefreshable(GitHubException): + """Exception to indicate that an object is not refreshable.""" + + message_format = ('"{}" is not refreshable because the GitHub API does ' + 'not provide a URL to retrieve its contents from.') + + def __init__(self, object_name): + """Initialize our NotRefreshable exception.""" + super(NotRefreshable, self).__init__( + self.message_format.format(object_name) + ) + + class ResponseError(GitHubError): """The base exception for errors stemming from GitHub responses.""" + pass -class TransportError(GitHubError): - """Catch-all exception for errors coming from Requests.""" +class TransportError(GitHubException): + """Catch-all exception for errors coming from Requests. + + .. versionchanged:: 1.0.0 + + Now inherits from :class:`~github3.exceptions.GitHubException`. + """ msg_format = 'An error occurred while making a request to GitHub: {0}' def __init__(self, exception): - Exception.__init__(self, exception) - self.exception = exception + """Initialize TransportError exception.""" self.msg = self.msg_format.format(str(exception)) + super(TransportError, self).__init__(self, self.msg, exception) + self.exception = exception def __str__(self): return '{0}: {1}'.format(type(self.exception), self.msg) @@ -77,7 +136,9 @@ class ConnectionError(TransportError): class UnprocessableResponseBody(ResponseError): """Exception class for response objects that cannot be handled.""" + def __init__(self, message, body): + """Initialize UnprocessableResponseBody.""" Exception.__init__(self, message) self.body = body self.msg = message @@ -91,6 +152,7 @@ def __str__(self): class BadRequest(ResponseError): """Exception class for 400 responses.""" + pass @@ -102,6 +164,7 @@ class AuthenticationFailed(ResponseError): - Need one time password (for two-factor authentication) - You are not authorized to access the resource """ + pass @@ -113,21 +176,25 @@ class ForbiddenError(ResponseError): - Too many requests (you've exceeded the ratelimit) - Too many login failures """ + pass class NotFoundError(ResponseError): """Exception class for 404 responses.""" + pass class MethodNotAllowed(ResponseError): """Exception class for 405 responses.""" + pass class NotAcceptable(ResponseError): """Exception class for 406 responses.""" + pass @@ -138,26 +205,31 @@ class Conflict(ResponseError): - Head branch was modified (SHA sums do not match) """ + pass class UnprocessableEntity(ResponseError): """Exception class for 422 responses.""" + pass class ClientError(ResponseError): """Catch-all for 400 responses that aren't specific errors.""" + pass class ServerError(ResponseError): """Exception class for 5xx responses.""" + pass class UnavailableForLegalReasons(ResponseError): """Exception class for 451 responses.""" + pass From 8e38d15adeb851aea66f9da7c0d90f4622c50ae2 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Thu, 11 Jan 2018 09:08:41 -0600 Subject: [PATCH 04/56] Update github3.users.Key to access attributes Also update our class documentation to be better. --- github3/users.py | 25 +++++++++++++++---------- tests/cassettes/User_keys.json | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/github3/users.py b/github3/users.py index 7dcb4ce3f..c421a13e8 100644 --- a/github3/users.py +++ b/github3/users.py @@ -13,25 +13,30 @@ class Key(models.GitHubCore): - """The :class:`Key ` object. + """The object representing a user's SSH key. Please see GitHub's `Key Documentation`_ for more information. .. _Key Documentation: http://developer.github.com/v3/users/keys/ - """ - def _update_attributes(self, key, session=None): - self._api = self._get_attribute(key, 'url') + .. versionchanged:: 1.0.0 - #: The text of the actual key - self.key = self._get_attribute(key, 'key') + Removed ``title`` attribute - #: The unique id of the key at GitHub - self.id = self._get_attribute(key, 'id') + .. attribute:: key - #: The title the user gave to the key - self.title = self._get_attribute(key, 'title') + A string containing the actual text of the SSH Key + + .. attribute:: id + + GitHub's unique ID for this key + """ + + def _update_attributes(self, key, session=None): + self._api = key.get('url') + self.key = key['key'] + self.id = key['id'] def _repr(self): return ''.format(self.title) diff --git a/tests/cassettes/User_keys.json b/tests/cassettes/User_keys.json index 76331ec2a..f0e29b967 100644 --- a/tests/cassettes/User_keys.json +++ b/tests/cassettes/User_keys.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Charset": "utf-8", "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0"}, "method": "GET", "uri": "https://api.github.com/users/sigmavirus24"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA52UT2+cMBDFv0rkMxuDF/aPpaqVesqhlypVpVxWxhh2VGMj24C2KP3sHcM2SrhUuyeQmd+b58HPE9G2AUM48dC0YgDXe5aThEBFOMvTwzZNiBhEEO7UO4115xA6zyldFv1jA+Hcl71XTloTlAmP0ra0pwv8efjEUK1xV40oS2SWH7bFrjoc6yMr1O7Isv2hVCqrjlsh6z0Cq14dXPss4tjM05Xhc2j1yuJibUZWxbXV2o6ost7U/xrRNxJNLu9gmjtVkJyoDWeFs8UtvcZBgQ+3m5qpicbHCaqo4/GHOVXdbOzKoa3RoKOJOtXZWbAvvXTQBbDmdoMfaFSzrhEGfov71JD2KBKt3W5lppBWA57V2/EFm2jnYBDyEkfjlFQw4LDvlFzxqBguncKc/MBDEUcPQZ1E1caY1kJ7lRAj2ljwJMzDV+sq4aXFQjzonTAX/PBdyF++E1LhaokJv+YWYzuOIwai0VDOufgDcuHpXJbgdSDnv4LEN1GBtyZ5+PkU59UKiPnHKNe1CNJqNNTY4QteG6CjGBadwSlRavR2NVqCJdz0Wiek60sN8rTMn+93byvz6SW8KP4lCnNJeJaxdwmLlxFuENUDDloENMLSLN2k+SZLn9Ocp3u+ZS9ooe+qDzX5Jj1sGHvOGM8LzooX8voX7IDCXfUEAAA=", "encoding": "utf-8"}, "headers": {"vary": "Accept, Accept-Encoding", "x-served-by": "88d924ed861736d2749ce1a55766cb53", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"ae5a7e3f4176271842f8995082d0d112\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "55", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "C61B3D82:0871:975D012:53F741A2", "cache-control": "public, max-age=60, s-maxage=60", "last-modified": "Fri, 22 Aug 2014 12:45:25 GMT", "date": "Fri, 22 Aug 2014 13:12:02 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "60", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1408715415"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/users/sigmavirus24"}, "recorded_at": "2014-08-22T13:12:02"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Charset": "utf-8", "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0"}, "method": "GET", "uri": "https://api.github.com/users/sigmavirus24/keys?per_page=100"}, "response": {"body": {"string": "", "base64_string": "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", "encoding": "utf-8"}, "headers": {"vary": "Accept, Accept-Encoding", "x-served-by": "d818ddef80f4c7d10683dd483558952a", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"08f544aa3dab0a20c270c8f2c74f67b3\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "54", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "C61B3D82:0871:975D02B:53F741A2", "cache-control": "public, max-age=60, s-maxage=60", "date": "Fri, 22 Aug 2014 13:12:02 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "60", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1408715415"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/users/sigmavirus24/keys?per_page=100"}, "recorded_at": "2014-08-22T13:12:02"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/users/sigmavirus24"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA52US2vbQBSF/8qgtWw97NiuoNQhEPAikLYpgWzMSBpLU49mxDwkVJP+9h5JbtJoU+yFsbm+35kzV/fo5AlVcOklnuFFRRuunYmXnu/x3EviZbhZhL5HG2qp3jst0FdaW5skCMaiWcwLbkuXOsN0pqRl0s4zVQUuGOkvzedertBnkV7XQ2EiVvOzzghDzAQTR6WtxMTDePSATJoPSgjVQmXq+n8HBW8kTI6/uSyuVAF5CpQtGYaHK732g+DGXm5qoE5B/7Xnea9j8EQ0yy82duZgq5VwdAo0q9Ug6FKTaV5bruTlBj/QUFO6oJL/otepgTYQ6a1dbmWgQLMGu3g5PmKnoNa8oVnXj0azjPEGw75ScsJD0XY1Qw5+YCn60XPL9jSv+hweqDDM9ySt+oYdleS7pbVgVklyp3ROTaaAYOVrKju0bLFd6uhQSxHlc0CRz7ZtEYxC8HTIx2+ejXQwtPnIfTY8HRAPNOdGSZ887/q5VZQj6NIJ4Xsl14ymAl6sdvCVcgXgXjmZM03UgWwfu7uvt3PyQLm0+KBKyYG15LGzJTxTmZNvLu1IrdVPllkzJ7cO/wzw2Fkpzf62v3ftSKv0kUBi29FKkEHJqIqRIVDElkgX1O51pUVHtqpmEsudHXGF2qWCZ/txE5Jo9emtNATJSzaovAc92azW/4QdL74YE8bFLZ45tbhwHEbhLFzOovApXCbhOlnELzjH1fmHnvUsimfx6im6SW7iJFq8eK9/AINp8dNhBQAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 11 Jan 2018 04:40:00 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "59", "X-RateLimit-Reset": "1515649200", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"15afde425b72e8cc0d7384fb5f4df8e6\"", "Last-Modified": "Tue, 26 Dec 2017 15:52:13 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.032589", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "BB02:19CC:1BE6888:3686A28:5A56EA9F"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/users/sigmavirus24"}, "recorded_at": "2018-01-11T04:40:00"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/users/sigmavirus24/keys?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 11 Jan 2018 04:40:00 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "58", "X-RateLimit-Reset": "1515649200", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"1e2ec5788c1d794a8c8300797cd28b09\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.019409", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "BB02:19CC:1BE68B3:3686A90:5A56EAA0"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/users/sigmavirus24/keys?per_page=100"}, "recorded_at": "2018-01-11T04:40:00"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file From 0ae0f25271ea8c25559d9d5cb384428076401cc9 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Thu, 11 Jan 2018 19:24:17 -0600 Subject: [PATCH 05/56] Migrate Plan to accessing values directly --- github3/users.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/github3/users.py b/github3/users.py index c421a13e8..8792cdab2 100644 --- a/github3/users.py +++ b/github3/users.py @@ -79,20 +79,33 @@ class Plan(models.GitHubCore): .. _Authenticated User: http://developer.github.com/v3/users/#get-the-authenticated-user - """ - def _update_attributes(self, plan): - #: Number of collaborators - self.collaborators = self._get_attribute(plan, 'collaborators') + .. attribute:: collaborators_count + + .. versionchanged:: 1.0.0 + + The number of collaborators allowed on this plan + + .. attribute:: name + + The name of the plan on GitHub - #: Name of the plan - self.name = self._get_attribute(plan, 'name') + .. attribute:: private_repos_count - #: Number of private repos - self.private_repos = self._get_attribute(plan, 'private_repos') + .. versionchanged:: 1.0.0 - #: Space allowed - self.space = self._get_attribute(plan, 'space') + The number of allowed private repositories + + .. attribute:: space + + The amount of space allotted by this plan + """ + + def _update_attributes(self, plan): + self.collaborators = plan['collaborators'] + self.name = plan['name'] + self.private_repos_count = plan['private_repos'] + self.space = plan['space'] def _repr(self): return ''.format(self.name) # (No coverage) @@ -164,6 +177,7 @@ class _User(models.GitHubCore): .. _User section: http://developer.github.com/v3/users/ """ + class_name = '_User' def _update_attributes(self, user): From 331f56c991afdbd091378968190f59faa2ced9c6 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Mon, 15 Jan 2018 23:19:53 -0600 Subject: [PATCH 06/56] Update github3.pulls to access attributes directly Also improve our documentation --- github3/pulls.py | 914 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 648 insertions(+), 266 deletions(-) diff --git a/github3/pulls.py b/github3/pulls.py index 471961e27..f325a5516 100644 --- a/github3/pulls.py +++ b/github3/pulls.py @@ -16,81 +16,154 @@ class PullDestination(models.GitHubCore): - """The :class:`PullDestination ` object. + """The object that represents a pull request destination. - Please see GitHub's `PullRequest Documentation`_ for more information. + This is the base class for the :class:`~github3.pulls.Head` and + :class:`~github3.pulls.Base` objects. Each has identical attributes to + this object. + + Please see GitHub's `Pull Request Documentation`_ for more information. .. _PullRequest Documentation: http://developer.github.com/v3/pulls/#get-a-single-pull-request + + .. attribute:: ref + + The full reference string for the git object + + .. attribute:: label + + The label for the destination (e.g., 'master', 'mybranch') + + .. attribute:: user + + If provided, a :class:`~github3.users.ShortUser` instance representing + the owner of the destination + + .. attribute:: sha + + The SHA of the commit at the head of the destination + + .. attribute:: repository + + A :class:`~github3.repos.repo.ShortRepository` representing the + repository containing this destination + + .. attribute:: repo + + A tuple containing the login and repository name, e.g., + ('sigmavirus24', 'github3.py') + + This attribute is generated by github3.py and may be deprecated in the + future. """ - def __init__(self, dest, direction): - super(PullDestination, self).__init__(dest) + direction = None + + def _update_attributes(self, dest): from .repos.repo import ShortRepository - #: Direction of the merge with respect to this destination - self.direction = direction #: Full reference string of the object - self.ref = dest.get('ref') + self.ref = dest['ref'] #: label of the destination - self.label = dest.get('label') + self.label = dest['label'] #: :class:`User ` representing the owner - self.user = None - if dest.get('user'): - self.user = users.ShortUser(dest.get('user'), None) + self.user = dest.get('user') + if self.user: + self.user = users.ShortUser(self.user, self) #: SHA of the commit at the head - self.sha = dest.get('sha') + self.sha = dest['sha'] self._repo_name = '' self._repo_owner = '' - if dest.get('repo'): - self._repo_name = dest['repo'].get('name') - self._repo_owner = dest['repo']['owner'].get('login') - self.repository = ShortRepository(dest.get('repo'), self) + repo = dest.get('repo') + if repo: + self._repo_name = repo.get('name') + self._repo_owner = repo['owner']['login'] + self.repository = ShortRepository(repo, self) self.repo = (self._repo_owner, self._repo_name) def _repr(self): return '<{0} [{1}]>'.format(self.direction, self.label) -class PullFile(models.GitHubCore): +class Head(PullDestination): + """An object representing the Head destination of a pull request. + + See :class:`~github3.pulls.PullDestination` for more details. + """ + + destination = 'Head' + + +class Base(PullDestination): + """An object representing the Base destination of a pull request. - """The :class:`PullFile ` object. + See :class:`~github3.pulls.PullDestination` for more details. + """ + + destination = 'Base' - Please see GitHub's `PR Files Documentation`_ for more information. + +class PullFile(models.GitHubCore): + """The object that represents a file in a pull request. + + Please see GitHub's `Pull Request Files Documentation`_ for more + information. .. _PR Files Documentation: http://developer.github.com/v3/pulls/#list-pull-requests-files - """ - def _update_attributes(self, pfile): - #: SHA of the commit - self.sha = self._get_attribute(pfile, 'sha') + .. attribute:: additions_count - #: Name of the file - self.filename = self._get_attribute(pfile, 'filename') + The number of additions made to this file - #: Status of the file, e.g., 'added' - self.status = self._get_attribute(pfile, 'status') + .. attribute:: blob_url - #: Number of additions on this file - self.additions_count = self._get_attribute(pfile, 'additions') + The API resource used to retrieve the blob for this file - #: Number of deletions on this file - self.deletions_count = self._get_attribute(pfile, 'deletions') + .. attribute:: changes_count - #: Number of changes made to this file - self.changes_count = self._get_attribute(pfile, 'changes') + The number of changes made to this file - #: URL to view the blob for this file - self.blob_url = self._get_attribute(pfile, 'blob_url') + .. attribute:: contents_url - #: URL to view the raw diff of this file - self.raw_url = self._get_attribute(pfile, 'raw_url') + The API resource to view the raw contents of this file - #: Patch generated by this pull request - self.patch = self._get_attribute(pfile, 'patch') + .. attribute:: deletions_count - #: URL to JSON object with content and metadata - self.contents_url = self._get_attribute(pfile, 'contents_url') + The number of deletions made to this file + + .. attribute:: filename + + The name of this file + + .. attribute:: patch + + The patch generated by this + + .. attribute:: raw_url + + The API resource to view the raw diff of this file + + .. attribute:: sha + + The SHA of the commit that this file belongs to + + .. attribute:: status + + The string with the status of the file, e.g., 'added' + """ + + def _update_attributes(self, pfile): + self.sha = pfile['sha'] + self.filename = pfile['filename'] + self.status = pfile['status'] + self.additions_count = pfile['additions'] + self.deletions_count = pfile['deletions'] + self.changes_count = pfile['changes'] + self.blob_url = pfile['blob_url'] + self.raw_url = pfile['raw_url'] + self.patch = pfile['patch'] + self.contents_url = pfile['contents_url'] def _repr(self): return ''.format(self.filename) @@ -98,14 +171,16 @@ def _repr(self): def contents(self): """Return the contents of the file. - :returns: :class:`Contents ` + :returns: + An object representing the contents of this file + :rtype: + :class:`Contents ` """ json = self._json(self._get(self.contents_url), 200) return self._instance_or_null(Contents, json) class _PullRequest(models.GitHubCore): - """The :class:`PullRequest ` object. Please see GitHub's `PullRequests Documentation`_ for more information. @@ -116,79 +191,41 @@ class _PullRequest(models.GitHubCore): def _update_attributes(self, pull): self._api = pull['url'] - - #: Base of the merge - self.base = PullDestination(pull['base'], 'Base') - - #: Body of the pull request message + self.assignee = pull['assignee'] + if self.assignee is not None: + self.assignee = users.ShortUser(self.assignee, self) + self.assignees = [users.ShortUser(a, self) for a in pull['assignees']] + self.base = Base(pull['base'], self) self.body = pull['body'] - - #: Body of the pull request as HTML self.body_html = pull['body_html'] - - #: Body of the pull request as plain text self.body_text = pull['body_text'] - - #: datetime object representing when the pull was closed - self.closed_at = self._strptime_attribute(pull, 'closed_at') - - #: datetime object representing when the pull was created - self.created_at = self._strptime_attribute(pull, 'created_at') - - #: The new head after the pull request - self.head = PullDestination(pull['head'], 'Head') - - #: The unique id of the pull request - self.id = self._get_attribute(pull, 'id') - - #: Dictionary of _links. Changed in 1.0 - self.links = self._get_attribute(pull, '_links', {}) - - #: If unmerged, holds the sha of the commit to test mergability. - #: If merged, holds commit sha of the merge commit, squashed commit on - #: the base branch or the commit that the base branch was updated to - #: after rebasing the PR. + self.closed_at = self._strptime(pull['closed_at']) + self.comments_url = pull['comments_url'] + self.commits_url = pull['commits_url'] + self.created_at = self._strptime(pull['created_at']) + self.diff_url = pull['diff_url'] + self.head = Head(pull['head'], self) + self.html_url = pull['html_url'] + self.id = pull['id'] + self.issue_url = pull['issue_url'] + self.links = pull['_links'] self.merge_commit_sha = pull['merge_commit_sha'] - - #: datetime object representing when the pull was merged - self.merged_at = self._strptime_attribute(pull, 'merged_at') - - #: Number of the pull/issue on the repository + self.merged_at = self._strptime(pull['merged_at']) self.number = pull['number'] + self.patch_url = pull['patch_url'] + self.review_comment_urlt = URITemplate(pull['review_comment_url']) + self.review_comments_url = pull['review_comments_url'] - #: Review comment URL Template. Expands with ``number`` - self.review_comment_url = URITemplate(pull['review_comment_url']) - - #: Returns ('owner', 'repository') this issue was filed on. - self.repository = self.base - if self.repository: - self.repository = self.base.repo + self.repository = None + if self.base: + self.repository = self.base.repository - #: The state of the pull self.state = pull['state'] - - #: The title of the request + self.statuses_url = pull['statuses_url'] self.title = pull['title'] - - #: datetime object representing the last time the object was changed - self.updated_at = self._strptime_attribute(pull, 'updated_at') - - #: :class:`User ` object representing the - #: creator of the pull request + self.updated_at = self._strptime(pull['updated_at']) self.user = users.ShortUser(pull['user']) - # This is only present if the PR has been assigned. - #: :class:`User ` object representing the - #: assignee of the pull request - self.assignee = self._class_attribute( - pull, 'assignee', users.ShortUser, self, - ) - - for urltype in ['comments_url', 'commits_url', 'diff_url', - 'html_url', 'issue_url', 'statuses_url', - 'patch_url', 'review_comments_url']: - setattr(self, urltype, pull[urltype]) - def _repr(self): return ''.format(self.number) @@ -196,7 +233,10 @@ def _repr(self): def close(self): """Close this Pull Request without merging. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ return self.update(self.title, self.body, 'closed') @@ -204,8 +244,12 @@ def close(self): def create_comment(self, body): """Create a comment on this pull request's issue. - :param str body: (required), comment body - :returns: :class:`IssueComment ` + :param str body: + (required), comment body + :returns: + the comment that was created on the pull request + :rtype: + :class:`~github3.issues.comment.IssueComment` """ url = self.comments_url json = None @@ -217,14 +261,22 @@ def create_comment(self, body): def create_review_comment(self, body, commit_id, path, position): """Create a review comment on this pull request. - All parameters are required by the GitHub API. - - :param str body: The comment text itself - :param str commit_id: The SHA of the commit to comment on - :param str path: The relative path of the file to comment on - :param int position: The line index in the diff to comment on. - :returns: The created review comment. - :rtype: :class:`~github3.pulls.ReviewComment` + .. note:: + + All parameters are required by the GitHub API. + + :param str body: + The comment text itself + :param str commit_id: + The SHA of the commit to comment on + :param str path: + The relative path of the file to comment on + :param int position: + The line index in the diff to comment on. + :returns: + The created review comment. + :rtype: + :class:`~github3.pulls.ReviewComment` """ url = self._build_url('comments', base_url=self._api) data = {'body': body, 'commit_id': commit_id, 'path': path, @@ -235,7 +287,10 @@ def create_review_comment(self, body, commit_id, path, position): def diff(self): """Return the diff. - :returns: bytestring representation of the diff. + :returns: + representation of the diff + :rtype: + bytes """ resp = self._get(self._api, headers={'Accept': 'application/vnd.github.diff'}) @@ -244,75 +299,95 @@ def diff(self): def is_merged(self): """Check to see if the pull request was merged. - :returns: bool - """ - if self.merged: - return self.merged + .. versionchanged:: 1.0.0 + This now always makes a call to the GitHub API. To avoid that, + check :attr:`merged` before making this call. + + :returns: + True if merged, False otherwise + :rtype: + bool + """ url = self._build_url('merge', base_url=self._api) return self._boolean(self._get(url), 204, 404) def issue(self): """Retrieve the issue associated with this pull request. - :returns: :class:`~github3.issues.Issue` + :returns: + the issue object that this pull request builds upon + :rtype: + :class:`~github3.issues.Issue` """ json = self._json(self._get(self.issue_url), 200) return self._instance_or_null(Issue, json) def commits(self, number=-1, etag=None): - r"""Iterate over the commits on this pull request. - - :param int number: (optional), number of commits to return. Default: - -1 returns all available commits. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of - :class:`RepoCommit `\ s + """Iterate over the commits on this pull request. + + :param int number: + (optional), number of commits to return. Default: -1 returns all + available commits. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of repository commit objects + :rtype: + :class:`~github3.repos.commit.RepoCommit` """ url = self._build_url('commits', base_url=self._api) return self._iter(int(number), url, RepoCommit, etag=etag) def files(self, number=-1, etag=None): - r"""Iterate over the files associated with this pull request. - - :param int number: (optional), number of files to return. Default: - -1 returns all available files. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`PullFile `\ s + """Iterate over the files associated with this pull request. + + :param int number: + (optional), number of files to return. Default: -1 returns all + available files. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: generator of pull request files + :rtype: :class:`~PullFile` """ url = self._build_url('files', base_url=self._api) return self._iter(int(number), url, PullFile, etag=etag) def issue_comments(self, number=-1, etag=None): - r"""Iterate over the issue comments on this pull request. - - :param int number: (optional), number of comments to return. Default: - -1 returns all available comments. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`IssueComment `\ s + """Iterate over the issue comments on this pull request. + + In this case, GitHub leaks implementation details. Pull Requests are + really just Issues with a diff. As such, comments on a pull request + that are not in-line with code, are technically issue comments. + + :param int number: + (optional), number of comments to return. Default: -1 returns all + available comments. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of non-review comments on this pull request + :rtype: + :class:`~github3.issues.comment.IssueComment` """ comments = self.links.get('comments', {}) url = comments.get('href') - if not url: - url = self._build_url( - 'comments', base_url=self._api.replace('pulls', 'issues') - ) return self._iter(int(number), url, IssueComment, etag=etag) @requires_auth def merge(self, commit_message=None, sha=None, squash=False): """Merge this pull request. - :param str commit_message: (optional), message to be used for the - merge commit - :param str sha: (optional), SHA that pull request head must match - to merge. - :param bool squash: (optional), commit a single commit to the - head branch. - :returns: bool + :param str commit_message: + (optional), message to be used for the merge commit + :param str sha: + (optional), SHA that pull request head must match to merge. + :param bool squash: + (optional), commit a single commit to the head branch. + :returns: + True if successful, False otherwise + :rtype: + bool """ parameters = {'squash': squash} if sha: @@ -328,7 +403,10 @@ def merge(self, commit_message=None, sha=None, squash=False): def patch(self): """Return the patch. - :returns: bytestring representation of the patch + :returns: + bytestring representation of the patch + :rtype: + bytes """ resp = self._get(self._api, headers={'Accept': 'application/vnd.github.patch'}) @@ -338,30 +416,41 @@ def patch(self): def reopen(self): """Re-open a closed Pull Request. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ - return self.update(self.title, self.body, 'open') + return self.update(self.title, self.body, state='open') def review_comments(self, number=-1, etag=None): - r"""Iterate over the review comments on this pull request. - - :param int number: (optional), number of comments to return. Default: - -1 returns all available comments. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`ReviewComment `\ s + """Iterate over the review comments on this pull request. + + :param int number: + (optional), number of comments to return. Default: -1 returns all + available comments. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of review comments + :rtype: + :class:`~github3.pulls.ReviewComment` """ url = self._build_url('comments', base_url=self._api) return self._iter(int(number), url, ReviewComment, etag=etag) def reviews(self, number=-1, etag=None): - r"""Iterate over the reviews associated with this pull request. - - :param int number: (optional), number of reviews to return. Default: - -1 returns all available files. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`PullReview `\ s + """Iterate over the reviews associated with this pull request. + + :param int number: + (optional), number of reviews to return. Default: -1 returns all + available files. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of reviews for this pull request + :rtype: + :class:`~github3.pulls.PullReview` """ url = self._build_url('reviews', base_url=self._api) return self._iter(int(number), url, PullReview, etag=etag) @@ -371,14 +460,22 @@ def update(self, title=None, body=None, state=None, base=None, maintainer_can_modify=None): """Update this pull request. - :param str title: (optional), title of the pull - :param str body: (optional), body of the pull request - :param str state: (optional), ('open', 'closed') - :param str base: (optional), Name of the branch on the current - repository that the changes should be pulled into. - :param bool maintainer_can_modify: (optional), Indicates whether - a maintainer is allowed to modify the pull request or not. - :returns: bool + :param str title: + (optional), title of the pull + :param str body: + (optional), body of the pull request + :param str state: + (optional), one of ('open', 'closed') + :param str base: + (optional), Name of the branch on the current repository that the + changes should be pulled into. + :param bool maintainer_can_modify: + (optional), Indicates whether a maintainer is allowed to modify the + pull request or not. + :returns: + True if successful, False otherwise + :rtype: + bool """ data = { 'title': title, @@ -400,15 +497,153 @@ def update(self, title=None, body=None, state=None, base=None, class ShortPullRequest(_PullRequest): - """Object for the shortened representation of a PullRequest + """Object for the shortened representation of a PullRequest. GitHub's API returns different amounts of information about prs based upon how that information is retrieved. Often times, when iterating over several prs, GitHub will return less information. To provide a clear - distinction between the types of prs, github3.py uses different classes - with different sets of attributes. + distinction between the types of Pull Requests, github3.py uses different + classes with different sets of attributes. .. versionadded:: 1.0.0 + + The attributes available on this object are: + + .. attribute:: url + + The URL that describes this exact pull request. + + .. attribute:: assignee + + .. deprecated:: 1.0.0 + + Use :attr:`assignees` instead. + + The assignee of the pull request, if present, represented as an + instance of :class:`~github3.users.ShortUser` + + .. attribute:: assignees + + .. versionadded:: 1.0.0 + + A list of the assignees of the pull request. If not empty, a list + of instances of :class:`~github3.users.ShortUser`. + + .. attribute:: base + + A :class:`~github3.pulls.Base` object representing the base pull + request destination. + + .. attribute:: body + + The Markdown formatted body of the pull request message. + + .. attribute:: body_html + + The HTML formatted body of the pull request mesage. + + .. attribute:: body_text + + The plain-text formatted body of the pull request message. + + .. attribute:: closed_at + + A :class:`~datetime.datetime` object representing the date and time + when this pull request was closed. + + .. attribute:: comments_url + + The URL to retrieve the comments on this pull request from the API. + + .. attribute:: commits_url + + The URL to retrieve the commits in this pull request from the API. + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + when this pull request was created. + + .. attribute:: diff_url + + The URL to retrieve the diff for this pull request via the API. + + .. attribute:: head + + A :class:`~github3.pulls.Head` object representing the head pull + request destination. + + .. attribute:: html_url + + The URL one would use to view this pull request in the browser. + + .. attribute:: id + + The unique ID of this pull request across all of GitHub. + + .. attribute:: issue_url + + The URL of the resource that represents this pull request as an issue. + + .. attribute:: links + + A dictionary provided by ``_links`` in the API response. + + .. versionadded:: 1.0.0 + + .. attribute:: merge_commit_sha + + If unmerged, holds the sha of the commit to test mergability. + If merged, holds commit sha of the merge commit, squashed commit on + the base branch or the commit that the base branch was updated to + after rebasing the PR. + + .. attribute:: merged_at + + A :class:`~datetime.datetime` object representing the date and time + this pull request was merged. If this pull request has not been merged + then this attribute will be ``None``. + + .. attribute:: number + + The number of the pull request on the repository. + + .. attribute:: patch_url + + The URL to retrieve the patch for this pull request via the API. + + .. attribute:: repository + + A :class:`~github3.repos.repo.ShortRepository` from the :attr:`base` + instance. + + .. attribute:: review_comment_urlt + + A URITemplate instance that expands to provide the review comment URL + provided a number. + + .. attribute:: review_comments_url + + The URl to retrieve all review comments on this pull request from the + API. + + .. attribute:: state + + The current state of this pull request. + + .. attribute:: title + + The title of this pull request. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` instance representing the date and time + when this pull request was last updated. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` instance representing who opened + this pull request. """ pass @@ -426,140 +661,287 @@ class PullRequest(_PullRequest): with different sets of attributes. .. versionchanged:: 1.0.0 - """ - def _update_attributes(self, pull): - super(PullRequest, self)._update_attributes(pull) + This object has all of the same attributes as + :class:`~github3.pulls.ShortPullRequest` as well as the following: - #: Number of additions on this pull request - self.additions_count = pull['additions'] + .. attribute:: additions_count - #: Number of deletions on this pull request - self.deletions_count = pull['deletions'] + The number of lines of code added in this pull request. - #: Number of comments - self.comments_count = pull['comments'] + .. attribute:: deletions_count - #: Number of commits - self.commits_count = pull['commits'] + The number of lines of code deleted in this pull request. - #: Boolean representing whether the pull request has been merged - self.merged = pull['merged'] + .. attribute:: comments_count - # This can be True, False, or None(Null). None is when the - # mergeability is still being computed. We default to False - # in that case. - #: Whether the pull is deemed mergeable by GitHub - self.mergeable = self._get_attribute(pull, 'mergeable', False) + The number of comments left on this pull request. - #: Whether it would be a clean merge or not - self.mergeable_state = pull['mergeable_state'] + .. attribute:: commits_count + + The number of commits included in this pull request. + + .. attribute:: mergeable + + A boolean attribute indicating whether GitHub deems this pull request + is mergeable. + + .. attribute:: mergeable_state + + A string indicating whether this would be a 'clean' or 'dirty' merge. - # This may? be None(Null) while mergeability is being determined - #: :class:`User ` who merged this pull - self.merged_by = self._class_attribute( - pull, 'merged_by', users.ShortUser, self, - ) + .. attribute:: merged - #: Number of review comments on the pull request + A boolean attribute indicating whether the pull request has been merged + or not. + + .. attribute:: merged_by + + An instance of :class:`~github3.users.ShortUser` to indicate the user + who merged this pull request. If this hasn't been merged or if + :attr:`mergeable` is still being decided by GitHub this will be + ``None``. + + .. attribute:: review_comments_count + + The number of review comments on this pull request. + """ + + def _update_attributes(self, pull): + super(PullRequest, self)._update_attributes(pull) + self.additions_count = pull['additions'] + self.deletions_count = pull['deletions'] + self.comments_count = pull['comments'] + self.commits_count = pull['commits'] + self.mergeable = pull['mergeable'] + self.mergeable_state = pull['mergeable_state'] + self.merged = pull['merged'] + self.merged_by = pull['merged_by'] + if self.merged_by is not None: + self.merged_by = users.ShortUser(self.merged_by, self) self.review_comments_count = pull['review_comments'] class PullReview(models.GitHubCore): + """Object representing a Pull Request Review returned by the API. - """The :class:`PullReview ` object. - - Please see GitHub's `PullReview Documentation`_ for more information. + Please see GitHub's `Pull Review Documentation`_ for more information. .. _PullReview Documentation: https://developer.github.com/v3/pulls/reviews/ - """ - def _update_attributes(self, preview): - #: ID of the review - self.id = self._get_attribute(preview, 'id') + .. attribute:: id + + The unique ID of this pull request review. + + .. attribute:: author_association + + .. versionadded:: 1.0.0 + + The relationship of this review's author to the project. - #: SHA of the commit the review is on - self.commit_id = self._get_attribute(preview, 'commit_id') + .. attribute:: body - #: :class:`User ` who made the comment - self.user = self._class_attribute( - preview, 'user', users.ShortUser, self, - ) + The Markdown formatted body of this review. - #: State of the review - self.state = self._get_attribute(preview, 'state') + .. attribute:: body_html - #: datetime object representing when the event was created. - self.submitted_at = self._strptime_attribute(preview, 'submitted_at') + .. versionadded:: 1.0.0 - #: Body text of the review - self.body = self._get_attribute(preview, 'body') + The HTML formatted body of this review. - #: API URL for the Pull Request - self.pull_request_url = self._get_attribute( - preview, 'pull_request_url' - ) + .. attribute:: body_text + + .. versionadded:: 1.0.0 + + The plain-text formatted body of this review. + + .. attribute:: commit_id + + The SHA of the commit that the review was left on. + + .. attribute:: html_url + + .. versionadded:: 1.0.0 + + The URL to view this pull request in a browser. + + .. attribute:: pull_request_url + + The URL to retrieve the pull request via the API. + + .. attribute:: state + + The state of this review, e.g., the option specified in the review + dialog by the author. + + .. attribute:: submitted_at + + A :class:`~datetime.datetime` object representing the date and time + this review was submitted. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` instance representing the author + of this review. + """ + + def _update_attributes(self, review): + self.id = review['id'] + self.author_association = review['author_association'] + self.body = review['body'] + self.body_html = review['body_html'] + self.body_text = review['body_text'] + self.commit_id = review['commit_id'] + self.html_url = review['html_url'] + self.user = users.ShortUser(review['user'], self) + self.state = review['state'] + self.submitted_at = review['submitted_at'] + self.pull_request_url = review['pull_request_url'] def _repr(self): return ''.format(self.id) -class ReviewComment(models.BaseComment): - - """The :class:`ReviewComment ` object. +class ReviewComment(models.GitHubCore): + """Object representing review comments left on a pull request. Please see GitHub's `Pull Comments Documentation`_ for more information. .. _Pull Comments Documentation: http://developer.github.com/v3/pulls/comments/ - """ - def _update_attributes(self, comment): - super(ReviewComment, self)._update_attributes(comment) - #: :class:`User ` who made the comment - self.user = self._class_attribute( - comment, 'user', users.ShortUser, self, - ) + .. attribute:: id + + The unique identifier for this comment across all GitHub review + comments. + + .. attribute:: author_association + + The role of the author of this comment on the repository. + + .. attribute:: body + + The Markdown formatted body of this comment. + + .. attribute:: body_html + + The HTML formatted body of this comment. + + .. attribute:: body_text - #: Original position inside the file - self.original_position = self._get_attribute( - comment, - 'original_position' - ) + The plain text formatted body of this comment. - #: Path to the file - self.path = self._get_attribute(comment, 'path') + .. attribute:: commit_id - #: Position within the commit - self.position = self._get_attribute(comment, 'position') + The SHA of current commit this comment was left on. - #: SHA of the commit the comment is on - self.commit_id = self._get_attribute(comment, 'commit_id') + .. attribute:: created_at - #: The diff hunk - self.diff_hunk = self._get_attribute(comment, 'diff_hunk') + A :class:`~datetime.datetime` instance representing the date and time + this comment was created. - #: Original commit SHA - self.original_commit_id = self._get_attribute( - comment, 'original_commit_id' - ) + .. attribute:: diff_hunk - #: API URL for the Pull Request - self.pull_request_url = self._get_attribute( - comment, 'pull_request_url' - ) + A string representation of the hunk of the diff where the comment was + left. + + .. attribute:: html_url + + The URL to view this comment in the webbrowser. + + .. attribute:: links + + A dictionary of relevant URLs usually returned in the ``_links`` + attribute. + + .. attribute:: original_commit_id + + The SHA of the original commit this comment was left on. + + .. attribute:: original_position + + The original position within the diff that this comment was left on. + + .. attribute:: pull_request_url + + The URL to retrieve the pull request via the API. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` instance representing the date and time + this comment was updated. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` instance representing the author + of this comment. + + """ + + def _update_attributes(self, comment): + self._api = comment['url'] + self.id = comment['id'] + self.author_association = comment['author_association'] + self.body = comment['body'] + self.body_html = comment['body_html'] + self.body_text = comment['body_text'] + self.commit_id = comment['commit_id'] + self.created_at = comment['created_at'] + self.diff_hunk = comment['diff_hunk'] + self.html_url = comment['html_url'] + self.links = comment['_links'] + self.original_commit_id = comment['original_commit_id'] + self.original_position = comment['original_position'] + self.path = comment['path'] + self.position = comment['position'] + self.pull_request_url = comment['pull_request_url'] + self.updated_at = comment['updated_at'] + self.user = users.ShortUser(comment['user'], self) def _repr(self): return ''.format(self.user.login) + @requires_auth + def delete(self): + """Delete this comment. + + :returns: + True if successful, False otherwise + :rtype: + bool + """ + return self._boolean(self._delete(self._api), 204, 404) + + @requires_auth + def edit(self, body): + """Edit this comment. + + :param str body: + (required), new body of the comment, Markdown formatted + :returns: + True if successful, False otherwise + :rtype: + bool + """ + if body: + json = self._json(self._patch(self._api, + data=dumps({'body': body})), 200) + if json: + self._update_attributes(json) + return True + return False + @requires_auth def reply(self, body): """Reply to this review comment with a new review comment. - :param str body: The text of the comment. - :returns: The created review comment. - :rtype: :class:`~github3.pulls.ReviewComment` + :param str body: + The text of the comment. + :returns: + The created review comment. + :rtype: + :class:`~github3.pulls.ReviewComment` """ url = self._build_url('comments', base_url=self.pull_request_url) index = self._api.rfind('/') + 1 From a91c04d652232ffe604ee1a14c596f1d8368f0ba Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Thu, 25 Jan 2018 18:35:06 -0600 Subject: [PATCH 07/56] Fix up tests from recent pull request changes --- github3/events.py | 38 ++++++++++++++++++- github3/pulls.py | 4 +- .../PullRequest_create_review_comment.json | 2 +- tests/cassettes/PullRequest_diff.json | 2 +- tests/cassettes/PullRequest_is_merged.json | 2 +- tests/cassettes/PullRequest_patch.json | 2 +- tests/cassettes/PullRequest_pull_reviews.json | 2 +- tests/cassettes/PullRequest_reply.json | 1 - .../PullRequest_review_comments.json | 2 +- tests/cassettes/ReviewComment_reply.json | 2 +- tests/integration/test_pulls.py | 4 +- tests/unit/json/pull_request_example | 19 ++++++++++ tests/unit/json/review_comment_example | 3 ++ tests/unit/test_events.py | 8 +++- tests/unit/test_pulls.py | 7 ---- 15 files changed, 75 insertions(+), 23 deletions(-) delete mode 100644 tests/cassettes/PullRequest_reply.json diff --git a/github3/events.py b/github3/events.py index 9db6a3033..a7a02f107 100644 --- a/github3/events.py +++ b/github3/events.py @@ -74,6 +74,41 @@ def to_pull(self): refresh = to_pull +class EventReviewComment(GitHubCore): + """Representation of review comments in events.""" + + def _update_attributes(self, comment): + from . import users + self._api = comment['url'] + self.id = comment['id'] + self.author_association = comment['author_association'] + self.body = comment['body'] + self.commit_id = comment['commit_id'] + self.created_at = self._strptime(comment['created_at']) + self.diff_hunk = comment['diff_hunk'] + self.html_url = comment['html_url'] + self.links = comment['_links'] + self.original_commit_id = comment['original_commit_id'] + self.original_position = comment['original_position'] + self.path = comment['path'] + self.position = comment['position'] + self.pull_request_url = comment['pull_request_url'] + self.updated_at = self._strptime(comment['updated_at']) + self.user = users.ShortUser(comment['user'], self) + + def to_review_comment(self): + """Retrieve a full ReviewComment object for this EventReviewComment. + + :rtype: + :class:`~github3.pulls.ReviewComment` + """ + from . import pulls + comment = self._json(self._get(self._api), 200) + return pulls.ReviewComment(comment, self) + + refresh = to_review_comment + + class EventIssue(GitHubCore): """The class that represents the issue information returned in Events.""" @@ -210,7 +245,6 @@ def _pullreqev(payload, session): def _pullreqcomm(payload, session): - from .pulls import ReviewComment # Transform the Pull Request attribute pull = payload.get('pull_request') if pull: @@ -219,7 +253,7 @@ def _pullreqcomm(payload, session): # Transform the Comment attribute comment = payload.get('comment') if comment: - payload['comment'] = ReviewComment(comment, session) + payload['comment'] = EventReviewComment(comment, session) return payload diff --git a/github3/pulls.py b/github3/pulls.py index e2b4fd6b9..7417867cc 100644 --- a/github3/pulls.py +++ b/github3/pulls.py @@ -893,7 +893,7 @@ def _update_attributes(self, comment): self.body_html = comment['body_html'] self.body_text = comment['body_text'] self.commit_id = comment['commit_id'] - self.created_at = comment['created_at'] + self.created_at = self._strptime(comment['created_at']) self.diff_hunk = comment['diff_hunk'] self.html_url = comment['html_url'] self.links = comment['_links'] @@ -902,7 +902,7 @@ def _update_attributes(self, comment): self.path = comment['path'] self.position = comment['position'] self.pull_request_url = comment['pull_request_url'] - self.updated_at = comment['updated_at'] + self.updated_at = self._strptime(comment['updated_at']) self.user = users.ShortUser(comment['user'], self) def _repr(self): diff --git a/tests/cassettes/PullRequest_create_review_comment.json b/tests/cassettes/PullRequest_create_review_comment.json index 61055accc..7481799e8 100644 --- a/tests/cassettes/PullRequest_create_review_comment.json +++ b/tests/cassettes/PullRequest_create_review_comment.json @@ -1 +1 @@ -{"recorded_with": "betamax/0.8.0", "http_interactions": [{"recorded_at": "2017-02-12T15:31:31", "response": {"body": {"base64_string": "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", "encoding": "utf-8", "string": ""}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286", "headers": {"Status": "200 OK", "X-Content-Type-Options": "nosniff", "Access-Control-Allow-Origin": "*", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "88AD:551F:32CFEAC:4019298:58A07FD3", "Date": "Sun, 12 Feb 2017 15:31:31 GMT", "X-RateLimit-Remaining": "4985", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Content-Type": "application/json; charset=utf-8", "X-Served-By": "0e17b94a265a427d9cafe798ceea7c02", "Transfer-Encoding": "chunked", "X-XSS-Protection": "1; mode=block", "X-RateLimit-Limit": "5000", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "X-RateLimit-Reset": "1486914697", "Content-Security-Policy": "default-src 'none'", "Server": "GitHub.com", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Last-Modified": "Sat, 11 Feb 2017 13:18:37 GMT", "ETag": "W/\"99b053c19fee88dbadb100a779de9fd6\"", "X-Frame-Options": "deny", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Cache-Control": "private, max-age=60, s-maxage=60"}}, "request": {"body": {"encoding": "utf-8", "string": ""}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286", "method": "GET", "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "Content-Type": "application/json", "Accept-Charset": "utf-8", "Authorization": "Basic ", "Accept": "application/vnd.github.v3.full+json"}}}, {"recorded_at": "2017-02-12T15:31:32", "response": {"body": {"encoding": "utf-8", "string": "{\"url\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/100695517\",\"pull_request_review_id\":21410030,\"id\":100695517,\"diff_hunk\":\"@@ -195,6 +195,25 @@ def close(self):\\n \\\"\\\"\\\"\\n return self.update(self.title, self.body, 'closed')\\n \\n+ @requires_auth\\n+ def create_review_comment(self, body, commit_id, path, position):\\n+ \\\"\\\"\\\"Create a review comment on this pull request.\",\"path\":\"github3/pulls.py\",\"position\":6,\"original_position\":6,\"commit_id\":\"fe5dd44af3eb7110a4a1f8c38f0c9bb235349ff6\",\"original_commit_id\":\"4437428aefdb50913e2acabd0552bd13021dc38f\",\"user\":{\"login\":\"gh3test\",\"id\":2354350,\"avatar_url\":\"https://avatars.githubusercontent.com/u/2354350?v=3\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gh3test\",\"html_url\":\"https://github.com/gh3test\",\"followers_url\":\"https://api.github.com/users/gh3test/followers\",\"following_url\":\"https://api.github.com/users/gh3test/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gh3test/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gh3test/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gh3test/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gh3test/orgs\",\"repos_url\":\"https://api.github.com/users/gh3test/repos\",\"events_url\":\"https://api.github.com/users/gh3test/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gh3test/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"Testing review comments\",\"created_at\":\"2017-02-12T15:31:32Z\",\"updated_at\":\"2017-02-12T15:31:32Z\",\"html_url\":\"https://github.com/sigmavirus24/github3.py/pull/286#discussion_r100695517\",\"pull_request_url\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/286\",\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/100695517\"},\"html\":{\"href\":\"https://github.com/sigmavirus24/github3.py/pull/286#discussion_r100695517\"},\"pull_request\":{\"href\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/286\"}},\"body_html\":\"

Testing review comments

\",\"body_text\":\"Testing review comments\"}"}, "status": {"message": "Created", "code": 201}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments", "headers": {"Status": "201 Created", "X-Content-Type-Options": "nosniff", "Location": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/100695517", "Access-Control-Allow-Origin": "*", "X-GitHub-Request-Id": "88AD:551F:32CFECD:40192AD:58A07FD3", "Date": "Sun, 12 Feb 2017 15:31:32 GMT", "X-RateLimit-Remaining": "4984", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Content-Type": "application/json; charset=utf-8", "X-Served-By": "7b641bda7ec2ca7cd9df72d2578baf75", "X-XSS-Protection": "1; mode=block", "X-RateLimit-Limit": "5000", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "X-RateLimit-Reset": "1486914697", "Content-Security-Policy": "default-src 'none'", "Content-Length": "2120", "Server": "GitHub.com", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "ETag": "\"359f8b24bc15c9c34f16f06320f2556d\"", "X-Frame-Options": "deny", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Cache-Control": "private, max-age=60, s-maxage=60"}}, "request": {"body": {"encoding": "utf-8", "string": "{\"path\": \"github3/pulls.py\", \"body\": \"Testing review comments\", \"position\": 6, \"commit_id\": \"4437428aefdb50913e2acabd0552bd13021dc38f\"}"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments", "method": "POST", "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive", "Content-Length": "135", "Content-Type": "application/json", "Accept-Charset": "utf-8", "Authorization": "Basic ", "Accept": "application/vnd.github.v3.full+json"}}}]} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 12:43:12 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4999", "X-RateLimit-Reset": "1516887792", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"372adf02e27bae1dded67e7e7c603169\"", "Last-Modified": "Tue, 26 Dec 2017 15:52:13 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.262153", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "8BFA:2D36F:10FC775:3218FBD:5A69D0E0"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286"}, "recorded_at": "2018-01-25T12:43:12"}, {"request": {"body": {"encoding": "utf-8", "string": "{\"body\": \"Testing review comments\", \"commit_id\": \"4437428aefdb50913e2acabd0552bd13021dc38f\", \"path\": \"github3/pulls.py\", \"position\": 6}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "135", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments"}, "response": {"body": {"encoding": "utf-8", "string": "{\"url\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/163831550\",\"pull_request_review_id\":91507151,\"id\":163831550,\"diff_hunk\":\"@@ -195,6 +195,25 @@ def close(self):\\n \\\"\\\"\\\"\\n return self.update(self.title, self.body, 'closed')\\n \\n+ @requires_auth\\n+ def create_review_comment(self, body, commit_id, path, position):\\n+ \\\"\\\"\\\"Create a review comment on this pull request.\",\"path\":\"github3/pulls.py\",\"position\":6,\"original_position\":6,\"commit_id\":\"fe5dd44af3eb7110a4a1f8c38f0c9bb235349ff6\",\"original_commit_id\":\"4437428aefdb50913e2acabd0552bd13021dc38f\",\"user\":{\"login\":\"gh3test\",\"id\":2354350,\"avatar_url\":\"https://avatars2.githubusercontent.com/u/2354350?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gh3test\",\"html_url\":\"https://github.com/gh3test\",\"followers_url\":\"https://api.github.com/users/gh3test/followers\",\"following_url\":\"https://api.github.com/users/gh3test/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gh3test/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gh3test/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gh3test/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gh3test/orgs\",\"repos_url\":\"https://api.github.com/users/gh3test/repos\",\"events_url\":\"https://api.github.com/users/gh3test/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gh3test/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"Testing review comments\",\"created_at\":\"2018-01-25T12:43:12Z\",\"updated_at\":\"2018-01-25T12:43:12Z\",\"html_url\":\"https://github.com/sigmavirus24/github3.py/pull/286#discussion_r163831550\",\"pull_request_url\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/286\",\"author_association\":\"NONE\",\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/163831550\"},\"html\":{\"href\":\"https://github.com/sigmavirus24/github3.py/pull/286#discussion_r163831550\"},\"pull_request\":{\"href\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/286\"}},\"body_html\":\"

Testing review comments

\",\"body_text\":\"Testing review comments\"}"}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 12:43:13 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "2149", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4998", "X-RateLimit-Reset": "1516887792", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"c72a7036a3b42e41a69835d039443704\"", "Location": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/163831550", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.407083", "X-GitHub-Request-Id": "8BFA:2D36F:10FC792:3219002:5A69D0E0"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments"}, "recorded_at": "2018-01-25T12:43:13"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/PullRequest_diff.json b/tests/cassettes/PullRequest_diff.json index 8afd06162..73118c792 100644 --- a/tests/cassettes/PullRequest_diff.json +++ b/tests/cassettes/PullRequest_diff.json @@ -1 +1 @@ -{"recorded_with": "betamax/0.6.0", "http_interactions": [{"recorded_at": "2016-04-16T20:35:33", "request": {"body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "method": "GET", "headers": {"Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive"}}, "response": {"status": {"message": "OK", "code": 200}, "body": {"string": "", "encoding": "utf-8", "base64_string": "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"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "headers": {"Status": "200 OK", "Server": "GitHub.com", "X-Frame-Options": "deny", "ETag": "W/\"51c76ea3e3d49ab7622c56288b405062\"", "Content-Security-Policy": "default-src 'none'", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-Served-By": "d0b3c2c33a23690498aa8e70a435a259", "X-RateLimit-Reset": "1460842265", "Date": "Sat, 16 Apr 2016 20:35:33 GMT", "Content-Encoding": "gzip", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-XSS-Protection": "1; mode=block", "X-RateLimit-Limit": "60", "Vary": "Accept", "X-GitHub-Request-Id": "60255B4F:1559F:1091B2D6:5712A215", "Transfer-Encoding": "chunked", "Last-Modified": "Tue, 05 Apr 2016 19:04:53 GMT", "Cache-Control": "public, max-age=60, s-maxage=60", "Access-Control-Allow-Origin": "*", "X-Content-Type-Options": "nosniff", "Content-Type": "application/json; charset=utf-8", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-RateLimit-Remaining": "47"}}}, {"recorded_at": "2016-04-16T20:35:33", "request": {"body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "method": "GET", "headers": {"Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4", "Content-Type": "application/json", "Accept": "application/vnd.github.diff", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive"}}, "response": {"status": {"message": "OK", "code": 200}, "body": {"string": "diff --git a/github3/repos/release.py b/github3/repos/release.py\nindex 8b4f942..10e0b77 100644\n--- a/github3/repos/release.py\n+++ b/github3/repos/release.py\n@@ -22,6 +22,8 @@ class Release(GitHubCore):\n def __init__(self, release, session=None):\n super(Release, self).__init__(release, session)\n self._api = release.get('url')\n+ #: List of :class:`Asset ` objects for this release\n+ self.assets = [Asset(i, self) for i in release.get('assets', [])]\n #: URL for uploaded assets\n self.assets_url = release.get('assets_url')\n #: Body of the release (the description)\ndiff --git a/tests/unit/test_repos_release.py b/tests/unit/test_repos_release.py\nindex c9d12f6..d0cd413 100644\n--- a/tests/unit/test_repos_release.py\n+++ b/tests/unit/test_repos_release.py\n@@ -15,6 +15,18 @@ class TestRelease(UnitHelper):\n example_data = {\n \"url\": releases_url(\"/1\"),\n \"html_url\": \"https://github.com/octocat/Hello-World/releases/v1.0.0\",\n+ \"assets\": [{\n+ \"url\": releases_url(\"/assets/1\"),\n+ \"id\": 1,\n+ \"name\": \"example.zip\",\n+ \"label\": \"short description\",\n+ \"state\": \"uploaded\",\n+ \"content_type\": \"application/zip\",\n+ \"size\": 1024,\n+ \"download_count\": 42,\n+ \"created_at\": \"2013-02-27T19:35:32Z\",\n+ \"updated_at\": \"2013-02-27T19:35:32Z\"\n+ }],\n \"assets_url\": releases_url(\"/1/assets\"),\n \"upload_url\": releases_url(\"/1/assets{?name}\"),\n \"id\": 1,\n@@ -29,6 +41,10 @@ class TestRelease(UnitHelper):\n }\n \n # Attribute tests\n+ def test_assets(self):\n+ assert self.instance.assets is not None\n+ assert isinstance(self.instance.assets[0], Asset)\n+\n def test_has_upload_urlt(self):\n assert self.instance.upload_urlt is not None\n \n", "encoding": "utf-8"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "headers": {"Status": "200 OK", "Server": "GitHub.com", "X-Frame-Options": "deny", "ETag": "\"8793127f3da0d2c6bbff09d2acffd524\"", "Content-Security-Policy": "default-src 'none'", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-Served-By": "07ff1c8a09e44b62e277fae50a1b1dc4", "X-RateLimit-Reset": "1460842265", "Date": "Sat, 16 Apr 2016 20:35:33 GMT", "X-GitHub-Media-Type": "github.v3; param=diff", "Content-Length": "1879", "X-XSS-Protection": "1; mode=block", "X-RateLimit-Limit": "60", "Vary": "Accept", "X-GitHub-Request-Id": "60255B4F:1559F:1091B310:5712A215", "Last-Modified": "Tue, 05 Apr 2016 19:04:53 GMT", "Cache-Control": "public, max-age=60, s-maxage=60", "Access-Control-Allow-Origin": "*", "X-Content-Type-Options": "nosniff", "Content-Type": "application/vnd.github.diff; charset=utf-8", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-RateLimit-Remaining": "46"}}}]} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 22:56:35 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "59", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"6a40ed61fa463a6dbe2bdd37dd9ae9f7\"", "Last-Modified": "Wed, 24 Jan 2018 15:25:22 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.087680", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "9568:2D373:9B5181:1674115:5A6A60A3"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "recorded_at": "2018-01-25T22:56:35"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.diff", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "response": {"body": {"encoding": "utf-8", "string": "diff --git a/github3/repos/release.py b/github3/repos/release.py\nindex 8b4f9424..10e0b774 100644\n--- a/github3/repos/release.py\n+++ b/github3/repos/release.py\n@@ -22,6 +22,8 @@ class Release(GitHubCore):\n def __init__(self, release, session=None):\n super(Release, self).__init__(release, session)\n self._api = release.get('url')\n+ #: List of :class:`Asset ` objects for this release\n+ self.assets = [Asset(i, self) for i in release.get('assets', [])]\n #: URL for uploaded assets\n self.assets_url = release.get('assets_url')\n #: Body of the release (the description)\ndiff --git a/tests/unit/test_repos_release.py b/tests/unit/test_repos_release.py\nindex c9d12f6d..d0cd4130 100644\n--- a/tests/unit/test_repos_release.py\n+++ b/tests/unit/test_repos_release.py\n@@ -15,6 +15,18 @@ class TestRelease(UnitHelper):\n example_data = {\n \"url\": releases_url(\"/1\"),\n \"html_url\": \"https://github.com/octocat/Hello-World/releases/v1.0.0\",\n+ \"assets\": [{\n+ \"url\": releases_url(\"/assets/1\"),\n+ \"id\": 1,\n+ \"name\": \"example.zip\",\n+ \"label\": \"short description\",\n+ \"state\": \"uploaded\",\n+ \"content_type\": \"application/zip\",\n+ \"size\": 1024,\n+ \"download_count\": 42,\n+ \"created_at\": \"2013-02-27T19:35:32Z\",\n+ \"updated_at\": \"2013-02-27T19:35:32Z\"\n+ }],\n \"assets_url\": releases_url(\"/1/assets\"),\n \"upload_url\": releases_url(\"/1/assets{?name}\"),\n \"id\": 1,\n@@ -29,6 +41,10 @@ class TestRelease(UnitHelper):\n }\n \n # Attribute tests\n+ def test_assets(self):\n+ assert self.instance.assets is not None\n+ assert isinstance(self.instance.assets[0], Asset)\n+\n def test_has_upload_urlt(self):\n assert self.instance.upload_urlt is not None\n \n"}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 22:56:35 GMT", "Content-Type": "application/vnd.github.diff; charset=utf-8", "Content-Length": "1883", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "58", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "\"61e88f2aa8636ea26de6af364acd35cd\"", "Last-Modified": "Wed, 24 Jan 2018 15:25:22 GMT", "X-GitHub-Media-Type": "github.v3; param=diff", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.130298", "X-GitHub-Request-Id": "9568:2D373:9B5187:167411F:5A6A60A3"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "recorded_at": "2018-01-25T22:56:35"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/PullRequest_is_merged.json b/tests/cassettes/PullRequest_is_merged.json index 7df87ec4a..1d22d646e 100644 --- a/tests/cassettes/PullRequest_is_merged.json +++ b/tests/cassettes/PullRequest_is_merged.json @@ -1 +1 @@ -{"recorded_with": "betamax/0.8.0", "http_interactions": [{"response": {"status": {"code": 200, "message": "OK"}, "body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"X-GitHub-Request-Id": "A68C:551F:331A143:4077129:58A08A18", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Vary": "Accept", "X-XSS-Protection": "1; mode=block", "Last-Modified": "Wed, 08 Feb 2017 02:05:35 GMT", "X-Served-By": "1e9204dbc0447a6f39c3b3c44d87b3f8", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "ETag": "W/\"06be44370df682f1efc21f803a926f7e\"", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Date": "Sun, 12 Feb 2017 16:15:20 GMT", "Cache-Control": "public, max-age=60, s-maxage=60", "Status": "200 OK", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Content-Encoding": "gzip", "X-RateLimit-Reset": "1486918405", "X-RateLimit-Remaining": "57", "Server": "GitHub.com", "X-RateLimit-Limit": "60", "Content-Security-Policy": "default-src 'none'"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"Accept": "application/vnd.github.v3.full+json", "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4", "Connection": "keep-alive"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "method": "GET"}, "recorded_at": "2017-02-12T16:15:20"}]} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:04:02 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "57", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"6a40ed61fa463a6dbe2bdd37dd9ae9f7\"", "Last-Modified": "Wed, 24 Jan 2018 15:25:22 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.073013", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "B552:2D373:9B96A1:167E22F:5A6A6262"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "recorded_at": "2018-01-25T23:04:02"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235/merge"}, "response": {"body": {"encoding": null, "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:04:02 GMT", "Content-Type": "application/octet-stream", "Status": "204 No Content", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "56", "X-RateLimit-Reset": "1516924595", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.027009", "X-GitHub-Request-Id": "B552:2D373:9B96A6:167E23B:5A6A6262"}, "status": {"code": 204, "message": "No Content"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235/merge"}, "recorded_at": "2018-01-25T23:04:02"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/PullRequest_patch.json b/tests/cassettes/PullRequest_patch.json index 322a132b9..eeebffb08 100644 --- a/tests/cassettes/PullRequest_patch.json +++ b/tests/cassettes/PullRequest_patch.json @@ -1 +1 @@ -{"recorded_with": "betamax/0.6.0", "http_interactions": [{"recorded_at": "2016-04-16T20:35:33", "request": {"body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "method": "GET", "headers": {"Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive"}}, "response": {"status": {"message": "OK", "code": 200}, "body": {"string": "", "encoding": "utf-8", "base64_string": "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"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "headers": {"Status": "200 OK", "Server": "GitHub.com", "X-Frame-Options": "deny", "ETag": "W/\"51c76ea3e3d49ab7622c56288b405062\"", "Content-Security-Policy": "default-src 'none'", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-Served-By": "bae57931a6fe678a3dffe9be8e7819c8", "X-RateLimit-Reset": "1460842265", "Date": "Sat, 16 Apr 2016 20:35:33 GMT", "Content-Encoding": "gzip", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-XSS-Protection": "1; mode=block", "X-RateLimit-Limit": "60", "Vary": "Accept", "X-GitHub-Request-Id": "60255B4F:1559E:12C74096:5712A215", "Transfer-Encoding": "chunked", "Last-Modified": "Tue, 05 Apr 2016 19:04:53 GMT", "Cache-Control": "public, max-age=60, s-maxage=60", "Access-Control-Allow-Origin": "*", "X-Content-Type-Options": "nosniff", "Content-Type": "application/json; charset=utf-8", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-RateLimit-Remaining": "45"}}}, {"recorded_at": "2016-04-16T20:35:33", "request": {"body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "method": "GET", "headers": {"Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4", "Content-Type": "application/json", "Accept": "application/vnd.github.patch", "Accept-Encoding": "gzip, deflate", "Connection": "keep-alive"}}, "response": {"status": {"message": "OK", "code": 200}, "body": {"string": "From 47cba939175db6f450e46c25279d3b83c88df94b Mon Sep 17 00:00:00 2001\nFrom: Benjamin Gilbert \nDate: Fri, 2 May 2014 02:08:14 -0400\nSubject: [PATCH 1/2] Add Release.assets attribute\n\nThe JSON describing a release includes complete information on its\nassets. Add Release.assets attribute with a list of Assets. This is\ncheaper for the application than making a separate request via\nRelease.iter_assets().\n\nLeave Release.iter_assets() in place, in case someone has a use for it,\nbut mention Release.assets in its documentation.\n---\n github3/repos/release.py | 6 +++++-\n tests/unit/test_repos_release.py | 16 ++++++++++++++++\n 2 files changed, 21 insertions(+), 1 deletion(-)\n\ndiff --git a/github3/repos/release.py b/github3/repos/release.py\nindex 8b4f942..9968adc 100644\n--- a/github3/repos/release.py\n+++ b/github3/repos/release.py\n@@ -22,6 +22,8 @@ class Release(GitHubCore):\n def __init__(self, release, session=None):\n super(Release, self).__init__(release, session)\n self._api = release.get('url')\n+ #: List of :class:`Asset ` objects for this release\n+ self.assets = [Asset(i, self) for i in release.get('assets', [])]\n #: URL for uploaded assets\n self.assets_url = release.get('assets_url')\n #: Body of the release (the description)\n@@ -104,7 +106,9 @@ def edit(self, tag_name=None, target_commitish=None, name=None, body=None,\n return successful\n \n def iter_assets(self, number=-1, etag=None):\n- \"\"\"Iterate over the assets available for this release.\n+ \"\"\"Iterate over the assets available for this release. The same\n+ information is available, without an additional network access,\n+ from the :attr:`assets` attribute.\n \n :param int number: (optional), Number of assets to return\n :param str etag: (optional), last ETag header sent\ndiff --git a/tests/unit/test_repos_release.py b/tests/unit/test_repos_release.py\nindex c9d12f6..d0cd413 100644\n--- a/tests/unit/test_repos_release.py\n+++ b/tests/unit/test_repos_release.py\n@@ -15,6 +15,18 @@ class TestRelease(UnitHelper):\n example_data = {\n \"url\": releases_url(\"/1\"),\n \"html_url\": \"https://github.com/octocat/Hello-World/releases/v1.0.0\",\n+ \"assets\": [{\n+ \"url\": releases_url(\"/assets/1\"),\n+ \"id\": 1,\n+ \"name\": \"example.zip\",\n+ \"label\": \"short description\",\n+ \"state\": \"uploaded\",\n+ \"content_type\": \"application/zip\",\n+ \"size\": 1024,\n+ \"download_count\": 42,\n+ \"created_at\": \"2013-02-27T19:35:32Z\",\n+ \"updated_at\": \"2013-02-27T19:35:32Z\"\n+ }],\n \"assets_url\": releases_url(\"/1/assets\"),\n \"upload_url\": releases_url(\"/1/assets{?name}\"),\n \"id\": 1,\n@@ -29,6 +41,10 @@ class TestRelease(UnitHelper):\n }\n \n # Attribute tests\n+ def test_assets(self):\n+ assert self.instance.assets is not None\n+ assert isinstance(self.instance.assets[0], Asset)\n+\n def test_has_upload_urlt(self):\n assert self.instance.upload_urlt is not None\n \n\nFrom 560c19155ac83eb38713db56c56c7aeaa122c528 Mon Sep 17 00:00:00 2001\nFrom: Benjamin Gilbert \nDate: Sat, 3 May 2014 00:06:20 -0400\nSubject: [PATCH 2/2] Revert Release.iter_assets() docstring change\n\n---\n github3/repos/release.py | 4 +---\n 1 file changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git a/github3/repos/release.py b/github3/repos/release.py\nindex 9968adc..10e0b77 100644\n--- a/github3/repos/release.py\n+++ b/github3/repos/release.py\n@@ -106,9 +106,7 @@ def edit(self, tag_name=None, target_commitish=None, name=None, body=None,\n return successful\n \n def iter_assets(self, number=-1, etag=None):\n- \"\"\"Iterate over the assets available for this release. The same\n- information is available, without an additional network access,\n- from the :attr:`assets` attribute.\n+ \"\"\"Iterate over the assets available for this release.\n \n :param int number: (optional), Number of assets to return\n :param str etag: (optional), last ETag header sent\n", "encoding": "utf-8"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "headers": {"Status": "200 OK", "Server": "GitHub.com", "X-Frame-Options": "deny", "ETag": "\"1ccc77cae0d830705145ca6034aea059\"", "Content-Security-Policy": "default-src 'none'", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-Served-By": "76d9828c7e4f1d910f7ba069e90ce976", "X-RateLimit-Reset": "1460842265", "Date": "Sat, 16 Apr 2016 20:35:33 GMT", "X-GitHub-Media-Type": "github.v3; param=patch", "Content-Length": "4168", "X-XSS-Protection": "1; mode=block", "X-RateLimit-Limit": "60", "Vary": "Accept", "X-GitHub-Request-Id": "60255B4F:1559E:12C740B2:5712A215", "Last-Modified": "Tue, 05 Apr 2016 19:04:53 GMT", "Cache-Control": "public, max-age=60, s-maxage=60", "Access-Control-Allow-Origin": "*", "X-Content-Type-Options": "nosniff", "Content-Type": "application/vnd.github.patch; charset=utf-8", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-RateLimit-Remaining": "44"}}}]} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:13:48 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "55", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"6a40ed61fa463a6dbe2bdd37dd9ae9f7\"", "Last-Modified": "Wed, 24 Jan 2018 15:25:22 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.102292", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "B604:2D36F:15745C9:3C80B39:5A6A64AC"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "recorded_at": "2018-01-25T23:13:48"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.patch", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "response": {"body": {"encoding": "utf-8", "string": "From 47cba939175db6f450e46c25279d3b83c88df94b Mon Sep 17 00:00:00 2001\nFrom: Benjamin Gilbert \nDate: Fri, 2 May 2014 02:08:14 -0400\nSubject: [PATCH 1/2] Add Release.assets attribute\n\nThe JSON describing a release includes complete information on its\nassets. Add Release.assets attribute with a list of Assets. This is\ncheaper for the application than making a separate request via\nRelease.iter_assets().\n\nLeave Release.iter_assets() in place, in case someone has a use for it,\nbut mention Release.assets in its documentation.\n---\n github3/repos/release.py | 6 +++++-\n tests/unit/test_repos_release.py | 16 ++++++++++++++++\n 2 files changed, 21 insertions(+), 1 deletion(-)\n\ndiff --git a/github3/repos/release.py b/github3/repos/release.py\nindex 8b4f9424..9968adc8 100644\n--- a/github3/repos/release.py\n+++ b/github3/repos/release.py\n@@ -22,6 +22,8 @@ class Release(GitHubCore):\n def __init__(self, release, session=None):\n super(Release, self).__init__(release, session)\n self._api = release.get('url')\n+ #: List of :class:`Asset ` objects for this release\n+ self.assets = [Asset(i, self) for i in release.get('assets', [])]\n #: URL for uploaded assets\n self.assets_url = release.get('assets_url')\n #: Body of the release (the description)\n@@ -104,7 +106,9 @@ def edit(self, tag_name=None, target_commitish=None, name=None, body=None,\n return successful\n \n def iter_assets(self, number=-1, etag=None):\n- \"\"\"Iterate over the assets available for this release.\n+ \"\"\"Iterate over the assets available for this release. The same\n+ information is available, without an additional network access,\n+ from the :attr:`assets` attribute.\n \n :param int number: (optional), Number of assets to return\n :param str etag: (optional), last ETag header sent\ndiff --git a/tests/unit/test_repos_release.py b/tests/unit/test_repos_release.py\nindex c9d12f6d..d0cd4130 100644\n--- a/tests/unit/test_repos_release.py\n+++ b/tests/unit/test_repos_release.py\n@@ -15,6 +15,18 @@ class TestRelease(UnitHelper):\n example_data = {\n \"url\": releases_url(\"/1\"),\n \"html_url\": \"https://github.com/octocat/Hello-World/releases/v1.0.0\",\n+ \"assets\": [{\n+ \"url\": releases_url(\"/assets/1\"),\n+ \"id\": 1,\n+ \"name\": \"example.zip\",\n+ \"label\": \"short description\",\n+ \"state\": \"uploaded\",\n+ \"content_type\": \"application/zip\",\n+ \"size\": 1024,\n+ \"download_count\": 42,\n+ \"created_at\": \"2013-02-27T19:35:32Z\",\n+ \"updated_at\": \"2013-02-27T19:35:32Z\"\n+ }],\n \"assets_url\": releases_url(\"/1/assets\"),\n \"upload_url\": releases_url(\"/1/assets{?name}\"),\n \"id\": 1,\n@@ -29,6 +41,10 @@ class TestRelease(UnitHelper):\n }\n \n # Attribute tests\n+ def test_assets(self):\n+ assert self.instance.assets is not None\n+ assert isinstance(self.instance.assets[0], Asset)\n+\n def test_has_upload_urlt(self):\n assert self.instance.upload_urlt is not None\n \n\nFrom 560c19155ac83eb38713db56c56c7aeaa122c528 Mon Sep 17 00:00:00 2001\nFrom: Benjamin Gilbert \nDate: Sat, 3 May 2014 00:06:20 -0400\nSubject: [PATCH 2/2] Revert Release.iter_assets() docstring change\n\n---\n github3/repos/release.py | 4 +---\n 1 file changed, 1 insertion(+), 3 deletions(-)\n\ndiff --git a/github3/repos/release.py b/github3/repos/release.py\nindex 9968adc8..10e0b774 100644\n--- a/github3/repos/release.py\n+++ b/github3/repos/release.py\n@@ -106,9 +106,7 @@ def edit(self, tag_name=None, target_commitish=None, name=None, body=None,\n return successful\n \n def iter_assets(self, number=-1, etag=None):\n- \"\"\"Iterate over the assets available for this release. The same\n- information is available, without an additional network access,\n- from the :attr:`assets` attribute.\n+ \"\"\"Iterate over the assets available for this release.\n \n :param int number: (optional), Number of assets to return\n :param str etag: (optional), last ETag header sent\n"}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:13:48 GMT", "Content-Type": "application/vnd.github.patch; charset=utf-8", "Content-Length": "4174", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "54", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "\"3f3f74e7e5c7460ca100a30ea3b16c19\"", "Last-Modified": "Wed, 24 Jan 2018 15:25:22 GMT", "X-GitHub-Media-Type": "github.v3; param=patch", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.051412", "X-GitHub-Request-Id": "B604:2D36F:15745D7:3C80B61:5A6A64AC"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "recorded_at": "2018-01-25T23:13:49"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/PullRequest_pull_reviews.json b/tests/cassettes/PullRequest_pull_reviews.json index a293c6e16..c617a6789 100644 --- a/tests/cassettes/PullRequest_pull_reviews.json +++ b/tests/cassettes/PullRequest_pull_reviews.json @@ -1 +1 @@ -{"http_interactions": [{"recorded_at": "2017-01-26T21:20:01", "response": {"headers": {"ETag": "W/\"7471cf763435127e2b3ee39680a8d92a\"", "Transfer-Encoding": "chunked", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Served-By": "0e17b94a265a427d9cafe798ceea7c02", "Date": "Thu, 26 Jan 2017 21:19:58 GMT", "X-RateLimit-Reset": "1485468031", "Content-Type": "application/json; charset=utf-8", "X-XSS-Protection": "1; mode=block", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-Content-Type-Options": "nosniff", "Content-Security-Policy": "default-src 'none'", "Access-Control-Allow-Origin": "*", "Status": "200 OK", "X-GitHub-Request-Id": "CC3D:6972:85BFE21:9F84A2A:588A67FE", "Cache-Control": "public, max-age=60, s-maxage=60", "Last-Modified": "Thu, 26 Jan 2017 19:58:51 GMT", "X-RateLimit-Remaining": "58", "X-Frame-Options": "deny", "Vary": "Accept", "Server": "GitHub.com", "X-RateLimit-Limit": "60", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Content-Encoding": "gzip"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671", "body": {"string": "", "base64_string": "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", "encoding": "utf-8"}, "status": {"message": "OK", "code": 200}}, "request": {"method": "GET", "headers": {"Accept-Charset": "utf-8", "Accept-Encoding": "gzip, deflate", "User-Agent": "github3.py/1.0.0a4", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Content-Type": "application/json"}, "body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671"}}, {"recorded_at": "2017-01-26T21:20:01", "response": {"headers": {"ETag": "W/\"a02d9791b92bad6db552e666d498f99c\"", "Transfer-Encoding": "chunked", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Served-By": "bae57931a6fe678a3dffe9be8e7819c8", "Date": "Thu, 26 Jan 2017 21:19:58 GMT", "X-RateLimit-Reset": "1485468031", "Content-Type": "application/json; charset=utf-8", "X-XSS-Protection": "1; mode=block", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-Content-Type-Options": "nosniff", "Content-Security-Policy": "default-src 'none'", "Access-Control-Allow-Origin": "*", "Status": "200 OK", "X-GitHub-Request-Id": "CC3D:6972:85BFE54:9F84A57:588A67FE", "Cache-Control": "public, max-age=60, s-maxage=60", "X-RateLimit-Remaining": "57", "X-Frame-Options": "deny", "Vary": "Accept", "Server": "GitHub.com", "X-RateLimit-Limit": "60", "X-GitHub-Media-Type": "github.black-cat-preview; format=json", "Content-Encoding": "gzip"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671/reviews?per_page=100", "body": {"string": "", "base64_string": "H4sIAAAAAAAAA92WS4+bMBSF/wvdJgHzDEhVF+0sp91MN62qyIBD3PKqbYjSKP+915iMEmeSGUKk0cwqBHyOD9f3fuLn1qCpEaG57zsocCdGwwkzoq2RVxktjcjgNCtwS1nDbdeYdItt15o71sTALRaYLRqWw7qVEDWPTFPd5NYso2LVxNIuqUpBSjFLqsJsTKX+1H50wC5jvYn0NeCGZlbT3keJwYybWqKVKHItg9q6k2iLl1WeV2tw0VM/t5H5qISQ6pqW2ZUuoNyalVgRKB680k4WgnIxPFSn2pryZ0FT6cPhRBhJBwfrdRBrXUKirclIXXWGTcwTRmtBq3J4wCM1uFUswyX9h69zAzUHExlteJROBWrSQi8OlyvZ1qwZbXGykaVhJCG0hWJfaanpwVFsagJz8F3OIJSeCrLAaSHncIlzTnYTI67SjZoU6O6CymOHvz6JQytGxEqTgGDbIU7oeFZMktB1kyC1lgjFMUKeahAh9/j87f7+7uvD3Re49/IRglaTU+3M6o1ZN3lu+gH6IC8Y+dsQLhhpKVlP9zgBb/lw0T+93JXdAR0NrL4bl9uB5yKn5R8uKSWTd7+MLA8gdAYAut9z6aHeh/Gf2Agfc+Olr7ADZxgNOD8B7YMFRLctFEwtNLX9B+RHjhfZ8x/GbrLHc2AFPvJP8fzb5lUOJZFt4NmOPQ8ucxmd5bJSj+DyPsrlbtqvGkTiTnQ9gg/lY9irfEZBV1ncjra93yGkoRsGY1bZDOWrUg0Hq9Ldhqj7DEcoflcoVaP/VlHap38tlIaRG0SuhtIwDAGT+pcuFbwgBRYiWTVl1jM1cLw5suzLULXPQrWXj6DqSarLeD1ZPoizx+rrgfukzxjyaoajEKx53Y7FuvFYKGt+Q+msyYdjWjO4Da9PUr1ncEvQvF1wd+lfD9zePPIQfAP/+g8gGKPqpBAAAA==", "encoding": "utf-8"}, "status": {"message": "OK", "code": 200}}, "request": {"method": "GET", "headers": {"Accept-Charset": "utf-8", "Accept-Encoding": "gzip, deflate", "User-Agent": "github3.py/1.0.0a4", "Accept": "application/vnd.github.black-cat-preview+json", "Connection": "keep-alive", "Content-Type": "application/json"}, "body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671/reviews?per_page=100"}}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+1cbY+jyBH+K8j5kigzxjbjl0F7e9lESu6kk3a1mnzJbWS1oW33DgYC2HOz1v73PNXdYLDdjAHvN0v7YuOuh+qXKqqe6mbf2yZBz+2tsyxOXdtmseivRLbeLvpetLETHkepnYrVhu1Esk1HD7b61enHr3a8DYLUnkyHvbue8HvucOCMho/OZHQHvE0wr0KXYOsANZ4vlsv2AH0Sh1Yxy7x1BxgpT71L0y0/wmk0VBIgH6twu1nwpOdi5O56acYyjhnwgijlPu4VRN4zPrhLFqT8rpeJLKDfP/i+lW7jOEoyaxkl1pJDNRGuLJoFK+H/A36G/3eCv6SA2aZ0iz3gViKEfLRZfQ2e9UyNR85oNr3rsR3LWHLcMXkxHemFQEBeFGY8zOSa2NpK+ufdTw+AWyUahFZAj25ct6AILLULXeqXSdFsGQVB9ALJY02rq7UMbhcyUEl9xmA1lofM3o6yNccgQfXv1GGRZk0Uke33sJs0mwufEDDlScL9BspoCajyEkKLvTRMCbVdpF4i4kxEYROlKnLAiZIVC8U31hQHcrTYpJ9o0B/ZHnJ8h1XVRFAJ7O04ETvmvdIQJNzjYofhbAx2JAms7DUmW/s32Q4GV2R8zvwN2U+WbPn3u94i8l/R4GktUov+hFasTM7axmmWcLbpWx9osaYHA8Xqye1SWi6zVtA3/BKWLffOYqFvUVNaZ/jAMkBHO+FzdVndpv8Fcp9YkgkWBK+W2MQB39AYWn+aTCb045+lbp8+W2km4BhCzv0Ut/RYmvIs4wp5zdKKShl8R2plkRWj2V/QdQ9dyTCmLENvR4Ph9H4wvB+Nn0Yj15m4zuw/aLON/aM2w8H9aPI0GrgPjvsg2yivdgQzJZjRg+uMqcmGJ6uTO51pMofz2Yhsnq4ZdJrxR48NBuPJYrbk/iP+n0x8tlyMncfZdDz1/Jk/W+AH3ABdEiuMQ9kblp9AaEK+a/QwmDmDep/oGH2iku7gE480qveMR40b+cfKw7e1lzyD0sVXHkUEHTxmBel6frMKW/a6WD6NvWcFrakPrQg396QV8ev40yONKv4Yw2P2qjLGgVvNTTTtub8fQpYy7M1IEf5gEBqFMpV5KSRbBzQVuE5hTdWaVDh0heCmCnszUp3Fqbi4o5H+lyItmWTgYa2CEVqR7u+VHzJEQPriRgRoHIV47oZIURALyOf3G9HehRmnrcFgEUoXGR28HUw2gSe0E/z6IPcS+FzRva3yQIphr6H8IcWUg6O1p/QS899p1HMMu0HQteYMMRV8OVtwIhhULufGyf0hRU34Er9ULjUO7mht39LcFs8GNSE6Te4SummgTs8DjXG9cC0H7PoM0DhNQzQt1jw404LXCcsKLS4PyHSaS4qTVVFeNEOWNXIoMwrZhrLjAwNI8Qhc+1z/UKwE4g+JIaTQmAiLm4HeDLTglCss3Y2HCp5B5jU2UMl/EW+sWeJ6uuCcYfq8IA5h059es3UUWoFYJCx5lTSVAOWbLJlHHPMLSgKSnPqXyH7ZLqwPn37dOTIbSZ4VN/YG76sCo3N6EMRF0cmJMJ5dEIUWz/y1JQJJ7m38q5lZD0QzW0QJy6K3yGZDjxB7lSD2la8U6ckA+ZIg8rS7KrZGbSWK2o6YFIUWqp5xCWFq6qaONvMH1SGU7QKqZKFfwQe0G6lCfG/nrD3WdeitL4uDT4c+l97b6pOcSbZqO5GQBMAiiBYtEfAItqX43kbErKoS2by9RoRH0hU4hOcd1CPpAg7MeNuhl6qReAHWJKU5ncoimdnrkQtYuNqyVVv9CnHMKMWvK/btzUKVyagO8gCjmlsiFtsuruiAQNqpYBilx5bTWgI4wMnSUzszLT/8ZYcv5gdOp1ULVxZwJ0Bad8egTdL08ypSVl5O/JUj1rjtRlF74ly3Kq0gy7Ytp1sXfVN7/1fUwdeap4hZclEl/Gz/SdjeLxhI336/vyeSgGBlCaillkoWICxBPXzXUrd9Lo2YYsMyWWFdkmo+EpggYn5L7QpxQKmJ6jLJ5bmVmy/agUnRMlZB1bUEPMiXUcMoE0vhXVJTNjnECsT+51SEHr9D5fMOCykTnsC6RHhK8yR5ppbqK1mojvyWsBIecCzRlmi59N5W1X6fx0H0ejE3eWo3JQDykqbK7MAdDN3B4HxlVldvVRtZdo236bpUdp3pAu8AldupOxxSE7hAvcDwCZuDVOIvN4GcaEmFUYikab7dBt//dhBwTQIoEIfHNnvJfXbHz5w6ISi2jjY8xlMeuU6+10lJOPFrH0PqI7vxIy/ti4i6Ib6h5Xj4MMZeptJT3Yu2ISri4EJeaGcQPUkPl/JIoEin6LYsnSu7P6RquITK/lfugV6W+wpUs4OrKF18Ec+iKkmRSnFFJU8HFTYiSSK9n0eR7tqvHfYTRTEPtUpl3YXHw7Sg6lVmRf0sNa/0W37x+ZJtg2yugmL020cEH0Rx7zttlYAJlRngcv3BzRuSsREJfPiuGOAh95nHnOmMDYeLMR843uPiYTqaTCePw5H34DHPcyaPDsMQHzPAt6qh2qh3K+1fuCXqVjU8u/fzKlVDtTUsp5Kd6XAwHWLT41tM8lGluY5Pvpn7zdwb7YC8mfuPNPdmxLTZzq9IT2uKvHZfcm3hHkHGxSy1oUeNuWoTTmfG2gR8Ld7ahN+YvTYBteWwTXhXYLJN0O34bBNaR1bbBNuF2zZhEpcMq7mY4TbhIEXrwHPXobZmu+tA23HedYjtmW8Tajf+24TangU3IXbiwk2gZU6d0vxmjLgJtRsv/gaq5NehawMy24R4TGfDuvSm+ouoLhMsGekxdBOm3IR7jtFuzJebwK/Empvgu3HnZtRNZwbdhN2GRzdhXYdNN6G349RNaGohtGLWTZAd+XUT7JVYdhP8j+DaTffqwribMDvy7ibYevZ9dD9w7ofO0/DRHc/csXOOfS+odfDqI83Q17PvEoa8s8pZ8KnKvht0fYuDrxd7g4mvF07r+HiDKNHj7Vh5R52bzWvtmv+ejh9OeXl58S1m/kDC/xBifjSDvu2o+eFgDPVzcn5PW51oMzUdSMXwaRrto/6axv4f2MiU77eXi4eqACDjNaEvNalQ+vIGeTGj58rhqqX154EIsYcIm0NTHoC63/fWisLveIQcStImtjOApcqOYSXJk+jy4DhQpEM/A9P2vDYg80jkeqiHLfqAPzrB0PUuxbH8mptc5x6nEZoeLBzzuM4dMKfFUQ9g58lLV/AiCbr4RANVtNgWmySTOfLwyBOyrA1b/MfH33778PePnz88ffxMKS8OCM/VQu69i99f46Dwu0Xyvt1h4Xd2DEmocfbE8Dtmken+9OWoIioLvCZL03EzHTbuWV6AsYC8vHhPjsH6mt4fvqEJjgize05VyfuM/5Gh8T8ZDgbhTHNk0b4KnKKGrCXfcpA3Fz6ajQaD6WTmPDr51ZgnGzTGqOdIvx5E6TC2ph7z9nB/7bv2no5Tv7PZ+2IIr3CumrDyJUKDgdVzjfXRbm3UHiO/QmfRUXWyO69xy29sQS+zUKXphFOJuHylaDInA6Va/TZ8DrEDpwCbL/D8u50QxTs0KgZ6q/Xear20sbDbazEqS6rJoYT8GPchTpqciWoQaG4YThXgL16n4rFwvonwnh4YtK7QaBIJLxLCs9b3hXwZSc99hKCPLVn6K/adeGvs2cXmpSUdMe25D9//D8XPzoHHSAAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:14:34 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "53", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"2c906c73d109148caa773ea48b3d72d1\"", "Last-Modified": "Wed, 24 Jan 2018 17:52:18 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.102127", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "9642:2D36F:157562A:3C834BC:5A6A64D9"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671"}, "recorded_at": "2018-01-25T23:14:34"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671/reviews?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+2ZXW+bMBSG/wu7TQuG8ClNU9v1YlLXSFWqSZumyICTeCWQYZOui/LfdwxuFdwmLQGl6dQrIvD7+hzb55F18mOp0VgLkOc4FnL7Pa1gJNeCpZZkE5pqgcboZIYXNC+Y2dd65WCzb3iW0dPwAnOcj4o8gXFTzucs0PXqJbOOJ5RPi1DYRVnKScqPo2ymF3ql/rT4KOwmuTQRvhq8UMzmVPpUYjBjuhLRlM8SJYZq6lKiDB5nSZLdgosa9XMT6Q9KCLL6TdPJji6gXOoZnxJYPEhpJRaCMt48qFK11MVjRGPhw2BHchI3DkzqIKzbFCJa6jmZZ6VhEbIop3NOs7R5gDU1uGX5BKf0L97NDdQMTERozUMpVaAmCziLzeWVbKnPc7rA0Z1YmpxEhC5gsXe0VPTgyO/mBOrgWtQgLD3lZITjmajDMU4YWfW0MIvvqkqBHeNi8Nng69fzy+H5Z1C8vBbgzIjytI7nd/q8SBLdcdEH8SMnvwvCeE4WlNwe3XMBvMXHkfy6/XiVK12rPHU2JqYDT1zwaZaPMGNZRMtDAQkNvl2eX8HHUULTGyZYJNIqnzkZr6FmQ5mrkz2XGqzqem5PTITrdHhpfiu5X6MqfoE3sX0jTv5wuYdFOKOcwxHC4o1pIPfIQEemM0ROYNmB6X0HEXAMRkGBwxCHhL4RImLEkUuwaRHLt2wjJJHf70dubIwRCkOEbG3Vuye7a7gOch6TPZtNfiU34C+MbdMyPXc7082NTK/ULZj+EMv2E/wwrBHHK9XuBK/p27BbGrWitvTojtf3huuch0PRmNTSpymjpaw5naWwGy4/RFEjOizDZiLzvHgVIFflvE8gnw0uLk5OB1cnw8FeuCwzPEwu+0HfDfrdcNn3fUCueuOmnM3IDHMeTYt0IvnsWraHDHM7oNFGQEt5C0I/imo7qR8Nb0Tsunp3cj/p04bgimErkite3RFdNW5LdsWvKeEVeXPSKwbdEP9RVC8n/6vdxV1DEGO/6L8cXn05vd4b+csED5X8thfYqIMbuW8g5EMDRSX/e6+lbDPtzvv1BZQubWhfs2vF+ppTd6Sv27blfM2tKeVr4uaMr8m7IbwS0Rvge8WFffJ9b70WmdoBkt0dIi+wzMA0VbJ7xI+wYdhO6I1J7MPTcWI8Dm3L91zbjWIv9kL4sNZrgTRN64k7/fpZlDf69y562Yt/76Ir3UVxKVC6p+9ddGhVb/gHCP6oeBtkBy78r2QXqR0w2S17d7L//Ac97uRSIR0AAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:14:34 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "52", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"2b6fc7127db008694299d5d51543dea6\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.145408", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "9642:2D36F:1575636:3C834DB:5A6A64DA"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/671/reviews?per_page=100"}, "recorded_at": "2018-01-25T23:14:34"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/PullRequest_reply.json b/tests/cassettes/PullRequest_reply.json deleted file mode 100644 index 537875f54..000000000 --- a/tests/cassettes/PullRequest_reply.json +++ /dev/null @@ -1 +0,0 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA62YTY+jOBCG/0rEddNxCP0xgzSa2dPu3ubQe9lL5IADVgNGtkmURv3f9y0MgWS0+WjvJUqI6/HrcpWpchvINIijl3D5EobzoOKlCOIgkzZvNtGiPgTzYNsUxbr/w8is5DupG7N6ZCej1L4SOojboFCZrMCYDgWFplk9Lr9Ey3nAd9xyvW50gXG5tbWJGXMPzcJRGyN0oiorKrtIVMka5oy/776tQMt0zyBsgAdnrFr2HGcMmGFngnJbFmcS3NSdydngrSoKtQflXPS1idjRkjzZUWSVfZICy5Ypmwv4Dkv6IEdIY+8X1Vm12EBj1zIljsGGaJHeLay3gyza/4+WaVGrDthsTKJlbaWq7hd4Yg2a0hmv5Dv/HA3WBhCSdr+UzgrWYodYvN/cmbWs1nLHkwO5RotEyB2c/UnkmT2I9lBT2v6NoCDXSyvWPC0pDbe8MOJjHnTTWwzqHsyRdbdG/2map+K4q5jw58HmqpoVcqO5Psy2Ss8kclZveYJYne1xjMwQrrM/pP2z2cx+//nXLoJAjHs7KrmYuZ3zT5LxVA6RruzJRQTSEwBIehMHLw7ZtwyffT4lSHW+UZpbde3QuCzwBNSy6U+KJSt46SW8AwCUK+XnyQ4AkDSmETeF9uWFdxzDhvypmnLjjrxbsuYy2hGglRuc85UQXh48Qlo2nMpIhyrJ/bADo2XuW7fbPPOSSvbAbAq18eLgRck6SMtMzt17yK591RGVGCdQLbbeUolxhFrtud+dTIIckXgJWmy9l86BwdreowWvsoZnftQjBLtOr+qMv18tYi7nzkgBkio0LTeN/yE3ckipqx2Q734uHTEjtCtILpc5VxwwKWw6F5SlvFYXXCb2iJOw/x+wFKfnaPp9vYy5LpcYLRvPZHfo93Qf7/an/qCTteMcfTvgFRIDg7W/1dzmdHJhqppr4SO6R7B2w1FsLRaLNhe8K6tLoT0z2BGA4jrJUTX66GwHBqqektuuWt+SzBTVe6F46uXbIwRAt40+Wh1hGmM1+lAvgR1gSixlIYxVld8ZO1Km7EpZuZXJLR3L5XQ7AbXfjawSMedFMUfUWplIxDFqbdpFFJzCz0OOgGXgGsB1KoVASHt5XQvHaJnrNBMt0Iika27RQKyW4ephGT2E0Wv4NX76Ej9F/2AlTZ2ejHl8CJcPq9Xr8il+eo6jkMbUjcknGDfk+XUVxuEjSDQEJ2AfgviGKwZ84lrjl/5+0lLQrQEMjclHwx+jWfwf9x+9WVIgls6C/vY5d+evpeumkJqrUtQoE/qblOMqo/qwgKdTtF+pSswCPTCjlcl3DA2XzxFueyYVQaKaChuyCr/Ogz23KF7x7p0+HCqJY9dHc3OzdnkaxFY31FbiyXgOTB7u5Zscm0+MIs1mMHNtXD/dywvOTam16m+IKqQtbgBqUfWTjbpcKwkM2UxG0ELGdfTLSsWWN4Vdu3Ia60jRBxSqplgSusRC6KqCrrD63tktieJs0EkniPuOlroSdo/ucVBDEqaFS7+a8OXjX0I8PsFkEwAA", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "a8d8e492d6966f0c23dee2eed64c678a", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"82c26520019a20d6714efbc128ab3fb9\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4918", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0B008:2E0E:3896DBD:544D6EBF", "cache-control": "private, max-age=60, s-maxage=60", "last-modified": "Wed, 22 Oct 2014 05:56:31 GMT", "date": "Sun, 26 Oct 2014 21:59:28 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1414364368"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2014-10-26T21:59:27"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286"}, "response": {"body": {"string": "", "base64_string": "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", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "971af40390ac4398fcdd45c8dab0fbe7", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"4d0782b03e7c121b6f3e065ffa4cb0d5\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4917", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0B008:2E0E:3896DEB:544D6EC0", "cache-control": "private, max-age=60, s-maxage=60", "last-modified": "Sun, 26 Oct 2014 21:27:18 GMT", "date": "Sun, 26 Oct 2014 21:59:28 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1414364368"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286"}, "recorded_at": "2014-10-26T21:59:27"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments?per_page=100"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA61V0W6bMBT9Fct76KrRAIZQQF1Xab/QvWydkMEmWCVAbZMui/Lvuxdol2Rt1URLpJCYe869nBwf/9jQXtc0pZW1nUldl3dqtlC26vNZ0S5dLbvWuEYtlnyldG9Y6I53g1m3dru+ro0LdUvZWOP6SRAHQZxQhypB06efDhWqLLOqb+6h0c0NufCTuRORT3hhcwIrQpakqFsjPxpZl+fpXUOeXnd0eP9d0NL2uiFYOOs7we0Imllla+mM63kr1g45GyjF2Tmg75pPyHij5UOvtDQZ7201LQ7dtQSmTMuVko/Z9EjDNA4Z2XBN2UwJh3TcVvDZGmVV2+C4Azm+xnG/DmyEk5GPTHykbYitlCEoHNx76KWxM5ALCUGbSdpRVxAY70xNaBo5tNVqoRpeZ3urz4MBg/CSMs/nnl/6eRQUISuKJJEhC4QXFPOYRXl0mTAvB+Znsl18GAaXIYu5LAWwJH4gGS94Lrz5nOXCDzzmiyKIS8D3RmqabmjdwkzQetckkwNY6MWB51C+4pbr7MBpw6KZ3IZsRdtYMNJgvN4dwV9WnxmwLfTEgcai2P0t1yLZvmsBUdllfTDCjtEPpi/bum4fgeVw6P3t8W8j9xkJLcfvqlmcyALIjdvaSoJ28EhbFEIZe/xQA2oDW9eggZHHgPZaiqMHm3Aw1mMDE22GhBgI+9wUWnW4I44fcA8NbK1e8Eb95qexAdoAyRBeRz/hgAK0XGGoHQ0fYRu302rFizVKo2Uh1QrEPpHyAA+Mdt1J2AffcAuC9AqSi4slbsOS10ZuHYqZBRW3EDDgooMcwscbA09k3EIZ8/zwwvcuWHTLvNT3UhZ9h5oxXl+o8VM/TOcx1rx/Wx2eHC6Low9CmaI3BkyT6Z3zAwMSwngIyLf/gvecUNAIJs1q1dwbjCyMdbxWWsL1/559oD1K8gL9K2nzflmAeleXF1qccHqjNtvJMNk4Ob3qrl8xzpXbXYOU6K7Myl/onVcq6fbnH4eJaSRdCAAA", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "c046d59f93ede9ab52d5ac29f1ed70f7", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"5b3c9a92ca7dec2970eb201f08904089\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4916", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0B008:2E0E:3896E1A:544D6EC0", "cache-control": "private, max-age=60, s-maxage=60", "date": "Sun, 26 Oct 2014 21:59:28 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1414364368"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments?per_page=100"}, "recorded_at": "2014-10-26T21:59:28"}, {"request": {"body": {"string": "{\"body\": \"Replying to comments is fun.\", \"in_reply_to\": \"19383389\"}", "encoding": "utf-8"}, "headers": {"Content-Length": "67", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments"}, "response": {"body": {"string": "{\"url\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/19384066\",\"id\":19384066,\"diff_hunk\":\"@@ -195,6 +195,25 @@ def close(self):\\n \\\"\\\"\\\"\\n return self.update(self.title, self.body, 'closed')\\n \\n+ @requires_auth\\n+ def create_review_comment(self, body, commit_id, path, position):\\n+ \\\"\\\"\\\"Create a review comment on this pull request.\",\"path\":\"github3/pulls.py\",\"position\":6,\"original_position\":6,\"commit_id\":\"d09fbb501f1b63c42cc99e423d03c5826b67920b\",\"original_commit_id\":\"4437428aefdb50913e2acabd0552bd13021dc38f\",\"user\":{\"login\":\"sigmavirus24\",\"id\":240830,\"avatar_url\":\"https://avatars.githubusercontent.com/u/240830?v=2\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/sigmavirus24\",\"html_url\":\"https://github.com/sigmavirus24\",\"followers_url\":\"https://api.github.com/users/sigmavirus24/followers\",\"following_url\":\"https://api.github.com/users/sigmavirus24/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/sigmavirus24/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/sigmavirus24/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/sigmavirus24/subscriptions\",\"organizations_url\":\"https://api.github.com/users/sigmavirus24/orgs\",\"repos_url\":\"https://api.github.com/users/sigmavirus24/repos\",\"events_url\":\"https://api.github.com/users/sigmavirus24/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/sigmavirus24/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"Replying to comments is fun.\",\"created_at\":\"2014-10-26T21:59:28Z\",\"updated_at\":\"2014-10-26T21:59:28Z\",\"html_url\":\"https://github.com/sigmavirus24/github3.py/pull/286#discussion_r19384066\",\"pull_request_url\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/286\",\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/19384066\"},\"html\":{\"href\":\"https://github.com/sigmavirus24/github3.py/pull/286#discussion_r19384066\"},\"pull_request\":{\"href\":\"https://api.github.com/repos/sigmavirus24/github3.py/pulls/286\"}},\"body_html\":\"

Replying to comments is fun.

\",\"body_text\":\"Replying to comments is fun.\"}", "encoding": "utf-8"}, "headers": {"content-length": "2154", "vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"eb1eb4bc45aec86442807cf9b9d7cda7\"", "location": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/comments/19384066", "access-control-allow-credentials": "true", "status": "201 Created", "x-ratelimit-remaining": "4915", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "x-github-request-id": "48A0B008:2E0E:3896E4D:544D6EC0", "cache-control": "private, max-age=60, s-maxage=60", "date": "Sun, 26 Oct 2014 21:59:28 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1414364368"}, "status": {"message": "Created", "code": 201}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/286/comments"}, "recorded_at": "2014-10-26T21:59:28"}], "recorded_with": "betamax/0.4.1"} diff --git a/tests/cassettes/PullRequest_review_comments.json b/tests/cassettes/PullRequest_review_comments.json index bc76032fa..6875fddca 100644 --- a/tests/cassettes/PullRequest_review_comments.json +++ b/tests/cassettes/PullRequest_review_comments.json @@ -1 +1 @@ -{"http_interactions": [{"response": {"body": {"string": "", "base64_string": "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", "encoding": "utf-8"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "headers": {"Access-Control-Allow-Origin": "*", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-RateLimit-Limit": "60", "X-Content-Type-Options": "nosniff", "Status": "200 OK", "ETag": "W/\"06be44370df682f1efc21f803a926f7e\"", "Date": "Sun, 12 Feb 2017 16:29:07 GMT", "Content-Type": "application/json; charset=utf-8", "X-Frame-Options": "deny", "Cache-Control": "public, max-age=60, s-maxage=60", "X-Served-By": "7f48e2f7761567e923121f17538d7a6d", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Server": "GitHub.com", "Content-Encoding": "gzip", "Vary": "Accept", "Last-Modified": "Wed, 08 Feb 2017 02:05:35 GMT", "X-RateLimit-Remaining": "52", "X-XSS-Protection": "1; mode=block", "X-GitHub-Request-Id": "99EA:551B:1DCDB93:258C613:58A08D53", "Content-Security-Policy": "default-src 'none'", "Transfer-Encoding": "chunked", "X-RateLimit-Reset": "1486918405"}}, "request": {"uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "body": {"string": "", "encoding": "utf-8"}, "method": "GET", "headers": {"Connection": "keep-alive", "Accept": "application/vnd.github.v3.full+json", "Accept-Charset": "utf-8", "Content-Type": "application/json", "User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate"}}, "recorded_at": "2017-02-12T16:29:07"}, {"response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA+2ZbW/bNhCA/wqhfViKyta735B0HTBgK1AMw5ZiwOpBoaizTVSWNJJy6hn57ztSsqM4ShonbrcOiQNYIe+Op9Px+OjyfmNVIrMm1kKpUk4ch5a8P+dqUSV9ViwdAWUhHcnnS7riopJ+6NSzQb9cO2WVZdJBuSXkSjqe74eD4SiwbEvPxAL+qkAq/F5xuIx5ak1yHLctfbUVtq2Uz2bxoso/oBuvX5Oe54b2kLz03IE9JjiQwoxAytWJhGxmE0XncU6XcPZzkYP+U8xBxdoJrrhcNMMtiaRI1/XoNCfbHwGqEjmRFWMg5azKcK6Z1utxBSKmUoKSzbJ5tUxAnPU8mwC6YAy+mEzz3tbi1NKfN6hIFZBiBYKoBZDaCKEryjOaZEBmhZ7gkgjIgEroT/OXT7ZByDmuJTEsOvhULTCWzYNqnuF2tXKtJQqJwSry7QMpBJ/znGbx9YQX2lYdVPPgrGjgMm/sRRFlowCSYDT0gjSJBgx/hxQoxQfKIn+E1nfW2vrhkCV0HIy9YZQmg1kYuRAOmB/5w3EaJKOAjUbpbBwmqF9JENZkY2UFOoVLt9MPp7U7fuiOAte2MKyYAPFeDptB2eSxtsaKXGGKmpSunFr5u9WZztS5aGyYu9Sr37cftLGb+wE1FmqZ7bnQ2kJ73s+KLCsu0cq+0zc33u2FnJ0mLllf83z+SCuouXEKzE+MHd7SlQ4El+pwp4zWBosC7nOeajsSYy8gPdixRg/duszRo43JW2OwSiQTvNQJe7iDN7TRWiHmNOd/08dZQ22JRkxZPPgOjRZqw0qXy4PVa7WNUwq+omytQyOAAV9hsB9pck8fLap1CbgP3uktiKHHOhjTdKm34YxmEq5sS5dTlHgL6ltdw7DOKVPo2ILmcyCqqKtbWrCeVAITrb+rTSRdY13mjGD1KwVIDAMpcnLxI2bPhSSXeO4QSi5mPAN5QWiekgtTiJuBknKB1RL9YgKwyKYxVeiJ73phz416rn/uuxN/PAkHf6BMVaYdMsG5G07cwSQItczDd+7+sef4QfRNyiWrpMS8jMVdh9+95eQhxysuhJ7GGc8/SF0V9SmovxcC8Pu4Bzc+Xh2SDvN3FLSHhwVNt6GgY4lHoIeOzVWTk3HtuXVavjpibp6yIoVXOkFPEXTwcpem9YxJzWbKZGw9fJ222zmTvKdO+Qofpt5CsYKPOnuP6Kv2cueeccx4dO0LMU5YV/bRqW8UDPC+Hkh9KNxBfZE9QOiLbG+koY9lCE7kHPHx1xqTTt7lXP0EWQlCY5chJvhIl2UGMW50Ss7IpsV3U32OT63JlrJMuT2ZWo43tV7YNwS3RUBLT3f7qZXwBVMFo8rB1bOi93shshQPJwNv0ll5fbfvTi202cK4mvq0xfcbHZiayBTejnQqvBFHXyIY62PkDjJD/urAsmcq63hLuQ1LB9V2FH6mMoPGt+jWeaay9utwR4D+W1T2W0NftCwBX4E0jSX4DopVkGnYoim+RyOu1JQG5Ptf3mh2yzWiUeQL83KKpY4tkNsMx32StwJv4vr/Fm91HDtfDW9p3z8TbzWmvxhvHT/rOkDp+IscH4SiMIp0B+RBIGSEO0Douf11cAvtf93+SuY8w9ajwrzSPapg4AVDxMBHtb5q5Se0vlrO3P/y3BI8CK62eo9vd+1ZeEqra2fqSW2unZXjwdS1yXZzDDPk4PbWztKhra2d4uFtrZ3qceCp5cmNdhiG48HtrB+wnX8f69R9o+Ek/CTrbGXu3x73/Uulq7fUebJ8JaxT+/5ZWGdn+ouxjkmUDjwx49bVn/8A8TNPAVIbAAA=", "encoding": "utf-8"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235/comments?per_page=100", "headers": {"Access-Control-Allow-Origin": "*", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-RateLimit-Limit": "60", "X-Content-Type-Options": "nosniff", "Status": "200 OK", "ETag": "W/\"e3976b4745a8e99e2b01f67573a6871a\"", "Date": "Sun, 12 Feb 2017 16:29:07 GMT", "Content-Type": "application/json; charset=utf-8", "X-Frame-Options": "deny", "Cache-Control": "public, max-age=60, s-maxage=60", "X-Served-By": "b0ef53392caa42315c6206737946d931", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Server": "GitHub.com", "Content-Encoding": "gzip", "Vary": "Accept", "X-RateLimit-Remaining": "51", "X-XSS-Protection": "1; mode=block", "X-GitHub-Request-Id": "99EA:551B:1DCDB9D:258C620:58A08D53", "Content-Security-Policy": "default-src 'none'", "Transfer-Encoding": "chunked", "X-RateLimit-Reset": "1486918405"}}, "request": {"uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235/comments?per_page=100", "body": {"string": "", "encoding": "utf-8"}, "method": "GET", "headers": {"Connection": "keep-alive", "Accept": "application/vnd.github.v3.full+json", "Accept-Charset": "utf-8", "Content-Type": "application/json", "User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate"}}, "recorded_at": "2017-02-12T16:29:07"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:20:46 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "51", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"6a40ed61fa463a6dbe2bdd37dd9ae9f7\"", "Last-Modified": "Wed, 24 Jan 2018 15:25:22 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.081646", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "965C:2D36F:157CB42:3C96BAB:5A6A664E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "recorded_at": "2018-01-25T23:20:46"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235/comments?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+1ZbW/bNhD+K4T2YS0qW+9+Q9J1b9gCDMmQpSiwelAoiraJyqJGUk49I/99R0p2FFdx48TphiJJACvk3cPj8e746Px+ZZUis0bWTKlCjhwHF6w7ZWpWJl3C546gBZeOZNM5XjBRSj90qtmgWyydoswy6YDcnOZKOp7vh73+ILBsS8/Egv5dUqngc8HoVcxSa5TDuG3pp7WwbaVsMolnZf4BzHjzBnU8N7T76JXn9uwhgoGUThBNmXohaTaxkcLTOMdzenzKc6r/FVOqYm0EU0zO6uGGRMLTZTU6ztH6R1BVihzJkhAq5aTMYK6e1usxRUWMpaRK1svm5Tyh4rjj2YiCCQbw5Wicd9aIY0v/noAiVhTxBRVIzSiqQBBeYJbhJKNowvUEk0jQjGJJu+P81aMxELqAtSS4RTsfqxn4sj6o+gzXqxVLLcElOIvn6wPhgk1ZjrP4ZsILbatyqjk4K+q5xBt6UYTJIKBJMOh7QZpEPQJ/fUwxhgMlkT8A9A1aUz/skwQPg6HXj9KkNwkjl4Y94kd+f5gGySAgg0E6GYYJ6JeSCmu0sjIORsHSzfCDaW2OH7qDwLUtcCsEQLwVw2ZQBnUgazjCcwUxamK6dCrt7xbHIcBNRQ1itqmX35UQGux2QoDGTM2zLRsaObRl/oRnGb8ClG2rb2fepws5G01Ysnpm+fSBKKC5cjgEKDgPtnStHcGk2t8oo7WCqgCJzlKNI8H5gqZ7G1brgVlXOVi0MoFrAMtEEsEKHbH7G3hLG9C4mOKc/YMfhgbaEkBMXdx7h0YLtOlC18u91Su1lVMItsBkqV0jKKFsAc5+IOSWPiCqZUEhD97qHATXQyGMcTrXeTjBmaTXtqXrKUj8RtW3uohBoVOm0pEZzqcUKV6Vt5STjlQCAq27KU4oXUJhZgRB+SsEleAGxHN0+QtEz6VEV3DxIIwuJyyj8hLhPEWXphLXAwVmAsol2EUEhSqbxliBJb7rhR036rj+he+O/OEo7P0JMmWRtsgEF244cnujINQy98/c7XvP8YPom5RJUkoJcRmLu26/neXkPvcrLASW4lLNuLmTOGEmeGHnZ+9Ofz6HyThj+Qepa6a+I/XnTFD4POy1Dmev/dUCf0e1u7/PALpJGVqWeAAx0Y67rgM2riy3jorXBwzcI8JT+lpH7xHQIHjcxHA1Y+K2njLhXA3fxPR6zkT2kVO8hsPU+RUr+lGH9gFt1VZuzDOGGYtubEHGCOvaPjgnHAQ92Nc9OSEIt3DCyO4BJYxsb6ApIckgD9AFkMvzikS9eJsz9SvNCio0KTN8in7E8yKjMVQBjI7RqsH+xvqSH1ujNQcztfjF2HK8sfXSviW4rhBaerzJp0bAc6I4wcqB1TPeecdFlsLNZaiddBZe1+26YwswGySv4oQa8f1KO6biawq2I50SNuLoR6DN+o65g7cBO2shbc+cre0l5lMqtVflB+FnzmaI8yfc13nmbM235RYH/b842x81N8NFQeENSXO1BF5RoQwSTcVwCq/ZwCwqDkfR97+faGaXawKHgWCYd1eodWQGrM6wvM+yscAbuf5/xcZa7p2vg43pjT0RG6uhvxgbO3xIttCowy9yeJoUhVGkuyf3oklGuIUmPbfO9m6/fdWts2TKMmhbKogr3d4Kel7QB5K4q23m3dk2q7Qf0TZrWLP7xbshuBf1Wus9vFW2hfCYNtkG6lEtsg3K4ajWDWSzsQYhsndrbIO0b1tso7h/S2yjehhq1bDkVisN3HHvVthP8F3ALiZU9Zz6o/CzTGgtszs9dn0f09aXar1anpIJ/Xh2enF+8sPbi7Mv0Z2qtvckfGgD/cX4kImlFgpjxq3rv/4FLIzBFbIbAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:20:47 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "50", "X-RateLimit-Reset": "1516924595", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"43a972ba207ed683aa2d3bb0c14e57da\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.116180", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "965C:2D36F:157CB49:3C96BCC:5A6A664E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235/comments?per_page=100"}, "recorded_at": "2018-01-25T23:20:47"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/ReviewComment_reply.json b/tests/cassettes/ReviewComment_reply.json index ca017a3aa..7b025ed28 100644 --- a/tests/cassettes/ReviewComment_reply.json +++ b/tests/cassettes/ReviewComment_reply.json @@ -1 +1 @@ -{"recorded_with": "betamax/0.8.0", "http_interactions": [{"recorded_at": "2017-02-12T16:48:56", "response": {"headers": {"Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Cache-Control": "private, max-age=60, s-maxage=60", "X-Frame-Options": "deny", "X-Content-Type-Options": "nosniff", "Content-Encoding": "gzip", "ETag": "W/\"cf547b625e7ae890c7789b6fb8100d2a\"", "X-RateLimit-Remaining": "4986", "X-RateLimit-Limit": "5000", "Last-Modified": "Sun, 12 Feb 2017 16:43:39 GMT", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "X-RateLimit-Reset": "1486919865", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Allow-Origin": "*", "X-Served-By": "52437fedc85beec8da3449496900fb9a", "Content-Security-Policy": "default-src 'none'", "Content-Type": "application/json; charset=utf-8", "Status": "200 OK", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Date": "Sun, 12 Feb 2017 16:48:56 GMT", "X-GitHub-Request-Id": "80B0:5521:354C51D:42BD6A6:58A091F8", "X-XSS-Protection": "1; mode=block", "Server": "GitHub.com", "Transfer-Encoding": "chunked"}, "url": "https://api.github.com/repos/github3py/delete_contents/pulls/2", "status": {"code": 200, "message": "OK"}, "body": {"string": "", "encoding": "utf-8", "base64_string": "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"}}, "request": {"headers": {"User-Agent": "github3.py/1.0.0a4", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Authorization": "Basic ", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json"}, "method": "GET", "body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/github3py/delete_contents/pulls/2"}}, {"recorded_at": "2017-02-12T16:48:56", "response": {"headers": {"Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Cache-Control": "private, max-age=60, s-maxage=60", "X-Frame-Options": "deny", "X-Content-Type-Options": "nosniff", "ETag": "W/\"bae220dff764e35a0566d1f02e0d4ef6\"", "X-RateLimit-Remaining": "4985", "X-RateLimit-Limit": "5000", "Content-Encoding": "gzip", "X-RateLimit-Reset": "1486919865", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Allow-Origin": "*", "X-Served-By": "e724c57ebb9961c772a91e2dd7421c8d", "Content-Security-Policy": "default-src 'none'", "Content-Type": "application/json; charset=utf-8", "Status": "200 OK", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Date": "Sun, 12 Feb 2017 16:48:56 GMT", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "X-GitHub-Request-Id": "80B0:5521:354C52B:42BD6B2:58A091F8", "X-XSS-Protection": "1; mode=block", "Server": "GitHub.com", "Transfer-Encoding": "chunked"}, "url": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments?per_page=100", "status": {"code": 200, "message": "OK"}, "body": {"string": "", "encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA61V0W6bMBT9FeQ9NqkxkKSJujafME3dy9YKGbiAVWMz25BlUf591xBVbdZGS7QnY3PP8fH1udc/dqQzkqxI7VxrV5TyVlxXwtVddp3rhhpotaXjQtxuaQESHKS5Vg6Us7TtpLQUI5thysJwvlwki5BMiP+VGvjZgXU49gI2qSjIKmIJY/NZOCF+9oKYkEKUZVp36hnlrNfBlAVXLFivH9W04dsMAqsbcLVQVZCB1KqyQQ0GJsH4V2n3qK7G7w0EOVf44xmCL1/tvVfDXY28DsX4mbbCCa1QzYRoIyqhuEzfrPozCTcoJklRsuWsiGcRi0KWZ0s+u5nHeXbDgDFWcl5mC5jP5sj8QnYhvrNgyGpHpEZNuLUVVcN7YTobJUg/JDAJb2JMH++54yY9ur9h0R7u0LMd7mq4zo6O4Pv+c4xslTlwDKfEhZNe8GSWHgmqXSOPJLyyz1FwqaXUG2Q5Fv3WdH9vRF+QKHL8Rh9cyILIHdUOzZP6nfY+EcK680UNqB1WBxpcFJ7HYu4NFGcLO+BQ1kahot1QdwNhl9nciNab9XyBb9DIpk3FlfjNL2NDtEWSoSWcfcIBhWjofaM4Gz7CdrQ1ouf51qfGQA6ix2RfSHmER0a3bQHr4JsvQUy9wEbHi8aXYcmlhf2EZLrYYsQDdpHg0PQCpwM8nNziB6JyA9yhKO4wDpvFYhpGUxY9sPkqiVdx8h1jurY4FbP0Mafr6nRDptGnQti8sxZdk5oPm/LJav+3zh+h1FQK9Wx907IgSz/WBnD8728KXoBPyzs7vGo5F6YGuV8/WO/scdHLGJH9wTbpKJ3ctncf2eeWtneYT2+y1MEv76CPQsn+6Q/RIQ6LuwcAAA=="}}, "request": {"headers": {"User-Agent": "github3.py/1.0.0a4", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Authorization": "Basic ", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json"}, "method": "GET", "body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments?per_page=100"}}, {"recorded_at": "2017-02-12T16:48:57", "response": {"headers": {"Location": "https://api.github.com/repos/github3py/delete_contents/pulls/comments/100697567", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Cache-Control": "private, max-age=60, s-maxage=60", "X-Frame-Options": "deny", "X-RateLimit-Remaining": "4984", "ETag": "\"d3c21ab7da1eddc208ed7d75d12fd7ac\"", "X-Content-Type-Options": "nosniff", "X-RateLimit-Limit": "5000", "Content-Length": "1931", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "X-RateLimit-Reset": "1486919865", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Allow-Origin": "*", "X-Served-By": "0e17b94a265a427d9cafe798ceea7c02", "Content-Security-Policy": "default-src 'none'", "Content-Type": "application/json; charset=utf-8", "Status": "201 Created", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Date": "Sun, 12 Feb 2017 16:48:57 GMT", "X-GitHub-Request-Id": "80B0:5521:354C532:42BD6C0:58A091F8", "X-XSS-Protection": "1; mode=block", "Server": "GitHub.com"}, "url": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments", "status": {"code": 201, "message": "Created"}, "body": {"string": "{\"url\":\"https://api.github.com/repos/github3py/delete_contents/pulls/comments/100697567\",\"pull_request_review_id\":21411733,\"id\":100697567,\"diff_hunk\":\"@@ -1 +1 @@\\n-maybe something belongs here, maybe not\\n+maybe we can make PRs?\",\"path\":\"test\",\"position\":2,\"original_position\":2,\"commit_id\":\"4df195d3521201cb9a5863cb81e111faafb7e656\",\"original_commit_id\":\"4df195d3521201cb9a5863cb81e111faafb7e656\",\"user\":{\"login\":\"gh3test\",\"id\":2354350,\"avatar_url\":\"https://avatars.githubusercontent.com/u/2354350?v=3\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gh3test\",\"html_url\":\"https://github.com/gh3test\",\"followers_url\":\"https://api.github.com/users/gh3test/followers\",\"following_url\":\"https://api.github.com/users/gh3test/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gh3test/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gh3test/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gh3test/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gh3test/orgs\",\"repos_url\":\"https://api.github.com/users/gh3test/repos\",\"events_url\":\"https://api.github.com/users/gh3test/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gh3test/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"Replying to comments is fun.\",\"created_at\":\"2017-02-12T16:48:57Z\",\"updated_at\":\"2017-02-12T16:48:57Z\",\"html_url\":\"https://github.com/github3py/delete_contents/pull/2#discussion_r100697567\",\"pull_request_url\":\"https://api.github.com/repos/github3py/delete_contents/pulls/2\",\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/github3py/delete_contents/pulls/comments/100697567\"},\"html\":{\"href\":\"https://github.com/github3py/delete_contents/pull/2#discussion_r100697567\"},\"pull_request\":{\"href\":\"https://api.github.com/repos/github3py/delete_contents/pulls/2\"}},\"body_html\":\"

Replying to comments is fun.

\",\"body_text\":\"Replying to comments is fun.\"}", "encoding": "utf-8"}}, "request": {"headers": {"Content-Length": "66", "User-Agent": "github3.py/1.0.0a4", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Authorization": "Basic ", "Accept-Encoding": "gzip, deflate", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json"}, "method": "POST", "body": {"string": "{\"body\": \"Replying to comments is fun.\", \"in_reply_to\": 100697470}", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments"}}]} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/github3py/delete_contents/pulls/2"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:32:50 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4999", "X-RateLimit-Reset": "1516926770", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"52629ae3dce4404a8b6559947ff4c9b9\"", "Last-Modified": "Tue, 26 Dec 2017 15:52:13 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.211420", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "975A:2D36F:158D40F:3CC0B47:5A6A6922"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/github3py/delete_contents/pulls/2"}, "recorded_at": "2018-01-25T23:32:50"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+1XyW7bMBD9FYE9xo6szRvSxCiQYxcEKQq0KQRKoiQisqiSlF3X8L93SMmO7dpK5CynnrTNe3wcDudRP5ao5Bkao1TKQoxNExf0PKEyLYPzkE1NTgomzOqFUyzMiGREEj9kuSS5FGZRZpkwIXKqH61erz8auIMe6iD1yefkV0mEhOuMkrlPIzS2Ldey+l6vg9TTBtFBEY1jPy3ze5AzmRhdyzizjMnkLu9O8SIghmBTIlOaJ0ZAMpYnwkgJJx2j+pozeZefVfdzYoQ4hw/3xPhyI66UGixT4JUgRj0xQSVlOajpIMZpQnOc+Ttv1Zyo1IqRG8XWyIscz7bsnhUGI+wN+04YDC1iWVaMcRwMSN/rA/OG7ER8KQhH4yXKGGiCoQVNpnhGeSlsF+h1At3e0IH04RmWmPt766dfCqdeREVXL5Zez9Ks0Fez94ou4TWJnia8aCwGRSbMPUWpnGZ7GrbqZy84ZlnG5sCyr3q36v4dyNwgQWR1D4VwIgsglyaTUD2+GmmlEkGFbC9Ko5awPaDCaaR4BCSfk6i1sBoHsuY5KFrqjacJy0CEnBaqWtsL3EHr6kxwTv/g09gALYBE94TWM9QoQJOZ6hSt4RVsaRacznC4UKnhJCR0Bsk+kXIPD4xyURDYB1/VHoTUU+h0OJqqfRjjTJBVBwUsWkDELbQRo+56hmQGTC5bwA2gQk6wBFFYQhx0i0G3Z3ct+9bqj11n7LjfIaYsoqaYkYpp3lfNHdm030VUhKUQUDU+P9qVG3f701q/DVJxKVPGfSwEC6muLZj652+frm/go5/R/F6oliZIFqtryglcX9xxYHVUzg6MsNWPTswbcG/b2YExTvJNG63qmvIr6eiiuDxWWxdmcQn5VBXoS/JbldexULTqvIave/0BCGj09YHjbPs6IP77uj4X7Pt6kjr1WURbuuO5jjoSNXm6fdzTK/gzTP1BziN9ZyO7lZXX9Ke7+C7Bcwx8zfQs716TvJxtbxi3/R7qprVjr4namvUa196n18iXsegHHTvuDql4sjvfKDdW/wngzOtfE4MKIy7zc+Bpcujh2Bs85tDrmEd2iv6JOvbPdNChD/TX13Toj9cfP7ydRavJvZZF19xvZtFNBXbAppvCoR4pHNFUxfqS6d/NzXFt9fMv218ZNp8PAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:32:50 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4998", "X-RateLimit-Reset": "1516926770", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"641ff7f4ced7f8c66525f3506e0c4e85\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.151952", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "975A:2D36F:158D41C:3CC0B78:5A6A6922"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments?per_page=100"}, "recorded_at": "2018-01-25T23:32:50"}, {"request": {"body": {"encoding": "utf-8", "string": "{\"body\": \"Replying to comments is fun.\", \"in_reply_to\": 100697470}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "66", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments"}, "response": {"body": {"encoding": "utf-8", "string": "{\"url\":\"https://api.github.com/repos/github3py/delete_contents/pulls/comments/163999672\",\"pull_request_review_id\":91708465,\"id\":163999672,\"diff_hunk\":\"@@ -1 +1 @@\\n-maybe something belongs here, maybe not\\n+maybe we can make PRs?\",\"path\":\"test\",\"position\":2,\"original_position\":2,\"commit_id\":\"4df195d3521201cb9a5863cb81e111faafb7e656\",\"original_commit_id\":\"4df195d3521201cb9a5863cb81e111faafb7e656\",\"user\":{\"login\":\"gh3test\",\"id\":2354350,\"avatar_url\":\"https://avatars2.githubusercontent.com/u/2354350?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gh3test\",\"html_url\":\"https://github.com/gh3test\",\"followers_url\":\"https://api.github.com/users/gh3test/followers\",\"following_url\":\"https://api.github.com/users/gh3test/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gh3test/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gh3test/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gh3test/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gh3test/orgs\",\"repos_url\":\"https://api.github.com/users/gh3test/repos\",\"events_url\":\"https://api.github.com/users/gh3test/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gh3test/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"Replying to comments is fun.\",\"created_at\":\"2018-01-25T23:32:51Z\",\"updated_at\":\"2018-01-25T23:32:51Z\",\"html_url\":\"https://github.com/github3py/delete_contents/pull/2#discussion_r163999672\",\"pull_request_url\":\"https://api.github.com/repos/github3py/delete_contents/pulls/2\",\"author_association\":\"MEMBER\",\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/github3py/delete_contents/pulls/comments/163999672\"},\"html\":{\"href\":\"https://github.com/github3py/delete_contents/pull/2#discussion_r163999672\"},\"pull_request\":{\"href\":\"https://api.github.com/repos/github3py/delete_contents/pulls/2\"}},\"body_html\":\"

Replying to comments is fun.

\",\"body_text\":\"Replying to comments is fun.\",\"in_reply_to_id\":100697470}"}, "headers": {"Server": "GitHub.com", "Date": "Thu, 25 Jan 2018 23:32:51 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "1989", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4997", "X-RateLimit-Reset": "1516926770", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"de5eaf2ccc66b194b8a3768d058a1df2\"", "Location": "https://api.github.com/repos/github3py/delete_contents/pulls/comments/163999672", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.466106", "X-GitHub-Request-Id": "975A:2D36F:158D427:3CC0B98:5A6A6922"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/repos/github3py/delete_contents/pulls/2/comments"}, "recorded_at": "2018-01-25T23:32:51"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/integration/test_pulls.py b/tests/integration/test_pulls.py index 285039b9a..2c525b3d6 100644 --- a/tests/integration/test_pulls.py +++ b/tests/integration/test_pulls.py @@ -154,11 +154,10 @@ def test_repository(self): cassette_name = self.cassette_name('single') with self.recorder.use_cassette(cassette_name): p = self.get_pull_request() - assert p.repository == ('sigmavirus24', 'github3.py') + assert isinstance(p.repository, github3.repos.ShortRepository) class TestReviewComment(IntegrationHelper): - """Integration tests for the ReviewComment object.""" def test_reply(self): @@ -174,6 +173,7 @@ def test_reply(self): class TestPullFile(IntegrationHelper): """Integration tests for the PullFile object.""" + def get_pull_request_file(self, owner, repo, pull_number, filename): p = self.gh.pull_request(owner, repo, pull_number) diff --git a/tests/unit/json/pull_request_example b/tests/unit/json/pull_request_example index 247d915ad..80774efdd 100644 --- a/tests/unit/json/pull_request_example +++ b/tests/unit/json/pull_request_example @@ -35,6 +35,25 @@ "type": "User", "site_admin": false }, + "assignees": [{ + "login": "octocat", + "id": 1, + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "gravatar_id": "", + "url": "https://api.github.com/users/octocat", + "html_url": "https://github.com/octocat", + "followers_url": "https://api.github.com/users/octocat/followers", + "following_url": "https://api.github.com/users/octocat/following{/other_user}", + "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}", + "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/octocat/subscriptions", + "organizations_url": "https://api.github.com/users/octocat/orgs", + "repos_url": "https://api.github.com/users/octocat/repos", + "events_url": "https://api.github.com/users/octocat/events{/privacy}", + "received_events_url": "https://api.github.com/users/octocat/received_events", + "type": "User", + "site_admin": false + }], "milestone": { "url": "https://api.github.com/repos/octocat/Hello-World/milestones/1", "html_url": "https://github.com/octocat/Hello-World/milestones/v1.0", diff --git a/tests/unit/json/review_comment_example b/tests/unit/json/review_comment_example index e84ad6e7e..61510d339 100644 --- a/tests/unit/json/review_comment_example +++ b/tests/unit/json/review_comment_example @@ -1,5 +1,6 @@ { "url": "https://api.github.com/repos/octocat/Hello-World/pulls/comments/1", + "author_association": "OWNER", "id": 10, "pull_request_review_id": 42, "diff_hunk": "@@ -16,33 +16,40 @@ public class Connection : IConnection...", @@ -29,6 +30,8 @@ "site_admin": false }, "body": "Great stuff", + "body_html": "Great stuff", + "body_text": "Great stuff", "created_at": "2011-04-14T16:00:49Z", "updated_at": "2011-04-14T16:00:49Z", "html_url": "https://github.com/octocat/Hello-World/pull/1#discussion-diff-1", diff --git a/tests/unit/test_events.py b/tests/unit/test_events.py index b7400084d..0f0de9ab0 100644 --- a/tests/unit/test_events.py +++ b/tests/unit/test_events.py @@ -6,6 +6,9 @@ get_example_data = create_example_data_helper('event_example') get_org_example_data = create_example_data_helper('org_example') get_comment_example_data = create_example_data_helper('comment_example') +get_review_comment_example_data = create_example_data_helper( + 'review_comment_example' +) get_pull_request_example_data = create_example_data_helper( 'pull_request_example' ) @@ -100,9 +103,10 @@ def test_pullreqev(self): def test_pullreqcomment(self): """Show that the event type is a PullRequestReviewCommentEvent.""" - pull_request = {'comment': get_comment_example_data()} + pull_request = {'comment': get_review_comment_example_data()} github3.events._pullreqcomm(pull_request, None) - assert isinstance(pull_request['comment'], github3.pulls.ReviewComment) + assert isinstance(pull_request['comment'], + github3.events.EventReviewComment) def test_team(self): """Show that the event type is a TeamAddEvent.""" diff --git a/tests/unit/test_pulls.py b/tests/unit/test_pulls.py index 4fc31f250..d4306308d 100644 --- a/tests/unit/test_pulls.py +++ b/tests/unit/test_pulls.py @@ -78,13 +78,6 @@ def test_is_merged_request(self): self.session.get.assert_called_once_with(url_for('merge')) - def test_is_merged_no_requset(self): - """Show that no request is needed if .merged is True.""" - self.instance.merged = True - - assert self.instance.is_merged() - assert self.session.get.called is False - def test_issue(self): """Show that a user can retrieve the associated issue of a PR.""" self.instance.issue() From c68d0b33c63d28ae3c9aee57e5bcac43b1ab6902 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Thu, 25 Jan 2018 18:35:31 -0600 Subject: [PATCH 08/56] Fix-up projects documentation --- github3/projects.py | 281 +++++++++++++++++++++++++++++++------------- 1 file changed, 201 insertions(+), 80 deletions(-) diff --git a/github3/projects.py b/github3/projects.py index 448f7820c..ded429ee0 100644 --- a/github3/projects.py +++ b/github3/projects.py @@ -13,9 +13,45 @@ class Project(models.GitHubCore): - """The :class:`Project ` object. + """Object representing a single project from the API. - See http://developer.github.com/v3/projects/ + See http://developer.github.com/v3/projects/ for more details. + + .. attribute:: body + + The Markdown formatted text describing the project. + + .. attribute:: created_at + + A :class:`~datetime.datetime` representing the date and time when + this project was created. + + .. attribute:: creator + + A :class:`~github3.users.ShortUser` instance representing the user who + created this project. + + .. attribute:: id + + The unique identifier for this project on GitHub. + + .. attribute:: name + + The name given to this project. + + .. attribute:: number + + The repository-local identifier of this project. + + .. attribute:: owner_url + + The URL of the resource in the API of the owning resource - either + a repository or an organization. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` representing the date and time when + this project was last updated. """ CUSTOM_HEADERS = { @@ -24,29 +60,13 @@ class Project(models.GitHubCore): def _update_attributes(self, project): self._api = project['url'] - - #: The body of the project self.body = project['body'] - - #: datetime object representing when the project was created self.created_at = self._strptime(project['created_at']) - - #: The user who created this project self.creator = users.ShortUser(project['creator'], self) - - #: The unique ID of the project self.id = project['id'] - - #: The name of this project self.name = project['name'] - - #: The number of the project self.number = project['number'] - - #: The owner repo or organisation of this project self.owner_url = project['owner_url'] - - #: datetime object representing the last time the object was changed self.updated_at = self._strptime(project['updated_at']) def _repr(self): @@ -55,9 +75,12 @@ def _repr(self): def column(self, id): """Get a project column with the given ID. - :param int id: (required), the column ID - :returns: :class:`ProjectColumn ` - or None + :param int id: + (required), the column ID + :returns: + the desired column in the project + :rtype: + :class:`~github3.projects.ProjectColumn` """ url = self._build_url( 'projects', 'columns', str(id), base_url=self._github_url) @@ -67,13 +90,18 @@ def column(self, id): def columns(self, number=-1, etag=None): """Iterate over the columns in this project. - :param int number: (optional), number of columns to return. Default: - -1 returns all available columns. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of - :class:`ProjectColumn ` + :param int number: + (optional), number of columns to return. Default: -1 returns all + available columns. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of columns + :rtype: + :class:`~github3.project.ProjectColumn` """ + # TODO(sigmaviurs24): Determine if we need to construct from scratch + # or if we can use `self._api` with 'columns' to build the URL url = self._build_url( 'projects', str(self.id), 'columns', base_url=self._github_url) return self._iter( @@ -88,9 +116,12 @@ def columns(self, number=-1, etag=None): def create_column(self, name): """Create a column in this project. - :param str name: (required), name of the column - :returns: :class:`ProjectColumn ` - or none + :param str name: + (required), name of the column + :returns: + the created project column + :rtype: + :class:`~github3.projects.ProjectColumn` """ url = self._build_url('columns', base_url=self._api) json = None @@ -103,7 +134,10 @@ def create_column(self, name): def delete(self): """Delete this project. - :returns: bool + :returns: + True if successfully deleted, False otherwise + :rtype: + bool """ return self._boolean(self._delete( self._api, headers=self.CUSTOM_HEADERS), 204, 404) @@ -112,9 +146,14 @@ def delete(self): def update(self, name=None, body=None): """Update this project. - :param str name: (optional), name of the project - :param str body: (optional), body of the project - :returns: bool + :param str name: + (optional), new name of the project + :param str body: + (optional), new body of the project + :returns: + True if successfully updated, False otherwise + :rtype: + bool """ data = {'name': name, 'body': body} json = None @@ -131,25 +170,38 @@ def update(self, name=None, body=None): class ProjectColumn(models.GitHubCore): - """The :class:`ProjectColumn ` object. + """Object representing a column in a project. See http://developer.github.com/v3/projects/columns/ + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + when the column was created. + + .. attribute:: id + + The unique identifier for this column across GitHub. + + .. attribute:: name + + The name given to this column. + + .. attribute:: project_url + + The URL used to retrieve the project that owns this column via the API. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` object representing the date and time + when the column was last updated. """ def _update_attributes(self, project_column): - #: datetime object representing the last time the object was created self.created_at = self._strptime(project_column['created_at']) - - #: The ID of this column self.id = project_column['id'] - - #: The name of this column self.name = project_column['name'] - - #: The URL of this column's project self.project_url = project_column['project_url'] - - #: datetime object representing the last time the object was changed self.updated_at = self._strptime(project_column['updated_at']) def _repr(self): @@ -158,8 +210,12 @@ def _repr(self): def card(self, id): """Get a project card with the given ID. - :param int id: (required), the card ID - :returns: :class:`ProjectCard ` or None + :param int id: + (required), the card ID + :returns: + the card identified by the provided id + :rtype: + :class:`~github3.projects.ProjectCard` """ url = self._build_url( 'projects/columns/cards', str(id), base_url=self._github_url) @@ -169,12 +225,15 @@ def card(self, id): def cards(self, number=-1, etag=None): """Iterate over the cards in this column. - :param int number: (optional), number of cards to return. Default: - -1 returns all available cards. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of - :class:`ProjectCard ` + :param int number: + (optional), number of cards to return. Default: -1 returns all + available cards. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of cards + :rtype: + :class:`~github3.project.ProjectCard` """ url = self._build_url( 'projects/columns', @@ -194,9 +253,14 @@ def cards(self, number=-1, etag=None): def create_card_with_content_id(self, content_id, content_type): """Create a content card in this project column. - :param int content_id: (required), the ID of the content - :param str content_type: (required), the type of the content - :returns: :class:`ProjectCard ` or none + :param int content_id: + (required), the ID of the content + :param str content_type: + (required), the type of the content + :returns: + the created card + :rtype: + :class:`~github3.projects.ProjectCard` """ if not content_id or not content_type: return None @@ -217,10 +281,15 @@ def create_card_with_content_id(self, content_id, content_type): def create_card_with_issue(self, issue): """Create a card in this project column linked with an Issue. - :param :class:`Issue `: (required), an issue - with which to link the card. Can also be - :class:`ShortIssue `. - :returns: :class:`ProjectCard ` or none + :param issue: + (required), an issue with which to link the card. Can also be + :class:`~github3.issues.ShortIssue`. + :type issue: + :class:`~github3.issues.Issue` + :returns: + the created card + :rtype: + :class:`~github3.projects.ProjectCard` """ if not issue: return None @@ -230,8 +299,12 @@ def create_card_with_issue(self, issue): def create_card_with_note(self, note): """Create a note card in this project column. - :param str note: (required), the note content - :returns: :class:`ProjectCard ` or none + :param str note: + (required), the note content + :returns: + the created card + :rtype: + :class:`~github3.projects.ProjectCard` """ url = self._build_url( 'projects/columns', @@ -249,7 +322,10 @@ def create_card_with_note(self, note): def delete(self): """Delete this column. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url( 'projects/columns', self.id, base_url=self._github_url) @@ -260,10 +336,14 @@ def delete(self): def move(self, position): """Move this column. - :param str position: (required), can be one of `first`, `last`, - or `after:`, where `` is the id value - of a column in the same project. - :returns: bool + :param str position: + (required), can be one of `first`, `last`, or `after:`, + where `` is the id value of a column in the same + project. + :returns: + True if successful, False otherwise + :rtype: + bool """ if not position: return False @@ -282,8 +362,12 @@ def move(self, position): def update(self, name=None): """Update this column. - :param str name: (optional), name of the column - :returns: bool + :param str name: + (optional), name of the column + :returns: + True if successful, False otherwise + :rtype: + bool """ data = {'name': name} json = None @@ -302,9 +386,35 @@ def update(self, name=None): class ProjectCard(models.GitHubCore): - """The :class:`ProjectCard ` object. + """Object representing a "card" on a project. See http://developer.github.com/v3/projects/cards/ + + .. attribute:: column_url + + The URL to retrieve this card's column via the API. + + .. attribute:: content_url + + The URl to retrieve this card's body content via the API. + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + when the column was created. + + .. attribute:: id + + The globally unique identifier for this card. + + .. attribute:: note + + The body of the note attached to this card. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` object representing the date and time + when the column was last updated. """ def _update_attributes(self, project_card): @@ -333,7 +443,10 @@ def _repr(self): def delete(self): """Delete this card. - :returns: bool + :returns: + True if successfully deleted, False otherwise + :rtype: + bool """ url = self._build_url( 'projects/columns/cards', self.id, base_url=self._github_url) @@ -344,12 +457,16 @@ def delete(self): def move(self, position, column_id): """Move this card. - :param str position: (required), can be one of `top`, `bottom`, or - `after:`, where `` is the id value of a card - in the same column, or in the new column specified by `column_id`. - :param int column_id: (required), the id value of a column in the - same project. - :returns: bool + :param str position: + (required), can be one of `top`, `bottom`, or `after:`, + where `` is the id value of a card in the same column, or + in the new column specified by `column_id`. + :param int column_id: + (required), the id value of a column in the same project. + :returns: + True if successfully moved, False + :rtype: + bool """ if not position or not column_id: return False @@ -368,10 +485,14 @@ def move(self, position, column_id): def update(self, note=None): """Update this card. - :param str note: (optional), the card's note content. Only valid for - cards without another type of content, so this cannot be specified - if the card already has a content_id and content_type. - :returns: bool + :param str note: + (optional), the card's note content. Only valid for cards without + another type of content, so this cannot be specified if the card + already has a content_id and content_type. + :returns: + True if successfully updated, False otherwise + :rtype: + bool """ data = {'note': note} json = None From e65d27b5474f06bff89a918e62e4d0058e51b637 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 3 Feb 2018 08:47:21 -0600 Subject: [PATCH 09/56] Split out ShortTeam from Team This also introduces consistency in the orgs module in how we set-up attributes for the *Team and *Organization classes. It also rewrites the docstrings to be consistent with the rest of the library --- github3/events.py | 5 +- github3/github.py | 29 +- github3/orgs.py | 866 +++++++++++++++++-------- github3/repos/repo.py | 4 +- github3/users.py | 9 +- tests/cassettes/Repository_teams.json | 2 +- tests/cassettes/Team_repositories.json | 2 +- tests/integration/test_github.py | 2 +- tests/integration/test_orgs.py | 2 +- tests/integration/test_repos_repo.py | 6 +- tests/unit/json/orgs_team_example | 39 +- tests/unit/test_events.py | 2 +- tests/unit/test_orgs_team.py | 7 +- 13 files changed, 678 insertions(+), 297 deletions(-) diff --git a/github3/events.py b/github3/events.py index a7a02f107..ee785da1c 100644 --- a/github3/events.py +++ b/github3/events.py @@ -266,10 +266,10 @@ def _release(payload, session): def _team(payload, session): - from .orgs import Team + from .orgs import ShortTeam from .repos import ShortRepository if payload.get('team'): - payload['team'] = Team(payload['team'], session) + payload['team'] = ShortTeam(payload['team'], session) if payload.get('repo'): payload['repo'] = ShortRepository(payload['repo'], session) if payload.get('sender'): @@ -278,6 +278,7 @@ def _team(payload, session): def identity(x, session): + """Return the value.""" return x diff --git a/github3/github.py b/github3/github.py index bbbdf55f1..7d5cd7a11 100644 --- a/github3/github.py +++ b/github3/github.py @@ -17,13 +17,14 @@ from . import gists from .issues import ShortIssue, Issue, issue_params from .models import GitHubCore -from .orgs import Membership, ShortOrganization, Organization, Team +from .orgs import Membership, ShortOrganization, Organization from .projects import Project, ProjectCard, ProjectColumn from .pulls import PullRequest from .repos import repo from .search import (CodeSearchResult, IssueSearchResult, RepositorySearchResult, UserSearchResult) from .structs import SearchIterator +from . import orgs from . import users from .notifications import Thread from .licenses import License @@ -828,9 +829,22 @@ def me(self): @requires_auth def membership_in(self, organization): - """Retrieve the user's membership in the specified organization.""" - url = self._build_url('user', 'memberships', 'orgs', - str(organization)) + """Retrieve the user's membership in the specified organization. + + :param organization: + the organization or organization login to retrieve the authorized + user's membership in + :type organization: + str + :type organization: + :class:`~github3.orgs.Organization` + :returns: + the user's membership + :rtype: + :class:`~github3.orgs.Membership` + """ + organization_name = getattr(organization, 'login', organization) + url = self._build_url('user', 'memberships', 'orgs', organization_name) json = self._json(self._get(url), 200) return self._instance_or_null(Membership, json) @@ -1708,10 +1722,13 @@ def user_teams(self, number=-1, etag=None): authenticated user belongs. This method requires user or repo scope when authenticating via OAuth. - :returns: generator of :class:`Team ` objects + :returns: + generator of teams + :rtype: + :class:`~github3.orgs.ShortTeam` """ url = self._build_url('user', 'teams') - return self._iter(int(number), url, Team, etag=etag) + return self._iter(int(number), url, orgs.ShortTeam, etag=etag) def user_with_id(self, number): """Get the user's information with id ``number``. diff --git a/github3/orgs.py b/github3/orgs.py index 9bbaefbe0..9aff240cd 100644 --- a/github3/orgs.py +++ b/github3/orgs.py @@ -15,56 +15,35 @@ from .repos import Repository, ShortRepository -class Team(models.GitHubCore): - - """The :class:`Team ` object. - - Please see GitHub's `Team Documentation`_ for more information. - - .. _Team Documentation: - http://developer.github.com/v3/orgs/teams/ - """ +class _Team(models.GitHubCore): + """Base class for Team representations.""" + class_name = '_Team' # Roles available to members on a team. members_roles = frozenset(['member', 'maintainer', 'all']) def _update_attributes(self, team): - self._api = self._get_attribute(team, 'url') - - #: This team's name. - self.name = self._get_attribute(team, 'name') - #: This team's slug. - self.slug = self._get_attribute(team, 'slug') - #: Unique ID of the team. - self.id = self._get_attribute(team, 'id') - - #: Permission level of the group. - self.permission = self._get_attribute(team, 'permission') - - #: Number of members in this team. - self.members_count = self._get_attribute(team, 'members_count') - - #: Members URL Template. Expands with ``member``. - self.members_urlt = self._class_attribute( - team, 'members_url', URITemplate - ) - - #: Number of repos owned by this team. - self.repos_count = self._get_attribute(team, 'repos_count') - - #: Repositories url (not a template). - self.repositories_url = self._get_attribute(team, 'repositories_url') + self._api = team['url'] + self.id = team['id'] + self.members_urlt = URITemplate(team['members_url']) + self.name = team['name'] + self.permission = team['permission'] + self.repositories_url = team['repositories_url'] + self.slug = team['slug'] def _repr(self): - return ''.format(self.name) + return '<{s.class_name} [{s.name}]>'.format(s=self) @requires_auth def add_member(self, username): """Add ``username`` to this team. - :param str username: the username of the user you would like to add to - the team. - :returns: bool + :param str username: + the username of the user you would like to add to this team. + :returns: + True if successfully added, False otherwise + :rtype: + bool """ warnings.warn( 'This is no longer supported by the GitHub API, see ' @@ -81,9 +60,14 @@ def add_repository(self, repository, permission=''): If a permission is not provided, the team's default permission will be assigned, by GitHub. - :param str repository: (required), form: 'user/repo' - :param str permission: (optional), ('pull', 'push', 'admin') - :returns: bool + :param str repository: + (required), form: 'user/repo' + :param str permission: + (optional), ('pull', 'push', 'admin') + :returns: + True if successful, False otherwise + :rtype: + bool """ data = {} if permission: @@ -95,7 +79,10 @@ def add_repository(self, repository, permission=''): def delete(self): """Delete this team. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ return self._boolean(self._delete(self._api), 204, 404) @@ -103,9 +90,14 @@ def delete(self): def edit(self, name, permission=''): """Edit this team. - :param str name: (required) - :param str permission: (optional), ('pull', 'push', 'admin') - :returns: bool + :param str name: + (required), the new name of this team + :param str permission: + (optional), one of ('pull', 'push', 'admin') + :returns: + True if successful, False otherwise + :rtype: + bool """ if name: data = {'name': name, 'permission': permission} @@ -119,8 +111,12 @@ def edit(self, name, permission=''): def has_repository(self, repository): """Check if this team has access to ``repository``. - :param str repository: (required), form: 'user/repo' - :returns: bool + :param str repository: + (required), form: 'user/repo' + :returns: + True if the team can access the repository, False otherwise + :rtype: + bool """ url = self._build_url('repos', repository, base_url=self._api) return self._boolean(self._get(url), 204, 404) @@ -133,8 +129,12 @@ def invite(self, username): {'state': 'pending', 'url': 'https://api.github.com/teams/...'} - :param str username: (required), user to invite to join this team. - :returns: dictionary + :param str username: + (required), login of user to invite to join this team. + :returns: + dictionary of the invitation response + :rtype: + dict """ url = self._build_url('memberships', username, base_url=self._api) return self._json(self._put(url), 200) @@ -143,24 +143,33 @@ def invite(self, username): def is_member(self, username): """Check if ``login`` is a member of this team. - :param str username: (required), username name of the user - :returns: bool + :param str username: + (required), username name of the user + :returns: + True if the user is a member, False otherwise + :rtype: + bool """ url = self._build_url('members', username, base_url=self._api) return self._boolean(self._get(url), 204, 404) @requires_auth def members(self, role=None, number=-1, etag=None): - r"""Iterate over the members of this team. - - :param str role: (optional), filter members returned by their role - in the team. Can be one of: ``"member"``, ``"maintainer"``, - ``"all"``. Default: ``"all"``. - :param int number: (optional), number of users to iterate over. - Default: -1 iterates over all values - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`User `\ s + """Iterate over the members of this team. + + :param str role: + (optional), filter members returned by their role in the team. + Can be one of: ``"member"``, ``"maintainer"``, ``"all"``. Default: + ``"all"``. + :param int number: + (optional), number of users to iterate over. Default: -1 iterates + over all values + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of the members of this team + :rtype: + :class:`~github3.users.ShortUser` """ headers = {} params = {} @@ -175,12 +184,15 @@ def members(self, role=None, number=-1, etag=None): def repositories(self, number=-1, etag=None): """Iterate over the repositories this team has access to. - :param int number: (optional), number of repos to iterate over. - Default: -1 iterates over all values - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`Repository ` - objects + :param int number: + (optional), number of repos to iterate over. Default: -1 iterates + over all values + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of repositories this team has access to + :rtype: + :class:`~github3.repos.ShortRepository` """ headers = {'Accept': 'application/vnd.github.ironman-preview+json'} url = self._build_url('repos', base_url=self._api) @@ -191,8 +203,12 @@ def repositories(self, number=-1, etag=None): def membership_for(self, username): """Retrieve the membership information for the user. - :param str username: (required), name of the user - :returns: dictionary + :param str username: + (required), name of the user + :returns: + dictionary with the membership + :rtype: + dict """ url = self._build_url('memberships', username, base_url=self._api) json = self._json(self._get(url), 200) @@ -202,8 +218,12 @@ def membership_for(self, username): def remove_member(self, username): """Remove ``username`` from this team. - :param str username: (required), username of the member to remove - :returns: bool + :param str username: + (required), username of the member to remove + :returns: + True if successful, False otherwise + :rtype: + bool """ warnings.warn( 'This is no longer supported by the GitHub API, see ' @@ -217,8 +237,12 @@ def remove_member(self, username): def revoke_membership(self, username): """Revoke this user's team membership. - :param str username: (required), name of the team member - :returns: bool + :param str username: + (required), name of the team member + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('memberships', username, base_url=self._api) return self._boolean(self._delete(url), 204, 404) @@ -227,15 +251,113 @@ def revoke_membership(self, username): def remove_repository(self, repository): """Remove ``repository`` from this team. - :param str repository: (required), form: 'user/repo' - :returns: bool + :param str repository: + (required), form: 'user/repo' + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('repos', repository, base_url=self._api) return self._boolean(self._delete(url), 204, 404) -class _Organization(models.GitHubCore): +class ShortTeam(_Team): + """Object representing a team in the GitHub API. + + .. attribute:: id + + Unique identifier for this team across all of GitHub. + + .. attribute:: members_count + + The number of members in this team. + + .. attribute:: members_urlt + + A :class:`~uritemplate.URITemplate` instance to either retrieve all + members in this team or to test if a user is a member. + + .. attribute:: name + + The human-readable name provided to this team. + + .. attribute:: permission + + The level of permissions this team has, e.g., ``push``, ``pull``, + or ``admin``. + + .. attribute:: repos_count + + The number of repositories this team can access. + + .. attribute:: repositories_url + + The URL of the resource to enumerate all repositories this team can + access. + + .. attribute:: slug + + The handle for this team or the portion you would use in an + at-mention after the ``/``, e.g., in ``@myorg/myteam`` the + slug is ``myteam``. + + Please see GitHub's `Team Documentation`_ for more information. + + .. _Team Documentation: + http://developer.github.com/v3/orgs/teams/ + """ + class_name = 'ShortTeam' + + +class Team(_Team): + """Object representing a team in the GitHub API. + + In addition to the attributes on a :class:`~github3.orgs.ShortTeam` a Team + has the following attribute: + + .. attribute:: created_at + + A :class:`~datetime.datetime` instance representing the time and date + when this team was created. + + .. attribute:: members_count + + The number of members in this team. + + .. attribute:: organization + + A :class:`~github3.orgs.ShortOrganization` representing the + organization this team belongs to. + + .. attribute:: repos_count + + The number of repositories this team can access. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` instance representing the time and date + when this team was updated. + + Please see GitHub's `Team Documentation`_ for more information. + + .. _Team Documentation: + http://developer.github.com/v3/orgs/teams/ + """ + + class_name = 'Team' + + def _update_attributes(self, team): + super(Team, self)._update_attributes(team) + self.created_at = self._strptime(team['created_at']) + self.members_count = team['members_count'] + self.organization = ShortOrganization(team['organization'], self) + self.repos_count = team['repos_count'] + self.updated_at = self._strptime(team['updated_at']) + + +class _Organization(models.GitHubCore): """The :class:`Organization ` object. Please see GitHub's `Organization Documentation`_ for more information. @@ -244,6 +366,8 @@ class _Organization(models.GitHubCore): http://developer.github.com/v3/orgs/ """ + class_name = '_Organization' + # Filters available when listing members. Note: ``"2fa_disabled"`` # is only available for organization owners. members_filters = frozenset(['2fa_disabled', 'all']) @@ -252,41 +376,41 @@ class _Organization(models.GitHubCore): members_roles = frozenset(['all', 'admin', 'member']) def _update_attributes(self, org): - #: URL of the avatar at gravatar self.avatar_url = org['avatar_url'] - - # Set the type of object (this doens't come through API data) - self.type = 'Organization' - - self.url = self._api = org['url'] - - #: Unique ID of the account + self.description = org['description'] + self.events_url = org['events_url'] + self.hooks_url = org['hooks_url'] self.id = org['id'] - - #: Name of the organization + self.issues_url = org['issues_url'] self.login = org['login'] - - #: Public Members URL Template. Expands with ``member`` + self.members_url = org['members_url'] self.public_members_urlt = URITemplate(org['public_members_url']) - - #: Various urls (not templates) - for urltype in ('avatar_url', 'events_url', 'issues_url', - 'repos_url'): - setattr(self, urltype, org[urltype]) + self.repos_url = org['repos_url'] + self.url = self._api = org['url'] + self.type = 'Organization' def _repr(self): - return ''.format(s=self) + display_name = '' + name = getattr(self, 'name', None) + if name is not None: + display_name = ':{}'.format(name) + return '<{s.class_name} [{s.login}{display}]>'.format( + s=self, + display=display_name, + ) @requires_auth def add_member(self, username, team_id): """Add ``username`` to ``team`` and thereby to this organization. .. warning:: + This method is no longer valid. To add a member to a team, you must now retrieve the team directly, and use the ``invite`` method. .. warning:: + This method is no longer valid. To add a member to a team, you must now retrieve the team directly, and use the ``invite`` method. @@ -300,9 +424,14 @@ def add_member(self, username, team_id): ``team_id``. This parameter is now required to be an integer to improve performance of this method. - :param str username: (required), login name of the user to be added - :param int team_id: (required), team id - :returns: bool + :param str username: + (required), login name of the user to be added + :param int team_id: + (required), team id + :returns: + True if successful, False otherwise + :rtype: + bool """ warnings.warn( 'This is no longer supported by the GitHub API, see ' @@ -326,9 +455,14 @@ def add_repository(self, repository, team_id): # FIXME(jlk): add perms ``team_id``. This parameter is now required to be an integer to improve performance of this method. - :param str repository: (required), form: 'user/repo' - :param int team_id: (required), team id - :returns: bool + :param str repository: + (required), form: 'user/repo' + :param int team_id: + (required), team id + :returns: + True if successful, False otherwise + :rtype: + bool """ if int(team_id) < 0: return False @@ -343,8 +477,14 @@ def create_project(self, name, body=''): If the client is authenticated and a member of the organization, this will create a new project in the organization. - :param str name: (required), name of the project - :param str body: (optional), the body of the project + :param str name: + (required), name of the project + :param str body: + (optional), the body of the project + :returns: + the new project + :rtype: + :class:`~github3.projects.Project` """ url = self._build_url('projects', base_url=self._api) data = {'name': name, 'body': body} @@ -362,25 +502,40 @@ def create_repository(self, name, description='', homepage='', If the client is authenticated and a member of the organization, this will create a new repository in the organization. - :param str name: (required), name of the repository - :param str description: (optional) - :param str homepage: (optional) - :param bool private: (optional), If ``True``, create a private - repository. API default: ``False`` - :param bool has_issues: (optional), If ``True``, enable issues for - this repository. API default: ``True`` - :param bool has_wiki: (optional), If ``True``, enable the wiki for - this repository. API default: ``True`` - :param int team_id: (optional), id of the team that will be granted - access to this repository - :param bool auto_init: (optional), auto initialize the repository. - :param str gitignore_template: (optional), name of the template; this - is ignored if auto_int = False. - :param str license_template: (optional), name of the license; this - is ignored if auto_int = False. - :returns: :class:`Repository ` - - .. warning: ``name`` should be no longer than 100 characters + ``name`` should be no longer than 100 characters + + :param str name: + (required), name of the repository + + .. warning:: this should be no longer than 100 characters + :param str description: + (optional) + :param str homepage: + (optional) + :param bool private: + (optional), If ``True``, create a private repository. API default: + ``False`` + :param bool has_issues: + (optional), If ``True``, enable issues for this repository. API + default: ``True`` + :param bool has_wiki: + (optional), If ``True``, enable the wiki for this repository. API + default: ``True`` + :param int team_id: + (optional), id of the team that will be granted access to this + repository + :param bool auto_init: + (optional), auto initialize the repository. + :param str gitignore_template: + (optional), name of the template; this is ignored if auto_int is + False. + :param str license_template: + (optional), name of the license; this is ignored if auto_int is + False. + :returns: + the created repository + :rtype: + :class:`~github3.repos.Repository` """ url = self._build_url('repos', base_url=self._api) data = {'name': name, 'description': description, @@ -397,8 +552,12 @@ def create_repository(self, name, description='', homepage='', def conceal_member(self, username): """Conceal ``username``'s membership in this organization. - :param str username: username of the organization member to conceal - :returns: bool + :param str username: + username of the organization member to conceal + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('public_members', username, base_url=self._api) return self._boolean(self._delete(url), 204, 404) @@ -409,10 +568,12 @@ def create_team(self, name, repo_names=[], permission='pull'): This only works if the authenticated user owns this organization. - :param str name: (required), name to be given to the team - :param list repo_names: (optional) repositories, e.g. - ['github/dotfiles'] - :param str permission: (optional), options: + :param str name: + (required), name to be given to the team + :param list repo_names: + (optional) repositories, e.g. ['github/dotfiles'] + :param str permission: + (optional), options: - ``pull`` -- (default) members can not push or administer repositories accessible by this team @@ -420,8 +581,10 @@ def create_team(self, name, repo_names=[], permission='pull'): repositories accessible by this team - ``admin`` -- members can push, pull and administer repositories accessible by this team - - :returns: :class:`Team ` + :returns: + the created team + :rtype: + :class:`~github3.orgs.Team` """ data = {'name': name, 'repo_names': repo_names, 'permission': permission} @@ -434,12 +597,20 @@ def edit(self, billing_email=None, company=None, email=None, location=None, name=None): """Edit this organization. - :param str billing_email: (optional) Billing email address (private) - :param str company: (optional) - :param str email: (optional) Public email address - :param str location: (optional) - :param str name: (optional) - :returns: bool + :param str billing_email: + (optional) Billing email address (private) + :param str company: + (optional) + :param str email: + (optional) Public email address + :param str location: + (optional) + :param str name: + (optional) + :returns: + True if successful, False otherwise + :rtype: + bool """ json = None data = {'billing_email': billing_email, 'company': company, @@ -457,8 +628,12 @@ def edit(self, billing_email=None, company=None, email=None, location=None, def is_member(self, username): """Check if the user named ``username`` is a member. - :param str username: name of the user you'd like to check - :returns: bool + :param str username: + name of the user you'd like to check + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('members', username, base_url=self._api) return self._boolean(self._get(url), 204, 404) @@ -466,70 +641,93 @@ def is_member(self, username): def is_public_member(self, username): """Check if the user named ``username`` is a public member. - :param str username: name of the user you'd like to check - :returns: bool + :param str username: + name of the user you'd like to check + :returns: + True if the user is a public member, False otherwise + :rtype: + bool """ url = self._build_url('public_members', username, base_url=self._api) return self._boolean(self._get(url), 204, 404) def all_events(self, username, number=-1, etag=None): - r"""Iterate over all org events visible to the authenticated user. - - :param str username: (required), the username of the currently - authenticated user. - :param int number: (optional), number of events to return. Default: -1 - iterates over all events available. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`Event `\ s + """Iterate over all org events visible to the authenticated user. + + :param str username: + (required), the username of the currently authenticated user. + :param int number: + (optional), number of events to return. Default: -1 iterates over + all events available. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of events + :rtype: + :class:`~github3.events.Event` """ url = self._build_url('users', username, 'events', 'orgs', self.login) return self._iter(int(number), url, Event, etag=etag) def events(self, number=-1, etag=None): - r"""Iterate over public events for this org (deprecated). + """Iterate over public events for this org (deprecated). - :param int number: (optional), number of events to return. Default: -1 - iterates over all events available. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`Event `\ s + .. deprecated:: - Deprecated: Use ``public_events`` instead. - """ + Use :meth:`public_events` instead. + :param int number: + (optional), number of events to return. Default: -1 iterates over + all events available. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of events + :rtype: + :class:`~github3.events.Event` + """ warnings.warn( 'This method is deprecated. Please use ``public_events`` instead.', DeprecationWarning) return self.public_events(number, etag=etag) def public_events(self, number=-1, etag=None): - r"""Iterate over public events for this org. + """Iterate over public events for this org. - :param int number: (optional), number of events to return. Default: -1 - iterates over all events available. - :param str etag: (optional), ETag from a previous request to the same + :param int number: + (optional), number of events to return. Default: -1 iterates over + all events available. + :param str etag: + (optional), ETag from a previous request to the same endpoint - :returns: generator of :class:`Event `\ s + :returns: + generator of public events + :rtype: + :class:`~github3.events.Event` """ url = self._build_url('events', base_url=self._api) return self._iter(int(number), url, Event, etag=etag) def members(self, filter=None, role=None, number=-1, etag=None): - r"""Iterate over members of this organization. - - :param str filter: (optional), filter members returned by this method. - Can be one of: ``"2fa_disabled"``, ``"all",``. Default: ``"all"``. - Filtering by ``"2fa_disabled"`` is only available for organization - owners with private repositories. - :param str role: (optional), filter members returned by their role. - Can be one of: ``"all"``, ``"admin"``, ``"member"``. Default: - ``"all"``. - :param int number: (optional), number of members to return. Default: - -1 will return all available. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`User `\ s + """Iterate over members of this organization. + + :param str filter: + (optional), filter members returned by this method. Can be one of: + ``"2fa_disabled"``, ``"all",``. Default: ``"all"``. Filtering by + ``"2fa_disabled"`` is only available for organization owners with + private repositories. + :param str role: + (optional), filter members returned by their role. Can be one of: + ``"all"``, ``"admin"``, ``"member"``. Default: ``"all"``. + :param int number: + (optional), number of members to return. Default: -1 will return + all available. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of members of this organization + :rtype: + :class:`~github3.users.ShortUser` """ headers = {} params = {} @@ -537,19 +735,25 @@ def members(self, filter=None, role=None, number=-1, etag=None): params['filter'] = filter if role in self.members_roles: params['role'] = role + # TODO(sigmavirus24): Determine if the preview header is still + # necessary headers['Accept'] = 'application/vnd.github.ironman-preview+json' url = self._build_url('members', base_url=self._api) return self._iter(int(number), url, users.ShortUser, params=params, etag=etag, headers=headers) def public_members(self, number=-1, etag=None): - r"""Iterate over public members of this organization. - - :param int number: (optional), number of members to return. Default: - -1 will return all available. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`User `\ s + """Iterate over public members of this organization. + + :param int number: + (optional), number of members to return. Default: -1 will return + all available. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of public members + :rtype: + :class:`~github3.users.ShortUser` """ url = self._build_url('public_members', base_url=self._api) return self._iter(int(number), url, users.ShortUser, etag=etag) @@ -557,9 +761,12 @@ def public_members(self, number=-1, etag=None): def project(self, id, etag=None): """Return the organization project with the given ID. - :param int id: (required), ID number of the project - :returns: :class:`Project ` if successful, - otherwise None + :param int id: + (required), ID number of the project + :returns: + requested project + :rtype: + :class:`~github3.projects.Project` """ url = self._build_url('projects', id, base_url=self._github_url) json = self._json(self._get(url, headers=Project.CUSTOM_HEADERS), 200) @@ -568,11 +775,15 @@ def project(self, id, etag=None): def projects(self, number=-1, etag=None): """Iterate over projects for this organization. - :param int number: (optional), number of members to return. Default: - -1 will return all available. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`Project ` + :param int number: + (optional), number of members to return. Default: -1 will return + all available. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of organization projects + :rtype: + :class:`~github3.projects.Project` """ url = self._build_url('projects', base_url=self._api) return self._iter( @@ -584,16 +795,20 @@ def projects(self, number=-1, etag=None): ) def repositories(self, type='', number=-1, etag=None): - r"""Iterate over repos for this organization. - - :param str type: (optional), accepted values: - ('all', 'public', 'member', 'private', 'forks', 'sources'), API - default: 'all' - :param int number: (optional), number of members to return. Default: - -1 will return all available. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`Repository ` + """Iterate over repos for this organization. + + :param str type: + (optional), accepted values: ('all', 'public', 'member', 'private', + 'forks', 'sources'), API default: 'all' + :param int number: + (optional), number of members to return. Default: -1 will return + all available. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of repositories in this organization + :rtype: + :class:`~github3.repos.Repository` """ url = self._build_url('repos', base_url=self._api) params = {} @@ -603,24 +818,31 @@ def repositories(self, type='', number=-1, etag=None): @requires_auth def teams(self, number=-1, etag=None): - r"""Iterate over teams that are part of this organization. - - :param int number: (optional), number of teams to return. Default: -1 - returns all available teams. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`Team `\ s + """Iterate over teams that are part of this organization. + + :param int number: + (optional), number of teams to return. Default: -1 returns all + available teams. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of this organization's teams + :rtype: + :class:`~github3.orgs.ShortTeam` """ url = self._build_url('teams', base_url=self._api) - return self._iter(int(number), url, Team, etag=etag) + return self._iter(int(number), url, ShortTeam, etag=etag) @requires_auth def publicize_member(self, username): """Make ``username``'s membership in this organization public. - :param str username: the name of the user whose membership you wish to - publicize - :returns: bool + :param str username: + the name of the user whose membership you wish to publicize + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('public_members', username, base_url=self._api) return self._boolean(self._put(url), 204, 404) @@ -629,8 +851,12 @@ def publicize_member(self, username): def remove_member(self, username): """Remove the user named ``username`` from this organization. - :param str username: name of the user to remove from the org - :returns: bool + :param str username: + name of the user to remove from the org + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('members', username, base_url=self._api) return self._boolean(self._delete(url), 204, 404) @@ -639,9 +865,14 @@ def remove_member(self, username): def remove_repository(self, repository, team_id): """Remove ``repository`` from the team with ``team_id``. - :param str repository: (required), form: 'user/repo' - :param int team_id: (required) - :returns: bool + :param str repository: + (required), form: 'user/repo' + :param int team_id: + (required), the unique identifier of the team + :returns: + True if successful, False otherwise + :rtype: + bool """ if int(team_id) > 0: url = self._build_url('teams', str(team_id), 'repos', @@ -653,8 +884,12 @@ def remove_repository(self, repository, team_id): def team(self, team_id): """Return the team specified by ``team_id``. - :param int team_id: (required), unique id for the team - :returns: :class:`Team ` + :param int team_id: + (required), unique id for the team + :returns: + the team identified by the id in this organization + :rtype: + :class:`~github3.orgs.Team` """ json = None if int(team_id) > 0: @@ -673,9 +908,64 @@ class ShortOrganization(_Organization): with different sets of attributes. .. versionadded:: 1.0.0 + + .. attribute:: avatar_url + + The URL of the avatar image for this organization. + + .. attribute:: description + + The user-provided description of this organization. + + .. attribute:: events_url + + The URL to retrieve the events related to this organization. + + .. attribute:: hooks_url + + The URL for the resource to manage organization hooks. + + .. attribute:: id + + The unique identifier for this organization across GitHub. + + .. attribute:: issues_url + + The URL to retrieve the issues across this organization's + repositories. + + .. attribute:: login + + The unique username of the organization. + + .. attribute:: members_url + + The URL to retrieve the members of this organization. + + .. attribute:: public_members_urlt + + A :class:`uritemplate.URITemplate` that can be expanded to either list + the public members of this organization or verify a user is a public + member. + + .. attribute:: repos_url + + The URL to retrieve the repositories in this organization. + + .. attribute:: url + + The URL to retrieve this organization from the GitHub API. + + .. attribute:: type + + .. deprecated:: 1.0.0 + + This will be removed in a future release. + + Previously returned by the API to indicate the type of the account. """ - pass + class_name = 'ShortOrganization' class Organization(_Organization): @@ -690,66 +980,117 @@ class Organization(_Organization): with different sets of attributes. .. versionchanged:: 1.0.0 + + This object includes all attributes on + :class:`~github3.orgs.ShortOrganization` as well as the following: + + .. attribute:: blog + + If set, the URL of this organization's blog. + + .. attribute:: company + + The name of the company that is associated with this organization. + + .. attribute:: created_at + + A :class:`~datetime.datetime` instance representing the time and date + when this organization was created. + + .. attribute:: email + + The email address associated with this organization. + + .. attribute:: followers_count + + The number of users following this organization. Organizations no + longer have followers so this number will always be 0. + + .. attribute:: following_count + + The number of users this organization follows. Organizations no + longer follow users so this number will always be 0. + + .. attribute:: html_url + + The URL used to view this organization in a browser. + + .. attribute:: location + + The location of this organization, e.g., New York, NY. + + .. attribute:: name + + The display name of this organization. + + .. attribute:: public_repos_count + + The number of public repositories owned by thi sorganization. """ + class_name = 'Organization' + def _update_attributes(self, org): super(Organization, self)._update_attributes(org) + self.created_at = self._strptime(org['created_at']) + self.followers_count = org['followers'] + self.following_count = org['following'] + self.html_url = org['html_url'] + self.public_repos_count = org['public_repos'] + # GitHub just doesn't return these 4 attributes sometimes. Compare + # /orgs/github3py to /orgs/testgh3py + self.blog = org.get('blog') + self.company = org.get('company') + self.email = org.get('email') + self.location = org.get('location') + self.name = org.get('name') - # this may be blank if the org hasn't set it - #: URL of the blog - self.blog = self._get_attribute(org, 'blog') - #: Name of the company - self.company = self._get_attribute(org, 'company') +class Membership(models.GitHubCore): + """Object describing a user's membership in teams and organizations. - #: datetime object representing the date the account was created - self.created_at = org['created_at'] + .. attribute:: organization - #: E-mail address of the org - self.email = self._get_attribute(org, 'email') + A :class:`~github3.orgs.ShortOrganization` instance representing the + organization this membership is part of. - # The number of people following this org - #: Number of followers - self.followers_count = org['followers'] + .. attribute:: organization_url - # The number of people this org follows - #: Number of people the org is following - self.following_count = org['following'] + The URL of the organization resource in the API that this membership + is part of. - #: Location of the org - self.location = self._get_attribute(org, 'location') + .. attribute:: state - #: Display name of the org - self.name = self._get_attribute(org, 'name') + The state of this membership, e.g., active or pending. - # The number of public_repos - #: Number of public repos owned by the org - self.public_repos_count = org['public_repos'] + .. attribute:: active - # e.g. https://github.com/self._login - #: URL of the org's profile - self.html_url = org['html_url'] + .. warning:: + This is a computed attribute, it is not returned by the API. -class Membership(models.GitHubCore): + A boolean attribute equivalent to ``self.state.lower() == 'active'``. - """The wrapper for information about Team and Organization memberships.""" + .. attribute:: pending + + .. warning:: + + This is a computed attribute, it is not returned by the API. + + A boolean attribute equivalent to ``self.state.lower() == 'pending'``. + """ def _repr(self): return ''.format(self.organization) def _update_attributes(self, membership): - self._api = self._get_attribute(membership, 'url') + self._api = membership['url'] + self.organization = ShortOrganization(membership['organization'], self) + self.organization_url = membership['organization_url'] + self.role = membership['role'] + self.state = membership['state'] + self.user = users.ShortUser(membership['user'], self) - self.organization = self._class_attribute( - membership, 'organization', ShortOrganization, self - ) - - self.organization_url = self._get_attribute( - membership, 'organization_url' - ) - - self.state = self._get_attribute(membership, 'state') self.active = self.state if self.active: self.active = self.state.lower() == 'active' @@ -761,14 +1102,19 @@ def _update_attributes(self, membership): def edit(self, state): """Edit the user's membership. - :param str state: (required), the state the membership should be in. - Only accepts ``"active"``. - :returns: whether the edit was successful or not - :rtype: bool + :param str state: + (required), the state the membership should be in. Only accepts + ``"active"``. + :returns: + True if successful, False otherwise + :rtype: + bool """ + json = None if state and state.lower() == 'active': data = dumps({'state': state.lower()}) json = self._json(self._patch(self._api, data=data), 200) + if json is not None: self._update_attributes(json) return True return False diff --git a/github3/repos/repo.py b/github3/repos/repo.py index 675a544bb..f8aa622ea 100644 --- a/github3/repos/repo.py +++ b/github3/repos/repo.py @@ -1785,9 +1785,9 @@ def teams(self, number=-1, etag=None): endpoint :returns: generator of :class:`Team `\ s """ - from ..orgs import Team + from .. import orgs url = self._build_url('teams', base_url=self._api) - return self._iter(int(number), url, Team, etag=etag) + return self._iter(int(number), url, orgs.ShortTeam, etag=etag) def tree(self, sha): """Get a tree. diff --git a/github3/users.py b/github3/users.py index 8792cdab2..8f75ce39c 100644 --- a/github3/users.py +++ b/github3/users.py @@ -204,7 +204,14 @@ def __str__(self): return self.login def _repr(self): - return '<{s.class_name} [{s.login}:{s.name}]>'.format(s=self) + full_name = '' + name = getattr(self, 'name', None) + if name is not None: + full_name = ':{}'.format(name) + return '<{s.class_name} [{s.login}{full_name}]>'.format( + s=self, + full_name=full_name, + ) def is_assignee_on(self, username, repository): """Check if this user can be assigned to issues on username/repository. diff --git a/tests/cassettes/Repository_teams.json b/tests/cassettes/Repository_teams.json index 4940dd64a..ecf7fc51b 100644 --- a/tests/cassettes/Repository_teams.json +++ b/tests/cassettes/Repository_teams.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/github3py/fork_this"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+1Yy3LrNgz9lYy2dUI7j5tEM53bfkE3d9WNh5Zoi40kqiRlj6PJv/eApCzJUzsOvc3GI1M4RyAIgAC6ROZJ+vSy+PH68jhLal6JJE3WSr8tbSFNMkvWbVkuw/pG2qJdPTR7NpZQu1roJO2SUm1kDfhBDHCiXzy/3C+efswSvuWW62WrS0gV1jYmZcwvmvmdh7VG6EzVVtT2LlMVa1mA/9z+/gjCjQ4sxJxg4YitkYHIo8Fm2FihwlblkQb+tZMfS65VWaod8McKn/0ETBNgZDz3LOtNDAVgHVO2ELAYtvFBm5fGflEdB+mwMWOXMicSgzPQIv+aSgEEhei0PzqmRaMcW7symZaNlar+omoTKKiU3vBavvMIKkDJWUmpLyrhIICKLTzui1iP6Vij5ZZnezKHFpmQW1g3hu8IDDq7bygg/xpZhmwurVjyvKJoW/PSiI9Z4nSwEHYLM4TXRX4+ieRcHI4SH/3zxtlGWqX3N1bdWGHsDQU+HPNGraEH/Tl88GwcOqYhuiZfJZZPDH8S7ojo+N7EPpqDsB3DbwiQDFHLV0pz7DyadELSsfFf8hMreBXN7cAgKZSKt5wDg0Qa04qL3PX0KTgOw/p4qNtq5RPWJVFwmtajoSM3Rm5qIaItdiDoWJ9LV5rXWRFP2eM75p/cqfJNtIqEBcWqVKtoDlxfzBF0zBTc3xh2eY1WxEj4CaEW66tUJPyB0OorztWpRwQHOlxUFkccrV+PZ12wYMnrTcs38YwHApwuXaMb/v5pUXE6JgYG0FGhpOWqvS5RDRykob/PEb/xJhwoBkJXIJyvOc5selRkuG1Xlfzssj7NFuATl76SkvzwmJb+f15TnFeT8B0b8qlP1oE51pohW/f6jflD5R199D2edb813BaUgfCZhmsRq2yAs27FUefc3d11heCujq2EviIqPRo0XGcFKrZY/boej0qk4tZVxmtSL0elXCqeR9vyQAAyf2SxOnr0+JwbdHXRijnwmK2SJWpDVcfnyIFhzFsrK9cyu6QhOB1GE5Lup5F1Jma8LGfwSiszCT9FQUsnhqJPxFvFo6E+emjfCZQCLhttZS08vmO+bctFU6r9VRllREGBqQUahnzJLYr9+/ni/nb+ert4+jW/Tx/n6cPD35Bpm3wi83wLscWPX/N5CrH5K8k0rSlGNEcizySC9Bh8F0/o+f+v4x56AmrgATKmGEB/DJDUP07GEAGSlXDCoyi57Fvb47vpPAzqFaoSDeqCJK0RD9SUveP5fnLHZ6qtYd35LNlxi2ITd+qw1NcFPUHBzdJHapJa3VIPh5VGq39EZs14bcgMI8GdfJMTINUsh+7MN1nh4wskT6m1CqMYr3/IY5iqhA5SNaIOCvVaPyNIZCZqc9i1779SMI7EkxSC/Y7d9nOx5m1pl75Uhr9V3FhMjeA9QlfYNU0PaIYUulq/f/KsfkuUdPwzml2Er9otzb8th4+4TN6L+TduCUpTmTB9owXdI1PMeO7wPccaRnzfc6x+RHl+4vc9x5pOWVEBTYZgiPLL51i1sDsaPw+patyRhNWHj/8A/lXdqLkWAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Mon, 18 Dec 2017 13:11:38 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4997", "X-RateLimit-Reset": "1513606239", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"e919a0ed725a72f0c5cf868c20d85e41\"", "Last-Modified": "Sat, 16 Dec 2017 00:02:09 GMT", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.071218", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C470:17F6:3478BBD:5E4E2F2:5A37BE8A"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/github3py/fork_this"}, "recorded_at": "2017-12-18T13:11:38"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/github3py/fork_this/teams?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62SS07DMBCGr4Jmnda0EdDmEj0AQpWbmGaEX/LYRajq3RkSJ6JSFgRlZ2v+h/1pXq9gpVFQweHTqkBQADZQbXb7/eOmANLpzDM3zBpFdUAf0VmobNK6AB/wIusvVtXakWo4IQXN1zZGT5UQ0uP6jLFNp3XtjIhKGhJ9AWuNMifuPf7ZI7Ljmg83DgnKO8LoAqo5SZ2N7V4Fg0Tdp0A2Bi3cihHMuwsfx9giPfDzDcb4G1NZls8vI6dRurqT3lGDn8J/Muva5kLrTMtQ66MmsflE7TS1Hmi/V9unHW/WdgLYoFqIVS6axyqblmA1RE2yyiv29g1XBrmmfQMAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Mon, 18 Dec 2017 13:11:38 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4996", "X-RateLimit-Reset": "1513606239", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"fff4c416127761f7aea1e4d2a9dc8994\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.070885", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C470:17F6:3478BD8:5E4E31C:5A37BE8A"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/github3py/fork_this/teams?per_page=100"}, "recorded_at": "2017-12-18T13:11:38"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/github3py/fork_this"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+1YwXKrOBD8lRTXdQJ24vcSqrbe7hfsJae9uGSQjTaAWEnY5VD59+2RhAHX2nHkay4uLNRNazQjzUwXiTxKl8/zHy/PT7OoZhWP0mgj1dvKFEJHs2jTluXKj2+FKdr1Y3OIxzPkvuYqSruolFtRA36cBjjRz38+L+bLH7OI7ZhhatWqErMKYxqdxrEb1MmDg7Waq0zWhtfmIZNV3MYe/mv3+xMIt8qzEHOEgRO2RngihwabjseCClOVJwrcazt/PHMjy1LugT8VfPETMI2HkfHss6i3IRSAdbE0BYfFsIwPWrzQ5otyLKTDwrRZiZxINPZA8fxrkjwIgmi3P7pY8UZatnatMyUaI2T9RWkTKKik2rJavLMAKkDJWUnUF0VYCKB8B4/7ItZhurhRYseyA5lD8YyLHawbwncCBp05NBSQf40sQzYXhq9YXlG0bVip+ccsshoMJtuBGcLrKj+fRHLOj1uJj/55Z20jjFSHOyPvDNfmjgIfjnknN9BBf44fvBiHlmmIrslXieUTw5+FWyLavjd+COYgbBfj1wdIhqhla6kYVh5MOiHp4vFf8hPDWRXMbcEgKaQMt5wFg0Ro3fKr3PX8LlgOHffxULfV2h1Y10TBeVqHhkamtdjWnAdb7EjQxf1Zulaszopwyh7fxe7J7irbBkskLCjWpVwHc+D6ii1BF+uCuRvDrG5RRYyEnxAqvrlJIuGPhEbdsK9WHhEc6XBRGWxxsL4eH3fegiWrty3bhjMeCbC7dI1u2funScX5mBgYQEeJkhLr9raDauAghe4+R/yGm3CgGAhtgnA557iw6FGSYZddVeKzy/o8m4dPXPpGSvLDU1r6/3lOcVkm4bt4OE/dYe2ZQ63pT+te35jfZ97BW9/j4+63hpmCTiB8pmGKh4r18LhbM+Q5Dw8PXcGZzWMrrm6ISocGDVNZgYwtVF/X45GJVMzYzHhD8nJkyqVkebAtjwQgc1sWqtGhx/vcoKoLFmbBY7ZKlMgNZR1+Rg4MY95aGrER2TUFwfkwmpB0v7SoMz5jZTmDVxqRCfgpElraMSR9PNwqDg35qKFdJVByuGywlRV3+C52ZVvOm1IebjpRRhQUmIqjYMhXzCDZXyTzxX3ycj9fviaL9ClJHx//xpy2ySdzft5j2vzHa5KkmJa80Jym1cWI5vk+md8ni9f5U7pcpssFTcHx6H0XT6j5/6/iHmoCKuAB0roYQH8MkNQ9TtoQHpKVcMKTKLnuW7vTu+kyDPIKWfEGeUGU1ogHKsre8Tyf3PGZbGtYN5lFe2aQbOJOHYb6vKAnKJheuUiNUqNaquEw0ij5D8+MHo8NJ8No4l68iQmQcpZjdeaKLP9xiKyEUtK3Ypx+f46hq+IrSNnw2gvqVc+xklJkvNbHZbsCjNY9mg87jNZsDZDzDWtLs3LJMjyuYtqgbwT/4arCuql/QF0kX9c6C5Bv9YuiY8c9o9xFAMv9Sv/bMniJPcv7ae6NHYJsShSmbxSnm2SKGXcevjtZQ5Pvu5PVNykv9/y+O1nTPityoEkbDFF+fSer5mZPDejhsBrXJH708eM/+otgF7sWAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 04 Feb 2018 12:24:02 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4996", "X-RateLimit-Reset": "1517748168", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"2c02c7511cb4cb7b62b3500c790d23bc\"", "Last-Modified": "Sat, 16 Dec 2017 00:02:09 GMT", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.065071", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "CC5E:2F295:13CF2AD:2DC6B37:5A76FB62"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/github3py/fork_this"}, "recorded_at": "2018-02-04T12:24:02"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/github3py/fork_this/teams?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62SS07DMBCGr4Jmnda0EdDmEj0AQpWbmGaEX/LYRajq3RkSJ6JSFgRlZ2v+h/1pXq9gpVFQweHTqkBQADZQbXb7/eOmANLpzDM3zBpFdUAf0VmobNK6AB/wIusvVtXakWo4IQXN1zZGT5UQ0uP6jLFNp3XtjIhKGhJ9AWuNMifuPf7ZI7Ljmg83DgnKO8LoAqo5SZ2N7V4Fg0Tdp0A2Bi3cihHMuwsfx9giPfDzDcb4G1NZls8vI6dRurqT3lGDn8J/Muva5kLrTMtQ66MmsflE7TS1Hmi/V9unHW/WdgLYoFqIVS6axyqblmA1RE2yyiv29g1XBrmmfQMAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 04 Feb 2018 12:24:02 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4995", "X-RateLimit-Reset": "1517748168", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"fff4c416127761f7aea1e4d2a9dc8994\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.058976", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "CC5E:2F295:13CF2B1:2DC6B48:5A76FB62"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/github3py/fork_this/teams?per_page=100"}, "recorded_at": "2018-02-04T12:24:02"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/Team_repositories.json b/tests/cassettes/Team_repositories.json index e0af08728..68f76712c 100644 --- a/tests/cassettes/Team_repositories.json +++ b/tests/cassettes/Team_repositories.json @@ -1 +1 @@ -{"http_interactions": [{"recorded_at": "2017-02-12T14:58:10", "response": {"status": {"code": 200, "message": "OK"}, "body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA52STW+jMBCG/0rlcxI+AkljabXnPVS9VFqpFzSAQ6waj+WPVNko/70Dpi1tT+wNXs8zH+/MlSnspGacddKfQr01F7ZismU829/nWblbsWAVPZ+8N44nCRi5iaGbBvsEbeeSOWqFQVctYJKRoKLiLLRfhkaE2BPiyzJ0JIZRnQtiGRoRYnvR18IugyfmmsSPG6UxoVayqf4n21d0nhTO4MF+X8QoummBwQnboPZk+7jLkEw7/33+taW+WuEaK42XONwHCRp68Xkpm/FUCDSgLzNZIsk1nVWEFDYwpXiAVjrUq7u/fyhE9CCHy/p0IF4C339Y0knnHePpih1RKXwls2d/UlMJejv5Xn0bdHah8+NsrAAv2go81c3TLF+n5TrfP6UFz0u+3T1TL8G0X2LKNYVlxVNW8OKeb9Mhxl/MYMSj7UDLf3E8UtGDqoyV5LKopmGoP3zVVPOn/q5MU+qgFJku3UsVHHRUICoNjQ41WvA4jB/FWipF81eTiVE0CmhT1/c9Ha0Q1Kwz0FCyw35X7vLicCB3f7R4pHTUoyN7qERJUPxKb7c3EEHIiCIEAAA=", "string": ""}, "url": "https://api.github.com/orgs/github3py", "headers": {"Content-Type": "application/json; charset=utf-8", "X-Content-Type-Options": "nosniff", "Server": "GitHub.com", "Last-Modified": "Mon, 14 Dec 2015 14:48:30 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Cache-Control": "private, max-age=60, s-maxage=60", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "89B0:551F:3298A4D:3FD28E7:58A07802", "X-RateLimit-Remaining": "4996", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "Status": "200 OK", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-XSS-Protection": "1; mode=block", "ETag": "W/\"767a0b9b0ca0fae10b634e7ff3302893\"", "Content-Security-Policy": "default-src 'none'", "Date": "Sun, 12 Feb 2017 14:58:10 GMT", "X-RateLimit-Reset": "1486914697", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Served-By": "5aeb3f30c9e3ef6ef7bcbcddfd9a68f7", "Transfer-Encoding": "chunked", "Access-Control-Allow-Origin": "*", "X-Frame-Options": "deny", "X-RateLimit-Limit": "5000"}}, "request": {"body": {"encoding": "utf-8", "string": ""}, "method": "GET", "headers": {"Connection": "keep-alive", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ", "Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4"}, "uri": "https://api.github.com/orgs/github3py"}}, {"recorded_at": "2017-02-12T14:58:10", "response": {"status": {"code": 200, "message": "OK"}, "body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA5VUy27qMBD9lWrWgTyAApaqrruouql0pbtBxnGDVb/kBxVF/PudJOY2RFULO3tmzrx8jo+gqeJA4OVDc+chA1EDKVfrdVFm4GVs0GfOvpp75oQNwmggOkqZgXViT9kBo5g0nteYITqJ110I1pM8p1ZMGxF2cTtlRuWBU+XzvgDGKq62WHdzNSZPiGM6nDCJ49Z4EYwT/JZMHQzhljslvO+GAloroQeNMRN1AFKlKpt0v8/AuIZq8Un7bRxBmgaRBPphZ/ZwXuZyVZULBPw4I2bz+RDadffzXi4x+Xkevuc63AbtIdjwzpj326Adoh3V+/jb+kcN95BrWTACf8MDG7dSsM1VnBplu4QOyUX3NFA3fojO6BOxo+eOGR1w7R3HY172b/64f5jheBeyATQkzaXnnnZUQaCluhXS2SwMmrdIK7ThSRqWuAbPtBbe6OzuzxM6uKKiVRwe0xg9E8jyv6ERPnggRQZvRkrz0Ur96yY0lkDfLig5GnSg3CE5meM08HpDURpQFWU1KRaTavlazEm1ILP7v9hLtPVFzGKCYeX8tZyT+YrMijYmHGz3+QyldDr9Az9H5xSVBAAA", "string": ""}, "url": "https://api.github.com/teams/189901", "headers": {"Content-Type": "application/json; charset=utf-8", "X-Content-Type-Options": "nosniff", "Server": "GitHub.com", "Last-Modified": "Mon, 14 Dec 2015 14:48:30 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Cache-Control": "private, max-age=60, s-maxage=60", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "89B0:551F:3298A5A:3FD2905:58A07802", "X-RateLimit-Remaining": "4995", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "Status": "200 OK", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-XSS-Protection": "1; mode=block", "ETag": "W/\"e0c7bb4fbbd833344aec7889291a9177\"", "Content-Security-Policy": "default-src 'none'", "Date": "Sun, 12 Feb 2017 14:58:10 GMT", "X-RateLimit-Reset": "1486914697", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Served-By": "76d9828c7e4f1d910f7ba069e90ce976", "Transfer-Encoding": "chunked", "Access-Control-Allow-Origin": "*", "X-Frame-Options": "deny", "X-RateLimit-Limit": "5000"}}, "request": {"body": {"encoding": "utf-8", "string": ""}, "method": "GET", "headers": {"Connection": "keep-alive", "Content-Type": "application/json", "Accept": "application/vnd.github.v3.full+json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ", "Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4"}, "uri": "https://api.github.com/teams/189901"}}, {"recorded_at": "2017-02-12T14:58:10", "response": {"status": {"code": 200, "message": "OK"}, "body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "url": "https://api.github.com/teams/189901/repos?per_page=100", "headers": {"Content-Type": "application/json; charset=utf-8", "X-Content-Type-Options": "nosniff", "Server": "GitHub.com", "Access-Control-Allow-Origin": "*", "X-GitHub-Media-Type": "github.v3; param=ironman-preview; format=json", "Cache-Control": "private, max-age=60, s-maxage=60", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "89B0:551F:3298A6C:3FD2914:58A07802", "X-RateLimit-Remaining": "4994", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "Status": "200 OK", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "X-XSS-Protection": "1; mode=block", "ETag": "W/\"2cd16617b5216e6f3e315d2d902ae209\"", "Content-Security-Policy": "default-src 'none'", "Date": "Sun, 12 Feb 2017 14:58:10 GMT", "X-RateLimit-Reset": "1486914697", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Served-By": "88531cdcf1929112ec480e1806d44a33", "Transfer-Encoding": "chunked", "X-Frame-Options": "deny", "X-RateLimit-Limit": "5000"}}, "request": {"body": {"encoding": "utf-8", "string": ""}, "method": "GET", "headers": {"Connection": "keep-alive", "Content-Type": "application/json", "Accept": "application/vnd.github.ironman-preview+json", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ", "Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4"}, "uri": "https://api.github.com/teams/189901/repos?per_page=100"}}], "recorded_with": "betamax/0.8.0"} +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/orgs/github3py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA51UTY+bMBD9KxXnhK8NJEGqutc9VL2sVKkXNIABd43Hsk1WaZT/3jEmDbs50ZsZz5uP9565BAI7LoMi6Ljtx+pJnYNNwJugSPaHNMnyTTBqQde9tcoUUQSKhz41rHGIUHcmWkI1U2jKFZhoQlBTdmLSroN6CGF7xLd10AnhVjVmZOugHkLYgQ0V0+vAM+YS+cOVyqixErwu/6faR+iyKJzAgv4sxBQ08azgaJiuUVrifRJzjGbRv52+7miwhplac2U5OoNQQMLA7lYJJ68QUIE8L8IcKVyRrzxIYA1zie/QcINy8+XnC6WwAbizFh17MCVZCST/M+WWSuNvVlsTFFaPzCdMRuEW9fnheubBW6k4/OO048bViDdBi0LgO6m1+OKSRqS73g7iE1MLiy/dXWsGljUlWJo7jZN0G2fbdP8a74o0K57yX7TLqJoPOfstpSX5axwXu6RIDy7HnpUj8sdiZRdFC4J24yQTK+dlaD58l9TzMX6L3Lcket/K0UBH1TOnjRBQoQYizS9ecSFo7fLGfadDaNsQnAFEOHAZdnh67pwyzhI0lBJA6l9u2reaMYoaBTX1OO7zLE93xyPlPYzdUi+a2xBl1Jz+JPMpvjprtTAK65ecNWV6oKflzSZRuja3N1GDLD33dwRnszuufwGL7Th8xQQAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 28 Jan 2018 20:19:58 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4999", "X-RateLimit-Reset": "1517174398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"21bae4d0d30b1b41330baefd55fa8540\"", "Last-Modified": "Sat, 16 Dec 2017 00:41:28 GMT", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.049648", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "889E:2D372:38375DA:673B8ED:5A6E306E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/orgs/github3py"}, "recorded_at": "2018-01-28T20:19:58"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/teams/189901"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA5VUyY7bMAz9lUJnO5YcZxMwmHMPRS8BCvRiKLJqq5UlQUsGaZB/L721jmcwndwkko8iH/l0RZq1AlH09UUL51GCZIUo2R8OmCTIq1iDz0y+SnjupA3SaER1VCpB1skz4xeI4sp4UUGG6BRcmxCsp1nGrFzVMjTxtOKmzYJgrc+GByC2Fe0J3i0/jMlGxHU83CCJE9Z4GYyT4pFMPQzgVrhWet83hVjVSg1G7gQLoipZAGOO8S4lOM3xkRCaF5QcvneN2moeQzYpyVNSHElBiz1d4y5mapCbqCFVMVZbjvdtgoyrmZa/2cDqFSlTQwUUDaSt7WUaym6fkw0A3uUKsvlsDu27fJ/fe0w28SLOQofHoAMECm6M+fUYtEd0rXof/zfGRcEDZEb2Awy9tU82npTk5Yd2c1HKPXS+pOzMAnPLQfRGj0eFRC8cNzoA771YYkaGoT+fnwro705/CAyjeMd5r/pdAaBlulPkZJYGzCfYK7DBSRk+Lhv6wirpjU4+ffsMDtEy2UkXjg3z5XwxS+vMT8GDRzS4KIaAv7q7vHKPPAyrRPcgsoHTWvouB07QD6OUeen+nH83qaFE8DWhVQumZl/IfLsXMgX94U2a7464oPmGrrdvyRSkDDLdHjGmBah538WEi+1/wbkWb7c/1wt6dh4FAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 28 Jan 2018 20:19:58 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4998", "X-RateLimit-Reset": "1517174398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"fffca5cebfa188a6207f751db31f1248\"", "Last-Modified": "Mon, 14 Dec 2015 14:48:30 GMT", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.041069", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "889E:2D372:38375E3:673B8FD:5A6E306E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/teams/189901"}, "recorded_at": "2018-01-28T20:19:58"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.ironman-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/teams/189901/repos?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 28 Jan 2018 20:19:59 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4997", "X-RateLimit-Reset": "1517174398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"9543b833db92341b2b9ecd6fbef0526f\"", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "admin:org, read:org, repo, user, write:org", "X-GitHub-Media-Type": "github.v3; param=ironman-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.293898", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "889E:2D372:38375EC:673B90D:5A6E306E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/teams/189901/repos?per_page=100"}, "recorded_at": "2018-01-28T20:19:59"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/integration/test_github.py b/tests/integration/test_github.py index 580b6d2a1..975747060 100644 --- a/tests/integration/test_github.py +++ b/tests/integration/test_github.py @@ -315,7 +315,7 @@ def test_user_teams(self): cassette_name = self.cassette_name('iter_user_teams') with self.recorder.use_cassette(cassette_name): for t in self.gh.user_teams(): - assert isinstance(t, github3.orgs.Team) + assert isinstance(t, github3.orgs.ShortTeam) def test_me(self): """Test the ability to retrieve the authenticated user's info.""" diff --git a/tests/integration/test_orgs.py b/tests/integration/test_orgs.py index 52488d02c..7beb613f1 100644 --- a/tests/integration/test_orgs.py +++ b/tests/integration/test_orgs.py @@ -235,7 +235,7 @@ def test_teams(self): o = self.get_organization() for team in o.teams(): - assert isinstance(team, github3.orgs.Team) + assert isinstance(team, github3.orgs.ShortTeam) def test_publicize_member(self): """Test the ability to publicize a member of the organization.""" diff --git a/tests/integration/test_repos_repo.py b/tests/integration/test_repos_repo.py index be13bb48c..8ba3506f7 100644 --- a/tests/integration/test_repos_repo.py +++ b/tests/integration/test_repos_repo.py @@ -986,9 +986,7 @@ def test_notifications(self): assert isinstance(notification, github3.notifications.Thread) def test_original_license(self): - """ - Test that a repository's license can be retrieved at repository load. - """ + """Test that a repository's license is present initially.""" cassette_name = self.cassette_name('original_license') with self.recorder.use_cassette(cassette_name): repository = self.gh.repository('github3py', 'github3.py') @@ -1213,7 +1211,7 @@ def test_teams(self): assert len(teams) > 0 for team in teams: - assert isinstance(team, github3.orgs.Team) + assert isinstance(team, github3.orgs.ShortTeam) def test_tree(self): """Test the ability to retrieve a tree from a repository.""" diff --git a/tests/unit/json/orgs_team_example b/tests/unit/json/orgs_team_example index 8760e411e..3830a7ece 100644 --- a/tests/unit/json/orgs_team_example +++ b/tests/unit/json/orgs_team_example @@ -1,14 +1,29 @@ { - "url": "https://api.github.com/teams/10", - "name": "Owners", - "id": 10, - "permission": "admin", - "members_count": 3, - "repos_count": 10, - "organization": { - "login": "github", - "id": 1, - "url": "https://api.github.com/orgs/github", - "avatar_url": "https://github.com/images/error/octocat_happy.gif" - } + "id": 1, + "url": "https://api.github.com/teams/1", + "name": "Justice League", + "slug": "justice-league", + "description": "A great team.", + "privacy": "closed", + "permission": "admin", + "members_url": "https://api.github.com/teams/1/members{/member}", + "repositories_url": "https://api.github.com/teams/1/repos", + "members_count": 3, + "repos_count": 10, + "created_at": "2017-07-14T16:53:42Z", + "updated_at": "2017-08-17T12:37:15Z", + "organization": { + "login": "github", + "id": 1, + "url": "https://api.github.com/orgs/github", + "repos_url": "https://api.github.com/orgs/github/repos", + "events_url": "https://api.github.com/orgs/github/events", + "hooks_url": "https://api.github.com/orgs/github/hooks", + "issues_url": "https://api.github.com/orgs/github/issues", + "members_url": "https://api.github.com/orgs/github/members{/member}", + "public_members_url": "https://api.github.com/orgs/github/public_members{/member}", + "avatar_url": "https://github.com/images/error/octocat_happy.gif", + "description": "A great organization" + }, + "parent": null } diff --git a/tests/unit/test_events.py b/tests/unit/test_events.py index 0f0de9ab0..1faa100aa 100644 --- a/tests/unit/test_events.py +++ b/tests/unit/test_events.py @@ -117,5 +117,5 @@ def test_team(self): } github3.events._team(team, None) - assert isinstance(team['team'], github3.orgs.Team) + assert isinstance(team['team'], github3.orgs.ShortTeam) assert isinstance(team['repo'], github3.repos.ShortRepository) diff --git a/tests/unit/test_orgs_team.py b/tests/unit/test_orgs_team.py index 4df74993f..d6f6edc3f 100644 --- a/tests/unit/test_orgs_team.py +++ b/tests/unit/test_orgs_team.py @@ -5,7 +5,7 @@ from . import helper -url_for = helper.create_url_helper('https://api.github.com/teams/10') +url_for = helper.create_url_helper('https://api.github.com/teams/1') get_team_example_data = helper.create_example_data_helper('orgs_team_example') @@ -119,10 +119,7 @@ def test_remove_repository_requires_auth(self): class TestTeamIterator(helper.UnitIteratorHelper): described_class = Team - - example_data = { - 'url': url_for() - } + example_data = get_team_example_data() def test_members(self): """Show that one can iterate over all members of a Team.""" From 973435ce7e5e83188a082f5f87e1c9b4163d7779 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 10 Feb 2018 18:41:49 -0600 Subject: [PATCH 10/56] Update our notifications module to conform --- LATEST_VERSION_NOTES.rst | 31 +- github3/github.py | 8 +- github3/notifications.py | 293 ++++++++++++------ github3/repos/repo.py | 23 +- tests/cassettes/GitHub_all_notifications.json | 2 +- tests/cassettes/ThreadSubscription_set.json | 1 + tests/cassettes/Thread_subscription.json | 2 +- tests/integration/test_notifications.py | 17 +- tests/integration/test_repos_repo.py | 3 +- tests/unit/json/subscription_example | 3 +- tests/unit/test_notifications.py | 5 +- tests/unit/test_subscription.py | 11 +- 12 files changed, 272 insertions(+), 127 deletions(-) create mode 100644 tests/cassettes/ThreadSubscription_set.json diff --git a/LATEST_VERSION_NOTES.rst b/LATEST_VERSION_NOTES.rst index 115613222..6063afe32 100644 --- a/LATEST_VERSION_NOTES.rst +++ b/LATEST_VERSION_NOTES.rst @@ -3,11 +3,38 @@ Unreleased ~~~~~~~~~~ +Breaking Changes (since 1.0.0a4) +```````````````````````````````` + +- Remove ``Thread.comment``, ``Thread.thread``, ``Thread.urls`` attributes. + +- Remove ``Thread#is_unread`` method. Use the ``Thread.unread`` attribute + instead. + +- ``Subscription`` has been split into two objects: ``ThreadSubscription`` and + ``RepositorySubscription`` with the same methods. + +- Remove ``is_ignored`` method from our Subscription objects. Use the + ``ignored`` attribute instead. + +- Remove ``is_subscribed`` method from our Subscription objects. Use the + ``subscribed`` attribute instead. + +Features Added (since 1.0.0a4) +`````````````````````````````` + - Add ``Organization#all_events``. -- Deprecate ``Organization#events`` in favor of ``Organization#public_events``. -- Fix test failtures on windows caused by unclosed file handles. + - Add ``Tag.tagger_as_User`` which attempts to return the tagger as as User. + - Add ``Repo.statuses`` and a corresponding ``repo.status.CombinedStatus`` to + +Deprecations and Other Changes (since 1.0.0a4) +`````````````````````````````````````````````` + +- Deprecate ``Organization#events`` in favor of ``Organization#public_events``. + +- Fix test failtures on windows caused by unclosed file handles. get a combined view of commit statuses for a given ref. 1.0.0a4: 2016-02-19 diff --git a/github3/github.py b/github3/github.py index 7d5cd7a11..b703210f5 100644 --- a/github3/github.py +++ b/github3/github.py @@ -24,9 +24,9 @@ from .search import (CodeSearchResult, IssueSearchResult, RepositorySearchResult, UserSearchResult) from .structs import SearchIterator +from . import notifications from . import orgs from . import users -from .notifications import Thread from .licenses import License from uritemplate import URITemplate @@ -870,7 +870,7 @@ def notifications(self, all=False, participating=False, number=-1, :param str etag: (optional), ETag from a previous request to the same endpoint :returns: generator of - :class:`Thread ` + :class:`~github3.notifications.Thread` """ params = None if all is True: @@ -879,7 +879,9 @@ def notifications(self, all=False, participating=False, number=-1, params = {'participating': 'true'} url = self._build_url('notifications') - return self._iter(int(number), url, Thread, params, etag=etag) + return self._iter( + int(number), url, notifications.Thread, params, etag=etag + ) def octocat(self, say=None): """Returns an easter egg of the API. diff --git a/github3/notifications.py b/github3/notifications.py index fcd3623d1..56fa6babf 100644 --- a/github3/notifications.py +++ b/github3/notifications.py @@ -1,8 +1,5 @@ # -*- coding: utf-8 -*- """ -github3.notifications -===================== - This module contains the classes relating to notifications. See also: http://developer.github.com/v3/activity/notifications/ @@ -10,61 +7,70 @@ from __future__ import unicode_literals from json import dumps -from .models import GitHubCore +from . import models -class Thread(GitHubCore): - """The :class:`Thread ` object wraps notification threads. This - contains information about the repository generating the notification, the - subject, and the reason. +class Thread(models.GitHubCore): + """Object representing a notification thread. - Two thread instances can be checked like so:: + .. versionchanged:: 1.0.0 - t1 == t2 - t1 != t2 + The ``comment``, ``thread``, and ``url`` attributes are no longer + present because GitHub stopped returning the comment that caused + the notification. - And is equivalent to:: + The ``is_unread`` method was removed since it just returned the + ``unread`` attribute. - t1.id == t2.id - t1.id != t2.id + This object has the following attributes: - See also: - http://developer.github.com/v3/activity/notifications/#view-a-single-thread - """ - def _update_attributes(self, notif): - self._api = self._get_attribute(notif, 'url') + .. attribute:: id - #: Comment responsible for the notification - self.comment = self._get_attribute(notif, 'comment', {}) + The unique identifier for this notification across all GitHub + notifications. - #: Thread information - self.thread = self._get_attribute(notif, 'thread', {}) + .. attribute:: last_read_at - from . import repos - #: Repository the comment was made on - self.repository = self._class_attribute( - notif, 'repository', repos.ShortRepository, self - ) + A :class:`~datetime.datetime` object representing the date and time + when the authenticated user last read this thread. + + .. attribute:: reason - #: When the thread was last updated - self.updated_at = self._strptime_attribute(notif, 'updated_at') + The reason the authenticated user is receiving this notification. - #: Id of the thread - self.id = self._get_attribute(notif, 'id') + .. attribute:: repository - #: Dictionary of urls for the thread - self.urls = self._get_attribute(notif, 'urls') + A :class:`~github3.repos.ShortRepository` this thread originated on. - #: datetime object representing the last time the user read the thread - self.last_read_at = self._strptime_attribute(notif, 'last_read_at') + .. attribute:: subject - #: The reason you're receiving the notification - self.reason = self._get_attribute(notif, 'reason') + A dictionary with the subject of the notification, for example, which + issue, pull request, or diff this is in relation to. - #: Subject of the Notification, e.g., which issue/pull/diff is this in - #: relation to. This is a dictionary - self.subject = self._get_attribute(notif, 'subject') - self.unread = self._get_attribute(notif, 'unread') + .. attribute:: unread + + A boolean attribute indicating whether this thread has been read or + not. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` representing the date and time when this + thread was last updated. + + See also: + http://developer.github.com/v3/activity/notifications/ + """ + + def _update_attributes(self, thread): + from . import repos + self._api = thread['url'] + self.id = thread['id'] + self.last_read_at = self._strptime(thread['last_read_at']) + self.reason = thread['reason'] + self.repository = repos.ShortRepository(thread['repository'], self) + self.subject = thread['subject'] + self.unread = thread['unread'] + self.updated_at = self._strptime(thread['updated_at']) def _repr(self): return ''.format(self.subject.get('title')) @@ -72,94 +78,207 @@ def _repr(self): def delete_subscription(self): """Delete subscription for this thread. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('subscription', base_url=self._api) return self._boolean(self._delete(url), 204, 404) - def is_unread(self): - """Tells you if the thread is unread or not.""" - return self.unread - def mark(self): """Mark the thread as read. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ return self._boolean(self._patch(self._api), 205, 404) def set_subscription(self, subscribed, ignored): - """Set the user's subscription for this thread - - :param bool subscribed: (required), determines if notifications should - be received from this thread. - :param bool ignored: (required), determines if notifications should be - ignored from this thread. - :returns: :class:`Subscription ` + """Set the user's subscription for this thread. + + :param bool subscribed: + (required), determines if notifications should be received from + this thread. + :param bool ignored: + (required), determines if notifications should be ignored from this + thread. + :returns: + new subscription + :rtype: + :class:`~github3.notifications.ThreadSubscription` """ url = self._build_url('subscription', base_url=self._api) sub = {'subscribed': subscribed, 'ignored': ignored} json = self._json(self._put(url, data=dumps(sub)), 200) - return self._instance_or_null(Subscription, json) + return self._instance_or_null(ThreadSubscription, json) def subscription(self): - """Checks the status of the user's subscription to this thread. + """Check the status of the user's subscription to this thread. - :returns: :class:`Subscription ` + :returns: + the subscription for this thread + :rtype: + :class:`~github3.notifications.ThreadSubscription` """ url = self._build_url('subscription', base_url=self._api) json = self._json(self._get(url), 200) - return self._instance_or_null(Subscription, json) + return self._instance_or_null(ThreadSubscription, json) -class Subscription(GitHubCore): - +class _Subscription(models.GitHubCore): """This object wraps thread and repository subscription information. See also: developer.github.com/v3/activity/notifications/#get-a-thread-subscription - """ + .. versionchanged:: 1.0.0 - def _update_attributes(self, sub): - self._api = self._get_attribute(sub, 'url') + The ``is_ignored`` and ``is_subscribed`` methods were removed. Use the + :attr`ignored` and :attr:`subscribed` attributes instead. + + This object has the following attributes: - #: reason user is subscribed to this thread/repository - self.reason = self._get_attribute(sub, 'reason') + .. attribute:: created_at - #: datetime representation of when the subscription was created - self.created_at = self._strptime_attribute(sub, 'created_at') + A :class:`~datetime.datetime` object representing the date and time + the user was subscribed to the thread. - #: API url of the thread if it exists - self.thread_url = self._get_attribute(sub, 'thread_url') + .. attribute:: ignored - #: API url of the repository if it exists - self.repository_url = self._get_attribute(sub, 'repository_url') + A boolean attribute indicating whether the user ignored this. - self.ignored = self._get_attribute(sub, 'ignored', False) + .. attribute:: reason - self.subscribed = self._get_attribute(sub, 'subscribed', False) + The reason the user is subscribed to the thread. + + .. attribute:: subscribed + + A boolean attribute indicating whether the user is subscribed or not. + + .. attribute:: thread_url + + The URL of the thread resource in the GitHub API. + """ + + class_name = '_Subscription' + + def _update_attributes(self, sub): + self._api = sub['url'] + self.created_at = self._strptime(sub['created_at']) + self.ignored = sub['ignored'] + self.reason = sub['reason'] + self.subscribed = sub['subscribed'] def _repr(self): - return ''.format(self.subscribed) + return '<{0} [{1}]>'.format(self.class_name, self.subscribed) def delete(self): - return self._boolean(self._delete(self._api), 204, 404) + """Delete the user's subscription to this thread. - def is_ignored(self): - return self.ignored - - def is_subscribed(self): - return self.subscribed + :returns: + True if successful, False otherwise + :rtype: + bool + """ + return self._boolean(self._delete(self._api), 204, 404) def set(self, subscribed, ignored): - """Set the user's subscription for this subscription - - :param bool subscribed: (required), determines if notifications should - be received from this thread. - :param bool ignored: (required), determines if notifications should be - ignored from this thread. + """Set the user's subscription for this subscription. + + :param bool subscribed: + (required), determines if notifications should be received from + this thread. + :param bool ignored: + (required), determines if notifications should be ignored from this + thread. """ sub = {'subscribed': subscribed, 'ignored': ignored} json = self._json(self._put(self._api, data=dumps(sub)), 200) self._update_attributes(json) + + +class ThreadSubscription(_Subscription): + """This object provides a representation of a thread subscription. + + See also: + developer.github.com/v3/activity/notifications/#get-a-thread-subscription + + .. versionchanged:: 1.0.0 + + The ``is_ignored`` and ``is_subscribed`` methods were removed. Use the + :attr`ignored` and :attr:`subscribed` attributes instead. + + This object has the following attributes: + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + the user was subscribed to the thread. + + .. attribute:: ignored + + A boolean attribute indicating whether the user ignored this. + + .. attribute:: reason + + The reason the user is subscribed to the thread. + + .. attribute:: subscribed + + A boolean attribute indicating whether the user is subscribed or not. + + .. attribute:: thread_url + + The URL of the thread resource in the GitHub API. + """ + + class_name = 'ThreadSubscription' + + def _update_subscription(self, sub): + super(ThreadSubscription, self)._update_attributes(sub) + self.thread_url = sub['thread_url'] + + +class RepositorySubscription(_Subscription): + """This object provides a representation of a thread subscription. + + See also: + developer.github.com/v3/activity/notifications/#get-a-thread-subscription + + .. versionchanged:: 1.0.0 + + The ``is_ignored`` and ``is_subscribed`` methods were removed. Use the + :attr`ignored` and :attr:`subscribed` attributes instead. + + This object has the following attributes: + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + the user was subscribed to the thread. + + .. attribute:: ignored + + A boolean attribute indicating whether the user ignored this. + + .. attribute:: reason + + The reason the user is subscribed to the thread. + + .. attribute:: repository_url + + The URL of the repository resource in the GitHub API. + + .. attribute:: subscribed + + A boolean attribute indicating whether the user is subscribed or not. + """ + + class_name = 'RepositorySubscription' + + def _update_subscription(self, sub): + super(RepositorySubscription, self)._update_attributes(sub) + self.repository_url = sub.get('repository_url') diff --git a/github3/repos/repo.py b/github3/repos/repo.py index f8aa622ea..282946571 100644 --- a/github3/repos/repo.py +++ b/github3/repos/repo.py @@ -23,7 +23,7 @@ from ..issues.milestone import Milestone from ..licenses import License from ..models import GitHubCore -from ..notifications import Subscription, Thread +from .. import notifications from ..projects import Project from ..pulls import ShortPullRequest, PullRequest from ..utils import stream_response_to_file, timestamp_parameter @@ -1088,11 +1088,12 @@ def ignore(self): This replaces ``Repository#set_subscription``. - :returns: :class:`Subscription ` + :returns: :class:~github3.notifications.RepositorySubscription` """ url = self._build_url('subscription', base_url=self._api) json = self._json(self._put(url, data=dumps({'ignored': True})), 200) - return self._instance_or_null(Subscription, json) + return self._instance_or_null(notifications.RepositorySubscription, + json) @requires_auth def imported_issue(self, imported_issue_id): @@ -1464,7 +1465,7 @@ def notifications(self, all=False, participating=False, since=None, :type since: datetime or string :param str etag: (optional), ETag from a previous request to the same endpoint - :returns: generator of :class:`Thread ` + :returns: generator of :class:`~github3.notifications.Thread` """ url = self._build_url('notifications', base_url=self._api) params = { @@ -1473,7 +1474,9 @@ def notifications(self, all=False, participating=False, since=None, 'since': timestamp_parameter(since) } self._remove_none(params) - return self._iter(int(number), url, Thread, params, etag) + return self._iter( + int(number), url, notifications.Thread, params, etag + ) @requires_auth def pages(self): @@ -1720,12 +1723,13 @@ def subscribe(self): be received from this repository. :param bool ignored: (required), determines if notifications should be ignored from this repository. - :returns: :class:`Subscription ` + :returns: :class:`~github3.notifications.RepositorySubscription` """ url = self._build_url('subscription', base_url=self._api) json = self._json(self._put(url, data=dumps({'subcribed': True})), 200) - return self._instance_or_null(Subscription, json) + return self._instance_or_null(notifications.RepositorySubscription, + json) def subscribers(self, number=-1, etag=None): r"""Iterate over users subscribed to this repository. @@ -1743,11 +1747,12 @@ def subscribers(self, number=-1, etag=None): def subscription(self): """Return subscription for this Repository. - :returns: :class:`Subscription ` + :returns: :class:`~github3.notifications.RepositorySubscription` """ url = self._build_url('subscription', base_url=self._api) json = self._json(self._get(url), 200) - return self._instance_or_null(Subscription, json) + return self._instance_or_null(notifications.RepositorySubscription, + json) def tag(self, sha): """Get an annotated tag. diff --git a/tests/cassettes/GitHub_all_notifications.json b/tests/cassettes/GitHub_all_notifications.json index 01a97f0b6..324a343a1 100644 --- a/tests/cassettes/GitHub_all_notifications.json +++ b/tests/cassettes/GitHub_all_notifications.json @@ -1 +1 @@ -{"http_interactions": [{"response": {"body": {"string": "", "encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+1aTW/bOBD9K4Wu65iWnY8mQFGgp/beXrpYGLRES9xIokBSDlwh/33fULItOfEXncMedElkie9pODMcDp/9dx3IOHgKppPJ/XQS3j4Eo6AqtOC4aXUlRgGujSowxFQLE2m5EDGNKWNuRTzn1oHDh5vJ9Cac/AzDp7vHp3D2G2MybuycqNyoosqyEZH8KyJ8rAMrbSaA/i6JT2e4TK0tzRNjvJTjRNq0WowjlTMtSmVYks6sMJbl65tCvNzQTSaNqYRhoXsbPZ1jfC4KO7+e0K5LMu8HvSJ4JUfACmmVXpP15LXP4e3jLJyEo6DgOY3tmAaLlpjxvH3yjvEYoV4KoYktU4kkH7fD8Ij4p7O729ndZBTwFbdc78/J3TStoyojdKQKi7k7n1WsRX9dfZmBL9EtiQv3KY8T29bjGJzaPNt7fSc+O6uXKsvUC7D7tvYD2qNnWxD5zBHIIrmcAKCaKZsKOArmv9KkpbEXmeIANaN/cxkThYGPNRL9aD7159NCYAyF97V2+eu4mhVUWqmKi8zqAUGkdMIL+YdfTASgAd6l8iVTcgAAxQr5dRGyQdSs1HLFozW5QYtIyBV8ejnbHhRk7Sr9hYiTh6UVcx7ntJiWPDMC69a92WJ5uhtn5nK3yoA3FlT6XOCwen6i0Hwil3yKUN7cTcpc/bx9x9FsOVjOWpYT/j0Ix0LSzxSlZ7H25iBszfC3zf8IC5IvlOYofN6kPZKadT9SQljBc29uBwZJqtSzN4kDg8TtJ2fl5eEotHvSJvGLKl801eicdD9M26BhIzdGJoUQ3pPdEtRsUygXmhdR6k+5wdesuXJR5Ym3iYQFxSJTC28ObFDMEdTMpLzZDuz8GquIkfA9Qi2WV5lI+C2h1VfE1ZlHBFs67EQWIfa2b4NndevBjBdJxRN/xi0Bokv7ZML/nOwWDq+JHQPoqPtBe1pdV6h2HGThpuX1L30dih2h20iO779HJt3pIty081ye2pMPs7XwXkpfSUl5uE/btuXembjB12xXT5ti/TEN/3v8bTt9hc2uHTes/qvkNqUKhNeUXAvf0LdwVi84WpvxeFynOF4RcS70FauyQYOG6yhFa+ZrX73BoxPJuXWt75LMi9EKZ4rH3r7cEoCs2WB9bWzQ3TwqcU7zNsyBu2y5zNAeqsK/Ru4YuryFsnIpo3N6/sOrvUdSfzWyiMSI42COrLQykshTHKMoYmj6hL9XGjTMx7m4afkzyAj+LtGiwdesOZXFoszUmg763oHrUNDp/mjH3nMbsymJGoZ1NZPuCe14Zp7gYl0mGNbXZ+4fEZqNPtOeZ3wEmsnDW4HmrYwzDWnUO5LNt7UgO67SbKYuyT5QsyHCQbPZaTGDZnM0QQfNpqPg9Z0xaDbnS9AoOk52OV70D+/Ig2bj67lBsxk0m9PfEA2azaDZXPqt4qDZOLl00GwGzWbQbM77IcKg2bz5bcb/WbNxOsoHaTb3j3uazT//AeDIOdJVIwAA"}, "url": "https://api.github.com/notifications?per_page=100&all=true", "status": {"message": "OK", "code": 200}, "headers": {"X-RateLimit-Reset": "1486731581", "ETag": "W/\"\"", "Date": "Fri, 10 Feb 2017 11:59:41 GMT", "X-GitHub-Request-Id": "BE9B:5521:1E96CDB:26829B3:589DAB2D", "X-Frame-Options": "deny", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-Served-By": "ef96c2e493b28ffea49b891b085ed2dd", "X-RateLimit-Limit": "5000", "Last-Modified": "Fri, 10 Feb 2017 11:59:13 GMT", "Cache-Control": "private, max-age=60, s-maxage=60", "Status": "200 OK", "Transfer-Encoding": "chunked", "X-Content-Type-Options": "nosniff", "Content-Type": "application/json; charset=utf-8", "X-RateLimit-Remaining": "4999", "X-Poll-Interval": "60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "Server": "GitHub.com", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Content-Encoding": "gzip", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "X-XSS-Protection": "1; mode=block"}}, "recorded_at": "2017-02-10T11:59:41", "request": {"uri": "https://api.github.com/notifications?per_page=100&all=true", "method": "GET", "body": {"encoding": "utf-8", "string": ""}, "headers": {"Accept-Charset": "utf-8", "User-Agent": "github3.py/1.0.0a4", "Content-Type": "application/json", "Connection": "keep-alive", "Accept-Encoding": "gzip, deflate", "Authorization": "Basic ", "Accept": "application/vnd.github.v3.full+json"}}}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/notifications?all=true&per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 04 Feb 2018 11:42:48 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4999", "X-RateLimit-Reset": "1517748168", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"\"", "Last-Modified": "Sun, 04 Feb 2018 11:39:55 GMT", "X-Poll-Interval": "60", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.091444", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "E352:2F29B:2D135D4:5B69F6F:5A76F1B8"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/notifications?all=true&per_page=100"}, "recorded_at": "2018-02-04T11:42:48"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/ThreadSubscription_set.json b/tests/cassettes/ThreadSubscription_set.json new file mode 100644 index 000000000..1933178fa --- /dev/null +++ b/tests/cassettes/ThreadSubscription_set.json @@ -0,0 +1 @@ +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62YQZPqNgzHvwqTa1kCBGZ5mem89tT21HfYXnphTGKIu0mc2g6Uzex37192EhLeFNh1LwwY62dZlmTJTSDSII6eF/PnxWIalKzgQRwchMnqXTSrzsE02Nd5vm3/0OJQsKNQtV6uwtEseSq5CuImyOVBlGAMp4JCyyxX8000nwbsyAxT21rlmJcZU+k4DN2gjmYOW2uuElkaXppZIouwDp301+OPK+AOqoUQN8DAFawSLccJA6bDK40yU+RXOrilrcjV5L3Mc3kC5VrrewuFvSSZ0lJEefgkBZJNKE3GYTxs6Z0MIbT5uFJWqsEJarMVKXE0TkTx9MOKtXJQixzgvQkVr6QF1judKFEZIcuPKziSBk2qAyvFG/scDdIaEFLt46pYKUjzI3zx4+JOrAkrJY4sOZNpFE+4OMLYn0ReyYNozhXF7R9wCjK9MHzL0oLicM9yzd+ngV3eYJIdmCLsHvX+cZynvD9VLPjtbDJZTnKxU0ydJ3upJgIxq/Ysga9OTsgjE7jr5Bdhfq13k5+//XaMoCDmvfaa3Ixca/xRMI7VIdKdM7mJQHgCAJVe+dmLQ/JNiM82nhKEOttJxYy8lzRuKzgCNeHwJ/mS4azwUtwCAMqk9LOkBQAktK75Q659e+OWo8Mufsq62LmU90jU3EY7AnRlGnm+5NzLgj2kCbusjHAok8wP2zGa0H2zp80OXqqSPDC7XO68OLgoQwtpQp0xdw+Zra92RCXGCKr43ltVYvRQozzP26pJkB6JS9Dg6L307Bhh01o0Z+WhZgc/ag/BqdNVfWBvd4uY27FzoQBJFZoSu9o/yV04pKmrHRDvfia9YC5QW5DcLnPuGGBQ2FgTFIW4VxfcJraIkdv/D1jy02s0/b5fxtxXlxhNeMnJLum3dB/rtlm/03O4RtsOeLlExwibHypmMspcWKpiivso3SLCZsdQbM1msybjzJbVBVeeEewIQDGVZKgaffRsOgaqnoIZW63vSc0U1XsuWepl2x4CoDtGH10dYXj+FRpRLwUtYEgsRM61kaVfjr1QhuxSGrEXySMdy+1wG4Gar1qUCZ+yPJ/Ca41IBPwYtTadIgpO7mchR8A28A7gOpWcw6W9rK64YzSh6zRTXuXy7J2FBhgKYsXR3aRbZtCVLOeL5dM8elpEL4sv8XoTr6M/Maeu0tGczdMc0zYvyyhezeP1iuZUtc4GGDfl+WWxjFerePVMU5BWW7/GNzxc4BOPJd89Ggz6FHqKgKDW2UXwp4tY/B+vKq1YksNBryLp8TWP13fdfVGomsmCV6g9Bu8zTi6qzjOYOkVTl8pEz4SkjYk3zFwv1uvlqMpIZF3iPJ7XX6bBiRkUxLjPh4NdddJ3krQ001sX+0FsVE2tKkYqJf/iidHDsUu+GUw8iVdxaXJJkkqofsT1i60Oy80KGVooJdvHqBIJok+0eFhqe2VZ8bLVqVN/Md8g3kTCS42tN9Q+YhP2aQZ7aF/Lfm9/6ir9B21hEDu+bXjpK9py137GVpPBMkFsF+iM1tow5XtW52br+gGsl6KRyWVFfstVAavRWwup0zb/zn7k053dKAW671gcSUSetvrvmsEz7T3TTXP/2CHsmAqc8T+K0003lim5OaGZ7ixktzQs5FqjR9H7v4XAYVt1FAAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 10 Feb 2018 23:46:06 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4996", "X-RateLimit-Reset": "1518309398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"4cf5ca83a11b955bc64d740461d259a9\"", "Last-Modified": "Thu, 08 Feb 2018 23:40:54 GMT", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "repo", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.040744", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C290:9220:13F21A9:257C322:5A7F843E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2018-02-10T23:46:06"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/notifications?all=true&participating=false&per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 10 Feb 2018 23:46:07 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4995", "X-RateLimit-Reset": "1518309398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"\"", "Last-Modified": "Sat, 10 Feb 2018 13:20:55 GMT", "X-Poll-Interval": "60", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "notifications, repo", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.049331", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C290:9220:13F21B8:257C334:5A7F843E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/notifications?all=true&participating=false&per_page=100"}, "recorded_at": "2018-02-10T23:46:07"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/notifications/threads/301660157/subscription"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA6WOSw6DMAxE7+I1kATERzlHV2xQCAEiQYJiZ1X17jUqN+huZjx64zdgntEmP7sFNKXsCvBbiOm2qzmQfXIGYwANpwvkWRVgOSO3TIY4rqUaSlmXcnipXjeNVu3InZwOPu5EF2ohzOWrzdOe58rGU4RIfvXW3DwUtDNvQdFI1XVStb14vrqevV9h+gcJny/pJwZX7AAAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 10 Feb 2018 23:46:07 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4994", "X-RateLimit-Reset": "1518309398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"81ae1569846ee021bbf902b6258c776d\"", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "notifications, repo", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.031733", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C290:9220:13F21C5:257C345:5A7F843F"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/notifications/threads/301660157/subscription"}, "recorded_at": "2018-02-10T23:46:07"}, {"request": {"body": {"encoding": "utf-8", "string": "{\"subscribed\": true, \"ignored\": false}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token ", "Content-Length": "38"}, "method": "PUT", "uri": "https://api.github.com/notifications/threads/301660157/subscription"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA6WOSw6DMAxE7+I1kATERzlHV2xQCAEiQYJiZ1X17jUqN+huZjx64zdgntEmP7sFNKXsCvBbiOm2qzmQfXIGYwANpwvkWRVgOSO3TIY4rqUaSlmXcnipXjeNVu3InZwOPu5EF2ohzOWrzdOe58rGU4RIfvXW3DwUtDNvQdFI1XVStb14vrqevV9h+gcJny/pJwZX7AAAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 10 Feb 2018 23:46:07 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4993", "X-RateLimit-Reset": "1518309398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"81ae1569846ee021bbf902b6258c776d\"", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "notifications, repo", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.036952", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C290:9220:13F21D1:257C35C:5A7F843F"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/notifications/threads/301660157/subscription"}, "recorded_at": "2018-02-10T23:46:07"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/Thread_subscription.json b/tests/cassettes/Thread_subscription.json index 941fa093f..03c271e23 100644 --- a/tests/cassettes/Thread_subscription.json +++ b/tests/cassettes/Thread_subscription.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62YQXPqNhDHvwrjawnGmDwSz3Ree2p76jukl14YYQusxrZcSYYST757/yvZYPOmEKJeGGNrf1qtdle7agORBUm8iuarKJoGFSt5kAQ7YfJmE8/qYzANtk1RrLsPWuxKtheq0YtlOBolDxVXQdIGhdyJCozhUFBomsVy/hTPpwHbM8PUulEFxuXG1DoJQ/dSxzOHbTRXqawMr8wslWXYhE766/7HJXA71UGIG+DFBawWHccJA6bDC41yUxYXOriprcjF4K0sCnkA5VLrWxOFJ0kypaWIavdJCiTbUJqcw3hY0jsZQmhzv1JWqsUOarMWGXE0dkTx7G7FOjmoRQ7w3oaK19ICm41OlaiNkNX9Co6kQZNqxyrxxj5Hg7QGhFS7XxUrBWm+hy/eL+7E2rBWYs/SI5lG8ZSLPYz9SeSFPIjmWFPc/gGnINMLw9csKykOt6zQ/H0a2OkNBtkXU4TdR71/HOcZP+0qJvx2NLmsJoXYKKaOk61UE4GYVVuWwlcnB+SRCdx18oswvzabyc/fftvHUBDjXk+aXI1ca/xRMI7VIdKNPbmKQHgCAJVe+dGLQ/JtiN8unlKEOttIxYy8lTSuKzgCteHwL/mS4az0UtwCAMql9LOkBQAktG74h1z7+sItR4d9/FRNuXEp7yNRcx3tCNCVaeT5inMvC54gbdhnZYRDleZ+2J7Rhu7J7jbbealK8sBsCrnx4uCgDC2kDXXO3Dlk1r7aEZUYI6jiW29ViXGCGuW531ZNgpyQOAQNtt5Lz54Rtp1FC1btGrbzo54g2HU6qnfs7WYRcz12zhQgqUJTYtP4J7kzhzR1tQPi3c+kZ8wZaguS62XODQMMChtrgrIUt+qC68QOMXL7/wFLfnqJpv+3y5jb6hKjDc852SX9ju5j3S7r93oO5+jaAS+X6Blh+0PNTE6ZC1PVTHEfpTtE2G4Yiq3ZbNbmnNmyuuTKM4IdASim0hxVo4+ebc9A1VMyY6v1LamZoXovJMu8bHuCAOi20UdXRxjuf41G1EtBCxgSS1FwbWTll2PPlCG7kkZsRfqRjuV6uI1A7VctqpRPWVFM4bVGpAJ+jFqbdhEFJ/ezkCNgGbgHcJ1KweHSXlZX3DHa0HWaGa8LefTOQgMMBbHi6G6yNTPoShbzaPEwjx+i+CV6Th6fksf4T4xp6mw0ZvWAYYunl/kyefySLO2YutH5AOOGPL9EMb4n0RcagrTa+TWecHGBX1yWfHdpMOhT6CoCglrnZ8GfzmLJf9yqdGJpAQe9iKSPz7m/POtui0LVXJa8Ru0xuJ9xcnF9nMHUGZq6TKZ6JiQtTLxhZPS0ip5HVUYqmwr7sVoup8GBGRTEOM+HL/vq5NRJ0tRMr13sB4lRDbWqeFMr+RdPjR6+O+ebwcCDeBXnJpckqYQ6vXH9YqfDYrVChhZKye4yqkKCOCVaXCx1vbKsedXp1KsfzWPEm0h5pbH0ltpHLMJezWAN3W3Z791fXWf/oC0MEse3DS89oi137WdiNRlMA2vSBL3ROhtmfMuawqxdP4D5MjQyhazJb7kqYTW6ayF1uubf2Y98urcbpUD3jMmRRORhrf9uGDzTnjP9MPfFvsKKqcAZf1GcTrqxTMXNAc10byG7pGEh1xk9Xr7/C4rYwGV1FAAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 30 Dec 2017 01:54:39 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4994", "X-RateLimit-Reset": "1514600339", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"8f7cab6cc8ac8f96f52e6baaaaa66274\"", "Last-Modified": "Thu, 28 Dec 2017 04:56:43 GMT", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "repo", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.048359", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "E18A:FD06:324C233:B866009:5A46F1DF"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2017-12-30T01:54:39"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/notifications?all=true&participating=false&per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 30 Dec 2017 01:54:39 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4993", "X-RateLimit-Reset": "1514600339", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"\"", "Last-Modified": "Fri, 29 Dec 2017 16:06:55 GMT", "X-Poll-Interval": "60", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "notifications, repo", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.058663", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "E18A:FD06:324C23A:B866024:5A46F1DF"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/notifications?all=true&participating=false&per_page=100"}, "recorded_at": "2017-12-30T01:54:39"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/notifications/threads/288450359/subscription"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA6WOMQ6DMBAE/3I1YDiCQvwOqjTIGAOWwEa+cxXl7zmU/CDl7o5G+wLKE9nkJzeD5pRdAX4NMV1xMTtJTs5QDKDBxuNwgaEAKx27eTQsNdbNvWywxH7AVmOnW3wKk9Mu48Z8klbKnL5aPW95qkSjQmS/eGvYx0CKN/HNpLDvb13ddg/1e3Veu7i+wPiPEt4fdiCIFewAAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 30 Dec 2017 01:54:39 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4992", "X-RateLimit-Reset": "1514600339", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"140d9f36aa0c0b4bf2ff2f1c404b4e35\"", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "notifications, repo", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.028210", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "E18A:FD06:324C241:B866041:5A46F1DF"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/notifications/threads/288450359/subscription"}, "recorded_at": "2017-12-30T01:54:39"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62YQZPqNgzHvwqTa1kCBGZ5mem89tT21HfYXnphTGKIu0mc2g6Uzex37192EhLeFNh1LwwY62dZlmTJTSDSII6eF/PnxWIalKzgQRwchMnqXTSrzsE02Nd5vm3/0OJQsKNQtV6uwtEseSq5CuImyOVBlGAMp4JCyyxX8000nwbsyAxT21rlmJcZU+k4DN2gjmYOW2uuElkaXppZIouwDp301+OPK+AOqoUQN8DAFawSLccJA6bDK40yU+RXOrilrcjV5L3Mc3kC5VrrewuFvSSZ0lJEefgkBZJNKE3GYTxs6Z0MIbT5uFJWqsEJarMVKXE0TkTx9MOKtXJQixzgvQkVr6QF1judKFEZIcuPKziSBk2qAyvFG/scDdIaEFLt46pYKUjzI3zx4+JOrAkrJY4sOZNpFE+4OMLYn0ReyYNozhXF7R9wCjK9MHzL0oLicM9yzd+ngV3eYJIdmCLsHvX+cZynvD9VLPjtbDJZTnKxU0ydJ3upJgIxq/Ysga9OTsgjE7jr5Bdhfq13k5+//XaMoCDmvfaa3Ixca/xRMI7VIdKdM7mJQHgCAJVe+dmLQ/JNiM82nhKEOttJxYy8lzRuKzgCNeHwJ/mS4azwUtwCAMqk9LOkBQAktK75Q659e+OWo8Mufsq62LmU90jU3EY7AnRlGnm+5NzLgj2kCbusjHAok8wP2zGa0H2zp80OXqqSPDC7XO68OLgoQwtpQp0xdw+Zra92RCXGCKr43ltVYvRQozzP26pJkB6JS9Dg6L307Bhh01o0Z+WhZgc/ag/BqdNVfWBvd4uY27FzoQBJFZoSu9o/yV04pKmrHRDvfia9YC5QW5DcLnPuGGBQ2FgTFIW4VxfcJraIkdv/D1jy02s0/b5fxtxXlxhNeMnJLum3dB/rtlm/03O4RtsOeLlExwibHypmMspcWKpiivso3SLCZsdQbM1msybjzJbVBVeeEewIQDGVZKgaffRsOgaqnoIZW63vSc0U1XsuWepl2x4CoDtGH10dYXj+FRpRLwUtYEgsRM61kaVfjr1QhuxSGrEXySMdy+1wG4Gar1qUCZ+yPJ/Ca41IBPwYtTadIgpO7mchR8A28A7gOpWcw6W9rK64YzSh6zRTXuXy7J2FBhgKYsXR3aRbZtCVLOeL5dM8elpEL4sv8XoTr6M/Maeu0tGczdMc0zYvyyhezeP1iuZUtc4GGDfl+WWxjFerePVMU5BWW7/GNzxc4BOPJd89Ggz6FHqKgKDW2UXwp4tY/B+vKq1YksNBryLp8TWP13fdfVGomsmCV6g9Bu8zTi6qzjOYOkVTl8pEz4SkjYk3zFwv1uvlqMpIZF3iPJ7XX6bBiRkUxLjPh4NdddJ3krQ001sX+0FsVE2tKkYqJf/iidHDsUu+GUw8iVdxaXJJkkqofsT1i60Oy80KGVooJdvHqBIJok+0eFhqe2VZ8bLVqVN/Md8g3kTCS42tN9Q+YhP2aQZ7aF/Lfm9/6ir9B21hEDu+bXjpK9py137GVpPBMkFsF+iM1tow5XtW52br+gGsl6KRyWVFfstVAavRWwup0zb/zn7k053dKAW671gcSUSetvrvmsEz7T3TTXP/2CHsmAqc8T+K0003lim5OaGZ7ixktzQs5FqjR9H7v4XAYVt1FAAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 10 Feb 2018 23:36:38 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4999", "X-RateLimit-Reset": "1518309398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"4cf5ca83a11b955bc64d740461d259a9\"", "Last-Modified": "Thu, 08 Feb 2018 23:40:54 GMT", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "repo", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.054375", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C274:921F:B80EAC:18081F3:5A7F8206"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2018-02-10T23:36:38"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/notifications?all=true&participating=false&per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 10 Feb 2018 23:36:38 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4998", "X-RateLimit-Reset": "1518309398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"\"", "Last-Modified": "Sat, 10 Feb 2018 13:20:55 GMT", "X-Poll-Interval": "60", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "notifications, repo", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.056638", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C274:921F:B80EB0:18081FB:5A7F8206"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/notifications?all=true&participating=false&per_page=100"}, "recorded_at": "2018-02-10T23:36:38"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "token "}, "method": "GET", "uri": "https://api.github.com/notifications/threads/301660157/subscription"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA6WOSw6DMAxE7+I1kATERzlHV2xQCAEiQYJiZ1X17jUqN+huZjx64zdgntEmP7sFNKXsCvBbiOm2qzmQfXIGYwANpwvkWRVgOSO3TIY4rqUaSlmXcnipXjeNVu3InZwOPu5EF2ohzOWrzdOe58rGU4RIfvXW3DwUtDNvQdFI1XVStb14vrqevV9h+gcJny/pJwZX7AAAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 10 Feb 2018 23:36:39 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4997", "X-RateLimit-Reset": "1518309398", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"81ae1569846ee021bbf902b6258c776d\"", "X-OAuth-Scopes": "admin:gpg_key, admin:org, admin:org_hook, admin:public_key, admin:repo_hook, delete_repo, gist, notifications, repo, user", "X-Accepted-OAuth-Scopes": "notifications, repo", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.025739", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C274:921F:B80EB7:1808205:5A7F8206"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/notifications/threads/301660157/subscription"}, "recorded_at": "2018-02-10T23:36:39"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/integration/test_notifications.py b/tests/integration/test_notifications.py index 1acf2b85f..09e65af47 100644 --- a/tests/integration/test_notifications.py +++ b/tests/integration/test_notifications.py @@ -4,11 +4,10 @@ class TestThread(IntegrationHelper): - - """Integration test for methods on Test class""" + """Integration test for methods on Test class.""" def test_subscription(self): - """Show that a user can retrieve notifications for repository""" + """Show that a user can retrieve notifications for repository.""" self.token_login() cassette_name = self.cassette_name("subscription") with self.recorder.use_cassette(cassette_name): @@ -18,15 +17,14 @@ def test_subscription(self): thread = threads[0] assert isinstance(thread, github3.notifications.Thread) assert isinstance(thread.subscription(), - github3.notifications.Subscription) - + github3.notifications.ThreadSubscription) -class TestSubscription(IntegrationHelper): - """Integration test for methods on Test class""" +class TestThreadSubscription(IntegrationHelper): + """Integration test for methods on Test class.""" def test_set(self): - """Show that user can successful set subscription""" + """Show that user can successful set subscription.""" self.token_login() cassette_name = self.cassette_name("set") with self.recorder.use_cassette(cassette_name): @@ -35,4 +33,5 @@ def test_set(self): assert len(threads) > 0 subscription = threads[0].subscription() assert subscription.set(True, False) is None - assert isinstance(subscription, github3.notifications.Subscription) + assert isinstance(subscription, + github3.notifications.ThreadSubscription) diff --git a/tests/integration/test_repos_repo.py b/tests/integration/test_repos_repo.py index 8ba3506f7..a40d450e3 100644 --- a/tests/integration/test_repos_repo.py +++ b/tests/integration/test_repos_repo.py @@ -1177,7 +1177,8 @@ def test_subscription(self): subscription = repository.subscription() repository.delete_subscription() - assert isinstance(subscription, github3.notifications.Subscription) + assert isinstance(subscription, + github3.notifications.RepositorySubscription) def test_tag(self): """Test the ability to retrieve an annotated tag.""" diff --git a/tests/unit/json/subscription_example b/tests/unit/json/subscription_example index 51785d1e8..3e5ea54d1 100644 --- a/tests/unit/json/subscription_example +++ b/tests/unit/json/subscription_example @@ -4,5 +4,6 @@ "reason": null, "created_at": "2012-10-06T21:34:12Z", "url": "https://api.github.com/notifications/threads/1/subscription", - "thread_url": "https://api.github.com/notifications/threads/1" + "thread_url": "https://api.github.com/notifications/threads/1", + "repository_url": "https://api.github.com/repos/octokit/octoki" } diff --git a/tests/unit/test_notifications.py b/tests/unit/test_notifications.py index bbdbc3eee..3e09a8db5 100644 --- a/tests/unit/test_notifications.py +++ b/tests/unit/test_notifications.py @@ -1,3 +1,4 @@ +"""Unit tests around the Thread class.""" import github3 from .helper import (UnitHelper, create_example_data_helper, create_url_helper) @@ -21,10 +22,6 @@ def test_equality(self): thread._uniq = 1 assert self.instance != thread - def test_is_unread(self): - """Show that is_unread() equals unread property.""" - assert self.instance.is_unread() == self.instance.unread - def test_repr(self): """Show instance string is formatted correctly.""" assert repr(self.instance) == ''.format( diff --git a/tests/unit/test_subscription.py b/tests/unit/test_subscription.py index 3d1acbfc5..fd7fefebf 100644 --- a/tests/unit/test_subscription.py +++ b/tests/unit/test_subscription.py @@ -1,3 +1,4 @@ +"""Unit tests around github3's Subscription classes.""" import github3 from .helper import (UnitHelper, create_url_helper, create_example_data_helper) @@ -11,7 +12,7 @@ class TestSubscription(UnitHelper): """Subscription unit tests.""" - described_class = github3.notifications.Subscription + described_class = github3.notifications._Subscription example_data = get_example_data() def test_repr(self): @@ -26,14 +27,6 @@ def test_delete(self): url_for() ) - def test_is_ignored(self): - """Show that subscription is ignored.""" - self.instance.is_ignored() == self.instance.ignored - - def test_is_subscription(self): - """Show that subscription is subscribed.""" - self.instance.is_subscribed() == self.instance.subscribed - def test_set(self): """Show that a user can set a subscription.""" self.instance._update_attributes = lambda *args: None From f85431845b83d78f63e891658467e0cd14bdf5c9 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sun, 11 Feb 2018 09:49:14 -0600 Subject: [PATCH 11/56] Update licenses module to better represent differences This splits up the different representations of licenses across the GitHub API for acccuracy. --- github3/github.py | 26 ++-- github3/licenses.py | 214 ++++++++++++++++++++++++--- github3/repos/repo.py | 16 +- tests/cassettes/GitHub_license.json | 2 +- tests/cassettes/GitHub_licenses.json | 2 +- tests/cassettes/Tree_ne.json | 2 +- tests/integration/test_github.py | 3 +- tests/integration/test_repos_repo.py | 4 +- tests/unit/json/license_example | 12 +- tests/unit/test_github.py | 5 +- tests/unit/test_licenses.py | 6 +- 11 files changed, 232 insertions(+), 60 deletions(-) diff --git a/github3/github.py b/github3/github.py index b703210f5..56c5a05c0 100644 --- a/github3/github.py +++ b/github3/github.py @@ -24,10 +24,10 @@ from .search import (CodeSearchResult, IssueSearchResult, RepositorySearchResult, UserSearchResult) from .structs import SearchIterator +from . import licenses from . import notifications from . import orgs from . import users -from .licenses import License from uritemplate import URITemplate @@ -738,22 +738,27 @@ def keys(self, number=-1, etag=None): def license(self, name): """Retrieve the license specified by the name. - :param string name: (required), name of license - :returns: :class:`License ` + :param string name: + (required), name of license + :returns: + the specified license + :rtype: + :class:`~github3.licenses.License` """ - url = self._build_url('licenses', name) - json = self._json(self._get(url, headers=License.CUSTOM_HEADERS), 200) - return self._instance_or_null(License, json) + json = self._json(self._get(url), 200) + return self._instance_or_null(licenses.License, json) def licenses(self, number=-1, etag=None): """Iterate over open source licenses. - :returns: generator of :class:`License ` + :returns: + generator of short license objects + :rtype: + :class:`~github3.licenses.ShortLicense` """ url = self._build_url('licenses') - return self._iter(int(number), url, License, etag=etag, - headers=License.CUSTOM_HEADERS) + return self._iter(int(number), url, licenses.ShortLicense, etag=etag) def login(self, username=None, password=None, token=None, two_factor_callback=None): @@ -1205,8 +1210,7 @@ def repository(self, owner, repository): json = None if owner and repository: url = self._build_url('repos', owner, repository) - json = self._json(self._get(url, headers=License.CUSTOM_HEADERS), - 200) + json = self._json(self._get(url), 200) return self._instance_or_null(repo.Repository, json) def repository_with_id(self, number): diff --git a/github3/licenses.py b/github3/licenses.py index bcfbb3250..49b80acdf 100644 --- a/github3/licenses.py +++ b/github3/licenses.py @@ -1,36 +1,208 @@ # -*- coding: utf-8 -*- """ -github3.licenses -================ - -This module contains the classes relating to licenses +This module contains the classes relating to licenses. See also: https://developer.github.com/v3/licenses/ """ from __future__ import unicode_literals -from .models import GitHubCore +import base64 + +from . import models + + +class _License(models.GitHubCore): + """Base license object.""" + + class_name = '_License' + + def _update_attributes(self, license): + self._api = license['url'] + self.key = license['key'] + self.name = license['name'] + self.spdx_id = license['spdx_id'] + + def _repr(self): + return '<{0} [{1}]>'.format(self.class_name, self.name) + + +class ShortLicense(_License): + """This object represents a license returned in a collection. + + GitHub's API returns different representations of objects in different + contexts. This object reprsents a license that would be returned in a + collection, e.g., retrieving all licenses from ``/licenses``. + + This object has the following attributes: + + .. attribute:: key + + The short, API name, for this license. + + .. attribute:: name + + The long form, legal name for this license. + + .. attribute:: spdx_id + + The Software Package Data Exchange (a.k.a, SPDX) identifier for this + license. + """ + + class_name = 'ShortLicense' + + +class License(_License): + """This object represents a license as returned by the GitHub API. + + See https://developer.github.com/v3/licenses/ for more information. + + This object has all of the attributes of :class:`ShortLicense` as well as + the following attributes: + + .. attribute:: body + + The full text of this license. + + .. attribute:: conditions + + A list of the conditions of this license. + + .. attribute:: description + + The short description of this license. + + .. attribute:: featured + + A boolean attribute describing whether this license is featured on + GitHub or not. + + .. attribute:: html_url + + The URL to view this license on GitHub. + + .. attribute:: implementation + + The short description of how a user applies this license to their + original work. + .. attribute:: limitations -class License(GitHubCore): + A list of limitations of this license. - CUSTOM_HEADERS = { - 'Accept': 'application/vnd.github.drax-preview+json' - } + .. attribute:: permissions + + A list of the permissions granted by this license. + """ def _update_attributes(self, license): - self._api = self._get_attribute(license, 'url') - self.name = self._get_attribute(license, 'name') - self.permitted = self._get_attribute(license, 'permitted') - self.category = self._get_attribute(license, 'category') - self.forbidden = self._get_attribute(license, 'forbidden') - self.featured = self._get_attribute(license, 'featured') - self.html_url = self._get_attribute(license, 'html_url') - self.body = self._get_attribute(license, 'body') - self.key = self._get_attribute(license, 'key') - self.description = self._get_attribute(license, 'description') - self.implementation = self._get_attribute(license, 'implementation') - self.required = self._get_attribute(license, 'required') + super(License, self)._update_attributes(license) + self.body = license['body'] + self.conditions = license['conditions'] + self.description = license['description'] + self.featured = license['featured'] + self.html_url = license['html_url'] + self.implementation = license['implementation'] + self.limitations = license['limitations'] + self.permissions = license['permissions'] def _repr(self): return ''.format(self.name) + + +class RepositoryLicense(models.GitHubCore): + """The representation of the repository's retrieved license. + + This object will be returned from + :meth:`~github3.repos.repo.Repository.license` and behaves like + :class:`~github3.repos.contents.Contents` with a few differences. + This also includes a :attr:`license` attribute to access the licenses API. + + This object has the following attributes: + + .. attribute:: name + + The name of the file this license is stored in on the repository. + + .. attribute:: path + + The path to the file of this license in the repository. + + .. attribute:: sha + + The current SHA of this license file in the repository. + + .. attribute:: size + + The size in bytes of this file. + + .. attribute:: html_url + + The URL used to view this file in a browser. + + .. attribute:: git_url + + The URL to retrieve this license file via the git protocol. + + .. attribute:: download_url + + The URL used to download this license file from the repository. + + .. attribute:: type + + Analogous to :attr:`github3.repos.contents.Contents.type`, this should + indicate whether this is a file, directory, or some other type. + + .. attribute:: content + + The content as returned by the API. This may be base64 encoded. See + :meth:`decode_content` to retrieve the content in plain-text. + + .. attribute:: encoding + + The encoding of the content. For example, ``base64``. + + .. attribute:: links + + The dictionary of URLs returned in the ``_links`` key by the API. + + .. attribute:: license + + A :class:`github3.licenses.ShortLicense` instance representing the + metadata GitHub knows about the license. + """ + + def _update_attributes(self, license): + self._api = license['url'] + self.name = license['name'] + self.path = license['path'] + self.sha = license['sha'] + self.size = license['size'] + self.html_url = license['html_url'] + self.git_url = license['git_url'] + self.download_url = license['download_url'] + self.type = license['type'] + self.content = license['content'] + self.encoding = license['encoding'] + self.links = license['_links'] + self.license = ShortLicense(license['license'], self) + + def _repr(self): + return ''.format(self.name) + + def decode_content(self): + """Decode the :attr:`content` attribute. + + If ``content`` is base64 encoded, decode this and return it. + Otherwise, return ``content``. + + :returns: + plain-text content of this license + :rtype: + text (unicode on Python 2, str on Python 3) + """ + if self.encoding == 'base64': + return base64.b64decode( + self.content.encode('utf-8') + ).decode('utf-8') + return self.content diff --git a/github3/repos/repo.py b/github3/repos/repo.py index 282946571..678e285e2 100644 --- a/github3/repos/repo.py +++ b/github3/repos/repo.py @@ -21,7 +21,7 @@ from ..issues.event import IssueEvent from ..issues.label import Label from ..issues.milestone import Milestone -from ..licenses import License +from .. import licenses from ..models import GitHubCore from .. import notifications from ..projects import Project @@ -1356,11 +1356,11 @@ def latest_release(self): def license(self): """Get the contents of a license for the repo. - :returns: :class:`License ` + :returns: :class:`~github3.licenses.RepsoitoryLicense` """ url = self._build_url('license', base_url=self._api) - json = self._json(self._get(url, headers=License.CUSTOM_HEADERS), 200) - return self._instance_or_null(License, json) + json = self._json(self._get(url), 200) + return self._instance_or_null(licenses.RepositoryLicense, json) @requires_auth def mark_notifications(self, last_read=''): @@ -2175,8 +2175,8 @@ class Repository(_Repository): .. attribute:: original_license - This is the :class:`~github3.license.License` returned as part of the - repository. To retrieve the most recent license, see the + This is the :class:`~github3.license.ShortLicense` returned as part of + the repository. To retrieve the most recent license, see the :meth:`~github3.repos.repo.Repository.license` method. .. attribute:: mirror_url @@ -2264,7 +2264,9 @@ def _update_attributes(self, repo): self.language = repo['language'] self.original_license = repo['license'] if self.original_license is not None: - self.original_license = License(self.original_license, self) + self.original_license = licenses.ShortLicense( + self.original_license, self + ) self.mirror_url = repo['mirror_url'] self.network_count = repo['network_count'] self.open_issues_count = repo['open_issues_count'] diff --git a/tests/cassettes/GitHub_license.json b/tests/cassettes/GitHub_license.json index 74f7b31ee..be63ef5dd 100644 --- a/tests/cassettes/GitHub_license.json +++ b/tests/cassettes/GitHub_license.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/licenses/mit"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA2VUXY+jRhD8Ky2ediXOft831sbrUTBYGN9mtZwiDGMzCWbIzHB7VpT/nurB9l4SyZKZpj+qqov5K/hDXoKn4KxcEAZ9dZY4bERBiaplbyWCo+kQa50b7NN8Xg1qdlKuHQ+zWp/n3ZRm51ODo6zcaGQTPDkzyhBV5+63zwaor1utrayudf/rMcfARtraqMEp3WNwRIM0Z2Wt+i7pWkaurRwpS7bVxlHVN+Q0gpIGrXo3I+Gok86iVA+dpEYj5+Ja1Z/oA+DpokdDtW7kdByMxhCqnDPqMPJg35NT9ejoozKm6t1lBnB15eRJG2jWj10XBuqMAWfZu+qKd2GggaSKnPzh6Kgw/sFdBlVXXXchVrihRCzidBeTNrfHmfvhHkn1noTR2pE+TigtoNZyAsugaj1cfJbvjyx+vukC8pMOPHdGuRy6CsXvF1mZbxNXTq9HYwCZOOyZvh9BhrH9lMRHegBEfrCPt1E836hT66jVXSONZVWM/HNUfu/vgerrbmzkl3ti8C0M/A6dmzJgnLM0taq6L6O32Fk36giFWELLDlD2vgkc7Xi4EsRhMOo7BPaVaHzU5qCaRsIq70Gvv3SqOqhOuQu/POiGzV2A8k+epgccHsu+7Bd3Lg/1402lTy04ZXs1HywBv7XSyMOFTmwH2YR0NFKyMHVbmZMM2YUwGjvWokAfXKV6Nl3l11b2fl3sW310cBVsAvErazXEQEMYtR7vZvLmsXAP4JfB7lpSBo9+ToOPqERzv//by7tljWQFaxY0hK14Izfzs6M7hW14uSfD8T5tyeaBrKEHG5LfCv9Lz23gLdg2pPt2EPxcTchc5rCLlR2AoYUC+Ks/b/h8EqOf/HAVynLko9Xnf3NRQHQcTY+hkIYpawjnZ/4ua3f75I+66/QHs6t13yjvoSdeHa+9OmhcG5+e7bXDjTWh4EXc7hYIcX1lW3yodJBX1TAZGiP0SQkUx4N1sAAcjBvH+JH/pTrzENYx7bJV8RrlMYkdbfPsq1jGS+wz2iFQBiG9imKd7QtCTh6lxRtlK4rSN/pFpMuQ4l+3ebzbUZaXvdhsExEjKNJFsl+K9IWeUZhmuK4FPI2+RUY889pLxChc0SbOF2u0jp5FIoq3sOxXoki56yrLKaJtlBdisU+inLb7fJvhZorSJfqmIl3lGBNv4rTArZoiRvFXHGi3jpKEZ5V9tAeBnCHSItu+5eJlXdA6S5Yxgs8xsEXPSTzNAq9FEolNSMtoE70wvpwytAE9zpsA0us65hhPjPBbFCJLmckiS4scxxBE8+Je+yp2cUhRLnasySrPNuDImqIE/dEFhWk8tWG9vUj3xSCFz3vwvqGhZRwlaIYlpRPLWzb2Gvz9D1l3uoM3BwAA", "encoding": "utf-8"}, "headers": {"vary": "Accept", "x-github-media-type": "github.drax-preview; format=json", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "W/\"7752486ec4302376f72db7e4afb52535\"", "cache-control": "public, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "57", "x-served-by": "bae57931a6fe678a3dffe9be8e7819c8", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "D54E579D:7FBF:192B58FD:5645E41F", "access-control-allow-credentials": "true", "date": "Fri, 13 Nov 2015 13:22:39 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "60", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1447424220"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/licenses/mit"}, "recorded_at": "2015-11-13T13:22:38"}], "recorded_with": "betamax/0.5.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/licenses/mit"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA2VVXW+jSBD8Ky0/JRJrv+eN2DhGh8HCeHNRvFphGIe5xTPszLCJtbr/ftWDsbM6KVJg6I+q6urx78kPcZ48TE7STYKJKk8CL+u4oERWQlmBQ9vVH99lPZzjvTctnhvnOvswm5WdnL5J1/SHaaVPs3ZIs7OhYONO7fdbAuKrRmsrykvc/3JmaFALWxnZOakVGoVkG20claomK09dK6gT5iStlb8EXerQOyBQpVUtOc2SVu2ZjPjZSyPVG3VGWGF+lfyR9BGR3dnIt2YoOxZR2gG+nY7ka3rX5ocN6KRreZSVT8crQ2lL8ybMEECn8kwHQbW0zshD70RNvarxGWlHYYRy5IDZ+kyGqntHVvemEoBSiylYe2onhPouID43onSCSqR+ODpKEL9z5w4wWnDjUdWUxPMo3Uakzfg4dR/unqQi1wgyWjume0arz/08DtbAR/n6iOLnUQqpnPYH3HdKuejaEmBfz6I03wa1+WvVG8+Oj33R12PftoztUxC/0h0g8oO9H1vdZtDoFmJZVmEcLXSePLxOYKmTMJUs2y+9N+Mfk2CvjJKzZkg3EkMWPvhbgPTREFxMqqrta/Hl2phDWgmnDoPlmFaWB9lKd0ax99KYUuERYQdd85p82oy92qv51UZ31f0ozk0CDtlcvArfSUsNzHA40xvXFXVARyOE92PDdgoIopfqzAa3bNSDK6Vi/5Z+Wnvlp4Q6Vh8d4MEd0Ly0VkMidl2tq/7qIT87C9NgUPvJ9pKyn9z7PjWWcI/ifsrjx6s5sS+wcsVWDOAmFo5xjN69qTb4jFfJ7tkzUD7wYC9bw/+F59b1h1baJvi0JgFZPvQ3jV+rGVxiRQtgKCEB/mLLEd+we2jjfeIuQlnm897o059cJBAde6PQFNIwZQ3hfM9/RIWVvDhct61+Z3Y3uzzw6AoIUx40bpmbVYcrwsvuB3HzK10+2Qb7ybfBxW41LyOObpRAsT9YBwvA19ThchuurGEDR6pTD2EV0TZbFs9hHlG8pU2efY0X0QLzDLc42E8Ceo6LVbYrCDF5mBYvlC0pTF/orzhdBBT9vcmj7ZayfK/i9SaJIxzG6TzZLeL0iR6RmGa47mNYG3WLjLjnpVYcIXFJ6yifr1A6fIyTuHgJ9moZFylXXWY5hbQJ8yKe75Iwp80u32S4kMJ0gbppnC5ztInWUVpM0RZnFH3FC21XYZJwr70KdyCQM0SaZ5uXPH5aFbTKkkWEw8cI2MLHJBp6gdc8CeN1QItwHT4xvpwylAE9jhsA0vMq4jPuGOJvXsRZykzmWVrkeA1ANC+uuc/xNgoozOMta7LMszU4sqZIQX1UQWIaDWVYby/SdTAI4fcdeI9oaBGFCYphSOnAcozGXHG3HHG390bgV9WZXvz7H/b4WQaHBwAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 11 Feb 2018 12:59:42 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "54", "X-RateLimit-Reset": "1518355556", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"36af1ff31a1b41fb5efd9e7176e9495c\"", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.011041", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "D06A:9220:18A771A:2DC48B3:5A803E3E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/licenses/mit"}, "recorded_at": "2018-02-11T12:59:42"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/GitHub_licenses.json b/tests/cassettes/GitHub_licenses.json index 0dde29bd6..0224eafdf 100644 --- a/tests/cassettes/GitHub_licenses.json +++ b/tests/cassettes/GitHub_licenses.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "User-Agent": "github3.py/1.0.0a2", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/licenses?per_page=100"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA61Vy27CMBD8FctnkvC4caO0QkiAqgKXlh6M2RCrzkO2k6qt+u91CNROhKsE9RZNVjOznvX65Qu/wQceY37MuDfy+7iHExKDRmarLVqAlCDQDBIQhKPHfM8ZRQtGIZGAiqo+F1yXR0plchwEJGP+kako3/s0jQNdX9bKwBIIgahcwAGPQ8IlfPcuJvLkXG5cbCJAWwtuJ2YTOdWudvwfrRpip3bMlOlxOd9czlSD7TqsCAy/Erl1kCQjNAJvaOc5OWG/4VX/2onV6FyaZdc1wXKAXMfZRd0Qu6SJUEwqRhsNn9HbWq5TOoNkkpog5+tp5yArAif/Xh68oUc5ySUYobv1PbqgaIfXLM44CxkcdrizgYbCn05GV51cUO1kBe/aQir05xMUTN7syFJyOgI9cQN7xB8oZ5leTI09VdW0G3XD6ZQ9bbKhP+i0Kqv6dh4sAacJcnV7TcIQROq8dV32tSXgNKGnrn7llukn45w0A+hy2w2nU5bSfj33qdAvCisATdM4ThOJnstTKHTu+u3QuJCEt96shr1p4PUHL8cx5S4HAAA=", "encoding": "utf-8"}, "headers": {"vary": "Accept", "x-github-media-type": "github.drax-preview; format=json", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "W/\"6ac24bbbf9b265b86e5c9e11718d16f0\"", "cache-control": "public, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "56", "x-served-by": "8a5c38021a5cd7cef7b8f49a296fee40", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "D54E579D:7FC0:1DB80D74:5645DB0C", "access-control-allow-credentials": "true", "date": "Fri, 13 Nov 2015 12:43:56 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "60", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1447420294"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/licenses?per_page=100"}, "recorded_at": "2015-11-13T12:43:55"}], "recorded_with": "betamax/0.5.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/licenses?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA5VUy27CMBD8lchnkrRw40ZbhCoFhAqcSlWZZAGrTmLFCX2Jf6+Jazaxota5rnd3RuOZff4mb/BJxmQnE3/ox5xWEsiAZDQFVb1bPXhD/76ueluyYqngbM8g2RIvYjFkdbMUyccrS3S/2qL71UNVcFU8lqWQ4zCkggUHVh6rXRDnacj1vAxb0OeBYXQQ3B8FN0hmtth4M8igoNxbVjs1bzh4J92IRGbL6HfYjYMBQ3jeiR+BlFA404j68riiWkSGwW1biH+I6H7Uoyaii26C1EQuA0iEdioy2e+hyJ0VmfRV5IqKRJQJFbWGM+b5F+Oc2q7QPSjCvNbgMuemgcFB5ItVR50pGWFKFvCu4pEXKjBPcGLyz7SYOWdSLQqNzxE0PkJblkldu4bElkM/91KEIgpCV9lvlNGhawW7aZTxD5pVt1/A9Q0HsBLB5o/rzmOk6s6qpmohrgfbYNOYM6FOoHV2bEWnPQ1mcBBZp87x6NnwOuPu/jZg55cf9hIpUwcGAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 11 Feb 2018 12:59:43 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "53", "X-RateLimit-Reset": "1518355556", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"cb4c94f15f133114ab60e613c8b222dd\"", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.014631", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "B79C:9221:122DFC9:3045E15:5A803E3E"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/licenses?per_page=100"}, "recorded_at": "2018-02-11T12:59:43"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/Tree_ne.json b/tests/cassettes/Tree_ne.json index e47f817eb..a9811fe40 100644 --- a/tests/cassettes/Tree_ne.json +++ b/tests/cassettes/Tree_ne.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62YTZPiNhCG/wrlaxgEmAmzrtra5JTklD1sLrlQwhZYO7blkmQI45r/nlcfNjZb4WOUCwVG/ehVS93uVhvxLEri9WK+XiymUUVLFiXRnuu82caz+hRNo11TFBv/h+L7kh64bNRyRUajxLFiMkraqBB7XoExHAqKmWa5mr/E82lED1RTuWlkgXG51rVKCHEPVTxz2EYxmYpKs0rPUlGShjjrL4fPK+D20kMMN8KDC1jNPccZA6bIhaJcl8WFBje1NbkYvBNFIY6gXKq+NRHpLY0rLYVX+w9SYNkSoXMG52FJ78YRXOnHRVmrFjuo9IZnhqOwI5JlDwvzdpBlDsB7SySrhQU2W5VKXmsuqscFjqxBE3JPK/5GP0aDtQLESHtcirWCNTvgLD5u7sxaUkt+oOnJuEaylPEDnP1B5IU9iPpUm7j9C4fCuJ5rtqFZaeJwRwvF3qeRnV5jkH0wRdjde/rHcZ6xflcx4deTzkU1KfhWUnma7ISccMSs3NEUZ3VyRB6Z4LhOfuP692Y7+fXrH4cYAjHutVdyNXKt80fBOJZjSDf25CoC4QkAJL2yUxDH2LcEnz6eUoQ63QpJtbiVNK4LHIFaMvxpzpJmtAwSbgEA5UKEedICAOJKNeyuo3194ZajSBc/VVNuXcq7J2quox0BWqlCnq8YC/JgD2lJl5URDlWah2E7RkvcN7vbdB8k1dgDsy3ENoiDFyWxkJaonLr3kN6EqjNUwxhBJdsFSzWMHqpl4H5bmQbSI/ES1Nj6IJ0dg7TeowWt9g3dh1F7CHbdvKr39O1mEXM9ds4UIE2FJvm2CU9yZ45R6moHxHuYS8+YM9QWJNfLnBsOGBQ21gVlyW/VBdeJHjE69v8D1pzTS7T5fbuMuS3XMFpyzsku6Xt6iHd91u90Dufw7UDQkegYpP2ppjo3mQtT1VSyENEeQdotRbE1m83anFFbVpdMBkawIwBFZZqjagzR2XYMVD0l1bZa3xmZGar3QtAsyLc9BEC3jSFaHWG4/zUa0SCBFjAklrxgSosqLMeeKUN2JTTf8fSejuV6uI1A7RfFq5RNaVFMcWo1TznOMWpts4soOFmYhxwBy8A9gOtUCoYjHeR1yRyjJa7TzFhdiFNwFhpgTBBLhu4m21CNrmQ5Xyyf5vHTIv62+JQ8vyTP8d8Y09TZaMz6CcOWL9/mq+T552Rlx9SNygeYbsgyTlbPyfyTGYK06s81vuHiAp+4LPnh0mDQp5irCBgqlZ8NfzmbJf9xq+LN0gIH9CKS7p/zcPmuu20KqbkoWY3aY3A/4+zi+jSDqzM0dZlI1YwLszD+hpGLl/UiHlUZqWgq7Md6tZpGR6pREON9PnzYVSd9J2mmpmrjYj9KtGxMq4ontRTfWarV8Nk53wwGHvkrPze5xtKUUP0T1y96Dcv1GhmaSyn8ZVSFBNEnWlws+V5Z1Kzymjr5i/kz4o2nrFJYemvaRyzCXs1gDf627E//U9XZP2gLo8TxbcNrvqItd+1nYpUMpoE3zQSd07wPM7ajTaE3rh/AfBkamULUZkamj+hkO3mWN6yi/Irj1fu/AEmXgfITAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Fri, 29 Dec 2017 00:38:15 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "59", "X-RateLimit-Reset": "1514511495", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"24874e5968a8c097a2217e95cbeb7fcf\"", "Last-Modified": "Thu, 28 Dec 2017 04:56:43 GMT", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.039630", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C628:8329:716D76A:12DE45A9:5A458E77"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2017-12-29T00:38:15"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62Ya2tbRxCG/4s+J9Ls7OzN31xHaQyNBLZSKKWYvczaIpal6hyFpMH/vaPEqU5oKWtyhD5oEct7Hs3tHX2edHdxcjYJ1qEtCZxBH71LLquK1nIhzEWjAgfkIOPkxeSwv5cLd32/685ms7hbT2/X/d0hTfN2M9vzbtvNuvXtJn5Y7w8d0uzrt3q6+3T8OOv3zN3sGXrHC5Oz3z9PdrG/E+Wj3Pr2YbtneZjNtsiXEwVgieTcf9odz+l+m+T0lY1VirkmFBRXmFVBilwNloq6uKirI0KO+nhh/ZdcVwZ+GPP4BN2sWfrxxYmv38tv100/be4bAZNhn5VzOZK3ySjvrS5BEUYyBoQvKFdDiCdApcxIhM3aA8Lzd6s3y6vr6b7rGwlzsBiTC95p0Ey1FEBrGIKGGG3wygaTLBwz4imEnvxIhM3aA8KL5av5zfL1zcVy8erdxWq6KY2goJKXTK5KxxywhlwQORRiHb2KTqtCznv6ktxfc1XgRwJt1v4OdLG6uvzp3epy8fMz4mkCJAQNwdYsRQk1MOQQ0ARTtQqxGsBoK/yDqQHDSJjN2gPMN5fXq+XVb88gTEIkpRdYsQtRSlO7VCRh0VYmdBCDNtmQHTQdVG4kxGbxAeIv56v59erm1/nV9eVycbNYyvEZvE4XX6OmZCWALlcCVypVBAu1Yk6xRkAdTk0WwZEdibdZfMh7eTFfXM8b61LGBicw3lnFrF0xJF21aKFlpkRGS2uyPqhTODXhSHTN2gO6t+eLy9cSz+n6oZVQk+MYVWQjjZWBIPrsoo3VV+0rK23kbcOpJInGAmyVHgLG91zX960eAFIwxTHLOMQSLOdqSsnotVMYZG6GKsE0Kp/o7Fjha5Ye0F3Nz1+9nT+j/CAa8iYr8hGl9kqimMTTuEyMXmaK1pBkqpyip4IfK3zN2gPAwh9e7vnPw3rPG37ou2n/sdULJLFsYt+SkhZjKfqovZhWUo7YscVQ2BvK4E+lCGONjmbpIek2d6cSlLKSl5yfjOoXc/vNqIKHKs6bJSUtKPBJFWMTRodBqWK1DdkaFapcGMWEN+sNcPhj3Ozu+eXDtue03b5vZUOS8pJhT9lKLspKkZXJqJ1HL5MetE7yy0R9LMBR2Jr1BmxPm0pjtMSLsVhtmW1J9ofovEz7krOV5slKBYHF6tgcrdooRM16A6L1Jt5ya4i0KeSD1gSy+0XUqWYXdCZSIUBwko5ZgWEzGlCr3gDouF/u+5t11x1YNspTqGQDdOb4aP+1AUbrQhY8STrg4AClV5Am8lVmHseKEjeZ78fCenLV1o3VHZu1B5Qd94fdNNfb7/j+b8M1XhVNOSpjSvZKW/beM1n0NhalsAp9OrVEVPqHs/Lbhtso/S+85ujZ6lP2hAFRvGRhJNkcSnUAKXlUPqaMqvIpehLesRb4Zu0BXs9d31pziNLPOQUZYaUoncU1ikchkz3kCiQNMmKEfPSVozSRZr0hz/aj2Mh1Yy5KUzfWGY1cMmTtLMgOlFUsWf5QysUoWWN91oN/W9CMtQc0az/+IY1if3jIsecyOavxvuPHvwFOarX/DBMAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Fri, 29 Dec 2017 00:38:15 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "58", "X-RateLimit-Reset": "1514511495", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"a4f13600f56f075736319df051d49826\"", "Last-Modified": "Thu, 28 Dec 2017 04:56:43 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.036467", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C628:8329:716D778:12DE45BF:5A458E77"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2"}, "recorded_at": "2017-12-29T00:38:15"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2?recursive=1"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA+Xda28fyZUn6O/i19OlvF/6XY/bM23stD2w3QssFgsirxLbEqkhqbLLg/7u88SfKma6SiQjWLHALNZ22UWpq49OZkbEiXN+l//5q/sP06/+8Vdj11fdOhd9Ww3T0M/9Uu5V121rUy1rXZVFXzR9sVS/+k+/+nL30T/w4eHh8/0/vns3fb7+7v31w4cv83fL7ad3d9vn2/t399fvP03fX999ua+ad4+/W3/3+Yfwt+8e7rbt/l1CvPAP/Oof/+//+avP08MHkUO46/c3t3ebP8yn29Vv/qosiq5p/Pzww+fw8/zxdvbTY25bOU/LPldS6ddtK9eqmba9rda9qtd+qve+aaptqsM/cP03/3jZFr84zfAnuH8XHfo//tOR38OdZ3f/3Q+fPkYmOLfbsJR9v0zN0M1tOQxdvY5lU01N2xbyG8t+H8fpSLAs20wZRsc+ZfhP//anf/n9H/743d39Q2SGy9hV09yPQ18X9dbs61pUXbsVY11MUzcOZTe2c1eEL+LrKxyaIVOG0bFPGf769//8m6vf/5erX//+d//8b7/+03ef1shEi3IefMl7WU/LWO3jslbVNq7NVk9DOfV1uTb9MDSXj/vxW5V8pkSjY/9dor/70x9++5//7U+//d1/TXif7VjMVVEXY7cvFmWxj1uxjGPVju1el+O0t0U1dXvxlGZdVGOmNKNjn9L8l9/+8U+//8P/lZDhLCNLb9zKrR8nS7Pu59UHW3X71lR9MY11u7RNd9p0qrLPlGJ08FOK/+2f/vSbP/7p6v/8zR/++Nvf/+7qd7/3Y0K+fb0O+1Q3c+cF9sveFP26N3tVdMW+V8s87VNR1eOxyVZF33SZ8o0Ofs73t7/+ze/++JvIdenY2OaiHfqu3La6X9vGrrrWst22Zm7a2tbUDWN5vM66qTJlFx37lN2//tPvfvtfvM/vrm9iM6ybfpumctpaG+tWNMU0LP3UTfuw18O+lXXrP914LMmmyZVgbOhzgtOft/36Y2wNUMxju/bb5jis1rHblr1d16Ua6r6sRufmuHuZbbkc2XW5Xl906FN2f/jNP/3zv/4mYfkVU9sM7VI2w1RZe+vcTLOapl+arRqcKXVdzE6V4+2V45Dr9UXHPiW4bt//w932P75c322ftpuH++8e/hpbC8xKNuXbXNpiumYapnpQtDZl32z91lXjug1tsxTDsRSLXEdHdOhzprfL/bEELSv/8vPXQvVS3P5YqBZDsau8N59kV5TFMJdr283V1FdjWa5d3Y1L15bj7h/IUoRHx/tJOu/+NW3xTY74od6Lti/2rljaqZiWaS9b1XjfFV1d7eW812uo3x+LmqYr61+c42MFHh37pzmGi018gdq5X0xNtw3uSdW6jIWCbW59jKNPdWy3vihdqE77SzU2ueq26Ng/S/HLw4f7hCSrqmmnulDQuC/NDoXVwadUK5auWbp6Gj2AZliPe0ZV5lp50aF/muNye7O7eh4r8MWrYr2W29K2yzC4Cq/LvhbtWhXDtizLXjsiXBWXflmP8lsxnqtoi4790xTXbbm9mx5u71Le5b4XQ7lMfdktq+p0X+dV5eaj9Ip9sWM9Tb3yLVz4H9dkNeQ6EKND/zTR7fvLURG/KpexX7pwddzLqp+ave63uq2KSQVeFFVIfXP2L6drY1Xlep3RsX+W5V+nT58/brGHxrqsdtZhHoZ1rGdVdjmPU7VMzou1W5z/S7X2bdvnOjSi4z2Xly7Q/UPKSyxDkVatTbnOropVWI8u/2099L2zo3SlWuduPk6PsutybTtLbOwXkk3JtR+a3uHh3J/6rVHWdOXetKXCW/XdKFlnh0hdtk+rsmzKXL2q6Ngv5Rr6gPHrs1gFdR9v+mndtRebbZyKrlIXzO4eWh5LXXdLdVySm6rOtT6jYz+b7vX9/ZctIduunO0481Tu3aAhqVyQs25A3Rdj2a5DsQ5dP/bHHdIOletDjo79fLYPW/Ihs1o/UisGTeViqRffdVHbhJe+VNNuYzeXg3L3uHWV/ZirMRkd+9mMP96+f3998z7hDS/1uq2lC0g/FRpZ89hMXdlvRT1eSsHClx5K4bAXf+3e5XvD0bGfzfd2Ug8mZLsPZTmbE8x2312jctIOGbZu1SrQ6FmLZtDvWstTy2dscq3e6NjPZ7s83C5TyuZcN8UyVZOLc9WsdTm0piWbCnFyx9b7WaZ5Gvd+OYpDW3WuDld07Gfzvb/9cnepdL6OTF68iS7DXGm3r46jfi40FhT5877tezlUo1JjbtvVhTtszFluotHxXknv3Xx3+5f77S6+4h+7cSqVu0NXLUU4ais9hXYb+8YjL5dBW7ramvH0Usdcg4Xo0K8l/XWjutr+Gp93UVaO3X5cmtB7dyvvHLlV35k2NIUzqaqWcmi2I++xynVfjQ79Wt63j0v46n76IT7xterHepzWQa08d+WwOaDKRfO60wWsukXrsx7My572aMfzL/7KH3sR0aFfS/wvd9Pnq4ftrw/xaZdbuffbutZa89OymkfMiyGEVa5r2DZbZ6m3XXNMXMou13ceHfrZtB/+cnu1T9723VXiGdVPvRbMupbjss3LUvuxW4fK5db1fhxcHdrGPffvboC57rnRsX+ad7ggpVxzw6fb1muoOJpx6Lq9Gaq+Kqeycl/Y93pZ16nrt3NHtM7VX4uO/fMkU87eft5nZcVmNx600ra6nOt23Gv7VTMMo95bsRubHpWVX8y0aqNDfyPDtOvQ0g+m2b3mb725zbvcFiN4QjmqnC1SLbfNDlUfN111daYko0P/NMnrm9WxE3/lM3MZ9n6t6r0DSWjnYZ5bdXJZGp/N2zRO3VC3c3H0nbom26AiOvbPkgw3vZQVqQc8tO3ommcBuuC22+581YyapiG0LtpmnJahPbadMdvnGh36p0mGuvBjSpK7plPnftd0vcq39MGCZZTVvLeq4L7uin7XIV6OI8XmlOlzjQ790yRvbh+u92t1//XtTUquva21X4p175bBOgxbESBGrxUe6gj3oLK0C+1HY0afMVOu0aF/muvt3fuUFIfKdGlpfZjLYgZcSMv1Zh/WHjSs2Ite+6JZx4Bkeby81nWuCWJ06J+m+Pnu9t+35eFq+TDdvN/UwQk7UduU4zwaCjddrSqaimKdymXf7MEBolGt7vDuOqeRfpmrAo4O/bN8v3xMWqLgQvpnq3ZiCeA3TAb7bVfN0+Dg7MtQFWinGo0/vVMbU6bPNjr0T3O8QAgT3mPZF3XoI1Vhblrvi/6+LLpGI2KClhq9Ujtwd9xk6rbIdS2Pjv3TJO+36W75cHX/cPdlSar1JihGPTRwogI0rBjqohzNaaxbFzowjQoQxWd9aplm+2qjQ/8s2eQsZWGkCPoGnKGpFIofg41ytA0V4zgvui/VUs3H2jTkyfTdRof+aZYP2/1DWruw6SZF3q4XGvALkEQz0IYyr5jdUHYdf8CGdqnPdXvb51qf0cF/mucX/ZWU9amBtLT9bjpVbG7bhqtVaJGC3o7KPciGPUxV62MP6oZcF+7o0Kcct8fx2z+oFLb59vbPsXO4qoEfgmYMk/C6gJn20S7GFWp0UEZLdgb9mOrQ687SMouO91Ju76aPH68uG+61y/W1Gvf68w83YauMAVa7W5rW7L0SYVzM1Xe4HAdNq6LXMxz6FTTHSXO097tiyFYBxsZ+MX3ogIcwU/6HgPZISd3gvG6NVd2t63ZfW8OqqhzcQjtdBS3xDVq5NlV/OlirtutyNb+jg7+Y+35792f71d+9/qv5h7TH0Ozz0oyGWrCP26Y5DOHTVo6nHeRMdVFO1XBGnvd9nWujNs+Pi/3iU7gM8dI++262lVnVo//qvdeyXmzdUGd1C9oE2LzUM7zPUXB0eha/eNU/thCjY7+c9GWWF17+7ffb3dXnL/PH6+Xqse2UsgrKYl8aULVSn0IbVSGygh4ahYRhde3G6+0PoOxPq2Ach1yNp+jYLz6JT9PNFIZ8V2/4DuzpJcRXoQ4xXh2da0Mz9VDOgCZtt3YdbMLQFcfBNrTZhvXRsV/M/vTir1J3wBU1qKzVLbMRfh82/3oE6V7LtjYQm9fGgNtDOd+Iy1ybf3TsF7O/2x4ced8fb//q9uZqOvbDtK2wGIEYCnQYPJS9nNoJy2gHLyrdReyNja3CVWQ4FXNjXed6INHBX3wg9w/Tg+ou/TSshmUqVOjtMoECqnSQdXQH8B/2oqwbnKS2DxyAp30ggLIy7YjRsV9M/ScTBjXB1yZR0nEI6Fk1y2ycEs6+elX3tvs4a9mOAMuzK6ppw16drqL6Z5meQ3Ts03P4Ss07yr0Xh8LIRxtumRc5I8xNPUjvuC5Lp6mwuZspftWCWxuyy1LhRsf7eUbvrq6m+fbLw9VV/IQMZsFJFkq6EjFp8B9j/W0fpnntSxQsv181zakzDSX5izN9PNWjQ38z0+ub66REh7XYFuP8Qd/SXWyBuXE/q6taTVO14f2iRgCeH7Ursl2mTKNjfyPTcELFI3mHCV/F/QunbDAa09LTFQmVesCU2Yy7qkEHOTrwgZyUq0qrY4N/K8sLKDs6T8Ai08wNN7DtO8dvFS6hI44L7FyxdmWpkdBX69EPgkXK9TKjY38jzRNoOTpXk1qrUj4LnFFrs5m7PqDpYO3Nk2aQDVgkEI6nD1eZnuvOFR37G7l+xS1H51lskNhDh/cx4Xr2YawyG6e0Bti+ZBP7ymcMWfeUZ1v3uWBz0bG/ledfl+3z42QlOte969pds0ApbVeaywoIdKhagGbo+3FXRjsvdY2OdwrKnWkzio79jVwvl6XIg3P39nbYt6kws4bRRlIy0N0CIyaw7Q3sl7UcLtekLAdndLzn8nJ8ph4qdaCfV5s55+g6oNKppzYcnHZhCPT9wpqs9u3EDRlz3QSjQz+bLuWCwEKL33VDJQQ+tXbjjmmm5WOG0gTOPdxjt219M8x+qz1dfLtcs6Po0M9mG2iT8amCdcL7TSae0OjTumzjbKfdCuiwqSknLWpUtX08Bvb+L3Odo9Gxn831wjWI3owQYFFgxrAftYCdbrSTbEtouE4v05xwBxsr+6OrN4CA/uJF+1gDRsd+NtcPcr29S4DCNQF2WSBQKgWtU+A/TS1V09rObrChmUMJBBP4ae8NII1M6UbH/ma6Ke+0wtx2+xwvte0AkwH0B2iPSwIlpW9jUm/6e6CUuy4ba03/My72t5MM6KHob7cAZqyAF5VCcJ2GgLgS44RQsVTAjhIGhGun+cA19hUKVKa3GR38G4k+dt4ij9LAoFj6MNUdiSgE1CKWiFwV3K6fDqAOLszOnOsojY73bGJvOEunfYfHQsVrLMyNqIsOI6CUj7du4GvUEdsIbn4Cu2XrK0aHfj7f5MN0g8IY1nrsDBEKc22D3RW1G9vSAMWsHsXUxXs8dc5M0jJ9uNGxn8/3Ut3Hr9N1pz80mGGb7Y61biEKyKxyQIsBOLdqpTzDozxturatXGdMdOzns30kPUXvSoDVlD+WgKE0xdcynpH2NtdSgHuov0m/sKCCcpJBMVPJVd9HB38+3Y/TvH2Mf7kLtvdUKHS1U/R/CaFMldc7QKasnsQ69XtZKKaOE9WwLNOnHB37+Ww/qQzVEDcJ5SEiCM2ptTQJ9nr1HPZQAE+Dvdk27CJnNBransf9rctGfI+O/Y2MDby2G73u+He7Vd5meL87Qq1JNpGCFXsNHKWZiuYy8y8MeU9ktqLI9SVHx/5Gpl9xndFLtp2h5JUN04q+Bh6HdaqHraE0QneaY5DdKKa9ORf8Y7YdKjr4s4lGFhKNHagYzapsr/3oiipV5GJVOJhus4wGumZsTbY7eXS8ZxP7KqSH65+wPLeOHgrK1lzhJRrNNKGOUBb2fasqdE1vhoV40bEhZTtYYwN/I9+/B+lGf7haD6HvSgeHREU/lC6ppHAMKvB75nG2dhEhypNIXBA0yrT5Rsf+VrpAnfHbUEe5oJ4nOBPqKctg/DJYn8viteK4rHKEUd6n04latLnK/OjY38jygkaOfpcgcAt4KoAY6jtAlQbaZt9VJg1F01Wk0qrWAOrcvndZzfQyo4N/I83PF4RudJ6oHfiHNh/ZNUFirIAtd44i1rqN634GbNU4ncUNHLSZ8owO/o08L6CxyL22rGD8ZmIbJYKZnbUZIDmbZmtLn6s2L3G4anFDzXVpi473XF5vuLNtnW0UZNy9bZrn1fEJPF5qkdUmouOmyYsO3i2nyi/b9DA69LPpznfTzfIh/quleOcgcVwqafFZ+s5CpY1DO26mojZNmO5Du2/HBbUG28300UbHfjbb9AtqG7YegOulKhVCI/mGfSSP56ba7jA9SiU6JMsxj9ESzUWN2GJjv5judcIFddpxBXEIsSWt06Fvm7XVclnUSQZQOsD6+0r9Y+ulS5Zrohgd+6VsP0931/e3N/GfczeiExoOj3tJkgMbDWpnNqbRDKlUvxumKDjPeFT27qi5Cofo2C9k/Ihhjc9309FedQlxRi8lEeCS1n6AZ5fdir3VNnaupjm1ROk+Zlq+0bGfzXfdPn+8/SFtXmO2SIWkL0tXUtR+CleBOgrARigpsKJhH4LA5TFlbPSKM2UcHfvZjD+Aoce/3QLZefKXrr4LzkyuYhineSBTAZpkrqGvBoC/njbnKh8OLTb2s7le+ktX158+394l7FltQ8twg7ieCJJUUwlo7zZHcpeIhekjgsGqG1Oe7qw6bZneb3TsZ3P+PL1PaUTsTlmN76FZtLxpJWtGQGH6vAGiCYF39YDwpQw5mkxdm2v5Rsd+Ntm77eM23SdcYe3F5V6rkLsJ/xAnWo9lDRe5hST2oiPe1mUYVR3pqqFzbc/RwV/I9/Nt/OLVc6HhvgSFJHswLqI6igqfbmkD4wPnQZ3DUOBIdrB15eogRgd/NtmAIE24/WzyXOZlWLvJGLI3XnXfcQnaWkgfo6yx0CWmEHq8WveHTMs2OvaLyX5JyBYwVN/fqi3Q9sDkCQ8umi/mAL3Lbhd644au2zFdJkySa9waHfvZbB+m9/Gfcd8bjIO8lMOuAwySVRjnGMK6FNT4Mq5+5Dfq/XStLbKJn0fH/kaqj7TMyGutVwflq1nQOGU6ooPah3SyO6mRcdChKZFAij4UyllgPdHxnk3sDffasd9NbEg+VRPxDRRpze9pc5/b2mnzk7OmAMc/ida1udow0aGfz3ehaRD/1SLueH0FqbqlodswbdtWtRAgHd0R7H87sJaTGfPppMm2HUXHfj7ZxNFc0cw6/W45nFGIVdB+AlxHWpEniepqtwF3kATHGtWI+8Vf8iPWJTr088k+kRYT8C66/HiJY0+Jw7Gp+WQ36t3ygGBI3u+4O3MX2DtP7xevJVPG0aGfzzjwbuO/5Y0OBwefhYqoTiJG+HJBpYGszYPX66BVTXXTURG32WDB0aG/mev9PWmOhDwJOLXaTzu5sk3jzWakIg5MxNX3HXYp2r9nn40WXC3XS42N/a1Ev3LiozvFtKv0JiB5fKdsNYY9NC3C5zqpEt1w8OFH0PbTxyvTTIlGx/5Goo908eg0NfZxxQ1UzeMuPim6ExMeTUnyhYIoeAT4rG7NsQeDveeq9qODfyvPh+uUxn+gg2NIB6MGKsZ8mgyuOG20umvu64jjph4cnE5dNgIsmV5ndOxTmtefwiU1sjKq21USgQFG9B4gjTwo0b2lobiiNdzDUKqN2i20W7JURtHxfpbQu/cf6n+gG+OKdvP+yO5FkXh6KsxuoH/D6VmOigTNtKEmHGEH6reg+L9gf53u36Ef/otTfTw6o4OfUg1n5d3DI8X1pzsrDru0v2WbFpTIyDKshAzgzfBaoX4NkJthZxSzBRTEsphYHRuOyjdXTyU69inL++3hy+fvlj32NW5lO5TenGYvIMmCp2yU6hUaLwags24RGq9r2tNOg+6a6SVGh/5Zej/ZR59/e13YLynVgr0yYIIBwMYkX4WoO1MXIVWAjUhy5AQzc+XOlF507FN6QT0ldnsx/h01osyYrAbse1ZL2rsKHROZnf9G3ZPpLS6ztizbS3S8n+bzhvvW/6cAG5eX9m6Z7q09fx95OgD8eX1BIQNBzxEIKgb9GeCtuiFdwDA3SvTLbD/L64uO97PX95TZu38KKV4td9v0sGGIX1qYV9tqrvbvRk2RB0cQ8EcFX2eGBvgFfP0wR1r1KWu/INEFr1gF35GnHSdox/zih/B4bkTHfvUhUAncHraUvFmLlJT+C7wCKvC0Skus4bpZcfj4jPREulpEklPpWqIT5+rzRQd/PfHbv9x8vJ3WlNTr4JxKOEtRUJoWUxkG+oXW2fVysTQBftvF75xaCh0l6lzFQnT06Nyv/vJhI5KAo/qVIr8lPY5gujJXnflMuXCuII1p0sw5SbnfjSOUo1trSTvjaQUARyNeZ1oD0dFffRypK5+GWejek6GD2UJ9IbzdmdawM90phBpeUI8s+lNbn05OrqyjY7+UtRdOH+pvF93Mq2ldr+6X28+GVim738weatmIireh5++lj+2AOwc7HIyIBv0JOlknCU3j2Vz1JNBIXOzoZ5C+CwabpRqpNxx2KHXcTlVvbOuC85I7H4RiwU2g/jtxiFy7f3Ts6Pz59tEOesNnEPgsfARCYQp84PRjTbzZC/Ub/eIYJgYuT8NRmOoC5Oo7RsdOeAyfP07LW56D2//Y11C4bsitpWAd0A3B+PZ5QFLN2tA737jjZGjMiXJthLGxX3gO//mCGbuiwPpAgTVlIyAUhcK0QChQmd3WmvUvp0PScSxV7ZNWQtMZqRwLofSgch2J0cFfT/3LzRuSN+lzc4Z47EEfSeLQFHF1mQN3QKurmrtpYRJcH+gM3LZcrz069gu5//r201d81dV6ve8p732HVcCu5YxDbBcVZkYdYSxCw8EiwEAFYcDyOvkfQejUfa47d3T0uOSZ0UNMJhx/Jr+UnMcVENZYu6w31MxA7KPPwYKDe7BBcO2EeCp9LtnnavlFR38x+0eg2VX62Ydlq7YjRezDJxGwQ5wR04a5mo3ACfcHih9kw4GwIxuZa9OPjh2T+pfPqxtgynt36akIgGrF0CoBHi0Mhckl7XPQGKJUTJ55UxceA1QTqlylX3TsF1L/5ye43Y/X30eZsJRnsBmsetPUo3S1OWn2kB16UhQStIZBarWeetqhp02Prmimsy46dtwz+FEjLSX9gAtQ4AeDHbAI+oi4ysPOj7kouQBwhMfD4RB2AvUU2dBp0bFfSP+/Eha4+oqaTir5vV6S8go6JkuquMt1364PXAy9xUnLlmd6c4KBmGdlE4iMDh6T+TVYU8JmrzMeOPg1GBfdY8SHEmelwgOgsxAu//TKnfnbYY1AYSzXECs69qt5P3a7foTLJ6QPmjfjGqO6QtWCsxFJqX3nTKZKV73CwIRGFafkp7POfThX8zk69mvpp59y4UYPzLasCHYtMwHi+whMBZ2xesEGhojSiq9OdpZAQ7nKm+jYr6Wd2trQtVDC1+2wrXCoNCU4DKw80wYNPt3NcdaR15k/MHy0nnLt7dGxX0s6SOIkLXDYEXh5dRs7qYpKFXC1Sxu22spAIsjNQUlRjTmNV7Q0c1U00cFfTZsEdMq2phnHn96cGggXgXQuiDzZ2lTtsHydwW5Zzzr5xzneET7PdI5Hx45JOuld91izfROEGmzhZk2MJZqJMMcKx2mm7fZGBsis9NjN8qn0R8d+Levre2YT091dWr+WrfJWBcM4V/Q5HONU59h9bs3mqhpwgMzVpuHkLOazyLWRR8d+LfWQd8pXjgVEko3T1tw6svCvaP9pTE0IUBvOjN5Ug1dx0sfUrsj1lUfHfi3pLzepaU/snEr3cdvXuLUgKTOXPODyeZMvgd86HGjwRk+fubRzdWWiY7+Y9sO/fJl/jR5/Rdx8+3j9iSyqNuVEyo6Lb1L5gmZgQM4hcUM2cAtnT0aWBUSQR2RL3puusbvsMaVAQsi0zRUMBaJiv/okfuO2fvcZFW7TsP90fRPWf1oV2zaVZdCsfdWwL4OJIb1oxh4w7Az39pU1ebjGnxASKoBMzyE69qvP4bdfjauvuH5pWP4uyJskfAzcHOgR4Tu6sLvIu7gy+iL0wdZ6DqyxaQMl9XxOI6tshnXRsVMfwgbNn3QGgnPxxaWIQZjKIHNHMis8BayNFtjJMG9mr7k2x+bgqperixEdO+Ep3H65CZvDtHzY7q+KlO/BAAuudIGtCYeh3m2QzDOpIvRukLmPJYUj/MkTGdilP9OiiI4d/yRugotswnLQrdxwIzdYBVjMkmPRiu/Ng5OcHnoLeCrJNCStp+WQ8UOIjh2f/t0G13F/FdZDylMg3TWGZsZARnvFh1YSB95hqPjR4JcZ0NEBcZplkvcacvVyo4O/+hj+uF3Q1lfPq98nfBlgLWxgOrqZ7ezY1OGhaUGbJLjOaf36b+II50s/qbdc9UN07NcfycUD4eKGkZB7J3MFMskkM7wxQEBZ1K52BZ0AKpMjThCQ+hkSyn0706YQHTs294+Tdt8nnwbEb8pD4Jze+U/Q6IZiAxuFE9DkqgwxA9ynhnqYVjeo46Sk7ZfpIUTHjn0IX/NPOiQLpAqTXDJE7UqBp9LRJgfCDKkw4Nb9AX/SEdqPi6KTI1P+0aFj809v8mt0XcpCWi7W/6LNS0sgjDdGFW3gLfSWg3bY6fVnY09Fx341/Qu4JVwaPoa/czwEjbiEnQDjhMw1ta+FFQ7Jbwqs0G90za0JUI8AWXV7OKnE6Zjl2gWjY0c8Bb5wfy/DlfAMVEYTrBW0MbAP3pGn4KTE7p32QoMM3IfAGm7ZUSMYAOXqCUYHj3sIZKumm6/Ap6QPAd81mGJBfA7E3YMGpC4o8VqVkxGIY4IkQTO1BwGL32OuOjE6dsQz+Ir8SjoJ+K2ac+mUULeqtkI/fMXRD6ciFfwdyMN9ikfGuUbOxj6Ljv167l/hvo+DgKs/bz+kbAQTVFMXbNXrih8iyRFEUl4rYRS80ZohDYqsVp5QLkzBc62B6NjRz+Cio56wBXTW+WjVQzyY8G+c4dqVljjnoBrFaTEGBoKYTj1TuJBsjcPY2NHZPzJrE9Jf+UCSoibaEKwsNEqRZ5YgsxPoFyTQqs1MkOrx0w4Y3JkzlQLRsaPTP3FtE57B7lLYbK6IsH3BVHehKbQ5GcOADrPYzZG+9XRqo/ZlNnPb6NivP4Ovq/8XlAQ0O3p+Jm1wkmKY2De8mnVXddI4ynMCIQxMV3U6g56rXL2T6NivPwiAz3+/TjoCcTqMTMaFhNhc8eJhFBpUBGbzMTZbNkVcc0KAJwZZxSsv0zKIDv565sgqa1Li9C5QVmGcOvLA1Jc0CNiK6ZSx66ahYJZihgLedRRA+RxCo2NH5H378ePtX7g9XwD/Kdv/7IUPnbkozSnvXB0QOL08JYht1eoAxggtH4bTJ6+LlusuGB085QncJkEdA52nt88vlOKCerIR8VSXOiC+AUsB94krajEe+XNRyfXhR8d+Pf3UU58cE26hohejch46nlVwHQo9l0J3IMZVU79A/52YsUGFLdOCjw4ek/fD9fubMEl62D4BeKch/qx3mAg0tnDbn6d2A23DeYJ8CdYcsK40p3sM4uMi3Je5Kr/o2G95CEl7YKXdt2sFoQlTolP3cgsnnzIuIGHsLDY4GLPi/pibBB+hTJ9CdOzXn4K5+X7ZBhNniIDc8iQPpFGsC0LFmLKVT4Ersmn6CvS8axQtZ7GnbDtAdOyo9N8AGyBitlGP6Vr+mRB/wTUJvaEMuHYOQlSuNIOcCofcIqWrXNtfdOyY5GkRphx7HdHfgSV2zw2AZCgDv3raCKle/G9lPlOJZfxxTMnAY3J1AKNjR+RtYno16QBdCv+UB6DTg2gVXGRLuz/vCxxfvZ3QDi2HVa1HzcMs/Wh66NZks4OIDp7wBB7VSxJuPW655TZsSvu19vIx7TtiZ8hNqhLO8NVAopGywEn5rK+zCXpHB498Al+NKxPSZ1o0jyWcjLt/s5C/howKg3KyqxAzSN90+MthOZlk9ArkTNt+dPDI9MPLVwFMn5LWQLcO+K1NUFoIlrLFRIu0ZKBhJ+ioRVcdTE2rJf50/PsectVA0bFffwKp7S5yUgiOxdqstKa8a1fb3ZiY5nkLRsO/Cti/nU4aym02PCS1vbjYr2f91RYmac9r6DIp7l3hvVhtbkwmzF4oIY1O0F/YSED//Sj3avSfTF+8KHGxozNP+tSJbQVzEQMOZC5Tj25tg8KjbQ7BU69DC3jl9H6q8aps8P7o2K+n/mm6+/OK3J/y1hvAKBNNfDZiTRsy50a+AkDK5jaWTnpdOEpk4+mqA0WW6a1Hx45IPam+0c3D0aYkg6q8ubnhNjjYWrI5CC4mXAi8toDh2NooHuSq6aNjxyT9MKW865al7Wr3WjSzeNQBd4T+jlsMMSQmJfMI/Uus93SoGfdmetfRsV9P+wbSY/urRj7phqv317/kisuRGcYntDDZecBCwQYiNoBJu+IQdlDfrMqc/jTr9dFkeiLRsV9/IrfLwy1UYMq3sGjrGHQTa2hAIokW98HWOJD7aqtd6ceNnAj3SUmeXU+mzKNjR2R+GmumpE8LddwC+tE1Dn2RDwLVdb+kwoOPbYPIegnvcFoK2G6Z0o+O/Xr6n7/M919m/qozi9WE8nb2whfiJc22o26PrAyD/Domd01v3ldhvqO1V5yQwRrdudKPjR2T/uVy9z++0G9KST8IFIE81gPNmtDbgH2c69VAxyWXUPcK+jiS8Tg0C3qFWab0o2O/nn6Ah19d8OEpyRP4Q3qw10ExYESQMcICMNap/L1LblUY94LInk78fKjw6NgRyYc7/TWj6Os0YIuig2gJ785lQUqhjtdS3feDga4eL3ZEF1reJ632esgnGBwdPC3/qzlppI/txM0zMNV9+/j6F0H+MNppXexQ+IuFar2a8JjqorzmutpFB094BEnZ73g+i6tdr6vnlq+t13Pa61VGNn/tvCnAfrvp+P7dfXNt/dGxU5K/+sv1w4er6yQBK6teHbiApLcoUf53ZkwXtFrcgGZuiroZ2ADrcf6BBOd6CNGxX38Ijzr3ON3k0ROOP7gVPRazezhPW8BUamDTLaqrXdOHPg3XHIOe6lgAWES5mjvRsZOyf/wGHoDgrz6lKnr0PRm7kqwH/Ya5wgTYIb0YO5PxLUqeWcB+sM/lUQxQ/M31LUTHjn4ajzbsKV9Dz9uOkk/VdjMxX+4HVIuxAdHESMk3AQBzsag8HYhs0bL1u6OjRz+BJ5hL4slY0vSiwa3F30D2BZY3uKcTAZiBtoduH30TBsGnpncQR85UFkUHf9Nj0P1808qg88MaudUTK+yPHPP0gVuNIPhoyABbJwsbmmxPB2VD5S8X/gnAMC549BNJHgLQXQyUSbvCSqedLSQGpd43Hx9jMY6mBTpdkD08JsAGpJk+iOjYaen/ko0SCNCtudP2p/ndmwBoiKscaaD4JZui/3FpLo87s1o6W9kUGzvicSTyiLVAe9j3bq9RBHdocqy5vWcnWA56h3qmdJJhQk+XRYrbmb6C6Nivp/3l5nEAnnI0kENQCYRWqIuiDpHtL9hPG3+CQvcDHPwGDjif/Ni6bEq30bFjUkcRXN8OhMcHGuwAYRakK4oXxIWj0jGndgcG6pxwhVxgZU5IkHw40OjgMc8hlUzebVa5OYjXOjsdqXn56qnjaw93wI/TxJTagjgoABpKuXbA6NgRiV/kvpChUj7+HrrVqKvGGoZ2ssE1DS5MsXO+CihInjNEj9aTcD4VpFzlQHTsiNyD30zC5SAYXiGzcCUZJvfEAuyzc1vSEmNe50OYDcY8lBPokZRGpu0uOnZc2m+5GcL4LXXBMwrimxu8m4F2yUrUlbeHJT+yiyD8dII88vvO9dajY7+e/t+2pDFYD9e/k1VdXABphWwjPwyTsR5FfgXoWuB6COWsp0FAlW0MFh37haz/hbXqG/QM97CRNXZzEq3QPQiuaM+Vpa0HarsH9Ifwg3582th7AM9M33p07NfSTlV62ta+drXR9L90PIMcRDPVwRHUCqdtp+LdAZyP02zgAJMp6ejYryX9ORHHx5WA0MWGvkvIqujg+AvTTgg2zCZTQOXdBNR5AnP2+cR/omO/lnTwaUjZyk015pZ3YdGGhh8ce4/qz9OH2hONUvJtlruK9njTZHFyXd+iY7+Q9G8vJsKByflxmje2TAnHGNU+M92WrwghL0bozP/0OIoWsnZA9SfkqItD++B0d82myxwd+/XcEfvfp+3k7uslQa8eRm3Ut265dWpmdRirfH309inUFnx5nvLGa8p1W+ljY7+a9/Lx9j5N4go4bxk1btttX3EW/NuAH3Oha5VqyDm4HzAO8/Gtq2py7WrRsV/P+/bTxRE94UNv+qELkgwBnkVmmRMSU3R+xx6BK2twJDBpL+ejla16zTXMi44dm3jSEt/BUly+10LrEiRt6zlRKFZYZlPlpeOga4mkcxLvA3bIValGx3498zfLcypSaq2peQk9KcpWrl4kmdu6cmcv6Jbg7QPwnZS+WNHlKlWjY7+af2r5UkPlrtg4RGp4bvTOGbauk1PNxYSiXYWUoUO3nYQqwRwylS/RsV/P+nvLPOlrZ3OGhVFXBlcGtQ7uETgzzGwal5OaaIltftxPPq8Km1xjiujYr+adfpC7bQV1ZZqsFOe5DgbD15LsrOltAGKXc+0Wroo/cLhFtiZsdOzX875dkiQ6Dd05xNNa2KhBrAF9zVnFSG4L3caqQkdnr7CcaOcGebn2tujYr2b9+cvbACosbjuFq3G0uwddeWoza9l5+4SlWRtrSVItNaN7eudADbm+9ejYr2b/1VslMDDSP/tgqdZvjY473Q0aPHRZOQCyXSrZKxCq1ZvqOQIfN/Imn21jdOzYR3BJP6moqTHMaewYRPKR2tCPENC64ECPXzpD6bFqB9c4ZZ9Pg8c4NC52RPbMldKqd7bOOm+6T+5pQWxIDctDDRnFgF77KeDQ6fQdLgOs63NVscEePip2RN6PbjrpX33bQyADXtvQffWh+4JWzy+YEhHlGSKNVKl72gOnW1s28bHo2K/m/4W/XNp2z87GXt/1XnFDpRPkZsG6IC+hJTiF8RJLcxP5Y9IYPHgzFTXRsV/I+//YfnhD+60MsjquYSOmFTmhCyoLBhEmfSsB7wviGkGC73RHzye3Fh37lazTnURUr0FJ3qm28j0lIuO71lcEQYE9Ix7DXiYIM56cs3SqMr3r6NgvZP3fwmb+hrcNR0N2lUVaj0mqy4hNTnlx4tWLc6Dzuu/Ap/Vpb/OLufKOjv1q3unvmx0qoyhSQYRne1qJYOYNKf2gxU12d16NjnlJzEcxQ5I0VzETHfuFvP81iOo/kNt9wztvoUW01MGngm+Ilx2IdEFDI7gJ1LgGE/FV6/xosHfZvJKiY0flnn6WDQP42Bg4oz5uTsbU9jesSnQijjl+p9Fw7xT0x9QY4TbX/Tw6eFTy6R+9O7gO80oZqJ1xCbWeO8QKEBp0cXcX3hoOeVeZ49aGT5lpk4uO/ULuvz8RKy4d6E/bpzltkAohQUMXQgIuRv2yq+IXTUrgkFVVC2Ve6cMyVTk6sbS0Mj2C6Ngpj+Bt+lFmDjsq4YxSikTKZIRsUABP1JyTGIeavAVVmRPDjqxSrscQHTv2MSy3N8s2fXzD1zDPAWdvxgpLstCUNWUOELrBMEK5Q4V+qfkHn7T0NPJyVfbRsaMfw48G2l85CGkA9N4QCmSGjhaUNfoVLzGAUgh0rsL8g22bPpeTuoJLX5/riwDcigue+CgCvTzlgstBTxFgUNFo3e2M78MgTutB72q0Xw5E1bRv20NXRNsjVxczOnbsM0ht4XIiICGmr8cvkJBqw3ZHTcSBAEsS4Li1IIKz7tHChVXP1dyKjh2dfHInF9sI94qkEm4xLd05NHXUAVWQVtTYwMR1+evOrMuqAsnJdDRER499AKR10g/HoKDUtXAI0IQeRRDS4ypIUHA0k6fI3xotQdscF/3Q+sn0BKJjJzwBTESaA294EBs5McMkeyGZCW3MatvwsKcdqs7gGje7rknwDic6jpZopgcRHTv2QTx+B0ljDZAjhupMxyjvt4y4DLFAMvbQ8TTdI7TLpqQr2hP7osumLRgdOzH/Kz5ktHeSnoObQrCSR8WsKE4Y3sGVUpedgugm8ikhGsUitP1Ttdj12axVo2OnPoe720Q/tq0EKe+ndl9JE+Biw6rA3vW+De3tJeDtgyPDSWOT+Fiuu3J07Nin8Hd7QtLHoE6mUUB+HvBUW6iAyjP1NOQFalBEaokFZf7iqA4CnS3TphAdO+0xXP8t4G+T71Bl29PfgcdzPeRh5UGEe1MQJ/A/muSGYrti6bhDMTXJ9CAofcfFjn0QX+dB6U/BzK8rax5OVEhrVD1uJdPIwC84mpEscXjwKPCvo4vilzM9hejYiU/hbZdJfiTa1UGUkg7hXLfbiq9FnXEwF1pdJhQQ8D/jCeUDBZTpSUTHjn8Sb6NwU2XnzmJj1FIC79JSG4MulaEYvT4YTp6dS0ew9fgc6my1U3Ts2IeQenFiM4yl6sq49Sx7jMWIco3UGurNoYGlYEdwlz61E0hy59oRomOnJJ90MPAexsBjNG/cGfAdbsrDjiinn9jvWum66DpO02l2YFCU6fuPjv1C9v8dIOC/6CejLD+a0KfcmZXDoGuVikjnvFvW1TXRudCC/LRDp9lmObBxPVkxDGW2WjE6eEz2QaXq4+2URFknwjcxYlYs46PpJroxt2z8APcBRRg0eQI4281xaa6D4Vqmdx8d/JXs//AoVnJ1wXemvHt4fEB1dGlypKUuaqgFHYkg3EBvOEijMSnY/kFZd4Wsc12Zo4PHZg/lmehEDuyzlDx5SnLbhMo6AuzU1zFvJngQIhYzl08D8hNBo7RRZHr70cFj838z5NHgkAq15hHQFwTQZMpg/9NBI9RGiTv4NLgvnVAxg0WS6SlEx057Cnfb99fbX2yIycjfmVxNH/S5TVRx9OFAB9SsEXmdv6NfMXcIUP+zOjsUUaanER088mms13uSNPsy0iQMosRIafSoAX4ZNZmqoykGyXYXpZa21XwgZXCZcp2E0bEjc0+2Le8DMqhvOoAYhyBpUnP0INXI6Jew3Y7dUqsDTphvs+cu1zqIDh6Z/aV/ePc+De7flZipcL/keHvlgMZAj72jKiz3fq97boU0rVwInmrgse5yXYmiY0c/gER96pFSBajvSktLubsGS6bJqifYCjHas+nbbAvteLoPkq3OtO6jY6ck/+Pul1QLb772HjYsUJFLCiaYmnTc2NQEkUfYEWcEpYIzZ7Goi1xbQHTwyMfwOVW1ZtAgV/HupQkaBpszoOj5000FcAGgRa0ixlluTpfAfPtfdOzI5O+2ZJxkjR0OCggNb9PvubQYqwYNU0sfZhSA1Si1PolYKQezTVBQQuOCR6f/+WPSBFWWuj7Kv3olWViqfxnx+fhRIGpChmwreLMMZyeiYHefaQOIDh6d/bn+SdoBgmxTb3C+TbTJ5waswP8uEEV4MET+VASQk9VZxbKEPsv0HKKDRz6HdIxN48VPhCfQWPuehpMLT6VHjK+80vTyTAh1cDY/1X/kLbPdCGODv5D+H7Z9u9sgKq7Sk9chZ05HkgmsRgOkd/lBBGPaYIhErlrHq2TrPh0yBWCGueZm0bFfzP3jNt1jt94tH66/T7oLUyNCdyBHUTv72XE56cupMjvmTS1l6mW1tXACFHIvYd2c6buPjh6TPFvWJLIj/2He1ACoVZDIBw7mR0zHk/8YpyYiHa1LsBvQ0QQZ0QcyJR4dOzbxpL0OsbXCAlgmSp0FoCxxZuRGnHZIiR1qpHDtpZ5/zEkN0rL1PWNjR2T+1Yzzbrt8/kktoCBKaDvnxkqlEbWXgfrMkxFmiAINNEWYBPDlOCCF+dzYqP/ExU5+Ara+0Am8mlKXAltao69e+5twp/3O7X9gS7aYE1N2bgLxd1AGH5cAm0auhlh07IjH8WjMmPIhaPNBzSt9YStZki6gI6tRkEZQh4mtEawbtvvr+BD4l2XaBKJjR2SeCpuagz45CC1rNjKEraHHhB8CS8qahjkvJ2LHwb6dHEmQCjLlHR07Iu+3fvFBo7lrjT4rPptkiYg41OM+cqGFHwsC3vToAvn36b27GeXa/KNjJ+b/KFE0PRIEUxYBOmSt5NcWX+lzzWxom9AA5MSGJFzQ+IUlHNeTQREARa7lHx37xYfx+fbXjz3PN/AKcIUo8YVZOBBxVdAqJ1neIY0Fzkgb5Eq1AOyKxwi0z3YaRseOzD699nWlCWxoNi2z2Sd1Bzd9AhC8+EADoKmXqcYhmk4nYTfm2gCjY0dkf/3wpsYP5aK9onqh1VOOuCRlLd2RIbcPYqJqDjdlOnJSKPMpZOt/RQePyz+17U2XXMEPxGrg48rT6nx4GOMO9ABYjzDLjH6rTjDyss/n3BAdPC735J4Xfgzg+EqHs6tNvIP6B5/SaZ2CdpfbcKBZaIqcXckQITKdgNHB45KnxPhAkDbpDsCWhMZLzY27MeMg9HLRpTTi4Ujvg+dEiRoMNXpqeme770fHfiX9i2fBD/99er/dO/SCotXV58sP85frj0kD8RZx1KfPpW7XkQtsimFxF9L04dE6Q0Ct6GZaI09Pw/0g10Q0OnbC07g8hpQSgN0srzJX3qDSaBqq+se0AQ/GtnMkgkwGPcUzOA7/MNNqiI6d+gAev4Ok59CpfdjxYpEoCmZm9Sw81OnYtOgExNyZupmT1MdsvCuzublEx456Dhem2cKndppvuZvcpgl3QgA5BUy+XA7WYiTcahoQTB26gKUHLV+rfjlB6hubZ6bPYYqNHfkYLrJnW9pyKELp10PIIIsQd3MIci7WKUek4XSybjvFvxIL7f+N/SA6dlz+88fbJD+jam11fzCpNFQdCFvw1tIqMvQoB/yCINOtUDw1wk2PczVDo2NHpn433SxJJvXGXnz6RppQqCQk0PCKYWXKzeqvB01SOAHKKcWBBKBcnGsYEh07Jfm0z55hHT1mhj6WYLFrjkKJkYoiAVbTGbD2Tb6xT080Uw8m07KPjp2W/tXnu9uHbXlIgwQEtbcyGJSimmPQB7MG4B/ooGDqMNsVLQoD4uNW1OoPZHoQ0bHjHkQwdLnaL85eN0vSaJD6HbaxRijJEGILnE1sCgEP22Iawwox8y3qaj5419BDuQ6B6NixD+E4B9PqgaYoSU3gnged101vsCeEx7i9CCb2tkqaxhPI6HEQ0JPK9CFwyIiLHfsMLqiwpPTpRdHohxPsicStPMtprLDwahRHremgYglMdjh5G7lEZ6uHooPH569LMC0P199fPyStBCMhBUAQCRzMx8M1ydFI6lfqu3GBe7Ny2ejw+Ao00zN9BdGxk57CGyCCeBFGRGCBDeJUu+iVLy4GhiZ4AlYBGINbNBn/4yF4ZpkeQnTslIeQtBLCYECWrsXIMRvgLLcO3QOVAo6lvbG8oIlPDfOy0mDPlH508Oj0P093ATifjB12Gx7UAlMFHjtO2N9A5PxsaKbSpenHfTFM3Y3PT83SbCIs0bFjn8LNw931/MXV6Cp0ULjgXi9J38RCaQnjFmy+cijAidIV6/TL1UnDYPNePQ0UzBOQ3FaR64SMDp78NJKeQYler0VOkmMmMmBihE0FQ7CMXGDBJjvY6vDTcUC6POQ6IKNjRz6CRyh56oUJO0otQHyJo0tLiaavgwOqnlE9852a+UF3vo7y6B11yBSZNobo2ElP4A2HA72/ZWODa4Lk+oQ6xeIryKKTXoOc1VglmQ1TcSwFCka5bg7RsZMfQpobrLORDTTJdHvi2nTGSJDjqmbz9GIHIVpZ4BVn87+cDhCxsd/wDB7nitunzw8/fD0yENJTmotBMR7lVMdZ8QRcxC4Y0ooeZQNg1wbjyMbAtTuYlqHyzbRComMnPZh1g7T4IVVeHZUAkExruYC4mu2P1Iahr8iLw5sYtNk/yTcsx6Sxy+eWER076Tk8fhSpO+ZGVXx3dZwQbrkhLmxSuyUcIxX/FnN2UFyMxOkk2JHPMTU6dtJzCKyLlBWBaox2SFWOjUSwhKrdrgCsG0Wjv90hURUK3ck1O1jIZloR0bHTnsDtXZIotXKZVh+Y2Wb2VLtFBfevyS5AwnDTdQ3Nx5kW+1MhCZuWjY4fHTzpEXxgHJTyESCZjCB4rP/m0G7yPezAKEgnCilNtgEkCymvOG0HBE4zfQTRsZOewMUwNuURBDBgEV43+xR2b0WJhLUSdZshT1c0vNIAZlFIP30F1kEuGE507KRH8OctqbMwrMFNJzSXSPOWhEw1mDcGSkoHl0l+O6jJ6Ecn8Am0QqZvIDp20gNI1uceYW43pDJ9haCXDncQektBnrptIM5DWb13Oq9HX4F+faZHEB076RF8+lHlNGUpgGG0JIx54u0s4wgSTBvaDf9wrERMND+Q5mhOFCQCt7keQ3TspMcQFPtTnkBXdKEIIsyPg6TFCo6HgxQIiY3SMWi6QSrDaj99CDqQ2b6E6ODJj0Dz/fbTVfLWSMh4ZKrVsRPbiDc1rs2OCRAt2yODmgJb0Tj6hMn1NMZcM4jo4ElP4w1AbaaZC2E/ZBOYVBDtBjBz1H4L5rFcSkL1aOcoTjMIqsiZNofo2EkP4RGsk7Iugqc6NoYL0wyjTuBu7VQM+i79RPYPeQtZ17juRE/us+0M0bGTnsHD9D7lAdCWC13GhaDbRLhBxVA5JQi9YS4X5c7DY9kN6c7w9GwCwNGx4x5AOkJ9oOnofAxnYwBnX6A42m2kHvmaMLCwX+o+nUXtIDQyrYDo2CnJXyWWSByzfek1I4uxVxxT8HJVouwo+6andQ6365w83ZXIwebqr0XHTnoA91/m++Xu+vPD9W2So4erAmpyhZdfTf5kIw3olTcfNokaod/029RO03iScmNtlOlTiI4d+yTe0kChY9kz8SlQ80jabWE+Gnha3CzC9I2Vywa7ArZ7msaOuRpJ0bFTH0BSu31BTBk6wERcTdPoVXe9MIhswyhywlnQfsXZOzWbzStznYfRsSOfwPUdXAYA55sEnAI5HU19CHuAwmieGJr5OgxYVlwGp6G1ob1y8iNl+5NpLUTHjnsQqdwdHVP6NLUtwMiFdp2yj3cbpyHsHcK3I5DeQsLlDNnPJnkcHTsy9WTBYzPHlVTDwP0AR30zclECovIZSm8+AGsCHsOA9tgCNJpykVWig8dlH7qGb/v42Rbqljr5gLVXnh8bsJLVgM+46SaDK9YwW6euQTO02dR6ptjgkQ9B4zBpC6TSB5BDyJgkxbBuJo3IG9vedfwpyd42rSmDHw5sJtRqNuR+dPC45N9/pa2kDZoaE5RRhiP1aXhtBC0XxJWqq7kClWNOEX1J0vOoA9q+ygXRjI4d9wBSe6a7t2uS2MiSe1212OPRlTUN4bBHdOYW6MJOcL4PZuPtRceOTz3pwy9IUA1zj6VEq4cwpYpkrk3WAiKTdFvtbqh31BxcVVo2uaqf6NhxuUNk394ldYrRkoKvhS0P0hw7b17ItVUWAZCiy2FZTota8CRaR7w3V+ETHTsy+U+fb+8e0jtCbCt1fehzqv9mbBXqdbvZkfqXXCE/4nFveuJFp2XfZuuFRMdOfwSP4+WvmIOkBcGAnOfB6gzsTZCnhnYhISNHo2UBsIjIOgXLvxNcGZ4/Vw0YGzvlgWxr+lexUO8qcZPcDCeOD8M0Tqjb04TAYapskTj8SLue2+fZdsTo2G95CEmfAtG+XSGkLwiNhrCxFY4IfXOO7RCsZWiNwuOdPFAYfua6DkTHjnwKN99PH6/Xq7ttT3oEzn4qzrDahgREC/AZSZovCAwuh9xhAsmRzG1z0rOus+ndR8eOfAT3QcPiQttJ6RNCJgPZMDghYsIRiIjFHhpFrU2zpGRVg3HTeDs5xGE65+qPRMeOfgJv5W7V1OxpNwbzU65hGydvwFwlM5AJeb/Wponlydv+uCEB4WTaFaNjxz6FxHmyOerO5YOUx07HotlmtK1A5x0UjQVhY8vCgOlk8G3unCv36NgJuV9tyRfkMgDxbP/0GkLC+gItgHZZD8aLJZ07oi4qhfbokdkXsx0I0cETnkHYC5btZr2+SRoaBJT2qCKQK1XzDUfDFAE2eYbQBckj5obHaKD6tAyIH2cjskUHT3oOYXRE5SttqmqMag9A9DdDxGok5wq6PbBPJH1cE/w2RqgovxwIg2CLnWtXjA4e9xwSJwc1C6xWP4Csa1D1UywHFw6Toqac8TfYIumYEHc7dkLCn7l2wtjY0ZmnFQMN0+tqofMOQuRdo7IFs29e2NCoY8HxgzUig7RT6lWujdBQLi52XOrJgJKg42aPR8opN9hsdgbsBjh8VDyA3BYKQm8t0sYh7QC1nYuoEh07IfekFx+YeRu2kkYgSRMyvnSMTYg0C3inaoXSvDMr6E7JG6Vn+uajY8cmf/P+S6qQATJGDz00UyqBKerNRoKMVTvS+YKtNUhE5XJd/jtXi1wvPzp2bP4XSYs3oCaWgKSk4OlmCG6tzNcdJzvXb42yuFi1EVwa+UY/rf7Oosj1EcTGjnwI187+NHE/XuD0rIKQWzBxmQ2IwKhXA9JdZ3AmeoLN3jgMjuzRdTJlHx07LvtP092fr25uH6736wVD6fYmaS/Y7HQmpQg5Cr9pbPWHQwFI26nWLvBlFNpGxqjnzyDXg4iOHfkggqp70l3QGnC8Q4a0k+HA7qyrg+kdQ9im3Dq7gk4abvtT7iPHxEwfQRsbOzL3t8AJi7EBI3TzbcgbBTfANax+12OOR3UfNF1BrPngHQUAFmum/KNjJ+af9PGjbG88HcZgaIOrqLLTDTQz84s4GNS9tcYGHnCnCiibnnN07LgHcLM9/MWU7C2XQWaoYL7B7Y2g9YKZFkQuiVt3MMXmhK6GZH/Gk8oVblo2l6cyNnrkY3jrPsgYWAufvUUNKzgtde0K4DQ0N0TfJm6/6pERPzqJ+ugrZ1oL0bHjnkHA1KoIiDncJ4kdA87Z7MAEV0Y/O6fw2cnQoOz2Fbk3pM1h2ChcH6vB9CTXdhAdO/0RJO0IC/GCKSDJPYKF7ZcNsmOkzttmIOOgOnAm8H07+R4VFMEyfQfRwd/wEGgaLNvnh6t7Y6WUMxJeaieDx/Wm4SBPAHff/D+iAEqYsVIluTMRAzvtDt0w5CoTo2PHPQ/U3fVTUoGgLcbnYmCARdCHcfrE9pTmXQ89AFoKW0YGFQj/JIKdD0IRHTs2+SS7I/hxbQ9qPgE95xDUD2H8AVdXqROQcRyXnfLtVBroF2VaBtGxozNP2gLQi+Tmpc+MLsEHSRFT8tIuR1Pul3Kle6dOOFGu3ByzyZ1GB4/NPVn2fKDxy/OYnF0wOzI2BpyakSu61uV41Bk2MlrG8xC9GHN1haJjJ2X/SK5IxJMj2MGP9cHwEVRQh5hVfN0zPetYIhsQ1SyPjEpOjH1LJdMCiI6d9BiSFgFzL7B+ev+aYEHsdEG/CzsAzumKg9yMFKiapTqt/7rJhaCLjh2b/qfb7wOG7m0yhwtJFxRMDGSdItdCm17ADuDVUPwaAiuZRO6ynyRtsFQzfQjRseOehNnA3fvpb4lO8WVo9pOyKqgWYFSoijceMPCD22KnJgJM6A/E+GgTl1oHuUqA6ODRTyBZBRehYABiaIzFxxrJjv9d8L4L6r/U8U3N5ovS2QlSA06R6QOIjh2Z/iOpYE4qgia+b3a/icptT9AJ4cxL0SkEpEJIpgJM9BGc4uyJnu1AiI6dmP9d0maoTU74mNxtcDnj8wRGbSIESRU8iXikmiGSuirPPbJsqlbRsZOeQDKtZKJ0HlAzPbs/Nsgk33DKmm6BMAtgonYErUIzO7eKhlwk7OjYcY8gsRAYdIVrFY9ZAbiMaw+fr4WvlWvyQJkCzhKpoDvLPIKfZlr+0bGjM0/67qkSrXPQHyk2LBpOjDPji22pSlc8luj46BsV5OnUHhuyud9Gx45MfZs+JeWOLKbMqzbaG5WMiwaCcGuYgATTX53RNsyOCKEefXHdskyvPTp2ZO53aRCpbdb21/aZuyroKgTznRZchMpzQ6NqAS7le8b56EgdyjxT6tGx41L/y7b9+eOPikRKwC83Sc2PzgRIyW/jH+x1vMCK2umvC0TbGXqqY3llJ6gPXARNmlxHf3TsF59E8Dr80fbkjiBRkvAEGeNSqYdEWI3OfYRS12HCtui15UD6fIekZAt0nHt0zrtcu3508Bfy/+OJRHmVaP2GQIgp6c5DgQb+xVhE8w9+yyv2b4pMOCUGZgeLQCc72w0wOvgLyf/JlncReP+0fZrTxLiAgaRGTELbw0s2CwEQptSmLTpNNXpxz/2SFcqxA5iY5doBYmPHpO6Tv310gEjpec7uOcydu5muPSGBVTMIJnDDFgSbQyaceWCxgzng0h0thEzpR8d+Lf10FnlnDDo3ldPeyAtcnMnfVmmDWP/6QfPYORFtdietoa7NdeePjv1a2qlESZtYmGpghrC4RR3h42DmVdKw5/c4zJpdweyyPQ09xmxEyejYryX9Ybo38HnLp96ZdyjmpgZbkpA0IARkEGIELUZt3sU0mOsjz9/TSs/GF4mO/Vr6F0f31D2OeSGc80JabGTtrtRb1kAAQJANqZvq0PE17j4v8mxsgOjYr2X+mHZSYQvo1tEP6rVxqgXWixwtPuwK9dga/HIybml5I8scbxxhOtPmFh07Mu+ru9uPae4FwbGTlFYQBQJ/QgzFC5Q4fYwdB2ChNWfrN5I+QT6ymZZEx34t+7vt0tFM/+bpprm49y7wNDGq8J03GpkqOfxAwEd2PS443amV5WDLda5Hx47M/m37HXw7SfYwwqJODvytkFnMu4NaSnAxWkipFWBv58om2xkXHfv1J/B1q79O+/gZ1y8ArhUZVUYV4V4H6Kl9B+0UNIl3gBcX3eH08Tv+Mi396NgvJf8hjHCv3iqNQgiJYFqlrpUrVD9D15pdk2+BWAorE6uCy295kqEmM5op/ejYL6XvHu+YX77cpWEdcduaAPQKI2uABsR3VR6lnKCdtnMtYeJCjvu06ktyerkKu+jgLyT+b/fb3RuATQu/BR5USL5IbSDdHOtoRY4z0NdALQvYx81+2o7apgLyaHK98ejoryW+G1zd/iVxaAPIvmvjEAJT0QyalNu0aOfUZjV08/RvK+MbxvVP51xZmGJn+tijg8elnkjqqRa7VqHIqXx7iJ0uKZBM2hhoLG43qtxLrXfY9gYp4UyZR8d+LXMl7Y/sxqs0ASjWC+3eIfFsnRYSCENbcKpi10VaPKgEmt3UFd++pzdfk0zMlH507Ij0Hz/7xHfPjFYhF5qU5tM48KSedOxhdJA+S0a1dnki/NUxqzTcz7Xgo2O/mjzp9Kvbu/dJZf28MlcoYFdd1tRzqhqSoBz3vPnVWp+gE+aSH8nTa+dVlatpGx37tcxxt5KSDr1X/J3KPa4HSJqD2VQYSLu2mtajtmA1aGacOhZ9tv09OvZrSXvT08313y7Q/TecciBpBQdubisWO+g6sH5wFxm8dVYCSAzBfwm2+enFM7PNp48cGzzlISR9AoC6lP7ADwI+iQc54tKF2VtRBh9IobjpoHZMxyfQ0EDKtN1Fx47IPinpmaBPT72C9i320kzhj6sMyzGad+YU3KdhmBnMnET+2PdmSjo69mtJq2S36+/JWaTzl3uo5L1R26wF+j6NnzkM4S18qAy6T2js7nHrqbphuZONwRYd/LUHEOA4d/J/uskmXufYpzjOg3uI4btDfJiQVsm/K3YvCidK34ZQ/IFMMsUask3qoqO/+hhOQ5qkVcAeRJNW0b7a/6A0LXRTGjI//NpVfpYEXUNKZEcvZ8BqyrQMooP/PP3bmz2Q9r77/IM/2SfWi7/6x1+5crE48fPDD5/Dz8EuI/y5P0x+wFUNRrPwdpQINiZaRBwxde1wOIs6Ofo5s2n0CZQOgZUpz+jYP8tzv/7rw5c7HYr4PN23Fa3uZJ1ZY7dPJF2hbFotWmKW5u4KjW08S3cWuaaNGNBxoX+W5vXNw/aeebLT+3id2qr+dbzOB1f343UimqrGNVpZGBRto/dkz54gLotAwGWkqwNFvM4/8OXuo/f/4eHh8/0/vns3fb7+jhrchy/zd6SQ3l32jXckUD5N31/ffbmvmnePv1t75OFv34Ww9++a2Hgv5fbu6ur6hhLdVfzr1F4zOx11GoNxhUmqeQq8EM8jTnABVM86lIzAUZLm6jlEB34x4Q/bx8/GptFf70hus1d66yMZEq78vGhNMuhAGKG8jUcZ+i8IBU/bUcXe5he/4rBR3L+Ljv1ixhcqcfjIonP2dskFQMgYEeussGMhoMFyzVtWgoXrJ04LivGRc5UNFhYdOyLnLw8fEvapreopSQ3AmQhQTHp0j7WPgwI73rDS29YFMdqc9uN8qiHRsV/P+j03w5SsC50Cpyt7W+L6VCMYT0DGcPfVaOK5MJHTCeIxT++6zXcKbbGxY7JOOHltzaFdzr0THg3QEQyKgaXO2lAghHBjKYOg3MnsGlIm15qOjh2Vczg0opd16Bb3AeGmk6eRhBpKRZBg8toRy/AuzEdBwU4+Izpo2err6OCxecN90ZGMTt59kkpeqxc8gT9SyiCFVbNg4mjMzVtBDQbPAP20j2fzN48O/Xrqj14i0Um3xnN8CQ3AlV1su0unGD191fVFLRH+AxG6HI4bJa/CXF3D6NiRWUMDPLHhox/AaEjiXbtVVvTjN5rBNCrYdNrSaEVSyAprnUDG0+5m5efql0fHfv0B/L0ORHT2lFFhWgc2IbyEaL8tClJ95NW9Qk/NNXNG+kR5ObI3NcxUu0THfj37S9M0OultmjUIAblBff3VY9vYzGeg/jGgXzXRySY34yEDo8rKda2Kjh2X9NUDsF985vs4qVB3FUxN/szHrmfWAPwVu04aXfgK+m3bTpwmjbVcALfo2K9nHojuCe+butPGCYG58FLhNIMfEcTdy2KjCqpet8cRQ+2L0+yfXUSmjzw69utZX659V/PddLN8iH/lYQRcEwKvGyRutUs/1jBeBD9UL3qloZlGCfU8BCaAkCn56NixyT+akscnT8oPiQF1e6MLbxBOzGsJQo/uoD3hN556WsVUHo7trcpmBBEdOzb5k69s9FbHe71YKNyAsTbmVDB+M1tRbqq1m0zdgdwaGFqZxwNgr5vp7UfHjn0Any96X9G529jQ1mk8GY2FuXC4StB9HQOXeWmAuBu0bjKYp7Mt28uPjh2b+49CX9HZw+8jKWhIAHrQRCdpQ8Kid5xjb5GAw+qlcVhXxw2d2keuplp07PjsP9/Gv3ioBw0ZCl+NLzxQNfURW6U71e+9RutX5AOx78eqN0rLhneKDv567vcbnWMggOh3XlLsxMvjdhSkC1iO8xUPi15Z10H2Kmt9A/j9T19832fb6mNDR6T9cPdlSWpQIKcDdTL/quCZi4pgS2PsH/gKqzpustm7wrcHopcGcq4idouN/XreX6CdErY3WPUB9azSSsbT9d5JuI5krEz+mV0YELA+MCE9G6fXubb26Ng/y/rf76Pb5dT4JjZm9HgAlWF02Z7SZEDHId6+ADE2RRBmuai0ZWmXR8f7ZlLvprvlg7GmP03MaGc2u0aq7oEvx4JvITxKYBwVuqnu4zRJidFWpNiOwynXACs68jNp3uNTRSbJiYSoODkVyAO9Yr0UreENqY64VtAWDGx6mIVDZ0/bIdcnGh37mTR1hm/vvqIzotMFphx3LQO1xT5xrqYbsKHOBuEQKxOfeGuwD57eqfbpL/52H+cAbvBxob+d7depY8yHq4xqWEmYm1UgFhvoDdlcOTNErQ21pr4FBuNVfSSZ7S4VHfqZJC83p8h3yVWWc6qmHwo4BRh3R2IYkzY3f10qSBVhCO5584GmQ4nM9TKjY387z8VkmfRN0IG7WWJHzRUKlP4+ordtVt/TJJ1TBAbYivSICyhxqILpGG1kU4SOjvxctp8+XcduSNzeUPqWluzvyBq2H3V6DNgrumZNRQCxDm/XbvX08ZI2yNXsi479Up7U3B6uv79+iH2tyD1Du2B0l5OlOY6scTV9hkGR2JpFc4ViCEvj6Eg4V0EYHfnFdL86/0Qu2kBMRl1FzqVijL8WTK/0fHCZB1C50ALqKyOdg8BewlNk2oGjYz+b7+fp7vrvqqMXsSGA/DRqAf9AgLRp4boNZkoNLuJdbRjWQcSwhD4VEA1V30zJRgd/LlnYiZuH+8jXqmrQljV50b7o6e7YdqF8STPulJkA/mzLK/TnqUkN+58p0+jYz2d6dz1/YWV6FRwaTF6vl9i8qfBD7+OtDbTZ6ZA0WMn9sCCu6VujbrG5nEANTqBmbZ1MeUfHfiZvhB12FMvt5UVHvuedURU0Dvs+0twjjx73mZXwCGzbBkJR15RnKqjHp80K4CtXvtGxv53v9mm6/hj7XtkvOXlGIJjO2RoUUEmLYavQ3V1dAEo1s98qTq2ZXGSs6MjPZBkMZyJfJqG4ABTY9QUYjNATMFabETCJZsHmkdBzqStI7D69TBCDTN9udOhvZxngEZFJMgnRYdNQoo9UdODWjtYNd3yyOQPAjFMRBLPWk0Qanl2uG0508OfSfLA+E4qn0DTGISvhfpqaGBZOYVvwT3LNYatZB8WcpiKHdSzPIpvFZHTsb+canEQjXymmVND9YI/FT30Hz2s33aUmHDutilF/qd9UiEczySQt03cbHfrbSV4m/5FZ4gaxfnGNcVsrGOHAV5qPcIHjBNCaejcmQ9ReT80je3GmNKNjv5Dm5cuN34zqlRE6T/BQ60JZbmju8OLtrq20NtxhDQX5H82nMYhreqZ0o2O/lO4FKh/7bnW6AfEYYSsQVLyhWuoo93SmAVi/jbkPIcPm9AW7I2RKto2N/e1k8YAik1wmDe0GWgkkq2NnR7XfdINoC6YbOggzL+yY+eRhxPAlU47Rob+d48WyKDbLoNdQLLLC4cR0UPWWO+FJ42tfrJbSCEpsWzptubkK3yU29HNZPvrzRCYapCY3Y3g4M3cZx8mq8wvG7xbHlIHa3tAR6diPdku2e1t05Gfy3N5Pyw9Xl/ovMlfCyrhpS3CnDw0zinowpMDuk2rQe3ZbVQvCSD+9VKdqpk83OvSLyaYcNFzXHSVNC15T6q6QnYC3qNzBQz0PBV7UZHTb0x0mn4hidOgXkw2oi8gXi4Bp1MZRb+lbw1dG3MXEhD447RYzGB2Ao6ncSTUe4ijTi40O/WKuYQIVmau1WjaG6+Ci+0wFGHSyVxJSiqITpk7aaCM383xgappszYfo0N/O9VNwC4rMclUjBNAn3ADLLHroMxHcmVug6ikowdJUmHVLTyVvtjlydOjnsnwI1UxMR58JMok/wC9WmAZqG/zvFByRl4ZLtH4ozQBTqv3omlVNrv0oOvQzSf4I94zMdCWC0qsUGFhg3kB8EjGG/QQJIo1DGgTk0S38hGTHI8tVNUTH/naqZ3xnZLami62Nx84bjJ2M4KAfXMCZgKOQOW7NaXpQiKP3iz2da8gYHfvb2cJzRiY5rTw6wD1agnVB7UJ3v9sMLnoqftw8CW6VJdHyc4XU54K5RMf+dpIBxRiZJRsWtYGV6cLGlwS0B6xHo4gUN8YvcmAQ/VAP+393f/03PELFfpPry40O/nyaZRjxxuxFs/7QyKSxUwqOi/dHqKi/qC1vQbUMaczFxZjqSNSAJlei0cFfSjTxZroEHwHSRGArhEsm3qs0OnauQ0Gqa1moMbZ0+oZT4etyk6loiI79fL5XrqXb3WeDi9gj1Vwe/IacLJo+PwWvGkQNEL6eAgOSZE/QqQJneXrDVVA3yJRxdPAXMt4dOrFfc2uBtianlRIQkYDaFEgWyYIhSMdzlyBME4R1n3J1O8+UKfx+XOgXMv1qJRaZLO/gMuDs4KxDg4FpDhEGJeGOnL+7BVBgCUokJ7ilMXquTzk6+LfTRePdPl7Hz5HNXahOFDyU6w4B3w3c7uROhxDITVWWk92Z6NDTi83W9I2O/EyiFyusyDe6kL6G15nwBbgB4cY03WCLCvbo2mMF7BlwnVn6U5Ygz7leaHTs5/IMf6qYE4fDE7Du0E6dSnecvcXRwcoem7oElAcsj5sLtbRTktl2o9jQz+aIZf/hKp1vr+FJP4SQv2l5kAYcubthrsIHu7ZBBOyLVj/BpKeczclzDdqiYz+X9MXYKvLlcnoOJF1QM16vm/Hh0qwzbVc2Xmg/RMIY/IRO6VOiAbyUaweOjf1cotF9h6GiYAnKG6olmhiAn3R88TzIgMH/mtVMmobDaW6Kw5Ury+jYz2eZWDFFAy2eauH/bUAed1uQ5U/Md3CqjKBZ1qADk2Ct/vY+YvDgdJCdC6UEU4bhaBf21F4yfcPRsb/9dgPi4UvsVJw2b2sjYjsIjIVSD74C7lBCA3AeAJUNqoU6hacZTZNNfD069jN5npRsIncmLkr0p4P4OLUyo1PyZQaJNH1UiqA8qHn055fqhLerc11bo0N/O1k2OpE5Qpn160qHEnzFWdPhWXKVgcICPSNf5V1TcZP3cbRmE2mLDv1MjliVkUka88NbwR+RVdbjprrINEuzB8qQ5gkGXM1MmEzdkWSRq8aPDv1ckp8+f1T4RiY64lAsxYQ9xxWnDsKqWPGAvq7nIOvIXqR09brPaKRchVJ06JcTjd2Jtg6jwvjJIJwPfMHxAb5jLMmtkRiD9vCu0Wj344pKeC3Thhsd+plMH+WGYupewlk6gSihlCuCWmjwsqMiGDT17EG8rbxj2opHkkFJNVOW0bG/nWXCmMJ0rTV+UtSb9a9AVcwMg5ujXZfgt2IfMdTV7dRecRRkyjI69jNZPuzDVUKq8FMVFdCByLXZaVCX0hYFmauNT8ngFVYtqYOTBKofctUJ0bG/neo33JoiNyWuxGi93GrXcqPXYFsyQKb/GiQsmJYAhkKh7ScoHdHATK83OvTPcr6Z02TgKpduqiRMSYJSAxyzZvfIos07JuytkV+0EEmnpWoClyvJ2NA/S/KiKfVVtCyewGjYxFcbKX8Aci1cXEpkRi6TpO4cNQTwAv1rO2BJqopMmXKGiAv97Uwv5Px4piaDqWFdCtw2UhPtRqhchyWQ+Mg40oyCKVwu3YenqgHeLldrJTr2zzL9QgjuWJgvat2hsNXhfNEsIlHbwwlqfRpGrYAc9iGOQzAPZRvKoizkveh430zq/x8id+H1vUtWtzPxRnXiCa9BRE1W029W5WpvBpV9o0S0xZqdxtOXanScq04IlrNRsb/9UhO4pi4o3J0N2eYw8nXXrIJKBE7mFhorGHwAdVjjAc6Q5XONjvd8Zu/oxG8PV9tfJ2V8bBFvzr8aGxI2mkCs6PQhhSCE9zB0+vUUKBtMcQzNp7dJ7ShXkRAd+6Wc0TKNnK4X95b1Uh0lPgANe2QgYMBKDQjDQhgFJYzwTdipiCFRBalajgnHA6AK9Itf+iNJMzr2Kw/giZeamDsQy2DqRLCwx3rjY6/bXTQNQUOCMOhSwQPKIj86LE22Myc69Aupf4X8JiZdDY4dAqsLGme5mpYDCXSGUUYbtDmNGkkFtxbD8cLrbFLJ0bFfyZr8auIy1+Z2H6dWpxSERrPSNWo75BLGvepkHQmFxsm7mFBGrvKC3kpc7JeTxobbErMefcaEKemZkfCqbNk6/q7x7rM4Ga1SkR8ISN5pbZdgFJkWd3TwF9O+0KUS044elf3YEP/fYkx3KUbCCf1ueeSKhbn6j4Sx+8RHQLHRBxy2cUiYTX9xcHQbhfgV2tH0eSsyd/yOjkU+DrkmINGxX3jxF3h/Ys5aURRuHFks2B2txrFlEDAMhQv4PwCqRwI2dBRmgEOZvvXo0C+kHFhWP05CEjMPbKuKpj1TF7rSrL2sbvoZHWUv5xuorQ+g5gxwOsOzWZ5Ex34t9bQN3UG1DcF1GduBjJHhNAANeWn1ONoZeiwretjjE2ac1Fmmtx0dOzLlq3vKGrFklqDN2cFIMeoMx1cxwIq3gCU6sZM3baBLAB+s87Sys+mTRsd+LfEPvvXbOyyBpFrdzYoRL3g1K1omN7j7I3leUwWjsdJUjBovYuWZ4V1bGJleenTwF3IPrLvEnKmTzTawoLLc6OLZ4YbOSQ7zpmDRKykKU25XkqfXbSvKlHF06BcyvjAjrqhn+PPFNOFhVOcRb4kszFgRBNpgUMioS7XU9lqr0pUBUPkE0W3z6VHExn4132QMoCE2WA0pTorxs08Z4pyCFRfaAglxxG7XqMdJPGZmjdMs02uOjv162m84tE0FqUlTe4JB7/omtE+Iz/m6qW3vtNSt6b0bmuMKhvifq5cbHfv1zJP2MaxglAkE8D7IkLqCjQi2K38PmEgqy2PQKbSpH+Dltm9y8WKiY7+a84W2l7ibsZps127Q2VWYVCvLAP1eErSctckaoHppnaGSnPwCylwA/OjQLyT+8XrZbu5Tb2EBwuBwpk4Sjqymo6gKEtkRwfJdY4LNXJdVKidwWT5j9ejYL2T9pCGe+LJNJ8CwjC72KkhFBcKtHc5Hj5cwQfoqW4KDz4mJwHU306YWHfuFvM8Mk8TUKUlPM0VlFlz6pLxsEDehuCt4ngEQtujwVwsT9aNI67IVKtGxX0gd3SQx44uDzwx51Q7lSAatuKjxdORmSzbbLQYKvF1x6qPmExiNDv1ywvcX6fDEtIceV5VpNN1w6EaN4303XGWwCfiBkgxnyTTBFvf0outs5Up06BfSDowbcFl9hrRK3Gdspl4EQifgAAIDKZ6RwocW6tq1Oy15LHTYvKe0u2xw2ejQr6X9FcyfmDlxvwop2xWEiy45XdNn8lI2dVeSdd2XMMMLl+1jZRdDtoIlOvgLud/xI7qjg5f6ykvi4IDC6Bq+b4u9absajK1gFQ9QgOxa1WWFTXd86dk28+jQL6b9+TbxVW9jg3tdUzq0jyPy7m5d+zZ1A5c5JavtnOAs/utpEyeJkukAiw7+Ss4X9+TkqVjQc3G1NLg0iFeUaimQzEaIZai5eCLU1LRa9mNGQE88U+LRoV9N/JCHT3zxmDoViXAaaiQfNJNJf7mJoDobmijX8dEo0QIbn158Nt5OdOxX0/8qkJ6Y+2z/qjeyC5MCZsZdD5cSoCGyTj3bbJJGPVPhkxWIZlOubz46dkTuyasd2I9+nA4qiBQ5rh6CaCMEtFAtoAuEDW5ObBGcOuZGSbkuJ9HBX8z8jKVPfO1sCWGK2LY52LrAk9tqdghayE4z2HP3NHrTnsrTJ1/RgM204qNjv5D8/Qlwnph6C8jRQsu5lVJ6nbDX2P5ov9DaNkAY6aGGXzwNge0NmTKPDv1C5m8oWoMaRRXqNy3kxkUM8T344dJWBHU1JkALatSvB9bKBpgp4+jQL2UM05v6jhlfBw6i+XNPDwmud0NMDCjQfXeSs7bDLVjqkyydfmumlGH642K/kPIbcB0rUAeIr+kIUiZfJ6yD2lgMyIORWa9WGzqG6PvpEMtnSBkd+7WUyV8lvmkEGUQ+al4uI8y/A1IJgJBRHRUL8zEgdedVsxw3E+zcTC86OvQrWafOeksbKMSGqV9T97rjWPIzc2QA9hZyx05OfgY34cCIBuPKTDlHx/52zuk+qyzyQnucKMDuCtIHsgXbg4a0JFGwgpkN+RlKsCfyF3WITMlGx34p2TSD1XU2sSeqoxwhFsW7pV7cugiXwD1rnTGDcPn2K8e5TDcrU7rRsV9I96ujfTTeOYC60Sw6hAvt8W2o/AWSxnCR66BZEI9vq/picfGo64GBnWveFR37hXwTnWQ1/ZGH6LjVQUOTRTLJebVXE44MAksXUDtVsOOe5cnkwixEx34x3QQL2Rp0Hd5o6CamPGb2dbdypgn2yEGluyRPuHRmX0cHwWmda+lGx3452STvWPsTah/LBBJnU0lRVKffr2gbadF2WLvYjNqiJ3Rh32XzkowO/mrCJ0WTeDh/YNqEq7M1yxujCIW0mVfdM0/wQQfkEf71Mh69EyjUXGdSdOzXU083nIKk7cL1GaiUbixPe3/bctB0kdYdpwZsjNt1xz2KumyuBe16Ghf7hbwv8/r7q0TP3HUAn2UrEF6urqAi0zYtecRl1wvGCi5RY7+dOmUN65dcx1Rs8NfTfoNbLpMpPZFOx7sK0mlktuzhLlCmfDwVG7xIksnNehoAuFJnyjw69guZfx1pJjB1UBtwBO1lcFclke+FfgSThd5cb9Eom2zaRDznk455NiRtdOgXEg4olBSv1KZchkViICk9TrpegLHevmiDbQukNMo2YA5Ry2PUoeGf6QVHx34h3zf6IHNp2uk7mstPYfMKkPi+56KhAVoVOgRmHnBXpw5wSY0gU9rRsV9K22Qr/rgCIJSobMnIwcIHlzzqA+a2muA7eQBk7i3MbI+Obz6Gc3TsF7JNs3vGarn4/FD9DjlSbnIWBwqE1o/PuSX1g6g2H590MNbLtWlFB38l3USj55rYefDOAIUNiKpiabxWF2bA6GXTGJpnsqb9iaxvjp3rYI6O/ULKiQ7PLsZSC57dIzwV3zyM2GBjj/yrGCntXmYbeD9PH3R4+5mWb3TsF9J9tHZOdTfeyBRoWQeZXRyXMITf6X3iCq8N0GhFt6p2Rp2s2EhhZtu0YmO/mvVbbI1b7o+oeWQiy65ERdxYAY1AZG5WNrBRcz+Q9U5cd0sg0+uODv1q4smWvvoiRKvgVBtS4TUcAp3/sqEHT4OusJdDHoX7xwlIZylkSjs6dkTaKV6+W20C7w7RhOWt/qISuQcj50tnSL6BzkgE/2iA+STGXFjR6OAvJH2f6mY7NrTJfN8MbIlhImiuINFUvBh3m0tp/jGVafrpuF2YzOdKODr2SwmfZlPxJQm/XsOYYM3HrM11UkubLj7pDns3nz46oWGPG0/zSEOcTN92dOwXsk40722R5JSahHx3AwpzWJ360AMEucBoqcwgw2k9Hc0S6KJsO1hs7JfSfWB3Ff92iTaEMqsho1M4rsqV/SLkGDSRSaRcdbZ1AE8kzKrPpoQaHfvn6aYl2XX00teGEj7wK44psCd8YIBI8VssVCIr1Jju0FMRAlGTq+EXHfuc5O1fv7u+ufbHiaEq0Exv9eVBgehWSAowfaP4OjEYR88JIvhY5Et9HrC1ubal6Nj/8f/8p1/Zb28u9PBf/eM+fbzf/uN/AZB91kK0LAIA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Fri, 29 Dec 2017 00:38:15 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "57", "X-RateLimit-Reset": "1514511495", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"97f23592965deea04121c4e28fea0018\"", "Last-Modified": "Thu, 28 Dec 2017 04:56:43 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.058486", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C628:8329:716D787:12DE45E0:5A458E77"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2?recursive=1"}, "recorded_at": "2017-12-29T00:38:15"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62YzZLqNhCFX4XyNgzCmLnDdVXqJqskq9zFZJMNJWyBlbEtlyRDGNe8e45+bGxSgZlRNhQY9aejlrrdrS7ieZQmT/HyKY7nUU0rFqXRgeui3SWL5hzNo31bllv/h+KHih65bNVqTSajxKlmMkq7qBQHXoMxHgqKmWa1Xm6S5TyiR6qp3LayxLhC60alhLiHKlk4bKuYzEStWa0XmahIS5z1t+OPa+AO0kMMN8KDK1jDPccZA6bIlaJCV+WVBje1NbkavBdlKU6gXKu+NxEZLI0rLYXXh09SYNkRoQsG52FJb8YRXOmPi7JWHXZQ6S3PDUdhRyTLPyzM20GWOQBvHZGsERbY7lQmeaO5qD8ucGINmpAHWvNX+jkarBUgRtrHpVgrWLMjzuLHzZ1ZRxrJjzQ7G9dIljF+hLM/ibyyB1GfGxO3f+BQGNdzzbY0r0wc7mmp2Ns8stNrDLIP5gi7957+aZznbNhVTPj9rAtRz0q+k1SeZ3shZxwxK/c0w1mdnZBHZjius1+4/rXdzX7+/tsxgUCMexmU3Ixc6/xJME7lGNKdPbmJQHgCAEkv7BzEMfYdwaePpwyhTndCUi3uJY3bAiegjox/mrOkGa2ChFsAQIUQYZ60AIC4Ui1719G+vXDLUaSPn7qtdi7lvSdqbqMdAVqpQp6vGQvy4ADpSJ+VEQ51VoRhe0ZH3De72/QQJNXYA7MrxS6IgxclsZCOqIK695DehqozVMOYQCXbB0s1jAGqZeB+W5kGMiDxEtTY+iCdPYN03qMlrQ8tPYRRBwh23byqD/T1bhFzO3YuFCBNhSb5rg1PcheOUepqB8R7mEsvmAvUFiS3y5w7DhgVNtYFVcXv1QW3iR4xOfb/A9ac02u0+X2/jLkv1zA6csnJLul7eoh3fdbvdY7n8O1A0JHoGaT7oaG6MJkLUzVUshDRHkG6HUWxtVgsuoJRW1ZXTAZGsCMARWVWoGoM0dn1DFQ9FdW2Wt8bmTmq91LQPMi3AwRAt40hWh1hvP8NGtEggRYwJla8ZEqLOizHXihjdi003/PsPR3L7XCbgLpvitcZm9OynOPUap5xnGPU2mYXUXCyMA85ApaBewDXqZQMRzrI65I5Rkdcp5mzphTn4Cw0wpgglgzdTb6lGl3JahmvHpbJQ5w8x1/Tx036mPyJMW2TT8ZsHpYYtnleJel6mT6uzZimVcUIY4fE8XMcp6svHoO06s81vuHiAp+4LPnXpcGoTzFXEWArVVwMf7qYpf9xq+LNshIH9CqS3j/n8fpdd98UUgtRsQa1x+h+xtklzXkBV+do6nKRqQUXZmH8FSMf4y/JelJlZKKtsR9Pj1/n0YlqFMR4n48f9tXJ0EmaqanautiPUi1b06riSSPFXyzTavzskm9GA0/8hV+aXGNpSqjhiesXvYbVBnorLqXwl1E1EsSQaHGx5Htl0bDaa+rlx8sN4o1nrFZYemfaRyzCXs1gDf627Hf/UzX532gLo9TxbcNrvqItd+1napWMpolSO0HvNO/DnO1pW+qt6wcwX45GphSNmZHpEzrZXp7ljasov+IkefsHtUZiVfITAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 11 Feb 2018 12:56:36 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "57", "X-RateLimit-Reset": "1518355556", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"d8f3338b2ce37ad8519c97587c6d67bf\"", "Last-Modified": "Thu, 08 Feb 2018 23:40:54 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.051528", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "B75A:9220:18A1FB6:2DBB4D6:5A803D84"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2018-02-11T12:56:36"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62Ya2tbRxCG/4s+J9Ls7OzN31xHaQyNBLZSKKWYvczaIpal6hyFpMH/vaPEqU5oKWtyhD5oEct7Hs3tHX2edHdxcjYJ1qEtCZxBH71LLquK1nIhzEWjAgfkIOPkxeSwv5cLd32/685ms7hbT2/X/d0hTfN2M9vzbtvNuvXtJn5Y7w8d0uzrt3q6+3T8OOv3zN3sGXrHC5Oz3z9PdrG/E+Wj3Pr2YbtneZjNtsiXEwVgieTcf9odz+l+m+T0lY1VirkmFBRXmFVBilwNloq6uKirI0KO+nhh/ZdcVwZ+GPP4BN2sWfrxxYmv38tv100/be4bAZNhn5VzOZK3ySjvrS5BEUYyBoQvKFdDiCdApcxIhM3aA8Lzd6s3y6vr6b7rGwlzsBiTC95p0Ey1FEBrGIKGGG3wygaTLBwz4imEnvxIhM3aA8KL5av5zfL1zcVy8erdxWq6KY2goJKXTK5KxxywhlwQORRiHb2KTqtCznv6ktxfc1XgRwJt1v4OdLG6uvzp3epy8fMz4mkCJAQNwdYsRQk1MOQQ0ARTtQqxGsBoK/yDqQHDSJjN2gPMN5fXq+XVb88gTEIkpRdYsQtRSlO7VCRh0VYmdBCDNtmQHTQdVG4kxGbxAeIv56v59erm1/nV9eVycbNYyvEZvE4XX6OmZCWALlcCVypVBAu1Yk6xRkAdTk0WwZEdibdZfMh7eTFfXM8b61LGBicw3lnFrF0xJF21aKFlpkRGS2uyPqhTODXhSHTN2gO6t+eLy9cSz+n6oZVQk+MYVWQjjZWBIPrsoo3VV+0rK23kbcOpJInGAmyVHgLG91zX960eAFIwxTHLOMQSLOdqSsnotVMYZG6GKsE0Kp/o7Fjha5Ye0F3Nz1+9nT+j/CAa8iYr8hGl9kqimMTTuEyMXmaK1pBkqpyip4IfK3zN2gPAwh9e7vnPw3rPG37ou2n/sdULJLFsYt+SkhZjKfqovZhWUo7YscVQ2BvK4E+lCGONjmbpIek2d6cSlLKSl5yfjOoXc/vNqIKHKs6bJSUtKPBJFWMTRodBqWK1DdkaFapcGMWEN+sNcPhj3Ozu+eXDtue03b5vZUOS8pJhT9lKLspKkZXJqJ1HL5MetE7yy0R9LMBR2Jr1BmxPm0pjtMSLsVhtmW1J9ofovEz7krOV5slKBYHF6tgcrdooRM16A6L1Jt5ya4i0KeSD1gSy+0XUqWYXdCZSIUBwko5ZgWEzGlCr3gDouF/u+5t11x1YNspTqGQDdOb4aP+1AUbrQhY8STrg4AClV5Am8lVmHseKEjeZ78fCenLV1o3VHZu1B5Qd94fdNNfb7/j+b8M1XhVNOSpjSvZKW/beM1n0NhalsAp9OrVEVPqHs/Lbhtso/S+85ujZ6lP2hAFRvGRhJNkcSnUAKXlUPqaMqvIpehLesRb4Zu0BXs9d31pziNLPOQUZYaUoncU1ikchkz3kCiQNMmKEfPSVozSRZr0hz/aj2Mh1Yy5KUzfWGY1cMmTtLMgOlFUsWf5QysUoWWN91oN/W9CMtQc0az/+IY1if3jIsecyOavxvuPHvwFOarX/DBMAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 11 Feb 2018 12:56:36 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "56", "X-RateLimit-Reset": "1518355556", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"a4f13600f56f075736319df051d49826\"", "Last-Modified": "Thu, 08 Feb 2018 23:40:54 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.035455", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "B75A:9220:18A1FC1:2DBB4E5:5A803D84"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2"}, "recorded_at": "2018-02-11T12:56:36"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2?recursive=1"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 11 Feb 2018 12:56:36 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "55", "X-RateLimit-Reset": "1518355556", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"97f23592965deea04121c4e28fea0018\"", "Last-Modified": "Thu, 08 Feb 2018 23:40:54 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.050494", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "B75A:9220:18A1FCB:2DBB4F4:5A803D84"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/git/trees/96726db07528a87b7c1f266ed42cd321070470c2?recursive=1"}, "recorded_at": "2018-02-11T12:56:36"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/integration/test_github.py b/tests/integration/test_github.py index 975747060..b541dd4ca 100644 --- a/tests/integration/test_github.py +++ b/tests/integration/test_github.py @@ -203,14 +203,13 @@ def test_license(self): def test_licenses(self): """Test the ability to retrieve open source licenses.""" - cassette_name = self.cassette_name('licenses') with self.recorder.use_cassette(cassette_name): licenses = list(self.gh.licenses()) assert len(licenses) > 0 license = licenses[0] - assert isinstance(license, github3.licenses.License) + assert isinstance(license, github3.licenses.ShortLicense) def test_markdown(self): """Test the ability to render a markdown document.""" diff --git a/tests/integration/test_repos_repo.py b/tests/integration/test_repos_repo.py index a40d450e3..7bd8452f1 100644 --- a/tests/integration/test_repos_repo.py +++ b/tests/integration/test_repos_repo.py @@ -919,7 +919,7 @@ def test_license(self): with self.recorder.use_cassette(cassette_name): repository = self.gh.repository('github3py', 'github3.py') license = repository.license() - assert isinstance(license, github3.licenses.License) + assert isinstance(license, github3.licenses.RepositoryLicense) def test_mark_notifications(self): """Verify we can mark all notifications on a repository as read.""" @@ -992,7 +992,7 @@ def test_original_license(self): repository = self.gh.repository('github3py', 'github3.py') assert repository is not None assert isinstance(repository.original_license, - github3.licenses.License) + github3.licenses.ShortLicense) def test_pull_request(self): """Test that a user can retrieve a pull request from a repo.""" diff --git a/tests/unit/json/license_example b/tests/unit/json/license_example index cc5749ae4..530a8da8c 100644 --- a/tests/unit/json/license_example +++ b/tests/unit/json/license_example @@ -1,23 +1,23 @@ { "key": "mit", "name": "MIT License", + "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "html_url": "http://choosealicense.com/licenses/mit/", "featured": true, "description": "A permissive license that is short and to the point. It lets people do anything with your code with proper attribution and without warranty.", - "category": "MIT", "implementation": "Create a text file (typically named LICENSE or LICENSE.txt) in the root of your source code and copy the text of the license into the file. Replace [year] with the current year and [fullname] with the name (or names) of the copyright holders.", - "required": [ - "include-copyright" - ], - "permitted": [ + "permissions": [ "commercial-use", "modifications", "distribution", "sublicense", "private-use" ], - "forbidden": [ + "conditions": [ + "include-copyright" + ], + "limitations": [ "no-liability" ], "body": "\n\nThe MIT License (MIT)\n\nCopyright (c) [year] [fullname]\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" diff --git a/tests/unit/test_github.py b/tests/unit/test_github.py index b4d5bcf41..3219a07b3 100644 --- a/tests/unit/test_github.py +++ b/tests/unit/test_github.py @@ -558,10 +558,7 @@ def test_repository(self): """Verify the GET request for a repository.""" self.instance.repository('user', 'repo') - self.session.get.assert_called_once_with( - url_for('repos/user/repo'), - headers={'Accept': 'application/vnd.github.drax-preview+json'} - ) + self.session.get.assert_called_once_with(url_for('repos/user/repo')) def test_repository_with_invalid_repo(self): """Verify there is no call made for invalid repo combos.""" diff --git a/tests/unit/test_licenses.py b/tests/unit/test_licenses.py index 97be715b5..44592d097 100644 --- a/tests/unit/test_licenses.py +++ b/tests/unit/test_licenses.py @@ -11,6 +11,8 @@ class TestLicenses(UnitHelper): + """Unit tests around the License class.""" + described_class = github3.licenses.License example_data = get_example_data() @@ -22,11 +24,7 @@ def test_get_attr(self): 'implementation', 'html_url', 'key', - 'required', 'name', - 'permitted', - 'category', - 'forbidden', 'featured', ] for attr in attributes: From 9981ea4a432f56b51d24e53ac6367685b4a1c911 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Wed, 14 Feb 2018 06:03:29 -0600 Subject: [PATCH 12/56] Fix up documentation for a passing CI build --- docs/notifications.rst | 13 ++++++++++--- github3/orgs.py | 2 +- github3/pulls.py | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/notifications.rst b/docs/notifications.rst index 73b47c0df..b14e1d0a1 100644 --- a/docs/notifications.rst +++ b/docs/notifications.rst @@ -4,8 +4,10 @@ Notifications ============= -This part of the documentation covers the :class:`Thread ` and -:class:`Subscription ` objects. +This part of the documentation covers the +:class:`~github3.notifications.Thread`, +:class:`~github3.notifications.RepositorySubscription`, and +:class:`~github3.notifications.ThreadSubscription` objects. Notification Objects -------------------- @@ -15,5 +17,10 @@ Notification Objects ------ -.. autoclass:: Subscription +.. autoclass:: RepositorySubscription + :inherited-members: + +------ + +.. autoclass:: ThreadSubscription :inherited-members: diff --git a/github3/orgs.py b/github3/orgs.py index 9aff240cd..83047271c 100644 --- a/github3/orgs.py +++ b/github3/orgs.py @@ -672,7 +672,7 @@ def all_events(self, username, number=-1, etag=None): def events(self, number=-1, etag=None): """Iterate over public events for this org (deprecated). - .. deprecated:: + .. deprecated:: 1.0.0 Use :meth:`public_events` instead. diff --git a/github3/pulls.py b/github3/pulls.py index 7417867cc..703d06aff 100644 --- a/github3/pulls.py +++ b/github3/pulls.py @@ -24,7 +24,7 @@ class PullDestination(models.GitHubCore): Please see GitHub's `Pull Request Documentation`_ for more information. - .. _PullRequest Documentation: + .. _Pull Request Documentation: http://developer.github.com/v3/pulls/#get-a-single-pull-request .. attribute:: ref @@ -109,7 +109,7 @@ class PullFile(models.GitHubCore): Please see GitHub's `Pull Request Files Documentation`_ for more information. - .. _PR Files Documentation: + .. _Pull Request Files Documentation: http://developer.github.com/v3/pulls/#list-pull-requests-files .. attribute:: additions_count From f64a47e03b7bdec727e93fe573e70d9c90270e7e Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Wed, 14 Feb 2018 14:17:32 -0800 Subject: [PATCH 13/56] Update events classes for attribute fetching Removes the use of _get_attribute and its ilk. Related-to: #773 --- github3/.DS_Store | Bin 0 -> 6148 bytes github3/events.py | 23 ++++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 github3/.DS_Store diff --git a/github3/.DS_Store b/github3/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..deb54681a7498073cd7214e5dd8e6678515761f7 GIT binary patch literal 6148 zcmeHKISv9b4752UBpOP}e1RWC2wt!spa9VzKp?2M;$1wA@zJbSbWniCk~4|pNt7wp zYZ1}qZMzVeiO2+QC=VO@X8Yzn8)QU*aGY_yH<#n#blmrH-vx|2mW%AsKC!FVBd!VH>`Bxq5@RluN2VHs#z`Zq^zyI$62i{@D1E@o^UhFor1y3G0@8~7FLeuo)me-=Gd=^ UZJ^T;cRG+i1Evd&3Vd6E7fF~D;s5{u literal 0 HcmV?d00001 diff --git a/github3/events.py b/github3/events.py index b0a4020b4..f8dec149a 100644 --- a/github3/events.py +++ b/github3/events.py @@ -119,31 +119,36 @@ def _update_attributes(self, event): event = copy.deepcopy(event) #: :class:`User ` object representing the actor. - self.actor = self._class_attribute(event, 'actor', EventUser, self) + self.actor = EventUser(event['actor'], self) #: datetime object representing when the event was created. - self.created_at = self._strptime_attribute(event, 'created_at') + self.created_at = self._strptime(event['created_at']) #: Unique id of the event - self.id = self._get_attribute(event, 'id') + self.id = event['id'] - #: List all possible types of Events - self.org = self._class_attribute(event, 'org', EventOrganization, self) + #: :class:`EventOrganization ` + # object representing the org. + # an event only has an org if the event relates to a resource owned + # by an org. + self.org = event.get('org') + if self.org: + self.org = EventOrganization(event['org'], self) #: Event type https://developer.github.com/v3/activity/events/types/ - self.type = self._get_attribute(event, 'type') + self.type = event['type'] handler = _payload_handlers.get(self.type, identity) #: Dictionary with the payload. Payload structure is defined by type_. # _type: http://developer.github.com/v3/events/types - self.payload = self._class_attribute(event, 'payload', handler, self) + self.payload = handler(event['payload'], self) #: Return ``tuple(owner, repository_name)`` - self.repo = self._get_attribute(event, 'repo') + self.repo = event['repo'] if self.repo: self.repo = tuple(self.repo['name'].split('/')) #: Indicates whether the Event is public or not. - self.public = self._get_attribute(event, 'public') + self.public = event['public'] def _repr(self): return ''.format(self.type[:-5]) From 6f733b1ff52cf4240babb48bcbf0e2181fd5505e Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Wed, 14 Feb 2018 14:32:04 -0800 Subject: [PATCH 14/56] Update github3.auths to remove get_attribute --- github3/auths.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/github3/auths.py b/github3/auths.py index 79f68b713..b5e26216b 100644 --- a/github3/auths.py +++ b/github3/auths.py @@ -31,34 +31,34 @@ class Authorization(GitHubCore): """ def _update_attributes(self, auth): - self._api = self._get_attribute(auth, 'url') + self._api = auth['url'] #: Details about the application (name, url) - self.app = self._get_attribute(auth, 'app', {}) + self.app = auth['app'] #: Returns the Authorization token - self.token = self._get_attribute(auth, 'token') + self.token = auth['token'] #: App name - self.name = self._get_attribute(self.app, 'name') + self.name = self.app['name'] #: URL about the note - self.note_url = self._get_attribute(auth, 'note_url') + self.note_url = auth['note_url'] #: Note about the authorization - self.note = self._get_attribute(auth, 'note') + self.note = auth['note'] #: List of scopes this applies to - self.scopes = self._get_attribute(auth, 'scopes') + self.scopes = auth['scopes'] #: Unique id of the authorization - self.id = self._get_attribute(auth, 'id') + self.id = auth['id'] #: datetime object representing when the authorization was created. - self.created_at = self._strptime_attribute(auth, 'created_at') + self.created_at = self._strptime(auth['created_at']) #: datetime object representing when the authorization was updated. - self.updated_at = self._strptime_attribute(auth, 'updated_at') + self.updated_at = self._strptime(auth['updated_at']) def _repr(self): return ''.format(self.name) From f7ad5a57c8055b1f131dd866b99c084e2e0f3da9 Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Wed, 14 Feb 2018 15:53:51 -0800 Subject: [PATCH 15/56] Update github3.git to remove get_attribute This also created a CommitTree object as the tree is different via the git object API vs the repository object API. New example data is added to account for this difference as well. --- github3/git.py | 90 ++++++++++++++++++++---------- tests/unit/json/git_commit_example | 31 ++++++++++ tests/unit/test_git.py | 2 +- 3 files changed, 91 insertions(+), 32 deletions(-) create mode 100644 tests/unit/json/git_commit_example diff --git a/github3/git.py b/github3/git.py index 41b47553c..ad71d0c62 100644 --- a/github3/git.py +++ b/github3/git.py @@ -24,15 +24,15 @@ class Blob(GitHubCore): """ def _update_attributes(self, blob): - self._api = self._get_attribute(blob, 'url') + self._api = blob['url'] #: Raw content of the blob. - self.content = self._get_attribute(blob, 'content') + self.content = blob['content'] if self.content is not None: self.content = self.content.encode() #: Encoding of the raw content. - self.encoding = self._get_attribute(blob, 'encoding') + self.encoding = blob['encoding'] #: Decoded content of the blob. self.decoded = self.content @@ -40,9 +40,9 @@ def _update_attributes(self, blob): self.decoded = b64decode(self.content) #: Size of the blob in bytes - self.size = self._get_attribute(blob, 'size') + self.size = blob['size'] #: SHA1 of the blob - self.sha = self._get_attribute(blob, 'sha') + self.sha = blob['sha'] def _repr(self): return ''.format(self.sha) @@ -58,8 +58,8 @@ class GitData(GitHubCore): def _update_attributes(self, data): #: SHA of the object - self.sha = self._get_attribute(data, 'sha') - self._api = self._get_attribute(data, 'url') + self.sha = data['sha'] + self._api = data['url'] class Commit(BaseCommit): @@ -75,21 +75,25 @@ def _update_attributes(self, commit): super(Commit, self)._update_attributes(commit) #: dict containing at least the name, email and date the commit was #: created - self.author = self._get_attribute(commit, 'author', {}) - # If GH returns nil/None then make sure author is a dict - self._author_name = self._get_attribute(self.author, 'name') + self.author = commit['author'] + # GitHub may not provide a name for the author + if self.author.get('name'): + self._author_name = self.author['name'] #: dict containing similar information to the author attribute - self.committer = self._get_attribute(commit, 'committer', {}) - # blank the data if GH returns no data + # If the committer is not different from the author, we may not get + # a committer key + if commit.get('committer'): + self.committer = commit['committer'] - self._commit_name = self._get_attribute(self.committer, 'name') + if self.committer.get('name'): + self._commit_name = self.committer['name'] - #: :class:`Tree ` the commit belongs to. - self.tree = self._class_attribute(commit, 'tree', Tree, self) + #: :class:`CommitTree ` the commit belongs to. + self.tree = CommitTree(commit['tree'], self) def _repr(self): - return ''.format(self._author_name, self.sha) + return ''.format(self.sha) class Reference(GitHubCore): @@ -102,13 +106,13 @@ class Reference(GitHubCore): """ def _update_attributes(self, ref): - self._api = self._get_attribute(ref, 'url') + self._api = ref['url'] #: The reference path, e.g., refs/heads/sc/featureA - self.ref = self._get_attribute(ref, 'ref') + self.ref = ref['ref'] #: :class:`GitObject ` the reference points to - self.object = self._class_attribute(ref, 'object', GitObject, self) + self.object = GitObject(ref['object'], self) def _repr(self): return ''.format(self.ref) @@ -146,7 +150,7 @@ class GitObject(GitData): def _update_attributes(self, obj): super(GitObject, self)._update_attributes(obj) #: The type of object. - self.type = self._get_attribute(obj, 'type') + self.type = obj['type'] def _repr(self): return ''.format(self.sha) @@ -164,21 +168,43 @@ def _update_attributes(self, tag): super(Tag, self)._update_attributes(tag) #: String of the tag - self.tag = self._get_attribute(tag, 'tag') + self.tag = tag['tag'] #: Commit message for the tag - self.message = self._get_attribute(tag, 'message') + self.message = tag['message'] #: dict containing the name and email of the person - self.tagger = self._get_attribute(tag, 'tagger') + self.tagger = tag['tagger'] #: :class:`GitObject ` for the tag - self.object = self._class_attribute(tag, 'object', GitObject, self) + self.object = GitObject(tag['object'], self) def _repr(self): return ''.format(self.tag) +class CommitTree(GitData): + + """The :class:`CommitTree ` object. + + Represents the tree data found in a commit object + + """ + + def _update_attributes(self, tree): + super(CommitTree, self)._update_attributes(tree) + + def _repr(self): + return ''.format(self.sha) + + def to_tree(self): + """Retrieve a full Tree object for this CommitTree.""" + json = self._json(self._get(self._api), 200) + return self._instance_or_null(Tree, json) + + refresh = to_tree + + class Tree(GitData): """The :class:`Tree ` object. @@ -191,7 +217,7 @@ def _update_attributes(self, tree): super(Tree, self)._update_attributes(tree) #: list of :class:`Hash ` objects - self.tree = self._get_attribute(tree, 'tree', []) + self.tree = tree['tree'] if self.tree: self.tree = [Hash(t, self) for t in self.tree] @@ -224,22 +250,24 @@ class Hash(GitHubCore): def _update_attributes(self, info): #: Path to file - self.path = self._get_attribute(info, 'path') + self.path = info['path'] #: File mode - self.mode = self._get_attribute(info, 'mode') + self.mode = info['mode'] #: Type of hash, e.g., blob - self.type = self._get_attribute(info, 'type') + self.type = info['type'] #: Size of hash - self.size = self._get_attribute(info, 'size') + # Size is not set if the type is a tree + if self.type != 'tree': + self.size = info['size'] #: SHA of the hash - self.sha = self._get_attribute(info, 'sha') + self.sha = info['sha'] #: URL of this object in the GitHub API - self.url = self._get_attribute(info, 'url') + self.url = info['url'] def _repr(self): return ''.format(self.sha) diff --git a/tests/unit/json/git_commit_example b/tests/unit/json/git_commit_example new file mode 100644 index 000000000..6e8751f27 --- /dev/null +++ b/tests/unit/json/git_commit_example @@ -0,0 +1,31 @@ +{ + "sha": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "date": "2014-11-07T22:01:45Z", + "name": "Scott Chacon", + "email": "schacon@gmail.com" + }, + "committer": { + "date": "2014-11-07T22:01:45Z", + "name": "Scott Chacon", + "email": "schacon@gmail.com" + }, + "message": "added readme, because im a good github citizen", + "tree": { + "url": "https://api.github.com/repos/octocat/Hello-World/git/trees/691272480426f78a0138979dd3ce63b77f706feb", + "sha": "691272480426f78a0138979dd3ce63b77f706feb" + }, + "parents": [ + { + "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/1acc419d4d6a9ce985db7be48c6349a0475975b5", + "sha": "1acc419d4d6a9ce985db7be48c6349a0475975b5" + } + ], + "verification": { + "verified": false, + "reason": "unsigned", + "signature": null, + "payload": null + } +} \ No newline at end of file diff --git a/tests/unit/test_git.py b/tests/unit/test_git.py index b2f0c40db..2338089d7 100644 --- a/tests/unit/test_git.py +++ b/tests/unit/test_git.py @@ -10,7 +10,7 @@ 'octocat/Hello-World/' 'git/refs/heads/featureA') -get_commit_example_data = create_example_data_helper('commit_example') +get_commit_example_data = create_example_data_helper('git_commit_example') get_git_tag_example_data = create_example_data_helper('git_tag_example') get_reference_example_data = create_example_data_helper('reference_example') From 45103a522a8d5ba4dc3aa9f0ac9603c5eb0bba8c Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Wed, 14 Feb 2018 20:58:21 -0800 Subject: [PATCH 16/56] Add py36 to python environments to test in --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index b589e8a36..8ddf23599 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,34,35,py},py{27,34}-flake8,docstrings +envlist = py{27,34,35,36,py},py{27,34,36}-flake8,docstrings minversion = 2.5.0 [testenv] From 2d67ae84b74764fc73d76451b59a4e292cd17b7d Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sun, 18 Feb 2018 06:25:36 -0600 Subject: [PATCH 17/56] Remove and ignore .DS_Store --- .gitignore | 1 + github3/.DS_Store | Bin 6148 -> 0 bytes 2 files changed, 1 insertion(+) delete mode 100644 github3/.DS_Store diff --git a/.gitignore b/.gitignore index 11de986be..a3d72cdca 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ build/ .ipynb_checkpoints .cache/ tests/id_rsa +*.DS_Store diff --git a/github3/.DS_Store b/github3/.DS_Store deleted file mode 100644 index deb54681a7498073cd7214e5dd8e6678515761f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKISv9b4752UBpOP}e1RWC2wt!spa9VzKp?2M;$1wA@zJbSbWniCk~4|pNt7wp zYZ1}qZMzVeiO2+QC=VO@X8Yzn8)QU*aGY_yH<#n#blmrH-vx|2mW%AsKC!FVBd!VH>`Bxq5@RluN2VHs#z`Zq^zyI$62i{@D1E@o^UhFor1y3G0@8~7FLeuo)me-=Gd=^ UZJ^T;cRG+i1Evd&3Vd6E7fF~D;s5{u From 112caa6a9f048798a1ca27bb796b7657c481e0a0 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sun, 18 Feb 2018 07:17:15 -0600 Subject: [PATCH 18/56] Further update github3.git for consistency Let's try to mainly import modules instead of functions or members. Let's update the class documentation and add otherwise missing attributes. --- github3/git.py | 194 +++++++++++++++++++++++++++++++------------------ 1 file changed, 125 insertions(+), 69 deletions(-) diff --git a/github3/git.py b/github3/git.py index ad71d0c62..7aa330ed2 100644 --- a/github3/git.py +++ b/github3/git.py @@ -1,105 +1,163 @@ # -*- coding: utf-8 -*- """ -github3.git -=========== - This module contains all the classes relating to Git Data. See also: http://developer.github.com/v3/git/ """ from __future__ import unicode_literals +import base64 +import warnings from json import dumps -from base64 import b64decode -from .models import GitHubCore, BaseCommit -from .decorators import requires_auth +from . import models +from .decorators import requires_auth -class Blob(GitHubCore): - """The :class:`Blob ` object. +class Blob(models.GitHubCore): + """This object provides an interface to the API representation of a blob. See also: http://developer.github.com/v3/git/blobs/ + .. versionchanged:: 1.0.0 + + - The :attr:`content` is no longer forcibly coerced to bytes. + - The :attr:`decoded` is deprecated in favor of :meth:`decode_content`. + + This object has the following atributes + + .. attribute:: content + + The raw content of the blob. This may be base64 encoded text. Use + :meth:`decode_content` to receive the non-encoded text. + + .. attribute:: encoding + + The encoding that GitHub reports for this blob's content. + + .. attribute:: size + + The size of this blob's content in bytes. + + .. attribute:: sha + + The SHA1 of this blob's content. """ def _update_attributes(self, blob): self._api = blob['url'] - - #: Raw content of the blob. self.content = blob['content'] - if self.content is not None: - self.content = self.content.encode() - - #: Encoding of the raw content. self.encoding = blob['encoding'] - - #: Decoded content of the blob. - self.decoded = self.content - if self.encoding == 'base64': - self.decoded = b64decode(self.content) - - #: Size of the blob in bytes self.size = blob['size'] - #: SHA1 of the blob self.sha = blob['sha'] def _repr(self): return ''.format(self.sha) + @property + def decoded(self): + """Compatibility shim for the deprecated attribute.""" + warnings.warn('The decoded attribute is deprecated. Use decode_content' + ' instead.', DeprecationWarning) + return self.decode_content() -class GitData(GitHubCore): + def decode_content(self): + """Return the unencoded content of this blob. - """The :class:`GitData ` object. This isn't directly returned to - the user (developer) ever. This is used to prevent duplication of some - common items among other Git Data objects. + If the content is base64 encoded, this will properly decode it. + Otherwise, it will return the content as returned by the API. - """ - - def _update_attributes(self, data): - #: SHA of the object - self.sha = data['sha'] - self._api = data['url'] + :returns: + Decoded content as text + :rtype: + unicode + """ + if self.encoding == 'base64' and self.content: + return base64.b64decode( + self.content.encode('utf-8') + ).decode('utf-8') + return self.content -class Commit(BaseCommit): +class Commit(models.GitHubCore): + """This represents a commit as returned by the git API. - """The :class:`Commit ` object. This represents a commit made in a - repository. + This is distinct from :class:`~github3.repos.commit.RepoCommit`. + Primarily this object represents the commit data stored by git and + it has no relationship to the repository on GitHub. See also: http://developer.github.com/v3/git/commits/ + This object has the following attributes: + + .. attribute:: author + + This is a dictionary with at least the name and email of the author + of this commit as well as the date it was authored. + + .. attribute:: committer + + This is a dictionary with at least the name and email of the committer + of this commit as well as the date it was committed. + + .. attribute:: html_url + + The URL to view this commit in a browser. + + .. attribute:: message + + The commit message that describes the changes as written by the author + and committer. + + .. attribute:: parents + + The list of commits that are the parents of this commit. This may be + empty if this is the initial commit, or it may have several if it is + the result of an octopus merge. Each parent is represented as a + dictionary with the API URL and SHA1. + + .. attribute:: sha + + The unique SHA1 which identifies this commit. + + .. attribute:: tree + + The git tree object this commit points to. + + .. attribute:: verification + + The GPG verification data about this commit. See + https://developer.github.com/v3/git/commits/#commit-signature-verification + for more information. """ def _update_attributes(self, commit): - super(Commit, self)._update_attributes(commit) - #: dict containing at least the name, email and date the commit was - #: created + self._api = commit['url'] self.author = commit['author'] - # GitHub may not provide a name for the author if self.author.get('name'): self._author_name = self.author['name'] - - #: dict containing similar information to the author attribute - # If the committer is not different from the author, we may not get - # a committer key - if commit.get('committer'): - self.committer = commit['committer'] - - if self.committer.get('name'): - self._commit_name = self.committer['name'] - - #: :class:`CommitTree ` the commit belongs to. + self.committer = commit['committer'] + if self.committer: + self._commit_name = self.committer.get('name') + self.html_url = commit['html_url'] + self.message = commit['message'] + self.parents = commit['parents'] + self.sha = commit['sha'] + if not self.sha: + i = self._api.rfind('/') + self.sha = self._api[i + 1:] + self._uniq = self.sha self.tree = CommitTree(commit['tree'], self) + self.verification = commit['verification'] def _repr(self): return ''.format(self.sha) -class Reference(GitHubCore): +class Reference(models.GitHubCore): + """The :class:`Reference ` object. - """The :class:`Reference ` object. This represents a reference - created on a repository. + This represents a reference created on a repository. See also: http://developer.github.com/v3/git/refs/ @@ -143,21 +201,19 @@ def update(self, sha, force=False): return False -class GitObject(GitData): - +class GitObject(models.GitHubCore): """The :class:`GitObject ` object.""" def _update_attributes(self, obj): - super(GitObject, self)._update_attributes(obj) - #: The type of object. - self.type = obj['type'] + self.sha = self._get_attribute(obj, 'sha') + self._api = self._get_attribute(obj, 'url') + self.type = self._get_attribute(obj, 'type') def _repr(self): return ''.format(self.sha) -class Tag(GitData): - +class Tag(models.GitHubCore): """The :class:`Tag ` object. See also: http://developer.github.com/v3/git/tags/ @@ -165,7 +221,8 @@ class Tag(GitData): """ def _update_attributes(self, tag): - super(Tag, self)._update_attributes(tag) + self.sha = self._get_attribute(tag, 'sha') + self._api = self._get_attribute(tag, 'url') #: String of the tag self.tag = tag['tag'] @@ -183,8 +240,7 @@ def _repr(self): return ''.format(self.tag) -class CommitTree(GitData): - +class CommitTree(models.GitHubCore): """The :class:`CommitTree ` object. Represents the tree data found in a commit object @@ -192,7 +248,8 @@ class CommitTree(GitData): """ def _update_attributes(self, tree): - super(CommitTree, self)._update_attributes(tree) + self._api = tree['url'] + self.sha = tree['sha'] def _repr(self): return ''.format(self.sha) @@ -205,8 +262,7 @@ def to_tree(self): refresh = to_tree -class Tree(GitData): - +class Tree(models.GitHubCore): """The :class:`Tree ` object. See also: http://developer.github.com/v3/git/trees/ @@ -214,7 +270,8 @@ class Tree(GitData): """ def _update_attributes(self, tree): - super(Tree, self)._update_attributes(tree) + self.sha = self._get_attribute(tree, 'sha') + self._api = self._get_attribute(tree, 'url') #: list of :class:`Hash ` objects self.tree = tree['tree'] @@ -240,8 +297,7 @@ def recurse(self): return self._instance_or_null(Tree, json) -class Hash(GitHubCore): - +class Hash(models.GitHubCore): """The :class:`Hash ` object. See also: http://developer.github.com/v3/git/trees/#create-a-tree From 929c13107dc1e5c038481a4409fae24a7c8f5d30 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Mon, 19 Feb 2018 13:14:47 -0600 Subject: [PATCH 19/56] Bring github3.git into a consistent state Add better documentation around the objects there and what they represent. Also add a new Commit-like object for RepoCommits --- github3/git.py | 294 +++++++++++++++++++++++++++------------- github3/repos/commit.py | 2 +- 2 files changed, 204 insertions(+), 92 deletions(-) diff --git a/github3/git.py b/github3/git.py index 7aa330ed2..1a8b3f604 100644 --- a/github3/git.py +++ b/github3/git.py @@ -79,7 +79,25 @@ def decode_content(self): return self.content -class Commit(models.GitHubCore): +class _Commit(models.GitHubCore): + class_name = '_Commit' + + def _update_attributes(self, commit): + self._api = commit['url'] + self.author = commit['author'] + if self.author.get('name'): + self._author_name = self.author['name'] + self.committer = commit['committer'] + if self.committer: + self._commit_name = self.committer.get('name') + self.message = commit['message'] + self.tree = CommitTree(commit['tree'], self) + + def _repr(self): + return '<{0} [{1}]>'.format(self.class_name, self.sha) + + +class Commit(_Commit): """This represents a commit as returned by the git API. This is distinct from :class:`~github3.repos.commit.RepoCommit`. @@ -88,26 +106,8 @@ class Commit(models.GitHubCore): See also: http://developer.github.com/v3/git/commits/ - This object has the following attributes: - - .. attribute:: author - - This is a dictionary with at least the name and email of the author - of this commit as well as the date it was authored. - - .. attribute:: committer - - This is a dictionary with at least the name and email of the committer - of this commit as well as the date it was committed. - - .. attribute:: html_url - - The URL to view this commit in a browser. - - .. attribute:: message - - The commit message that describes the changes as written by the author - and committer. + This object has all of the attributes of a + :class:`~github3.git.ShortCommit` as well as the following attributes: .. attribute:: parents @@ -120,10 +120,6 @@ class Commit(models.GitHubCore): The unique SHA1 which identifies this commit. - .. attribute:: tree - - The git tree object this commit points to. - .. attribute:: verification The GPG verification data about this commit. See @@ -131,46 +127,78 @@ class Commit(models.GitHubCore): for more information. """ + class_name = 'Commit' + def _update_attributes(self, commit): - self._api = commit['url'] - self.author = commit['author'] - if self.author.get('name'): - self._author_name = self.author['name'] - self.committer = commit['committer'] - if self.committer: - self._commit_name = self.committer.get('name') - self.html_url = commit['html_url'] - self.message = commit['message'] + super(Commit, self)._update_attributes(commit) self.parents = commit['parents'] self.sha = commit['sha'] if not self.sha: i = self._api.rfind('/') self.sha = self._api[i + 1:] self._uniq = self.sha - self.tree = CommitTree(commit['tree'], self) self.verification = commit['verification'] - def _repr(self): - return ''.format(self.sha) + +class ShortCommit(_Commit): + """This represents a commit as returned by the git API. + + This is distinct from :class:`~github3.repos.commit.RepoCommit`. + Primarily this object represents the commit data stored by git. This + shorter representation of a Commit is most often found on a + :class:`~github3.repos.commit.RepoCommit` to represent the git data + associated with it. + + See also: http://developer.github.com/v3/git/commits/ + + This object has the following attributes: + + .. attribute:: author + + This is a dictionary with at least the name and email of the author + of this commit as well as the date it was authored. + + .. attribute:: committer + + This is a dictionary with at least the name and email of the committer + of this commit as well as the date it was committed. + + .. attribute:: message + + The commit message that describes the changes as written by the author + and committer. + + .. attribute:: tree + + The git tree object this commit points to. + """ + + class_name = 'ShortCommit' + refresh_to = Commit class Reference(models.GitHubCore): - """The :class:`Reference ` object. + """Object representing a git reference associated with a repository. - This represents a reference created on a repository. + This represents a reference (or ref) created on a repository via git. See also: http://developer.github.com/v3/git/refs/ + This object has the following attributes: + + .. attribute:: object + + A :class:`~github3.git.GitObject` that this reference points to. + + .. attribute:: ref + + The string path to the reference, e.g., ``'refs/heads/sc/feature-a'``. """ def _update_attributes(self, ref): self._api = ref['url'] - - #: The reference path, e.g., refs/heads/sc/featureA - self.ref = ref['ref'] - - #: :class:`GitObject ` the reference points to self.object = GitObject(ref['object'], self) + self.ref = ref['ref'] def _repr(self): return ''.format(self.ref) @@ -179,8 +207,10 @@ def _repr(self): def delete(self): """Delete this reference. - :returns: bool - + :returns: + True if successful, False otherwise + :rtype: + bool """ return self._boolean(self._delete(self._api), 204, 404) @@ -188,10 +218,14 @@ def delete(self): def update(self, sha, force=False): """Update this reference. - :param str sha: (required), sha of the reference - :param bool force: (optional), force the update or not - :returns: bool - + :param str sha: + (required), sha of the reference + :param bool force: + (optional), force the update or not + :returns + True if successful, False otherwise + :rtype: + bool """ data = {'sha': sha, 'force': force} json = self._json(self._patch(self._api, data=dumps(data)), 200) @@ -202,49 +236,92 @@ def update(self, sha, force=False): class GitObject(models.GitHubCore): - """The :class:`GitObject ` object.""" + """This object represents an arbitrary 'object' in git. + + This object is intended to be versatile and is usually found on one of the + following: + + - :class:`~github3.git.Reference` + - :class:`~github3.git.Tag` + + This object has the following attributes: + + .. attribute:: sha + + The SHA1 of the object this is representing. + + .. attribute:: type + + The name of the type of object this is representing. + """ def _update_attributes(self, obj): - self.sha = self._get_attribute(obj, 'sha') - self._api = self._get_attribute(obj, 'url') - self.type = self._get_attribute(obj, 'type') + self._api = obj['url'] + self.sha = obj['sha'] + self.type = obj['type'] def _repr(self): return ''.format(self.sha) class Tag(models.GitHubCore): - """The :class:`Tag ` object. + """This represents an annotated tag. + + Tags are a special kind of git reference and annotated tags have more + information than lightweight tags. See also: http://developer.github.com/v3/git/tags/ - """ + This object has the following attributes: - def _update_attributes(self, tag): - self.sha = self._get_attribute(tag, 'sha') - self._api = self._get_attribute(tag, 'url') + .. attribute:: message - #: String of the tag - self.tag = tag['tag'] + This is the message that was written to accompany the creation of the + annotated tag. - #: Commit message for the tag - self.message = tag['message'] + .. attribute:: object - #: dict containing the name and email of the person - self.tagger = tag['tagger'] + A :class:`~github3.git.GitObject` that represents the underlying git + object. + + .. attribute:: sha + + The SHA1 of this tag in the git repository. + + .. attribute:: tag - #: :class:`GitObject ` for the tag + The "lightweight" tag (or reference) that backs this annotated tag. + + .. attribute:: tagger + + The person who created this tag. + """ + + def _update_attributes(self, tag): + self._api = tag['url'] + self.message = tag['message'] self.object = GitObject(tag['object'], self) + self.sha = tag['sha'] + self.tag = tag['tag'] + self.tagger = tag['tagger'] def _repr(self): return ''.format(self.tag) class CommitTree(models.GitHubCore): - """The :class:`CommitTree ` object. + """This object represents the abbreviated tree data in a commit. + + The API returns different representations of different objects. When + representing a :class:`~github3.git.ShortCommit` or + :class:`~github3.git.Commit`, the API returns an abbreviated + representation of a git tree. + + This object has the following attributes: - Represents the tree data found in a commit object + .. attribute:: sha + The SHA1 of this tree in the git repository. """ def _update_attributes(self, tree): @@ -255,7 +332,13 @@ def _repr(self): return ''.format(self.sha) def to_tree(self): - """Retrieve a full Tree object for this CommitTree.""" + """Retrieve a full Tree object for this CommitTree. + + :returns: + The full git data about this tree + :rtype: + :class:`~github3.git.Tree` + """ json = self._json(self._get(self._api), 200) return self._instance_or_null(Tree, json) @@ -263,17 +346,27 @@ def to_tree(self): class Tree(models.GitHubCore): - """The :class:`Tree ` object. + """This represents a tree object from a git repository. + + Trees tend to represent directories and subdirectories. See also: http://developer.github.com/v3/git/trees/ + This object has the following attributes: + + .. attribute:: sha + + The SHA1 of this tree in the git repository. + + .. attribute:: tree + + A list that represents the nodes in the tree. If this list has members + it will have instances of :class:`~github3.git.Hash`. """ def _update_attributes(self, tree): - self.sha = self._get_attribute(tree, 'sha') - self._api = self._get_attribute(tree, 'url') - - #: list of :class:`Hash ` objects + self._api = tree['url'] + self.sha = tree['sha'] self.tree = tree['tree'] if self.tree: self.tree = [Hash(t, self) for t in self.tree] @@ -288,9 +381,12 @@ def __ne__(self, other): return self.as_dict() != other.as_dict() def recurse(self): - """Recurse into the tree. + """Recurse into this tree. - :returns: :class:`Tree ` + :returns: + A new tree + :rtype: + :class:`~github3.git.Tree` """ json = self._json(self._get(self._api, params={'recursive': '1'}), 200) @@ -298,32 +394,48 @@ def recurse(self): class Hash(models.GitHubCore): - """The :class:`Hash ` object. + """This is used to represent the elements of a tree. + + This provides the path to the object and the type of object it is. For + a brief explanation of what these types are and represent, this + StackOverflow question answers some of that: + https://stackoverflow.com/a/18605496/1953283 See also: http://developer.github.com/v3/git/trees/#create-a-tree + This object has the following attributes: + + .. attribute:: mode + + The mode of the file, directory, or link. + + .. attribute:: path + + The path to the file, directory, or link. + + .. attribute:: sha + + The SHA1 for this hash. + + .. attribute:: size + + This attribute is only not ``None`` if the :attr:`type` is not a tree. + + .. attribute:: type + + The type of git object this is representing, e.g., tree, blob, etc. """ def _update_attributes(self, info): - #: Path to file - self.path = info['path'] - - #: File mode + self._api = info['url'] self.mode = info['mode'] - - #: Type of hash, e.g., blob + self.path = info['path'] + self.sha = info['sha'] + self.size = None self.type = info['type'] - #: Size of hash - # Size is not set if the type is a tree if self.type != 'tree': self.size = info['size'] - #: SHA of the hash - self.sha = info['sha'] - - #: URL of this object in the GitHub API - self.url = info['url'] - def _repr(self): return ''.format(self.sha) diff --git a/github3/repos/commit.py b/github3/repos/commit.py index 199e25379..49f05c1eb 100644 --- a/github3/repos/commit.py +++ b/github3/repos/commit.py @@ -41,7 +41,7 @@ def _update_attributes(self, commit): ) #: :class:`Commit `. - self.commit = self._class_attribute(commit, 'commit', git.Commit, self) + self.commit = self._class_attribute(commit, 'commit', git.ShortCommit, self) self.sha = self._get_attribute(commit, 'sha') From f2b0bdd4f6046bf0057563be2e9e6f76b20ec055 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Mon, 19 Feb 2018 13:32:21 -0600 Subject: [PATCH 20/56] Update github3.git API docs --- docs/git.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/git.rst b/docs/git.rst index 7bfb133ec..f8d84d233 100644 --- a/docs/git.rst +++ b/docs/git.rst @@ -9,7 +9,6 @@ section of the GitHub API. - :class:`Blob ` - :class:`Commit ` -- :class:`GitData ` - :class:`GitObject ` - :class:`Hash ` - :class:`Reference ` @@ -27,12 +26,12 @@ Git Objects ------ -.. autoclass:: Commit +.. autoclass:: ShortCommit :inherited-members: ------ -.. autoclass:: GitData +.. autoclass:: Commit :inherited-members: ------ @@ -59,3 +58,8 @@ Git Objects .. autoclass:: Tree :inherited-members: + +------ + +.. autoclass:: CommitTree + :inherited-members: From e8e45ea768da60f480f08ae4a73b9632e09a639d Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Mon, 19 Feb 2018 14:08:27 -0600 Subject: [PATCH 21/56] Fix line length and docstring --- github3/git.py | 2 +- github3/repos/commit.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/github3/git.py b/github3/git.py index 1a8b3f604..88d46c334 100644 --- a/github3/git.py +++ b/github3/git.py @@ -222,7 +222,7 @@ def update(self, sha, force=False): (required), sha of the reference :param bool force: (optional), force the update or not - :returns + :returns: True if successful, False otherwise :rtype: bool diff --git a/github3/repos/commit.py b/github3/repos/commit.py index 49f05c1eb..3b7a3f5f4 100644 --- a/github3/repos/commit.py +++ b/github3/repos/commit.py @@ -41,7 +41,9 @@ def _update_attributes(self, commit): ) #: :class:`Commit `. - self.commit = self._class_attribute(commit, 'commit', git.ShortCommit, self) + self.commit = self._class_attribute( + commit, 'commit', git.ShortCommit, self, + ) self.sha = self._get_attribute(commit, 'sha') From e5d6994352cc7e49296c0ec82ba94ab8349dd609 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Wed, 21 Feb 2018 18:35:54 -0600 Subject: [PATCH 22/56] Add documentation for classes in github3.events --- github3/events.py | 277 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 233 insertions(+), 44 deletions(-) diff --git a/github3/events.py b/github3/events.py index 940c617b5..bebfc96d7 100644 --- a/github3/events.py +++ b/github3/events.py @@ -1,20 +1,40 @@ # -*- coding: utf-8 -*- -""" -github3.events -============== - -This module contains the class(es) related to Events - -""" +"""This module contains the classes related to Events.""" from __future__ import unicode_literals import copy -from .models import GitHubCore +from . import models + + +class EventUser(models.GitHubCore): + """The class that represents the user information returned in Events. + + .. note:: + + Refreshing this object will return a :class:`~github3.users.User`. + + .. attribute:: avatar_url + + The URL of the avatar image this user chose. + + .. attribute:: display_login + + The login that is displayed as part of the event. + + .. attribute:: gravatar_id + + The unique ID for the user's gravatar, if they're using gravatar to + host their avatar. + + .. attribute:: id + + The user's unique ID in GitHub. + .. attribute:: login -class EventUser(GitHubCore): - """The class that represents the user information returned in Events.""" + The user's login (or handle) on GitHub. + """ def _update_attributes(self, user): self.avatar_url = user['avatar_url'] @@ -25,7 +45,13 @@ def _update_attributes(self, user): self._api = self.url = user['url'] def to_user(self): - """Retrieve a full User object for this EventUser.""" + """Retrieve a full User object for this EventUser. + + :returns: + The full information about this user. + :rtype: + :class:`~github3.users.User` + """ from . import users url = self._build_url('users', self.login) json = self._json(self._get(url), 200) @@ -34,8 +60,33 @@ def to_user(self): refresh = to_user -class EventOrganization(GitHubCore): - """The class that represents the org information returned in Events.""" +class EventOrganization(models.GitHubCore): + """Representation of the organization information returned in Events. + + .. note:: + + Refreshing this object will return a + :class:`~github3.orgs.Organization`. + + This object has the following attributes: + + .. attribute:: avatar_url + + The URL to this organization's avatar. + + .. attribute:: gravatar_id + + The unique identifier for this organization on Gravatar, if its + avatar is hosted there. + + .. attribute:: id + + This organization's unique identifier on GitHub. + + .. attribute:: login + + The unique login for this organization. + """ def _update_attributes(self, org): self.avatar_url = org['avatar_url'] @@ -45,7 +96,13 @@ def _update_attributes(self, org): self._api = self.url = org['url'] def to_org(self): - """Retrieve a full Organization object for this EventOrganization.""" + """Retrieve a full Organization object for this EventOrganization. + + :returns: + The full information about this organization. + :rtype: + :class:`~github3.orgs.Organization` + """ from . import orgs url = self._build_url('orgs', self.login) json = self._json(self._get(url), 200) @@ -54,8 +111,35 @@ def to_org(self): refresh = to_org -class EventPullRequest(GitHubCore): - """The class that represents the pr information returned in Events.""" +class EventPullRequest(models.GitHubCore): + """Representation of a Pull Request returned in Events. + + .. note:: + + Refreshing this object returns a :class:`~github3.pulls.PullRequest`. + + This object has the following attributes: + + .. attribute:: id + + The unique id of this pull request across all of GitHub. + + .. attribute:: number + + The number of this pull request on its repository. + + .. attribute:: state + + The state of this pull request during this event. + + .. attribute:: title + + The title of this pull request during this event. + + .. attribute:: locked + + A boolean attribute describing if this pull request was locked. + """ def _update_attributes(self, pull): self.id = pull['id'] @@ -66,7 +150,13 @@ def _update_attributes(self, pull): self._api = self.url = pull['url'] def to_pull(self): - """Retrieve a full PullRequest object for this EventPullRequest.""" + """Retrieve a full PullRequest object for this EventPullRequest. + + :returns: + The full information about this pull request. + :rtype: + :class:`~github3.pulls.PullRequest` + """ from . import pulls json = self._json(self._get(self.url), 200) return self._instance_or_null(pulls.PullRequest, json) @@ -74,8 +164,79 @@ def to_pull(self): refresh = to_pull -class EventReviewComment(GitHubCore): - """Representation of review comments in events.""" +class EventReviewComment(models.GitHubCore): + """Representation of review comments in events. + + .. note:: + + Refreshing this object will return a new + :class`~github3.pulls.ReviewComment` + + This object has the following attributes: + + .. attribute:: id + + The unique id of this comment across all of GitHub. + + .. attribute:: author_association + + The association the author has with this project. + + .. attribute:: body + + The markdown body of this review comment. + + .. attribute:: commit_id + + The identifier of the commit that this comment was left on. + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + this comment was created. + + .. attribute:: diff_hunk + + The section (or hunk) of the diff this comment was left on. + + .. attribute:: html_url + + The URL to view this comment in a browser. + + .. attribute:: links + + A dictionary of links to various items about this comment. + + .. attribute:: original_commit_id + + The identifier of original commit this comment was left on. + + .. attribute:: original_position + + The original position within the diff this comment was left. + + .. attribute:: path + + The path to the file this comment was left on. + + .. attribute:: position + + The current position within the diff this comment is placed. + + .. attribute:: pull_request_url + + The URL to retrieve the pull request informtation from the API. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` object representing the date and time + this comment was updated. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` representing the user who authored + this comment. + """ def _update_attributes(self, comment): from . import users @@ -99,6 +260,8 @@ def _update_attributes(self, comment): def to_review_comment(self): """Retrieve a full ReviewComment object for this EventReviewComment. + :returns: + The full information about this review comment :rtype: :class:`~github3.pulls.ReviewComment` """ @@ -109,7 +272,7 @@ def to_review_comment(self): refresh = to_review_comment -class EventIssue(GitHubCore): +class EventIssue(models.GitHubCore): """The class that represents the issue information returned in Events.""" def _update_attributes(self, issue): @@ -129,10 +292,10 @@ def to_issue(self): refresh = to_issue -class Event(GitHubCore): +class Event(models.GitHubCore): + """Represents an event as returned by the API. - """The :class:`Event ` object. It structures and handles the data - returned by via the + It structures and handles the data returned by via the `Events `_ section of the GitHub API. @@ -146,43 +309,69 @@ class Event(GitHubCore): e1.id == e2.id e1.id != e2.id + .. attribute:: actor + + A :class:`~github3.events.EventUser` that represents the user whose + action generated this event. + + .. attribute:: created_at + + A :class:`~datetime.datetime` representing when this event was created. + + .. attribute:: id + + The unique identifier for this event. + + .. attribute:: org + + If present, a :class:`~github3.events.EventOrganization` representing + the organization on which this event occurred. + + .. attribute:: type + + The type of event this is. + + .. seealso:: + + `Event Types Documentation`_ + GitHub's documentation of different event types + + .. attribute:: payload + + The payload of the event which has all of the details relevant to this + event. + + .. attribute:: repo + + The string representation of the repository this event pertains to. + + .. versionchanged:: 1.0.0 + + This restores the behaviour of the API. To get a tuple, + representation, use ``self.repo.split('/', 1)`` + + .. attribute:: public + + A boolean representing whether the event is publicly viewable or not. + + .. _Event Types Documentation: + https://developer.github.com/v3/activity/events/types/ """ def _update_attributes(self, event): # If we don't copy this, then we end up altering _json_data which we do # not want to do: event = copy.deepcopy(event) - - #: :class:`User ` object representing the actor. self.actor = EventUser(event['actor'], self) - #: datetime object representing when the event was created. self.created_at = self._strptime(event['created_at']) - - #: Unique id of the event self.id = event['id'] - - #: :class:`EventOrganization ` - # object representing the org. - # an event only has an org if the event relates to a resource owned - # by an org. self.org = event.get('org') if self.org: self.org = EventOrganization(event['org'], self) - - #: Event type https://developer.github.com/v3/activity/events/types/ self.type = event['type'] handler = _payload_handlers.get(self.type, identity) - - #: Dictionary with the payload. Payload structure is defined by type_. - # _type: http://developer.github.com/v3/events/types self.payload = handler(event['payload'], self) - - #: Return ``tuple(owner, repository_name)`` self.repo = event['repo'] - if self.repo: - self.repo = tuple(self.repo['name'].split('/')) - - #: Indicates whether the Event is public or not. self.public = event['public'] def _repr(self): From 5b350756a20d919ec7052a8f0349f72979a91772 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Wed, 21 Feb 2018 18:37:45 -0600 Subject: [PATCH 23/56] Clean up docstring violations in github3.decorators --- github3/decorators.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/github3/decorators.py b/github3/decorators.py index f01884604..168f531ed 100644 --- a/github3/decorators.py +++ b/github3/decorators.py @@ -1,11 +1,5 @@ # -*- coding: utf-8 -*- -""" -github3.decorators -================== - -This module provides decorators to the rest of the library - -""" +"""This module provides decorators to the rest of the library.""" from functools import wraps from requests.models import Response @@ -20,7 +14,10 @@ class RequestsStringIO(StringIO): + """Shim compatibility for string IO.""" + def read(self, n=-1, *args, **kwargs): + """Ignore extra args and kwargs.""" # StringIO is an old-style class, so can't use super return StringIO.read(self, n) @@ -86,6 +83,7 @@ def auth_wrapper(self, *args, **kwargs): def generate_fake_error_response(msg, status_code=401, encoding='utf-8'): + """Generate a fake Response from requests.""" r = Response() r.status_code = status_code r.encoding = encoding From d2fb59419cce00157cb114a8465137aac6aa7f35 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 24 Feb 2018 08:40:38 -0600 Subject: [PATCH 24/56] Update the authorization class and its methods --- github3/auths.py | 170 ++++++++++++------ tests/cassettes/Authorization_add_scopes.json | 2 +- tests/cassettes/Authorization_delete.json | 2 +- .../Authorization_remove_scopes.json | 2 +- .../Authorization_replace_scopes.json | 2 +- tests/cassettes/GitHub_authorize.json | 2 +- tests/integration/test_auths.py | 32 +++- tests/unit/json/authorization_example | 5 +- 8 files changed, 150 insertions(+), 67 deletions(-) diff --git a/github3/auths.py b/github3/auths.py index b5e26216b..e6519eccf 100644 --- a/github3/auths.py +++ b/github3/auths.py @@ -1,11 +1,5 @@ # -*- coding: utf-8 -*- -""" -github3.auths -============= - -This module contains the Authorization object. - -""" +"""This module contains the Authorization object.""" from __future__ import unicode_literals from .decorators import requires_basic_auth @@ -13,51 +7,97 @@ class Authorization(GitHubCore): + """Representation of an OAuth Authorization. - """The :class:`Authorization ` object. + See also: https://developer.github.com/v3/oauth_authorizations/ - Two authorization instances can be checked like so:: + This object has the following attributes: - a1 == a2 - a1 != a2 + .. attribute:: app - And is equivalent to:: + Details about the application the authorization was created for. - a1.id == a2.id - a1.id != a2.id + .. attribute:: created_at - See also: http://developer.github.com/v3/oauth/#oauth-authorizations-api + A :class:`~datetime.datetime` representing when this authorization was + created. - """ + .. attribute:: fingerprint - def _update_attributes(self, auth): - self._api = auth['url'] + .. versionadded:: 1.0 - #: Details about the application (name, url) - self.app = auth['app'] + The optional parameter that is used to allow an OAuth application to + create multiple authorizations for the same user. This will help + distinguish two authorizations for the same app. - #: Returns the Authorization token - self.token = auth['token'] + .. attribute:: hashed_token - #: App name - self.name = self.app['name'] + .. versionadded:: 1.0 - #: URL about the note - self.note_url = auth['note_url'] + This is the base64 of the SHA-256 digest of the token. - #: Note about the authorization - self.note = auth['note'] + .. seealso:: - #: List of scopes this applies to - self.scopes = auth['scopes'] + `Removing Authorization Tokens`_ + The blog post announcing the removal of :attr:`token`. - #: Unique id of the authorization - self.id = auth['id'] + .. attribute:: id - #: datetime object representing when the authorization was created. - self.created_at = self._strptime(auth['created_at']) + The unique identifier for this authorization. + + .. attribute:: note_url + + The URL that points to a longer description about the purpose of this + autohrization. + + .. attribute:: note + + The short note provided when this authorization was created. + + .. attribute:: scopes + + The list of scopes assigned to this token. + + .. seealso:: + + `Scopes for OAuth Applications`_ + GitHub's documentation around available scopes and what they + mean - #: datetime object representing when the authorization was updated. + .. attribute:: token + + If this authorization was created, this will contain the full token. + Otherwise, this attribute will be an empty string. + + .. attribute:: token_last_eight + + .. versionadded:: 1.0 + + The last eight characters of the token. This allows users to identify + a token after the initial retrieval. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` representing when this authorization was + most recently updated. + + .. _Scopes for OAuth Applications: + https://developer.github.com/apps/building-oauth-apps/scopes-for-oauth-apps/ + .. _Removing Authorization Tokens: + https://developer.github.com/changes/2014-12-08-removing-authorizations-token/#what-should-you-do + """ + + def _update_attributes(self, auth): + self._api = auth['url'] + self.app = auth['app'] + self.created_at = self._strptime(auth['created_at']) + self.fingerprint = auth['fingerprint'] + self.id = auth['id'] + self.note_url = auth['note_url'] + self.note = auth['note'] + self.scopes = auth['scopes'] + self.token = auth['token'] + self.token_last_eight = auth['token_last_eight'] self.updated_at = self._strptime(auth['updated_at']) def _repr(self): @@ -79,23 +119,32 @@ def _update(self, scopes_data, note, note_url): @requires_basic_auth def add_scopes(self, scopes, note=None, note_url=None): - """Adds the scopes to this authorization. + """Add the scopes to this authorization. .. versionadded:: 1.0 - :param list scopes: Adds these scopes to the ones present on this - authorization - :param str note: (optional), Note about the authorization - :param str note_url: (optional), URL to link to when the user views - the authorization - :returns: True if successful, False otherwise - :rtype: bool + :param list scopes: + Adds these scopes to the ones present on this authorization + :param str note: + (optional), Note about the authorization + :param str note_url: + (optional), URL to link to when the user views the authorization + :returns: + True if successful, False otherwise + :rtype: + bool """ return self._update({'add_scopes': scopes}, note, note_url) @requires_basic_auth def delete(self): - """Delete this authorization.""" + """Delete this authorization. + + :returns: + True if successful, False otherwise + :rtype: + bool + """ return self._boolean(self._delete(self._api), 204, 404) @requires_basic_auth @@ -104,13 +153,16 @@ def remove_scopes(self, scopes, note=None, note_url=None): .. versionadded:: 1.0 - :param list scopes: Remove these scopes from the ones present on this - authorization - :param str note: (optional), Note about the authorization - :param str note_url: (optional), URL to link to when the user views - the authorization - :returns: True if successful, False otherwise - :rtype: bool + :param list scopes: + Remove these scopes from the ones present on this authorization + :param str note: + (optional), Note about the authorization + :param str note_url: + (optional), URL to link to when the user views the authorization + :returns: + True if successful, False otherwise + :rtype: + bool """ return self._update({'rm_scopes': scopes}, note, note_url) @@ -120,11 +172,15 @@ def replace_scopes(self, scopes, note=None, note_url=None): .. versionadded:: 1.0 - :param list scopes: Use these scopes instead of the previous list - :param str note: (optional), Note about the authorization - :param str note_url: (optional), URL to link to when the user views - the authorization - :returns: True if successful, False otherwise - :rtype: bool + :param list scopes: + Use these scopes instead of the previous list + :param str note: + (optional), Note about the authorization + :param str note_url: + (optional), URL to link to when the user views the authorization + :returns: + True if successful, False otherwise + :rtype: + bool """ return self._update({'scopes': scopes}, note, note_url) diff --git a/tests/cassettes/Authorization_add_scopes.json b/tests/cassettes/Authorization_add_scopes.json index 4b46ece84..a7e273160 100644 --- a/tests/cassettes/Authorization_add_scopes.json +++ b/tests/cassettes/Authorization_add_scopes.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA4WPzWrDMBCEXyXsqQUnliz/6pZjbj3k1FLMWl5iUVsS9hpKQ969MrSUQmj3OjPfzlzB9qClqGQphUxgnUfQMDCHRacpBnu4WB7W7mD8lOLKg5/tB7L1bkm/U5AAhgD6Cg4nivEzLbz7Zd49HJ9Oj9H4w494escpjLSxo2RGS47brQ+IOwe3BNi/kYu6MqaQJFXXmKLLZFEj9iozJseubiqq0NSqzKmJWOf5fqcvrf2r0kzI1LfI8WcmZL4X9T4rzyLTRaOVet4Whf5fz2J8oAX0y+vtE4dC6a5xAQAA", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "3061975e1f37121b3751604ad153c687", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"af5e035a265070984e2b70fe601d470d\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4960", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0C4D3:4A6F:E6B62CD:53FBF998", "cache-control": "private, max-age=60, s-maxage=60", "last-modified": "Tue, 26 Aug 2014 02:59:33 GMT", "date": "Tue, 26 Aug 2014 03:06:00 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409025614"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:06:00"}, {"request": {"body": {"string": "{\"add_scopes\": [\"user\"]}", "encoding": "utf-8"}, "headers": {"Content-Length": "24", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA32PTWvDMAyG/0rRaYO0seN8+rZjbz30tDGC4ojFLIlNrMBY6X+fAxtjEKbr++jRqxvYHrQUlSylkAmsywgaBmYfdJqit6c3y8PanYybUlx5cIv9RLZuDunPFiSA3oO+wYwTxfUrBT78gQ8PT5fzYwR//VFPHzj5kTZ3jMxoaeZ26wNiZ+CeALt3mmOujCkkSdU1pugyWdSIvcqMybGrm4oqNLUqc2qidna83+k7a/+rtBAy9S1yvJkJmR9FfczKq8h00WilnrePfL/PKC1KLcTGBOM8BdAvsAZa4PX+BQxYish3AQAA", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "88d924ed861736d2749ce1a55766cb53", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"def9f0eba11df7c937fd185809fab2f1\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4959", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0C4D3:4A6F:E6B62E3:53FBF998", "cache-control": "private, max-age=60, s-maxage=60", "date": "Tue, 26 Aug 2014 03:06:00 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409025614"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:06:01"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": "{\"note\": \"testing github3.py\", \"note_url\": \"\", \"client_id\": \"\", \"client_secret\": \"\", \"scopes\": [\"gist\"]}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "104", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations"}, "response": {"body": {"encoding": "utf-8", "string": "{\"id\":168042708,\"url\":\"https://api.github.com/authorizations/168042708\",\"app\":{\"name\":\"testing github3.py\",\"url\":\"https://developer.github.com/v3/oauth_authorizations/\",\"client_id\":\"00000000000000000000\"},\"token\":\"e710ce692a74b47e0dcf971cf22383d9763e77e5\",\"hashed_token\":\"34ddb39bb2a0df0c24059b3649b19c2542f7b84677ebea715dbe9966171821ba\",\"token_last_eight\":\"763e77e5\",\"note\":\"testing github3.py\",\"note_url\":\"\",\"created_at\":\"2018-02-24T13:59:08Z\",\"updated_at\":\"2018-02-24T13:59:08Z\",\"scopes\":[\"gist\"],\"fingerprint\":null}"}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:08 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "519", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4998", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"53afa5813f3b57d0cc6e5e3d28664ef6\"", "Location": "https://api.github.com/authorizations/168042708", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.136552", "X-GitHub-Request-Id": "BB66:328F:2F607B:9153C5:5A916FAC"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/authorizations"}, "recorded_at": "2018-02-24T13:59:08"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/authorizations/168042708"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA4VQ207EIBD9FTPP3RboFb7DJ41poMy2xC4lZbqJbvbfpW40ajTyyLnNORdwFhRvOlaJlnUZbOsMCiaiEFVR6ODy0dG0mXxYToXeaFpW96rJLT4WnzLIQIcA6gJenzDpCSM5P97dtGUeXhLlu7XFM85LwPVrwLkslj2k/5GU1MPs0FO/nwvslwfXDGh5Rp/wRJ90nND2Hz9lZa0ppTFCM3tkg6hYLU3ZVNJwOYi6EsfWdFXTtmhQt7y2BqVsGt7yTnCjk+O7VT/rSD26caKU0zYlJkWdUL/Qn8V3rL+134usqCmdpncHwXh3YOIgqnteqloq1j3sUwX7LycOab0I6hFGFwmeMjimyXENq/PJ2m/zfH0D5tfGR98BAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:08 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4997", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"cf7dbbd60d744f43163f591c5d03afd7\"", "Last-Modified": "Sat, 24 Feb 2018 13:59:08 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.045674", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "BB66:328F:2F6086:9153E3:5A916FAC"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/authorizations/168042708"}, "recorded_at": "2018-02-24T13:59:08"}, {"request": {"body": {"encoding": "utf-8", "string": "{\"add_scopes\": [\"user\"]}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "24", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations/168042708"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA4VQ2U7EIBT9FXOfOy1LN/gOnzSmgXKnJXYoKXQSncy/C040ajTyyNnuORewBiRte1KzjvQF7NsCEuYYfZBVpbwtJxvnXZfjeqrUHud1s68q2tWF6lMGBSjvQV7AqRMmfcQQrZvublpe+pdE+W5t8IzL6nH7GnDm1ZpDhh9JST0uFl0c8rlAfnlwLSCuz+gSnuizCjOa4eOH18ZoLrRmipgjGVlNGqF5WwtNxciamh073ddt16FG1dHGaBSibWlHe0a1So7vVsOiQhzQTnNMOV3LMSmahLo1/lk8Y8OtfS6yoYrpNJUdGKH9gbADq+8pl42QpH/IU3nzLyeMab0A8hEmG2IWBdzgqYBjWh43v1mXEty+LNc3omXqsOYBAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:08 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4996", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"68a5d20f096d0dae11a525aa86a55fb7\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.156098", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "BB66:328F:2F608A:9153F5:5A916FAC"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/authorizations/168042708"}, "recorded_at": "2018-02-24T13:59:08"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "0", "Authorization": "Basic "}, "method": "DELETE", "uri": "https://api.github.com/authorizations/168042708"}, "response": {"body": {"encoding": null, "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:08 GMT", "Content-Type": "application/octet-stream", "Status": "204 No Content", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4995", "X-RateLimit-Reset": "1519483301", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.097571", "X-GitHub-Request-Id": "BB66:328F:2F6092:915412:5A916FAC"}, "status": {"code": 204, "message": "No Content"}, "url": "https://api.github.com/authorizations/168042708"}, "recorded_at": "2018-02-24T13:59:08"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/Authorization_delete.json b/tests/cassettes/Authorization_delete.json index d7ca36a76..877f01d9c 100644 --- a/tests/cassettes/Authorization_delete.json +++ b/tests/cassettes/Authorization_delete.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA32PzWrEMAyEX2XRqYXsxo7z61uPe9vDnlpKUBzRmCaxiRUoXfbd60BLKYTqqPlmNLqB7UFLUclSCpnAuoygYWD2Qacpent6szys3cm4KcWVB7fYT2Tr5pD+uCAB9B70DWacKNqvFPjwBz48PF3OjxH8zY/x9IGTH2nLjpIZLc3cbn1A7AzcE2D3TnPUlTGFJKm6xhRdJosasVeZMTl2dVNRhaZWZU5NjJ0d73f61tr/Ki2ETH2LHG9mQuZHUR+z8ioyXTRaqeftI9/vM0qLSufVxgTjPAXQL7AGWuLCr91oTbuQd/B6/wJ2IBBahQEAAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "c436b2b44345c72ff906059f604991e7", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"20b124262b00d14b866e87bfb6c1eead\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4945", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0C4D3:6A43:29CFD9D7:53FBFAB1", "cache-control": "private, max-age=60, s-maxage=60", "last-modified": "Tue, 26 Aug 2014 03:07:47 GMT", "date": "Tue, 26 Aug 2014 03:10:41 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409025614"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:10:42"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Content-Length": "0", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "DELETE", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "encoding": null}, "headers": {"status": "204 No Content", "x-ratelimit-remaining": "4944", "x-github-media-type": "github.v3; param=full; format=json", "x-content-type-options": "nosniff", "content-security-policy": "default-src 'none'", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "x-github-request-id": "48A0C4D3:6A43:29CFDA26:53FBFAB1", "strict-transport-security": "max-age=31536000; includeSubdomains", "vary": "Accept-Encoding", "server": "GitHub.com", "access-control-allow-origin": "*", "x-ratelimit-limit": "5000", "x-served-by": "03d91026ad8428f4d9966d7434f9d82e", "access-control-allow-credentials": "true", "date": "Tue, 26 Aug 2014 03:10:41 GMT", "x-frame-options": "deny", "x-xss-protection": "1; mode=block", "x-ratelimit-reset": "1409025614"}, "status": {"message": "No Content", "code": 204}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:10:42"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": "{\"note\": \"testing github3.py\", \"note_url\": \"\", \"client_id\": \"\", \"client_secret\": \"\", \"scopes\": [\"gist\"]}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "104", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations"}, "response": {"body": {"encoding": "utf-8", "string": "{\"id\":168042711,\"url\":\"https://api.github.com/authorizations/168042711\",\"app\":{\"name\":\"testing github3.py\",\"url\":\"https://developer.github.com/v3/oauth_authorizations/\",\"client_id\":\"00000000000000000000\"},\"token\":\"1adaa26cd44a029e71873cc1d41083b92b537d40\",\"hashed_token\":\"a15e0358a43e47334ecebe4cea01431ca3dfb8bee264f7a4cda376e3154edebe\",\"token_last_eight\":\"2b537d40\",\"note\":\"testing github3.py\",\"note_url\":\"\",\"created_at\":\"2018-02-24T13:59:09Z\",\"updated_at\":\"2018-02-24T13:59:09Z\",\"scopes\":[\"gist\"],\"fingerprint\":null}"}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:09 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "519", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4994", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"ab07e9cdb257c7f7cd7994356db17e28\"", "Location": "https://api.github.com/authorizations/168042711", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.266743", "X-GitHub-Request-Id": "A298:3290:4DF695:8ED32F:5A916FAC"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/authorizations"}, "recorded_at": "2018-02-24T13:59:09"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "0", "Authorization": "Basic "}, "method": "DELETE", "uri": "https://api.github.com/authorizations/168042711"}, "response": {"body": {"encoding": null, "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:09 GMT", "Content-Type": "application/octet-stream", "Status": "204 No Content", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4993", "X-RateLimit-Reset": "1519483301", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.075041", "X-GitHub-Request-Id": "A298:3290:4DF6AE:8ED364:5A916FAD"}, "status": {"code": 204, "message": "No Content"}, "url": "https://api.github.com/authorizations/168042711"}, "recorded_at": "2018-02-24T13:59:09"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/Authorization_remove_scopes.json b/tests/cassettes/Authorization_remove_scopes.json index ea48ff129..42657c716 100644 --- a/tests/cassettes/Authorization_remove_scopes.json +++ b/tests/cassettes/Authorization_remove_scopes.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA32PzWrEMAyEX2XRqYXsxo7z61uPe9vDnlpKUBzRmCaxiRUoXfbd60BLKYTqqPlmNLqB7UFLUclSCpnAuoygYWD2Qacpent6szys3cm4KcWVB7fYT2Tr5pD+uCAB9B70DWacKNqvFPjwBz48PF3OjxH8zY/x9IGTH2nLjpIZLc3cbn1A7AzcE2D3TnPUlTGFJKm6xhRdJosasVeZMTl2dVNRhaZWZU5NjJ0d73f61tr/Ki2ETH2LHG9mQuZHUR+z8ioyXTRaqeftI9/vM0qLSufVxgTjPAXQL7AGWuLCr91oTbuQd/B6/wJ2IBBahQEAAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "6d7de9e645814cac34ea2a8d72ba3141", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"20b124262b00d14b866e87bfb6c1eead\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4956", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0C4D3:0875:29EC956B:53FBFA45", "cache-control": "private, max-age=60, s-maxage=60", "last-modified": "Tue, 26 Aug 2014 03:07:47 GMT", "date": "Tue, 26 Aug 2014 03:08:53 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409025614"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:08:54"}, {"request": {"body": {"string": "{\"rm_scopes\": [\"user\", \"public_repo\"]}", "encoding": "utf-8"}, "headers": {"Content-Length": "38", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA32PzWrEMAyEX2XRqYXsxo7z61uPe9vDnlpKUBzRmCaxiRUoXfbd60BLKYTqqPlmNLqB7UFLUclSCpnAuoygYWD2Qacpent6szys3cm4KcWVB7fYT2Tr5pD+uCAB9B70DWacKNqvFPjwBz48PF3OjxH8zY/x9IGTH2nLjpIZLc3cbn1A7AzcE2D3TnPUlTGFJKm6xhRdJosasVeZMTl2dVNRhaZWZU5NjJ0d73f61tr/Ki2ETH2LHG9mQuZHUR+z8ioyXTRaqeftI9/vM0qLSufVxgTjPAXQL7AGWuLCr91oTbuQd/B6/wJ2IBBahQEAAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "c436b2b44345c72ff906059f604991e7", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"20b124262b00d14b866e87bfb6c1eead\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4955", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0C4D3:0875:29EC95B5:53FBFA45", "cache-control": "private, max-age=60, s-maxage=60", "date": "Tue, 26 Aug 2014 03:08:53 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409025614"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:08:54"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": "{\"note\": \"testing github3.py\", \"note_url\": \"\", \"client_id\": \"\", \"client_secret\": \"\", \"scopes\": [\"gist\", \"user\", \"public_repo\"]}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "127", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations"}, "response": {"body": {"encoding": "utf-8", "string": "{\"id\":168042714,\"url\":\"https://api.github.com/authorizations/168042714\",\"app\":{\"name\":\"testing github3.py\",\"url\":\"https://developer.github.com/v3/oauth_authorizations/\",\"client_id\":\"00000000000000000000\"},\"token\":\"aa1d4975043a601e4d04e5334d33e45e5cabbaa4\",\"hashed_token\":\"a343b0667166915e18e9a7124327b1fa7aefc7d8a0154b5b289a3398aa848ff3\",\"token_last_eight\":\"5cabbaa4\",\"note\":\"testing github3.py\",\"note_url\":\"\",\"created_at\":\"2018-02-24T13:59:09Z\",\"updated_at\":\"2018-02-24T13:59:09Z\",\"scopes\":[\"gist\",\"user\",\"public_repo\"],\"fingerprint\":null}"}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:09 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "540", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4992", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"d3d2904e974d9b0634357b19353f5fc8\"", "Location": "https://api.github.com/authorizations/168042714", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.171428", "X-GitHub-Request-Id": "BB6A:328E:2CB73B:5CC624:5A916FAD"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/authorizations"}, "recorded_at": "2018-02-24T13:59:09"}, {"request": {"body": {"encoding": "utf-8", "string": "{\"rm_scopes\": [\"user\", \"public_repo\"]}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "38", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations/168042714"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA4VR206EMBD9FTPP7EJpgcJ3+KQxZAoDNLJt05ZNdLP/bnGjUaOxL016bnOmF9AjdKyWhSgbJjLY/AodLDG60OU5On2cdVw2dRzsKcctLtbrV4zampB/yiADdA66Cxg8UdJHClGb+e6m5Uf3kijfrUc602od+a8BZ57bPaT/kZTUw6rJxH4fF4pfDlwziPaZTMITfcGw0Nh/vCAXXBV13bC6bllFTFKLDSsFLxvFJmyQpqEZJRasEqpSpWyR81YiSiGniSfHd6t+xRB70vMSU041oFKIIqHGxj+L71h/a78X8YQxjYa7Q1kweSjKQynuGe+qtivah31VbvyXE4a0vQDdI8w6xF0UyKfLbWrVQ+/JWXjKYEr/QN55bVKe2db1+ga6a7hw9AEAAA==", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:09 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4991", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"818851fbea4822163acc76174ca281e1\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.045947", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "BB6A:328E:2CB748:5CC641:5A916FAD"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/authorizations/168042714"}, "recorded_at": "2018-02-24T13:59:09"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "0", "Authorization": "Basic "}, "method": "DELETE", "uri": "https://api.github.com/authorizations/168042714"}, "response": {"body": {"encoding": null, "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:09 GMT", "Content-Type": "application/octet-stream", "Status": "204 No Content", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4990", "X-RateLimit-Reset": "1519483301", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.061053", "X-GitHub-Request-Id": "BB6A:328E:2CB74A:5CC648:5A916FAD"}, "status": {"code": 204, "message": "No Content"}, "url": "https://api.github.com/authorizations/168042714"}, "recorded_at": "2018-02-24T13:59:09"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/Authorization_replace_scopes.json b/tests/cassettes/Authorization_replace_scopes.json index 0879735ad..0b5e224af 100644 --- a/tests/cassettes/Authorization_replace_scopes.json +++ b/tests/cassettes/Authorization_replace_scopes.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA32PTWvDMAyG/0rRaYO0seN8+rZjbz30tDGC4ojFLIlNrMBY6X+fAxtjEKbr++jRqxvYHrQUlSylkAmsywgaBmYfdJqit6c3y8PanYybUlx5cIv9RLZuDunPFiSA3oO+wYwTxfUrBT78gQ8PT5fzYwR//VFPHzj5kTZ3jMxoaeZ26wNiZ+CeALt3mmOujCkkSdU1pugyWdSIvcqMybGrm4oqNLUqc2qidna83+k7a/+rtBAy9S1yvJkJmR9FfczKq8h00WilnrePfL/PKC1KLcTGBOM8BdAvsAZa4PX+BQxYish3AQAA", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "3061975e1f37121b3751604ad153c687", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"def9f0eba11df7c937fd185809fab2f1\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4958", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0C4D3:6A40:12B3053A:53FBFA02", "cache-control": "private, max-age=60, s-maxage=60", "last-modified": "Tue, 26 Aug 2014 03:06:00 GMT", "date": "Tue, 26 Aug 2014 03:07:46 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409025614"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:07:47"}, {"request": {"body": {"string": "{\"scopes\": [\"user\", \"public_repo\"]}", "encoding": "utf-8"}, "headers": {"Content-Length": "35", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations/10716101"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA32PzWrEMAyEX2XRqYXsxo7z61uPe9vDnlpKUBzRmCaxiRUoXfbd60BLKYTqqPlmNLqB7UFLUclSCpnAuoygYWD2Qacpent6szys3cm4KcWVB7fYT2Tr5pD+uCAB9B70DWacKNqvFPjwBz48PF3OjxH8zY/x9IGTH2nLjpIZLc3cbn1A7AzcE2D3TnPUlTGFJKm6xhRdJosasVeZMTl2dVNRhaZWZU5NjJ0d73f61tr/Ki2ETH2LHG9mQuZHUR+z8ioyXTRaqeftI9/vM0qLSufVxgTjPAXQL7AGWuLCr91oTbuQd/B6/wJ2IBBahQEAAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept, Authorization, Cookie, X-GitHub-OTP, Accept-Encoding", "x-served-by": "03d91026ad8428f4d9966d7434f9d82e", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"20b124262b00d14b866e87bfb6c1eead\"", "access-control-allow-credentials": "true", "status": "200 OK", "x-ratelimit-remaining": "4957", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "48A0C4D3:6A40:12B30556:53FBFA02", "cache-control": "private, max-age=60, s-maxage=60", "date": "Tue, 26 Aug 2014 03:07:47 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409025614"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/authorizations/10716101"}, "recorded_at": "2014-08-26T03:07:47"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": "{\"note\": \"testing github3.py\", \"note_url\": \"\", \"client_id\": \"\", \"client_secret\": \"\", \"scopes\": [\"gist\"]}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "104", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations"}, "response": {"body": {"encoding": "utf-8", "string": "{\"id\":168042715,\"url\":\"https://api.github.com/authorizations/168042715\",\"app\":{\"name\":\"testing github3.py\",\"url\":\"https://developer.github.com/v3/oauth_authorizations/\",\"client_id\":\"00000000000000000000\"},\"token\":\"4e23a28968db9098ef5678825e2f843f67f415ab\",\"hashed_token\":\"22eef884dcf505aaa4fca8180bbf7be13c92f05372cc67be01c9b6837f52e8d4\",\"token_last_eight\":\"67f415ab\",\"note\":\"testing github3.py\",\"note_url\":\"\",\"created_at\":\"2018-02-24T13:59:10Z\",\"updated_at\":\"2018-02-24T13:59:10Z\",\"scopes\":[\"gist\"],\"fingerprint\":null}"}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:10 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "519", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4989", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"533cce8fb3c82d4a730b066a32164a29\"", "Location": "https://api.github.com/authorizations/168042715", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.139574", "X-GitHub-Request-Id": "A29C:328E:2CB754:5CC668:5A916FAE"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/authorizations"}, "recorded_at": "2018-02-24T13:59:10"}, {"request": {"body": {"encoding": "utf-8", "string": "{\"scopes\": [\"user\", \"public_repo\"]}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "35", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations/168042715"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA4VR207EIBD9FTPP3S3QG8t3+KQxhNJhS+wCAbqJbvbfpW40ajTyOOc2Z7iAnUDQnpOWDbSrYI0LCJhzDknUtQp2f7R5Xse99qdarXn20b6qbL1L9acMKlAhgLiAUycs+owpW3e8u2mbfXgplO/WE55x8QHj14BzU/stRP5IKmq9WHRZbusC+eXBtYLsn9EVvNBnlWac5MeEMUTDeTtp05FOKdUarTjlZBzNMCJt9IEZ0jUD07ovA0L1Yex5M5iOIZ/a4vhuJReVskR7nHPJ6QfT0k6NBXU+/1l8w+St/VYkosplNbU5MEL5jrAda+9pI7qDoORhO1WY/uUkXa6XQDzCmjAWUVjHxWoZMXh4qsCUD8AYonUlyK3Lcn0DT9fr8O0BAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:10 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4988", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"4b9696e161f83dcce02c21c348e85abb\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.150612", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "A29C:328E:2CB758:5CC672:5A916FAE"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/authorizations/168042715"}, "recorded_at": "2018-02-24T13:59:10"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "0", "Authorization": "Basic "}, "method": "DELETE", "uri": "https://api.github.com/authorizations/168042715"}, "response": {"body": {"encoding": null, "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:10 GMT", "Content-Type": "application/octet-stream", "Status": "204 No Content", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4987", "X-RateLimit-Reset": "1519483301", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.059198", "X-GitHub-Request-Id": "A29C:328E:2CB764:5CC68D:5A916FAE"}, "status": {"code": 204, "message": "No Content"}, "url": "https://api.github.com/authorizations/168042715"}, "recorded_at": "2018-02-24T13:59:10"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/GitHub_authorize.json b/tests/cassettes/GitHub_authorize.json index 59075b338..c7a1a108f 100644 --- a/tests/cassettes/GitHub_authorize.json +++ b/tests/cassettes/GitHub_authorize.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"string": "{\"note\": \"Test authorization\", \"client_secret\": \"\", \"client_id\": \"\", \"note_url\": \"http://example.com\"}", "encoding": "utf-8"}, "headers": {"Content-Length": "102", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "User-Agent": "github3.py/1.0.0b1", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations"}, "response": {"body": {"string": "{\"id\":10716101,\"url\":\"https://api.github.com/authorizations/10716101\",\"app\":{\"name\":\"Test authorization (API)\",\"url\":\"http://example.com\",\"client_id\":\"00000000000000000000\"},\"token\":\"3cc51e13b9c5b2158aad32cc4ab897e7ac8364e9\",\"note\":\"Test authorization\",\"note_url\":\"http://example.com\",\"created_at\":\"2014-08-26T02:59:33Z\",\"updated_at\":\"2014-08-26T02:59:33Z\",\"scopes\":[]}", "encoding": "utf-8"}, "headers": {"content-length": "369", "vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"af5e035a265070984e2b70fe601d470d\"", "location": "https://api.github.com/authorizations/10716101", "access-control-allow-credentials": "true", "status": "201 Created", "x-ratelimit-remaining": "4925", "x-github-media-type": "github.v3; param=full; format=json", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "x-github-request-id": "48A0C4D3:4A6E:2A216161:53FBF815", "cache-control": "private, max-age=60, s-maxage=60", "date": "Tue, 26 Aug 2014 02:59:33 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "strict-transport-security": "max-age=31536000; includeSubdomains", "server": "GitHub.com", "x-ratelimit-limit": "5000", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1409022013"}, "status": {"message": "Created", "code": 201}, "url": "https://api.github.com/authorizations"}, "recorded_at": "2014-08-26T02:59:34"}], "recorded_with": "betamax/0.4.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": "{\"note\": \"Test authorization\", \"note_url\": \"http://example.com\", \"client_id\": \"\", \"client_secret\": \"\"}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "102", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/authorizations"}, "response": {"body": {"encoding": "utf-8", "string": "{\"id\":168042778,\"url\":\"https://api.github.com/authorizations/168042778\",\"app\":{\"name\":\"Test authorization\",\"url\":\"http://example.com\",\"client_id\":\"00000000000000000000\"},\"token\":\"4107db863bdeb2b7d669c74b63192f2205c8e48b\",\"hashed_token\":\"18a2cd7312840f313366dce10184c1b309a98e84355402a2265d6fadf36f4ee4\",\"token_last_eight\":\"05c8e48b\",\"note\":\"Test authorization\",\"note_url\":\"http://example.com\",\"created_at\":\"2018-02-24T13:59:38Z\",\"updated_at\":\"2018-02-24T13:59:38Z\",\"scopes\":[],\"fingerprint\":null}"}, "headers": {"Server": "GitHub.com", "Date": "Sat, 24 Feb 2018 13:59:38 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "496", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4986", "X-RateLimit-Reset": "1519483301", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"eefd90fb26f659021ba3d06ec4c10e29\"", "Location": "https://api.github.com/authorizations/168042778", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.094263", "X-GitHub-Request-Id": "BB70:328E:2CBCDE:5CD28B:5A916FCA"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/authorizations"}, "recorded_at": "2018-02-24T13:59:38"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/integration/test_auths.py b/tests/integration/test_auths.py index e270fd871..d8067f1b9 100644 --- a/tests/integration/test_auths.py +++ b/tests/integration/test_auths.py @@ -13,16 +13,28 @@ def test_add_scopes(self): self.basic_login() cassette_name = self.cassette_name('add_scopes') with self.recorder.use_cassette(cassette_name): - auth = self.gh.authorization(10716101) + created_auth = self.gh.authorize( + username=self.user, + password=self.password, + scopes=['gist'], + note='testing github3.py', + ) + auth = self.gh.authorization(created_auth.id) assert isinstance(auth, github3.auths.Authorization) assert auth.add_scopes(['user']) is True + auth.delete() def test_delete(self): """Test the ability to delete an authorization.""" self.basic_login() cassette_name = self.cassette_name('delete') with self.recorder.use_cassette(cassette_name): - auth = self.gh.authorization(10716101) + auth = self.gh.authorize( + username=self.user, + password=self.password, + scopes=['gist'], + note='testing github3.py', + ) assert isinstance(auth, github3.auths.Authorization) assert auth.delete() is True @@ -31,15 +43,27 @@ def test_remove_scopes(self): self.basic_login() cassette_name = self.cassette_name('remove_scopes') with self.recorder.use_cassette(cassette_name): - auth = self.gh.authorization(10716101) + auth = self.gh.authorize( + username=self.user, + password=self.password, + scopes=['gist', 'user', 'public_repo'], + note='testing github3.py', + ) assert isinstance(auth, github3.auths.Authorization) assert auth.remove_scopes(['user', 'public_repo']) is True + auth.delete() def test_replace_scopes(self): """Test the ability to replace scopes on an authorization.""" self.basic_login() cassette_name = self.cassette_name('replace_scopes') with self.recorder.use_cassette(cassette_name): - auth = self.gh.authorization(10716101) + auth = self.gh.authorize( + username=self.user, + password=self.password, + scopes=['gist'], + note='testing github3.py', + ) assert isinstance(auth, github3.auths.Authorization) assert auth.replace_scopes(['user', 'public_repo']) is True + auth.delete() diff --git a/tests/unit/json/authorization_example b/tests/unit/json/authorization_example index be380d9e3..81114a019 100644 --- a/tests/unit/json/authorization_example +++ b/tests/unit/json/authorization_example @@ -5,6 +5,8 @@ "public_repo" ], "token": "abc123", + "token_last_eight": "12345678", + "hashed_token": "25f94a2a5c7fbaf499c665bc73d67c1c87e496da8985131633ee0a95819db2e8", "app": { "url": "http://my-github-app.com", "name": "my github app", @@ -13,5 +15,6 @@ "note": "optional note", "note_url": "http://optional/note/url", "updated_at": "2011-09-06T20:39:23Z", - "created_at": "2011-09-06T17:26:27Z" + "created_at": "2011-09-06T17:26:27Z", + "fingerprint": "jklmnop12345678" } From 0751ee8fd70c6126626311850b1e981b11f5ec61 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 24 Feb 2018 09:25:21 -0600 Subject: [PATCH 25/56] Remove GistComment dependence on BaseComment Update our example response for unit tests to make this more testable and an accurate representation of what github3.py gets back. --- github3/gists/comment.py | 100 +++++++++++++++++++++------ tests/unit/json/gist_comment_example | 3 + 2 files changed, 83 insertions(+), 20 deletions(-) diff --git a/github3/gists/comment.py b/github3/gists/comment.py index abaf22da5..0f231cc95 100644 --- a/github3/gists/comment.py +++ b/github3/gists/comment.py @@ -1,42 +1,102 @@ # -*- coding: utf-8 -*- -""" -github3.gists.comment ---------------------- - -Module containing the logic for a GistComment - -""" +"""Module containing the logic for a GistComment.""" from __future__ import unicode_literals +from .. import decorators +from .. import models from .. import users -from ..models import BaseComment -class GistComment(BaseComment): +class GistComment(models.GitHubCore): + """Representation of a comment left on a :class:`~github3.gists.Gist`. + + See also: http://developer.github.com/v3/gists/comments/ - """This object represents a comment on a gist. + .. versionchanged:: 1.0.0 - Two comment instances can be checked like so:: + The ``links``, ``html_url``, and ``pull_request_url`` attributes were + removed as none of them exist in the response from GitHub. - c1 == c2 - c1 != c2 + This object has the following attributes: - And is equivalent to:: + .. attribute:: author_association - c1.id == c2.id - c1.id != c2.id + The comment author's (:attr:`user`) association with this gist. - See also: http://developer.github.com/v3/gists/comments/ + .. attribute:: body + + The markdown formatted original text written by the author. + + .. attribute:: body_html + + The HTML formatted comment body. + + .. attribute:: body_text + + The plain-text formatted comment body. + + .. attribute:: created_at + A :class:`~datetime.datetime` object representing the date and time + when this comment was created. + + .. attribute:: id + + The unique identifier for this comment. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` object representing the date and time + when this comment was most recently updated. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` representing the author of this + comment. """ def _update_attributes(self, comment): - self._api = self._get_attribute(comment, 'url') - #: :class:`User ` who made the comment - #: Unless it is not associated with an account + self._api = comment['url'] + self.author_association = comment['author_association'] + self.body = comment['body'] + self.body_html = comment['body_html'] + self.body_text = comment['body_text'] + self.created_at = comment['created_at'] + self.id = comment['id'] + self.updated_at = comment['updated_at'] self.user = self._class_attribute( comment, 'user', users.ShortUser, self, ) def _repr(self): return ''.format(self.user.login) + + @decorators.requires_auth + def delete(self): + """Delete this comment from the gist. + + :returns: + True if successful, False otherwise + :rtype: + bool + """ + return self._boolean(self._delete(self._api), 204, 404) + + @decorators.requires_auth + def edit(self, body): + """Edit this comment. + + :param str body: + (required), new body of the comment, Markdown-formatted + :returns: + True if successful, False otherwise + :rtype: + bool + """ + if body: + json = self._json(self._patch(self._api, + json={'body': body}), 200) + if json: + self._update_attributes(json) + return True + return False diff --git a/tests/unit/json/gist_comment_example b/tests/unit/json/gist_comment_example index a07723840..a2125a5ef 100644 --- a/tests/unit/json/gist_comment_example +++ b/tests/unit/json/gist_comment_example @@ -1,5 +1,8 @@ { + "author_association": "OWNER", "body": "I was using curl, but this is awesome, too :)\r\n\r\n`curl -u -XDELETE https://api.github.com/gists//comments/`", + "body_html": "I was using curl, but this is awesome, too", + "body_text": "I was using curl, but this is awesome, too", "created_at": "2012-12-17T19:56:05Z", "id": 655725, "updated_at": "2012-12-17T19:56:05Z", From 373a5821be7988c53a7840a7bc5c1c87b01ae675 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 24 Feb 2018 10:03:05 -0600 Subject: [PATCH 26/56] Fix-up GistFile docstring --- github3/gists/file.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/github3/gists/file.py b/github3/gists/file.py index 661c4d2dd..9ea8dc9d1 100644 --- a/github3/gists/file.py +++ b/github3/gists/file.py @@ -21,8 +21,10 @@ def _repr(self): def content(self): """Retrieve contents of file from key 'raw_url'. - :returns: unaltered, untruncated contents of file. - :rtype: bytes + :returns: + unaltered, untruncated contents of file. + :rtype: + bytes """ resp = self._get(self.raw_url) if self._boolean(resp, 200, 404): From b21bd444e8dfa9b3b094c1f7821f5fd28ab862cd Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 24 Feb 2018 10:06:38 -0600 Subject: [PATCH 27/56] Touch up ShortGist and Gist docstrings --- github3/gists/gist.py | 105 +++++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 38 deletions(-) diff --git a/github3/gists/gist.py b/github3/gists/gist.py index a3c17d5f0..24b3fe1f2 100644 --- a/github3/gists/gist.py +++ b/github3/gists/gist.py @@ -63,9 +63,12 @@ def _repr(self): def create_comment(self, body): """Create a comment on this gist. - :param str body: (required), body of the comment - :returns: Created comment or None - :rtype: :class:`~github3.gists.comment.GistComment` + :param str body: + (required), body of the comment + :returns: + Created comment or None + :rtype: + :class:`~github3.gists.comment.GistComment` """ json = None if body: @@ -77,8 +80,10 @@ def create_comment(self, body): def delete(self): """Delete this gist. - :returns: Whether the deletion was successful or not - :rtype: bool + :returns: + Whether the deletion was successful or not + :rtype: + bool """ return self._boolean(self._delete(self._api), 204, 404) @@ -86,14 +91,17 @@ def delete(self): def edit(self, description='', files={}): """Edit this gist. - :param str description: (optional), description of the gist - :param dict files: (optional), files that make up this gist; the - key(s) should be the file name(s) and the values should be another - (optional) dictionary with (optional) keys: 'content' and - 'filename' where the former is the content of the file and the - latter is the new name of the file. - :returns: Whether the edit was successful or not - :rtype: bool + :param str description: + (optional), description of the gist + :param dict files: + (optional), files that make up this gist; the key(s) should be the + file name(s) and the values should be another (optional) dictionary + with (optional) keys: 'content' and 'filename' where the former is + the content of the file and the latter is the new name of the file. + :returns: + Whether the edit was successful or not + :rtype: + bool """ data = {} json = None @@ -112,8 +120,10 @@ def edit(self, description='', files={}): def fork(self): """Fork this gist. - :returns: New gist if successfully forked, ``None`` otherwise - :rtype: :class:`~github3.gists.gist.ShortGist` + :returns: + New gist if successfully forked, ``None`` otherwise + :rtype: + :class:`~github3.gists.gist.ShortGist` """ url = self._build_url('forks', base_url=self._api) json = self._json(self._post(url), 201) @@ -123,8 +133,10 @@ def fork(self): def is_starred(self): """Check to see if this gist is starred by the authenticated user. - :returns: True if it is starred, False otherwise - :rtype: bool + :returns: + True if it is starred, False otherwise + :rtype: + bool """ url = self._build_url('star', base_url=self._api) return self._boolean(self._get(url), 204, 404) @@ -132,12 +144,15 @@ def is_starred(self): def comments(self, number=-1, etag=None): """Iterate over comments on this gist. - :param int number: (optional), number of comments to iterate over. + :param int number: + (optional), number of comments to iterate over. Default: -1 will iterate over all comments on the gist - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of comments - :rtype: :class:`~github3.gists.comment.GistComment` + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of comments + :rtype: + :class:`~github3.gists.comment.GistComment` """ url = self._build_url('comments', base_url=self._api) return self._iter(int(number), url, comment.GistComment, etag=etag) @@ -154,13 +169,16 @@ def commits(self, number=-1, etag=None): Added param ``etag``. - :param int number: (optional), number of commits to iterate over. + :param int number: + (optional), number of commits to iterate over. Default: -1 will iterate over all commits associated with this gist. - :param str etag: (optional), ETag from a previous request to this - endpoint. - :returns: generator of the gist's history - :rtype: :class:`~github3.gists.history.GistHistory` + :param str etag: + (optional), ETag from a previous request to this endpoint. + :returns: + generator of the gist's history + :rtype: + :class:`~github3.gists.history.GistHistory` """ url = self._build_url('commits', base_url=self._api) return self._iter(int(number), url, history.GistHistory) @@ -172,12 +190,15 @@ def forks(self, number=-1, etag=None): Added params ``number`` and ``etag``. - :param int number: (optional), number of forks to iterate over. + :param int number: + (optional), number of forks to iterate over. Default: -1 will iterate over all forks of this gist. - :param str etag: (optional), ETag from a previous request to this - endpoint. - :returns: generator of gists - :rtype: :class:`~github3.gists.gist.ShortGist` + :param str etag: + (optional), ETag from a previous request to this endpoint. + :returns: + generator of gists + :rtype: + :class:`~github3.gists.gist.ShortGist` """ url = self._build_url('forks', base_url=self._api) return self._iter(int(number), url, ShortGist, etag=etag) @@ -186,8 +207,10 @@ def forks(self, number=-1, etag=None): def star(self): """Star this gist. - :returns: True if successful, False otherwise - :rtype: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('star', base_url=self._api) return self._boolean(self._put(url), 204, 404) @@ -196,8 +219,10 @@ def star(self): def unstar(self): """Un-star this gist. - :returns: True if successful, False otherwise - :rtype: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ url = self._build_url('star', base_url=self._api) return self._boolean(self._delete(url), 204, 404) @@ -324,12 +349,16 @@ def _repr(self): def to_gist(self): """Retrieve the full Gist representation of this fork. - :returns: The Gist if retrieving it was successful or ``None`` - :rtype: :class:`~github3.gists.gist.Gist` + :returns: + The Gist if retrieving it was successful or ``None`` + :rtype: + :class:`~github3.gists.gist.Gist` """ json = self._json(self._get(self.url), 200) return self._instance_or_null(Gist, json) + refresh = to_gist + class Gist(_Gist): """This object constitutes the full representation of a Gist. From 58eef7755e5d58f467734d5ade12b70db1b29518 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 24 Feb 2018 10:08:23 -0600 Subject: [PATCH 28/56] Clean up gists imports and GistHistory docstrings --- github3/gists/file.py | 4 ++-- github3/gists/gist.py | 6 +++--- github3/gists/history.py | 25 ++++++------------------- 3 files changed, 11 insertions(+), 24 deletions(-) diff --git a/github3/gists/file.py b/github3/gists/file.py index 9ea8dc9d1..83c2a0e57 100644 --- a/github3/gists/file.py +++ b/github3/gists/file.py @@ -2,10 +2,10 @@ """Module containing the GistFile object.""" from __future__ import unicode_literals -from ..models import GitHubCore +from .. import models -class _GistFile(GitHubCore): +class _GistFile(models.GitHubCore): """Base for GistFile classes.""" def _update_attributes(self, gistfile): diff --git a/github3/gists/gist.py b/github3/gists/gist.py index 24b3fe1f2..f3720d5ac 100644 --- a/github3/gists/gist.py +++ b/github3/gists/gist.py @@ -4,16 +4,16 @@ from json import dumps +from .. import models from .. import users -from ..models import GitHubCore from ..decorators import requires_auth from . import comment from . import file as gistfile from . import history -class _Gist(GitHubCore): +class _Gist(models.GitHubCore): """This object holds all the information returned by Github about a gist. With it you can comment on or fork the gist (assuming you are @@ -309,7 +309,7 @@ class ShortGist(_Gist): class_name = 'ShortGist' -class GistFork(GitHubCore): +class GistFork(models.GitHubCore): """This object represents a forked Gist. This has a subset of attributes of a diff --git a/github3/gists/history.py b/github3/gists/history.py index 04220eb0c..698680c68 100644 --- a/github3/gists/history.py +++ b/github3/gists/history.py @@ -2,11 +2,11 @@ """Module containing the GistHistory object.""" from __future__ import unicode_literals +from .. import models from .. import users -from ..models import GitHubCore -class GistHistory(GitHubCore): +class GistHistory(models.GitHubCore): """This object represents one version (or revision) of a gist. The GitHub API returns the following attributes: @@ -53,27 +53,12 @@ class GistHistory(GitHubCore): def _update_attributes(self, history): self.url = self._api = history['url'] - - #: SHA of the commit associated with this version self.version = history['version'] - - #: user who made these changes self.user = users.ShortUser(history['user'], self) - - #: dict containing the change status; see also: deletions, additions, - #: total self.change_status = history['change_status'] - - #: number of additions made self.additions = self.change_status['additions'] - - #: number of deletions made self.deletions = self.change_status['deletions'] - - #: total number of changes made self.total = self.change_status['total'] - - #: datetime representation of when the commit was made self.committed_at = self._strptime(history['committed_at']) def _repr(self): @@ -82,8 +67,10 @@ def _repr(self): def gist(self): """Retrieve the gist at this version. - :returns: the gist at this point in history or ``None`` - :rtype: :class:`Gist ` + :returns: + the gist at this point in history or ``None`` + :rtype: + :class:`Gist ` """ from .gist import Gist json = self._json(self._get(self._api), 200) From 86e66e082e3f133abeef3d611669ce9f0328c123 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Sat, 24 Feb 2018 19:02:09 -0600 Subject: [PATCH 29/56] Ensure created_at and updated_at are datetimes --- github3/gists/comment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/github3/gists/comment.py b/github3/gists/comment.py index 0f231cc95..2e6fa9a66 100644 --- a/github3/gists/comment.py +++ b/github3/gists/comment.py @@ -61,9 +61,9 @@ def _update_attributes(self, comment): self.body = comment['body'] self.body_html = comment['body_html'] self.body_text = comment['body_text'] - self.created_at = comment['created_at'] + self.created_at = self._strptime(comment['created_at']) self.id = comment['id'] - self.updated_at = comment['updated_at'] + self.updated_at = self._strptime(comment['updated_at']) self.user = self._class_attribute( comment, 'user', users.ShortUser, self, ) From 787e9b084a797b8869bc23d39fd757ed05cfedfc Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Wed, 28 Feb 2018 05:43:20 -0600 Subject: [PATCH 30/56] Update IssueComment for consistency with project This removes the unnecessary reliance on BaseComment and directly accesses the properties we expect to be there. --- github3/events.py | 74 ++++++++++- github3/issues/comment.py | 116 ++++++++++++++---- .../cassettes/PullRequest_create_comment.json | 2 +- .../cassettes/PullRequest_issue_comments.json | 2 +- tests/cassettes/Repository_events.json | 2 +- tests/unit/json/comment_example | 2 + tests/unit/test_events.py | 3 +- 7 files changed, 170 insertions(+), 31 deletions(-) diff --git a/github3/events.py b/github3/events.py index bebfc96d7..162aa3570 100644 --- a/github3/events.py +++ b/github3/events.py @@ -292,6 +292,77 @@ def to_issue(self): refresh = to_issue +class EventIssueComment(models.GitHubCore): + """Representation of a comment left on an issue. + + See also: http://developer.github.com/v3/issues/comments/ + + This object has the following attributes: + + .. attribute:: author_association + + The association of the author (:attr:`user`) with the repository + this issue belongs to. + + .. attribute:: body + + The markdown formatted original text written by the author. + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + when this comment was created. + + .. attribute:: html_url + + The URL to view this comment in a browser. + + .. attribute:: id + + The unique identifier for this comment. + + .. attribute:: issue_url + + The URL of the parent issue in the API. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` object representing the date and time + when this comment was most recently updated. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` representing the author of this + comment. + """ + + def _update_attributes(self, comment): + from . import users + self._api = comment['url'] + self.author_association = comment['author_association'] + self.body = comment['body'] + self.created_at = self._strptime(comment['created_at']) + self.html_url = comment['html_url'] + self.id = comment['id'] + self.issue_url = comment['issue_url'] + self.updated_at = self._strptime(comment['updated_at']) + self.user = users.ShortUser(comment['user'], self) + + def to_issue_comment(self): + """Retrieve the full IssueComment object for this comment. + + :returns: + All the information about an IssueComment. + :rtype: + :class:`~github3.issues.comment.IssueComment` + """ + from .issues import comment + json = self._json(self._get(self.url), 200) + return self._instance_or_null(comment.IssueComment, json) + + refresh = to_issue_comment + + class Event(models.GitHubCore): """Represents an event as returned by the API. @@ -411,11 +482,10 @@ def _gist(payload, session): def _issuecomm(payload, session): - from .issues.comment import IssueComment if payload.get('issue'): payload['issue'] = EventIssue(payload['issue'], session) if payload.get('comment'): - payload['comment'] = IssueComment(payload['comment'], session) + payload['comment'] = EventIssueComment(payload['comment'], session) return payload diff --git a/github3/issues/comment.py b/github3/issues/comment.py index 88f4f73f0..52313892a 100644 --- a/github3/issues/comment.py +++ b/github3/issues/comment.py @@ -1,46 +1,114 @@ # -*- coding: utf-8 -*- +"""Module with class(es) representing issue comments.""" from __future__ import unicode_literals +from .. import decorators +from .. import models from .. import users -from ..utils import timestamp_parameter -from ..models import BaseComment +from .. import utils -class IssueComment(BaseComment): - """The :class:`IssueComment ` object. This structures and - handles the comments on issues specifically. +class IssueComment(models.GitHubCore): + """Representation of a comment left on an issue. - Two comment instances can be checked like so:: + See also: http://developer.github.com/v3/issues/comments/ - c1 == c2 - c1 != c2 + This object has the following attributes: - And is equivalent to:: + .. attribute:: author_association - c1.id == c2.id - c1.id != c2.id + The association of the author (:attr:`user`) with the repository + this issue belongs to. - See also: http://developer.github.com/v3/issues/comments/ + .. attribute:: body + + The markdown formatted original text written by the author. + + .. attribute:: body_html + + The HTML formatted comment body. + + .. attribute:: body_text + + The plain-text formatted comment body. + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + when this comment was created. + + .. attribute:: html_url + + The URL to view this comment in a browser. + + .. attribute:: id + + The unique identifier for this comment. + + .. attribute:: issue_url + + The URL of the parent issue in the API. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` object representing the date and time + when this comment was most recently updated. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` representing the author of this + comment. """ + def _update_attributes(self, comment): - super(IssueComment, self)._update_attributes(comment) + self._api = comment['url'] + self.author_association = comment['author_association'] + self.body = comment['body'] + self.body_html = comment['body_html'] + self.body_text = comment['body_text'] + self.created_at = self._strptime(comment['created_at']) + self.html_url = comment['html_url'] + self.id = comment['id'] + self.issue_url = comment['issue_url'] + self.updated_at = self._strptime(comment['updated_at']) + self.user = users.ShortUser(comment['user'], self) - #: :class:`User ` who made the comment - self.user = self._class_attribute( - comment, 'user', users.ShortUser, self, - ) + def _repr(self): + return ''.format(self.user.login) - #: Issue url (not a template) - self.issue_url = self._get_attribute(comment, 'issue_url') + @decorators.requires_auth + def delete(self): + """Delete this comment. - #: Html url (not a template) - self.html_url = self._get_attribute(comment, 'html_url') + :returns: bool + """ + return self._boolean(self._delete(self._api), 204, 404) - def _repr(self): - return ''.format(self.user.login) + @decorators.requires_auth + def edit(self, body): + """Edit this comment. + + :param str body: (required), new body of the comment, Markdown + formatted + :returns: bool + """ + if body: + json = self._json(self._patch(self._api, + json={'body': body}), 200) + if json: + self._update_attributes(json) + return True + return False def issue_comment_params(sort, direction, since): + """Properly format parameters for issue comments. + + .. warning:: + + This is not a public API designed for users of github3.py. + + """ params = {} if sort in ('created', 'updated'): @@ -49,7 +117,7 @@ def issue_comment_params(sort, direction, since): if direction in ('asc', 'desc'): params['direction'] = direction - since = timestamp_parameter(since) + since = utils.timestamp_parameter(since) if since: params['since'] = since diff --git a/tests/cassettes/PullRequest_create_comment.json b/tests/cassettes/PullRequest_create_comment.json index fe37e8a28..d3a0a3c78 100644 --- a/tests/cassettes/PullRequest_create_comment.json +++ b/tests/cassettes/PullRequest_create_comment.json @@ -1 +1 @@ -{"http_interactions": [{"response": {"body": {"string": "", "base64_string": "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", "encoding": "utf-8"}, "headers": {"Access-Control-Allow-Origin": "*", "Content-Encoding": "gzip", "Last-Modified": "Sun, 06 Nov 2016 10:25:43 GMT", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Content-Security-Policy": "default-src 'none'", "Cache-Control": "private, max-age=60, s-maxage=60", "X-Frame-Options": "deny", "X-GitHub-Request-Id": "B483:551B:1D96BA2:25469FA:58A07F58", "ETag": "W/\"78dba4ce25b81699f897a75270193b9a\"", "X-Served-By": "46808ddc41c302090177e58148908b23", "Date": "Sun, 12 Feb 2017 15:29:28 GMT", "Status": "200 OK", "Transfer-Encoding": "chunked", "X-XSS-Protection": "1; mode=block", "Content-Type": "application/json; charset=utf-8", "X-RateLimit-Limit": "5000", "X-Content-Type-Options": "nosniff", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-RateLimit-Remaining": "4987", "X-RateLimit-Reset": "1486914697", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Server": "GitHub.com"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/423", "status": {"message": "OK", "code": 200}}, "recorded_at": "2017-02-12T15:29:28", "request": {"body": {"string": "", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/423", "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept": "application/vnd.github.v3.full+json", "Authorization": "Basic ", "Content-Type": "application/json", "Accept-Encoding": "gzip, deflate", "Accept-Charset": "utf-8", "Connection": "keep-alive"}, "method": "GET"}}, {"response": {"body": {"string": "{\"url\":\"https://api.github.com/repos/sigmavirus24/github3.py/issues/comments/279225874\",\"html_url\":\"https://github.com/sigmavirus24/github3.py/pull/423#issuecomment-279225874\",\"issue_url\":\"https://api.github.com/repos/sigmavirus24/github3.py/issues/423\",\"id\":279225874,\"user\":{\"login\":\"gh3test\",\"id\":2354350,\"avatar_url\":\"https://avatars.githubusercontent.com/u/2354350?v=3\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gh3test\",\"html_url\":\"https://github.com/gh3test\",\"followers_url\":\"https://api.github.com/users/gh3test/followers\",\"following_url\":\"https://api.github.com/users/gh3test/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gh3test/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gh3test/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gh3test/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gh3test/orgs\",\"repos_url\":\"https://api.github.com/users/gh3test/repos\",\"events_url\":\"https://api.github.com/users/gh3test/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gh3test/received_events\",\"type\":\"User\",\"site_admin\":false},\"created_at\":\"2017-02-12T15:29:28Z\",\"updated_at\":\"2017-02-12T15:29:28Z\",\"body_html\":\"

Testing pull request comment

\",\"body_text\":\"Testing pull request comment\",\"body\":\"Testing pull request comment\"}", "encoding": "utf-8"}, "headers": {"Access-Control-Allow-Origin": "*", "Server": "GitHub.com", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Content-Security-Policy": "default-src 'none'", "Cache-Control": "private, max-age=60, s-maxage=60", "Status": "201 Created", "X-Frame-Options": "deny", "X-GitHub-Request-Id": "B483:551B:1D96BBA:2546A0A:58A07F58", "ETag": "\"7405df0ff82e6ba26188b8c2d3433eaf\"", "X-Served-By": "76d9828c7e4f1d910f7ba069e90ce976", "Date": "Sun, 12 Feb 2017 15:29:29 GMT", "Location": "https://api.github.com/repos/sigmavirus24/github3.py/issues/comments/279225874", "X-XSS-Protection": "1; mode=block", "Content-Type": "application/json; charset=utf-8", "X-RateLimit-Limit": "5000", "X-Content-Type-Options": "nosniff", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-RateLimit-Remaining": "4986", "X-RateLimit-Reset": "1486914697", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Content-Length": "1340"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/issues/423/comments", "status": {"message": "Created", "code": 201}}, "recorded_at": "2017-02-12T15:29:29", "request": {"body": {"string": "{\"body\": \"Testing pull request comment\"}", "encoding": "utf-8"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/issues/423/comments", "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept": "application/vnd.github.v3.full+json", "Authorization": "Basic ", "Content-Type": "application/json", "Content-Length": "40", "Accept-Encoding": "gzip, deflate", "Accept-Charset": "utf-8", "Connection": "keep-alive"}, "method": "POST"}}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Authorization": "Basic "}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/423"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 25 Feb 2018 13:33:43 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4999", "X-RateLimit-Reset": "1519569223", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "W/\"487b084939cefb9a4cbf03a5a6e57153\"", "Last-Modified": "Wed, 31 Jan 2018 04:12:14 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.284420", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C0B6:328F:7E7D25:1826BC8:5A92BB37"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/423"}, "recorded_at": "2018-02-25T13:33:43"}, {"request": {"body": {"encoding": "utf-8", "string": "{\"body\": \"Testing pull request comment\"}"}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json", "Content-Length": "40", "Authorization": "Basic "}, "method": "POST", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/issues/423/comments"}, "response": {"body": {"encoding": "utf-8", "string": "{\"url\":\"https://api.github.com/repos/sigmavirus24/github3.py/issues/comments/368309777\",\"html_url\":\"https://github.com/sigmavirus24/github3.py/pull/423#issuecomment-368309777\",\"issue_url\":\"https://api.github.com/repos/sigmavirus24/github3.py/issues/423\",\"id\":368309777,\"user\":{\"login\":\"gh3test\",\"id\":2354350,\"avatar_url\":\"https://avatars2.githubusercontent.com/u/2354350?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gh3test\",\"html_url\":\"https://github.com/gh3test\",\"followers_url\":\"https://api.github.com/users/gh3test/followers\",\"following_url\":\"https://api.github.com/users/gh3test/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gh3test/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gh3test/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gh3test/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gh3test/orgs\",\"repos_url\":\"https://api.github.com/users/gh3test/repos\",\"events_url\":\"https://api.github.com/users/gh3test/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gh3test/received_events\",\"type\":\"User\",\"site_admin\":false},\"created_at\":\"2018-02-25T13:33:43Z\",\"updated_at\":\"2018-02-25T13:33:43Z\",\"author_association\":\"NONE\",\"body_html\":\"

Testing pull request comment

\",\"body_text\":\"Testing pull request comment\",\"body\":\"Testing pull request comment\"}"}, "headers": {"Server": "GitHub.com", "Date": "Sun, 25 Feb 2018 13:33:43 GMT", "Content-Type": "application/json; charset=utf-8", "Content-Length": "1369", "Status": "201 Created", "X-RateLimit-Limit": "5000", "X-RateLimit-Remaining": "4998", "X-RateLimit-Reset": "1519569223", "Cache-Control": "private, max-age=60, s-maxage=60", "Vary": "Accept, Authorization, Cookie, X-GitHub-OTP", "ETag": "\"c7e12c375d110b824c9231c4f61a2b02\"", "Location": "https://api.github.com/repos/sigmavirus24/github3.py/issues/comments/368309777", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.284784", "X-GitHub-Request-Id": "C0B6:328F:7E7D42:1826C06:5A92BB37"}, "status": {"code": 201, "message": "Created"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/issues/423/comments"}, "recorded_at": "2018-02-25T13:33:43"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/PullRequest_issue_comments.json b/tests/cassettes/PullRequest_issue_comments.json index d4dbb5890..941fd86ac 100644 --- a/tests/cassettes/PullRequest_issue_comments.json +++ b/tests/cassettes/PullRequest_issue_comments.json @@ -1 +1 @@ -{"http_interactions": [{"response": {"headers": {"X-RateLimit-Remaining": "54", "Date": "Sun, 12 Feb 2017 16:16:59 GMT", "Transfer-Encoding": "chunked", "ETag": "W/\"06be44370df682f1efc21f803a926f7e\"", "X-RateLimit-Reset": "1486918405", "Access-Control-Allow-Origin": "*", "X-GitHub-Request-Id": "90E1:5521:351570F:4277F59:58A08A7B", "Content-Security-Policy": "default-src 'none'", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Last-Modified": "Wed, 08 Feb 2017 02:05:35 GMT", "Status": "200 OK", "Server": "GitHub.com", "X-RateLimit-Limit": "60", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Content-Encoding": "gzip", "Content-Type": "application/json; charset=utf-8", "X-Frame-Options": "deny", "X-Content-Type-Options": "nosniff", "Vary": "Accept", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-XSS-Protection": "1; mode=block", "X-Served-By": "e183f7c661b1bbc2c987b3c4dc7b04e0", "Cache-Control": "public, max-age=60, s-maxage=60"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "body": {"base64_string": "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", "string": "", "encoding": "utf-8"}}, "request": {"headers": {"Content-Type": "application/json", "Accept-Charset": "utf-8", "Accept-Encoding": "gzip, deflate", "User-Agent": "github3.py/1.0.0a4", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235", "body": {"string": "", "encoding": "utf-8"}, "method": "GET"}, "recorded_at": "2017-02-12T16:16:59"}, {"response": {"headers": {"X-RateLimit-Remaining": "53", "Date": "Sun, 12 Feb 2017 16:16:59 GMT", "Transfer-Encoding": "chunked", "ETag": "W/\"4a16839f0cc54167cb28d96d3b843a50\"", "X-RateLimit-Reset": "1486918405", "Access-Control-Allow-Origin": "*", "X-GitHub-Request-Id": "90E1:5521:351571F:4277F67:58A08A7B", "Content-Encoding": "gzip", "Access-Control-Expose-Headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Content-Security-Policy": "default-src 'none'", "Status": "200 OK", "Server": "GitHub.com", "X-RateLimit-Limit": "60", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "Content-Type": "application/json; charset=utf-8", "X-Frame-Options": "deny", "X-Content-Type-Options": "nosniff", "Vary": "Accept", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "X-XSS-Protection": "1; mode=block", "X-Served-By": "02ea60dfed58b2a09106fafd6ca0c108", "Cache-Control": "public, max-age=60, s-maxage=60"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/issues/235/comments?per_page=100", "body": {"base64_string": "H4sIAAAAAAAAA52U3Y7bIBCFXyWit0nwX7aVlc32IbY3baoI28RGiw1iwNvUyrt3IN4oSXdbObcw55vDgeHHQJyRJCeNtRpySpkWy1rYxhXLUrXUcK2Agqhb1gvjIMnoaTdd6gMVAI4DxcKWdxZolsTRw+ohJnPktXJ3jb7AfgTUTkqapKtPgTxyFxfYsH7Dvccy9kCToiL5G3xOHHBD8oFIVYsOI7k0ORYnWfQljeaE9cwyc+sjLMIYn6eVqrMYTEjS0ZP4qX9MkVabkeE9EFz45zV42PU1TIoYi/dKSvWKlFvT1/f9dyN6Vp4poqvvpKByoMo2HLPDIx19EALsdFNBNeBbBLsTlecAZm94NdnYqENbrx06GsKTD0BXQGmEtkJ10w1eqZGmTM068ZvdR0M1ICRM4+QTBhWqee+HdLL8JBuoNqJn5cFHY3jJRY9h34m80SPRHjTHOfjmRxCjF5bvWNX6MdwzCfw4J6XhzGJLZrEuieJsEa0WUfocZ3kW58nn76hzuvpvTaGqw87/TohZ681zw7oXmK3ZrDF8/7g9f4QXv1VRC1lwY7dkVkoGgFX+9S78p4ePY0s2X99K1pRt1lRv0ExoZPkv73fsci4bt9/ZmW07cvz5B+MqYdGXBQAA", "string": "", "encoding": "utf-8"}}, "request": {"headers": {"Content-Type": "application/json", "Accept-Charset": "utf-8", "Accept-Encoding": "gzip, deflate", "User-Agent": "github3.py/1.0.0a4", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive"}, "uri": "https://api.github.com/repos/sigmavirus24/github3.py/issues/235/comments?per_page=100", "body": {"string": "", "encoding": "utf-8"}, "method": "GET"}, "recorded_at": "2017-02-12T16:16:59"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 25 Feb 2018 13:34:21 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "59", "X-RateLimit-Reset": "1519569261", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"75edbcd693a7fa0ee4905f1d781a0ba5\"", "Last-Modified": "Wed, 24 Jan 2018 15:25:22 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.084071", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C0BE:328F:7E886A:18284A1:5A92BB5D"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/pulls/235"}, "recorded_at": "2018-02-25T13:34:21"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/issues/235/comments?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA52UW4/TMBCF/0plXts6ty4o6hZeeAUJLUKCriIncRMLx7Z8yVKi/nfGblq15ab01Z7zzfGxx98G5DRHOWqtVSbHmCi2bJhtXbmsZIc1VdJgw5qO9Ew7k2T4uJsu1R4zYxw1GAo7KqzBWRJHD6uHGM2B1/HiGn2B/RtQOc5xkq5eBfLIXVxgw/oN9x7L0ANMshrlJ/gcOUM1ygfEZcMERHJpcixOsuhNGs0R6Ykl+tZHWDTpmJ/HVVJYSCZE6fBR/bZ/zADX6BHiTSBY+Oc9eNj1PUzKGIp3knP5ApRb19cX/nsjfFaeKUw0d1JAOWBpWwrhwZEOPghm7HRTQTXAYzS2YLXnGAhf03qysVEHtl4EOBrCmw9AV5pKM2WZFNMNXqmBJnVDBPtJ7qOB2gAkjOPkEwYVqGnvp3Sy/CgbsNKsJ9XeR6NpRVkPYd+JvNED0e4VhTn47GcQomeWFqTu/BzuCDf0MEeVpsRCS2KhLonibBGtFlH6FGd5FufJ66+gc6r+bw1xtpW6IMbIioXrAN7HLx/efwJAKet94f8uWFurzVNLxHczW5NZq+nucXv+Ji/+srJhvKTabtGs4kCFKv+0F/5LBPgWbd6dStaYbNZYbU6NLP3hDzN2OZeN23/YmW0FOjz/AgDS1fO1BQAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 25 Feb 2018 13:34:21 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "58", "X-RateLimit-Reset": "1519569261", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"4f8c896a6a5b52c1010091704ab11eb9\"", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.064447", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C0BE:328F:7E8873:18284B4:5A92BB5D"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/issues/235/comments?per_page=100"}, "recorded_at": "2018-02-25T13:34:21"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/cassettes/Repository_events.json b/tests/cassettes/Repository_events.json index 60aaa7c18..103e64025 100644 --- a/tests/cassettes/Repository_events.json +++ b/tests/cassettes/Repository_events.json @@ -1 +1 @@ -{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.drax-preview+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62YzW7rNhCFX8XQto5pW07jCChuu2q7u4t0041BS7TFRiIFkrLhCHn3HpKSLPmi/gm7CRKF8/FoODOaYRPxLEril8X8ZbGYRoKWLEqiPTd5vY1n1SmaRru6KDbtPzTfl/TAVa2XKzJaJY+CqShpokLuuQBjuBQUu81yNV/H82lED9RQtalVgXW5MZVOCPEPdTzz2FozlUphmDCzVJakJt762+GXFXB71UIsN8KDC1jFW443BkyTC0W5KYsLDX5rZ3KxeCeLQh5BuVR9ayPSW1pXOgoX+y9SYNkQaXIG5+GVPq0juDaPi3JWDU5Qmw3PLEfjRBTLHhbW2kGWDYDPhihWSQestzpVvDJciscFjqxBk2pPBf+gX6PBWgNipT0uxVnBmh0Qi4+be7OGVIofaHqyrlEsZfwAZ38ReWEPojlVNm//QlBY13PDNjQrbR7uaKHZ5zRy2xsscg+mSLt7o3+c5xnrTxUbfj+ZXIpJwbeKqtNkJ9WEI2fVjqaI1ckRdWSCcJ38zs0f9Xby2/c/DzEEYt17r+Rq5jrnj5JxLMeSbpzJVQTSEwBIemenII61bwh+tvmUItXpVipq5K2icV3gCNSQ4Z82lgyjZZBwBwAolzLMkw4AENe6ZneF9vUXdxxNuvwRdbn1Je+erLmO9gRopRp1XjAW5MEe0pCuKiMdRJqHYTtGQ/xv7rTpPkiqtQdmW8htEAcfSuIgDdE59d8hswlVZ6mWMYIqtguWahk91KjA83YyLaRH4iNocPRBOjsGaVqPFlTsa7oPo/YQnLr9VO/px80m5nrunClA2g5N8W0dXuTOHKvU9w7I9zCXnjFnqGtIrrc5NxwwaGycC8qS3+oLrhNbxCjs/wesjdNLtP37dhtzW65lNORck33Rb+kh3m2rfqdzuEc7DgSFRMcgzU8VNbmtXNiqooqFiG4RpNlSNFuz2azJGXVtdclUYAZ7AlBUpTm6xhCdTcdA11NS47r1nZWZoXsvJM2CfNtDAPTHGKLVE4bnX2EQDRLoAENiyQumjRRhNfZMGbKFNHzH03smluvpNgI13zQXKZvSopgiag1POeIYvbY9RTScLMxDnoDXwD2An1QKhpAO8rpintEQP2lmrCrkKbgKDTA2iRXDdJNtqMFUspwvlk/z+GkRvy1ek+d18hz/jTV1lY3WrJ/mCyx7W8yT5TqJn+2aqtb5AOOXLN/m82T1msQ/2yUoq21c4zdcXOAnLkt+uDQYzCn2KgKGWudnw1/PZsl/3Kq0ZmmBAL3IpPv3PFx+626bQmouS1ah9xjcz3i7uDrN4OoMQ10mUz3j0r4Y/8DKxfpl8TrqMlJZC5zHy+p5Gh2pQUOM7/nwYded9JOk3Zrqjc/9KDGqtqMqnlRK/sNSo4fPzvVmsPDI3/l5yLWWtoXqn/h5sdWwfIHekisl28sogQLRF1pcLLWzsqyYaDV18nFfhnzjKRMar+7t/CiZOOrABJ6xizsHtP7I2I7Whdn43h4OyDCUFLKCBwQzR0yl3VaON+yIWvXx6vNfeTbvT74TAAA=", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Wed, 03 Jan 2018 17:40:41 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "50", "X-RateLimit-Reset": "1515003057", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"da781e044c5021e4944ed3a886afa4f9\"", "Last-Modified": "Wed, 03 Jan 2018 10:28:35 GMT", "X-GitHub-Media-Type": "github.v3; param=drax-preview; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.044447", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "CD3E:7A9D:226EC6:4D78C2:5A4D1599"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2018-01-03T17:40:41"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/events?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Wed, 03 Jan 2018 17:40:41 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "49", "X-RateLimit-Reset": "1515003057", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"fce31bc319a096227494050a6b651254\"", "Last-Modified": "Wed, 03 Jan 2018 10:28:35 GMT", "X-Poll-Interval": "60", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Link": "; rel=\"next\", ; rel=\"last\"", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.162295", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "CD3E:7A9D:226ED1:4D78D6:5A4D1599"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/events?per_page=100"}, "recorded_at": "2018-01-03T17:40:41"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file +{"http_interactions": [{"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py"}, "response": {"body": {"encoding": "utf-8", "base64_string": "H4sIAAAAAAAAA62YQXPqNhDHvwrjawkymLzwPNN57antqe+QXnphhC2wGtnySDKUePLd+5dkG5tOIYl6YcBof/prpV3vqo14HqXJ0zJ+Wi7nUUVLFqXRgZui2SWL+hzNo30jxLb7Q/NDSY9cNXq1JpNR8lQxFaVtJOSBV2CMh4Jip1mt400SzyN6pIaqbaMExhXG1DolxD/UycJjG81UJivDKrPIZEka4q2/HX9cA3dQHcRyIzy4gtW843hjwDS5UlSYUlxp8FM7k6vBeymEPIFyrfreRGSwtK50FF4dPkmBZUukKRichyW9WUdwbT4uylm12EFttjy3HI0dUSz/sLDODrLsAXhriWK1dMBmpzPFa8Nl9XGBE2vQpDrQir/Sz9FgrQGx0j4uxVnBmh1xFj9u7s1aUit+pNnZukaxjPEjnP1J5JU9iOZc27j9A4fCup4btqV5aeNwT4Vmb/PITW8wyD2YI+zee/qncZ6zYVcx4fezKWQ1E3ynqDrP9lLNOGJW7WmGszo7IY/McFxnv3Dza7Ob/fz9t2MCgRj3Mii5GbnO+ZNgnMqxpDt7chOB8AQAkl7YOYhj7VuCzy6eMoQ63UlFjbyXNG4LnIBaMv5pz5JhtAwS7gAAFVKGedIBAOJaN+xdR/v2wh1Hkz5+qqbc+ZT3nqi5jfYEaKUaeb5iLMiDA6QlfVZGOFRZEYbtGS3x39xu00OQVGsPzE7IXRAHL0riIC3RBfXvIbMNVWepljGBKrYPlmoZA9SowP12Mi1kQOIlaLD1QTp7Bmk7jwpaHRp6CKMOEOy6fVUf6OvdIuZ27FwoQNoKTfFdE57kLhyr1NcOiPcwl14wF6grSG6XOXccMCpsnAvKkt+rC24TO8Tk2P8PWHtOr9H29/0y5r5cy2jJJSf7pN/RQ7zbZf1e53iOrh0IOhI9g7Q/1NQUNnNhqpoqFiK6Q5B2R1FsLRaLtmDUldUlU4ER7AlAUZUVqBpDdLY9A1VPSY2r1vdWZo7qXUiaB/l2gADotzFEqyeM979GIxok0AHGxJILpo2swnLshTJmV9LwPc/e07HcDrcJqP2meZWxORVijlNreMZxjlFr211EwcnCPOQJWAbuAXynIhiOdJDXFfOMlvhOM2e1kOfgLDTC2CBWDN1NvqUGXckqXq4e4uRhmTwvv6aPm/Qx+RNjmjqfjNk8xKuHVfwcr9PlJo2f7Ji60cUI44esn5df0niTJms7BGm1O9f4hosLfOKy5F+XBqM+xV5FwFDr4mL408Us/Y9blc4sEzigV5H0/jmP1++6+6aQWsiS1ag9Rvcz3i6pzwu4OkdTl8tML7i0C+OvGPm4fHz6OqkyMtlU2I+nL7jzOVGDghjv8/HDvjoZOkk7NdVbH/tRalRjW1U8qZX8i2VGj59d8s1o4Im/8EuTay1tCTU88f1ip2G1+YIMzZWS3WVUhQQxJFpcLHW9sqxZ1Wnq5S9jLFXwjFUaS29t+4hFuKsZrKG7Lfu9+6nr/G+0hVHq+a7htV/Rlvv2M3VKRtNEqZugd1rnw5ztaSPM1vcDmC9HIyNkbWdk5oROtpfneOMqqltxsn77B5Gp6N/yEwAA", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 25 Feb 2018 13:40:56 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "57", "X-RateLimit-Reset": "1519569261", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"0d17c091cb7730a0e56d7c3d4bd94667\"", "Last-Modified": "Tue, 20 Feb 2018 04:18:07 GMT", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.037683", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C136:3290:CF2649:17C9590:5A92BCE8"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py"}, "recorded_at": "2018-02-25T13:40:56"}, {"request": {"body": {"encoding": "utf-8", "string": ""}, "headers": {"User-Agent": "github3.py/1.0.0a4", "Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.v3.full+json", "Connection": "keep-alive", "Accept-Charset": "utf-8", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/events?per_page=100"}, "response": {"body": {"encoding": "utf-8", "base64_string": "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", "string": ""}, "headers": {"Server": "GitHub.com", "Date": "Sun, 25 Feb 2018 13:40:56 GMT", "Content-Type": "application/json; charset=utf-8", "Transfer-Encoding": "chunked", "Status": "200 OK", "X-RateLimit-Limit": "60", "X-RateLimit-Remaining": "56", "X-RateLimit-Reset": "1519569261", "Cache-Control": "public, max-age=60, s-maxage=60", "Vary": "Accept", "ETag": "W/\"017606478d9fbbd2d69d98bfbfcbc1bc\"", "Last-Modified": "Sun, 25 Feb 2018 13:33:43 GMT", "X-Poll-Interval": "60", "X-GitHub-Media-Type": "github.v3; param=full; format=json", "Link": "; rel=\"next\", ; rel=\"last\"", "Access-Control-Expose-Headers": "ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "Access-Control-Allow-Origin": "*", "Content-Security-Policy": "default-src 'none'", "Strict-Transport-Security": "max-age=31536000; includeSubdomains; preload", "X-Content-Type-Options": "nosniff", "X-Frame-Options": "deny", "X-XSS-Protection": "1; mode=block", "X-Runtime-rack": "0.205052", "Content-Encoding": "gzip", "X-GitHub-Request-Id": "C136:3290:CF2650:17C95A5:5A92BCE8"}, "status": {"code": 200, "message": "OK"}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/events?per_page=100"}, "recorded_at": "2018-02-25T13:40:56"}], "recorded_with": "betamax/0.8.0"} \ No newline at end of file diff --git a/tests/unit/json/comment_example b/tests/unit/json/comment_example index 2810b40fc..b6b097d97 100644 --- a/tests/unit/json/comment_example +++ b/tests/unit/json/comment_example @@ -7,6 +7,8 @@ "position": 4, "line": 14, "commit_id": "6dcb09b5b57875f334f61aebed695e2e4193db5e", + "author_association": "OWNER", + "issue_url": "https://api.github.com/repos/octocat/Hello-World/issues/1", "user": { "login": "octocat", "id": 1, diff --git a/tests/unit/test_events.py b/tests/unit/test_events.py index 025970eb3..2400ea4a9 100644 --- a/tests/unit/test_events.py +++ b/tests/unit/test_events.py @@ -79,8 +79,7 @@ def test_issuecomm(self): } github3.events._issuecomm(comment, None) assert isinstance(comment['issue'], github3.events.EventIssue) - assert isinstance(comment['comment'], - github3.issues.comment.IssueComment) + assert isinstance(comment['comment'], github3.events.EventIssueComment) def test_issueevent(self): """Show that the event type is a IssueEvent.""" From fd23bb5565d846f476247daea424e0d7b159d5b7 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Wed, 28 Feb 2018 06:44:41 -0600 Subject: [PATCH 31/56] Update github3.issues.event to be consistent This also acknowledges the difference between /repos/:owner/:name/issues/:number/events and /repos/:owner/:name/issues/events with separate classes to represent each --- github3/issues/event.py | 128 +++++++++++++++++---------- github3/repos/repo.py | 5 +- tests/integration/test_repos_repo.py | 2 +- tests/unit/json/issue_event_example | 1 + 4 files changed, 85 insertions(+), 51 deletions(-) diff --git a/github3/issues/event.py b/github3/issues/event.py index 0f9dc3371..25a3c0d72 100644 --- a/github3/issues/event.py +++ b/github3/issues/event.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +"""Issue events logic.""" from __future__ import unicode_literals from .. import users @@ -6,71 +7,102 @@ class IssueEvent(GitHubCore): - """The :class:`IssueEvent ` object. This specifically deals - with events described in the - `Issues\>Events `_ section of - the GitHub API. + """Representation of an event from a specific issue. - Two event instances can be checked like so:: + This object will be instantiated from calling + :meth:`~github3.issues.issue.Issue.events` which calls + https://developer.github.com/v3/issues/events/#list-events-for-an-issue - e1 == e2 - e1 != e2 + See also: http://developer.github.com/v3/issues/events - And is equivalent to:: + This object has the following attributes: - e1.commit_id == e2.commit_id - e1.commit_id != e2.commit_id + .. attribute:: actor - """ - def _update_attributes(self, event): - # The type of event: - # ('closed', 'reopened', 'subscribed', 'merged', 'referenced', - # 'mentioned', 'assigned') - #: The type of event, e.g., closed - self.event = self._get_attribute(event, 'event') - #: SHA of the commit. - self.commit_id = self._get_attribute(event, 'commit_id') - self._api = self._get_attribute(event, 'url') - - #: :class:`ShortIssue ` where this comment - #: was made. - from .issue import ShortIssue - self.issue = self._class_attribute(event, 'issue', ShortIssue, self) - - #: :class:`User ` who caused this event. - self.actor = self._class_attribute( - event, 'actor', users.ShortUser, self, - ) + A :class:`~github3.users.ShortUser` representing the user who + generated this event. - #: Number of comments - self.comments = self._get_attribute(event, 'comments') + .. attribute:: commit_id - #: datetime object representing when the event was created. - self.created_at = self._strptime_attribute(event, 'created_at') + The string SHA of a commit that referenced the parent issue. If there + was no commit referencing this issue, then this will be ``None``. - #: Dictionary of links for the pull request - self.pull_request = self._get_attribute(event, 'pull_request', {}) + .. attribute:: commit_url - #: Dictionary containing label details - self.label = self._get_attribute(event, 'label', {}) + The URL to retrieve commit information from the API for the commit + that references the parent issue. If there was no commit, this will be + ``None``. - #: The integer ID of the event - self.id = self._get_attribute(event, 'id') + .. attribute:: created_at - #: :class:`User ` that is assigned - self.assignee = self._class_attribute( - event, 'assignee', users.ShortUser, self, - ) + A :class:`~datetime.datetime` object representing the date and time + this event occurred. + + .. attribute:: event + + The issue-specific action that generated this event. Some examples + are: - #: Dictionary containing milestone details - self.milestone = self._get_attribute(event, 'milestone', {}) + - closed + - reopened + - subscribed + - merged + - referenced + - mentioned + - assigned - #: Dictionary containing to and from attributes - self.rename = self._get_attribute(event, 'rename', {}) + See `this list of events`_ for a full listing. + .. attribute:: id + + The unique identifier for this event. + + .. _this list of events: + https://developer.github.com/v3/issues/events/#events-1 + """ + + def _update_attributes(self, event): + self._api = event['url'] + self.actor = users.ShortUser(event['actor'], self) + self.commit_id = event['commit_id'] + self.commit_url = event['commit_url'] + self.created_at = event['created_at'] + self.event = event['event'] + self.id = self._get_attribute(event, 'id') self._uniq = self.commit_id def _repr(self): return ''.format( self.event, self.actor ) + + +class RepositoryIssueEvent(IssueEvent): + """Representation of an issue event on the repository level. + + This object will be instantiated from calling + :meth:`~github3.repos.repo.Repository.issue_events` or + :meth:`~github3.repos.repo.ShortRepository.issue_events`which call + https://developer.github.com/v3/issues/events/#list-events-for-a-repository + + See also: http://developer.github.com/v3/issues/events + + This object has all of the attributes of + :class:`~github3.issues.event.IssueEvent` and the following: + + .. attribute:: issue + + A :class:`~github3.issues.issue.ShortIssue` representing the issue + where this event originated from. + + """ + + def _update_attributes(self, event): + super(RepositoryIssueEvent, self)._update_attributes(event) + from . import issue + self.issue = issue.ShortIssue(event['issue'], self) + + def _repr(self): + return ''.format( + self.issue.number, self.event, self.actor.login + ) diff --git a/github3/repos/repo.py b/github3/repos/repo.py index 678e285e2..94783856e 100644 --- a/github3/repos/repo.py +++ b/github3/repos/repo.py @@ -12,13 +12,13 @@ from uritemplate import URITemplate +from ..issues import event as ievent from .. import users from ..decorators import requires_auth from ..events import Event from ..git import Blob, Commit, Reference, Tag, Tree from ..issues import ShortIssue, Issue, issue_params -from ..issues.event import IssueEvent from ..issues.label import Label from ..issues.milestone import Milestone from .. import licenses @@ -1229,7 +1229,8 @@ def issue_events(self, number=-1, etag=None): :class:`IssueEvent `\ s """ url = self._build_url('issues', 'events', base_url=self._api) - return self._iter(int(number), url, IssueEvent, etag=etag) + return self._iter(int(number), url, ievent.RepositoryIssueEvent, + etag=etag) def issues(self, milestone=None, state=None, assignee=None, mentioned=None, labels=None, sort=None, direction=None, since=None, number=-1, diff --git a/tests/integration/test_repos_repo.py b/tests/integration/test_repos_repo.py index 7bd8452f1..893f00f3d 100644 --- a/tests/integration/test_repos_repo.py +++ b/tests/integration/test_repos_repo.py @@ -803,7 +803,7 @@ def test_issue_events(self): events = list(repository.issue_events(number=50)) for ev in events: - assert isinstance(ev, github3.issues.event.IssueEvent) + assert isinstance(ev, github3.issues.event.RepositoryIssueEvent) def test_issues_sorts_ascendingly(self): """Test that issues will be returned in ascending order.""" diff --git a/tests/unit/json/issue_event_example b/tests/unit/json/issue_event_example index 521e31d29..32868218c 100644 --- a/tests/unit/json/issue_event_example +++ b/tests/unit/json/issue_event_example @@ -22,6 +22,7 @@ }, "event": "closed", "commit_id": "6dcb09b5b57875f334f61aebed695e2e4193db5e", + "commit_url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "created_at": "2011-04-14T16:00:49Z", "issue": { "id": 1, From ad6e03f94b28ca34030095afa74276042d39e922 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Thu, 1 Mar 2018 19:00:07 -0600 Subject: [PATCH 32/56] Further clean up github3.issues.issue and add docs --- github3/issues/issue.py | 424 +++++++++++++++++++++----------- tests/integration/test_issue.py | 10 +- tests/unit/test_issues_issue.py | 8 - 3 files changed, 282 insertions(+), 160 deletions(-) diff --git a/github3/issues/issue.py b/github3/issues/issue.py index 3d21b943f..1211022da 100644 --- a/github3/issues/issue.py +++ b/github3/issues/issue.py @@ -1,19 +1,19 @@ # -*- coding: utf-8 -*- +"""Module containing the Issue logic.""" from __future__ import unicode_literals from json import dumps -from re import match from uritemplate import URITemplate -from .. import users +from . import comment +from . import event +from . import label +from . import milestone from .. import models +from .. import users from ..decorators import requires_auth -from .comment import IssueComment, issue_comment_params -from .event import IssueEvent -from .label import Label -from .milestone import Milestone class _Issue(models.GitHubCore): @@ -25,13 +25,10 @@ class _Issue(models.GitHubCore): http://developer.github.com/v3/issues """ + class_name = '_Issue' + def _update_attributes(self, issue): self._api = issue['url'] - - # Assignment may be none/empty if the issue hasn't been assigned to - # anybody. The key is there though, so just grab it. - #: :class:`User ` representing the user the issue - #: was assigned to. self.assignee = issue['assignee'] if self.assignee: self.assignee = users.ShortUser(self.assignee, self) @@ -40,102 +37,68 @@ def _update_attributes(self, issue): self.assignees = [ users.ShortUser(assignee, self) for assignee in self.assignees ] - - #: Body (description) of the issue. self.body = issue['body'] - - # If an issue is still open, this field will be None - #: datetime object representing when the issue was closed. - self.closed_at = self._strptime_attribute(issue, 'closed_at') - - #: Number of comments on this issue. + self.closed_at = self._strptime(issue['closed_at']) self.comments_count = issue['comments'] - - #: Comments url (not a template) # MAKE A LOOP - self.comments_url = self._get_attribute(issue, 'comments_url') - - #: datetime object representing when the issue was created. - self.created_at = self._strptime_attribute(issue, 'created_at') - - #: Events url (not a template) # MAKE A LOOP - self.events_url = self._get_attribute(issue, 'events_url') - - #: URL to view the issue at GitHub. # MAKE A LOOP - self.html_url = self._get_attribute(issue, 'html_url') - - #: Unique ID for the issue. + self.comments_url = issue['comments_url'] + self.created_at = self._strptime(issue['created_at']) + self.events_url = issue['events_url'] + self.html_url = issue['html_url'] self.id = issue['id'] - - #: Returns the list of :class:`Label `\ s - #: on this issue. - self.original_labels = issue['labels'] - self.original_labels = [ - Label(l, self) for l in self.original_labels - ] - - #: Labels URL Template. Expand with ``name`` self.labels_urlt = URITemplate(issue['labels_url']) - - #: Locked status self.locked = issue['locked'] - - #: :class:`Milestone ` this - #: issue was assigned to. self.milestone = issue['milestone'] if self.milestone: - self.milestone = Milestone(self.milestone, self) - - #: Issue number (e.g. #15) + self.milestone = milestone.Milestone(self.milestone, self) self.number = issue['number'] - - #: Dictionary URLs for the pull request (if they exist) - self.pull_request_urls = self._get_attribute(issue, 'pull_request', {}) - - #: Returns ('owner', 'repository') this issue was filed on. - self.repository = None - m = match(r'https?://[\w\d\-\.\:]+/(\S+)/(\S+)/(?:issues|pull)/\d+', - self.html_url) - self.repository = m.groups() - - #: State of the issue, e.g., open, closed + self.original_labels = issue['labels'] + if self.original_labels: + self.original_labels = [ + label.Label(lbl, self) for lbl in self.original_labels + ] + self.pull_request_urls = issue.get('pull_request') self.state = issue['state'] - - #: Title of the issue. self.title = issue['title'] - - #: datetime object representing the last time the issue was updated. - self.updated_at = self._strptime_attribute(issue, 'updated_at') - - #: :class:`User ` who opened the issue. + self.updated_at = self._strptime(issue['updated_at']) self.user = users.ShortUser(issue['user'], self) def _repr(self): - return ''.format(r=self.repository, - n=self.number) + return '<{class_name} [#{n}]>'.format( + n=self.number, class_name=self.class_name, + ) @requires_auth def add_labels(self, *args): """Add labels to this issue. - :param str args: (required), names of the labels you wish to add - :returns: list of :class:`Label`\ s + :param str args: + (required), names of the labels you wish to add + :returns: + list of labels + :rtype: + :class:`~github3.issues.label.Label` """ url = self._build_url('labels', base_url=self._api) json = self._json(self._post(url, data=args), 200) - return [Label(l, self) for l in json] if json else [] + return [label.Label(lbl, self) for lbl in json] if json else [] @requires_auth def assign(self, username): - """Assign user ``username`` to this issue. This is a short cut for - ``issue.edit``. + """Assign user ``username`` to this issue. + + This is a short cut for :meth:`~github3.issues.issue.Issue.edit`. - :param str username: username of the person to assign this issue to - :returns: bool + :param str username: + username of the person to assign this issue to + :returns: + True if successful, False, otherwise + :rtype: + bool """ if not username: return False number = self.milestone.number if self.milestone else None - labels = [str(l) for l in self.original_labels] + labels = [str(lbl) for lbl in self.original_labels] return self.edit(self.title, self.body, username, self.state, number, labels) @@ -143,11 +106,14 @@ def assign(self, username): def close(self): """Close this issue. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ assignee = self.assignee.login if self.assignee else '' number = self.milestone.number if self.milestone else None - labels = [l.name for l in self.original_labels] + labels = [lbl.name for lbl in self.original_labels] return self.edit(self.title, self.body, assignee, 'closed', number, labels) @@ -159,68 +125,90 @@ def comment(self, id_num): you were to look at the comments on issue #15 in sigmavirus24/Todo.txt-python, the first comment's id is 4150787. - :param int id_num: (required), comment id, see example above - :returns: :class:`IssueComment ` + :param int id_num: + (required), comment id, see example above + :returns: + the comment identified by ``id_num`` + :rtype: + :class:`~github3.issues.comment.IssueComment` """ json = None if int(id_num) > 0: # Might as well check that it's positive - owner, repo = self.repository - url = self._build_url('repos', owner, repo, 'issues', 'comments', - str(id_num)) + base_url, _ = self.url.rsplit('/', 1) + url = self._build_url('comments', str(id_num), + base_url=base_url) json = self._json(self._get(url), 200) - return self._instance_or_null(IssueComment, json) + return self._instance_or_null(comment.IssueComment, json) def comments(self, number=-1, sort='', direction='', since=None): """Iterate over the comments on this issue. - :param int number: (optional), number of comments to iterate over + :param int number: + (optional), number of comments to iterate over Default: -1 returns all comments - :param str sort: accepted valuees: ('created', 'updated') - api-default: created - :param str direction: accepted values: ('asc', 'desc') - Ignored without the sort parameter - :param since: (optional), Only issues after this date will - be returned. This can be a `datetime` or an ISO8601 formatted - date string, e.g., 2012-05-20T23:10:27Z - :type since: datetime or string - :returns: iterator of - :class:`IssueComment `\ s + :param str sort: + accepted valuees: ('created', 'updated') api-default: created + :param str direction: + accepted values: ('asc', 'desc') Ignored without the sort parameter + :param since: + (optional), Only issues after this date will be returned. This can + be a ``datetime`` or an ISO8601 formatted date string, e.g., + ``2012-05-20T23:10:27Z`` + :type since: + datetime or string + :returns: + iterator of comments + :rtype: + :class:`~github3.issues.comment.IssueComment` """ url = self._build_url('comments', base_url=self._api) - params = issue_comment_params(sort, direction, since) - return self._iter(int(number), url, IssueComment, params) + params = comment.issue_comment_params(sort, direction, since) + return self._iter(int(number), url, comment.IssueComment, params) @requires_auth def create_comment(self, body): """Create a comment on this issue. - :param str body: (required), comment body - :returns: :class:`IssueComment ` + :param str body: + (required), comment body + :returns: + the created comment + :rtype: + :class:`~github3.issues.comment.IssueComment` """ json = None if body: url = self._build_url('comments', base_url=self._api) json = self._json(self._post(url, data={'body': body}), 201) - return self._instance_or_null(IssueComment, json) + return self._instance_or_null(comment.IssueComment, json) @requires_auth def edit(self, title=None, body=None, assignee=None, state=None, milestone=None, labels=None, assignees=None): """Edit this issue. - :param str title: Title of the issue - :param str body: markdown formatted body (description) of the issue - :param str assignee: login name of user the issue should be assigned - to - :param str state: accepted values: ('open', 'closed') - :param int milestone: the NUMBER (not title) of the milestone to - assign this to [1]_, or 0 to remove the milestone - :param list labels: list of labels to apply this to - :param assignees: (optional), login of the users to assign the - issue to - :type assignees: list of strings - :returns: bool + :param str title: + title of the issue + :param str body: + markdown formatted body (description) of the issue + :param str assignee: + login name of user the issue should be assigned to + :param str state: + accepted values: ('open', 'closed') + :param int milestone: + the NUMBER (not title) of the milestone to assign this to [1]_, or + 0 to remove the milestone + :param list labels: + list of labels to apply this to + :param assignees: + (optional), login of the users to assign the issue to + :type assignees: + list of strings + :returns: + True if successful, False otherwise + :rtype: + bool .. [1] Milestone numbering starts at 1, i.e. the first milestone you create is 1, the second is 2, etc. @@ -242,18 +230,24 @@ def edit(self, title=None, body=None, assignee=None, state=None, def events(self, number=-1): """Iterate over events associated with this issue only. - :param int number: (optional), number of events to return. Default: -1 - returns all events available. - :returns: generator of - :class:`IssueEvent `\ s + :param int number: + (optional), number of events to return. Default: -1 returns all + events available. + :returns: + generator of events on this issues + :rtype: + :class:`~github3.issues.event.IssueEvent` """ url = self._build_url('events', base_url=self._api) - return self._iter(int(number), url, IssueEvent) + return self._iter(int(number), url, event.IssueEvent) def is_closed(self): """Check if the issue is closed. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ if self.closed_at or (self.state == 'closed'): return True @@ -262,29 +256,38 @@ def is_closed(self): def labels(self, number=-1, etag=None): """Iterate over the labels associated with this issue. - :param int number: (optional), number of labels to return. Default: -1 - returns all labels applied to this issue. - :param str etag: (optional), ETag from a previous request to the same - endpoint - :returns: generator of :class:`Label `\ s + :param int number: + (optional), number of labels to return. Default: -1 returns all + labels applied to this issue. + :param str etag: + (optional), ETag from a previous request to the same endpoint + :returns: + generator of labels on this issue + :rtype: + :class:`~github3.issues.label.Label` """ url = self._build_url('labels', base_url=self._api) - return self._iter(int(number), url, Label, etag=etag) + return self._iter(int(number), url, label.Label, etag=etag) @requires_auth def lock(self): """Lock an issue. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ - url = self._build_url('lock', base_url=self._api) return self._boolean(self._put(url), 204, 404) def pull_request(self): """Retrieve the pull request associated with this issue. - :returns: :class:`~github3.pulls.PullRequest` + :returns: + the pull request associated with this issue + :rtype: + :class:`~github3.pulls.PullRequest` """ from .. import pulls json = None @@ -297,19 +300,26 @@ def pull_request(self): def remove_label(self, name): """Remove label ``name`` from this issue. - :param str name: (required), name of the label to remove - :returns: list of :class:`Label` + :param str name: + (required), name of the label to remove + :returns: + list of removed labels + :rtype: + :class:`~github3.issues.label.Label` """ url = self._build_url('labels', name, base_url=self._api) json = self._json(self._delete(url), 200, 404) - labels = [Label(label, self) for label in json] if json else [] + labels = [label.Label(lbl, self) for lbl in json] if json else [] return labels @requires_auth def remove_all_labels(self): """Remove all labels from this issue. - :returns: an empty list if successful + :returns: + the list of current labels (empty) if successful + :rtype: + list """ # Can either send DELETE or [] to remove all labels return self.replace_labels([]) @@ -318,22 +328,31 @@ def remove_all_labels(self): def replace_labels(self, labels): """Replace all labels on this issue with ``labels``. - :param list labels: label names - :returns: list of :class:`Label` + :param list labels: + label names + :returns: + list of labels + :rtype: + :class:`~github3.issues.label.Label` """ url = self._build_url('labels', base_url=self._api) json = self._json(self._put(url, data=dumps(labels)), 200) - return [Label(l, self) for l in json] if json else [] + return [label.Label(lbl, self) for lbl in json] if json else [] @requires_auth def reopen(self): """Re-open a closed issue. - :returns: bool + .. note:: This is a short cut to using :meth:`edit`. + + :returns: + True if successful, False otherwise + :rtype: + bool """ assignee = self.assignee.login if self.assignee else '' number = self.milestone.number if self.milestone else None - labels = [str(l) for l in self.original_labels] + labels = [str(lbl) for lbl in self.original_labels] return self.edit(self.title, self.body, assignee, 'open', number, labels) @@ -341,9 +360,11 @@ def reopen(self): def unlock(self): """Unlock an issue. - :returns: bool + :returns: + True if successful, False otherwise + :rtype: + bool """ - url = self._build_url('lock', base_url=self._api) return self._boolean(self._delete(url), 204, 404) @@ -358,6 +379,106 @@ class ShortIssue(_Issue): with different sets of attributes. .. versionadded:: 1.0.0 + + This object has the following attributes: + + .. attribute:: assignee + + .. deprecated:: 1.0.0 + + While the API still returns this attribute, it's not as useful in + the context of multiple assignees. + + If a user is assigned to this issue, then it will be represented as a + :class:`~github3.users.ShortUser`. + + .. attribute:: assignees + + If users are assigned to this issue, then they will be represented as + a list of :class:`~github3.users.ShortUser`. + + .. attribute:: body + + The markdown formatted text of the issue as writen by the user who + opened the issue. + + .. attribute:: closed_at + + If this issue is closed, this will be a :class:`~datetime.datetime` + object representing the date and time this issue was closed. Otherwise + it will be ``None``. + + .. attribute:: comments_count + + The number of comments on this issue. + + .. attribute:: comments_url + + The URL to retrieve the comments on this issue from the API. + + .. attribute:: created_at + + A :class:`~datetime.datetime` object representing the date and time + this issue was created. + + .. attribute:: events_url + + The URL to retrieve the events related to this issue from the API. + + .. attribute:: html_url + + The URL to view this issue in a browser. + + .. attribute:: id + + The unique identifier for this issue in GitHub. + + .. attribute:: labels_urlt + + A :class:`~uritemplate.URITemplate` object that can expand to a URL to + retrieve the labels on this issue from the API. + + .. attribute:: locked + + A boolean attribute representing whether or not this issue is locked. + + .. attribute:: milestone + + A :class:`~github3.issues.milestone.Milestone` object representing the + milestone to which this issue was assigned. + + .. attribute:: number + + The number identifying this issue on its parent repository. + + .. attribute:: original_labels + + If any are assigned to this issue, the list of + :class:`~github3.issues.label.Label` objects representing the labels + returned by the API for this issue. + + .. attribute:: pull_request_urls + + If present, a dictionary of URLs for retrieving information about the + associated pull request for this issue. + + .. attribute:: state + + The current state of this issue, e.g., ``'closed'`` or ``'open'``. + + .. attribute:: title + + The title for this issue. + + .. attribute:: updated_at + + A :class:`~datetime.datetime` object representing the date and time + when this issue was last updated. + + .. attribute:: user + + A :class:`~github3.users.ShortUser` representing the user who opened + this issue. """ pass @@ -375,19 +496,28 @@ class Issue(_Issue): with different sets of attributes. .. versionchanged:: 1.0.0 + + This object has all of the same attributes as a + :class:`~github3.issues.issue.ShortIssue` as well as the following: + + .. attribute:: body_html + + The HTML formatted body of this issue. + + .. attribute:: body_text + + The plain-text formatted body of this issue. + + .. attribute:: closed_by + + If the issue is closed, a :class:`~github3.users.ShortUser` + representing the user who closed the issue. """ def _update_attributes(self, issue): super(Issue, self)._update_attributes(issue) - - #: HTML formatted body of the issue. self.body_html = issue['body_html'] - - #: Plain text formatted body of the issue. self.body_text = issue['body_text'] - - # This maybe None if it hasn't been closed, but the key will exist - #: :class:`User ` who closed the issue. self.closed_by = issue['closed_by'] if self.closed_by: self.closed_by = users.ShortUser(self.closed_by, self) diff --git a/tests/integration/test_issue.py b/tests/integration/test_issue.py index 43c11e4ea..8063a1e8a 100644 --- a/tests/integration/test_issue.py +++ b/tests/integration/test_issue.py @@ -24,7 +24,7 @@ def test_add_labels(self): assert len(labels) > 0 for label in labels: - assert isinstance(label, github3.issues.issue.Label) + assert isinstance(label, github3.issues.label.Label) def test_assign(self): """Test the ability to assign a user to an issue.""" @@ -47,7 +47,7 @@ def test_comment(self): number=497) comment = issue.comment('165547512') - assert isinstance(comment, github3.issues.issue.IssueComment) + assert isinstance(comment, github3.issues.comment.IssueComment) def test_comments(self): """Test the ability to retrieve comments on an issue.""" @@ -87,7 +87,7 @@ def test_create_comment(self): body='Comment from integration test' ) - assert isinstance(comment, github3.issues.issue.IssueComment) + assert isinstance(comment, github3.issues.comment.IssueComment) def test_edit(self): """Test the ability to edit an issue.""" @@ -215,7 +215,7 @@ def test_remove_label(self): assert len(labels) > 0 for label in labels: - assert isinstance(label, github3.issues.issue.Label) + assert isinstance(label, github3.issues.label.Label) def test_replace_labels(self): """Test the ability to replace labels from an issue.""" @@ -230,7 +230,7 @@ def test_replace_labels(self): assert len(replaced_labels) == len(labels) for replaced_label in replaced_labels: - assert isinstance(replaced_label, github3.issues.issue.Label) + assert isinstance(replaced_label, github3.issues.label.Label) def test_unlock(self): """Test the ability to lock an issue.""" diff --git a/tests/unit/test_issues_issue.py b/tests/unit/test_issues_issue.py index e47069960..8a8dbae09 100644 --- a/tests/unit/test_issues_issue.py +++ b/tests/unit/test_issues_issue.py @@ -267,7 +267,6 @@ def test_issue_137(self): self.assertEqual( issue.html_url, "https://github.com/sigmavirus24/github3.py/pull/1") - self.assertEqual(issue.repository, ("sigmavirus24", "github3.py")) def test_pull_request(self): """Verify the request to retrieve an associated Pull Request.""" @@ -284,13 +283,6 @@ def test_pull_request_without_urls(self): assert self.session.get.called is False - def test_repr(self): - """Show that instance string is formattted properly.""" - assert repr(self.instance) == ''.format( - r=self.instance.repository, - n=self.instance.number - ) - def test_remove_all_labels(self): """Verify that all labels are removed.""" with mock.patch.object(Issue, 'replace_labels') as replace_labels: From 56598776ce6588445cf0d76b5faaea507d5d1405 Mon Sep 17 00:00:00 2001 From: Ian Stapleton Cordasco Date: Thu, 1 Mar 2018 19:26:33 -0600 Subject: [PATCH 33/56] Update Labels for consistency --- github3/issues/label.py | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/github3/issues/label.py b/github3/issues/label.py index fa005df8e..c6ca86099 100644 --- a/github3/issues/label.py +++ b/github3/issues/label.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +"""Module containing the logic for labels.""" from __future__ import unicode_literals from json import dumps @@ -7,18 +8,25 @@ class Label(GitHubCore): - """The :class:`Label