8000 Break up User class into three classes · pythonthings/github3.py@f8de3b7 · GitHub
[go: up one dir, main page]

Skip to content

Commit f8de3b7

Browse files
committed
Break up User class into three classes
Each one has only the attributes that are (currently) returned by the API.
1 parent f5e564d commit f8de3b7

File tree

1 file changed

+148
-111
lines changed

1 file changed

+148
-111
lines changed

github3/users.py

Lines changed: 148 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
from github3.auths import Authorization
88
from uritemplate import URITemplate
99

10+
from . import models
1011
from .decorators import requires_auth
1112
from .events import Event
12-
from .models import GitHubCore
1313

1414

15-
class Key(GitHubCore):
15+
class Key(models.GitHubCore):
1616
"""The :class:`Key <Key>` object.
1717
1818
Please see GitHub's `Key Documentation`_ for more information.
@@ -67,7 +67,7 @@ def update(self, title, key):
6767
return False
6868

6969

70-
class Plan(GitHubCore):
70+
class Plan(models.GitHubCore):
7171
"""The :class:`Plan <Plan>` object.
7272
7373
Please see GitHub's `Authenticated User`_ documentation for more details.
@@ -103,7 +103,7 @@ def is_free(self):
103103
return self.name == 'free' # (No coverage)
104104

105105

