Finish the feature of share and bridge.

This commit is contained in:
zicla
2019-04-29 21:14:29 +08:00
parent ca721c78e6
commit d75c4a222e
20 changed files with 605 additions and 330 deletions

View File

@ -0,0 +1,256 @@
package support
import (
"flag"
"fmt"
"github.com/eyebluecn/tank/code/core"
"github.com/eyebluecn/tank/code/tool/result"
"github.com/eyebluecn/tank/code/tool/util"
jsoniter "github.com/json-iterator/go"
"golang.org/x/crypto/ssh/terminal"
"io/ioutil"
"log"
"net/http"
"net/url"
"strings"
"syscall"
)
const (
//启动web服务默认是这种方式
MODE_WEB = "web"
//映射本地文件到云盘中
MODE_MIRROR = "mirror"
//将远程的一个文件爬取到蓝眼云盘中
MODE_CRAWL = "crawl"
)
//命令行输入相关的对象
type TankApplication struct {
//模式
mode string
//蓝眼云盘的主机,需要带上协议和端口号。默认: http://127.0.0.1:core.DEFAULT_SERVER_PORT
host string
//用户名
username string
//密码
password string
//源文件/文件夹,本地绝对路径/远程资源url
src string
//目标(表示的是文件夹)路径蓝眼云盘中的路径。相对于root的路径。
dest string
//同名文件或文件夹是否直接替换 true 全部替换; false 跳过
overwrite bool
//拉取文件存储的名称
filename string
}
//启动应用。可能是web形式也可能是命令行工具。
func (this *TankApplication) Start() {
defer func() {
if err := recover(); err != nil {
fmt.Printf("ERROR:%v\r\n", err)
}
}()
//超级管理员信息
modePtr := flag.String("mode", this.mode, "cli mode web/mirror/crawl")
hostPtr := flag.String("host", this.username, "tank host")
usernamePtr := flag.String("username", this.username, "username")
passwordPtr := flag.String("password", this.password, "password")
srcPtr := flag.String("src", this.src, "src absolute path")
destPtr := flag.String("dest", this.dest, "destination path in tank.")
overwritePtr := flag.Bool("overwrite", this.overwrite, "whether same file overwrite")
filenamePtr := flag.String("filename", this.filename, "filename when crawl")
//flag.Parse()方法必须要在使用之前调用。
flag.Parse()
this.mode = *modePtr
this.host = *hostPtr
this.username = *usernamePtr
this.password = *passwordPtr
this.src = *srcPtr
this.dest = *destPtr
this.overwrite = *overwritePtr
this.filename = *filenamePtr
//默认采用web的形式启动
if this.mode == "" || strings.ToLower(this.mode) == MODE_WEB {
//直接web启动
this.HandleWeb()
} else {
//准备蓝眼云盘地址
if this.host == "" {
this.host = fmt.Sprintf("http://127.0.0.1:%d", core.DEFAULT_SERVER_PORT)
}
//准备用户名
if this.username == "" {
panic(result.BadRequest("%s模式下用户名必填", this.mode))
}
//准备密码
if this.password == "" {
if util.EnvDevelopment() {
panic(result.BadRequest("IDE中请运行请直接使用 -password yourPassword 的形式输入密码"))
} else {
fmt.Print("Enter Password:")
bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
if err != nil {
panic(err)
}
this.password = string(bytePassword)
fmt.Println()
}
}
if strings.ToLower(this.mode) == MODE_MIRROR {
//映射本地文件到蓝眼云盘
this.HandleMirror()
} else if strings.ToLower(this.mode) == MODE_CRAWL {
//将远程文件拉取到蓝眼云盘中
this.HandleCrawl()
} else {
panic(result.BadRequest("不能处理命名行模式: %s \r\n", this.mode))
}
}
}
//采用Web的方式启动应用
func (this *TankApplication) HandleWeb() {
//第1步。日志
tankLogger := &TankLogger{}
core.LOGGER = tankLogger
tankLogger.Init()
defer tankLogger.Destroy()
//第2步。配置
tankConfig := &TankConfig{}
core.CONFIG = tankConfig
tankConfig.Init()
//第3步。全局运行的上下文
tankContext := &TankContext{}
core.CONTEXT = tankContext
tankContext.Init()
defer tankContext.Destroy()
//第4步。启动http服务
http.Handle("/", core.CONTEXT)
core.LOGGER.Info("App started at http://localhost:%v", core.CONFIG.ServerPort())
dotPort := fmt.Sprintf(":%v", core.CONFIG.ServerPort())
err1 := http.ListenAndServe(dotPort, nil)
if err1 != nil {
log.Fatal("ListenAndServe: ", err1)
}
}
//处理本地映射的情形
func (this *TankApplication) HandleMirror() {
if this.src == "" {
panic("src 必填")
}
if this.dest == "" {
panic("dest 必填")
}
fmt.Printf("开始映射本地文件 %s 到蓝眼云盘 %s\r\n", this.src, this.dest)
urlString := fmt.Sprintf("%s/api/matter/mirror", this.host)
params := url.Values{
"srcPath": {this.src},
"destPath": {this.dest},
"overwrite": {fmt.Sprintf("%v", this.overwrite)},
core.USERNAME_KEY: {this.username},
core.PASSWORD_KEY: {this.password},
}
response, err := http.PostForm(urlString, params)
util.PanicError(err)
bodyBytes, err := ioutil.ReadAll(response.Body)
webResult := &result.WebResult{}
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(bodyBytes, webResult)
if err != nil {
fmt.Printf("返回格式错误!%s \r\n", err.Error())
return
}
if webResult.Code == result.CODE_WRAPPER_OK.Code {
fmt.Println("success")
} else {
fmt.Printf("error %s\r\n", webResult.Msg)
}
}
//拉取远程文件到本地。
func (this *TankApplication) HandleCrawl() {
if this.src == "" {
panic("src 必填")
}
if this.dest == "" {
panic("dest 必填")
}
if this.filename == "" {
panic("filename 必填")
}
fmt.Printf("开始映射拉取远程文件 %s 到蓝眼云盘 %s\r\n", this.src, this.dest)
urlString := fmt.Sprintf("%s/api/matter/crawl", this.host)
params := url.Values{
"url": {this.src},
"destPath": {this.dest},
"filename": {this.filename},
core.USERNAME_KEY: {this.username},
core.PASSWORD_KEY: {this.password},
}
response, err := http.PostForm(urlString, params)
util.PanicError(err)
bodyBytes, err := ioutil.ReadAll(response.Body)
webResult := &result.WebResult{}
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(bodyBytes, webResult)
if err != nil {
fmt.Printf("返回格式错误!%s \r\n", err.Error())
return
}
if webResult.Code == result.CODE_WRAPPER_OK.Code {
fmt.Println("success")
} else {
fmt.Printf("error %s\r\n", webResult.Msg)
}
}

