8000 Split up Organization objects · omgjlk/github3.py@3a33e62 · GitHub
[go: up one dir, main page]

Skip to content

Commit 3a33e62

Browse files
committed
Split up Organization objects
This creates 3 new objects, one for iterations (Short), one for direct GETs (Organization), and one for events (EventOrganization). Most attributes can now be directly assigned, aside from a few that are only returned in the API if they are set on the server. Default those to None. Many test cassettes needed to be updated to pick up attributes added to orgs since the cassette was recorded (yay for additive REST APIs...). Introduce a 'auto_login' method to handle either token auth or username/password auth. Use it in the places I needed to update the cassette. Fix a few POST calls that were sending malformed (according to GitHub API) json data. Specifically an empty permission is not accepted. Related-to: sigmavirus24#670 Signed-off-by: Jesse Keating <jkeating@j2solutions.net>
1 parent 6cbef12 commit 3a33e62

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+211
-442
lines changed

github3/api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ def organizations_with(username, number=-1, etag=None):
285285
:param str etag: (optional), ETag from a previous request to the same
286286
endpoint
287287
:returns: generator of
288-
:class:`Organization <github3.orgs.Organization>`
288+
:class:`ShortOrganization <github3.orgs.ShortOrganization>`
289289
290290
"""
291291
return gh.organizations_with(username, number, etag)

github3/events.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,24 @@ def to_user(self):
3232
return self._instance_or_null(users.User, json)
3333

3434

35+
class EventOrganization(GitHubCore):
36+
"""The class that represents the org information returned in Events."""
37+
38+
def _update_attributes(self, org):
39+
self.avatar_url = org['avatar_url']
40+
self.gravatar_id = org['id']
41+
self.id = org['id']
42+
self.login = org['login']
43+
self._api = self.url = org['url']
44+
45+
def to_org(self):
46+
"""Retrieve a full Organization object for this EventOrganization."""
47+
from . import orgs
48+
url = self._build_url('orgs', self.login)
49+
json = self._json(self._get(url), 200)
50+
return self._instance_or_null(orgs.Organization, json)
51+
52+
3553
class Event(GitHubCore):
3654

3755
"""The :class:`Event <Event>` object. It structures and handles the data
@@ -56,7 +74,6 @@ def _update_attributes(self, event):
5674
# not want to do:
5775
event = copy.deepcopy(event)
5876

59-
from .orgs import Organization
6077
#: :class:`User <github3.users.User>` object representing the actor.
6178
self.actor = self._class_attribute(event, 'actor', EventUser)
6279
#: datetime object representing when the event was created.
@@ -66,7 +83,7 @@ def _update_attributes(self, event):
6683
self.id = self._get_attribute(event, 'id')
6784

6885
#: List all possible types of Events
69-
self.org = self._class_attribute(event, 'org', Organization)
86+
self.org = self._class_attribute(event, 'org', EventOrganization)
7087

7188
#: Event type https://developer.github.com/v3/activity/events/types/
7289
self.type = self._get_attribute(event, 'type')