106-
class Email(GitHubCore):
106+
class Email(models.GitHubCore):
107107
"""The :class:`Email` object.
108108
109109
Please see GitHub's `Emails documentation`_ for more information.
@@ -129,7 +129,7 @@ def __str__(self):
129129
return self.email
130130

131131

132-
class User(GitHubCore):
132+
class _User(models.GitHubCore):
133133
"""The :class:`User <User>` object.
134134
135135
This handles and structures information in the `User section`_.
@@ -149,133 +149,56 @@ class User(GitHubCore):
149149
"""
150150

151151
def _update_attributes(self, user):
152-
#: Tells you what type of account this is
153-
self.type = self._get_attribute(user, 'type')
154-
if not self.type:
155-
self.type = 'User'
156-
157-
self._api = self._get_attribute(user, 'url')
158-
159152
#: URL of the avatar at gravatar
160-
self.avatar_url = self._get_attribute(user, 'avatar_url')
161-
162-
#: URL of the blog
163-
self.blog = self._get_attribute(user, 'blog')
164-
165-
#: Name of the company
166-
self.company = self._get_attribute(user, 'company')
167-
168-
#: datetime object representing the date the account was created
169-
self.created_at = self._strptime_attribute(user, 'created_at')
170-
171-
#: E-mail address of the user/org
172-
self.email = self._get_attribute(user, 'email')
173-
174-
# The number of people following this user
175-
#: Number of followers
176-
self.followers_count = self._get_attribute(user, 'followers')
177-
178-
# The number of people this user follows
179-
#: Number of people the user is following
180-
self.following_count = self._get_attribute(user, 'following')
153+
self.avatar_url = user['avatar_url']
181154

182-
#: Unique ID of the account
183-
self.id = self._get_attribute(user, 'id')
155+
#: Events URL Template. Expands with ``privacy``
156+
self.events_urlt = URITemplate(user['events_url'])
184157

185-
#: Location of the user/org
186-
self.location = self._get_attribute(user, 'location')
158+
#: Followers URL (not a template)
159+
self.followers_url = user['followers_url']
187160

188-
#: User name of the user/organization
189-
self.login = self._get_attribute(user, 'login')
161+
#: Following URL Template. Expands with ``other_user``
162+
self.following_urlt = URITemplate(user['following_url'])
190163

191-
# e.g. first_name last_name
192-
#: Real name of the user/org
193-
self.name = self._get_attribute(user, 'name')
164+
#: Gists URL Template. Expands with ``gist_id``
165+
self.gists_urlt = URITemplate(user['gists_url'])
194166

195-
# The number of public_repos
196-
#: Number of public repos owned by the user/org
197-
self.public_repos_count = self._get_attribute(user, 'public_repos')
167+
#: ID of the user's image on Gravatar
168+
self.gravatar_id = user['gravatar_id']
198169

199170
# e.g. https://github.com/self._login
200171
#: URL of the user/org's profile
201-
self.html_url = self._get_attribute(user, 'html_url')
202-
203-
#: Markdown formatted biography
204-
self.bio = self._get_attribute(user, 'bio')
205-
206-
#: ID of the user's image on Gravatar
207-
self.gravatar_id = self._get_attribute(user, 'gravatar_id')
208-
#: True -- for hire, False -- not for hire
209-
self.hireable = self._get_attribute(user, 'hireable', False)
172+
self.html_url = user['html_url']
210173

211-
# The number of public_gists
212-
#: Number of public gists
213-
self.public_gists = self._get_attribute(user, 'public_gists')
214-
215-
# Private information
216-
#: How much disk consumed by the user
217-
self.disk_usage = self._get_attribute(user, 'disk_usage')
218-
219-
#: Number of private repos owned by this user
220-
self.owned_private_repos = self._get_attribute(
221-
user, 'owned_private_repos'
222-
)
223-
#: Number of private gists owned by this user
224-
self.total_private_gists = self._get_attribute(
225-
user, 'total_private_gists'
226-
)
227-
#: Total number of private repos
228-
self.total_private_repos = self._get_attribute(
229-
user, 'total_private_repos'
230-
)
231-
232-
#: Which plan this user is on
233-
self.plan = self._class_attribute(user, 'plan', Plan)
234-
235-
#: Events URL Template. Expands with ``privacy``
236-
self.events_urlt = self._class_attribute(
237-
user, 'events_url', URITemplate)
238-
239-
#: Followers URL (not a template)
240-
self.followers_url = self._get_attribute(user, 'followers_url')
241-
242-
#: Following URL Template. Expands with ``other_user``
243-
self.following_urlt = self._class_attribute(
244-
user, 'following_url', URITemplate
245-
)
174+
#: Unique ID of the account
175< 10000 /code>+
self.id = user['id']
246176

247-
#: Gists URL Template. Expands with ``gist_id``
248-
self.gists_urlt = self._class_attribute(user, 'gists_url', URITemplate)
177+
#: User name of the user
178+
self.login = user['login']
249179

250180
#: Organizations URL (not a template)
251-
self.organizations_url = self._get_attribute(user, 'organizations_url')
181+
self.organizations_url = user['organizations_url']
252182

253183
#: Received Events URL (not a template)
254-
self.received_events_url = self._get_attribute(
255-
user, 'received_events_url'
256-
)
184+
self.received_events_url = user['received_events_url']
257185

258186
#: Repostories URL (not a template)
259-
self.repos_url = self._get_attribute(user, 'repos_url')
187+
self.repos_url = user['repos_url']
188+
189+
self.site_admin = user['site_admin']
260190

261191
#: Starred URL Template. Expands with ``owner`` and ``repo``
262-
self.starred_urlt = self._class_attribute(
263-
user, 'starred_url', URITemplate
264-
)
192+
self.starred_urlt = URITemplate(user['starred_url'])
265193

266194
#: Subscriptions URL (not a template)
267-
self.subscriptions_url = self._get_attribute(user, 'subscriptions_url')
195+
self.subscriptions_url = user['subscriptions_url']
268196

269-
#: Number of repo contributions. Only appears in ``repo.contributors``
270-
contributions = self._get_attribute(user, 'contributions')
271-
# The refresh method uses __init__ to replace the attributes on the
272-
# instance with what it receives from the /users/:username endpoint.
273-
# What that means is that contributions is no longer returned and as
274-
# such is changed because it doesn't exist. This guards against that.
275-
if contributions is not None:
276-
self.contributions = contributions
197+
self.type = user['type']
277198

278-
self._uniq = self._get_attribute(user, 'id')
199+
self.url = self._api = user['url']
200+
201+
self._uniq = self.id
279202

280203
def __str__(self):
281204
return self.login
@@ -332,7 +255,7 @@ def followers(self, number=-1, etag=None):
332255
:returns: generator of :class:`User <User>`\ s
333256
"""
334257
url = self._build_url('followers', base_url=self._api)
335-
return self._iter(int(number), url, User, etag=etag)
258+
return self._iter(int(number), url, ShortUser, etag=etag)
336259

337260
def following(self, number=-1, etag=None):
338261
r"""Iterate over the users being followed by this user.
@@ -344,7 +267,7 @@ def following(self, number=-1, etag=None):
344267
:returns: generator of :class:`User <User>`\ s
345268
"""
346269
url = self._build_url('following', base_url=self._api)
347-
return self._iter(int(number), url, User, etag=etag)
270+
return self._iter(int(number), url, ShortUser, etag=etag)
348271

