예제 #1
0
    def test_content(self):
        responses.add(
            responses.GET,
            'https://api.github.com/gists/1',
            body=json.dumps({
                "files": {
                    "file-A.txt": {
                        "filename": "file-A.txt",
                        "content": b64encode("test-content-A"),
                    },
                    "file-B.txt": {
                        "filename": "file-B.txt",
                        "content": b64encode("test-content-\u212C"),
                    }
                },
                "description": "test-gist",
                "public": True,
                "id": 1,
            }),
            status=200,
        )

        content = gist.GistAPI(token='foo').content('1')

        self.assertEqual(len(content), 2)
        self.assertTrue('file-A.txt' in content)
        self.assertTrue('file-B.txt' in content)
        self.assertEqual(content['file-A.txt'], 'test-content-A')
        self.assertEqual(content['file-B.txt'], 'test-content-\u212C')
예제 #2
0
    def test_list(self):
        responses.add(
            responses.GET,
            'https://api.github.com/gists',
            body=json.dumps([
                {
                    'id': 1,
                    'description': 'test-desc-A',
                    'public': True,
                },
                {
                    'id': 2,
                    'description': 'test-desc-\u212C',
                    'public': False,
                },
            ]),
            status=200,
        )

        gists = gist.GistAPI(token='foo').list()

        gistA = gists[0]
        gistB = gists[1]

        self.assertEqual(gistA.id, 1)
        self.assertEqual(gistA.desc, 'test-desc-A')
        self.assertTrue(gistA.public)

        self.assertEqual(gistB.id, 2)
        self.assertEqual(gistB.desc, 'test-desc-\u212C')
        self.assertFalse(gistB.public)
예제 #3
0
    def test_create(self):
        def request_handler(request):
            data = json.loads(request.body)
            self.assertEqual(len(data['files']), 2)
            self.assertTrue('test-file-A' in data['files'])

            content = {k: v['content'] for k, v in data['files'].items()}

            self.assertEqual(content['test-file-A'], 'test-content-A')
            self.assertEqual(content['test-file-B'], 'test-content-\u212C')

            status = 200
            headers = {}
            body = json.dumps({'html_url': 'https://gist.github.com/gists/1'})
            return status, headers, body

        responses.add_callback(
            responses.POST,
            'https://api.github.com/gists',
            callback=request_handler,
            content_type='application/json',
        )

        public = True
        desc = 'test-desc'
        files = {
            'test-file-A': {
                'content': 'test-content-A'
            },
            'test-file-B': {
                'content': 'test-content-\u212C'
            },
        }

        gist.GistAPI(token='foo').create(desc, files, public)
예제 #4
0
파일: test_gist.py 프로젝트: kbenzie/gist
    def test_list_empty(self):
        responses.add(responses.GET, 'https://api.github.com/gists',
                body="",
                status=200,
                )

        gists = gist.GistAPI(token='foo').list()

        self.assertTrue(len(gists) == 0)
