From c23698e64f3244636290ffa4065f3b70ba5151e9 Mon Sep 17 00:00:00 2001 From: David Medina Date: Sat, 29 Oct 2011 16:11:27 +0200 Subject: Wip on handlers --- github3/api.py | 28 ++--- github3/exceptions.py | 8 ++ github3/handlers/__init__.py | 0 github3/handlers/base.py | 26 +++++ github3/handlers/user.py | 41 ++++++++ github3/helpers.py | 2 +- github3/models.py | 246 ------------------------------------------- github3/models/__init__.py | 0 github3/models/base.py | 178 +++++++++++++++++++++++++++++++ github3/models/user.py | 79 ++++++++++++++ 10 files changed, 341 insertions(+), 267 deletions(-) create mode 100644 github3/exceptions.py create mode 100644 github3/handlers/__init__.py create mode 100644 github3/handlers/base.py create mode 100644 github3/handlers/user.py delete mode 100644 github3/models.py create mode 100644 github3/models/__init__.py create mode 100644 github3/models/base.py create mode 100644 github3/models/user.py (limited to 'github3') diff --git a/github3/api.py b/github3/api.py index 81ae3e7..7b63b2d 100644 --- a/github3/api.py +++ b/github3/api.py @@ -18,8 +18,7 @@ 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 PAGING_SIZE = 100 @@ -199,24 +198,13 @@ class Github(GithubCore): super(Github, self).__init__() self.is_authenticated = False - - def get_user(self, username): - """Get a single user.""" - return self._get_resource(('users', username), User) - - - def get_me(self): - """Get the authenticated user.""" - return self._get_resource(('user'), CurrentUser) - - def get_repo(self, username, reponame): - """Get the given repo.""" - return self._get_resource(('repos', username, reponame), Repo) - - def get_org(self, login): - """Get organization.""" - return self._get_resource(('orgs', login), Org) - + def user_handler(self, username=None): + if not getattr(self, '_user_handler'): + if self.is_authenticated: + self._user_handler = handlers.AuthUser(self) + else: + self._user_handler = handlers.User(self, username) + return self._user_handler class ResponseError(Exception): """The API Response was unexpected.""" diff --git a/github3/exceptions.py b/github3/exceptions.py new file mode 100644 index 0000000..72da776 --- /dev/null +++ b/github3/exceptions.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# +# author: David Medina + +class AnomUser(Exception): + """ Exception for AnomUser handler """ + pass diff --git a/github3/handlers/__init__.py b/github3/handlers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/github3/handlers/base.py b/github3/handlers/base.py new file mode 100644 index 0000000..6a5ac65 --- /dev/null +++ b/github3/handlers/base.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# +# author: David Medina + +import models + +class Handler(object): + """ Abstract handler, that inject github.api """ + + def __init__(self, gh): + self._gh = gh + super(Handler, self).__init__() + + def _extend_url(self, *args): + return self._url + args + + def _get_resource(self, *args, **kwargs): + url = self._extend_url(*args) + map_model = kwargs.get('model', self._model) + return self._gh._get_resource(url, map_model, **kwargs) + + def _get_resources(self, *args, **kwargs): + 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 new file mode 100644 index 0000000..16f8363 --- /dev/null +++ b/github3/handlers/user.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# +# author: David Medina + +from .base import Handler + +class User(Handler): + """ Handler to query public user api """ + + def __init__(self, gh, username): + if not username: + raise exceptions.AnomUser("%s need a username" % self.__class__) + + self._url = ('users', username) + self._model = models.AnomUser + self.username = username + super(User, self).__init__(gh) + + def __repr__(self): + return ' %s' % self.username + + def get(self): + return self._get_resource() + + def get_followers(self, limit=None): + return self._get_resources('followers') + + def get_following(self, limit=None): + return self._get_resources('following') + +class AuthUser(AnomUser): + """ Handler to query public/private api for authenticated user """ + + def __init__(self, gh): + self._url = ('user',) + self._model = models.User + super(AnomUser, self).__init__(gh) + + def __repr__(self): + return '' diff --git a/github3/helpers.py b/github3/helpers.py index abdeb4a..498a005 100644 --- a/github3/helpers.py +++ b/github3/helpers.py @@ -166,4 +166,4 @@ def get_scope(f, args=None): # scrub readability.models namespace scope = scope.replace('readability.api.', '') - return scope \ No newline at end of file + return scope diff --git a/github3/models.py b/github3/models.py deleted file mode 100644 index 3c86687..0000000 --- a/github3/models.py +++ /dev/null @@ -1,246 +0,0 @@ -""" -github3.models -~~~~~~~~~~~~~~ - -This module provides the Github3 object model. -""" - -import json - -from .helpers import to_python, to_api, key_diff - - -class BaseResource(object): - """A BaseResource object.""" - - _strs = [] - _ints = [] - _dates = [] - _bools = [] - _map = {} - _writeable = [] - _cache = {} - - - def __init__(self): - self._bootstrap() - super(BaseResource, self).__init__() - - - def __dir__(self): - return self.keys() - - def _bootstrap(self): - """Bootstraps the model object based on configured values.""" - - for attr in self.keys(): - setattr(self, attr, None) - - def keys(self): - return self._strs + self._ints + self._dates + self._bools + self._map.keys() - - def dict(self): - d = dict() - for k in self.keys(): - d[k] = self.__dict__.get(k) - - return d - - @classmethod - def new_from_dict(cls, d, gh=None): - - return to_python( - obj=cls(), in_dict=d, - str_keys = cls._strs, - int_keys = cls._ints, - date_keys = cls._dates, - bool_keys = cls._bools, - object_map = cls._map, - _gh = gh - ) - - - def update(self): - deploy = key_diff(self._cache, self.dict(), pack=True) - - deploy = to_api(deploy, int_keys=self._ints, date_keys=self._dates, bool_keys=self._bools) - deploy = json.dumps(deploy) - - r = self._gh._patch_resource(self.ri, deploy) - return r - - -class Plan(BaseResource): - """Github Plan object model.""" - - _strs = ['name'] - _ints = ['space', 'collaborators', 'private_repos'] - - def __repr__(self): - return ''.format(str(self.name)) - - - -class User(BaseResource): - """Github User object model.""" - - _strs = [ - 'login','avatar_url', 'url', 'name', 'company', 'blog', 'location', - 'email', 'bio', 'html_url'] - - _ints = ['id', 'public_repos', 'public_gists', 'followers', 'following'] - _dates = ['created_at',] - _bools = ['hireable', ] - # _map = {} - # _writeable = [] - - @property - def ri(self): - return ('users', self.login) - - def __repr__(self): - return ''.format(self.login) - - 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) - -class CurrentUser(User): - """Github Current User object model.""" - - _ints = [ - 'id', 'public_repos', 'public_gists', 'followers', 'following', - 'total_private_repos', 'owned_private_repos', 'private_gists', - 'disk_usage', 'collaborators'] - _map = {'plan': Plan} - _writeable = ['name', 'email', 'blog', 'company', 'location', 'hireable', 'bio'] - - @property - def ri(self): - return ('user',) - - def __repr__(self): - return ''.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) - - def gists(self, limit=None): - return self._gh._get_resources('gists', Gist, limit=limit) - - - -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 ''.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 '' % (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 ''.format(self.owner.login, self.name) - # owner diff --git a/github3/models/__init__.py b/github3/models/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/github3/models/base.py b/github3/models/base.py new file mode 100644 index 0000000..618e57f --- /dev/null +++ b/github3/models/base.py @@ -0,0 +1,178 @@ +""" +github3.models +~~~~~~~~~~~~~~ + +This module provides the Github3 object model. +""" + +import json + +from .helpers import to_python, to_api, key_diff + + +class BaseResource(object): + """A BaseResource object.""" + + _strs = [] + _ints = [] + _dates = [] + _bools = [] + _map = {} + _writeable = [] + _cache = {} + + + def __init__(self): + self._bootstrap() + super(BaseResource, self).__init__() + + + def __dir__(self): + return self.keys() + + def _bootstrap(self): + """Bootstraps the model object based on configured values.""" + + for attr in self.keys(): + setattr(self, attr, None) + + def keys(self): + return self._strs + self._ints + self._dates + self._bools + self._map.keys() + + def dict(self): + d = dict() + for k in self.keys(): + d[k] = self.__dict__.get(k) + + return d + + @classmethod + def new_from_dict(cls, d, gh=None): + + return to_python( + obj=cls(), in_dict=d, + str_keys = cls._strs, + int_keys = cls._ints, + date_keys = cls._dates, + bool_keys = cls._bools, + object_map = cls._map, + _gh = gh + ) + + + def update(self): + deploy = key_diff(self._cache, self.dict(), pack=True) + + deploy = to_api(deploy, int_keys=self._ints, date_keys=self._dates, bool_keys=self._bools) + deploy = json.dumps(deploy) + + r = self._gh._patch_resource(self.ri, deploy) + return r + + +class Plan(BaseResource): + """Github Plan object model.""" + + _strs = ['name'] + _ints = ['space', 'collaborators', 'private_repos'] + + def __repr__(self): + return ''.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 ''.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 '' % (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 ''.format(self.owner.login, self.name) + # owner diff --git a/github3/models/user.py b/github3/models/user.py new file mode 100644 index 0000000..cdbd04f --- /dev/null +++ b/github3/models/user.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# +# author: David Medina + +from .base import BaseResource + +class User(BaseResource): + """Github User object model.""" + + _strs = [ + 'login','avatar_url', 'url', 'name', 'company', 'blog', 'location', + 'email', 'bio', 'html_url'] + + _ints = ['id', 'public_repos', 'public_gists', 'followers', 'following'] + _dates = ['created_at',] + _bools = ['hireable', ] + # _map = {} + # _writeable = [] + + @property + def ri(self): + return ('users', self.login) + + def __repr__(self): + return ''.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) + +class AuthUser(User): + """Github Current User object model.""" + + _ints = [ + 'id', 'public_repos', 'public_gists', 'followers', 'following', + 'total_private_repos', 'owned_private_repos', 'private_gists', + 'disk_usage', 'collaborators'] + _map = {'plan': Plan} + _writeable = ['name', 'email', 'blog', 'company', 'location', 'hireable', 'bio'] + + @property + def ri(self): + return ('user',) + + def __repr__(self): + return ''.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) + + def gists(self, limit=None): + return self._gh._get_resources('gists', Gist, limit=limit) -- cgit v1.2.3-59-g8ed1b