-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
monigo
committed
Dec 2, 2019
1 parent
32fc63f
commit 6abdc5c
Showing
3 changed files
with
353 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"errors" | ||
"fmt" | ||
log "github.com/sirupsen/logrus" | ||
"github.com/vouv/srun/core" | ||
"github.com/vouv/srun/model" | ||
"github.com/vouv/srun/pkg/term" | ||
"github.com/vouv/srun/store" | ||
"io" | ||
"os" | ||
"runtime" | ||
"strings" | ||
) | ||
|
||
var ErrReadAccount = errors.New("读取账号文件错误, 请执行`srun config`配置账号信息") | ||
|
||
type Func func(cmd string, params ...string) | ||
|
||
var DefaultClient = &Client{} | ||
|
||
type Client struct{} | ||
|
||
var serverTypes = map[string]string{ | ||
"xyw": model.ServerTypeOrigin, | ||
"yd": model.ServerTypeCMCC, | ||
"lt": model.ServerTypeWCDMA, | ||
} | ||
|
||
// 登录 | ||
func (s *Client) Login(cmd string, params ...string) { | ||
account, gErr := store.ReadAccount() | ||
if gErr != nil { | ||
log.Error(ErrReadAccount.Error()) | ||
log.Debug(gErr) | ||
os.Exit(1) | ||
} | ||
|
||
if len(params) != 0 { | ||
if t, ok := serverTypes[params[0]]; ok { | ||
account.Server = t | ||
} else { | ||
s.CmdList() | ||
return | ||
} | ||
} | ||
log.Info("尝试登录: ", account.Server) | ||
|
||
//username = model.AddSuffix(username, server) | ||
info, err := core.Login(&account) | ||
if err != nil { | ||
log.Error(err) | ||
os.Exit(1) | ||
} | ||
log.Info("登录成功!") | ||
log.Info("在线IP: ", info.ClientIp) | ||
|
||
err = store.SetInfo(info.AccessToken, info.ClientIp) | ||
if err != nil { | ||
log.Error(err) | ||
os.Exit(1) | ||
} | ||
} | ||
|
||
func (s *Client) Logout(cmd string, params ...string) { | ||
if len(params) == 0 { | ||
var err error | ||
account, err := store.ReadAccount() | ||
if err != nil { | ||
log.Error(ErrReadAccount.Error()) | ||
log.Debug(err) | ||
os.Exit(1) | ||
} | ||
if err = core.Logout(account.Username); err != nil { | ||
log.Error(err) | ||
os.Exit(1) | ||
} | ||
log.Info("注销成功!") | ||
} else { | ||
s.CmdList() | ||
} | ||
} | ||
|
||
func (s *Client) GetInfo(cmd string, params ...string) { | ||
if len(params) == 0 { | ||
var err error | ||
account, err := store.ReadAccount() | ||
if err != nil { | ||
log.Error(ErrReadAccount.Error()) | ||
log.Debug(err) | ||
os.Exit(1) | ||
} | ||
log.Info("当前校园网登录账号:", account.Username) | ||
if err = core.Info(account); err != nil { | ||
log.Error(err) | ||
os.Exit(1) | ||
} | ||
} else { | ||
s.CmdList() | ||
} | ||
} | ||
|
||
func (Client) SetAccount(cmd string, params ...string) { | ||
|
||
in := os.Stdin | ||
fmt.Print("设置校园网账号:\n>") | ||
username := readInput(in) | ||
|
||
// 终端API | ||
fd, _ := term.GetFdInfo(in) | ||
oldState, err := term.SaveState(fd) | ||
if err != nil { | ||
log.Error(err) | ||
os.Exit(1) | ||
} | ||
fmt.Print("设置校园网密码:\n>") | ||
|
||
// read in stdin | ||
_ = term.DisableEcho(fd, oldState) | ||
pwd := readInput(in) | ||
_ = term.RestoreTerminal(fd, oldState) | ||
|
||
fmt.Println() | ||
|
||
setServer: | ||
fmt.Print("设置默认登录模式( 校园网(默认): 1 | 移动: 2 | 联通: 3 )\n>") | ||
server := readInput(in) | ||
switch server { | ||
case "", "1": | ||
server = model.ServerTypeOrigin | ||
case "2": | ||
server = model.ServerTypeCMCC | ||
case "3": | ||
server = model.ServerTypeWCDMA | ||
default: | ||
goto setServer | ||
} | ||
|
||
// trim | ||
username = strings.TrimSpace(username) | ||
pwd = strings.TrimSpace(pwd) | ||
|
||
if err := store.SetAccount(username, pwd, server); err != nil { | ||
log.Error(err) | ||
os.Exit(1) | ||
} | ||
log.Info("账号密码已被保存") | ||
} | ||
|
||
func readInput(in io.Reader) string { | ||
reader := bufio.NewReader(in) | ||
line, _, err := reader.ReadLine() | ||
if err != nil { | ||
panic(err) | ||
} | ||
return string(line) | ||
} | ||
|
||
func (Client) ShowVersion() { | ||
fmt.Println("System:") | ||
fmt.Printf("\tOS:%s ARCH:%s GOVERSION:%s\n", runtime.GOOS, runtime.GOARCH, runtime.Version()) | ||
fmt.Println("About:") | ||
fmt.Printf("\tVersion:%s\n", Version) | ||
fmt.Println("\n\t</> with ❤ By vouv") | ||
} | ||
|
||
// srun help [COMMAND] | ||
func (s *Client) CmdHelp(cmd string, params ...string) { | ||
if len(params) == 0 { | ||
fmt.Println(s.CmdList()) | ||
} else { | ||
if c, ok := cmdDocs[params[0]]; ok { | ||
fmt.Println("Usage: ", c[0]) | ||
} else { | ||
fmt.Println(s.CmdList()) | ||
} | ||
} | ||
} | ||
|
||
func (Client) CmdList() string { | ||
sb := &strings.Builder{} | ||
sb.WriteString(fmt.Sprint("\r\nUsage: srun [OPTIONS] COMMAND \r\n\r\n")) | ||
|
||
sb.WriteString("A efficient client for BIT campus network\r\n\r\n") | ||
|
||
sb.WriteString("Options:\r\n") | ||
for k, v := range optionDocs { | ||
sb.WriteString(fmt.Sprintf(" %-10s%-20s\r\n", k, v)) | ||
} | ||
|
||
sb.WriteString("\r\nCommands:\r\n") | ||
for k, v := range cmdDocs { | ||
sb.WriteString(fmt.Sprintf(" %-10s%-20s\r\n", k, v[1])) | ||
} | ||
return sb.String() | ||
} | ||
|
||
func (Client) Update(cmd string, params ...string) { | ||
ok, v, d := HasUpdate() | ||
if !ok { | ||
log.Info("当前已是最新版本:", Version) | ||
return | ||
} | ||
log.Info("发现新版本: ", v, "当前版本: ", Version) | ||
log.Info("打开链接下载: ", d) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package main | ||
|
||
import ( | ||
"flag" | ||
log "github.com/sirupsen/logrus" | ||
"net/http" | ||
"os" | ||
"time" | ||
) | ||
|
||
const ( | ||
Version = "v0.1.14" | ||
Timeout = 3 * time.Second | ||
) | ||
|
||
var LogLevel = log.InfoLevel | ||
|
||
var CommandMap = map[string]Func{ | ||
"config": DefaultClient.SetAccount, | ||
"login": DefaultClient.Login, | ||
"logout": DefaultClient.Logout, | ||
"info": DefaultClient.GetInfo, | ||
"update": DefaultClient.Update, | ||
|
||
"help": DefaultClient.CmdHelp, | ||
} | ||
|
||
var optionDocs = map[string]string{ | ||
"-d": "Show debug message", | ||
"-v": "Print version information and quit", | ||
"-h": "Show help", | ||
} | ||
|
||
var cmdDocs = map[string][]string{ | ||
"config": {"srun config", "Set Username and Password"}, | ||
"login": {"srun [login] [xyw|yd|lt]", "Login Srun"}, | ||
"logout": {"srun logout", "Logout Srun"}, | ||
"info": {"srun info", "Get Srun Info"}, | ||
"update": {"srun update", "Update srun"}, | ||
} | ||
|
||
func main() { | ||
var debugMode bool | ||
var helpMode bool | ||
var versionMode bool | ||
|
||
flag.BoolVar(&debugMode, "d", false, "debug mode") | ||
flag.BoolVar(&helpMode, "h", false, "show help") | ||
flag.BoolVar(&versionMode, "v", false, "show version") | ||
|
||
flag.Parse() | ||
|
||
var cmd string | ||
var params []string | ||
|
||
args := flag.Args() | ||
if len(args) > 0 { | ||
cmd = args[0] | ||
params = args[1:] | ||
} else { | ||
cmd = "login" | ||
} | ||
|
||
switch { | ||
case helpMode: | ||
DefaultClient.CmdHelp(cmd, args...) | ||
return | ||
case versionMode: | ||
DefaultClient.ShowVersion() | ||
return | ||
case debugMode: | ||
LogLevel = log.DebugLevel | ||
} | ||
|
||
// config | ||
http.DefaultClient.Timeout = Timeout | ||
log.SetOutput(os.Stdout) | ||
log.SetLevel(LogLevel) | ||
log.SetFormatter(&log.TextFormatter{ | ||
//DisableTimestamp: true, | ||
TimestampFormat: "2006-01-02 15:04:05", | ||
FullTimestamp: true, | ||
}) | ||
|
||
if handle, ok := CommandMap[cmd]; ok { | ||
handle(cmd, params...) | ||
} else { | ||
DefaultClient.CmdHelp(cmd, params...) | ||
} | ||
|
||
// has update | ||
// todo 修改更新逻辑, 减少更新频率 | ||
//if ok, repo := cli.HasUpdate(); ok { | ||
// fmt.Print("更新: " + repo) | ||
// fmt.Println(" 当前版本: " + config.Version) | ||
//} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
log "github.com/sirupsen/logrus" | ||
"net" | ||
"net/http" | ||
"strings" | ||
"time" | ||
) | ||
|
||
const repo = "https://github.com/vouv/srun/releases/latest" | ||
const updateTimeout = 3 * time.Second | ||
|
||
var client = http.Transport{ | ||
DialContext: func(ctx context.Context, network, addr string) (conn net.Conn, e error) { | ||
conn, err := net.DialTimeout(network, addr, updateTimeout) | ||
if err != nil { | ||
return nil, err | ||
} | ||
_ = conn.SetDeadline(time.Now().Add(updateTimeout)) | ||
return conn, nil | ||
}, | ||
} | ||
|
||
func HasUpdate() (ok bool, version string, dist string) { | ||
req, err := http.NewRequest("GET", repo, nil) | ||
|
||
if err != nil { | ||
log.Debug("请求错误", err) | ||
return | ||
} | ||
res, err := client.RoundTrip(req) | ||
if err != nil { | ||
log.Debug("请求错误", err) | ||
return | ||
} | ||
dist = res.Header.Get("Location") | ||
arr := strings.Split(dist, "/") | ||
version = arr[len(arr)-1] | ||
|
||
log.Debug("最新版本", version) | ||
|
||
ok = version != Version | ||
return | ||
|
||
} |