Beispiel #1
0
 def _get():
     if id:
         logger.info(f"Query release: {id}")
         logger.info(f"Owner:\t{owner}")
         logger.info(f"Repo:\t{repo}")
         logger.info("Waiting...")
         code, data = r.get_release(owner, repo, id)
         if code != 200:
             utils.print_failed()
             logger.error(repo.get("message"))
             ctx.exit()
         data.pop('author')
         utils.print_dict(data)
     else:
         logger.info("Query releases")
         logger.info(f"Owner:\t{owner}")
         logger.info(f"Repo:\t{repo}")
         logger.info("Waiting...")
         code, data = r.get_releases(owner, repo)
         if code != 200:
             utils.print_failed()
             logger.error(repo.get("message"))
             ctx.exit()
         utils.print_list(data, *['id', 'name', 'tag_name'])
         logger.info('Now you can see the detail with command:')
         logger.info('\t\tgoss-cli release <id>')
     utils.print_success()
     ctx.exit()
Beispiel #2
0
def login(ctx, user, password, yes):
    g = ctx.obj
    confirm = utils.make_error_msg('The login information already exists. Do you want to replace it?')
    if not yes:
        # 判断已经登录过,是否替换登录信息
        if g and not click.confirm(confirm):
            return
    conf = configparser.ConfigParser()
    conf['default'] = dict(user = user, password = password)

    g = Github(user, password)
    code, data = g.get_user_info()
    if code != 200:
        utils.print_failed()
        logger.error('用户名或密码错误')
        return

    owner = data.get("name")
    conf['default']['owner'] = owner
    with open(GOSS_CREDENTIAL_PATH, 'w') as f:
        conf.write(f)
    with open(GOSS_USER_INFO_PATH, 'w') as f:
        f.write(json.dumps(data, indent = 4))
        f.flush()
        f.close()

    conf_data = dict(name = owner)
    email = data.get("email")
    if email:
        conf_data['email'] = email

    utils.config(GOSS_CONFIG_PATH, 'user', **conf_data)

    utils.print_success()
    logger.info('Name  :', owner)
    logger.info('Email :', email)
Beispiel #3
0
def config(ctx, name, value):
    '''
    Get/Create/Update goss config

    goss-cli config                  :  Show config

    goss-cli config user.name wxnacy :  Create/Update config value
    '''
    if name and value and '.' in name:
        names = name.split('.')
        section = names[0]
        key = names[1]
        utils.config(GOSS_CONFIG_PATH, section, **{key: value})
        utils.print_success()
        return

    conf = configparser.ConfigParser()
    conf.read(GOSS_CONFIG_PATH)
    secs = conf.sections()
    for sec in secs:
        click.echo('[{}]'.format(sec))
        kv = conf[sec]
        for k, v in kv.items():
            click.echo('    {} = {}'.format(k, v))
Beispiel #4
0
def create(g, filepath, path=None, repo=None, yes=False, **kw):
    '''
    创建文件
    '''
    r = g.get_release()
    #  print(g._user)
    owner = g.owner
    if kw.get("config"):
        g.config.read(kw['config'])
    if not path:
        path = g.config.repo.path

    if not path:
        path = os.path.basename(filepath)

    if path.endswith('/'):
        path += os.path.basename(filepath)

    if not repo:
        repo = g.config.repo.name

    def _upload_asset():
        '''上传 release 的资产'''
        name = kw.get("name")
        if not name:
            name = os.path.basename(filepath)
        logger.info('Upload asset')
        logger.info('Release\t:', release)
        logger.info('Source\t:', filepath)
        #  logger.info('Path\t:', path)
        download_url = f'https://github.com/{owner}/{repo}/releases/download/{release}/{name}'
        html_url = f'https://github.com/{owner}/{repo}/blob/master/{path}'
        #  logger.info('HtmlUrl\t:', html_url)
        logger.info('DownUrl\t:', click.style(download_url, fg='blue'))
        pyperclip.copy(download_url)
        logger.info(
            'Now you can use it with {} and wait for the upload to succeed.'.
            format(click.style('<CTRL-V>', fg='blue')))
        logger.info('Waiting...')
        code, data = r.get_release_by_tag(owner, repo, release)
        if code == 404:
            utils.print_failed()
            logger.error('Release not found', with_color=True)
            sys.exit(0)

        release_id = data.get("id")

        code, data = r.upload_asset_from_path(owner, repo, release_id,
                                              filepath, name)
        if code != 201:
            utils.print_failed()
            utils.print_error(data['message'])
            for err in data.get('errors', []):
                utils.print_error(f"\t- {err['field']} {err['code']}")
            sys.exit(0)

    release = kw.get('release')
    if release:
        _upload_asset()
    else:
        upload_file(g, owner, repo, filepath, path, yes)
    utils.print_success()