349272
def keys(self, number=-1, etag=None):
350273
r"""Iterate over the public keys of this user.
@@ -572,3 +495,117 @@ def delete(self):
572495
"""
573496
url = self._build_url('admin', 'users', self.login)
574497
return self._boolean(self._delete(url), 204, 403)
498+
499+
500+
class ShortUser(_User):
501+
"""Object for the shortened representation of a User.
502+
503+
GitHub's API returns different amounts of information about users based
504+
upon how that information is retrieved. Often times, when iterating over
505+
several users, GitHub will return less information. To provide a clear
506+
distinction between the types of users, github3.py uses different classes
507+
with different sets of attributes.
508+
509+
.. versionadded:: 1.0.0
510+
"""
511+
512+
pass
513+
514+
515+
class User(_User):
516+
"""Object for the full representation of a User.
517+
518+
GitHub's API returns different amounts of information about users based
519+
upon how that information is retrieved. This object exists to represent
520+
the full amount of information returned for a specific user. For example,
521+
you would receive this class when calling
522+
:meth:`~github3.github.GitHub.user`. To provide a clear distinction
523+
between the types of users, github3.py uses different classes with
524+
different sets of attributes.
525+
526+
This object no longer contains information about the currently
527+
authenticated user (e.g., :meth:`~github3.github.GitHub.me`).
528+
529+
.. versionchanged:: 1.0.0
530+
"""
531+
532+
def _update_attributes(self, user):
533+
super(User, self)._update_attributes(user)
534+
#: Markdown formatted biography
535+
self.bio = user['bio']
536+
537+
#: URL of the blog
538+
self.blog = user['blog']
539+
540+
#: Name of the company
541+
self.company = user['company']
542+
543+
#: datetime object representing the date the account was created
544+
self.created_at = self._strptime(user['created_at'])
545+
546+
#: E-mail address of the user/org
547+
self.email = user['email']
548+
549+
# The number of people following this user
550+
#: Number of followers
551+
self.followers_count = user['followers']
552+
553+
# The number of people this user follows
554+
#: Number of people the user is following
555+
self.following_count = user['following']
556+
557+
#: True -- for hire, False -- not for hire
558+
self.hireable = user['hireable']
559+
560+
#: Location of the user/org
561+
self.location = user['location']
562+
563+
# e.g. first_name last_name
564+
#: Real name of the user/org
565+
self.name = user['name']
566+
567+
# The number of public_gists
568+
#: Number of public gists
569+
self.public_gists_count = user['public_gists']
570+
571+
# The number of public_repos
572+
#: Number of public repos owned by the user/org
573+
self.public_repos_count = user['public_repos']
574+
575+
self.updated_at = self._strptime(user['updated_at'])
576+
577+
578+
class AuthenticatedUser(User):
579+
"""Object to represent the currently authenticated user.
580+
581+
This is returned by :meth:`~github3.github.GitHub.me`. It contains the
582+
extra informtation that is not returned for other users such as the
583+
currently authenticated user's plan and private email information.
584+
585+
.. versionadded:: 1.0.0
586+
"""
587+
588+
def _update_attributes(self, user):
589+
#: How much disk consumed by the user
590+
self.disk_usage = user['disk_usage']
591+
592+
#: Number of private repos owned by this user
593+
self.owned_private_repos = user['owned_private_repos']
594+
595+
#: Number of private gists owned by this user
596+
self.total_private_gists = user['total_private_gists']
597+
598+
#: Total number of private repos
599+
self.total_private_repos = user['total_private_repos']
600+
601+
#: Which plan this user is on
602+
self.plan = Plan(user['plan'])
603+
604+
#: Number of repo contributions. Only appears in ``repo.contributors``
605+
contributions = user.get('contributions')
606+
# The refresh method uses __init__ to replace the attributes on the
607+
# instance with what it receives from the /users/:username endpoint.
608+
# What that means is that contributions is no longer returned and as
609+
# such is changed because it doesn't exist. This guards against that.
610+
if contributions is not None:
611+
self.contributions = contributions

0 commit comments

Comments
 (0)
0