Created
July 9, 2012 19:53
-
-
Save rubik/3078516 to your computer and use it in GitHub Desktop.
Example command line program powered by Baker and other cool libraries (pathlib, slumber & colorama)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import baker | |
import slumber | |
import pathlib | |
import colorama | |
API_URL = 'https://api.github.com/' | |
def get_api(auth=None): | |
if auth is not None: | |
auth = tuple(map(str.strip, auth.split(','))) | |
return slumber.API(base_url=API_URL, auth=auth, append_slash=False) | |
def find_matching(dir, include, exclude): | |
if not include: | |
return [] | |
included = set(dir.glob(include)) | |
if exclude is not None: | |
included -= set(dir.glob(exclude)) | |
return [path for path in included if path.is_file()] | |
def log(msg, indent=0): | |
if indent == 0: | |
prompt = colorama.Fore.RED + '=>' | |
msg = '{0}{1} {2}{3}'.format(colorama.Style.BRIGHT, | |
prompt, | |
colorama.Fore.GREEN, | |
msg) | |
sys.stdout.write('{0}{1}{2}\n'.format(' ' * indent * 4, msg, | |
colorama.Style.RESET_ALL)) | |
@baker.command(shortopts={'dest': 'd'}) | |
def get(id, dest='.', auth=None): | |
'''Download all files from a specified gist. | |
:param id: The number identifying the gist. | |
:param dest: The destination directory. Default to the current working | |
directory. | |
:param auth: Authentication tokens separated by a comma | |
(i.e. username,password).. | |
''' | |
dest = pathlib.Path(dest).resolve() | |
api = get_api(auth) | |
log('Downloading gist {0}'.format(id)) | |
files = api.gists(id).get()['files'] | |
for file, properties in files.items(): | |
filename = properties['filename'] | |
with dest[str(filename)].open('w') as fobj: | |
log('Getting {0}'.format(filename), 1) | |
fobj.write(properties['content']) | |
@baker.command(shortopts={'dir': 'd', 'include': 'i', 'exclude': 'e', | |
'public': 'p', 'description': 'D', 'auth': 'a'}) | |
def new(dir='.', include=None, exclude=None, public=False, description=None, | |
auth=None, *additional_files): | |
'''Create a new gist and upload files to it. | |
:param dir: The directory where to search for files. Default to current | |
working directory. | |
:param include: A glob pattern indicating which files to select. | |
:param exclude: A glob pattern indicating which files to exclude. | |
:param public: If True, gist will be set to public. Otherwise it will | |
be private. Default to False. | |
:param description: A description of the gist. | |
:param auth: Authentication tokens separated by a comma | |
(i.e. username,password).. | |
''' | |
dir = pathlib.Path(dir).resolve() | |
payload = {'description': description, 'public': public, 'files': {}} | |
log('Looking for matching files') | |
files = find_matching(dir, include, exclude) | |
if not files + list(additional_files): | |
log('ERROR: No files to upload!') | |
sys.exit(1) | |
for path in files + map(pathlib.Path, additional_files): | |
log('Adding {0}'.format(path), 1) | |
with path.open() as fobj: | |
payload['files'][path.parts[-1]] = {'content': fobj.read()} | |
log('Metadata') | |
log('Description: {0}'.format(payload['description']), 1) | |
log('Public: {0}'.format(payload['public']), 1) | |
api = get_api(auth) | |
log('Uploading') | |
response = api.gists.post(payload) | |
log('Gist id is: {0}'.format(response['id'])) | |
@baker.command | |
def delete(id, auth): | |
'''Delete a gist. | |
:param id: The number which identifies the gist. | |
:param auth: Authentication tokens separated by a comma | |
(i.e. username,password). | |
''' | |
api = get_api(auth) | |
log('Deleting gist') | |
api.gists(id).delete() | |
def _star(func): | |
def aux(id, auth): | |
'''{0} a gist. | |
:param id: The number identifying the gist. | |
:param auth: Authentication tokens separated by a comma | |
(i.e. username,password). | |
''' | |
api = get_api(auth).gists(id).star | |
func(api) | |
name = func.__name__ | |
aux.__name__ = name | |
aux.__doc__ = aux.__doc__.format(name.capitalize()) | |
return aux | |
@baker.command | |
@_star | |
def star(api): | |
log('Starring the gist') | |
api.put({}) | |
@baker.command | |
@_star | |
def unstar(api): | |
log('Unstarring the gist') | |
api.delete() | |
if __name__ == '__main__': | |
baker.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment