From b17dbea56f59aa5403e5722e12878c7183742551 Mon Sep 17 00:00:00 2001 From: David Medina Date: Tue, 1 Nov 2011 12:30:25 +0100 Subject: Decouple Handlers and Models Handler User complete --- github3/models/gists.py | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 github3/models/gists.py (limited to 'github3/models/gists.py') 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 ' %s' % self.filename + +class GistFork(BaseResource): + _strs = ['url'] + _dates = ['created_at'] + _map = {'user': User} + + def __repr__(self): + return ' %s>' % self.user.login + +class ChangeStatus(BaseResource): + _ints = ['deletions', 'additions', 'total'] + + def __repr__(self): + return ' 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 '' % (self.user.login, self.description) + -- cgit v1.2.3-59-g8ed1b From 6f2d2115fa578e2d5aa611fe03474341d73f73cc Mon Sep 17 00:00:00 2001 From: David Medina Date: Sun, 6 Nov 2011 18:14:51 +0100 Subject: Modelizer class. json<->model parser Also reorganize code --- github3/__init__.py | 2 - github3/core.py | 124 +++++++++++++++++++++++++++++++++------- github3/handlers/base.py | 62 +++++--------------- github3/models/base.py | 145 +++-------------------------------------------- github3/models/gists.py | 68 +++++++++++++++------- github3/models/orgs.py | 27 ++++----- github3/models/repos.py | 35 ++++++------ github3/models/user.py | 69 +++++++++++----------- 8 files changed, 236 insertions(+), 296 deletions(-) (limited to 'github3/models/gists.py') diff --git a/github3/__init__.py b/github3/__init__.py index fcb882b..40a96af 100644 --- a/github3/__init__.py +++ b/github3/__init__.py @@ -1,3 +1 @@ # -*- coding: utf-8 -*- - -from core import * diff --git a/github3/core.py b/github3/core.py index d6eed22..0aa5949 100644 --- a/github3/core.py +++ b/github3/core.py @@ -1,30 +1,114 @@ -# -*- coding: utf-8 -*- +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +# +# author: David Medina -""" -github3.core -~~~~~~~~~~~~ +class Paginate: + """ Paginate resource iterator -This module provides the entrance point for the GitHub3 module. -""" + :param resource: URL resource + :param requester: Bound method to request. See `GithubCore.get` + """ -__version__ = '0.0.0' -__license__ = 'MIT' -__author__ = 'Kenneth Reitz' + def __init__(self, resource, requester): + self.resource = resource + self.requester = requester + self.page = 1 -from .api import Github + def _last_page(self, link): + """ Get and cached last page from link header """ + if not getattr(self, 'last', False): + from github3.packages.link_header import parse_link_value + from urlparse import urlparse, parse_qs + for link, rels in parse_link_value(link).items(): + if rels.get('rel') == 'last': + query = urlparse(link).query + self.last = int(parse_qs(query).get('page').pop()) -def no_auth(): - """Returns an un-authenticated Github object.""" + return self.last - gh = Github() + def __iter__(self): + return self - return gh + def initial(self): + """ First request. Force requester to paginate returning link header """ + link, content = self.requester(self.resource, paginate=True, page=1) + self.last = self._last_page(link) if link else 1 + return content -def basic_auth(username, password): - """Returns an authenticated Github object, via HTTP Basic.""" + def next(self): + if self.page == 1: + content = self.initial() + self.page += 1 + return content + else: + if self.page > self.last: + raise StopIteration + else: + content = self.requester(self.resource, page=self.page) + self.page += 1 + return content - gh = Github() - gh.is_authenticated = True - gh.session.auth = (username, password) +class Modelizer(object): + """ Converter json into model and vice versa """ - return gh + def __init__(self, model): + self.model = model + self.attrs = {} + + def _parse_date(self, string_date): + from datetime import datetime + try: + date = datetime.strptime(string_date, '%Y-%m-%dT%H:%M:%SZ') + except TypeError: + date = None + + return date + + def _parse_map(self, model, raw_resource): + if model == 'self': + model = self.model + + return Modelizer(model).loads(raw_resource) + + def _parse_collection_map(self, model, raw_resources): + # Dict of resources (Ex: Gist file) + if getattr(raw_resources, 'items', False): + dict_map = {} + for key, raw_resource in raw_resources.items(): + dict_map[key] = Modelizer(model).loads(raw_resource) + return dict_map + # list of resources + else: + return [Modelizer(model).loads(raw_resource) + for raw_resource in raw_resources] + + def loads(self, raw_resource): + attrs = {} + idl = self.model.idl() + attrs.update( + {attr: raw_resource[attr] for attr in idl.get('strs',()) + if raw_resource.get(attr)}) + attrs.update( + {attr: raw_resource[attr] for attr in idl.get('ints',()) + if raw_resource.get(attr)}) + attrs.update( + {attr: self._parse_date(raw_resource[attr]) + for attr in idl.get('dates',()) if raw_resource.get(attr)}) + attrs.update( + {attr: raw_resource[attr] for attr in idl.get('bools',()) + if raw_resource.get(attr)}) + attrs.update( + {attr: self._parse_map(model, raw_resource[attr]) + for attr, model in idl.get('maps',{}).items() + if raw_resource.get(attr)}) + attrs.update( + {attr: self._parse_collection_map(model, raw_resource[attr]) + for attr, model in idl.get('collection_maps',{}).items() + if raw_resource.get(attr)}) + + return self.model(attrs) + + def dumps(self): + # return JSON + pass diff --git a/github3/handlers/base.py b/github3/handlers/base.py index 3f82817..0d8be0e 100644 --- a/github3/handlers/base.py +++ b/github3/handlers/base.py @@ -3,53 +3,7 @@ # # author: David Medina -import github3.exceptions as ghexceptions - -class Paginate: - """ Paginate resource iterator - - :param resource: URL resource - :param requester: Bound method to request. See `GithubCore.get` - """ - - def __init__(self, resource, requester): - self.resource = resource - self.requester = requester - self.page = 1 - - def _last_page(self, link): - """ Get and cached last page from link header """ - if not getattr(self, 'last', False): - from github3.packages.link_header import parse_link_value - from urlparse import urlparse, parse_qs - for link, rels in parse_link_value(link).items(): - if rels.get('rel') == 'last': - query = urlparse(link).query - self.last = int(parse_qs(query).get('page').pop()) - - return self.last - - def __iter__(self): - return self - - def initial(self): - """ First request. Force requester to paginate returning link header """ - link, content = self.requester(self.resource, paginate=True, page=1) - self.last = self._last_page(link) if link else 1 - return content - - def next(self): - if self.page == 1: - content = self.initial() - self.page += 1 - return content - else: - if self.page > self.last: - raise StopIteration - else: - content = self.requester(self.resource, page=self.page) - self.page += 1 - return content +from github3.core import Paginate, Modelizer class Handler(object): """ Handler base. Requests to API and modelize responses """ @@ -60,9 +14,11 @@ class Handler(object): def _bool(self, resource, **kwargs): """ Handler request to boolean response """ + + from github3.exceptions import NotFound try: response = self._gh.head(resource, **kwargs) - except ghexceptions.NotFound: + except NotFound: return False assert response.status_code == 204 return True @@ -70,13 +26,21 @@ class Handler(object): #TODO: if limit is multiple of per_page... it do another request for nothing def _get_resources(self, resource, model=None, limit=None): """ Hander request to multiple resources """ + page_resources = Paginate(resource, self._gh.get) counter = 1 for page in page_resources: for raw_resource in page: if limit and counter > limit: break counter += 1 - yield raw_resource + yield Modelizer(model or self.model).loads(raw_resource) + #yield raw_resource else: continue break + + def _get_resource(self, resource, model=None): + """ Handler request to single request """ + + raw_resource = self._gh.get(resource) + return Modelizer(model or self.model).loads(raw_resource) diff --git a/github3/models/base.py b/github3/models/base.py index f98af2d..df0c82b 100644 --- a/github3/models/base.py +++ b/github3/models/base.py @@ -2,149 +2,18 @@ github3.models ~~~~~~~~~~~~~~ -This module provides the Github3 object model. +This package provides the Github3 object model. """ -import json -import inspect - -from github3.helpers import to_python, to_api, key_diff - class BaseResource(object): """A BaseResource object.""" - _strs = [] - _ints = [] - _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[1]), - inspect.getmembers(handler, inspect.ismethod)) - for name, callback in methods: - setattr(self, name, callback) - except: - pass - - def __init__(self): - self._bootstrap() + def __init__(self, attrs=None): + if attrs: + for attr, value in attrs.items(): + setattr(self, attr, value) 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, - list_map = cls._list_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 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) -# -# + def idl(self): + raise NotImplementedError('Each model need subcass that method') diff --git a/github3/models/gists.py b/github3/models/gists.py index 5ad61c3..d1b416d 100644 --- a/github3/models/gists.py +++ b/github3/models/gists.py @@ -7,43 +7,71 @@ from .base import BaseResource from .user import User class File(BaseResource): - _strs = ['filename', 'raw_url', 'content', 'language', 'type'] - _ints = ['size'] + """ File model """ + + @classmethod + def idl(self): + return { + 'strs': ['filename', 'raw_url', 'content', 'language', 'type'], + 'ints': ['size'], + } def __repr__(self): return ' %s' % self.filename class GistFork(BaseResource): - _strs = ['url'] - _dates = ['created_at'] - _map = {'user': User} + """ GistFork model """ + + @classmethod + def idl(self): + return { + 'strs': ['url'], + 'dates': ['created_at'], + 'maps': {'user': User} + } def __repr__(self): return ' %s>' % self.user.login class ChangeStatus(BaseResource): - _ints = ['deletions', 'additions', 'total'] + """ ChangeStatus model """ + + @classmethod + def idl(self): + return { + 'ints': ['deletions', 'additions', 'total'], + } def __repr__(self): return ' change_status>' class GistHistory(BaseResource): - _strs = ['url', 'version'] - _map = {'user': User, 'change_status': ChangeStatus} - _dates = ['committed_at'] + """ """ + + @classmethod + def idl(self): + return { + 'strs': ['url', 'version'], + 'maps': {'user': User, 'change_status': ChangeStatus}, + 'dates': ['committed_at'], + } + + def __repr__(self): + return '' % (self.user, self.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) + @classmethod + def idl(self): + return { + 'strs': ['url', 'description', 'html_url', 'git_pull_url', 'git_push_url'], + 'ints': ['id', 'comments'], + 'bools': ['public'], + 'dates': ['created_at'], + 'maps': {'user': User}, + 'collection_maps': {'files': File, 'forks': GistFork, 'history': GistHistory}, + } def __repr__(self): - return '' % (self.user.login, self.description) - + return '' % (self.user, self.description) diff --git a/github3/models/orgs.py b/github3/models/orgs.py index 1ce638e..840b51a 100644 --- a/github3/models/orgs.py +++ b/github3/models/orgs.py @@ -9,20 +9,17 @@ 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) + @classmethod + def idl(self): + return { + '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'], + 'maps': {'plan': plan} + } def __repr__(self): - return ''.format(self.login) + return '' % self.login diff --git a/github3/models/repos.py b/github3/models/repos.py index 8dbe970..ba6ac33 100644 --- a/github3/models/repos.py +++ b/github3/models/repos.py @@ -8,23 +8,24 @@ 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', - } + """ Repo model """ - @property - def ri(self): - return ('repos', self.owner.login, self.name) + @classmethod + def idl(self): + return { + 'strs': [ + 'url', 'html_url', 'clone_url', 'git_url', 'ssh_url', 'svn_url', + 'name', 'description', 'homepage', 'language', 'master_branch'], + 'ints': ['forks', 'watchers', 'size', 'open_issues'], + 'dates': ['created_at', 'pushed_at'], + 'bools': ['private', 'fork', 'has_issues', 'has_wiki', 'has_downloads'], + 'maps': { + 'owner': User, + 'organization': Org, + 'parent': 'self', + 'source': 'self', + } + } def __repr__(self): - return ''.format(self.owner.login, self.name) - # owner + return '' % (self.owner.login, self.name) diff --git a/github3/models/user.py b/github3/models/user.py index 3f0efc4..7ec7999 100644 --- a/github3/models/user.py +++ b/github3/models/user.py @@ -8,59 +8,58 @@ from .base import BaseResource class Plan(BaseResource): """Github Plan object model.""" - _strs = ['name'] - _ints = ['space', 'collaborators', 'private_repos'] + @classmethod + def idl(self): + return { + 'strs': ['name'], + 'ints': ['space', 'collaborators', 'private_repos'], + } def __repr__(self): - return ''.format(str(self.name)) + return '' % self.name class Key(BaseResource): """Github Key object model.""" - _strs = ['url', 'title', 'key'] - _ints = ['id'] + @classmethod + def idl(self): + return { + 'strs': ['url', 'title', 'key'], + 'ints': ['id'], + } def __repr__(self): - return ''.format(str(self.title)) + return '' % self.title class User(BaseResource): """Github User object model.""" - _strs = [ - 'login','avatar_url', 'url', 'name', 'company', 'blog', 'location', - 'email', 'bio', 'html_url', 'type'] - - _ints = ['id', 'public_repos', 'public_gists', 'followers', 'following'] - _dates = ['created_at',] - _bools = ['hireable', ] - - @property - def ri(self): - return ('users', self.login) + @classmethod + def idl(self): + return { + 'strs': ['login','avatar_url', 'url', 'name', 'company', 'blog', + 'location', 'email', 'bio', 'html_url', 'type'], + 'ints': [ + 'id', 'public_repos', 'public_gists', 'followers', 'following', + 'total_private_repos', 'owned_private_repos', 'private_gists', + 'disk_usage', 'collaborators'], + 'maps': {'plan': Plan}, + 'dates': ['created_at',], + 'bools': ['hireable', ], + } def __repr__(self): - return ''.format(self.login) + return '' % self.login - def handler(self): - return self._gh.user_handler(self.login, force=True) + #def handler(self): + # return self._gh.user_handler(self.login, force=True) 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'] - - def handler(self): - return self._gh.user_handler(self.login, force=True, private=True) + """Github Authenticated User object model.""" - @property - def ri(self): - return ('user',) + #def handler(self): + # return self._gh.user_handler(self.login, force=True, private=True) def __repr__(self): - return ''.format(self.login) + return '' % self.login -- cgit v1.2.3-59-g8ed1b From b04156007fa3411c2ae8228e7dbc01da64193eef Mon Sep 17 00:00:00 2001 From: David Medina Date: Thu, 17 Nov 2011 00:16:23 +0100 Subject: Del authors on code. Delegate it to AUTHORS ;) --- github3/api.py | 2 - github3/core.py | 2 - github3/errors.py | 2 - github3/exceptions.py | 2 - github3/handlers/base.py | 2 - github3/handlers/gists.py | 2 - github3/handlers/users.py | 2 - github3/helpers.py | 188 ---------------------------------------- github3/models/base.py | 8 +- github3/models/gists.py | 2 - github3/models/orgs.py | 2 - github3/models/repos.py | 2 - github3/models/user.py | 2 - github3/packages/link_header.py | 3 +- 14 files changed, 4 insertions(+), 217 deletions(-) delete mode 100644 github3/helpers.py (limited to 'github3/models/gists.py') diff --git a/github3/api.py b/github3/api.py index a4ee4a9..d8d2ffb 100644 --- a/github3/api.py +++ b/github3/api.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina import requests import json diff --git a/github3/core.py b/github3/core.py index b838bf1..ab71943 100644 --- a/github3/core.py +++ b/github3/core.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina class Paginate: diff --git a/github3/errors.py b/github3/errors.py index eed1e6c..e96e2da 100644 --- a/github3/errors.py +++ b/github3/errors.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina import json import github3.exceptions as exceptions diff --git a/github3/exceptions.py b/github3/exceptions.py index dbc4d2c..b9070d7 100644 --- a/github3/exceptions.py +++ b/github3/exceptions.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina class BadRequest(Exception): pass diff --git a/github3/handlers/base.py b/github3/handlers/base.py index 0b3fa8a..4e9198f 100644 --- a/github3/handlers/base.py +++ b/github3/handlers/base.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina from github3.core import Paginate from github3.converters import Modelizer diff --git a/github3/handlers/gists.py b/github3/handlers/gists.py index fa961b2..38418ca 100644 --- a/github3/handlers/gists.py +++ b/github3/handlers/gists.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: Antti Kaihola from .base import Handler from .. import models diff --git a/github3/handlers/users.py b/github3/handlers/users.py index 84180b5..34ed013 100644 --- a/github3/handlers/users.py +++ b/github3/handlers/users.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina from .base import Handler import github3.models as models diff --git a/github3/helpers.py b/github3/helpers.py deleted file mode 100644 index 205e097..0000000 --- a/github3/helpers.py +++ /dev/null @@ -1,188 +0,0 @@ -# -*- coding: utf-8 -*- - -""" -github3.helpers -~~~~~~~~~~~~~~~~ - -This module provides various helper functions to the rest of the package. -""" - -import inspect -from datetime import datetime - -from dateutil.parser import parse as parse_datetime - - -def is_collection(obj): - """Tests if an object is a collection.""" - - col = getattr(obj, '__getitem__', False) - val = False if (not col) else True - - if isinstance(obj, basestring): - val = False - - return val - - -def key_diff(source, update, pack=False): - """Given two dictionaries, returns a list of the changed keys.""" - - source = dict(source) - update = dict(update) - - changed = [] - - for (k, v) in source.items(): - u_v = update.get(k) - - if (v != u_v) and (u_v is not None): - changed.append(k) - - if pack is False: - return changed - - d = dict() - - for k in changed: - d[k] = update[k] - - return d - - -# from arc90/python-readability-api -def to_python(obj, - in_dict, - str_keys=None, - date_keys=None, - int_keys=None, - object_map=None, - list_map=None, - bool_keys=None, **kwargs): - """Extends a given object for API Consumption. - - :param obj: Object to extend. - :param in_dict: Dict to extract data from. - :param string_keys: List of in_dict keys that will be extracted as strings. - :param date_keys: List of in_dict keys that will be extrad as datetimes. - :param object_map: Dict of {key, obj} map, for nested object results. - """ - - d = dict() - - if str_keys: - for in_key in str_keys: - d[in_key] = in_dict.get(in_key) - - if date_keys: - for in_key in date_keys: - in_date = in_dict.get(in_key) - try: - out_date = datetime.strptime(in_date, '%Y-%m-%dT%H:%M:%SZ') - except TypeError: - out_date = None - - d[in_key] = out_date - - if int_keys: - for in_key in int_keys: - if (in_dict is not None) and (in_dict.get(in_key) is not None): - d[in_key] = int(in_dict.get(in_key)) - - if bool_keys: - for in_key in bool_keys: - if in_dict.get(in_key) is not None: - d[in_key] = bool(in_dict.get(in_key)) - - 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 - - -# from arc90/python-readability-api -def to_api(in_dict, int_keys=None, date_keys=None, bool_keys=None): - """Extends a given object for API Production.""" - - # Cast all int_keys to int() - if int_keys: - for in_key in int_keys: - if (in_key in in_dict) and (in_dict.get(in_key, None) is not None): - in_dict[in_key] = int(in_dict[in_key]) - - # Cast all date_keys to datetime.isoformat - if date_keys: - for in_key in date_keys: - if (in_key in in_dict) and (in_dict.get(in_key, None) is not None): - - _from = in_dict[in_key] - - if isinstance(_from, basestring): - dtime = parse_datetime(_from) - - elif isinstance(_from, datetime): - dtime = _from - - in_dict[in_key] = dtime.isoformat() - - elif (in_key in in_dict) and in_dict.get(in_key, None) is None: - del in_dict[in_key] - - # Remove all Nones - for k, v in in_dict.items(): - if v is None: - del in_dict[k] - - return in_dict - - - -# from kennethreitz/showme -def get_scope(f, args=None): - """Get scope of given function for Exception scopes.""" - - if args is None: - args=list() - - scope = inspect.getmodule(f).__name__ - # guess that function is a method of it's class - try: - if f.func_name in dir(args[0].__class__): - scope += '.' + args[0].__class__.__name__ - scope += '.' + f.__name__ - else: - scope += '.' + f.__name__ - except IndexError: - scope += '.' + f.__name__ - - # scrub readability.models namespace - scope = scope.replace('readability.api.', '') - - return scope diff --git a/github3/models/base.py b/github3/models/base.py index bd07650..5295d07 100644 --- a/github3/models/base.py +++ b/github3/models/base.py @@ -1,9 +1,5 @@ -""" -github3.models -~~~~~~~~~~~~~~ - -This package provides the Github3 object model. -""" +#!/usr/bin/env python +# -*- encoding: utf-8 -*- class BaseResource(object): """A BaseResource object.""" diff --git a/github3/models/gists.py b/github3/models/gists.py index d1b416d..b317f57 100644 --- a/github3/models/gists.py +++ b/github3/models/gists.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina from .base import BaseResource from .user import User diff --git a/github3/models/orgs.py b/github3/models/orgs.py index 5e66c35..b2dacbd 100644 --- a/github3/models/orgs.py +++ b/github3/models/orgs.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina from .base import BaseResource from .user import Plan diff --git a/github3/models/repos.py b/github3/models/repos.py index d1b7b75..882fb37 100644 --- a/github3/models/repos.py +++ b/github3/models/repos.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina from .base import BaseResource from .user import User diff --git a/github3/models/user.py b/github3/models/user.py index e2d82b6..93201bd 100644 --- a/github3/models/user.py +++ b/github3/models/user.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # -*- encoding: utf-8 -*- -# -# author: David Medina from .base import BaseResource diff --git a/github3/packages/link_header.py b/github3/packages/link_header.py index 3959604..5ad20f1 100644 --- a/github3/packages/link_header.py +++ b/github3/packages/link_header.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# -*- encoding: utf-8 -*- """ HTTP Link Header Parsing @@ -86,4 +87,4 @@ def parse_link_value(instr): if __name__ == '__main__': import sys if len(sys.argv) > 1: - print parse_link_value(sys.argv[1]) \ No newline at end of file + print parse_link_value(sys.argv[1]) -- cgit v1.2.3-59-g8ed1b From 88e54d4dc2e9c49dadf1a9b8e14fc107270c9415 Mon Sep 17 00:00:00 2001 From: David Medina Date: Tue, 29 Nov 2011 22:19:26 +0100 Subject: pep8 --- github3/handlers/base.py | 12 +++++++----- github3/models/gists.py | 10 ++++++++-- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'github3/models/gists.py') diff --git a/github3/handlers/base.py b/github3/handlers/base.py index 7bc55d2..b20bb7d 100644 --- a/github3/handlers/base.py +++ b/github3/handlers/base.py @@ -55,9 +55,9 @@ class Handler(object): def _get_converter(self, **kwargs): converter = kwargs.get( - 'converter', # 1. in kwargs - getattr(self, 'converter', # 2. in handler - Modelizer)) # 3. Default + 'converter', # 1. in kwargs + getattr(self, 'converter', # 2. in handler + Modelizer)) # 3. Default return converter() @@ -77,7 +77,8 @@ class Handler(object): from github3.exceptions import NotFound resource = self._prefix_resource(resource) try: - callback = getattr(self._gh, kwargs.get('method',''), self._gh.head) + callback = getattr(self._gh, kwargs.get('method', ''), + self._gh.head) response = callback(resource, **kwargs) except NotFound: return False @@ -97,7 +98,8 @@ class Handler(object): converter = self._get_converter(**kwargs) converter.inject(model) yield converter.loads(raw_resource) - if limit and counter > limit: break + if limit and counter > limit: + break else: continue break diff --git a/github3/models/gists.py b/github3/models/gists.py index b317f57..13f3a62 100644 --- a/github3/models/gists.py +++ b/github3/models/gists.py @@ -17,6 +17,7 @@ class File(BaseResource): def __repr__(self): return ' %s' % self.filename + class GistFork(BaseResource): """ GistFork model """ @@ -31,6 +32,7 @@ class GistFork(BaseResource): def __repr__(self): return ' %s>' % self.user.login + class ChangeStatus(BaseResource): """ ChangeStatus model """ @@ -43,6 +45,7 @@ class ChangeStatus(BaseResource): def __repr__(self): return ' change_status>' + class GistHistory(BaseResource): """ """ @@ -57,18 +60,21 @@ class GistHistory(BaseResource): def __repr__(self): return '' % (self.user, self.committed_at) + class Gist(BaseResource): """ """ @classmethod def idl(self): return { - 'strs': ['url', 'description', 'html_url', 'git_pull_url', 'git_push_url'], + 'strs': ['url', 'description', 'html_url', 'git_pull_url', + 'git_push_url'], 'ints': ['id', 'comments'], 'bools': ['public'], 'dates': ['created_at'], 'maps': {'user': User}, - 'collection_maps': {'files': File, 'forks': GistFork, 'history': GistHistory}, + 'collection_maps': {'files': File, 'forks': GistFork, + 'history': GistHistory}, } def __repr__(self): -- cgit v1.2.3-59-g8ed1b From 1b310d37945c6f846f2145817353d9d03916a2ae Mon Sep 17 00:00:00 2001 From: David Medina Date: Tue, 29 Nov 2011 23:24:15 +0100 Subject: GistComment model --- github3/models/__init__.py | 2 +- github3/models/gists.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) (limited to 'github3/models/gists.py') diff --git a/github3/models/__init__.py b/github3/models/__init__.py index ff0c28a..0471393 100644 --- a/github3/models/__init__.py +++ b/github3/models/__init__.py @@ -1,4 +1,4 @@ from .user import AuthUser, User, Key from .repos import Repo from .orgs import Org -from .gists import Gist +from .gists import Gist, GistComment diff --git a/github3/models/gists.py b/github3/models/gists.py index 13f3a62..8979dbb 100644 --- a/github3/models/gists.py +++ b/github3/models/gists.py @@ -4,6 +4,23 @@ from .base import BaseResource from .user import User + +class GistComment(BaseResource): + """ Gist comment """ + + @classmethod + def idl(self): + return { + 'strs': ['url', 'body', 'body_text', 'body_html'], + 'ints': ['id'], + 'maps': {'user': User}, + 'dates': ['created_at'], + } + + def __repr__(self): + return '' % self.user.login + + class File(BaseResource): """ File model """ -- cgit v1.2.3-59-g8ed1b