aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--github3/api.py18
-rw-r--r--github3/handlers/__init__.py1
-rw-r--r--github3/handlers/base.py3
-rw-r--r--github3/handlers/user.py19
-rw-r--r--github3/helpers.py19
-rw-r--r--github3/models/__init__.py4
-rw-r--r--github3/models/base.py187
-rw-r--r--github3/models/gists.py49
-rw-r--r--github3/models/orgs.py28
-rw-r--r--github3/models/repos.py30
-rw-r--r--github3/models/user.py49
11 files changed, 244 insertions, 163 deletions
diff --git a/github3/api.py b/github3/api.py
index 7b63b2d..d99682a 100644
--- a/github3/api.py
+++ b/github3/api.py
@@ -15,7 +15,6 @@ from decorator import decorator
from .packages import omnijson as json
from .packages.link_header import parse_link_value
-from .models import *
from .helpers import is_collection, to_python, to_api, get_scope
from .config import settings
import handlers
@@ -170,6 +169,9 @@ class GithubCore(object):
page += 1
+ def _get_bool(self, resource):
+ resp = self._http_resource('GET', resource, check_status=False)
+ return True if resp.status_code == 204 else False
def _to_map(self, obj, iterable):
"""Maps given dict iterable to a given Resource object."""
@@ -181,16 +183,6 @@ class GithubCore(object):
return a
- def _get_url(self, resource):
-
- if is_collection(resource):
- resource = map(str, resource)
- resource = '/'.join(resource)
-
- return resource
-
-
-
class Github(GithubCore):
"""docstring for Github"""
@@ -198,8 +190,8 @@ class Github(GithubCore):
super(Github, self).__init__()
self.is_authenticated = False
- def user_handler(self, username=None):
- if not getattr(self, '_user_handler'):
+ def user_handler(self, username=None, force=False):
+ if force or not getattr(self, '_user_handler', False):
if self.is_authenticated:
self._user_handler = handlers.AuthUser(self)
else:
diff --git a/github3/handlers/__init__.py b/github3/handlers/__init__.py
index e69de29..126efcb 100644
--- a/github3/handlers/__init__.py
+++ b/github3/handlers/__init__.py
@@ -0,0 +1 @@
+from user import AuthUser, User
diff --git a/github3/handlers/base.py b/github3/handlers/base.py
index 6a5ac65..93a4680 100644
--- a/github3/handlers/base.py
+++ b/github3/handlers/base.py
@@ -3,8 +3,6 @@
#
# author: David Medina
-import models
-
class Handler(object):
""" Abstract handler, that inject github.api """
@@ -24,3 +22,4 @@ class Handler(object):
url = self._extend_url(*args)
map_model = kwargs.get('model', self._model)
return self._gh._get_resources(url, map_model, **kwargs)
+
diff --git a/github3/handlers/user.py b/github3/handlers/user.py
index 16f8363..c59607d 100644
--- a/github3/handlers/user.py
+++ b/github3/handlers/user.py
@@ -4,6 +4,7 @@
# author: David Medina
from .base import Handler
+import github3.models as models
class User(Handler):
""" Handler to query public user api """
@@ -13,7 +14,7 @@ class User(Handler):
raise exceptions.AnomUser("%s need a username" % self.__class__)
self._url = ('users', username)
- self._model = models.AnomUser
+ self._model = models.User
self.username = username
super(User, self).__init__(gh)
@@ -29,12 +30,24 @@ class User(Handler):
def get_following(self, limit=None):
return self._get_resources('following')
-class AuthUser(AnomUser):
+ def get_repos(self, limit=None):
+ return self._get_resources('repos', model=models.Repo)
+
+ def get_watched(self, limit=None):
+ return self._get_resources('watched', model=models.Repo)
+
+ def get_orgs(self, limit=None):
+ return self._get_resources('orgs', model=models.Org)
+
+ def get_gists(self, limit=None):
+ return self._get_resources('gists', model=models.Gist)
+
+class AuthUser(User):
""" Handler to query public/private api for authenticated user """
def __init__(self, gh):
self._url = ('user',)
- self._model = models.User
+ self._model = models.AuthUser
super(AnomUser, self).__init__(gh)
def __repr__(self):
diff --git a/github3/helpers.py b/github3/helpers.py
index 498a005..205e097 100644
--- a/github3/helpers.py
+++ b/github3/helpers.py
@@ -57,6 +57,7 @@ def to_python(obj,
date_keys=None,
int_keys=None,
object_map=None,
+ list_map=None,
bool_keys=None, **kwargs):
"""Extends a given object for API Consumption.
@@ -96,14 +97,32 @@ def to_python(obj,
if object_map:
for (k, v) in object_map.items():
if in_dict.get(k):
+ if v == 'self':
+ v = obj.__class__
d[k] = v.new_from_dict(in_dict.get(k))
+ if list_map:
+ for k, model in list_map.items():
+ nested_map = in_dict.get(k)
+ if nested_map:
+ if getattr(nested_map, 'items', False):
+ map_dict = {}
+ for nested_item, nested_dict in nested_map.items():
+ map_dict[nested_item] = model.new_from_dict(nested_dict)
+ d[k] = map_dict
+ else:
+ map_list = []
+ for item_map in nested_map:
+ map_list.append(model.new_from_dict(item_map))
+ d[k] = map_list
+
obj.__dict__.update(d)
obj.__dict__.update(kwargs)
# Save the dictionary, for write comparisons.
obj._cache = d
obj.__cache = in_dict
+ obj.post_map()
return obj
diff --git a/github3/models/__init__.py b/github3/models/__init__.py
index e69de29..6e4db1b 100644
--- a/github3/models/__init__.py
+++ b/github3/models/__init__.py
@@ -0,0 +1,4 @@
+from .user import AuthUser, User
+from .repos import Repo
+from .orgs import Org
+from .gists import Gist
diff --git a/github3/models/base.py b/github3/models/base.py
index 618e57f..1b1ce89 100644
--- a/github3/models/base.py
+++ b/github3/models/base.py
@@ -6,9 +6,9 @@ This module provides the Github3 object model.
"""
import json
+import inspect
-from .helpers import to_python, to_api, key_diff
-
+from github3.helpers import to_python, to_api, key_diff
class BaseResource(object):
"""A BaseResource object."""
@@ -18,15 +18,24 @@ class BaseResource(object):
_dates = []
_bools = []
_map = {}
+ _list_map = {}
_writeable = []
_cache = {}
+ def post_map(self):
+ try:
+ handler = self.handler()
+ methods = filter(lambda x: x[0].startswith('get') and callable(x),
+ inspect.getmembers(handler, inspect.ismethod))
+ for name, callback in methods:
+ setattr(self, method, callback)
+ except:
+ pass
def __init__(self):
self._bootstrap()
super(BaseResource, self).__init__()
-
def __dir__(self):
return self.keys()
@@ -56,6 +65,7 @@ class BaseResource(object):
date_keys = cls._dates,
bool_keys = cls._bools,
object_map = cls._map,
+ list_map = cls._list_map,
_gh = gh
)
@@ -70,109 +80,70 @@ class BaseResource(object):
return r
-class Plan(BaseResource):
- """Github Plan object model."""
-
- _strs = ['name']
- _ints = ['space', 'collaborators', 'private_repos']
-
- def __repr__(self):
- return '<plan {0}>'.format(str(self.name))
-
-class Org(BaseResource):
- """Github Organization object model."""
-
- _strs = [
- 'login', 'url', 'avatar_url', 'name', 'company', 'blog', 'location', 'email'
- 'html_url', 'type', 'billing_email']
- _ints = [
- 'id', 'public_repos', 'public_gists', 'followers', 'following',
- 'total_private_repos', 'owned_private_repos', 'private_gists', 'disk_usage',
- 'collaborators']
- _dates = ['created_at']
- _map = {'plan': Plan}
- _writable = ['billing_email', 'blog', 'company', 'email', 'location', 'name']
-
- @property
- def ri(self):
- return ('orgs', self.login)
-
- def __repr__(self):
- return '<org {0}>'.format(self.login)
-
- def repos(self, limit=None):
- return self._gh._get_resources(('orgs', self.login, 'repos'), Repo, limit=limit)
-
- def members(self, limit=None):
- return self._gh._get_resources(('orgs', self.login, 'members'), User, limit=limit)
-
- def is_member(self, username):
- if isinstance(username, User):
- username = username.login
-
- r = self._gh._http_resource('GET', ('orgs', self.login, 'members', username), check_status=False)
- return (r.status_code == 204)
-
- def publicize_member(self, username):
- if isinstance(username, User):
- username = username.login
-
- r = self._gh._http_resource('PUT', ('orgs', self.login, 'public_members', username), check_status=False, data='')
- return (r.status_code == 204)
-
- def conceal_member(self, username):
- if isinstance(username, User):
- username = username.login
-
- r = self._gh._http_resource('DELETE', ('orgs', self.login, 'public_members', username), check_status=False)
- return (r.status_code == 204)
-
- def remove_member(self, username):
- if isinstance(username, User):
- username = username.login
-
- r = self._gh._http_resource('DELETE', ('orgs', self.login, 'members', username), check_status=False)
- return (r.status_code == 204)
-
- def public_members(self, limit=None):
- return self._gh._get_resources(('orgs', self.login, 'public_members'), User, limit=limit)
-
- def is_public_member(self, username):
- if isinstance(username, User):
- username = username.login
-
- r = self._gh._http_resource('GET', ('orgs', self.login, 'public_members', username), check_status=False)
- return (r.status_code == 204)
-
-
-class Gist(BaseResource):
- _strs = ['url', 'description', 'html_url', 'git_pull_url', 'git_push_url']
- _ints = ['id', 'comments']
- _bools = ['public']
- _dates = ['created_at']
- _map = {'user': User} #TODO: file
-
- @property
- def ri(self):
- return ('users', self.user.login, self.id)
-
- def __repr__(self):
- return '<gist %s/%s>' % (self.user.login, self.description)
-
-class Repo(BaseResource):
- _strs = [
- 'url', 'html_url', 'clone_url', 'git_url', 'ssh_url', 'svn_url',
- 'name', 'description', 'homepage', 'language', 'master_branch']
- _bools = ['private', 'fork']
- _ints = ['forks', 'watchers', 'size',]
- _dates = ['pushed_at', 'created_at']
- _map = {'owner': User}
-
-
- @property
- def ri(self):
- return ('repos', self.owner.login, self.name)
- def __repr__(self):
- return '<repo {0}/{1}>'.format(self.owner.login, self.name)
- # owner
+#class Org(BaseResource):
+# """Github Organization object model."""
+#
+# _strs = [
+# 'login', 'url', 'avatar_url', 'name', 'company', 'blog', 'location', 'email'
+# 'html_url', 'type', 'billing_email']
+# _ints = [
+# 'id', 'public_repos', 'public_gists', 'followers', 'following',
+# 'total_private_repos', 'owned_private_repos', 'private_gists', 'disk_usage',
+# 'collaborators']
+# _dates = ['created_at']
+# _map = {'plan': Plan}
+# _writable = ['billing_email', 'blog', 'company', 'email', 'location', 'name']
+#
+# @property
+# def ri(self):
+# return ('orgs', self.login)
+#
+# def __repr__(self):
+# return '<org {0}>'.format(self.login)
+#
+# def repos(self, limit=None):
+# return self._gh._get_resources(('orgs', self.login, 'repos'), Repo, limit=limit)
+#
+# def members(self, limit=None):
+# return self._gh._get_resources(('orgs', self.login, 'members'), User, limit=limit)
+#
+# def is_member(self, username):
+# if isinstance(username, User):
+# username = username.login
+#
+# r = self._gh._http_resource('GET', ('orgs', self.login, 'members', username), check_status=False)
+# return (r.status_code == 204)
+#
+# def publicize_member(self, username):
+# if isinstance(username, User):
+# username = username.login
+#
+# r = self._gh._http_resource('PUT', ('orgs', self.login, 'public_members', username), check_status=False, data='')
+# return (r.status_code == 204)
+#
+# def conceal_member(self, username):
+# if isinstance(username, User):
+# username = username.login
+#
+# r = self._gh._http_resource('DELETE', ('orgs', self.login, 'public_members', username), check_status=False)
+# return (r.status_code == 204)
+#
+# def remove_member(self, username):
+# if isinstance(username, User):
+# username = username.login
+#
+# r = self._gh._http_resource('DELETE', ('orgs', self.login, 'members', username), check_status=False)
+# return (r.status_code == 204)
+#
+# def public_members(self, limit=None):
+# return self._gh._get_resources(('orgs', self.login, 'public_members'), User, limit=limit)
+#
+# def is_public_member(self, username):
+# if isinstance(username, User):
+# username = username.login
+#
+# r = self._gh._http_resource('GET', ('orgs', self.login, 'public_members', username), check_status=False)
+# return (r.status_code == 204)
+#
+#
diff --git a/github3/models/gists.py b/github3/models/gists.py
new file mode 100644
index 0000000..5ad61c3
--- /dev/null
+++ b/github3/models/gists.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+#
+# author: David Medina
+
+from .base import BaseResource
+from .user import User
+
+class File(BaseResource):
+ _strs = ['filename', 'raw_url', 'content', 'language', 'type']
+ _ints = ['size']
+
+ def __repr__(self):
+ return '<File gist> %s' % self.filename
+
+class GistFork(BaseResource):
+ _strs = ['url']
+ _dates = ['created_at']
+ _map = {'user': User}
+
+ def __repr__(self):
+ return '<Gist fork> %s>' % self.user.login
+
+class ChangeStatus(BaseResource):
+ _ints = ['deletions', 'additions', 'total']
+
+ def __repr__(self):
+ return '<Gist history> change_status>'
+
+class GistHistory(BaseResource):
+ _strs = ['url', 'version']
+ _map = {'user': User, 'change_status': ChangeStatus}
+ _dates = ['committed_at']
+
+class Gist(BaseResource):
+ _strs = ['url', 'description', 'html_url', 'git_pull_url', 'git_push_url']
+ _ints = ['id', 'comments']
+ _bools = ['public']
+ _dates = ['created_at']
+ _map = {'user': User}
+ _list_map = {'files': File, 'forks': GistFork, 'history': GistHistory}
+
+ @property
+ def ri(self):
+ return ('users', self.user.login, self.id)
+
+ def __repr__(self):
+ return '<gist %s/%s>' % (self.user.login, self.description)
+
diff --git a/github3/models/orgs.py b/github3/models/orgs.py
new file mode 100644
index 0000000..1ce638e
--- /dev/null
+++ b/github3/models/orgs.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+#
+# author: David Medina
+
+from .base import BaseResource
+from .user import Plan
+
+class Org(BaseResource):
+ """Github Organization object model."""
+
+ _strs = [
+ 'login', 'url', 'avatar_url', 'name', 'company', 'blog', 'location', 'email'
+ 'html_url', 'type', 'billing_email']
+ _ints = [
+ 'id', 'public_repos', 'public_gists', 'followers', 'following',
+ 'total_private_repos', 'owned_private_repos', 'private_gists', 'disk_usage',
+ 'collaborators']
+ _dates = ['created_at']
+ _map = {'plan': Plan}
+ _writable = ['billing_email', 'blog', 'company', 'email', 'location', 'name']
+
+ @property
+ def ri(self):
+ return ('orgs', self.login)
+
+ def __repr__(self):
+ return '<org {0}>'.format(self.login)
diff --git a/github3/models/repos.py b/github3/models/repos.py
new file mode 100644
index 0000000..8dbe970
--- /dev/null
+++ b/github3/models/repos.py
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+#
+# author: David Medina
+
+from .base import BaseResource
+from .user import User
+from .orgs import Org
+
+class Repo(BaseResource):
+ _strs = [
+ 'url', 'html_url', 'clone_url', 'git_url', 'ssh_url', 'svn_url',
+ 'name', 'description', 'homepage', 'language', 'master_branch']
+ _bools = ['private', 'fork', 'has_issues', 'has_wiki', 'has_downloads']
+ _ints = ['forks', 'watchers', 'size', 'open_issues']
+ _dates = ['pushed_at', 'created_at']
+ _map = {
+ 'owner': User,
+ 'organization': Org,
+ 'parent': 'self',
+ 'source': 'self',
+ }
+
+ @property
+ def ri(self):
+ return ('repos', self.owner.login, self.name)
+
+ def __repr__(self):
+ return '<Repo {0}/{1}>'.format(self.owner.login, self.name)
+ # owner
diff --git a/github3/models/user.py b/github3/models/user.py
index cdbd04f..d58d9b2 100644
--- a/github3/models/user.py
+++ b/github3/models/user.py
@@ -5,18 +5,25 @@
from .base import BaseResource
+class Plan(BaseResource):
+ """Github Plan object model."""
+
+ _strs = ['name']
+ _ints = ['space', 'collaborators', 'private_repos']
+
+ def __repr__(self):
+ return '<Plan {0}>'.format(str(self.name))
+
class User(BaseResource):
"""Github User object model."""
_strs = [
'login','avatar_url', 'url', 'name', 'company', 'blog', 'location',
- 'email', 'bio', 'html_url']
+ 'email', 'bio', 'html_url', 'type']
_ints = ['id', 'public_repos', 'public_gists', 'followers', 'following']
_dates = ['created_at',]
_bools = ['hireable', ]
- # _map = {}
- # _writeable = []
@property
def ri(self):
@@ -25,26 +32,8 @@ class User(BaseResource):
def __repr__(self):
return '<User {0}>'.format(self.login)
- @property
def handler(self):
- return self._gh.user_handler(self.login)
-
- def get_followers(self, limit=None):
- return self.handler.followers(limit)
-
- def get_following(self, limit=None):
- return self.handler.following(limit)
-
- def repos(self, limit=None):
- return self._gh._get_resources(('users', self.login, 'repos'), Repo, limit=limit)
- def repo(self, reponame):
- return self._gh._get_resource(('repos', self.login, reponame), Repo)
-
- def orgs(self):
- return self._gh._get_resources(('users', self.login, 'orgs'), Org)
-
- def gists(self):
- return self._gh._get_resources(('users', self.login, 'gists'), Gist)
+ return self._gh.user_handler(self.login, force=True)
class AuthUser(User):
"""Github Current User object model."""
@@ -61,19 +50,5 @@ class AuthUser(User):
return ('user',)
def __repr__(self):
- return '<current-user {0}>'.format(self.login)
-
- def repos(self, limit=None):
- return self._gh._get_resources(('user', 'repos'), Repo, limit=limit)
-
- def repo(self, reponame):
- return self._gh._get_resource(('repos', self.login, reponame), Repo)
-
- def orgs(self, limit=None):
- return self._gh._get_resources(('user', 'orgs'), Org, limit=limit)
-
- def org(self, orgname):
- return self._gh._get_resource(('orgs', orgname), Org)
+ return '<AuthUser {0}>'.format(self.login)
- def gists(self, limit=None):
- return self._gh._get_resources('gists', Gist, limit=limit)