This commit is contained in:
Kenneth Reitz
2011-12-26 23:19:40 -05:00
parent 5f12865629
commit b26751f3a9
+263
View File
@@ -0,0 +1,263 @@
# -*- coding: utf-8 -*-
"""
github3.models
~~~~~~~~~~~~~~
This module contains the models that comprise the Github API.
"""
import json
from urllib import quote
import requests
from .helpers import to_python
from .structures import *
class BaseResource(object):
_strs = []
_ints = []
_dates = []
_bools = []
_dicts = []
_map = {}
_pks = []
def __init__(self):
self._bootstrap()
self._h = None
super(BaseResource, self).__init__()
def __repr__(self):
return "<resource '{0}'>".format(self._id)
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()
@property
def _id(self):
try:
return getattr(self, self._pks[0])
except IndexError:
return None
@property
def _ids(self):
"""The list of primary keys to validate against."""
for pk in self._pks:
yield getattr(self, pk)
for pk in self._pks:
try:
yield str(getattr(self, pk))
except ValueError:
pass
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, h=None, **kwargs):
d = to_python(
obj=cls(),
in_dict=d,
str_keys=cls._strs,
int_keys=cls._ints,
date_keys=cls._dates,
bool_keys=cls._bools,
dict_keys= cls._dicts,
object_map=cls._map,
_h = h
)
d.__dict__.update(kwargs)
return d
class App(BaseResource):
"""Heroku App."""
_strs = ['name', 'create_status', 'stack', 'repo_migrate_status']
_ints = ['id', 'slug_size', 'repo_size', 'dynos', 'workers']
_dates = ['created_at',]
_pks = ['name', 'id']
def __init__(self):
super(App, self).__init__()
def __repr__(self):
return "<app '{0}'>".format(self.name)
def new(self, name=None, stack='cedar'):
"""Creates a new app."""
payload = {}
if name:
payload['app[name]'] = name
if stack:
payload['app[stack]'] = stack
r = self._h._http_resource(
method='POST',
resource=('apps',),
data=payload
)
name = json.loads(r.content).get('name')
return self._h.apps.get(name)
@property
def addons(self):
return self._h._get_resources(
resource=('apps', self.name, 'addons'),
obj=Addon, app=self
)
@property
def collaborators(self):
"""The collaborators for this app."""
return self._h._get_resources(
resource=('apps', self.name, 'collaborators'),
obj=Collaborator, app=self
)
@property
def domains(self):
"""The domains for this app."""
return self._h._get_resources(
resource=('apps', self.name, 'domains'),
obj=Domain, app=self
)
@property
def releases(self):
"""The releases for this app."""
return self._h._get_resources(
resource=('apps', self.name, 'releases'),
obj=Release, app=self
)
@property
def processes(self):
"""The proccesses for this app."""
return self._h._get_resources(
resource=('apps', self.name, 'ps'),
obj=Process, app=self, map=ProcessListResource
)
@property
def config(self):
"""The envs for this app."""
return self._h._get_resource(
resource=('apps', self.name, 'config_vars'),
obj=ConfigVars, app=self
)
@property
def info(self):
"""Returns current info for this app."""
return self._h._get_resource(
resource=('apps', self.name),
obj=App,
)
def rollback(self, release):
"""Rolls back the release to the given version."""
r = self._h._http_resource(
method='POST',
resource=('apps', self.name, 'releases'),
data={'rollback': release}
)
return self.releases[-1]
def rename(self, name):
"""Renames app to given name."""
r = self._h._http_resource(
method='PUT',
resource=('apps', self.name),
data={'app[name]': name}
)
return r.ok
def transfer(self, user):
"""Transfers app to given username's account."""
r = self._h._http_resource(
method='PUT',
resource=('apps', self.name),
data={'app[transfer_owner]': user}
)
return r.ok
def maintenance(self, on=True):
"""Toggles maintenance mode."""
r = self._h._http_resource(
method='POST',
resource=('apps', self.name, 'server', 'maintenance'),
data={'maintenance_mode': int(on)}
)
return r.ok
def destroy(self):
"""Destoys the app. Do be careful."""
r = self._h._http_resource(
method='DELETE',
resource=('apps', self.name)
)
return r.ok
def logs(self, num=None, source=None, tail=False):
"""Returns the requested log."""
# Bootstrap payload package.
payload = {'logplex': 'true'}
if num:
payload['num'] = num
if source:
payload['source'] = source
if tail:
payload['tail'] = 1
# Grab the URL of the logplex endpoint.
r = self._h._http_resource(
method='GET',
resource=('apps', self.name, 'logs'),
data=payload
)
# Grab the actual logs.
r = requests.get(r.content)
if not tail:
return r.content
else:
# Return line iterator for tail!
return r.iter_lines()