View File

@ -1,151 +0,0 @@
package support
import (
"flag"
"fmt"
"github.com/eyebluecn/tank/code/core"
"github.com/eyebluecn/tank/code/tool/result"
"github.com/eyebluecn/tank/code/tool/util"
jsoniter "github.com/json-iterator/go"
"golang.org/x/crypto/ssh/terminal"
"io/ioutil"
"net/http"
"net/url"
"strings"
"syscall"
)
const (
//启动web服务默认是这种方式
MODE_WEB = "web"
//映射本地文件到云盘中
MODE_MIRROR = "mirror"
)
//命令行输入相关的对象
type TankCommand struct {
//模式
mode string
//蓝眼云盘的主机,需要带上协议和端口号。默认: http://127.0.0.1:core.DEFAULT_SERVER_PORT
host string
//用户名
username string
//密码
password string
//源文件/文件夹,本地绝对路径
src string
//目标(表示的是文件夹)路径蓝眼云盘中的路径。相对于root的路径。
dest string
//同名文件或文件夹是否直接替换 true 全部替换; false 跳过
overwrite bool
}
//第三级. 从程序参数中读取配置项
func (this *TankCommand) Cli() bool {
//超级管理员信息
modePtr := flag.String("mode", this.mode, "cli mode web/mirror")
hostPtr := flag.String("host", this.username, "tank host")
usernamePtr := flag.String("username", this.username, "username")
passwordPtr := flag.String("password", this.password, "password")
srcPtr := flag.String("src", this.src, "src absolute path")
destPtr := flag.String("dest", this.dest, "destination path in tank.")
overwritePtr := flag.Bool("overwrite", this.overwrite, "whether same file overwrite")
//flag.Parse()方法必须要在使用之前调用。
flag.Parse()
this.mode = *modePtr
this.host = *hostPtr
this.username = *usernamePtr
this.password = *passwordPtr
this.src = *srcPtr
this.dest = *destPtr
this.overwrite = *overwritePtr
//准备模式
if this.mode == "" || strings.ToLower(this.mode) == MODE_WEB {
return false
}
//准备蓝眼云盘地址
if this.host == "" {
this.host = fmt.Sprintf("http://127.0.0.1:%d", core.DEFAULT_SERVER_PORT)
}
//准备用户名
if this.username == "" {
fmt.Println("用户名必填")
return true
}
//准备密码
if this.password == "" {
if util.EnvDevelopment() {
fmt.Println("IDE中请运行请直接使用 -password yourPassword 的形式输入密码")
return true
} else {
fmt.Print("Enter Password:")
bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
if err != nil {
panic(err)
}
this.password = string(bytePassword)
fmt.Println()
}
}
if strings.ToLower(this.mode) == MODE_MIRROR {
this.HandleMirror()
} else {
fmt.Printf("不能处理命名行模式: %s \r\n", this.mode)
}
return true
}
//处理本地映射的情形
func (this *TankCommand) HandleMirror() {
fmt.Printf("开始映射本地文件 %s 到蓝眼云盘 %s\r\n", this.src, this.dest)
urlString := fmt.Sprintf("%s/api/matter/mirror", this.host)
params := url.Values{
"srcPath": {this.src},
"destPath": {this.dest},
"overwrite": {fmt.Sprintf("%v", this.overwrite)},
core.USERNAME_KEY: {this.username},
core.PASSWORD_KEY: {this.password},
}
response, err := http.PostForm(urlString, params)
util.PanicError(err)
bodyBytes, err := ioutil.ReadAll(response.Body)
webResult := &result.WebResult{}
err = jsoniter.ConfigCompatibleWithStandardLibrary.Unmarshal(bodyBytes, webResult)
if err != nil {
fmt.Printf("返回格式错误!%s \r\n", err.Error())
return
}
if webResult.Code == result.CODE_WRAPPER_OK.Code {
fmt.Println("success")
} else {
fmt.Printf("error %s\r\n", webResult.Msg)
}
}

View File

@ -131,7 +131,6 @@ func (this *TankContext) registerBeans() {
this.registerBean(new(rest.AlienService))
//bridge
this.registerBean(new(rest.BridgeController))
this.registerBean(new(rest.BridgeDao))
this.registerBean(new(rest.BridgeService))

View File

@ -10,6 +10,7 @@ import (
"io"
"net/http"
"os"
"runtime"
"strings"
"time"
)
@ -72,7 +73,13 @@ func NewRouter() *TankRouter {
func (this *TankRouter) GlobalPanicHandler(writer http.ResponseWriter, request *http.Request, startTime time.Time) {
if err := recover(); err != nil {
core.LOGGER.Error("错误: %v", err)
//控制台中打印日志,记录行号。
_, file, line, ok := runtime.Caller(2)
if !ok {
file = "???"
line = 0
}
core.LOGGER.Error("panic on %s:%d %v", util.GetFilenameOfPath(file), line, err)
var webResult *result.WebResult = nil
if value, ok := err.(string); ok {