Skip to content

Instantly share code, notes, and snippets.

@Lunatrius
Last active August 29, 2015 14:16
Show Gist options
  • Save Lunatrius/9d1d8502c9e169da66f3 to your computer and use it in GitHub Desktop.
Save Lunatrius/9d1d8502c9e169da66f3 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
import os
import sys
if sys.version_info.major < 2:
reload(sys)
sys.setdefaultencoding('utf-8')
import time
import uuid
from functools import wraps
from getpass import getpass, getuser
import requests
from github3 import authorize, login, GitHubError
try:
from urlparse import urlparse
except ImportError:
# py3k
from urllib.parse import urlparse
from argparse import ArgumentParser
from argparse import FileType
def auth_check(func):
@wraps(func)
def check_wrapper(self, *args, **kwargs):
if not kwargs.get('anonymous'):
try:
with open(os.path.expanduser('~/.gist'), 'r') as tkf:
self.token = tkf.readline()
self.github = login(token=self.token)
except IOError:
raise SystemExit('Please use `gist --login` authenticate gist on this computer')
try:
return func(self, *args, **kwargs)
except GitHubError as ghe:
if ghe.code in (401, 403):
raise SystemExit('Your current gist authorize is bad, please use `gist --login` to authenticate it again!')
raise SystemExit(ghe + '\nPlease report this bug to the author!')
return check_wrapper
def token_request():
try:
prompt = raw_input
except NameError:
prompt = input
user = prompt('GitHub username (default is {0}): '.format(getuser())) or getuser()
password = ''
while not password:
password = getpass('GitHub password for {0}: '.format(user))
note = 'gist -> {0}'.format(uuid.uuid4())
note_url = 'https://github.com/Lunatrius/pgist'
scopes = ['gist']
try:
auth = authorize(user, password, scopes, note, note_url)
except GitHubError as ghe:
if 'two-factor' in str(ghe):
raise SystemExit('GitHub 2-factor auth is not supported temporarily o(>_<)o, please disable it to use gist!')
raise SystemExit('Gist authorize failed, please check your username and/or password!')
with open(os.path.expanduser('~/.gist'), 'w') as f:
f.write(auth.token)
print('Done...')
class Gist:
def __init__(self, stdin_ext='txt'):
self.token, self.github = None, None
self.stdin_ext = stdin_ext
@auth_check
def list_gists(self, _all=False):
gists = [gist for gist in self.github.gists() if _all or gist.public]
print('List of {0} gists:'.format(['public', 'all'][_all]))
for gist in gists:
print('{0}{1}'.format(gist.html_url.ljust(50), [g.name for g in gist.files()][0]))
@auth_check
def create_gist(self, description=None, files=[], public=True, anonymous=False, short_url=False):
if description is None:
description = ''
if anonymous:
from github3 import create_gist
gist = create_gist(description, self.upload_files(files))
else:
gist = self.github.create_gist(description, self.upload_files(files), public)
print(self.shorten_url(gist.html_url) if short_url else gist.html_url)
@auth_check
def update_gist(self, _id, description=None, files=[]):
if description is None:
description = ''
dest = self.find_gist_by_id(self.get_id(_id))
if dest.edit(description, self.upload_files(files)):
print('<{0}> has been updated successfully.'.format(dest.html_url))
@auth_check
def delete_gist(self, _id):
dest = self.find_gist_by_id(self.get_id(_id))
if dest.delete():
print('<{0}> has been deleted successfully.'.format(dest.html_url))
def upload_files(self, files):
_files = {}
for obj in files:
content = obj.readlines()
if not content:
continue
name = obj.name.split('/')[-1]
if name == '<stdin>':
name = 'stdin-{0}.{1}'.format(time.strftime('%Y%m%d-%H%M%S'), self.stdin_ext)
_files[name] = {'content': ''.join(content)}
if not _files:
raise SystemExit('All of your files are empty.')
return _files
def find_gist_by_id(self, _id):
dest = None
for gist in self.github.gists():
if _id == gist.id or _id == gist.html_url:
dest = gist
break
if dest is None:
raise SystemExit('The gist ID/URL was not found.')
return dest
def get_id(self, _id):
result = urlparse(_id)
if result.path:
return result.path.split('/')[-1]
raise SystemExit('Your url/id <{0}> is invalid!'.format(_id))
def shorten_url(self, long_url):
req = requests.post('http://git.io', data={'url': long_url})
return req.headers['location']
def cli():
parser = ArgumentParser()
parser.add_argument('--login', action='store_true',
help='authenticate gist on this computer')
parser.add_argument('--shorten', '-s', action='store_true',
help='shorten the gist URL using git.io')
parser.add_argument('--list', '-l', action='store_true',
help='lists public gists')
parser.add_argument('--all', '-A', action='store_true',
help='lists all gists')
parser.add_argument('--public', '-p', action='store_true',
help='makes your gist public')
parser.add_argument('--anonymous', '-a', action='store_true',
help='create an anonymous gist')
parser.add_argument('--update', '-u', metavar='ID/URL', type=str,
help='update an existing gist')
parser.add_argument('--delete', '-D', metavar='ID/URL', type=str,
help='delete an existing gist')
parser.add_argument('--desc', '-d', metavar='DESCRIPTION', type=str,
help='update an existing gist')
parser.add_argument('--ext', '-e', metavar='EXT', type=str, default='txt',
help='file extension for stdin')
parser.add_argument('infile', nargs='*', type=FileType('r', encoding='utf-8'),
default=[sys.stdin])
args = parser.parse_args()
gist = Gist(args.ext)
if args.login:
token_request()
elif args.list:
gist.list_gists(args.all)
elif args.update:
gist.update_gist(args.update, description=args.desc, files=args.infile)
elif args.delete:
gist.delete_gist(args.delete)
else:
gist.create_gist(description=args.desc, files=args.infile, public=args.public, anonymous=args.anonymous, short_url=args.shorten)
if __name__ == '__main__':
cli()
#!/usr/bin/env python
import os
from setuptools import setup
# README = open(os.path.join(os.path.dirname(__file__), 'README.rst')).read()
# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
setup(
name='gist',
version='0.1',
# license=open('LICENSE').read(),
description='A Python command-line wrapper with github3.py library to access GitHub Gist',
# long_description=README,
author='Lunatrius',
author_email='lunatrius@gmail.com',
# url='https://github.com/Lunatrius/gist',
py_modules=['gist'],
# package_data={'': ['LICENSE',]},
install_requires=['github3.py >= 0.7.1'],
entry_points='''
[console_scripts]
gist=gist:cli
''',
# zip_safe=False,
classifiers=(
'Intended Audience :: Developers',
'Natural Language :: English',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
),
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment