diff --git a/.gitignore b/.gitignore index 3da785e80..c8f3ae875 100644 --- a/.gitignore +++ b/.gitignore @@ -358,3 +358,13 @@ tencentScf/.env # vs code .vscode + +# krew +krew/bilipro +krew/cmd/kubectl-bilipro +krew/kustomization.yaml +bilipro +kustomization.yaml + +# cookie config +cookies.json \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index fce9a6529..3b5b367b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,5 +63,10 @@ - 合并PR(#309)新增lv6后开启白嫖模式的配置(多账号时可以实现不足lv6的继续投币,达到lv6的开始白嫖),感谢@cluom - 优化青龙安装dotnet的脚本,改为使用官方`dotnet-install.sh`脚本安装(之前测试网络不通,后发现--no-cdn可以) - 优化青龙的执行脚本,提取公共部分,并且在执行前会尝试安装一次dotnet,会清理一次缓存 -## 0.2.3 +## 0.3.0 - hotfix docker build error +- 合并PR(#341),新增krew部署,感谢@chenliu1993 +- 合并PR(##348),更新文档,感谢@jexjws +- 合并PR(#350),修改请求header错误的bug +- 合并PR(#353),新增python扫码登录的feature(仅针对青龙),感谢@AFUL1991 +- Feature(#351):重构并新增了扫码登录功能,使之适用于各种部署平台 diff --git a/README.md b/README.md index 3cb5d732f..3457bb5cf 100644 --- a/README.md +++ b/README.md @@ -40,15 +40,14 @@ BiliBiliTool - [1. 如何使用](#1-如何使用) - - [1.1. 第一步:获取BiliBili的 Cookie](#11-第一步获取bilibili的-cookie) - - [1.2. 第二步:配置 Cookie 并运行 BiliBiliTool](#12-第二步配置-cookie-并运行-bilibilitool) - - [1.2.1. 方式一:青龙运行(推荐)](#121-方式一青龙运行推荐) - - [1.2.2. 方式二:Docker或Podman容器化运行](#122-方式二docker或podman容器化运行) - - [1.2.3. 方式三:下载程序包到本地或服务器运行](#123-方式三下载程序包到本地或服务器运行) - - [1.2.4. 方式四:腾讯云函数SCF](#124-方式四腾讯云函数scf) - - [1.2.5. 方式五:~~GitHub Actions~~](#125-方式五github-actions) - - [1.2.6. 方式六:Chart部署](#126-方式六chart部署) - - [1.3. 消息推动(可选)](#13-消息推动可选) + - [1.1. 部署 BiliBiliTool](#11-部署-bilibilitool) + - [1.1.1. 方式一:青龙(推荐)](#111-方式一青龙推荐) + - [1.1.2. 方式二:Docker或Podman容器化运行](#112-方式二docker或podman容器化运行) + - [1.1.3. 方式三:下载程序包到本地或服务器运行](#113-方式三下载程序包到本地或服务器运行) + - [1.1.4. 方式四:腾讯云函数SCF](#114-方式四腾讯云函数scf) + - [1.1.5. 方式五:~~GitHub Actions~~](#115-方式五github-actions) + - [1.1.6. 方式六:Chart部署](#116-方式六chart部署) + - [1.2. 消息推送(可选)](#12-消息推送可选) - [2. 功能任务说明](#2-功能任务说明) - [3. 个性化自定义配置](#3-个性化自定义配置) - [4. 多账号支持](#4-多账号支持) @@ -82,105 +81,44 @@ _(如果图片挂了,请自己架梯子,没有的也可以先参考 [我 BiliBiliTool 实现自动完成任务的原理,是通过调用一系列开放的api实现的。 -**要使用 BiliBiliTool,我们只需要做两步:获取自己的 Cookie 作为配置,然后将其输入 BiliBiliTool 并运行即可。** +**要使用 BiliBiliTool,很简单,按照下面教程部署完成,运行后扫码登录即可。** -### 1.1. 第一步:获取BiliBili的 Cookie +### 1.1. 部署 BiliBiliTool -- 浏览器打开并登录 [BiliBili 网站](https://www.bilibili.com/) -- 登录成功后,访问 `https://api.bilibili.com/x/web-interface/nav`,按 **F12** 打开"开发者工具",按 **F5** 刷新一下 -- 在"开发者工具"面板中,点击 **网络(Network)**,在左侧的请求列表中,找到名称为 `nav` 的接口,点击它 -- 依次查找 **Headers** ——> **RequestHeader** ——> **cookie**,可以看到很长一串以英文分号分隔的字符串,复制整个这个cookie字符串(不要使用右键复制,请使用 Ctrl+C 复制,部分浏览器右键可能会进行 UrlDecode ),保存它们到记事本,待会儿会用到。 +支持多种部署方式,以下选择任一适合自己的方式即可。 -![获取Cookie图示](docs/imgs/get-bilibili-web-cookie.jpg) - - -### 1.2. 第二步:配置 Cookie 并运行 BiliBiliTool - -#### 1.2.1. 方式一:青龙运行(推荐) +#### 1.1.1. 方式一:青龙(推荐) [>>青龙部署教程](qinglong/README.md) -#### 1.2.2. 方式二:Docker或Podman容器化运行 +#### 1.1.2. 方式二:Docker或Podman容器化运行 [>>Docker部署说明](docker/README.md) [>>Podman部署说明](podman/README.md) -#### 1.2.3. 方式三:下载程序包到本地或服务器运行 - -如果是 DotNet 开发者,直接 Clone 源码,然后 VS 打开解决方案,配置 Cookie 后即可直接本地进行运行和调试。 - -对于不是开发者的朋友,可以通过下载 Release 包到本地或任意服务器运行,步骤如下。 -
- -Ⅰ. **下载应用文件** - -点击 [BiliBiliTool/release](https://github.com/RayWangQvQ/BiliBiliToolPro/releases),下载已发布的最新版本。 - -* 如果本地已安装 `.NET 6.0` 环境: - -请下载 `net-dependent.zip` 文件,本文件依赖本地运行库(runtime-dependent),所以文件包非常小(不到1M)。 - -P.S.这里的运行环境指的是 `.NET Runtime 6.0.0` ,安装方法可详见 [常见问题](docs/questions.md) 中的 **本地或服务器如何安装.net环境** - -* 如果不希望安装或不知如何安装.net运行环境: - -请根据操作系统下载对应的 zip 文件,此文件已自包含(self-contained)运行环境,但相较不包含运行时的文件略大(20M 左右,Github 服务器在国外,下载可能比较慢)。 - -如,Windows系统请下载 `win-x86-x64.zip` ,其他以此类推。 - - -Ⅱ. **解压并填写配置** - -下载并解压后,找到 appsettings.json 文件,使用记事本编辑,将之前获取到的 Cookie 字符串填入指定位置,保存后关闭: - -![配置文件图示](docs/imgs/appsettings-cookie.png) - -Ⅲ. **运行** - -* Windows 系统 - -对于已安装.net环境,且使用的是依赖包,可在当前目录下执行命令:`dotnet Ray.BiliBiliTool.Console.dll`,或者直接双击运行名称为 start.bat 的批处理文件,均可运行。 - -对于使用自包含运行环境版本的,可直接双击运行名称为 Ray.BiliBiliTool.Console.exe 的可执行文件。 - -* Linux 系统 - -对于已安装.net环境,且使用的是依赖包,同上,可在终端中执行命令:`dotnet Ray.BiliBiliTool.Console.dll` - -对于使用独立包的,可在终端中执行命令: - -``` -chmod +x ./Ray.BiliBiliTool.Console -Ray.BiliBiliTool.Console -``` - -其他系统依此类推,运行结果图示如下: - -![运行图示](docs/imgs/run-exe.png) - -除了修改配置文件,也可以通过添加环境变量或在启动命令后附加参数来实现配置,详细方法可参考下面的**配置说明**章节。 +#### 1.1.3. 方式三:下载程序包到本地或服务器运行 -
+[>>本地部署说明](docs/runInLocal.md) -#### 1.2.4. 方式四:腾讯云函数SCF +#### 1.1.4. 方式四:腾讯云函数SCF 当前腾讯云函数已改为收费模式,不推荐。 [>>腾讯云函数部署说明](tencentScf/README.md) -#### 1.2.5. 方式五:~~GitHub Actions~~ +#### 1.1.5. 方式五:~~GitHub Actions~~ 暂时删掉该方式避避风头。 **建议所有使用该方式运行的朋友,暂时先替换其他运行方式,避免造成不必要的损失。** -#### 1.2.6. 方式六:Chart部署 +#### 1.1.6. 方式六:Chart部署 [>>Chart部署说明](helm/README.md) -### 1.3. 消息推动(可选) +### 1.2. 消息推送(可选) 如果配置了推送,执行成功后,指定的接收端会收到推送消息,推送效果如下所示: diff --git a/common.props b/common.props index 8180db785..1ac4a8905 100644 --- a/common.props +++ b/common.props @@ -1,7 +1,7 @@ Ray - 0.2.3 + 0.3.0 $(NoWarn);CS1591;CS0436 diff --git a/docker/README.md b/docker/README.md index 120cc892a..140c2805c 100644 --- a/docker/README.md +++ b/docker/README.md @@ -6,14 +6,14 @@ - [1.2. 须知](#12-须知) - [2. 方式一:Docker Compose(推荐)](#2-方式一docker-compose推荐) - [2.1. 启动](#21-启动) - - [2.2. 修改bili下的docker-compose.yml,填入cookie](#22-修改bili下的docker-composeyml填入cookie) - - [2.3. 其他命令参考](#23-其他命令参考) + - [2.2. 其他命令参考](#22-其他命令参考) - [3. 方式二:Docker指令](#3-方式二docker指令) - [3.1. Docker启动](#31-docker启动) - [3.2. 其他指令参考](#32-其他指令参考) - [3.3. 使用Watchtower更新容器](#33-使用watchtower更新容器) -- [4. 自己构建镜像(非必须)](#4-自己构建镜像非必须) -- [5. 其他](#5-其他) +- [4. 登录](#4-登录) +- [5. 自己构建镜像(非必须)](#5-自己构建镜像非必须) +- [6. 其他](#6-其他) ## 1. 前期工作 @@ -52,6 +52,7 @@ docker pull zai7lou/bilibili_tool_pro # 下载 wget https://raw.githubusercontent.com/RayWangQvQ/BiliBiliToolPro/main/src/Ray.BiliBiliTool.Console/appsettings.json +wget https://raw.githubusercontent.com/RayWangQvQ/BiliBiliToolPro/main/docker/sample/cookies.json wget https://raw.githubusercontent.com/RayWangQvQ/BiliBiliToolPro/main/docker/sample/docker-compose.yml # 启动 @@ -61,21 +62,16 @@ docker compose up -d docker logs -f bili ``` -### 2.2. 修改bili下的docker-compose.yml,填入cookie - -根据 docker-compose.yaml 里面的注释编辑所需配置,`environment` 下可以通过环境变量自由添加自定义配置,其中Cookie是必填的,所以请至少填入Cookie并保存。 - -保存后,重新运行下`docker compose up -d` - 最终文件结构如下: ``` bili ├── appsettings.json +├── cookies.json └── docker-compose.yml ``` -### 2.3. 其他命令参考 +### 2.2. 其他命令参考 ``` # 启动 docker-compose @@ -103,7 +99,6 @@ docker compose pull && docker compose up -d docker pull zai7lou/bilibili_tool_pro docker run -d --name="bili" \ -v /bili/Logs:/app/Logs \ - -e Ray_BiliBiliCookies__1="cookie" \ -e Ray_DailyTaskConfig__Cron="0 15 * * *" \ -e Ray_LiveLotteryTaskConfig__Cron="0 22 * * *" \ -e Ray_UnfollowBatchedTaskConfig__Cron="0 6 1 * *" \ @@ -125,6 +120,9 @@ docker start bili # 停止容器 docker stop bili +# 重启容器 +docker restart bili + # 删除容器 docker rm bili @@ -141,7 +139,15 @@ docker run --rm \ bili ``` -## 4. 自己构建镜像(非必须) +## 4. 登录 + +在宿主机运行`docker exec -it bili bash -c "dotnet Ray.BiliBiliTool.Console.dll --runTasks=Login"` + +扫码进行登录。 + +![login](../docs/imgs/docker-login.png) + +## 5. 自己构建镜像(非必须) 目前我提供和维护的镜像:`[zai7lou/bilibili_tool_pro](https://hub.docker.com/repository/docker/zai7lou/bilibili_tool_pro)`; @@ -153,7 +159,7 @@ docker run --rm \ `TARGET_NAME`为镜像名称和版本,可以自己起个名字 -## 5. 其他 +## 6. 其他 代码编译和发布环境: mcr.microsoft.com/dotnet/sdk:6.0 diff --git a/docker/sample/docker-compose.yml b/docker/sample/docker-compose.yml index e87fd75f8..bca5efa0e 100644 --- a/docker/sample/docker-compose.yml +++ b/docker/sample/docker-compose.yml @@ -8,15 +8,12 @@ services: volumes: - ./Logs:/app/Logs - ./appsettings.json:/app/appsettings.json + - ./cookies.json:/app/cookies.json tty: true environment: - ASPNETCORE_ENVIRONMENT=Production - Ray_Security__IsSkipDailyTask=false - # Cookie字符串(必填): - - Ray_BiliBiliCookies__1= - - Ray_BiliBiliCookies__2= - # 定时任务 - Ray_DailyTaskConfig__Cron=0 15 * * * - Ray_LiveLotteryTaskConfig__Cron=0 22 * * * diff --git a/docs/imgs/docker-login.png b/docs/imgs/docker-login.png new file mode 100644 index 000000000..07d4d1f38 Binary files /dev/null and b/docs/imgs/docker-login.png differ diff --git a/docs/imgs/qinglong-login.png b/docs/imgs/qinglong-login.png new file mode 100644 index 000000000..c20d25376 Binary files /dev/null and b/docs/imgs/qinglong-login.png differ diff --git a/docs/runInLocal.md b/docs/runInLocal.md new file mode 100644 index 000000000..74d56533a --- /dev/null +++ b/docs/runInLocal.md @@ -0,0 +1,58 @@ +# 下载程序包到本地或服务器运行 + + + +- [1. 下载应用文件](#1-下载应用文件) +- [2. 运行](#2-运行) + + + +如果是 DotNet 开发者,直接 Clone 源码,然后 VS 打开解决方案,配置 Cookie 后即可直接本地进行运行和调试。 + +对于不是开发者的朋友,可以通过下载 Release 包到本地或任意服务器运行,步骤如下。 +
+ +## 1. 下载应用文件 + +点击 [BiliBiliTool/release](https://github.com/RayWangQvQ/BiliBiliToolPro/releases),下载已发布的最新版本。 + +* 如果本地已安装 `.NET 6.0` 环境: + +请下载 `net-dependent.zip` 文件,本文件依赖本地运行库(runtime-dependent),所以文件包非常小(不到1M)。 + +P.S.这里的运行环境指的是 `.NET Runtime 6.0.0` ,安装方法可详见 [常见问题](docs/questions.md) 中的 **本地或服务器如何安装.net环境** + +* 如果不希望安装或不知如何安装.net运行环境: + +请根据操作系统下载对应的 zip 文件,此文件已自包含(self-contained)运行环境,但相较不包含运行时的文件略大(20M 左右,Github 服务器在国外,下载可能比较慢)。 + +如,Windows系统请下载 `win-x86-x64.zip` ,其他以此类推。 + +## 2. 运行 + +下载并解压zip文件。 + +* Windows 系统 + +对于已安装.net环境,且使用的是依赖包,可在当前目录下执行命令:`dotnet Ray.BiliBiliTool.Console.dll --runTasks=Login`,或者直接双击运行名称为 start.bat 的批处理文件,均可运行。 + +对于使用自包含运行环境版本的,可直接双击运行名称为 Ray.BiliBiliTool.Console.exe 的可执行文件。 + +* Linux 系统 + +对于已安装.net环境,且使用的是依赖包,同上,可在终端中执行命令:`dotnet Ray.BiliBiliTool.Console.dll --runTasks=Login` + +对于使用独立包的,可在终端中执行命令: + +``` +chmod +x ./Ray.BiliBiliTool.Console +Ray.BiliBiliTool.Console +``` + +其他系统依此类推,运行结果图示如下: + +![运行图示](docs/imgs/run-exe.png) + +除了修改配置文件,也可以通过添加环境变量或在启动命令后附加参数来实现配置,详细方法可参考下面的**配置说明**章节。 + +
diff --git a/krew/Makefile b/krew/Makefile new file mode 100644 index 000000000..bd1bf7be1 --- /dev/null +++ b/krew/Makefile @@ -0,0 +1,34 @@ +.DEFAULT_GOAL:=help +SHELL := /usr/bin/env bash + +ROOT_DIR := $(shell git rev-parse --show-toplevel) +GOOS ?= $(shell go env GOOS) +GOARCH ?= $(shell go env GOARCH) +BIN_NAME ?= kubectl-bilipro +KUBECTL_DIR ?= $(shell which kubectl | awk -F 'kubectl' '{printf "%s\n", $$1 }') + + + +GITCOMMIT ?= `git rev-parse HEAD` + +help: #### display help + @awk 'BEGIN {FS = ":.*## "; printf "\nTargets:\n"} /^[a-zA-Z_-]+:.*?#### / { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + @awk 'BEGIN {FS = ":.* ## "; printf "\n \033[1;32mBuild targets\033[36m\033[0m\n \033[0;37mTargets for building and/or installing CLI plugins on the system.\n Append \"ENVS=\" to the end of these targets to limit the binaries built.\n e.g.: make build-all-tanzu-cli-plugins ENVS=linux-amd64 \n List available at https://github.com/golang/go/blob/master/src/go/build/syslist.go\033[36m\033[0m\n\n"} /^[a-zA-Z_-]+:.*? ## / { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) +##### GLOBAL + +.PHONY: deploy +deploy: build install #### build + install + + +.PHONY: build +build: #### build the plugin + @go vet ./... && \ + go fmt ./... && \ + cd ${ROOT_DIR}/krew/cmd && \ + GOOS=${GOOS} GOARCH=${GOARCH} CGO_ENABLED=0 go build -ldflags "-X github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/cmd.Version=${GITCOMMIT}" -o $(BIN_NAME) kubectl-bilipro.go + + +.PHONY: install +install: #### install the plugin + @cd ${ROOT_DIR}/krew/cmd && \ + sudo install ./$(BIN_NAME) ${KUBECTL_DIR}/$(BIN_NAME) \ No newline at end of file diff --git a/krew/README.md b/krew/README.md new file mode 100644 index 000000000..af6acd696 --- /dev/null +++ b/krew/README.md @@ -0,0 +1,68 @@ +# BiliBiliPro Kubectl Plugin + +## Prerequisites + +- Kubernetes >= v1.23.0. +- go >= v1.18 +- kubectl installed on your local machine, configured to an existing healthy Kubernetes cluster. +- [krew](https://krew.sigs.k8s.io/docs/user-guide/setup/install/) plugin installed + +## Install Plugin + +Command: `cd ./krew && make deploy` +The binary will be generated in cmd/ install it alonside the kubectl binary. + +For example: the kubectl is installed under `/usr/bin`, then put the bilibilipro plugin under `/usr/bin` too. + +## Plugin Commands + +### Deployment && Update + +Command: `kubectl bilipro init --config config.yaml` + +Creates Deployment with the needed environments. + + +Optional Options: + +- `--image=zai7lou/bilibili_tool_pro:0.2.1` +- `--namespace=bilipro` +- `--image-pull-secret=` + +Required Options: + +- `--config=` + +The content of is a yaml array, please refer to the example config yaml under the krew directory. + +For example +````yaml +- name: Ray_BiliBiliCookies__2 + value: "cookie" + # DailyTrigger - required +- name: Ray_DailyTaskConfig__Cron + value: "11 11 * * *" +```` + + +Suggestions: Deploy this workload in namespace other than default or kube-* namespace, because the delete logic should be improved + + +### Deletion + +Command: `kubectl bilipro delete [options]` + +Deletes Deployment. +v +Optional Options: + +- `--namespace=` +- `--name=` + +### Version + +Command: `kubectl bilipro version` + +Output the plugin version. + + diff --git a/krew/cmd/kubectl-bilipro.go b/krew/cmd/kubectl-bilipro.go new file mode 100644 index 000000000..8132bd0ec --- /dev/null +++ b/krew/cmd/kubectl-bilipro.go @@ -0,0 +1,20 @@ +package main + +import ( + "os" + + "github.com/spf13/pflag" + + "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/cmd" + "k8s.io/cli-runtime/pkg/genericclioptions" +) + +func main() { + flags := pflag.NewFlagSet("kubectl-bilipro", pflag.ExitOnError) + pflag.CommandLine = flags + + cmd := cmd.NewExecutor(genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}) + if err := cmd.Execute(); err != nil { + os.Exit(1) + } +} diff --git a/krew/config.yaml b/krew/config.yaml new file mode 100644 index 000000000..d19b59a8a --- /dev/null +++ b/krew/config.yaml @@ -0,0 +1,5 @@ +- name: Ray_BiliBiliCookies__2 + value: "cookie" + # DailyTrigger - required +- name: Ray_DailyTaskConfig__Cron + value: "11 11 * * *" \ No newline at end of file diff --git a/krew/go.mod b/krew/go.mod new file mode 100644 index 000000000..cf9f7d3fe --- /dev/null +++ b/krew/go.mod @@ -0,0 +1,68 @@ +module github.com/RayWangQvQ/BiliBiliToolPro/krew + +go 1.18 + +require ( + github.com/spf13/cobra v1.4.0 + github.com/spf13/pflag v1.0.5 + k8s.io/api v0.25.4 + k8s.io/cli-runtime v0.25.4 + k8s.io/klog/v2 v2.70.1 + sigs.k8s.io/kustomize/api v0.12.1 + sigs.k8s.io/kustomize/kyaml v0.13.9 + sigs.k8s.io/yaml v1.2.0 +) + +require ( + github.com/PuerkitoBio/purell v1.1.1 // indirect + github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.8.0 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/go-errors/errors v1.0.1 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.19.5 // indirect + github.com/go-openapi/swag v0.19.14 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/btree v1.0.1 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/google/uuid v1.1.2 // indirect + github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect + github.com/imdario/mergo v0.3.6 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/mailru/easyjson v0.7.6 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/xlab/treeprint v1.1.0 // indirect + go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect + golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect + golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/apimachinery v0.25.4 // indirect + k8s.io/client-go v0.25.4 // indirect + k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect + k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect +) + +replace github.com/RayWangQvQ/BiliBiliToolPro/krew => ../krew diff --git a/krew/go.sum b/krew/go.sum new file mode 100644 index 000000000..2f58a67d1 --- /dev/null +++ b/krew/go.sum @@ -0,0 +1,517 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw= +github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.25.4 h1:3YO8J4RtmG7elEgaWMb4HgmpS2CfY1QlaOz9nwB+ZSs= +k8s.io/api v0.25.4/go.mod h1:IG2+RzyPQLllQxnhzD8KQNEu4c4YvyDTpSMztf4A0OQ= +k8s.io/apimachinery v0.25.4 h1:CtXsuaitMESSu339tfhVXhQrPET+EiWnIY1rcurKnAc= +k8s.io/apimachinery v0.25.4/go.mod h1:jaF9C/iPNM1FuLl7Zuy5b9v+n35HGSh6AQ4HYRkCqwo= +k8s.io/cli-runtime v0.25.4 h1:GTSBN7aKBrc2LqpdO30CmHQqJtRmotxV7XsMSP+QZIk= +k8s.io/cli-runtime v0.25.4/go.mod h1:JGOw1CR8v4Mcz6cEKA7bFQe0bPrNn1l5sGAX1/Ke4Eg= +k8s.io/client-go v0.25.4 h1:3RNRDffAkNU56M/a7gUfXaEzdhZlYhoW8dgViGy5fn8= +k8s.io/client-go v0.25.4/go.mod h1:8trHCAC83XKY0wsBIpbirZU4NTUpbuhc2JnI7OruGZw= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.70.1 h1:7aaoSdahviPmR+XkS7FyxlkkXs6tHISSG03RxleQAVQ= +k8s.io/klog/v2 v2.70.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA= +k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed h1:jAne/RjBTyawwAy0utX5eqigAwz/lQhTmy+Hr/Cpue4= +k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= +sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s= +sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= +sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/krew/pkg/cmd/cmd.go b/krew/pkg/cmd/cmd.go new file mode 100644 index 000000000..5066f7a04 --- /dev/null +++ b/krew/pkg/cmd/cmd.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "log" + + "github.com/spf13/cobra" + "k8s.io/cli-runtime/pkg/genericclioptions" +) + +const ( + biliproDesc = `Manage and deploy bilibili pro tools on k8s` + kubeconfig = "kubeconfig" +) + +var ( + confPath string + rootCmd = &cobra.Command{ + Use: "bilipro", + Long: biliproDesc, + SilenceUsage: true, + } +) + +func init() { + rootCmd.PersistentFlags().StringVar(&confPath, kubeconfig, "", "Custom kubeconfig path") + + log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) +} + +// New creates a new root command for kubectl-bilipro +func NewExecutor(streams genericclioptions.IOStreams) *cobra.Command { + cobra.EnableCommandSorting = false + rootCmd.AddCommand(newInitCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr())) + // If you want to update, just init again + rootCmd.AddCommand(newGetCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr())) + rootCmd.AddCommand(newDeleteCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr())) + rootCmd.AddCommand(newVersionCmd(rootCmd.OutOrStdout(), rootCmd.ErrOrStderr())) + return rootCmd +} diff --git a/krew/pkg/cmd/delete.go b/krew/pkg/cmd/delete.go new file mode 100644 index 000000000..9483ae248 --- /dev/null +++ b/krew/pkg/cmd/delete.go @@ -0,0 +1,165 @@ +package cmd + +import ( + "bufio" + "fmt" + "io" + "os" + "os/exec" + "strings" + + "sigs.k8s.io/kustomize/api/krusty" + "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/yaml" + + "k8s.io/klog/v2" + + "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/options" + "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/utils" + "github.com/spf13/cobra" +) + +const ( + deleteDesc = ` +'delete' command delete bilibilipro tool.` + deleteExample = ` kubectl bilipro delete <--name deployment_name>` +) + +type deleteCmd struct { + out io.Writer + errOut io.Writer + output bool + deployOpts options.DeployOptions +} + +func newDeleteCmd(out io.Writer, errOut io.Writer) *cobra.Command { + o := &deleteCmd{out: out, errOut: errOut} + + cmd := &cobra.Command{ + Use: "delete", + Short: "Delete bilibilipro", + Long: deleteDesc, + Example: deleteExample, + Args: cobra.MaximumNArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + + err := o.run(out) + if err != nil { + klog.Warning(err) + return err + } + return nil + }, + } + + f := cmd.Flags() + f.StringVarP(&o.deployOpts.Namespace, "namespace", "n", "bilipro", "namespace scope for this request") + f.StringVarP(&o.deployOpts.Name, "name", "", "bilibilipro", "name of deployment to delete") + return cmd +} + +func (o *deleteCmd) run(writer io.Writer) error { + inDiskSys, err := utils.GetResourceFileSys() + if err != nil { + klog.Error(err) + return err + } + + // if the bilibili tool is deployed under system/pre-defined namespace, ignore the namespace file + resources := []string{} + if o.deployOpts.Namespace == "default" || o.deployOpts.Namespace == "kube-system" || o.deployOpts.Namespace == "kube-public" { + resources = []string{"bilipro/bilibiliPro"} + } else { + resources = []string{"bilipro/bilibiliPro", "bilipro/ns"} + } + + // write the kustomization file + + kustomizationYaml := types.Kustomization{ + TypeMeta: types.TypeMeta{ + Kind: "Kustomization", + APIVersion: "kustomize.config.k8s.io/v1beta1", + }, + Resources: resources, + } + + if o.deployOpts.Namespace != "" { + kustomizationYaml.Namespace = o.deployOpts.Namespace + } + + // Compile the kustomization to a file and create on the in memory filesystem + kustYaml, err := yaml.Marshal(kustomizationYaml) + if err != nil { + klog.Error(err) + return err + } + + kustFile, err := inDiskSys.Create("kustomization.yaml") + if err != nil { + klog.Error(err) + return err + } + + _, err = kustFile.Write(kustYaml) + if err != nil { + klog.Error(err) + return err + } + + // kustomize build the target location + k := krusty.MakeKustomizer( + krusty.MakeDefaultOptions(), + ) + + m, err := k.Run(inDiskSys, "./bilipro") + if err != nil { + klog.Error(err) + return err + } + + yml, err := m.AsYaml() + if err != nil { + klog.Error(err) + return err + } + + if o.output { + _, err = writer.Write(yml) + klog.Error(err) + return err + } + + // do kubectl delete + cmd := exec.Command("kubectl", "delete", "-f", "-") + + cmd.Stdin = strings.NewReader(string(yml)) + + stdoutReader, _ := cmd.StdoutPipe() + stdoutScanner := bufio.NewScanner(stdoutReader) + go func() { + for stdoutScanner.Scan() { + fmt.Println(stdoutScanner.Text()) + } + }() + stderrReader, _ := cmd.StderrPipe() + stderrScanner := bufio.NewScanner(stderrReader) + go func() { + for stderrScanner.Scan() { + fmt.Println(stderrScanner.Text()) + } + }() + err = cmd.Start() + if err != nil { + fmt.Printf("Error : %v \n", err) + os.Exit(1) + } + + // stuck here to wait for the completion + err = cmd.Wait() + if err != nil { + fmt.Printf("Error: %v \n", err) + os.Exit(1) + } + + return nil +} diff --git a/krew/pkg/cmd/get.go b/krew/pkg/cmd/get.go new file mode 100644 index 000000000..226183caa --- /dev/null +++ b/krew/pkg/cmd/get.go @@ -0,0 +1,88 @@ +package cmd + +import ( + "bufio" + "fmt" + "io" + "os" + "os/exec" + + "k8s.io/klog/v2" + + "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/options" + "github.com/spf13/cobra" +) + +const ( + getDesc = ` +'get' command get bilibilipro tool deployment.` + getExample = ` kubectl bilipro get <--name deployment_name --namespace namespace_name>` +) + +type getCmd struct { + out io.Writer + errOut io.Writer + + deployOpts options.DeployOptions +} + +func newGetCmd(out io.Writer, errOut io.Writer) *cobra.Command { + o := &getCmd{out: out, errOut: errOut} + + cmd := &cobra.Command{ + Use: "get", + Short: "Get bilibilipro", + Long: getDesc, + Example: getExample, + Args: cobra.MaximumNArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + + err := o.run(out) + if err != nil { + klog.Warning(err) + return err + } + return nil + }, + } + + f := cmd.Flags() + f.StringVarP(&o.deployOpts.Namespace, "namespace", "n", "bilipro", "namespace scope for this request") + f.StringVarP(&o.deployOpts.Name, "name", "", "bilibilipro", "name of deployment to get") + return cmd +} + +func (o *getCmd) run(writer io.Writer) error { + // do kubectl get + cmd := exec.Command("kubectl", "get", "deploy", o.deployOpts.Name, "-n", o.deployOpts.Namespace) + + stdoutReader, _ := cmd.StdoutPipe() + stdoutScanner := bufio.NewScanner(stdoutReader) + go func() { + for stdoutScanner.Scan() { + fmt.Println(stdoutScanner.Text()) + } + }() + stderrReader, _ := cmd.StderrPipe() + stderrScanner := bufio.NewScanner(stderrReader) + go func() { + for stderrScanner.Scan() { + fmt.Println(stderrScanner.Text()) + } + }() + + err := cmd.Start() + if err != nil { + fmt.Printf("Error : %v \n", err) + os.Exit(1) + } + + // stuck here to wait for the completion + err = cmd.Wait() + if err != nil { + fmt.Printf("Error: %v \n", err) + os.Exit(1) + } + + return nil +} diff --git a/krew/pkg/cmd/init.go b/krew/pkg/cmd/init.go new file mode 100644 index 000000000..69c8a5564 --- /dev/null +++ b/krew/pkg/cmd/init.go @@ -0,0 +1,255 @@ +package cmd + +import ( + "bufio" + "encoding/json" + "fmt" + "io" + "io/ioutil" + "os" + "os/exec" + "strings" + + corev1 "k8s.io/api/core/v1" + + "sigs.k8s.io/kustomize/kyaml/resid" + + "sigs.k8s.io/yaml" + + "sigs.k8s.io/kustomize/api/types" + + "k8s.io/klog/v2" + + "github.com/spf13/cobra" + + "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/options" + "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/utils" + "sigs.k8s.io/kustomize/api/krusty" +) + +const ( + initDesc = ` + 'init' command creates BilibiliPro deployment along with all the dependencies.` + initExample = ` kubectl bilipro init --config ` +) + +type initCmd struct { + out io.Writer + errOut io.Writer + output bool + deployOpts options.DeployOptions +} + +func newInitCmd(out io.Writer, errOut io.Writer) *cobra.Command { + o := &initCmd{out: out, errOut: errOut} + + cmd := &cobra.Command{ + Use: "init", + Short: "Initialize bilipro", + Long: initDesc, + Example: initExample, + Args: cobra.MaximumNArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + err := o.run(out) + if err != nil { + klog.Warning(err) + return err + } + return nil + }, + } + + f := cmd.Flags() + f.StringVarP(&o.deployOpts.Image, "image", "i", "zai7lou/bilibili_tool_pro:0.2.1", "bilibilipro image") + f.StringVarP(&o.deployOpts.Namespace, "namespace", "n", "bilipro", "namespace scope for this request") + f.StringVar(&o.deployOpts.ImagePullSecret, "image-pull-secret", "", "image pull secret to be used for pulling bilibilipro image") + f.StringVarP(&o.deployOpts.ConfigFilePath, "config", "c", "", "the config file contanis the environment variables") + f.BoolVarP(&o.output, "output", "o", false, "dry run this command and generate requisite yaml") + return cmd +} + +type opStr struct { + Op string `json:"op"` + Path string `json:"path"` + Value string `json:"value"` +} + +type opInterface struct { + Op string `json:"op"` + Path string `json:"path"` + Value interface{} `json:"value"` +} + +type normalEnvVars struct { + Name string `json:"name"` + Value string `json:"value"` +} + +// run initializes local config and installs BiliBiliPro tool to Kubernetes Cluster. +func (o *initCmd) run(writer io.Writer) error { + inDiskSys, err := utils.GetResourceFileSys() + if err != nil { + return err + } + + // if the bilibili tool is deployed under system/pre-defined namespace, ignore the namespace file + resources := []string{} + if o.deployOpts.Namespace == "default" || o.deployOpts.Namespace == "kube-system" || o.deployOpts.Namespace == "kube-public" { + resources = []string{"bilipro/bilibiliPro"} + } else { + resources = []string{"bilipro/ns", "bilipro/bilibiliPro"} + } + + // write the kustomization file + kustomizationYaml := types.Kustomization{ + TypeMeta: types.TypeMeta{ + Kind: "Kustomization", + APIVersion: "kustomize.config.k8s.io/v1beta1", + }, + Resources: resources, + PatchesJson6902: []types.Patch{}, + } + + var deployDepPatches []interface{} + // create patches for the supplied arguments + if o.deployOpts.Image != "" { + deployDepPatches = append(deployDepPatches, opStr{ + Op: "replace", + Path: "/spec/template/spec/containers/0/image", + Value: o.deployOpts.Image, + }) + } + // create patches for the env + content, err := ioutil.ReadFile(o.deployOpts.ConfigFilePath) + if err != nil { + klog.Error(err) + return err + } + + envs := []normalEnvVars{} + err = yaml.Unmarshal(content, &envs) + if err != nil { + klog.Error(err) + return err + } + + deployDepPatches = append(deployDepPatches, opInterface{ + Op: "add", + Path: "/spec/template/spec/containers/0/env", + Value: envs, + }) + + if o.deployOpts.ImagePullSecret != "" { + deployDepPatches = append(deployDepPatches, opInterface{ + Op: "add", + Path: "/spec/template/spec/imagePullSecrets", + Value: []corev1.LocalObjectReference{{Name: o.deployOpts.ImagePullSecret}}, + }) + } + + // attach the patches to the kustomization file + if len(deployDepPatches) > 0 { + kustomizationYaml.PatchesJson6902 = append(kustomizationYaml.PatchesJson6902, types.Patch{ + Patch: o.serializeJSONPatchOps(deployDepPatches), + Target: &types.Selector{ + ResId: resid.ResId{ + Gvk: resid.Gvk{ + Group: "apps", + Version: "v1", + Kind: "Deployment", + }, + Name: "bilibilipro", + }, + }, + }) + } + + // Not deploying in kube-* namespace + if o.deployOpts.Namespace == "kube-system" || o.deployOpts.Namespace == "kube-public" { + fmt.Println("better not deployed under system namesapce") + } + + if o.deployOpts.Namespace != "" { + kustomizationYaml.Namespace = o.deployOpts.Namespace + } + // Compile the kustomization to a file and create on the in memory filesystem + kustYaml, err := yaml.Marshal(kustomizationYaml) + if err != nil { + klog.Error(err) + return err + } + + kustFile, err := inDiskSys.Create("kustomization.yaml") + if err != nil { + klog.Error(err) + return err + } + + _, err = kustFile.Write(kustYaml) + if err != nil { + klog.Error(err) + return err + } + + // kustomize build the target location + k := krusty.MakeKustomizer( + krusty.MakeDefaultOptions(), + ) + + m, err := k.Run(inDiskSys, "./bilipro") + if err != nil { + klog.Error(err) + return err + } + + yml, err := m.AsYaml() + if err != nil { + klog.Error(err) + return err + } + + if o.output { + _, err = writer.Write(yml) + klog.Error(err) + return err + } + + // do kubectl apply + cmd := exec.Command("kubectl", "apply", "-f", "-") + + cmd.Stdin = strings.NewReader(string(yml)) + + stdoutReader, _ := cmd.StdoutPipe() + stdoutScanner := bufio.NewScanner(stdoutReader) + go func() { + for stdoutScanner.Scan() { + fmt.Println(stdoutScanner.Text()) + } + }() + stderrReader, _ := cmd.StderrPipe() + stderrScanner := bufio.NewScanner(stderrReader) + go func() { + for stderrScanner.Scan() { + fmt.Println(stderrScanner.Text()) + } + }() + err = cmd.Start() + if err != nil { + fmt.Printf("Error : %v \n", err) + os.Exit(1) + } + + // Stuck here until there are out and err + err = cmd.Wait() + if err != nil { + fmt.Printf("Error: %v \n", err) + os.Exit(1) + } + + return nil +} + +func (o *initCmd) serializeJSONPatchOps(jp []interface{}) string { + jpJSON, _ := json.Marshal(jp) + return string(jpJSON) +} diff --git a/krew/pkg/cmd/version.go b/krew/pkg/cmd/version.go new file mode 100644 index 000000000..f7b05283a --- /dev/null +++ b/krew/pkg/cmd/version.go @@ -0,0 +1,52 @@ +package cmd + +import ( + "fmt" + "io" + + "k8s.io/klog/v2" + + "github.com/spf13/cobra" +) + +// version provides the version of this plugin +var version = "NO.VERSION" + +const ( + versionDesc = ` +'version' command displays the kubectl plugin version.` + versionExample = ` kubectl bilipro version` +) + +type versionCmd struct { + out io.Writer + errOut io.Writer +} + +func newVersionCmd(out io.Writer, errOut io.Writer) *cobra.Command { + o := &versionCmd{out: out, errOut: errOut} + + cmd := &cobra.Command{ + Use: "version", + Short: "Display plugin version", + Long: versionDesc, + Example: versionExample, + Args: cobra.MaximumNArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + err := o.run() + if err != nil { + klog.Warning(err) + return err + } + return nil + }, + } + + return cmd +} + +// run initializes local config and installs BilibiliPro Plugin to Kubernetes cluster. +func (o *versionCmd) run() error { + fmt.Println(version) + return nil +} diff --git a/krew/pkg/options/deployment.go b/krew/pkg/options/deployment.go new file mode 100644 index 000000000..4382e85cb --- /dev/null +++ b/krew/pkg/options/deployment.go @@ -0,0 +1,10 @@ +package options + +// DeployOptions encapsulates the CLI options for a BiliBiliPro +type DeployOptions struct { + Name string + Image string + Namespace string + ImagePullSecret string + ConfigFilePath string +} diff --git a/krew/pkg/resources/asset.go b/krew/pkg/resources/asset.go new file mode 100644 index 000000000..20cea3136 --- /dev/null +++ b/krew/pkg/resources/asset.go @@ -0,0 +1,13 @@ +package resources + +import ( + "embed" +) + +//go:embed * +var fs embed.FS + +// GetStaticResources returns the fs with the embedded assets +func GetStaticResources() embed.FS { + return fs +} diff --git a/krew/pkg/resources/base/bilibiliPro/deployment.yaml b/krew/pkg/resources/base/bilibiliPro/deployment.yaml new file mode 100644 index 000000000..df8c8008e --- /dev/null +++ b/krew/pkg/resources/base/bilibiliPro/deployment.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: bilibilipro +spec: + selector: + matchLabels: + app: bilibilipro + template: + metadata: + labels: + app: bilibilipro + spec: + containers: + - name: bilibilipro + image: zai7lou/bilibili_tool_pro:0.2.1 + imagePullPolicy: IfNotPresent + \ No newline at end of file diff --git a/krew/pkg/resources/base/bilibiliPro/kustomization.yaml b/krew/pkg/resources/base/bilibiliPro/kustomization.yaml new file mode 100644 index 000000000..991a8834e --- /dev/null +++ b/krew/pkg/resources/base/bilibiliPro/kustomization.yaml @@ -0,0 +1,2 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization \ No newline at end of file diff --git a/krew/pkg/resources/base/kustomization.yaml b/krew/pkg/resources/base/kustomization.yaml new file mode 100644 index 000000000..991a8834e --- /dev/null +++ b/krew/pkg/resources/base/kustomization.yaml @@ -0,0 +1,2 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization \ No newline at end of file diff --git a/krew/pkg/resources/base/ns/kustomization.yaml b/krew/pkg/resources/base/ns/kustomization.yaml new file mode 100644 index 000000000..991a8834e --- /dev/null +++ b/krew/pkg/resources/base/ns/kustomization.yaml @@ -0,0 +1,2 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization \ No newline at end of file diff --git a/krew/pkg/resources/base/ns/namespace.yaml b/krew/pkg/resources/base/ns/namespace.yaml new file mode 100644 index 000000000..6057bc06d --- /dev/null +++ b/krew/pkg/resources/base/ns/namespace.yaml @@ -0,0 +1,5 @@ + +apiVersion: v1 +kind: Namespace +metadata: + name: bilipro \ No newline at end of file diff --git a/krew/pkg/resources/kustomization.yaml b/krew/pkg/resources/kustomization.yaml new file mode 100644 index 000000000..b929f13d0 --- /dev/null +++ b/krew/pkg/resources/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - base/ns/namespace.yaml + - base/bilibiliPro/deployment.yaml + \ No newline at end of file diff --git a/krew/pkg/utils/utils.go b/krew/pkg/utils/utils.go new file mode 100644 index 000000000..504d02de2 --- /dev/null +++ b/krew/pkg/utils/utils.go @@ -0,0 +1,82 @@ +package utils + +import ( + "io" + "io/fs" + "log" + "path" + "strings" + + "github.com/RayWangQvQ/BiliBiliToolPro/krew/pkg/resources" + "sigs.k8s.io/kustomize/kyaml/filesys" +) + +var assetFS = resources.GetStaticResources() + +// GetResourceFileSys file +func GetResourceFileSys() (filesys.FileSystem, error) { + inDiskSys := filesys.MakeFsOnDisk() + // copy from the resources into the target folder on the in memory FS + if err := copyDirtoDiskFS(".", "bilipro", inDiskSys); err != nil { + log.Println(err) + return nil, err + } + return inDiskSys, nil +} + +func copyFileToDiskFS(src, dst string, diskFS filesys.FileSystem) error { + // skip all .go files + if strings.HasSuffix(src, ".go") { + return nil + } + var err error + var srcFileDesc fs.File + var dstFileDesc filesys.File + + if srcFileDesc, err = assetFS.Open(src); err != nil { + return err + } + defer srcFileDesc.Close() + + if dstFileDesc, err = diskFS.Create(dst); err != nil { + return err + } + defer dstFileDesc.Close() + + // Note: I had to read the whole string, for some reason io.Copy was not copying the whole content + input, err := io.ReadAll(srcFileDesc) + if err != nil { + return err + } + + _, err = dstFileDesc.Write(input) + return err +} + +func copyDirtoDiskFS(src string, dst string, diskFS filesys.FileSystem) error { + var err error + var fds []fs.DirEntry + + if err = diskFS.MkdirAll(dst); err != nil { + return err + } + + if fds, err = assetFS.ReadDir(src); err != nil { + return err + } + for _, fd := range fds { + srcfp := path.Join(src, fd.Name()) + dstfp := path.Join(dst, fd.Name()) + + if fd.IsDir() { + if err = copyDirtoDiskFS(srcfp, dstfp, diskFS); err != nil { + return err + } + } else { + if err = copyFileToDiskFS(srcfp, dstfp, diskFS); err != nil { + return err + } + } + } + return nil +} diff --git a/podman/README.md b/podman/README.md index 6aef954b8..6956c4a2e 100644 --- a/podman/README.md +++ b/podman/README.md @@ -7,6 +7,7 @@ - [2. 运行容器](#2-运行容器) - [2.1. 极简版](#21-极简版) - [2.2. 综合版](#22-综合版) +- [登录](#登录) - [3. 自己构建镜像(非必须)](#3-自己构建镜像非必须) - [4. 其他](#4-其他) @@ -52,9 +53,7 @@ Podman可以和Docker共存,命令也基本可以通用。 ``` # 生成并运行容器 -podman run -itd --name="bili" \ - -e Ray_BiliBiliCookies__1="cookie" \ - docker.io/zai7lou/bilibili_tool_pro +podman run -itd --name="bili" docker.io/zai7lou/bilibili_tool_pro # 查看实时日志 podman logs -f bili @@ -71,13 +70,13 @@ mkdir -p Logs # 下载appsettings.json wget https://raw.githubusercontent.com/RayWangQvQ/BiliBiliToolPro/main/src/Ray.BiliBiliTool.Console/appsettings.json +wget https://raw.githubusercontent.com/RayWangQvQ/BiliBiliToolPro/main/docker/sample/cookies.json # 运行 podman run -itd --name="bili" \ -v /bili/Logs:/app/Logs \ -v /bili/appsettings.json:/app/appsettings.json \ - -e Ray_BiliBiliCookies__1="cookie" \ - -e Ray_BiliBiliCookies__2="cookie" \ + -v /bili/cookies.json:/app/cookies.json \ -e Ray_DailyTaskConfig__Cron="0 15 * * *" \ -e Ray_LiveLotteryTaskConfig__Cron="0 22 * * *" \ -e Ray_UnfollowBatchedTaskConfig__Cron="0 6 1 * *" \ @@ -99,6 +98,14 @@ podman ps -a podman exec -it bili bash ``` +## 登录 + +在宿主机运行`podman exec -it bili bash -c "dotnet Ray.BiliBiliTool.Console.dll --runTasks=Login"` + +扫码进行登录。 + +![login](../docs/imgs/docker-login.png) + ## 3. 自己构建镜像(非必须) 目前我提供和维护的镜像:`[zai7lou/bilibili_tool_pro](https://hub.docker.com/repository/docker/zai7lou/bilibili_tool_pro)`; diff --git a/qinglong/DefaultTasks/bili_task_base.sh b/qinglong/DefaultTasks/bili_task_base.sh index 3b8d15d41..5dfeea189 100644 --- a/qinglong/DefaultTasks/bili_task_base.sh +++ b/qinglong/DefaultTasks/bili_task_base.sh @@ -18,4 +18,5 @@ echo -e "\nrepo目录: $dir_repo" bili_repo_dir="$(find $dir_repo -type d -iname $bili_repo | head -1)" echo -e "bili仓库目录: $bili_repo_dir\n" -cd $bili_repo_dir \ No newline at end of file +cd $bili_repo_dir +export Ray_PlateformType=QingLong \ No newline at end of file diff --git a/qinglong/DefaultTasks/bili_task_daily.sh b/qinglong/DefaultTasks/bili_task_daily.sh index 55cef2f06..e9ebd6adc 100644 --- a/qinglong/DefaultTasks/bili_task_daily.sh +++ b/qinglong/DefaultTasks/bili_task_daily.sh @@ -4,6 +4,6 @@ . bili_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=Daily && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_task_liveLottery.sh b/qinglong/DefaultTasks/bili_task_liveLottery.sh index b3caa3b0c..9c209094f 100644 --- a/qinglong/DefaultTasks/bili_task_liveLottery.sh +++ b/qinglong/DefaultTasks/bili_task_liveLottery.sh @@ -4,6 +4,6 @@ . bili_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=LiveLottery && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_task_login.sh b/qinglong/DefaultTasks/bili_task_login.sh new file mode 100644 index 000000000..3ff547614 --- /dev/null +++ b/qinglong/DefaultTasks/bili_task_login.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# new Env("bili扫码登录") +# cron 0 0 1 1 * bili_task_login.sh +. bili_task_base.sh + +cd ./src/Ray.BiliBiliTool.Console + +export Ray_RunTasks=Login && \ +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_task_test.sh b/qinglong/DefaultTasks/bili_task_test.sh index 38e740aaa..bf18cf76e 100644 --- a/qinglong/DefaultTasks/bili_task_test.sh +++ b/qinglong/DefaultTasks/bili_task_test.sh @@ -4,6 +4,6 @@ . bili_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=Test && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_task_unfollowBatched.sh b/qinglong/DefaultTasks/bili_task_unfollowBatched.sh index 7fa37a101..0db839f19 100644 --- a/qinglong/DefaultTasks/bili_task_unfollowBatched.sh +++ b/qinglong/DefaultTasks/bili_task_unfollowBatched.sh @@ -4,6 +4,6 @@ . bili_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=UnfollowBatched && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_task_vipBigPoint.sh b/qinglong/DefaultTasks/bili_task_vipBigPoint.sh index f6f9792a2..da6baffec 100644 --- a/qinglong/DefaultTasks/bili_task_vipBigPoint.sh +++ b/qinglong/DefaultTasks/bili_task_vipBigPoint.sh @@ -4,6 +4,6 @@ . bili_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=VipBigPoint && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_dev_task_base.sh b/qinglong/DefaultTasks/dev/bili_dev_task_base.sh similarity index 92% rename from qinglong/DefaultTasks/bili_dev_task_base.sh rename to qinglong/DefaultTasks/dev/bili_dev_task_base.sh index 6da1c3a65..40a6fa5a2 100644 --- a/qinglong/DefaultTasks/bili_dev_task_base.sh +++ b/qinglong/DefaultTasks/dev/bili_dev_task_base.sh @@ -18,4 +18,5 @@ echo -e "\nrepo目录: $dir_repo" bili_repo_dir="$(find $dir_repo -type d -iname $bili_repo | head -1)" echo -e "bili仓库目录: $bili_repo_dir\n" -cd $bili_repo_dir \ No newline at end of file +cd $bili_repo_dir +export Ray_PlateformType=QingLong \ No newline at end of file diff --git a/qinglong/DefaultTasks/bili_dev_task_daily.sh b/qinglong/DefaultTasks/dev/bili_dev_task_daily.sh similarity index 80% rename from qinglong/DefaultTasks/bili_dev_task_daily.sh rename to qinglong/DefaultTasks/dev/bili_dev_task_daily.sh index 574d3d0df..6b30dd4e5 100644 --- a/qinglong/DefaultTasks/bili_dev_task_daily.sh +++ b/qinglong/DefaultTasks/dev/bili_dev_task_daily.sh @@ -4,6 +4,6 @@ . bili_dev_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=Daily && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_dev_task_liveLottery.sh b/qinglong/DefaultTasks/dev/bili_dev_task_liveLottery.sh similarity index 81% rename from qinglong/DefaultTasks/bili_dev_task_liveLottery.sh rename to qinglong/DefaultTasks/dev/bili_dev_task_liveLottery.sh index 521b03a48..eb2c20124 100644 --- a/qinglong/DefaultTasks/bili_dev_task_liveLottery.sh +++ b/qinglong/DefaultTasks/dev/bili_dev_task_liveLottery.sh @@ -5,6 +5,5 @@ cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ export Ray_RunTasks=LiveLottery && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/dev/bili_dev_task_login.sh b/qinglong/DefaultTasks/dev/bili_dev_task_login.sh new file mode 100644 index 000000000..933e05cfa --- /dev/null +++ b/qinglong/DefaultTasks/dev/bili_dev_task_login.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# new Env("bili扫码登录[dev先行版]") +# cron 0 0 1 1 * bili_dev_task_login.sh +. bili_dev_task_base.sh + +cd ./src/Ray.BiliBiliTool.Console + +export Ray_RunTasks=Login && \ +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_dev_task_test.sh b/qinglong/DefaultTasks/dev/bili_dev_task_test.sh similarity index 80% rename from qinglong/DefaultTasks/bili_dev_task_test.sh rename to qinglong/DefaultTasks/dev/bili_dev_task_test.sh index a175c5bd5..19c6f798e 100644 --- a/qinglong/DefaultTasks/bili_dev_task_test.sh +++ b/qinglong/DefaultTasks/dev/bili_dev_task_test.sh @@ -4,6 +4,6 @@ . bili_dev_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=Test && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_dev_task_tryFix.sh b/qinglong/DefaultTasks/dev/bili_dev_task_tryFix.sh similarity index 100% rename from qinglong/DefaultTasks/bili_dev_task_tryFix.sh rename to qinglong/DefaultTasks/dev/bili_dev_task_tryFix.sh diff --git a/qinglong/DefaultTasks/bili_dev_task_unfollowBatched.sh b/qinglong/DefaultTasks/dev/bili_dev_task_unfollowBatched.sh similarity index 82% rename from qinglong/DefaultTasks/bili_dev_task_unfollowBatched.sh rename to qinglong/DefaultTasks/dev/bili_dev_task_unfollowBatched.sh index 71cd7be83..0f8311dba 100644 --- a/qinglong/DefaultTasks/bili_dev_task_unfollowBatched.sh +++ b/qinglong/DefaultTasks/dev/bili_dev_task_unfollowBatched.sh @@ -4,6 +4,6 @@ . bili_dev_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=UnfollowBatched && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/DefaultTasks/bili_dev_task_vipBigPoint.sh b/qinglong/DefaultTasks/dev/bili_dev_task_vipBigPoint.sh similarity index 82% rename from qinglong/DefaultTasks/bili_dev_task_vipBigPoint.sh rename to qinglong/DefaultTasks/dev/bili_dev_task_vipBigPoint.sh index 3dbcfbb8e..d6cc9d4de 100644 --- a/qinglong/DefaultTasks/bili_dev_task_vipBigPoint.sh +++ b/qinglong/DefaultTasks/dev/bili_dev_task_vipBigPoint.sh @@ -4,6 +4,6 @@ . bili_dev_task_base.sh cd ./src/Ray.BiliBiliTool.Console -export ENVIRONMENT=Production && \ + export Ray_RunTasks=VipBigPoint && \ -dotnet run +dotnet run --ENVIRONMENT=Production diff --git a/qinglong/README.md b/qinglong/README.md index 8a43d2827..34313140b 100644 --- a/qinglong/README.md +++ b/qinglong/README.md @@ -10,16 +10,16 @@ - [1.1. 安装 `dotnet` 环境](#11-安装-dotnet-环境) - [1.2. 重启青龙容器](#12-重启青龙容器) - [1.3. 登录青龙面板并修改配置](#13-登录青龙面板并修改配置) - - [1.4. 添加bili配置](#14-添加bili配置) - - [1.5. 在青龙面板中添加拉库定时任务](#15-在青龙面板中添加拉库定时任务) - - [1.5.1 订阅管理](#151-订阅管理) - - [1.5.2 定时任务拉库](#152-定时任务拉库) + - [1.4. 在青龙面板中添加拉库定时任务](#14-在青龙面板中添加拉库定时任务) + - [1.4.1. 订阅管理](#141-订阅管理) + - [1.4.2. 定时任务拉库](#142-定时任务拉库) + - [1.5. 登录](#15-登录) - [2. 先行版](#2-先行版) - - [2.1 订阅管理](#21-订阅管理) - - [2.2 定时任务拉库](#22-定时任务拉库) + - [2.1. 订阅管理](#21-订阅管理) + - [2.2. 定时任务拉库](#22-定时任务拉库) - [3. GitHub加速](#3-github加速) -- [4 常见问题](#4-常见问题) - - [4.1 Couldn't find a valid ICU package installed on the system](#41-couldnt-find-a-valid-icu-package-installed-on-the-system) +- [4. 常见问题](#4-常见问题) + - [4.1. Couldn't find a valid ICU package installed on the system](#41-couldnt-find-a-valid-icu-package-installed-on-the-system) @@ -53,29 +53,10 @@ curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliB 保存配置。 -### 1.4. 添加bili配置 - -青龙面板,`环境变量`页,添加环境变量: - -``` -名称:Ray_BiliBiliCookies__1 -值:abc -``` - -``` -名称:Ray_BiliBiliCookies__2 -值:defg -``` - -`abc`、`defg`为你抓取到的真实cookie字符串。 - -![qinglong-env.png](../docs/imgs/qinglong-env.png) - - -### 1.5. 在青龙面板中添加拉库定时任务 +### 1.4. 在青龙面板中添加拉库定时任务 两种方式: -#### 1.5.1 订阅管理 +#### 1.4.1. 订阅管理 ``` 名称:Bilibili @@ -91,7 +72,7 @@ curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliB 保存后,点击运行按钮,运行拉库。 -#### 1.5.2 定时任务拉库 +#### 1.4.2. 定时任务拉库 青龙面板,`定时任务`页,右上角`添加任务`,填入以下信息: ``` @@ -108,6 +89,15 @@ curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliB ![qinglong-tasks.png](../docs/imgs/qinglong-tasks.png) +### 1.5. 登录 + +在青龙定时任务中,点击运行`bili扫码登录`任务,查看运行日志,扫描日志中的二维码进行登录。 +![qinglong-login.png](../docs/imgs/qinglong-login.png) + +登录成功后,会将cookie保存到青龙的环境变量中: + +![qinglong-env.png](../docs/imgs/qinglong-env.png) + ## 2. 先行版 青龙拉库时可以指定分支,develop分支的代码会超前于默认的main分支,包含当前正在开发的新功能。 @@ -116,7 +106,7 @@ curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliB 方式有两种: -### 2.1 订阅管理 +### 2.1. 订阅管理 ``` 分支:develop @@ -125,16 +115,16 @@ curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliB 其他选项同上。 -### 2.2 定时任务拉库 +### 2.2. 定时任务拉库 修改拉库命令为`ql repo https://github.com/RayWangQvQ/BiliBiliToolPro.git "bili_dev_task_" "" "" "develop"` ## 3. GitHub加速 拉库时,如果服务器在国内,访问GitHub速度慢,可以在仓库地址前加上 `https://ghproxy.com/` 进行加速, 如:`ql repo https://ghproxy.com/https://github.com/RayWangQvQ/BiliBiliToolPro.git "bili_task_"` -## 4 常见问题 +## 4. 常见问题 -### 4.1 Couldn't find a valid ICU package installed on the system +### 4.1. Couldn't find a valid ICU package installed on the system 如 #266 ,需要在青龙面板的环境变量添加如下环境变量: diff --git a/qinglong/bak/bili_dev_task_get_cookie.py.bak b/qinglong/bak/bili_dev_task_get_cookie.py.bak new file mode 100644 index 000000000..7cf0e8304 --- /dev/null +++ b/qinglong/bak/bili_dev_task_get_cookie.py.bak @@ -0,0 +1,87 @@ +''' +1 9 11 11 1 bili_dev_task_get_cookie.py +手动运行,查看日志,并使用手机B站app扫描日志中二维码,注意,只能修改第一个cookie +如果产生错误,重新运行并用手机扫描二维码 +有可能识别不出来二维码,我测试了几次都能识别 + +默认环境变量存放位置为/ql/data/config/env.sh +可以自己通过docker命令进入容器查找这个文件位置。docker exec -it qinglong /bin/bash,进入青龙容器,然后查找一下这个文件位置 +filename = '../config/env.sh' +''' + +import qrcode +import requests +import json +import time +import os + +filename = '/ql/data/config/env.sh' + +url_get = 'http://passport.bilibili.com/x/passport-login/web/qrcode/generate' +headers = { + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.42" + } +session = requests.session() +response = session.get(url_get, headers=headers) +json_data = json.loads(response.text) +qr_data = json_data['data']['url'] +qr_code = json_data['data']['qrcode_key'] +# print(qr_data) +# img = qrcode.make(qr_data) +# img.save('../upload/B.png') +# 生成二维码,并且打印,只有invert是True手机才能识别,默认的打印识别不出来 +qr = qrcode.QRCode() +qr.add_data(qr_data) +qr.print_ascii(invert=True) + +url_get_2 = f'http://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qr_code}&source=main_mini' +refresh_token = '' +# 尝试次数 +try_time = 8 +while True: + try_time -= 1 + if not try_time: + print('一直没有扫码,退出登录!') + exit(1) + response = session.get(url_get_2, headers=headers) + json_data = json.loads(response.text) + response_data_2 = json_data['data'] + if response_data_2['code'] == 0: + try_time += 5 + refresh_token = response_data_2['refresh_token'] + print(response_data_2, end='') + if response_data_2['message'] == '二维码已失效': + print(response_data_2['message']) + print('-' * 20) + break + print(response_data_2['message']) + print('-' * 20) + time.sleep(5) +session.get('https://api.bilibili.com/x/web-interface/nav') +cookies = requests.utils.dict_from_cookiejar(session.cookies) +lst = [] +for item in cookies.items(): + lst.append(f"{item[0]}={item[1]}") + +cookie_str = ';'.join(lst) +print('=' * 20) +print(cookie_str) +print('=' * 20) +# 修改环境变量 +with open(filename, 'r') as f: + lines = f.readlines() + +flag = True +with open(filename, 'w') as f: + for l in lines: + if 'Ray_BiliBiliCookies__1' in l: + flag = False + l = f'export Ray_BiliBiliCookies__1="{cookie_str}"\n' + print(l) + f.write(l) + if flag: + flag = False + l = f'export Ray_BiliBiliCookies__1="{cookie_str}"\n' + print(l) + f.write(l) +os.popen(f'source {filename}') diff --git a/qinglong/bak/bili_task_get_cookie.py.bak b/qinglong/bak/bili_task_get_cookie.py.bak new file mode 100644 index 000000000..9243a6387 --- /dev/null +++ b/qinglong/bak/bili_task_get_cookie.py.bak @@ -0,0 +1,87 @@ +''' +1 9 11 11 1 bili_task_get_cookie.py +手动运行,查看日志,并使用手机B站app扫描日志中二维码,注意,只能修改第一个cookie +如果产生错误,重新运行并用手机扫描二维码 +有可能识别不出来二维码,我测试了几次都能识别 + +默认环境变量存放位置为/ql/data/config/env.sh +可以自己通过docker命令进入容器查找这个文件位置。docker exec -it qinglong /bin/bash,进入青龙容器,然后查找一下这个文件位置 +filename = '../config/env.sh' +''' + +import qrcode +import requests +import json +import time +import os + +filename = '/ql/data/config/env.sh' + +url_get = 'http://passport.bilibili.com/x/passport-login/web/qrcode/generate' +headers = { + "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.42" + } +session = requests.session() +response = session.get(url_get, headers=headers) +json_data = json.loads(response.text) +qr_data = json_data['data']['url'] +qr_code = json_data['data']['qrcode_key'] +# print(qr_data) +# img = qrcode.make(qr_data) +# img.save('../upload/B.png') +# 生成二维码,并且打印,只有invert是True手机才能识别,默认的打印识别不出来 +qr = qrcode.QRCode() +qr.add_data(qr_data) +qr.print_ascii(invert=True) + +url_get_2 = f'http://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key={qr_code}&source=main_mini' +refresh_token = '' +# 尝试次数 +try_time = 8 +while True: + try_time -= 1 + if not try_time: + print('一直没有扫码,退出登录!') + exit(1) + response = session.get(url_get_2, headers=headers) + json_data = json.loads(response.text) + response_data_2 = json_data['data'] + if response_data_2['code'] == 0: + try_time += 5 + refresh_token = response_data_2['refresh_token'] + print(response_data_2, end='') + if response_data_2['message'] == '二维码已失效': + print(response_data_2['message']) + print('-' * 20) + break + print(response_data_2['message']) + print('-' * 20) + time.sleep(5) +session.get('https://api.bilibili.com/x/web-interface/nav') +cookies = requests.utils.dict_from_cookiejar(session.cookies) +lst = [] +for item in cookies.items(): + lst.append(f"{item[0]}={item[1]}") + +cookie_str = ';'.join(lst) +print('=' * 20) +print(cookie_str) +print('=' * 20) +# 修改环境变量 +with open(filename, 'r') as f: + lines = f.readlines() + +flag = True +with open(filename, 'w') as f: + for l in lines: + if 'Ray_BiliBiliCookies__1' in l: + flag = False + l = f'export Ray_BiliBiliCookies__1="{cookie_str}"\n' + print(l) + f.write(l) + if flag: + flag = False + l = f'export Ray_BiliBiliCookies__1="{cookie_str}"\n' + print(l) + f.write(l) +os.popen(f'source {filename}') diff --git a/qinglong/extra.sh b/qinglong/extra.sh index c5f16c828..9d3840a3e 100644 --- a/qinglong/extra.sh +++ b/qinglong/extra.sh @@ -5,4 +5,6 @@ # 安装 dotnet 环境 # curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliBiliToolPro/main/qinglong/ray-dotnet-install.sh | bash /dev/stdin --no-official curl -sSL https://ghproxy.com/https://raw.githubusercontent.com/RayWangQvQ/BiliBiliToolPro/main/qinglong/ray-dotnet-install.sh | bash /dev/stdin -# 其他代码... \ No newline at end of file +# 安装需要用到的包 +pip3 install requests qrcode pillow +# 其他代码... diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Passport/QrCodeDto.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Passport/QrCodeDto.cs new file mode 100644 index 000000000..b89250338 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Passport/QrCodeDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Passport +{ + public class QrCodeDto + { + public string Qrcode_key { get; set; } + + public string Url { get; set; } + } +} diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Passport/TokenDto.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Passport/TokenDto.cs new file mode 100644 index 000000000..e8153df40 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Dtos/Passport/TokenDto.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Passport +{ + public class TokenDto + { + public string Url { get; set; } + public string Refresh_token { get; set; } + public long Timestamp { get; set; } + public int Code { get; set; } + public string Message { get; set; } + } + +} diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IPassportApi.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IPassportApi.cs new file mode 100644 index 000000000..8ce564a70 --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IPassportApi.cs @@ -0,0 +1,17 @@ +using System.Threading.Tasks; +using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos; +using Ray.BiliBiliTool.Agent.BiliBiliAgent.Dtos.Passport; +using WebApiClientCore.Attributes; + +namespace Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces +{ + [Header("Host", "passport.bilibili.com")] + public interface IPassportApi : IBiliBiliApi + { + [HttpGet("/x/passport-login/web/qrcode/generate")] + Task> GenerateQrCode(); + + [HttpGet("/x/passport-login/web/qrcode/poll?qrcode_key={qrcode_key}&source=main_mini")] + Task> CheckQrCodeHasScaned(string qrcode_key); + } +} diff --git a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVideoApi.cs b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVideoApi.cs index 2651d4325..d86cd0d84 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVideoApi.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliBiliAgent/Interfaces/IVideoApi.cs @@ -103,7 +103,7 @@ public interface IVideoWithoutCookieApi : IVideoApi /// /// /// - [Header("Referer", "https://space.bilibili.com/")] + [Header("Referer", "https://www.bilibili.com/")] [Header("Origin", "https://space.bilibili.com")] [HttpGet("/x/space/arc/search?mid={upId}&ps={pageSize}&tid=0&pn={pageNumber}&keyword={keyword}&order=pubdate&jsonp=jsonp")] Task> SearchVideosByUpId(long upId, int pageSize = 30, int pageNumber = 1, string keyword = ""); diff --git a/src/Ray.BiliBiliTool.Agent/BiliCookie.cs b/src/Ray.BiliBiliTool.Agent/BiliCookie.cs index a8f9efea7..ab52c4ba6 100644 --- a/src/Ray.BiliBiliTool.Agent/BiliCookie.cs +++ b/src/Ray.BiliBiliTool.Agent/BiliCookie.cs @@ -1,14 +1,9 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; +using Microsoft.Extensions.Logging.Abstractions; using Ray.BiliBiliTool.Config; -using Ray.BiliBiliTool.Config.Options; using Ray.BiliBiliTool.Infrastructure; namespace Ray.BiliBiliTool.Agent @@ -35,8 +30,10 @@ public BiliCookie(ILogger logger, { SessData = sess; } + } - this.Check(); + public BiliCookie(List ckList) : this(NullLogger.Instance,new CookieStrFactory(ckList)) + { } [Description("DedeUserID")] diff --git a/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs b/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs index e7eaf0fd6..36d17512e 100644 --- a/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs +++ b/src/Ray.BiliBiliTool.Agent/Extensions/ServiceCollectionExtension.cs @@ -11,6 +11,7 @@ using Polly.Extensions.Http; using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces; using Ray.BiliBiliTool.Agent.HttpClientDelegatingHandlers; +using Ray.BiliBiliTool.Agent.QingLong; using Ray.BiliBiliTool.Config.Options; using Ray.BiliBiliTool.Infrastructure; @@ -69,6 +70,23 @@ public static IServiceCollection AddBiliBiliClientApi(this IServiceCollection se services.AddBiliBiliClientApi("https://api.bilibili.com"); + services.AddBiliBiliClientApi("http://passport.bilibili.com", false); + + //qinglong + var qinglongHost = configuration["QL_URL"]?? "http://localhost:5600"; + services + .AddHttpApi(o => + { + o.HttpHost = new Uri(qinglongHost); + o.UseDefaultUserAgent = false; + }) + .ConfigureHttpClient((sp, c) => + { + c.DefaultRequestHeaders.Add("User-Agent", + sp.GetRequiredService>().CurrentValue.UserAgent); + }) + .AddPolicyHandler(GetRetryPolicy()); + return services; } diff --git a/src/Ray.BiliBiliTool.Agent/QingLong/IQingLongApi.cs b/src/Ray.BiliBiliTool.Agent/QingLong/IQingLongApi.cs new file mode 100644 index 000000000..b8c579b7b --- /dev/null +++ b/src/Ray.BiliBiliTool.Agent/QingLong/IQingLongApi.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Ray.BiliBiliTool.Agent.Attributes; +using WebApiClientCore.Attributes; + +namespace Ray.BiliBiliTool.Agent.QingLong +{ + [LogFilter] + public interface IQingLongApi + { + [HttpGet("/api/envs")] + Task>> GetEnvs(string searchValue, [Header("Authorization")] string token); + + [HttpPost("/api/envs")] + Task>> AddEnvs([JsonContent] List envs, [Header("Authorization")] string token); + + [HttpPut("/api/envs")] + Task> UpdateEnvs([JsonContent] UpdateQingLongEnv env, [Header("Authorization")] string token); + } + + public class QingLongGenericResponse + { + public int Code { get; set; } + + public T Data { get; set; } + } + + + public class QingLongEnv : UpdateQingLongEnv + { + public string timestamp { get; set; } + public int status { get; set; } + public long position { get; set; } + public DateTime createdAt { get; set; } + public DateTime updatedAt { get; set; } + } + + public class AddQingLongEnv + { + public string value { get; set; } + public string name { get; set; } + public string remarks { get; set; } + } + + public class UpdateQingLongEnv : AddQingLongEnv + { + public int id { get; set; } + } +} diff --git a/src/Ray.BiliBiliTool.Application.Contracts/ILoginTaskAppService.cs b/src/Ray.BiliBiliTool.Application.Contracts/ILoginTaskAppService.cs new file mode 100644 index 000000000..6cdc8fb3b --- /dev/null +++ b/src/Ray.BiliBiliTool.Application.Contracts/ILoginTaskAppService.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Text; + +namespace Ray.BiliBiliTool.Application.Contracts +{ + /// + /// 登录任务 + /// + [Description("Login")] + public interface ILoginTaskAppService : IAppService + { + } +} diff --git a/src/Ray.BiliBiliTool.Application/LoginTaskAppService.cs b/src/Ray.BiliBiliTool.Application/LoginTaskAppService.cs new file mode 100644 index 000000000..f2ab99620 --- /dev/null +++ b/src/Ray.BiliBiliTool.Application/LoginTaskAppService.cs @@ -0,0 +1,378 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Text.Json.Nodes; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using QRCoder; +using Ray.BiliBiliTool.Agent; +using Ray.BiliBiliTool.Agent.BiliBiliAgent.Interfaces; +using Ray.BiliBiliTool.Agent.QingLong; +using Ray.BiliBiliTool.Application.Attributes; +using Ray.BiliBiliTool.Application.Contracts; +using Ray.BiliBiliTool.Infrastructure; +using Ray.BiliBiliTool.Infrastructure.Enums; + +namespace Ray.BiliBiliTool.Application +{ + public class LoginTaskAppService : AppService, ILoginTaskAppService + { + private readonly ILogger _logger; + private readonly IPassportApi _passportApi; + private readonly IHostEnvironment _hostingEnvironment; + private readonly IQingLongApi _qingLongApi; + private readonly IConfiguration _configuration; + + public LoginTaskAppService( + IConfiguration configuration, + ILogger logger, + IPassportApi passportApi, + IHostEnvironment hostingEnvironment, + IQingLongApi qingLongApi + ) + { + _configuration = configuration; + _logger = logger; + _passportApi = passportApi; + _hostingEnvironment = hostingEnvironment; + _qingLongApi = qingLongApi; + } + + [TaskInterceptor("扫码登录", TaskLevel.One)] + public override void DoTask() + { + //扫码登录 + var suc = QrCodeLogin(out BiliCookie cookieInfo); + if (!suc) return; + + var plateformType = _configuration.GetSection("PlateformType").Get(); + + //更新cookie到青龙env + if (plateformType == PlateformType.QingLong) + { + AddOrUpdateCkToQingLong(cookieInfo); + return; + } + + //更新cookie到json + AddOrUpdateCkToJson(cookieInfo); + } + + [TaskInterceptor("二维码登录", TaskLevel.Two)] + protected bool QrCodeLogin(out BiliCookie cookieInfo) + { + var result = false; + cookieInfo = new BiliCookie(new List() { "" }); + + var re = _passportApi.GenerateQrCode().Result; + if (re.Code != 0) + { + _logger.LogWarning("获取二维码失败:{msg}", re.ToJson()); + return result; + } + + var url = re.Data.Url; + GenerateQrCode(url); + + var online = GetOnlinePic(url); + _logger.LogInformation(Environment.NewLine + Environment.NewLine); + _logger.LogInformation("如果上方二维码显示异常,或扫描失败,请使用浏览器访问如下链接,查看高清二维码:"); + _logger.LogInformation(online + Environment.NewLine + Environment.NewLine); + + var waitTimes = 10; + _logger.LogInformation("我数到{num},动作快点", waitTimes); + for (int i = 0; i < waitTimes; i++) + { + _logger.LogInformation("[{num}]等待扫描...", i + 1); + + Task.Delay(5 * 1000).Wait(); + + var check = _passportApi.CheckQrCodeHasScaned(re.Data.Qrcode_key).Result; + if (check.Code != 0) + { + _logger.LogWarning("调用检查接口异常:{msg}", check.ToJson()); + break; + } + + if (check.Data.Code == 86038)//已失效 + { + _logger.LogInformation(check.Data.Message); + break; + } + + if (check.Data.Code == 0) + { + _logger.LogInformation("扫描成功!"); + cookieInfo = GetCookie(check.Data.Url); + result = true; + break; + } + + _logger.LogInformation("{msg}", check.Data.Message + Environment.NewLine); + } + + return result; + } + + + [TaskInterceptor("添加ck到json配置文件", TaskLevel.Two)] + protected void AddOrUpdateCkToJson(BiliCookie ckInfo) + { + //读取json + var path = _hostingEnvironment.ContentRootPath; + var indexOfBin = path.LastIndexOf("bin"); + if (indexOfBin != -1) path = path.Substring(0, indexOfBin); + var fileProvider = new PhysicalFileProvider(path); + IFileInfo fileInfo = fileProvider.GetFileInfo("cookies.json"); + _logger.LogInformation("目标json地址:{path}", fileInfo.PhysicalPath); + + if (!fileInfo.Exists) + { + using (var stream = File.Create(fileInfo.PhysicalPath)) + { + using (var sw = new StreamWriter(stream)) + { + sw.Write($"{{{Environment.NewLine}}}"); + } + } + } + + string json; + using (var stream = new FileStream(fileInfo.PhysicalPath, FileMode.Open)) + { + using var reader = new StreamReader(stream); + json = reader.ReadToEnd(); + } + var lines = json.Split(Environment.NewLine).ToList(); + + var indexOfCkConfigKey = lines.FindIndex(x => x.TrimStart().StartsWith("\"BiliBiliCookies\"")); + if (indexOfCkConfigKey == -1) + { + _logger.LogInformation("未配置过cookie,初始化并新增"); + + var indexOfInsert = lines.FindIndex(x => x.TrimStart().StartsWith("{")); + lines.InsertRange(indexOfInsert + 1, new List() + { + " \"BiliBiliCookies\":[", + $@" ""{ckInfo.CookieStr}"",", + " ]," + }); + + SaveJson(lines, fileInfo); + _logger.LogInformation("新增成功!"); + return; + } + + ckInfo.CookieItemDictionary.TryGetValue("DedeUserID", out string userId); + userId ??= ckInfo.CookieStr; + var indexOfCkConfigEnd = lines.FindIndex(indexOfCkConfigKey, x => x.TrimStart().StartsWith("]")); + var indexOfTargetCk = lines.FindIndex(indexOfCkConfigKey, + indexOfCkConfigEnd - indexOfCkConfigKey, + x => x.Contains(userId) && !x.TrimStart().StartsWith("//")); + + if (indexOfTargetCk == -1) + { + _logger.LogInformation("不存在该用户,新增cookie"); + lines.Insert(indexOfCkConfigEnd, $@" ""{ckInfo.CookieStr}"","); + SaveJson(lines, fileInfo); + _logger.LogInformation("新增成功!"); + return; + } + + _logger.LogInformation("已存在该用户,更新cookie"); + lines[indexOfTargetCk] = $@" ""{ckInfo.CookieStr}"","; + SaveJson(lines, fileInfo); + _logger.LogInformation("更新成功!"); + } + + [TaskInterceptor("添加ck到青龙环境变量", TaskLevel.Two)] + protected void AddOrUpdateCkToQingLong(BiliCookie ckInfo) + { + //拿token + var suc = GetToken(out string token); + + if (!suc) return; + + token = $"Bearer {token}"; + + //查env + var re = _qingLongApi.GetEnvs("Ray_BiliBiliCookies__", token).Result; + + if (re.Code != 200) + { + _logger.LogInformation($"查询环境变量失败:{re}", re.ToJson()); + return; + } + + var list = re.Data.OrderBy(x => x.id); + QingLongEnv oldEnv = list.FirstOrDefault(x => x.value.Contains(ckInfo.UserId)); + + if (oldEnv != null) + { + _logger.LogInformation("用户已存在,更新cookie"); + var update = new UpdateQingLongEnv() + { + id = oldEnv.id, + name = oldEnv.name, + value = ckInfo.CookieStr, + remarks = oldEnv.remarks, + }; + + var updateRe = _qingLongApi.UpdateEnvs(update, token).Result; + if (updateRe.Code == 200) _logger.LogInformation("更新成功!"); + else _logger.LogInformation(updateRe.ToJson()); + + return; + } + + _logger.LogInformation("用户不存在,新增cookie"); + var lastNum = list.LastOrDefault()?.value.Split("__").LastOrDefault(); + var newNum = int.Parse(lastNum ?? "-1") + 1; + var name = $"Ray_BiliBiliCookies__{newNum}"; + + var add = new AddQingLongEnv() + { + name = name, + value = ckInfo.CookieStr, + remarks = "" + }; + var addRe = _qingLongApi.AddEnvs(new List() { add }, token).Result; + if (addRe.Code == 200) _logger.LogInformation("新增成功!"); + else _logger.LogInformation(addRe.ToJson()); + + return; + } + + private void GenerateQrCode(string str) + { + var qrGenerator = new QRCodeGenerator(); + QRCodeData qrCodeData = qrGenerator.CreateQrCode(str, QRCodeGenerator.ECCLevel.L); + + _logger.LogInformation("AsciiQRCode:"); + //var qrCode = new AsciiQRCode(qrCodeData); + //var qrCodeStr = qrCode.GetGraphic(1, drawQuietZones: false); + //_logger.LogInformation(Environment.NewLine + qrCodeStr); + + //Console.WriteLine("Console:"); + //Print(qrCodeData); + PrintSmall(qrCodeData); + } + + private void Print(QRCodeData qrCodeData) + { + Console.BackgroundColor = ConsoleColor.White; + for (int i = 0; i < qrCodeData.ModuleMatrix.Count + 2; i++) Console.Write(" ");//中文全角的空格符 + Console.WriteLine(); + for (int j = 0; j < qrCodeData.ModuleMatrix.Count; j++) + { + for (int i = 0; i < qrCodeData.ModuleMatrix.Count; i++) + { + //char charToPoint = qrCode.Matrix[i, j] ? '█' : ' '; + Console.Write(i == 0 ? " " : "");//中文全角的空格符 + Console.BackgroundColor = qrCodeData.ModuleMatrix[i][j] ? ConsoleColor.Black : ConsoleColor.White; + Console.Write(' ');//中文全角的空格符 + Console.BackgroundColor = ConsoleColor.White; + Console.Write(i == qrCodeData.ModuleMatrix.Count - 1 ? " " : "");//中文全角的空格符 + } + Console.WriteLine(); + } + for (int i = 0; i < qrCodeData.ModuleMatrix.Count + 2; i++) Console.Write(" ");//中文全角的空格符 + + Console.WriteLine(); + } + + private void PrintSmall(QRCodeData qrCodeData) + { + //黑黑(" ") + //白白("█") + //黑白("▄") + //白黑("▀") + var dic = new Dictionary() + { + {"11", ' '}, + {"00", '█'}, + {"10", '▄'}, + {"01", '▀'},//todo:win平台的cmd会显示?,是已知问题,待想办法解决 + //{"01", '^'},//▼▔ + }; + + var count = qrCodeData.ModuleMatrix.Count; + + var list = new List(); + for (int rowNum = 0; rowNum < count; rowNum++) + { + var rowStr = ""; + for (int colNum = 0; colNum < count; colNum++) + { + var num = qrCodeData.ModuleMatrix[colNum][rowNum] ? "1" : "0"; + var numDown = "0"; + if (rowNum + 1 < count) + numDown = qrCodeData.ModuleMatrix[colNum][rowNum + 1] ? "1" : "0"; + + rowStr += dic[num + numDown]; + } + list.Add(rowStr); + rowNum++; + } + + _logger.LogInformation(Environment.NewLine + string.Join(Environment.NewLine, list)); + } + + private string GetOnlinePic(string str) + { + var encode = System.Web.HttpUtility.UrlEncode(str); ; + return $"https://tool.lu/qrcode/basic.html?text={encode}"; + } + + private BiliCookie GetCookie(string url) + { + var ckItemList = url.Split('?')[1] + .Split("&gourl=")[0] + .Split('&') + .ToList(); + var ckStr = string.Join(';', ckItemList); + var biliCk = new BiliCookie(new List() { ckStr }); + + biliCk.Check(); + return biliCk; + } + + private void SaveJson(List lines, IFileInfo fileInfo) + { + var newJson = string.Join(Environment.NewLine, lines); + + using (var sw = new StreamWriter(fileInfo.PhysicalPath)) + { + sw.Write(newJson); + } + } + + #region qinglong + + private bool GetToken(out string token) + { + token = ""; + + var qlDir = _configuration["QL_DIR"] ?? "/ql"; + var authFile = Path.Combine(qlDir, "data/config/auth.json"); + + if (!File.Exists(authFile)) return false; + + var authJson = File.ReadAllText(authFile); + + var jb = JsonConvert.DeserializeObject(authJson); + token = jb["token"].ToString(); + + return true; + } + + #endregion + } +} diff --git a/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj b/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj index 9de70e91c..65607513b 100644 --- a/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj +++ b/src/Ray.BiliBiliTool.Application/Ray.BiliBiliTool.Application.csproj @@ -6,8 +6,10 @@ + + diff --git a/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationProvider.cs b/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationProvider.cs index d72123f42..e6aaa0064 100644 --- a/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationProvider.cs +++ b/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationProvider.cs @@ -13,13 +13,15 @@ namespace Ray.BiliBiliTool.Config /// public class EnvironmentVariablesExcludeEmptyConfigurationProvider : EnvironmentVariablesConfigurationProvider { + private readonly bool _removeKeyPrefix; private readonly string _prefix; private readonly Func, bool> _startsWith; private readonly Func, bool> _removeNullValue; private readonly Func, bool> _fifter; - public EnvironmentVariablesExcludeEmptyConfigurationProvider(string prefix = null) : base(prefix) + public EnvironmentVariablesExcludeEmptyConfigurationProvider(string prefix = null, bool removeKeyPrefix = true) : base(prefix) { + _removeKeyPrefix = removeKeyPrefix; _prefix = prefix ?? string.Empty; _startsWith = c => c.Key.StartsWith(prefix, StringComparison.OrdinalIgnoreCase); @@ -44,7 +46,7 @@ public override void Load() /// private string NormalizeKey(string key) { - key = RemoveKeyPrefix(key); + if(_removeKeyPrefix) key = RemoveKeyPrefix(key); key = ReplaceKeyDelimiter(key); return key; } diff --git a/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationSource.cs b/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationSource.cs index 263c0bf6f..fea853940 100644 --- a/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationSource.cs +++ b/src/Ray.BiliBiliTool.Config/EnvironmentVariablesExcludeEmptyConfigurationSource.cs @@ -16,9 +16,11 @@ public class EnvironmentVariablesExcludeEmptyConfigurationSource : IConfiguratio { public string Prefix { get; set; } + public bool RemoveKeyPrefix { get; set; } + public IConfigurationProvider Build(IConfigurationBuilder builder) { - return new EnvironmentVariablesExcludeEmptyConfigurationProvider(Prefix); + return new EnvironmentVariablesExcludeEmptyConfigurationProvider(Prefix, RemoveKeyPrefix); } } } diff --git a/src/Ray.BiliBiliTool.Config/Extensions/ConfigurationBuilderExtension.cs b/src/Ray.BiliBiliTool.Config/Extensions/ConfigurationBuilderExtension.cs index 5264eba75..4271c1030 100644 --- a/src/Ray.BiliBiliTool.Config/Extensions/ConfigurationBuilderExtension.cs +++ b/src/Ray.BiliBiliTool.Config/Extensions/ConfigurationBuilderExtension.cs @@ -25,9 +25,10 @@ public static IConfigurationBuilder AddExcludeEmptyEnvironmentVariables(this ICo /// The . public static IConfigurationBuilder AddExcludeEmptyEnvironmentVariables( this IConfigurationBuilder configurationBuilder, - string prefix) + string prefix, + bool removeKeyPrefix = true) { - configurationBuilder.Add(new EnvironmentVariablesExcludeEmptyConfigurationSource { Prefix = prefix }); + configurationBuilder.Add(new EnvironmentVariablesExcludeEmptyConfigurationSource { Prefix = prefix, RemoveKeyPrefix = removeKeyPrefix }); return configurationBuilder; } @@ -40,4 +41,4 @@ public static IConfigurationBuilder AddExcludeEmptyEnvironmentVariables( public static IConfigurationBuilder AddExcludeEmptyEnvironmentVariables(this IConfigurationBuilder builder, Action configureSource) => builder.Add(configureSource); } -} \ No newline at end of file +} diff --git a/src/Ray.BiliBiliTool.Console/BiliBiliToolHostedService.cs b/src/Ray.BiliBiliTool.Console/BiliBiliToolHostedService.cs index 048e3b2f5..885022e72 100644 --- a/src/Ray.BiliBiliTool.Console/BiliBiliToolHostedService.cs +++ b/src/Ray.BiliBiliTool.Console/BiliBiliToolHostedService.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading; @@ -20,6 +19,7 @@ public class BiliBiliToolHostedService : IHostedService { private readonly IHostApplicationLifetime _applicationLifetime; private readonly IServiceProvider _serviceProvider; + private readonly IHostEnvironment _environment; private readonly IConfiguration _configuration; private readonly ILogger _logger; private readonly CookieStrFactory _cookieStrFactory; @@ -28,6 +28,7 @@ public class BiliBiliToolHostedService : IHostedService public BiliBiliToolHostedService( IHostApplicationLifetime applicationLifetime , IServiceProvider serviceProvider + , IHostEnvironment environment , IConfiguration configuration , ILogger logger , CookieStrFactory cookieStrFactory @@ -35,6 +36,7 @@ IHostApplicationLifetime applicationLifetime { _applicationLifetime = applicationLifetime; _serviceProvider = serviceProvider; + _environment = environment; _configuration = configuration; _logger = logger; _cookieStrFactory = cookieStrFactory; @@ -57,26 +59,34 @@ public Task StartAsync(CancellationToken cancellationToken) var tasks = _configuration["RunTasks"] .Split("&", options: StringSplitOptions.RemoveEmptyEntries); - for (int i = 0; i < _cookieStrFactory.Count; i++) + if (tasks.Contains("Login")) { - _cookieStrFactory.CurrentNum = i + 1; - _logger.LogInformation("######### 账号 {num} #########{newLine}", _cookieStrFactory.CurrentNum, Environment.NewLine); + DoTasks(tasks); + } - try + else + { + for (int i = 0; i < _cookieStrFactory.Count; i++) { - DoTasks(tasks); - if (isNotifySingle) - { - LogAppInfo(); + _cookieStrFactory.CurrentNum = i + 1; + _logger.LogInformation("######### 账号 {num} #########{newLine}", _cookieStrFactory.CurrentNum, Environment.NewLine); - var accountName = _cookieStrFactory.Count > 1 ? $"账号【{_cookieStrFactory.CurrentNum}】" : ""; - _logger.LogInformation("·开始推送·{task}·{user}", $"{_configuration["RunTasks"]}任务", accountName); + try + { + DoTasks(tasks); + if (isNotifySingle) + { + LogAppInfo(); + + var accountName = _cookieStrFactory.Count > 1 ? $"账号【{_cookieStrFactory.CurrentNum}】" : ""; + _logger.LogInformation("·开始推送·{task}·{user}", $"{_configuration["RunTasks"]}任务", accountName); + } + } + catch (Exception e) + { + //ignore + _logger.LogWarning("异常:{msg}", e); } - } - catch (Exception e) - { - //ignore - _logger.LogWarning("异常:{msg}", e); } } } @@ -92,6 +102,9 @@ public Task StartAsync(CancellationToken cancellationToken) LogAppInfo(); _logger.LogInformation("·开始推送·{task}·{user}", $"{_configuration["RunTasks"]}任务", ""); } + //环境 + _logger.LogInformation("运行环境:{env}", _environment.EnvironmentName); + _logger.LogInformation("应用目录:{path}{newLine}", _environment.ContentRootPath, Environment.NewLine); _logger.LogInformation("运行结束"); _applicationLifetime.StopApplication(); } @@ -113,7 +126,7 @@ private bool PreCheck() //Cookie _logger.LogInformation("【账号个数】{count}个{newLine}", _cookieStrFactory.Count, Environment.NewLine); - if (_cookieStrFactory.Count == 0) return false; + if (_cookieStrFactory.Count == 0 && !tasks.Contains("Login")) return false; //是否跳过 if (_securityOptions.IsSkipDailyTask) diff --git a/src/Ray.BiliBiliTool.Console/Program.cs b/src/Ray.BiliBiliTool.Console/Program.cs index 4dbb96baf..bb649ddad 100644 --- a/src/Ray.BiliBiliTool.Console/Program.cs +++ b/src/Ray.BiliBiliTool.Console/Program.cs @@ -76,6 +76,7 @@ internal static IHostBuilder CreateHostBuilder(string[] args) } //环境变量: + configurationBuilder.AddExcludeEmptyEnvironmentVariables("QL_", false); configurationBuilder.AddExcludeEmptyEnvironmentVariables("Ray_"); //命令行: @@ -85,6 +86,9 @@ internal static IHostBuilder CreateHostBuilder(string[] args) .GetSection("CommandLineMappings") .Get>()); } + + //本地cookie存储文件 + configurationBuilder.AddJsonFile("cookies.json", true, true); }); //日志: diff --git a/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj b/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj index 7b01192d7..cc6d544eb 100644 --- a/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj +++ b/src/Ray.BiliBiliTool.Console/Ray.BiliBiliTool.Console.csproj @@ -90,6 +90,9 @@ PreserveNewest + + PreserveNewest + diff --git a/src/Ray.BiliBiliTool.Console/appsettings.json b/src/Ray.BiliBiliTool.Console/appsettings.json index a9103aac4..6ad77d850 100644 --- a/src/Ray.BiliBiliTool.Console/appsettings.json +++ b/src/Ray.BiliBiliTool.Console/appsettings.json @@ -1,7 +1,7 @@ { //Cookie集合,取自浏览器,必填 "BiliBiliCookies": [ //Cookie字符串集合,登录bilibili后F12获取,形如"_uuid=abcd; buvid3=1234; sid=abc123" - "" + "", ], "RunTasks": "Daily", //要运行的任务名称[Daily,LiveLottery,UnfollowBatched,VipBigPoint,Test],多个使用&分隔,如“Daily&LiveLottery”,建议使用命令行参数指定 diff --git a/src/Ray.BiliBiliTool.Infrastructure/Cookie/CookieInfo.cs b/src/Ray.BiliBiliTool.Infrastructure/Cookie/CookieInfo.cs index 0021ad57c..ff9e25ac5 100644 --- a/src/Ray.BiliBiliTool.Infrastructure/Cookie/CookieInfo.cs +++ b/src/Ray.BiliBiliTool.Infrastructure/Cookie/CookieInfo.cs @@ -26,6 +26,19 @@ public CookieInfo(string cookieStr) } } + public CookieInfo(List cookieItemList) + { + CookieItemList=cookieItemList ?? new List(); + foreach (var item in CookieItemList) + { + var list = item.Split('='); + if (list.Length >= 2) + CookieItemDictionary.TryAdd(list[0].Trim(), list[1].Trim()); + } + + CookieStr = string.Join(';', CookieItemList); + } + public string CookieStr { get; set; } public List CookieItemList { get; set; } diff --git a/src/Ray.BiliBiliTool.Infrastructure/Enums/PlateformType.cs b/src/Ray.BiliBiliTool.Infrastructure/Enums/PlateformType.cs index adac3bd13..47991555c 100644 --- a/src/Ray.BiliBiliTool.Infrastructure/Enums/PlateformType.cs +++ b/src/Ray.BiliBiliTool.Infrastructure/Enums/PlateformType.cs @@ -10,6 +10,7 @@ public enum PlateformType { Unknown, GitHubActions, - Docker + Docker, + QingLong } }