def main(argv=sys.argv[1:], config=None):
    args = docopt.docopt(
            __doc__,
            argv=argv,
            version='gist-v{}'.format(gist.__version__),
            )

    # Read in the configuration file
    if config is None:
        config = configparser.ConfigParser()
        config_path = os.path.expanduser('~/.gist')
        config_path = alternative_config(config_path)
        config_path = xdg_data_config(config_path)
        with open(config_path) as fp:
            config.readfp(fp)

    # Setup logging
    fmt = "%(created).3f %(levelname)s[%(name)s] %(message)s"
    logging.basicConfig(format=fmt)

    try:
        log_level = config.get('gist', 'log-level').upper()
        logging.getLogger('gist').setLevel(log_level)
    except Exception:
        logging.getLogger('gist').setLevel(logging.ERROR)

    # Determine the editor to use
    editor = None
    editor = alternative_editor(editor)
    editor = environment_editor(editor)
    editor = configuration_editor(config, editor)

    if editor is None:
        raise ValueError('Unable to find an editor.')

    token = config.get('gist', 'token')
    gapi = gist.GistAPI(token=token, editor=editor)

    if args['list']:
        logger.debug(u'action: list')
        gists = gapi.list()
        for info in gists:
            public = '+' if info.public else '-'
            desc = '' if info.desc is None else info.desc
            line = u'{} {} {}'.format(info.id, public, desc)
            try:
                print(elide(line))
            except UnicodeEncodeError:
                logger.error('unable to write gist {}'.format(info.id))
        return

    if args['info']:
        gist_id = args['<id>']
        logger.debug(u'action: info')
        logger.debug(u'action: - {}'.format(gist_id))
        info = gapi.info(gist_id)
        print(json.dumps(info, indent=2))
        return

    if args['edit']:
        gist_id = args['<id>']
        logger.debug(u'action: edit')
        logger.debug(u'action: - {}'.format(gist_id))
        gapi.edit(gist_id)
        return

    if args['description']:
        gist_id = args['<id>']
        description = args['<desc>']
        logger.debug(u'action: description')
        logger.debug(u'action: - {}'.format(gist_id))
        logger.debug(u'action: - {}'.format(description))
        gapi.description(gist_id, description)
        return

    if args['fork']:
        gist_id = args['<id>']
        logger.debug(u'action: fork')
        logger.debug(u'action: - {}'.format(gist_id))
        info = gapi.fork(gist_id)
        return

    if args['clone']:
        gist_id = args['<id>']
        gist_name = args['<name>']
        logger.debug(u'action: clone')
        logger.debug(u'action: - {} as {}'.format(gist_id, gist_name))
        gapi.clone(gist_id, gist_name)
        return

    if args['content']:
        gist_id = args['<id>']
        logger.debug(u'action: content')
        logger.debug(u'action: - {}'.format(gist_id))

        content = gapi.content(gist_id)
        gist_file = content.get(args['<filename>'])

        if args['--decrypt']:
            if not config.has_option('gist', 'gnupg-homedir'):
                raise GistError('gnupg-homedir missing from config file')

            homedir = config.get('gist', 'gnupg-homedir')
            logger.debug(u'action: - {}'.format(homedir))

            gpg = gnupg.GPG(gnupghome=homedir, use_agent=True)
            if gist_file is not None:
                print(gpg.decrypt(gist_file).data.decode('utf-8'))
            else:
                for name, lines in content.items():
                    lines = gpg.decrypt(lines).data.decode('utf-8')
                    print(u'{} (decrypted):\n{}\n'.format(name, lines))

        else:
            if gist_file is not None:
                print(gist_file)
            else:
                for name, lines in content.items():
                    print(u'{}:\n{}\n'.format(name, lines))

        return

    if args['files']:
        gist_id = args['<id>']
        logger.debug(u'action: files')
        logger.debug(u'action: - {}'.format(gist_id))
        for f in gapi.files(gist_id):
            print(f)
        return

    if args['archive']:
        gist_id = args['<id>']
        logger.debug(u'action: archive')
        logger.debug(u'action: - {}'.format(gist_id))
        gapi.archive(gist_id)
        return

    if args['delete']:
        gist_ids = args['<ids>']
        logger.debug(u'action: delete')
        for gist_id in gist_ids:
            logger.debug(u'action: - {}'.format(gist_id))
            gapi.delete(gist_id)
        return

    if args['version']:
        logger.debug(u'action: version')
        print('v{}'.format(gist.__version__))
        return

    if args['create']:
        logger.debug('action: create')

        # If encryption is selected, perform an initial check to make sure that
        # it is possible before processing any data.
        if args['--encrypt']:
            if not config.has_option('gist', 'gnupg-homedir'):
                raise GistError('gnupg-homedir missing from config file')

            if not config.has_option('gist', 'gnupg-fingerprint'):
                raise GistError('gnupg-fingerprint missing from config file')

        # Retrieve the data to add to the gist
        if sys.stdin.isatty():
            if args['FILES']:
                logger.debug('action: - reading from files')
                files = {}
                for path in args['FILES']:
                    name = os.path.basename(path)
                    with open(path, 'rb') as fp:
                        files[name] = fp.read().decode('utf-8')
            else:
                logger.debug('action: - reading from editor')
                with tempfile.NamedTemporaryFile('wb+') as fp:
                    os.system('{} {}'.format(editor, fp.name))
                    fp.flush()
                    fp.seek(0)
                    files = {'file1.txt': fp.read().decode('utf-8')}

        else:
            logger.debug('action: - reading from stdin')
            files = {'file1.txt': sys.stdin.read()}

        description = args['<desc>']
        public = args['--public']

        # Encrypt the files or leave them unmodified
        if args['--encrypt']:
            logger.debug('action: - encrypting content')

            fingerprint = config.get('gist', 'gnupg-fingerprint')
            gnupghome = config.get('gist', 'gnupg-homedir')

            gpg = gnupg.GPG(gnupghome=gnupghome, use_agent=True)
            data = {}
            for k, v in files.items():
                cypher = gpg.encrypt(v.encode('utf-8'), fingerprint)
                content = cypher.data.decode('utf-8')
                data['{}.asc'.format(k)] = {'content': content}
        else:
            data = {k: {'content': v} for k, v in files.items()}

        print(gapi.create(description, data, public))
        return