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

Skip to content

Commit 181f08d

Browse files
omgjlksigmavirus24
authored andcommitted
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 ffa06ad commit 181f08d

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 .projects import Project, ProjectCard, ProjectColumn
2222
from .pulls import PullRequest
2323
from .repos.repo import Repository, repo_issue_params
@@ -106,11 +106,11 @@ def all_organizations(self, number=-1, since=None, etag=None,
106106
endpoint
107107
:param int per_page: (optional), number of organizations to list per
108108
request
109-
:returns: generator of :class:`Organization
110-
<github3.orgs.Organization>`
109+
:returns: generator of :class:`ShortOrganization
110+
<github3.orgs.ShortOrganization>`
111111
"""
112112
url = self._build_url('organizations')
113-
return self._iter(int(number), url, Organization,
113+
return self._iter(int(number), url, ShortOrganization,
114114
params={'since': since, 'per_page': per_page},
115115
etag=etag)
116116

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

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

950950
def project(self, number):

github3/orgs.py

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

@@ -229,7 +234,7 @@ def remove_repository(self, repository):
229234
return self._boolean(self._delete(url), 204, 404)
230235

231236

232-
class Organization(models.GitHubCore):
237+
class _Organization(models.GitHubCore):
233238

234239
"""The :class:`Organization <Organization>` object.
235240
@@ -247,75 +252,27 @@ class Organization(models.GitHubCore):
247252
members_roles = frozenset(['all', 'admin', 'member'])
248253

249254
def _update_attributes(self, org):
250-
# Set the type of object
251-
self.type = self._get_attribute(org, 'type')
252-
if not self.type:
253-
self.type = 'Organization'
254-
255-
self._api = self._get_attribute(org, 'url')
256-
257255
#: URL of the avatar at gravatar
258-
self.avatar_url = self._get_attribute(org, 'avatar_url')
259-
260-
#: URL of the blog
261-
self.blog = self._get_attribute(org, 'blog')
256+
self.avatar_url = org['avatar_url']
262257

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

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

280263
#: Unique ID of the account
281-
self.id = self._get_attribute(org, 'id')
282-
283-
#: Location of the org
284-
self.location = self._get_attribute(org, 'location')
264+
self.id = org['id']
285265

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

310269
#: Public Members URL Template. Expands with ``member``
311-
self.public_members_urlt = self._class_attribute(
312-
org,
313-
'public_members_url',
314-
URITemplate
315-
)
270+
self.public_members_urlt = URITemplate(org['public_members_url'])
316271

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

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

362319
@requires_auth
363-
def add_repository(self, repository, team_id):
320+
def add_repository(self, repository, team_id): # FIXME(jlk): add perms
364321
"""Add ``repository`` to ``team``.
365322
366323
.. versionchanged:: 1.0
@@ -447,7 +404,7 @@ def conceal_member(self, username):
447404
return self._boolean(self._delete(url), 204, 404)
448405

449406
@requires_auth
450-
def create_team(self, name, repo_names=[], permission=''):
407+
def create_team(self, name, repo_names=[], permission='pull'):
451408
"""Create a new team and return it.
452409
453410
This only works if the authenticated user owns this organization.
@@ -706,6 +663,74 @@ def team(self, team_id):
706663
return self._instance_or_null(Team, json)
707664

708665

666+
class ShortOrganization(_Organization):
667+
"""Object for the shortened representation of an Organization.
668+
669+
GitHub's API returns different amounts of information about orgs based
670+
upon how that information is retrieved. Often times, when iterating over
671+
several orgs, GitHub will return less information. To provide a clear
672+
distinction between the types of orgs, github3.py uses different classes
673+
with different sets of attributes.
674+
675+
.. versionadded:: 1.0.0
676+
"""
677+
678+
pass
679+
680+
681+
class Organization(_Organization):
682+
"""Object for the full representation of a Organization.
683+
684+
GitHub's API returns different amounts of information about orgs based
685+
upon how that information is retrieved. This object exists to represent
686+
the full amount of information returned for a specific org. For example,
687+
you would receive this class when calling
688+
:meth:`~github3.github.GitHub.organization`. To provide a clear
689+
distinction between the types of orgs, github3.py uses different classes
690+
with different sets of attributes.
691+
692+
.. versionchanged:: 1.0.0
693+
"""
694+
695+
def _update_attributes(self, org):
696+
super(Organization, self)._update_attributes(org)
697+
698+
# this may be blank if the org hasn't set it
699+
#: URL of the blog
700+
self.blog = self._get_attribute(org, 'blog')
701+
702+
#: Name of the company
703+
self.company = self._get_attribute(org, 'company')
704+
705+
#: datetime object representing the date the account was created
706+
self.created_at = org['created_at']
707+
708+
#: E-mail address of the org
709+
self.email = self._get_attribute(org, 'email')
710+
711+
# The number of people following this org
712+
#: Number of followers
713+
self.followers_count = org['followers']
714+
715+
# The number of people this org follows
716+
#: Number of people the org is following
717+
self.following_count = org['following']
718+
719+
#: Location of the org
720+
self.location = self._get_attribute(org, 'location')
721+
722+
#: Display name of the org
723+
self.name = self._get_attribute(org, 'name')
724+
725+
# The number of public_repos
726+
#: Number of public repos owned by the org
727+
self.public_repos_count = org['public_repos']
728+
729+
# e.g. https://github.com/self._login
730+
#: URL of the org's profile
731+
self.html_url = org['html_url']
732+
733+
709734
class Membership(models.GitHubCore):
710735

711736
"""The wrapper for information about Team and Organization memberships."""
@@ -717,7 +742,7 @@ def _update_attributes(self, membership):
717742
self._api = self._get_attribute(membership, 'url')
718743

719744
self.organization = self._class_attribute(
720-
membership, 'organization', Organization, self
745+
membership, 'organization', ShortOrganization, self
721746
)
722747

723748
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