github3/github.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from .gists import Gist
1818
from .issues import Issue, issue_params
1919
from .models import GitHubCore
20-
from .orgs import Membership, Organization, Team
20+
from .orgs import Membership, ShortOrganization, Organization, Team
2121
from .pulls import PullRequest
2222
from .repos.repo import Repository, repo_issue_params
2323
from .search import (CodeSearchResult, IssueSearchResult,
@@ -105,11 +105,11 @@ def all_organizations(self, number=-1, since=None, etag=None,
105105
endpoint
106106
:param int per_page: (optional), number of organizations to list per
107107
request
108-
:returns: generator of :class:`Organization
109-
<github3.orgs.Organization>`
108+
:returns: generator of :class:`ShortOrganization
109+
<github3.orgs.ShortOrganization>`
110110
"""
111111
url = self._build_url('organizations')
112-
return self._iter(int(number), url, Organization,
112+
return self._iter(int(number), url, ShortOrganization,
113113
params={'since': since, 'per_page': per_page},
114114
etag=etag)
115115

@@ -921,10 +921,10 @@ def organizations(self, number=-1, etag=None):
921921
:param str etag: (optional), ETag from a previous request to the same
922922
endpoint
923923
:returns: generator of
924-
:class:`Organization <github3.orgs.Organization>`\ s
924+
:class:`ShortOrganization <github3.orgs.ShortOrganization>`\ s
925925
"""
926926
url = self._build_url('user', 'orgs')
927-
return self._iter(int(number), url, Organization, etag=etag)
927+
return self._iter(int(number), url, ShortOrganization, etag=etag)
928928

929929
def organizations_with(self, username, number=-1, etag=None):
930930
"""Iterate over organizations with ``username`` as a public member.
@@ -939,11 +939,11 @@ def organizations_with(self, username, number=-1, etag=None):
939939
:param str etag: (optional), ETag from a previous request to the same
940940
endpoint
941941
:returns: generator of
942-
:class:`Organization <github3.orgs.Organization>`\ s
942+
:class:`ShortOrganization <github3.orgs.ShortOrganization>`\ s
943943
"""
944944
if username:
945945
url = self._build_url('users', username, 'orgs')
946-
return self._iter(int(number), url, Organization, etag=etag)
946+
return self._iter(int(number), url, ShortOrganization, etag=etag)
947947
return iter([])
948948

949949
def public_gists(self, number=-1, etag=None):

github3/orgs.py

Lines changed: 89 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,16 @@ def add_member(self, username):
7777
def add_repository(self, repository, permission=''):
7878
"""Add ``repository`` to this team.
7979
80+
If a permission is not provided, the team's default permission
81+
will be assigned, by GitHub.
82+
8083
:param str repository: (required), form: 'user/repo'
8184
:param str permission: (optional), ('pull', 'push', 'admin')
8285
:returns: bool
8386
"""
84-
data = {'permission': permission}
87+
data = {}
88+
if permission:
89+
data = {'permission': permission}
8590
url = self._build_url('repos', repository, base_url=self._api)
8691
return self._boolean(self._put(url, data=dumps(data)), 204, 404)
8792

@@ -228,7 +233,7 @@ def remove_repository(self, repository):
228233
return self._boolean(self._delete(url), 204, 404)
229234

230235

231-
class Organization(models.GitHubCore):
236+
class _Organization(models.GitHubCore):
232237

233238
"""The :class:`Organization <Organization>` object.
234239
@@ -246,75 +251,27 @@ class Organization(models.GitHubCore):
246251
members_roles = frozenset(['all', 'admin', 'member'])
247252

248253
def _update_attributes(self, org):
249-
# Set the type of object
250-
self.type = self._get_attribute(org, 'type')
251-
if not self.type:
252-
self.type = 'Organization'
253-
254-
self._api = self._get_attribute(org, 'url')
255-
256254
#: URL of the avatar at gravatar
257-
self.avatar_url = self._get_attribute(org, 'avatar_url')
258-
259-
#: URL of the blog
260-
self.blog = self._get_ F438 attribute(org, 'blog')
255+
self.avatar_url = org['avatar_url']
261256

262-
#: Name of the company
263-
self.company = self._get_attribute(org, 'company')
257+
# Set the type of object (this doens't come through API data)
258+
self.type = 'Organization'
264259

265-
#: datetime object representing the date the account was created
266-
self.created_at = self._strptime_attribute(org, 'created_at')
267-
268-
#: E-mail address of the org
269-
self.email = self._get_attribute(org, 'email')
270-
271-
# The number of people following this org
272-
#: Number of followers
273-
self.followers_count = self._get_attribute(org, 'followers')
274-
275-
# The number of people this org follows
276-
#: Number of people the org is following
277-
self.following_count = self._get_attribute(org, 'following')
260+
self.url = self._api = org['url']
278261

279262
#: Unique ID of the account
280-
self.id = self._get_attribute(org, 'id')
281-
282-
#: Location of the org
283-
self.location = self._get_attribute(org, 'location')
263+
self.id = org['id']
284264

285265
#: Name of the organization
286-
self.login = self._get_attribute(org, 'login')
287-
288-
# e.g. first_name last_name
289-
#: Real name of the org
290-
self.name = self._get_attribute(org, 'name')
291-
292-
# The number of public_repos
293-
#: Number of public repos owned by the org
294-
self.public_repos_count = self._get_attribute(org, 'public_repos')
295-
296-
# e.g. https://github.com/self._login
297-
#: URL of the org's profile
298-
self.html_url = self._get_attribute(org, 'html_url')
299-
300-
#: Description of the org
301-
self.description = self._get_attribute(org, 'description')
302-
303-
#: Events url (not a template)
304-
self.events_url = self._get_attribute(org, 'events_url')
305-
306-
#: Number of private repositories.
307-
self.private_repos = self._get_attribute(org, 'owned_private_repos')
266+
self.login = org['login']
308267

309268
#: Public Members URL Template. Expands with ``member``
310-
self.public_members_urlt = self._class_attribute(
311-
org,
312-
'public_members_url',
313-
URITemplate
314-
)
269+
self.public_members_urlt = URITemplate(org['public_members_url'])
315270

316-
#: Repositories url (not a template)
317-
self.repos_url = self._get_attribute(org, 'repos_url')
271+
#: Various urls (not templates)
272+
for urltype in ('avatar_url', 'events_url', 'issues_url',
273+
'repos_url'):
274+
self.__setattr__(urltype, org[urltype])
318275

319276
def _repr(self):
320277
return '<Organization [{s.login}:{s.name}]>'.format(s=self)
@@ -359,7 +316,7 @@ def add_member(self, username, team_id):
359316
return self._boolean(self._put(url), 204, 404)
360317

361318
@requires_auth
362-
def add_repository(self, repository, team_id):
319+
def add_repository(self, repository, team_id): # FIXME(jlk): add perms
363320
"""Add ``repository`` to ``team``.
364321
365322
.. versionchanged:: 1.0
@@ -430,7 +387,7 @@ def conceal_member(self, username):
430387
return self._boolean(self._delete(url), 204, 404)
431388

432389
@requires_auth
433-
def create_team(self, name, repo_names=[], permission=''):
390+
def create_team(self, name, repo_names=[], permission='pull'):
434391
"""Create a new team and return it.
435392
436393
This only works if the authenticated user owns this organization.
@@ -660,6 +617,74 @@ def team(self, team_id):
660617
return self._instance_or_null(Team, json)
661618

662619

620+
class ShortOrganization(_Organization):
621+
"""Object for the shortened representation of an Organization.
622+
623+
GitHub's API returns different amounts of information about orgs based
624+
upon how that information is retrieved. Often times, when iterating over
625+
several orgs, GitHub will return less information. To provide a clear
626+
distinction between the types of orgs, github3.py uses different classes
627+
with different sets of attributes.
628+
629+
.. versionadded:: 1.0.0
630+
"""
631+
632+
pass
633+
634+
635+
class Organization(_Organization):
636+
"""Object for the full representation of a Organization.
637+
638+
GitHub's API returns different amounts of information about orgs based
639+
upon how that information is retrieved. This object exists to represent
640+
the full amount of information returned for a specific org. For example,
641+
you would receive this class when calling
642+
:meth:`~github3.github.GitHub.organization`. To provide a clear
643+
distinction between the types of orgs, github3.py uses different classes
644+
with different sets of attributes.
645+
646+
.. versionchanged:: 1.0.0
647+
"""
648+
649+
def _update_attributes(self, org):
650+
super(Organization, self)._update_attributes(org)
651+
652+
# this may be blank if the org hasn't set it
653+
#: URL of the blog
654+
self.blog = self._get_attribute(org, 'blog')
655+
656+
#: Name of the company
657+
self.company = self._get_attribute(org, 'company')
658+
659+
#: datetime object representing the date the account was created
660+
self.created_at = org['created_at']
661+
662+
#: E-mail address of the org
663+
self.email = self._get_attribute(org, 'email')
664+
665+
# The number of people following this org
666+
#: Number of followers
667+
self.followers_count = org['followers']
668+
669+
# The number of people this org follows
670+
#: Number of people the org is following
671+
self.following_count = org['following']
672+
673+
#: Location of the org
674+
self.location = self._get_attribute(org, 'location')
675+
676+
#: Display name of the org
677+
self.name = self._get_attribute(org, 'name')
678+
679+
# The number of public_repos
680+
#: Number of public repos owned by the org
681+
self.public_repos_count = org['public_repos']
682+
683+
# e.g. https://github.com/self._login
684+
#: URL of the org's profile
685+
self.html_url = org['html_url']
686+
687+
663688
class Membership(models.GitHubCore):
664689

665690
"""The wrapper for information about Team and Organization memberships."""
@@ -671,7 +696,7 @@ def _update_attributes(self, membership):
671696
self._api = self._get_attribute(membership, 'url')
672697

673698
self.organization = self._class_attribute(
674-
membership, 'organization', Organization, self
699+
membership, 'organization', ShortOrganization, self
675700
)
676701

677702
self.organization_url = self._get_attribute(

github3/users.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,12 +328,13 @@ def organizations(self, number=-1, etag=None):
328328
Default: -1 returns all available organization
329329
:param str etag: (optional), ETag from a previous request to the same
330330
endpoint
331-
:returns: generator of :class:`Event <github3.orgs.Organization>`\ s
331+
:returns: generator of
332+
:class:`ShortOrganization <github3.orgs.ShortOrganization>`\ s
332333
"""
333334
# Import here, because a toplevel import causes an import loop
334-
from .orgs import Organization
335+
from .orgs import ShortOrganization
335336
url = self._build_url('orgs', base_url=self._api)
336-
return self._iter(int(number), url, Organization, etag=etag)
337+
return self._iter(int(number), url, ShortOrganization, etag=etag)
337338

338339
def starred_repositories(self, sort=None, direction=None, number=-1,
339340
etag=None):

0 commit comments

Comments
 (0)
0