1 Star 0 Fork 1

Free/tencentKeTang

forked from 吴昊/tencentKeTang 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
main.go 6.74 KB
一键复制 编辑 原始数据 按行查看 历史
人渣29 提交于 2021-06-18 16:15 . feat:增加通过url解析获取cid/tid
package main
import (
"crawler/tencentKeTang/config"
"crawler/tencentKeTang/internal/httplib"
"crawler/tencentKeTang/pcsliner"
"crawler/tencentKeTang/pcsliner/args"
"crawler/tencentKeTang/project"
"fmt"
"github.com/peterh/liner"
"github.com/pkg/errors"
"github.com/urfave/cli/v2"
"log"
"net/url"
"os"
"strconv"
"strings"
)
var (
Version = "Not Found"
)
func main() {
myApp := config.NewApp()
//设置日志
httplib.SetDebug(myApp.Config.App.Debug)
//启动程序
app := cli.NewApp()
app.Name = "TencentKeTang"
app.Version = Version
app.Description = "腾讯课堂视频下载工具"
app.Authors = []*cli.Author{
{
Name: "HarryWRZ",
Email: "wrz890829@gmail.com",
},
}
app.Action = func(c *cli.Context) error {
if c.NArg() != 0 {
return fmt.Errorf("未找到命令: %s\n运行命令 %s help 获取帮助\n", c.Args().Get(0), app.Name)
}
var (
line = pcsliner.NewLiner()
)
if myApp.Config.Http.Cookie == "" {
log.Println("配置文件中未找到cookie,可输入`login -h`查看登录命令")
}
for {
var (
prompt string
activeUser string
)
if un, ok := c.App.Metadata["user_name"]; ok && un != nil {
activeUser = un.(string)
}
if activeUser != "" {
prompt = app.Name + ":" + activeUser + "$ "
} else {
// TencentKeTang >
prompt = app.Name + " > "
}
commandLine, err := line.State.Prompt(prompt)
switch err {
case liner.ErrPromptAborted:
return nil
case nil:
// continue
default:
return err
}
cmdArgs := args.Parse(commandLine)
if len(cmdArgs) == 0 {
continue
}
s := []string{os.Args[0]}
s = append(s, cmdArgs...)
// 恢复原始终端状态
// 防止运行命令时程序被结束, 终端出现异常
line.Pause()
err = c.App.Run(s)
if err != nil {
fmt.Println(err)
}
line.Resume()
}
}
app.Commands = []*cli.Command{
{
Name: "login",
Usage: "登录课堂",
Description: `
登录腾讯课堂
示例:
tencentKeTang login 123 456 #qq帐号密码登录,暂未支持
tencentKeTang login -type 1 -user_name=123 #qq帐号密码登录,暂未支持
tencentKeTang login -type 2 #qq扫码登录,暂未支持
tencentKeTang login -type 3 #微信扫码登录
`,
Action: func(context *cli.Context) error {
myApp.Project.SetCookie("")
myApp.KeTang.SetCookie(nil)
nickName := ""
var err error
switch context.Int64("type") {
case 1:
log.Println("帐号密码登录,暂未支持")
case 2:
nickName, err = myApp.Project.QQQRLogin()
if err != nil {
return errors.Wrap(err, "QQQrLogin")
}
case 3:
err = myApp.Project.WxQRLogin()
if err == project.ErrExpire {
return fmt.Errorf("登录码超时,请重新申请")
}
resp, err := myApp.KeTang.Info()
if err != nil {
return err
}
nickName = resp.NickName
default:
log.Println("帐号密码登录,暂未支持")
}
log.Printf("登录成功,欢迎%s使用本程序(请自行关闭二维码)", nickName)
context.App.Metadata["user_name"] = nickName
return nil
},
Flags: []cli.Flag{
&cli.Int64Flag{
Name: "type",
Usage: "登录方式",
},
},
},
{
Name: "tree",
Aliases: []string{"t"},
Usage: "列目录",
UsageText: app.Name + " tree -c 123 -t 456",
Description: `
列出指定cid/term下所有章节与文件(暂时直接只支持单个cid)
也可解析url获取cid与termID(暂时只支持两种格式的链接)
示例:
TencentKeTang tree -c 123 -t 456 (获取123中的456term)
TencentKeTang t -c 123 (获取123中所有视频)
TencentKeTang t -u https://ke.qq.com/course/123?taid=1234
TencentKeTang t -u https://ke.qq.com/webcourse/index.html#cid=1111&term_id=2222&taid=3333&type=4444&vid=55555
`,
Action: func(context *cli.Context) error {
var cid string
var tid int64
switch true {
case context.IsSet("cid"):
cid = context.String("cid")
tid = context.Int64("tid")
case context.IsSet("url"):
u, err := url.Parse(context.String("url"))
if err != nil {
return errors.Wrap(err, "url.Parse")
}
//看query中是否有cid
v, err := url.ParseQuery(u.Fragment)
if err != nil {
return errors.Wrap(err, "url.ParseQuery")
}
cid = v.Get("cid")
if cid == "" {
//query中不存在cid,则通过path部分获取
split := strings.Split(u.Path, "/")
if len(split) == 0 {
return errors.New("请确认url格式")
}
cid = split[len(split)-1]
} else {
//从query获取tid
termID := v.Get("term_id")
if termID != "" {
tid, err = strconv.ParseInt(termID, 10, 64)
if err != nil {
return errors.Wrap(err, "strconv.ParseInt")
}
}
}
default:
return errors.New("请填写参数,可输入tree -h查看详情")
}
//获取章节列表
list, err := myApp.Project.GetCatalogue(cid, tid)
if err != nil {
return err
}
for i, l := range list {
fmt.Printf("[%d] ", i+1)
for j := 0; j < int(l.Depth); j++ {
fmt.Printf("\t")
}
fmt.Println(l.Name)
}
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "cid",
Usage: "通过cid下载",
Aliases: []string{"c"},
},
&cli.StringFlag{
Name: "url",
Usage: "通过url解析必要参数",
Aliases: []string{"u"},
},
&cli.Int64Flag{
Name: "tid",
Usage: "通过cid中的termID过滤",
Aliases: []string{"t"},
},
},
},
{
Name: "download",
Aliases: []string{"d"},
Usage: "下载文件",
UsageText: app.Name + " download <cid>",
Description: `
下载文件默认保存到当前目录的download目录
可输入cid直接下载全部内容
若不填写 flag 则通过tree中的序号下载(支持多序号下载)
示例:
TencentKeTang d -c 123456
TencentKeTang d 1
TencentKeTang d 1 2 3 4
`,
Action: func(context *cli.Context) error {
var err error
switch true {
case context.IsSet("cid"):
err = myApp.Project.DownLoadByCID(context.String("cid"))
default:
for _, s := range context.Args().Slice() {
var index int64
index, err = strconv.ParseInt(s, 10, 64)
if err != nil {
return errors.Wrap(err, "strconv.ParseInt")
}
err = myApp.Project.DownLoadByIndex(index - 1)
if err != nil {
break
}
}
}
if err != nil {
return errors.Wrap(err, "myApp.Project.DownLoad*")
}
return nil
},
Flags: []cli.Flag{
&cli.StringFlag{
Name: "cid",
Usage: "通过cid下载",
Aliases: []string{"c"},
},
},
},
}
app.Run(os.Args)
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/lxbase/tencentKeTang.git
git@gitee.com:lxbase/tencentKeTang.git
lxbase
tencentKeTang
tencentKeTang
main

搜索帮助