Skip to content
This repository was archived by the owner on Oct 24, 2022. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
beebe5c
Testing post gist
copitux Oct 29, 2011
c23698e
Wip on handlers
copitux Oct 29, 2011
b17dbea
Decouple Handlers and Models
copitux Nov 1, 2011
2506d0e
Merge branch 'handlers' into develop
copitux Nov 1, 2011
51d258b
Fix bug. Import own exceptions
copitux Nov 1, 2011
c0a5c2c
Fix bug. PEP8
copitux Nov 1, 2011
15b7cc0
Fix names. Added raw request
copitux Nov 1, 2011
d57caeb
Fix bug generate_url
copitux Nov 1, 2011
aeed4c5
Add get_bool request
copitux Nov 1, 2011
81f483a
Complete AuthUser handler
copitux Nov 1, 2011
bb54072
Refactor base to handler design
copitux Nov 4, 2011
bdc593a
Fix litle bugs and args to request
copitux Nov 5, 2011
7616bc8
Handlers and paginate resources
copitux Nov 5, 2011
dfc3826
Added gitignore, it doesn't matter
copitux Nov 6, 2011
df73c78
Doc and refactorize
copitux Nov 6, 2011
79b46e9
Cleaning files from origin repo
copitux Nov 6, 2011
6f2d211
Modelizer class. json<->model parser
copitux Nov 6, 2011
b9dc036
Fix typo
copitux Nov 7, 2011
a423c22
_post_resource
akaihola Nov 7, 2011
6d7b654
Added the create_gist() method
akaihola Nov 7, 2011
86da17c
Added akaihola to authors
akaihola Nov 7, 2011
878a2fa
Added create_gist() example to readme
akaihola Nov 7, 2011
e738e47
Fix clean
copitux Nov 8, 2011
d783e25
Abstract and decouple converters
copitux Nov 8, 2011
88f3b88
Added post_resource to handler
copitux Nov 8, 2011
a7cb909
Prefix handlers
copitux Nov 8, 2011
6dc5997
Added User/AuthUser handler
copitux Nov 8, 2011
c614dde
Added support for extra args to get_resources
copitux Nov 8, 2011
ba1fcac
Support for proxys in _bool handler
copitux Nov 8, 2011
40cbe59
Fixing bugs. Crazy night :S
copitux Nov 9, 2011
f1a03e9
Merged create_gist() into current HEAD of copitux/develop
akaihola Nov 9, 2011
15fd929
Updated example in README.rst to work with current version
akaihola Nov 9, 2011
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Modelizer class. json<->model parser
Also reorganize code
  • Loading branch information
copitux committed Nov 6, 2011
commit 6f2d2115fa578e2d5aa611fe03474341d73f73cc
2 changes: 0 additions & 2 deletions github3/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
# -*- coding: utf-8 -*-

from core import *
124 changes: 104 additions & 20 deletions github3/core.py
Original file line number Diff line number Diff line change
@@ -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
62 changes: 13 additions & 49 deletions github3/handlers/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 """
Expand All @@ -60,23 +14,33 @@ def __init__(self, gh):

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

#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)
145 changes: 7 additions & 138 deletions github3/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 '<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)
#
#
def idl(self):
raise NotImplementedError('Each model need subcass that method')
Loading