8000 Merge pull request #747 from omgjlk/split-org-object-670 · pythonthings/github3.py@8f21f79 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 /react-partial>

Commit 8f21f79

Browse files
authored
Merge pull request sigmavirus24#747 from omgjlk/split-org-object-670
Implement Organization object refactor
2 parents a43ae53 + db4278a commit 8f21f79

Some content is hidden

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

48 files changed

+232
-431
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 return 3D1D ed 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)
10000 947+
return self._iter(int(number), url, ShortOrganization, etag=etag)
948948
return iter([])
949949

950950
def project(self, number):

github3/orgs.py

Lines changed: 109 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,28 @@
11
# -*- coding: utf-8 -*-
2-
"""
3-
github3.orgs
4-
============
5-
6-
This module contains all of the classes related to organizations.
7-
8-
"""
2+
"""This module contains all of the classes related to organizations."""
93
from __future__ import unicode_literals
104

115
import warnings
126
from json import dumps
137

148
from uritemplate import URITemplate
159

16-
from . import users
10+
from . import users, models
1711

1812
from .decorators import requires_auth
1913
from .events import Event
20-
from .models import BaseAccount, GitHubCore
2114
from .projects import Project
2215
from .repos import Repository
2316

2417

25-
class Team(GitHubCore):
18+
class Team(models.GitHubCore):
2619

2720
"""The :class:`Team <Team>` object.
2821
29-
Two team instances can be checked like so::
30-
31-
t1 == t2
32-
t1 != t2
33-
34-
And is equivalent to::
35-
36-
t1.id == t2.id
37-
t1.id != t2.id
38-
39-
See also: http://developer.github.com/v3/orgs/teams/
22+
Please see GitHub's `Team Documentation`_ for more information.
4023
24+
.. _Team Documentation:
25+
http://developer.github.com/v3/orgs/teams/
4126
"""
4227

4328
# Roles available to members on a team.
@@ -93,11 +78,16 @@ def add_member(self, username):
9378
def add_repository(self, repository, permission=''):
9479
"""Add ``repository`` to this team.
9580
81+
If a permission is not provided, the team's default permission
82+
will be assigned, by GitHub.
83+
9684
:param str repository: (required), form: 'user/repo'
9785
:param str permission: (optional), ('pull', 'push', 'admin')
9886
:returns: bool
9987
"""
100-
data = {'permission': permission}
88+
data = {}
89+
if permission:
90+
data = {'permission': permission}
10191
url = self._build_url('repos', repository, base_url=self._api)
10292
return self._boolean(self._put(url, data=dumps(data)), 204, 404)
10393

@@ -244,22 +234,14 @@ def remove_repository(self, repository):
244234
return self._boolean(self._delete(url), 204, 404)
245235

246236

247-
class Organization(BaseAccount):
237+
class _Organization(models.GitHubCore):
248238

249239
"""The :class:`Organization <Organization>` object.
250240
251-
Two organization instances can be checked like so::
252-
253-
o1 == o2
254-
o1 != o2
255-
256-
And is equivalent to::
257-
258-
o1.id == o2.id
259-
o1.id != o2.id
260-
261-
See also: http://developer.github.com/v3/orgs/
241+
Please see GitHub's `Organization Documentation`_ for more information.
262242
243+
.. _Organization Documentation:
244+
http://developer.github.com/v3/orgs/
263245
"""
264246

265247
# Filters available when listing members. Note: ``"2fa_disabled"``
@@ -270,23 +252,30 @@ class Organization(BaseAccount):
270252
members_roles = frozenset(['all', 'admin', 'member'])
271253

272254
def _update_attributes(self, org):
273-
super(Organization, self)._update_attributes(org)
274-
self.type = self.type or 'Organization'
255+
#: URL of the avatar at gravatar
256+
self.avatar_url = org['avatar_url']
257+
258+
# Set the type of object (this doens't come through API data)
259+
self.type = 'Organization'
260+
261+
self.url = self._api = org['url']
275262

276-
#: Events url (not a template)
277-
self.events_url = self._get_attribute(org, 'events_url')
278-
#: Number of private repositories.
279-
self.private_repos = self._get_attribute(org, 'private_repos')
263+
#: Unique ID of the account
264+
self.id = org['id']
265+
266+
#: Name of the organization
267+
self.login = org['login']
280268

281269
#: Public Members URL Template. Expands with ``member``
282-
self.public_members_urlt = self._class_attribute(
283-
org,
284-
'public_members_url',
285-
URITemplate
286-
)
270+
self.public_members_urlt = URITemplate(org['public_members_url'])
287271

288-
#: Repositories url (not a template)
289-
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])
276+
277+
def _repr(self):
278+
return '<Organization [{s.login}:{s.name}]>'.format(s=self)
290279

291280
@requires_auth
292281
def add_member(self, username, team_id):
@@ -328,7 +317,7 @@ def add_member(self, username, team_id):
328317
return self._boolean(self._put(url), 204, 404)
329318

330319
@requires_auth
331-
def add_repository(self, repository, team_id):
320+
def add_repository(self, repository, team_id): # FIXME(jlk): add perms
332321
"""Add ``repository`` to ``team``.
333322
334323
.. versionchanged:: 1.0
@@ -415,7 +404,7 @@ def conceal_member(self, username):
415404
return self._boolean(self._delete(url), 204, 404)
416405

417406
@requires_auth
418-
def create_team(self, name, repo_names=[], permission=''):
407+
def create_team(self, name, repo_names=[], permission='pull'):
419408
"""Create a new team and return it.
420409
421410
This only works if the authenticated user owns this organization.
@@ -674,7 +663,75 @@ def team(self, team_id):
674663
return self._instance_or_null(Team, json)
675664

676665

677-
class Membership(GitHubCore):
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+
734+
class Membership(models.GitHubCore):
678735

679736
"""The wrapper for information about Team and Organization memberships."""
680737

@@ -685,7 +742,7 @@ def _update_attributes(self, membership):
685742
self._api = self._get_attribute(membership, 'url')
686743

687744
self.organization = self._class_attribute(
688-
membership, 'organization', Organization, self
745+
membership, 'organization', ShortOrganization, self
689746
)
690747

691748
self.organization_url = self._get_attribute(
@@ -711,7 +768,7 @@ def edit(self, state):
711768
"""
712769
if state and state.lower() == 'active':
713770
data = dumps({'state': state.lower()})
714-
json = self._json(self._patch(self._api, data=data))
771+
json = self._json(self._patch(self._api, data=data), 200)
715772
self._update_attributes(json)
716773
return True
717774
return False

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