Beispiel #5
0
def repo(g, ctx, name, orga, method):
    '''
    Get/Create your repositorys
    '''

    if name and '/' in name:
        orga = name.split('/')[0]
        name = name.split('/')[1]

    owner = orga if orga else g.owner

    method = method.lower()
    if method == 'get':     # 处理 get 请求
        if name:            # 获取单个 repository
            logger.info('Query repository {}/{}'.format(owner, name))
            logger.info('Waiting...')
            code, repo = g.get_repository(owner, name)
            if code != 200:
                utils.print_failed()
                logger.error(repo.get("message"))
                ctx.exit()
            utils.print_dict(repo, ['owner'])
            utils.print_success()
            ctx.exit()

        # 获取全部 repositorys
        logger.info('Query your repositorys.')
        logger.info('Waiting...')
        code, repos = g.get_owner_repositorys()
        if code != 200:
            utils.print_failed()
            logger.error(repo.get("message"))
            ctx.exit()
        utils.print_list(repos, *['id', 'name', 'full_name', 'url'])
        utils.print_success()
        ctx.exit()
    elif method == 'post':
        logger.info("Create repository")
        logger.info("Url : https://github.com/{}/{}".format(owner, name))
        logger.info('Waiting...')
        code, data = g.create_repository(name)
        if code != 201:
            utils.print_failed()
            logger.error(data.get("message"))
        logger.info("Create README.md")
        logger.info("Url : https://github.com/{}/{}/blob/master/README.md".format(owner, name))
        logger.info('Waiting...')
        code, data = g.create_file_from_url(owner, name,
            'https://raw.githubusercontent.com/wxnacy/goss/master/create_readme.md',
            'README.md')
        if code != 201:
            utils.print_failed()
            logger.error(data.get("message"))
        utils.print_success()

    elif method == 'delete':
        logger.info("Delete repository")
        logger.info("Url : https://github.com/{}/{}".format(owner, name))
        logger.info('Waiting...')
        code, data = g.delete_repository(owner, name)
        if code == 204:
            utils.print_success()
        else:
            utils.print_failed()
            logger.error(data.get("message"))
