把代码上传到数据库中

# -*- coding: utf-8 -*-
import inspect
import os
import sys
from os import walk
from os.path import splitext

import click
from redis import Redis


@click.group()
def cli():
    """远程代码管理"""
    pass


def __get_path(code_path):
    for rt, dirs, files in walk(code_path):

        f_names = []
        for file in files:
            f_name, f_ext = splitext(file)
            if not f_name.startswith("_") and f_ext == '.py':
                f_names.append(f_name)

        yield rt, ".".join(rt.split(code_path).pop().split("/")[1:]), f_names


def __get_codes(code_path):
    for p, k_p, files in __get_path(code_path):
        sys.path.append(p)
        for file in files:
            __obj = __import__(file)
            for k, v in inspect.getmembers(__obj):
                if k.startswith("_"):
                    continue
                if v.__class__.__name__ in ['type']:
                    yield "{}{}.{}".format("" if not k_p else  k_p + ".", file,
                                           k), "# -*- coding: utf-8 -*-\n\n\n{}".format(
                        inspect.getsource(v))


@cli.command()
@click.option('-pp', '--prefix', default='__code__', help=u'上传代码到redis的前缀', show_default=True)
@click.option('-n', '--name', help=u'为上传的代码指定一个package名字,默认为指定路径名字', show_default=True)
@click.option('-p', '--path', default='.', help=u'代码的路径', show_default=True)
@click.option('-d', '--debug', default=True, help=u'调试输出', show_default=True)
@click.option('-r', '--redis_url', default="redis://localhost:6379/0", help=u'指定redis url', show_default=True)
@click.option('-hk', '--hook_url', help=u'更新代码后以post的方式触发钩子', show_default=True)
def up(**options):
    """上传代码到远程"""
    code_path = options['path']
    if code_path == '.':
        code_path = os.getcwd()
    else:
        code_path = os.path.join(os.getcwd(), code_path)

    name = options['name']
    if not name:
        name = code_path.split('/').pop()

    redis_url = options['redis_url']
    prefix = options['prefix']

    r = Redis.from_url(redis_url)
    change_codes = []
    for n, c in __get_codes(code_path):
        _code = r.hget("{}.{}".format(prefix, name), n)
        if _code == c:
            continue

        change_codes.append("{}#{}".format(name, n))
        r.hset("{}.{}".format(prefix, name), n, c)

    hook_url = options['hook_url']
    if change_codes and hook_url:
        import requests
        requests.post(hook_url, body={"packages": change_codes})

    debug = options['debug']
    if debug:
        print "\n\nparams:"
        click.echo("code_path: {}".format(code_path))
        click.echo("redis_url: {}".format(redis_url))
        click.echo("prefix: {}".format(prefix))
        click.echo("name: {}".format(name))
        click.echo("debug: {}".format(debug))


@cli.command()
@click.option('-pp', '--prefix', default='__code__', help=u'上传代码到redis的前缀', show_default=True)
@click.option('-n', '--name', help=u'为上传的代码指定一个package名字,默认为指定路径名字', show_default=True)
@click.option('-d', '--debug', default=True, help=u'调试输出', show_default=True)
@click.option('-r', '--redis_url', default="redis://localhost:6379/0", help=u'指定redis url', show_default=True)
@click.option('-hk', '--hook_url', help=u'以delete的方式触发钩子', show_default=True)
def rm(**options):
    """从远程删除代码"""

    redis_url = options['redis_url']
    prefix = options['prefix']
    hook_url = options['hook_url']

    r = Redis.from_url(redis_url)

    name = options['name']
    remove_names = []
    try:
        if '#' in name:
            p, n = name.split("#")
            r.hdel('{}.{}'.format(prefix, p), n)
            remove_names.append(name)
        else:
            for key in r.hkeys("{}.{}".format(prefix, name)):
                if key.startswith(name):
                    r.hdel(key)
                    remove_names.append("{}#{}".format(name, key))
    except Exception, e:
        click.echo(e.message, color="red")

    if remove_names and hook_url:
        import requests
        requests.delete(hook_url, body={"packages": remove_names})

    debug = options['debug']
    if debug:
        print "\n\nparams:"
        click.echo("redis_url: {}".format(redis_url))
        click.echo("prefix: {}".format(prefix))
        click.echo("name: {}".format(name))
        click.echo("debug: {}".format(debug))

if __name__ == '__main__':
    cli()
posted @ 2017-05-27 12:58  白云辉  阅读(321)  评论(0编辑  收藏  举报