Beispiel #6
0
def file(g, ctx, repo, path, orga, method, download, output, yes):
    '''
    Get/Delete/Download your file

    If you want to upload file. Please use command

        goss <filepath> --repo=<repository-name>

    More usage see : goss --help
    '''

    owner = orga if orga else g.owner
    repo = repo if repo else g.config.repo.name

    #  def _get_progress(progress, total):
        #  '''打印进度条'''
        #  progress_ratio = progress / total
        #  progress_len = 20
        #  progress_num = int(progress_ratio * 20)
        #  pro_text = '[{:-<20s}] {:.2f}% {} / {}'.format(
            #  '=' * progress_num, progress_ratio * 100, progress, total)
        #  return pro_text

    #  def _save(p, filepath, content):
        #  '''保存文件'''
        #  byte_data = base64.b64decode(content.encode())
        #  _save_by_bytes(p, filepath, byte_data)

    #  def _save_by_bytes(p, filepath, byte_data):
        #  '''保存文件'''
        #  filedir = os.path.dirname(filepath)
        #  filename = os.path.dirname(filepath)
        #  with open(name, 'wb') as f:
            #  total = len(byte_data)
            #  progress = 0
            #  step = 10
            #  while progress < total:
                #  b = progress
                #  e = b + step
                #  f.write(byte_data[b:e])
                #  progress += step
                #  end = '\r'
                #  if progress >= total:
                    #  end = '\n'
                    #  progress = total
                #  print(p, _get_progress(progress, total), end = end)
            #  f.flush()
            #  f.close()

    #  if download:
        #  logger.info('Download file')
        #  logger.info('Owner\t: {}'.format(owner))
        #  logger.info('Repo\t: {}'.format(repo))
        #  logger.info('Path\t: {}'.format(path))
        #  logger.info('Waiting...')
        #  code, data = g.get_file(owner, repo, path)
        #  if code == 403:         # 文件太大,需要使用其它方式进行下载
            #  logger.warn('The file is larger than 1 MB and needs to be downloaded using the download_url.')
            #  path_dir = os.path.dirname(path)
            #  if not path_dir:
                #  path_dir = '/'
            #  c, files = g.get_file(owner, repo, path_dir)
            #  down_url = ''
            #  file_name = []
            #  for f in files:
                #  if f['path'] == path:
                    #  down_url = f['download_url']
                    #  file_name = f['name']
            #  file_res = requests.get(down_url)

            #  name = output or file_name
            #  _save_by_bytes(path, name, file_res.content)
            #  utils.print_success()
            #  ctx.exit()

        #  if code != 200:         # 其他错误直接返回
            #  utils.print_failed()
            #  logger.error(data.get("message"))
            #  ctx.exit()
        #  type = data.get("type")
        #  name = output or data.get("name")
        #  if isinstance(data, dict):
            #  content = data.get("content")
            #  _save(path, name, content)
        #  elif isinstance(data, list):
            #  pass
        #  utils.print_success()
        #  ctx.exit()

    def _print_file_list(lines):
        '''打印文件列表信息'''
        max_size_len = 0
        max_path_len = 0
        for l in lines:
            max_size_len = max(max_size_len, len(str(l['size'])))
            l['path'] = reprlib.repr(l['path'].replace(path, '').replace('/',
                '')).strip('\'')
            max_path_len = max(max_path_len, utils.charlen(l['path']))
        title = 'Title\t{}\t{}\tDownloadUrl'.format('Size'.ljust(max_size_len),
            'Path'.ljust(max_path_len))
        hor_len = len(title) + 50
        hor_line = click.style('-' * hor_len, fg='yellow')
        click.secho(title, fg='magenta')
        click.secho(hor_line)
        for l in lines:
            size = str(l['size']).ljust(max_size_len)
            l['size'] = size
            l['path'] = utils.charljust(l['path'], max_path_len)
            #  l['path'] = l['path'].ljust(max_path_len, '*')
            line = '{type}\t{size}\t{path}\t{download_url}'.format(**l)
            click.echo(line)
        click.secho(hor_line)
        total = click.style(str(len(data)), fg='cyan')
        click.secho(f'Total : {total}')
        click.echo('')

    def fmt_list(data):
        for l in data:
            l['path'] = reprlib.repr(l['path'].replace(path, '').replace('/',
                '')).strip('\'')

    def print_data(data):
        '''打印文件信息'''
        if isinstance(data, list):      # 打印列表
            #  _print_file_list(data)
            fmt_list(data)
            utils.print_list(data, 'type', 'size', 'path', 'download_url')
        elif isinstance(data, dict):    # 打印单个文件
            utils.print_dict(data, exclude=['_links', 'content'])
            try:
                pyperclip.copy(data['download_url'])
            except:
                pass
            logger.info('Now you can use download_url with {}.'.format(
                click.style('<CTRL-V>', fg='blue')
            ))

    def _del_file(path, sha):
        '''删除单个文件'''
        code, data = g.delete_file(owner, repo, path, sha)
        if code != 200:
            utils.print_failed()
            logger.error(path, filedata.get("message"))
            ctx.exit()
        logger.info(path, 'deleted')

    method = method.lower()
    if method == 'get':     # 处理 get 请求
        logger.info('Query file')
        logger.info('Owner\t: {}'.format(owner))
        logger.info('Repo\t: {}'.format(repo))
        logger.info('Path\t: {}'.format(path))
        logger.info('Waiting...')
        code, data = g.get_file(owner, repo, path)
        if code == 200:
            print_data(data)
            utils.print_success()
        else:
            utils.print_failed()
            logger.error(data.get("message"))
    elif method == 'delete':
        logger.info('Delete file')
        logger.info('Owner\t: {}'.format(owner))
        logger.info('Repo\t: {}'.format(repo))
        logger.info('Path\t: {}'.format(path))
        logger.info('Waiting...')
        code, filedata = g.get_file(owner, repo, path)
        if code != 200:
            utils.print_failed()
            logger.error(filedata.get("message"))
            ctx.exit()

        if isinstance(filedata, list):      # 删除文件夹

            if not yes:                     # 确认是否删除
                if not click.confirm('The {} is a folder, are you sure to delete?'.format(path)):
                    ctx.exit()
            else:
                logger.warn('The {} is a folder and is now being deleted'.format(path),
                        with_color=True)

            for f in filedata:
                _del_file(f['path'], f['sha'])

        elif isinstance(filedata, dict):    # 删除文件
            sha = filedata.get("sha")
            _del_file(path, sha)

        utils.print_success()