diff --git a/UI b/UI
index 247c099..74fa1f8 160000
--- a/UI
+++ b/UI
@@ -1 +1 @@
-Subproject commit 247c099bf14a2d9eb94bf7798e04d00dbc8f7efd
+Subproject commit 74fa1f8920aa23f40b04b87cc04ebef5c36b0890
diff --git a/conf/conf.ini.sample b/conf/conf.ini.sample
index 808e6ea..612c015 100644
--- a/conf/conf.ini.sample
+++ b/conf/conf.ini.sample
@@ -14,11 +14,12 @@ RootPath = /casaOS
[server]
HttpPort = 8089
+UDPPort =
RunMode = release
ServerApi = https://api.casaos.zimaboard.com
-Handshake =
+Handshake = socket.casaos.io
Token =
-NickName =
+USBAutoMount = true
[user]
@@ -28,11 +29,7 @@ Email = user@gmail.com
Description = description
Initialized = false
Avatar =
-
-[zerotier]
-UserName = user
-PWD = pwd
-Token = yBKYyavr2RdFAIVN7iTpzlsB1o6CqTgm
+NickName =
[redis]
Host = 127.0.0.1:6379
@@ -48,4 +45,4 @@ Analyse =
[file]
ShareDir =
-DownloadDir = /DATA
\ No newline at end of file
+DownloadDir =
\ No newline at end of file
diff --git a/go.mod b/go.mod
index 4d293b4..a703c0c 100644
--- a/go.mod
+++ b/go.mod
@@ -50,6 +50,7 @@ require (
github.com/sirupsen/logrus v1.8.1
github.com/smartystreets/assertions v1.2.0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
+ github.com/spf13/afero v1.2.2
github.com/swaggo/gin-swagger v1.3.0
github.com/swaggo/swag v1.7.3
github.com/tidwall/gjson v1.10.2
diff --git a/go.sum b/go.sum
index 2043428..cce619d 100644
--- a/go.sum
+++ b/go.sum
@@ -794,6 +794,7 @@ github.com/sourcegraph/annotate v0.0.0-20160123013949-f4cad6c6324d/go.mod h1:Udh
github.com/sourcegraph/syntaxhighlight v0.0.0-20170531221838-bd320f5d308e/go.mod h1:HuIsMU8RRBOtsCgI77wP899iHVBQpCmg4ErYMZB+2IA=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
diff --git a/main.go b/main.go
index d089b7a..9cf8f67 100644
--- a/main.go
+++ b/main.go
@@ -4,9 +4,9 @@ import (
"flag"
"fmt"
"net/http"
+ "runtime"
"time"
- "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/cache"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
@@ -29,6 +29,24 @@ func init() {
config.InitSetup(*configFlag)
config.UpdateSetup()
loger2.LogSetup()
+ sysType := runtime.GOOS
+ if sysType == "windows" {
+ config.AppInfo.ProjectPath = "C:\\CasaOS\\service"
+ config.Cfg.Section("app").Key("ProjectPath").SetValue("C:\\CasaOS\\service")
+
+ config.AppInfo.RootPath = "C:\\CasaOS"
+ config.Cfg.Section("app").Key("RootPath").SetValue("C:\\CasaOS")
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ }
+ if sysType == "darwin" {
+ config.AppInfo.ProjectPath = "./CasaOS/service"
+ config.Cfg.Section("app").Key("ProjectPath").SetValue("./CasaOS/service")
+
+ config.AppInfo.RootPath = "./CasaOS"
+ config.Cfg.Section("app").Key("RootPath").SetValue("./CasaOS")
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ }
+
sqliteDB = sqlite.GetDb(config.AppInfo.ProjectPath)
//gredis.GetRedisConn(config.RedisInfo),
service.MyService = service.NewService(sqliteDB, loger2.NewOLoger())
@@ -36,10 +54,10 @@ func init() {
go service.UDPService()
- service.Summary = make(map[string]model.FileSummaryModel)
+ fmt.Println("token", service.GetToken())
service.UDPAddressMap = make(map[string]string)
//go service.SocketConnect()
-
+ service.CancelList = make(map[string]string)
route.InitFunction()
go service.SendIPToServer()
@@ -69,20 +87,30 @@ func main() {
//gredis.Setup()
r := route.InitRouter()
//service.SyncTask(sqliteDB)
- cron2 := cron.New() //创建一个cron实例
+ cron2 := cron.New()
//every day execution
err := cron2.AddFunc("0 0/5 * * * *", func() {
//service.PushIpInfo(*&config.ServerInfo.Token)
//service.UpdataDDNSList(mysqldb)
//service.SyncTask(sqliteDB)
+
service.SendIPToServer()
+
service.LoopFriend()
+
})
if err != nil {
fmt.Println(err)
}
+ // err = cron2.AddFunc("0/1 * * * * *", func() {
- //启动/关闭
+ // //service.SendIPToServer()
+ // //service.LoopNet()
+
+ // })
+ // if err != nil {
+ // fmt.Println(err)
+ // }
cron2.Start()
defer cron2.Stop()
s := &http.Server{
diff --git a/model/net.go b/model/net.go
index fcc90a6..1f2897a 100644
--- a/model/net.go
+++ b/model/net.go
@@ -1,19 +1,17 @@
package model
-import "time"
-
type IOCountersStat struct {
- Name string `json:"name"` // interface name
- BytesSent uint64 `json:"bytesSent"` // number of bytes sent
- BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
- PacketsSent uint64 `json:"packetsSent"` // number of packets sent
- PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
- Errin uint64 `json:"errin"` // total number of errors while receiving
- Errout uint64 `json:"errout"` // total number of errors while sending
- Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped
- Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
- Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving
- Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending
- State string `json:"state"`
- DateTime time.Time `json:"date_time"`
+ Name string `json:"name"` // interface name
+ BytesSent uint64 `json:"bytesSent"` // number of bytes sent
+ BytesRecv uint64 `json:"bytesRecv"` // number of bytes received
+ PacketsSent uint64 `json:"packetsSent"` // number of packets sent
+ PacketsRecv uint64 `json:"packetsRecv"` // number of packets received
+ Errin uint64 `json:"errin"` // total number of errors while receiving
+ Errout uint64 `json:"errout"` // total number of errors while sending
+ Dropin uint64 `json:"dropin"` // total number of incoming packets which were dropped
+ Dropout uint64 `json:"dropout"` // total number of outgoing packets which were dropped (always 0 on OSX and BSD)
+ Fifoin uint64 `json:"fifoin"` // total number of FIFO buffers errors while receiving
+ Fifoout uint64 `json:"fifoout"` // total number of FIFO buffers errors while sending
+ State string `json:"state"`
+ Time int64 `json:"time"`
}
diff --git a/model/person.go b/model/person.go
index 0dbcf16..d8a119a 100644
--- a/model/person.go
+++ b/model/person.go
@@ -45,3 +45,10 @@ type FileSummaryModel struct {
Size int64 `json:"size"`
Message string `json:"message"`
}
+
+type FriendsModel struct {
+ Id uint `gorm:"column:id;primary_key" json:"id"`
+ NickName string `json:"nick_name"`
+ Desc string `json:"desc"`
+ ShareId string `json:"share_id"`
+}
diff --git a/model/sys_common.go b/model/sys_common.go
index 8c33ec7..0c166ce 100644
--- a/model/sys_common.go
+++ b/model/sys_common.go
@@ -22,12 +22,14 @@ type UserModel struct {
//服务配置
type ServerModel struct {
- HttpPort string
- RunMode string
- ServerApi string
- LockAccount bool
- Handshake string
- Token string
+ HttpPort string
+ RunMode string
+ ServerApi string
+ LockAccount bool
+ Handshake string
+ Token string
+ UDPPort string
+ USBAutoMount string
}
//服务配置
@@ -50,13 +52,6 @@ type Result struct {
Data interface{} `json:"data" example:"返回结果"`
}
-//zeritier相关
-type ZeroTierModel struct {
- UserName string
- PWD string
- Token string
-}
-
//redis配置文件
type RedisModel struct {
Host string
diff --git a/model/user.go b/model/user.go
new file mode 100644
index 0000000..fbc9398
--- /dev/null
+++ b/model/user.go
@@ -0,0 +1,9 @@
+package model
+
+type UserInfo struct {
+ NickName string `json:"nick_name"`
+ Desc string `json:"desc"`
+ ShareId string `json:"share_id"`
+ Avatar string `json:"avatar"`
+ Version int `json:"version,omitempty"`
+}
diff --git a/model/zima.go b/model/zima.go
index dafaa43..6d3afbb 100644
--- a/model/zima.go
+++ b/model/zima.go
@@ -3,11 +3,11 @@ package model
import "time"
type Path struct {
- Name string `json:"name"`
- Path string `json:"path"`
- IsDir bool `json:"is_dir"`
+ Name string `json:"name"` //File name or document name
+ Path string `json:"path"` //Full path to file or folder
+ IsDir bool `json:"is_dir"` //Is it a folder
Date time.Time `json:"date"`
- Size int64 `json:"size"`
+ Size int64 `json:"size"` //File Size
Type string `json:"type,omitempty"`
Label string `json:"label,omitempty"`
}
diff --git a/pkg/config/init.go b/pkg/config/init.go
index 5cb0df4..38680c0 100644
--- a/pkg/config/init.go
+++ b/pkg/config/init.go
@@ -25,9 +25,6 @@ var AppInfo = &model.APPModel{}
//redis相关配置
var RedisInfo = &model.RedisModel{}
-//zerotier相关
-var ZeroTierInfo = &model.ZeroTierModel{}
-
//server相关
var ServerInfo = &model.ServerModel{}
@@ -56,7 +53,6 @@ func InitSetup(config string) {
mapTo("user", UserInfo)
mapTo("app", AppInfo)
- mapTo("zerotier", ZeroTierInfo)
mapTo("redis", RedisInfo)
mapTo("server", ServerInfo)
mapTo("system", SystemConfigInfo)
diff --git a/pkg/config/update.go b/pkg/config/update.go
index 9091a34..7dbae82 100644
--- a/pkg/config/update.go
+++ b/pkg/config/update.go
@@ -1,13 +1,30 @@
package config
-import "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
+import (
+ "runtime"
+
+ "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
+)
//检查目录是否存在
func mkdirDATAAll() {
- dirArray := [7]string{"/DATA/AppData", "/DATA/Documents", "/DATA/Downloads", "/DATA/Gallery", "/DATA/Media/Movies", "/DATA/Media/TV Shows", "/DATA/Media/Music"}
+ sysType := runtime.GOOS
+ var dirArray []string
+ if sysType == "linux" {
+ dirArray = []string{"/DATA/AppData", "/DATA/Documents", "/DATA/Downloads", "/DATA/Gallery", "/DATA/Media/Movies", "/DATA/Media/TV Shows", "/DATA/Media/Music"}
+ }
+
+ if sysType == "windows" {
+ dirArray = []string{"C:\\CasaOS\\DATA\\AppData", "C:\\CasaOS\\DATA\\Documents", "C:\\CasaOS\\DATA\\Downloads", "C:\\CasaOS\\DATA\\Gallery", "C:\\CasaOS\\DATA\\Media/Movies", "C:\\CasaOS\\DATA\\Media\\TV Shows", "C:\\CasaOS\\DATA\\Media\\Music"}
+ }
+ if sysType == "darwin" {
+ dirArray = []string{"./CasaOS/DATA/AppData", "./CasaOS/DATA/Documents", "./CasaOS/DATA/Downloads", "./CasaOS/DATA/Gallery", "./CasaOS/DATA/Media/Movies", "./CasaOS/DATA/Media/TV Shows", "./CasaOS/DATA/Media/Music"}
+ }
+
for _, v := range dirArray {
file.IsNotExistMkDir(v)
}
+
}
func UpdateSetup() {
diff --git a/pkg/sqlite/db.go b/pkg/sqlite/db.go
index 2b85a71..0338d05 100644
--- a/pkg/sqlite/db.go
+++ b/pkg/sqlite/db.go
@@ -31,7 +31,7 @@ func GetDb(projectPath string) *gorm.DB {
return nil
}
gdb = db
- err = db.AutoMigrate(&model2.TaskDBModel{}, &model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersionDownloadDBModel{}, model2.FriendModel{})
+ err = db.AutoMigrate(&model2.TaskDBModel{}, &model2.AppNotify{}, &model2.AppListDBModel{}, &model2.SerialDisk{}, model2.PersonDownloadDBModel{}, model2.FriendModel{})
if err != nil {
fmt.Println("检查和创建数据库出错", err)
}
diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go
index c2d3316..069b2c0 100644
--- a/pkg/utils/file/file.go
+++ b/pkg/utils/file/file.go
@@ -8,6 +8,8 @@ import (
"mime/multipart"
"os"
"path"
+ path2 "path"
+ "path/filepath"
"strconv"
"strings"
)
@@ -226,6 +228,17 @@ func CopyFile(src, dst string) error {
return os.Chmod(dst, srcinfo.Mode())
}
+//Check for duplicate file names
+func GetNoDuplicateFileName(fullPath string) string {
+ path, fileName := filepath.Split(fullPath)
+ fileSuffix := path2.Ext(fileName)
+ filenameOnly := strings.TrimSuffix(fileName, fileSuffix)
+ for i := 0; Exists(fullPath); i++ {
+ fullPath = path2.Join(path, filenameOnly+"("+strconv.Itoa(i+1)+")"+fileSuffix)
+ }
+ return fullPath
+}
+
// Dir copies a whole directory recursively
func CopyDir(src string, dst string) error {
var err error
diff --git a/pkg/utils/httper/httper.go b/pkg/utils/httper/httper.go
index 09848d9..651453f 100644
--- a/pkg/utils/httper/httper.go
+++ b/pkg/utils/httper/httper.go
@@ -3,6 +3,7 @@ package httper
import (
"bytes"
"encoding/json"
+ "fmt"
"io"
"io/ioutil"
"net/http"
@@ -67,7 +68,8 @@ func Post(url string, data []byte, contentType string, head map[string]string) (
client := &http.Client{Timeout: 5 * time.Second}
resp, error := client.Do(req)
if error != nil {
- panic(error)
+ fmt.Println(error)
+ return
}
defer resp.Body.Close()
diff --git a/pkg/utils/ini_helper.go b/pkg/utils/ini_helper.go
deleted file mode 100644
index d4b585b..0000000
--- a/pkg/utils/ini_helper.go
+++ /dev/null
@@ -1 +0,0 @@
-package utils
diff --git a/pkg/utils/oasis_err/e.go b/pkg/utils/oasis_err/e.go
index 4b1c15c..bb6fcbd 100644
--- a/pkg/utils/oasis_err/e.go
+++ b/pkg/utils/oasis_err/e.go
@@ -37,13 +37,18 @@ const (
FILE_DOES_NOT_EXIST = 60001
FILE_READ_ERROR = 60002
FILE_DELETE_ERROR = 60003
+ DIR_NOT_EXISTS = 60004
//shortcuts
SHORTCUTS_URL_ERROR = 70001
- //persion
- PERSION_REMOTE_ERROR = 80001
- PERSION_DOWN_NOT_EXIST = 80002
+ //person
+ PERSON_REMOTE_ERROR = 80001
+ PERSON_DOWN_NOT_EXIST = 80002
+ PERSON_EXIST_DOWNLOAD = 80003
+ PERSON_NOT_EXIST_USER = 80004
+ PERSON_EXIST_FRIEND = 80005
+ PERSON_MYSELF = 80006
)
var MsgFlags = map[int]string{
@@ -82,12 +87,18 @@ var MsgFlags = map[int]string{
//
FILE_DOES_NOT_EXIST: "File does not exist",
+ DIR_NOT_EXISTS: "Directory does not exist",
+
FILE_READ_ERROR: "File read error",
FILE_DELETE_ERROR: "Delete error",
SHORTCUTS_URL_ERROR: "URL error",
- PERSION_REMOTE_ERROR: "Remote connection error",
- PERSION_DOWN_NOT_EXIST: "Download record does not exist",
+ PERSON_REMOTE_ERROR: "Remote connection error",
+ PERSON_DOWN_NOT_EXIST: "Download record does not exist",
+ PERSON_EXIST_DOWNLOAD: "The same download task exists",
+ PERSON_EXIST_FRIEND: "Friend already exist",
+ PERSON_NOT_EXIST_USER: "User does not exist",
+ PERSON_MYSELF: "You can not add yourself",
}
//获取错误信息
diff --git a/pkg/zerotier/zerotier_api.go b/pkg/zerotier/zerotier_api.go
deleted file mode 100644
index f7ad214..0000000
--- a/pkg/zerotier/zerotier_api.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package zerotier
-
-import (
- httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
- "github.com/tidwall/gjson"
- "net/http"
-)
-
-func PostData(url, token string, data string) interface{} {
-
- body, code := httper2.ZeroTierPostJson(url, data, GetHead(token))
-
- if code != http.StatusOK {
- return ""
- }
- result := gjson.Parse(body)
- return result.Value()
-}
-
-func GetData(url, token string) interface{} {
-
- body, code := httper2.ZeroTierGet(url, GetHead(token))
-
- if code != http.StatusOK {
- return ""
- }
- result := gjson.Parse(body)
- return result.Value()
-}
-
-func DeleteMember(url, token string) interface{} {
-
- body, code := httper2.ZeroTierDelete(url, GetHead(token))
-
- if code != http.StatusOK {
- return ""
- }
- result := gjson.Parse(body)
- return result.Value()
-}
-
-func GetHead(token string) map[string]string {
- var head = make(map[string]string)
- head["Authorization"] = "Bearer " + token
- head["Content-Type"] = "application/json"
- return head
-}
diff --git a/route/init.go b/route/init.go
index 4db6a6f..3859361 100644
--- a/route/init.go
+++ b/route/init.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"encoding/xml"
"fmt"
+ "runtime"
"strconv"
"time"
@@ -231,10 +232,10 @@ func CheckSerialDiskMount() {
}
service.MyService.Disk().RemoveLSBLKCache()
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;AutoRemoveUnuseDir")
-
}
func Update2_3() {
command.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/assist.sh")
+
}
func CheckToken2_11() {
if len(config.ServerInfo.Token) == 0 {
@@ -253,20 +254,34 @@ func CheckToken2_11() {
// config.AppInfo.RootPath = "/casaOS"
// config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
// }
- if len(config.FileSettingInfo.ShareDir) == 0 {
- config.Cfg.Section("file").Key("ShareDir").SetValue("/DATA")
- config.FileSettingInfo.ShareDir[0] = "/DATA"
-
- config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
- }
-
+ sysType := runtime.GOOS
if len(config.FileSettingInfo.DownloadDir) == 0 {
- config.Cfg.Section("file").Key("DownloadDir").SetValue("/DATA/share")
- config.FileSettingInfo.DownloadDir = "/DATA/share"
+ downloadPath := "/DATA/Downloads"
+ if sysType == "windows" {
+ downloadPath = "C:\\CasaOS\\DATA\\Downloads"
+ }
+ if sysType == "darwin" {
+ downloadPath = "~/CasaOS/DATA/Downloads"
+ }
+ config.Cfg.Section("file").Key("DownloadDir").SetValue(downloadPath)
+ config.FileSettingInfo.DownloadDir = downloadPath
file.IsNotExistMkDir(config.FileSettingInfo.DownloadDir)
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
+ if len(config.UserInfo.Description) == 0 {
+ config.Cfg.Section("user").Key("Description").SetValue("nothing")
+ config.UserInfo.Description = "nothing"
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ }
+ if len(config.ServerInfo.Handshake) == 0 {
+ config.Cfg.Section("server").Key("Handshake").SetValue("socket.casaos.io")
+ config.ServerInfo.Handshake = "socket.casaos.io"
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ }
+
+ service.MyService.System().ExecUSBAutoMountShell(config.ServerInfo.USBAutoMount)
+
// str := []string{}
// str = append(str, "ddd")
// str = append(str, "aaa")
diff --git a/route/route.go b/route/route.go
index 04671dd..80b7eee 100644
--- a/route/route.go
+++ b/route/route.go
@@ -18,6 +18,7 @@ var OnlineDemo bool = false
func InitRouter() *gin.Engine {
r := gin.Default()
+
r.Use(middleware.Cors())
r.Use(gzip.Gzip(gzip.DefaultCompression))
gin.SetMode(config.ServerInfo.RunMode)
@@ -52,13 +53,16 @@ func InitRouter() *gin.Engine {
//chang head
v1UserGroup.POST("/head", v1.PostUserHead)
//chang user name
- v1UserGroup.PUT("/changusername", v1.PutUserName)
+ v1UserGroup.PUT("/username", v1.PutUserName)
//chang pwd
- v1UserGroup.PUT("/changuserpwd", v1.PutUserPwd)
+ v1UserGroup.PUT("/password", v1.PutUserPwd)
//edit user info
v1UserGroup.POST("/info", v1.PostUserChangeInfo)
v1UserGroup.PUT("/nick", v1.PutUserChangeNick)
v1UserGroup.PUT("/desc", v1.PutUserChangeDesc)
+ v1UserGroup.POST("/person/info", v1.PostUserPersonInfo)
+
+ v1UserGroup.GET("/shareid", v1.GetUserShareID)
}
@@ -78,51 +82,6 @@ func InitRouter() *gin.Engine {
//获取系统信息
v1ZiMaGroup.GET("/sysinfo", v1.SysInfo)
}
-
- v1ZeroTierGroup := v1Group.Group("/zerotier")
- v1ZeroTierGroup.Use()
- {
- //获取zerotier token
- v1ZeroTierGroup.POST("/login", v1.ZeroTierGetToken)
- //注册zerotier
- v1ZeroTierGroup.POST("/register", v1.ZeroTierRegister)
- //是否需要登录
- v1ZeroTierGroup.GET("/islogin", v1.ZeroTierIsNeedLogin)
- //获取网络列表
- v1ZeroTierGroup.GET("/list", v1.ZeroTierGetNetworkList)
- //加入网络
- v1ZeroTierGroup.POST("/join/:id", v1.ZeroTierJoinNetwork)
- //离开网络
- v1ZeroTierGroup.POST("/leave/:id", v1.ZeroTierLeaveNetwork)
- //详情
- v1ZeroTierGroup.GET("/info/:id", v1.ZeroTierGetNetworkGetInfo)
- ////网络状态
- //v1ZeroTierGroup.GET("/status", v1.ZeroTierGetNetworkGetStatus)
- //修改网络类型
- //v1ZeroTierGroup.PUT("/type/:id", v1.ZeroTierEditType)
- //修改网络类型
- //v1ZeroTierGroup.PUT("/name/:id", v1.ZeroTierEditName)
- //修改v6 assign
- //v1ZeroTierGroup.PUT("/v6assign/:id", v1.ZeroTierEditV6Assign)
- //修改 broadcast
- //v1ZeroTierGroup.PUT("/broadcast/:id", v1.ZeroTierEditBroadcast)
- //create new network
- v1ZeroTierGroup.POST("/create", v1.ZeroTierCreateNetwork)
- //获取用户列表
- v1ZeroTierGroup.GET("/member/:id", v1.ZeroTierMemberList)
- //修改用户信息
- //v1ZeroTierGroup.PUT("/members/:id/auth/:mId", v1.ZeroTierMemberAuth)
- //修改网络用户name
- //v1ZeroTierGroup.PUT("/members/:id/name/:mId", v1.ZeroTierMemberName)
- v1ZeroTierGroup.DELETE("/members/:id/del/:mId", v1.ZeroTierMemberDelete)
- v1ZeroTierGroup.DELETE("/network/:id/del", v1.ZeroTierDeleteNetwork)
- //修改网络用户bridge功能
- //v1ZeroTierGroup.PUT("/members/:id/bridge/:mId", v1.ZeroTierMemberBridge)
- v1ZeroTierGroup.PUT("/edit/:id", v1.ZeroTierEdit)
- v1ZeroTierGroup.GET("/joined/list", v1.ZeroTierJoinedList)
- v1ZeroTierGroup.PUT("/member/:id/edit/:mId", v1.ZeroTierMemberEdit)
-
- }
v1DDNSGroup := v1Group.Group("/ddns")
v1DDNSGroup.Use()
{
@@ -201,6 +160,9 @@ func InitRouter() *gin.Engine {
v1SysGroup.PUT("/port", v1.PutCasaOSPort)
v1SysGroup.POST("/kill", v1.PostKillCasaOS)
v1SysGroup.GET("/info", v1.Info)
+ v1SysGroup.PUT("/usb/off", v1.PutSystemOffUSBAutoMount)
+ v1SysGroup.GET("/usb/on", v1.PutSystemOnUSBAutoMount)
+ v1SysGroup.GET("/usb", v1.GetSystemUSBAutoMount)
}
v1FileGroup := v1Group.Group("/file")
v1FileGroup.Use()
@@ -216,6 +178,7 @@ func InitRouter() *gin.Engine {
v1FileGroup.POST("/create", v1.PostCreateFile)
v1FileGroup.GET("/download", v1.GetDownloadFile)
+ v1FileGroup.GET("/new/download", v1.GetFileDownloadNew)
v1FileGroup.POST("/operate", v1.PostOperateFileOrDir)
v1FileGroup.DELETE("/delete", v1.DeleteFile)
v1FileGroup.PUT("/update", v1.PutFileContent)
@@ -289,19 +252,26 @@ func InitRouter() *gin.Engine {
{
v1SearchGroup.GET("/search", v1.GetSearchList)
}
- v1PersonGroup := v1Group.Group("/persion")
+ v1PersonGroup := v1Group.Group("/person")
v1PersonGroup.Use()
{
v1PersonGroup.GET("/test", v1.PersonTest)
- v1PersonGroup.GET("/users", v1.GetPersionFriend)
- v1PersonGroup.POST("/user", v1.PostAddPersionFriend)
- v1PersonGroup.GET("/directory", v1.GetPersionDirectory)
- v1PersonGroup.GET("/file", v1.GetPersionFile)
- v1PersonGroup.GET("/refile/:uuid", v1.GetPersionReFile)
- v1PersonGroup.PUT("/nick/:token", v1.PutPersionNick)
- v1PersonGroup.GET("/list", v1.GetPersionDownloadList)
- v1PersonGroup.DELETE("/file/:uuid", v1.DeletePersionDownloadFile)
- // v1PersonGroup.PUT("/state/:id", v1.PutPersionCancelDownload) //修改下载状态(开始暂停删除)
+ v1PersonGroup.GET("/users", v1.GetPersonFriend)
+ v1PersonGroup.POST("/user/:shareids", v1.PostAddPersonFriend)
+ v1PersonGroup.DELETE("/user/:shareid", v1.DeletePersonFriend)
+ v1PersonGroup.GET("/directory", v1.GetPersonDirectory)
+ v1PersonGroup.GET("/file", v1.GetPersonFile)
+ v1PersonGroup.GET("/refile/:uuid", v1.GetPersonReFile)
+ v1PersonGroup.PUT("/remarks/:shareid", v1.PutPersonRemarks)
+ v1PersonGroup.GET("/list", v1.GetPersonDownloadList)
+ v1PersonGroup.DELETE("/file/:uuid", v1.DeletePersonDownloadFile)
+
+ v1PersonGroup.POST("/share", v1.PostPersonShare)
+ v1PersonGroup.GET("/share", v1.GetPersonShare)
+ v1PersonGroup.POST("/down/dir", v1.PostPersonDownDir)
+ v1PersonGroup.GET("/down/dir", v1.GetPersonDownDir)
+ v1PersonGroup.PUT("/block/:shareid", v1.PutPersonBlock)
+ v1PersonGroup.GET("/public", v1.GetPersonPublic)
}
v1AnalyseGroup := v1Group.Group("/analyse")
diff --git a/route/v1/app.go b/route/v1/app.go
index 6b2425b..a2b326e 100644
--- a/route/v1/app.go
+++ b/route/v1/app.go
@@ -248,7 +248,7 @@ func ShareAppFile(c *gin.Context) {
// @Tags app
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /app/share [post]
+// @Router /app/shares [post]
func AppListResourceUsage() {
}
diff --git a/route/v1/file.go b/route/v1/file.go
index 9f3a7c6..f85fbea 100644
--- a/route/v1/file.go
+++ b/route/v1/file.go
@@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"net/http"
+ url2 "net/url"
"os"
"path"
"strconv"
@@ -17,6 +18,7 @@ import (
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/IceWhaleTech/CasaOS/service"
"github.com/gin-gonic/gin"
+ "github.com/spf13/afero"
)
func downloadReadFile(c *gin.Context) {
@@ -157,16 +159,59 @@ func GetDownloadFile(c *gin.Context) {
//获取文件的名称
fileName := path.Base(filePath)
c.Header("Content-Type", "application/octet-stream")
- c.Header("Content-Disposition", "attachment; filename="+fileName)
+ c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
c.Header("Content-Transfer-Encoding", "binary")
c.Header("Cache-Control", "no-cache")
- c.Header("Content-Type", "application/octet-stream")
- c.Header("Content-Disposition", "attachment; filename="+fileName)
- c.Header("Content-Transfer-Encoding", "binary")
c.File(filePath)
}
+// @Summary download
+// @Produce application/json
+// @Accept application/json
+// @Tags file
+// @Security ApiKeyAuth
+// @Param path query string true "path of file"
+// @Success 200 {string} string "ok"
+// @Router /file/new/download [get]
+func GetFileDownloadNew(c *gin.Context) {
+ filePath := c.Query("path")
+ if len(filePath) == 0 {
+ c.JSON(http.StatusOK, model.Result{
+ Success: oasis_err2.INVALID_PARAMS,
+ Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS),
+ })
+ return
+ }
+ if !file.Exists(filePath) {
+ c.JSON(http.StatusOK, model.Result{
+ Success: oasis_err2.FILE_DOES_NOT_EXIST,
+ Message: oasis_err2.GetMsg(oasis_err2.FILE_DOES_NOT_EXIST),
+ })
+ return
+ }
+ //打开文件
+ fileStat, _ := os.Stat(filePath)
+ var AppFs = afero.NewOsFs()
+ fileT, _ := AppFs.Open(filePath)
+ //fileTmp, _ := os.Open(filePath)
+ //defer fileTmp.Close()
+ //获取文件的名称
+ //fileName := path.Base(filePath)
+
+ //c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
+ //在线
+ //c.Header("Content-Disposition", "inline")
+ // extraHeaders := map[string]string{
+ // "Content-Disposition": `attachment; filename="` + url2.PathEscape(fileName) + `"`,
+ // }
+
+ //c.Header("Cache-Control", "private")
+ //c.Header("Content-Type", "application/octet-stream")
+
+ http.ServeContent(c.Writer, c.Request, fileStat.Name(), fileStat.ModTime(), fileT)
+}
+
// @Summary 获取目录列表
// @Produce application/json
// @Accept application/json
diff --git a/route/v1/persion.go b/route/v1/persion.go
index 3f7b651..7900fc1 100644
--- a/route/v1/persion.go
+++ b/route/v1/persion.go
@@ -7,9 +7,12 @@ import (
"net/http"
"reflect"
"strconv"
+ "strings"
+ "time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
+ "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
"github.com/IceWhaleTech/CasaOS/service"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
@@ -19,8 +22,10 @@ import (
)
func PersonTest(c *gin.Context) {
-
token := c.Query("token")
+ _, err := uuid.FromString(token)
+ fmt.Println(err)
+
//service.MyService.Person().GetPersionInfo("fb2333a1-72b2-4cb4-9e31-61ccaffa55b9")
msg := model.MessageModel{}
@@ -35,45 +40,48 @@ func PersonTest(c *gin.Context) {
fmt.Println(err)
}
fmt.Println(dd)
+ user := service.MyService.Casa().GetUserInfoByShareId(token)
+ if reflect.DeepEqual(user, model.UserInfo{}) {
+ fmt.Println("空数据")
+ }
+ fmt.Println(user)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
-// @Summary retry download file
+// @Summary Retry the file that failed to download
// @Produce application/json
// @Accept application/json
-// @Tags persion
+// @Tags person
// @Param uui path string true "download uuid"
-// @Param path query string true "file path"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /persion/refile/{uuid} [get]
-func GetPersionReFile(c *gin.Context) {
+// @Router /person/refile/{uuid} [get]
+func GetPersonReFile(c *gin.Context) {
- path := c.Query("path")
- uuid := c.Param("uuid")
-
- if len(path) == 0 && len(uuid) == 0 {
+ uid := c.Param("uuid")
+ _, err := uuid.FromString(uid)
+ if err != nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
- task := service.MyService.Download().GetDownloadById(uuid)
- if reflect.DeepEqual(task, model2.PersionDownloadDBModel{}) {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSION_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSION_REMOTE_ERROR)})
+ task := service.MyService.Download().GetDownloadById(uid)
+ if reflect.DeepEqual(task, model2.PersonDownloadDBModel{}) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSON_REMOTE_ERROR)})
return
}
token := task.From
if _, ok := service.UDPAddressMap[token]; !ok {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSION_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSION_REMOTE_ERROR)})
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSON_REMOTE_ERROR)})
return
}
m := model.MessageModel{}
- m.Data = path
+ m.Data = task.Path
m.From = config.ServerInfo.Token
m.To = token
m.Type = types.PERSONDOWNLOAD
- m.UUId = uuid
+ m.UUId = uid
go service.Dial(m, false)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
@@ -82,35 +90,57 @@ func GetPersionReFile(c *gin.Context) {
// @Summary download file
// @Produce application/json
// @Accept application/json
-// @Tags persion
-// @Param token query string true "opponent token"
+// @Tags person
+// @Param share_id query string true "opponent share_id"
// @Param path query string true "file path"
+// @Param file_name query string true "file name"
+// @Param local_path query string true "local_path"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /persion/file [get]
-func GetPersionFile(c *gin.Context) {
+// @Router /person/file [get]
+func GetPersonFile(c *gin.Context) {
path := c.Query("path")
- token := c.Query("token")
- if len(path) == 0 && len(token) == 0 {
+ localPath := c.Query("local_path")
+ token := c.Query("share_id")
+ fileName := c.Query("file_name")
+ _, err := uuid.FromString(token)
+ if len(path) == 0 || err != nil || len(localPath) == 0 || len(fileName) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
- if _, ok := service.UDPAddressMap[token]; !ok {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSION_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSION_REMOTE_ERROR)})
+ if file.CheckNotExist(localPath) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.DIR_NOT_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.DIR_NOT_EXISTS)})
return
}
+ if _, ok := service.UDPAddressMap[token]; !ok {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSON_REMOTE_ERROR)})
+ return
+ }
+
+ if _, ok := service.UDPAddressMap[token]; !ok {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSON_REMOTE_ERROR)})
+ return
+ }
+
// task id
uuid := uuid.NewV4().String()
- task := model2.PersionDownloadDBModel{}
+ task := model2.PersonDownloadDBModel{}
task.UUID = uuid
- task.Name = ""
+ task.Name = fileName
task.Length = 0
task.From = token
+ task.Path = path
task.Size = 0
task.State = types.DOWNLOADAWAIT
+ task.Created = time.Now().Unix()
task.Type = 0
+ task.LocalPath = localPath
+ if service.MyService.Download().GetDownloadListByPath(task) > 0 {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_EXIST_DOWNLOAD, Message: oasis_err2.GetMsg(oasis_err2.PERSON_EXIST_DOWNLOAD)})
+ return
+ }
service.MyService.Download().AddDownloadTask(task)
m := model.MessageModel{}
@@ -127,79 +157,92 @@ func GetPersionFile(c *gin.Context) {
// @Summary delete download file records
// @Produce application/json
// @Accept application/json
-// @Tags persion
+// @Tags person
// @Param uuid path string true "download uuid"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /persion/file/{uuid} [delete]
-func DeletePersionDownloadFile(c *gin.Context) {
+// @Router /person/file/{uuid} [delete]
+func DeletePersonDownloadFile(c *gin.Context) {
id := c.Param("uuid")
- if len(id) == 0 {
+ _, err := uuid.FromString(id)
+ if err != nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
+ task := service.MyService.Download().GetDownloadById(id)
+ if task.State == types.DOWNLOADING {
+ m := model.MessageModel{}
+ m.Data = ""
+ m.From = config.ServerInfo.Token
+ m.To = task.From
+ m.Type = types.PERSONCANCEL
+ m.UUId = task.UUID
+ service.CancelList[task.UUID] = task.UUID
+ service.Dial(m, false)
+ }
service.MyService.Download().DelDownload(id)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
-// @Summary get file download list
+// @Summary Get file download list
// @Produce application/json
// @Accept application/json
-// @Tags persion
-// @Param state query int true "wait:1,downloading:1,pause:2,finish:3,error:4" Enums(0,1,2,4)
+// @Tags person
+// @Param state query int false "wait:0,downloading:1,pause:2,finish:3,error:4,finished:5" Enums(0,1,2,3,4,5)
// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /persion/list [get]
-func GetPersionDownloadList(c *gin.Context) {
+// @Success 200 {object} []model2.PersonDownloadDBModel
+// @Router /person/list [get]
+func GetPersonDownloadList(c *gin.Context) {
state := c.DefaultQuery("state", "")
list := service.MyService.Download().GetDownloadListByState(state)
//if it is downloading, it need to add 'already'
- if state == strconv.Itoa(types.DOWNLOADING) {
- for i := 0; i < len(list); i++ {
+ for i := 0; i < len(list); i++ {
+ if list[i].State == types.DOWNLOADING {
tempDir := config.AppInfo.RootPath + "/temp" + "/" + list[i].UUID
files, err := ioutil.ReadDir(tempDir)
if err == nil {
list[i].Already = len(files)
}
}
+ list[i].Duration = time.Now().Unix() - list[i].Created
}
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
}
-// @Summary edit friend's nick
+// @Summary edit friend's remarks
// @Produce application/json
// @Accept application/json
-// @Tags persion
-// @Param token path string true "token"
-// @Param nick formData string true "nick name"
+// @Tags person
+// @Param remarks formData string true "remarks name"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /persion/nick/{token} [put]
-func PutPersionNick(c *gin.Context) {
- token := c.Param("token")
- nick := c.PostForm("nick")
- if len(token) == 0 || len(nick) == 0 {
+// @Router /person/remarks/{shareid} [put]
+func PutPersonRemarks(c *gin.Context) {
+ token := c.Param("shareid")
+ _, err := uuid.FromString(token)
+ mark := c.PostForm("remarks")
+ if err != nil || len(mark) == 0 {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
friend := model2.FriendModel{}
friend.Token = token
- friend.NickName = nick
- service.MyService.Friend().EditFriendNick(friend)
+ friend.Mark = mark
+ service.MyService.Friend().EditFriendMark(friend)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
-// @Summary get friend list
+// @Summary get my friend list
// @Produce application/json
// @Accept application/json
-// @Tags persion
+// @Tags person
// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /persion/users [get]
-func GetPersionFriend(c *gin.Context) {
+// @Success 200 {object} []model2.FriendModel
+// @Router /person/users [get]
+func GetPersonFriend(c *gin.Context) {
list := service.MyService.Friend().GetFriendList()
for i := 0; i < len(list); i++ {
if v, ok := service.UDPAddressMap[list[i].Token]; ok && len(v) > 0 {
@@ -212,51 +255,79 @@ func GetPersionFriend(c *gin.Context) {
// @Summary add friend
// @Produce application/json
// @Accept application/json
-// @Tags persion
-// @Param token formData int true "Opponent token"
+// @Tags person
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /persion/user [post]
-func PostAddPersionFriend(c *gin.Context) {
- token := c.PostForm("token")
- if len(token) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
+// @Router /person/user/{shareids} [post]
+func PostAddPersonFriend(c *gin.Context) {
+ token := c.Param("shareids")
+ tokenList := strings.Split(token, ",")
+
+ for _, v := range tokenList {
+ _, err := uuid.FromString(v)
+ if err != nil {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+ return
+ }
+
+ if v == config.ServerInfo.Token {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_MYSELF, Message: oasis_err2.GetMsg(oasis_err2.PERSON_MYSELF)})
+ return
+ }
+
+ udb := service.MyService.Friend().GetFriendById(model2.FriendModel{Token: v})
+ if !reflect.DeepEqual(udb, model2.FriendModel{Token: v}) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_EXIST_FRIEND, Message: oasis_err2.GetMsg(oasis_err2.PERSON_EXIST_FRIEND)})
+ return
+ }
+
+ user := service.MyService.Casa().GetUserInfoByShareId(v)
+ if reflect.DeepEqual(user, model.UserInfo{}) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_NOT_EXIST_USER, Message: oasis_err2.GetMsg(oasis_err2.PERSON_NOT_EXIST_USER)})
+ return
+ }
+
+ message := model.MessageModel{}
+ message.Type = types.PERSONCONNECTION
+ message.Data = v
+ message.From = config.ServerInfo.Token
+ message.To = v
+ message.UUId = uuid.NewV4().String()
+
+ go service.Dial(message, true)
+
+ friend := model2.FriendModel{}
+ friend.Token = v
+ friend.Avatar = user.Avatar
+ friend.Block = false
+ friend.NickName = user.NickName
+ friend.Profile = user.Desc
+ friend.Version = user.Version
+ service.MyService.Friend().AddFriend(friend)
}
- msg := model.MessageModel{}
- msg.Type = types.PERSONCONNECTION
- msg.Data = token
- msg.From = config.ServerInfo.Token
- msg.To = token
- msg.UUId = uuid.NewV4().String()
-
- go service.Dial(msg, true)
-
- friend := model2.FriendModel{}
- friend.Token = token
- service.MyService.Friend().AddFriend(friend)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
-// @Summary get directory list
+// @Summary Get a list of directories
// @Produce application/json
// @Accept application/json
-// @Tags persion
-// @Param token query string true "Opponent token"
+// @Tags person
+// @Param share_id query string true "Opponent share_id"
// @Param path query string true "dir path"
// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /persion/directory [get]
-func GetPersionDirectory(c *gin.Context) {
+// @Success 200 {object} []model.Path
+// @Router /person/directory [get]
+func GetPersonDirectory(c *gin.Context) {
path := c.Query("path")
- token := c.Query("token")
- if len(path) == 0 && len(token) == 0 {
+ token := c.Query("share_id")
+ _, err := uuid.FromString(token)
+ if len(path) == 0 || err != nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
if _, ok := service.UDPAddressMap[token]; !ok {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSION_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSION_REMOTE_ERROR)})
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PERSON_REMOTE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.PERSON_REMOTE_ERROR)})
return
}
uuid := uuid.NewV4().String()
@@ -282,3 +353,144 @@ func GetPersionDirectory(c *gin.Context) {
}
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: dataModel})
}
+
+// @Summary Modify the download storage directory
+// @Produce application/json
+// @Accept multipart/form-data
+// @Tags person
+// @Security ApiKeyAuth
+// @Param path formData string true "path"
+// @Success 200 {string} string "ok"
+// @Router /person/down/dir [post]
+func PostPersonDownDir(c *gin.Context) {
+
+ downPath := c.PostForm("path")
+
+ if len(downPath) == 0 {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+ return
+ }
+ if file.CheckNotExist(downPath) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.DIR_NOT_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.DIR_NOT_EXISTS)})
+ return
+ }
+ config.Cfg.Section("file").Key("DownloadDir").SetValue(downPath)
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ config.FileSettingInfo.DownloadDir = downPath
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
+}
+
+// @Summary Get the download storage directory
+// @Produce application/json
+// @Accept application/json
+// @Tags person
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /person/down/dir [get]
+func GetPersonDownDir(c *gin.Context) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: config.FileSettingInfo.DownloadDir})
+}
+
+// @Summary Modify the shared directory
+// @Produce application/json
+// @Accept multipart/form-data
+// @Tags person
+// @Security ApiKeyAuth
+// @Param share formData string true "share"
+// @Success 200 {string} string "ok"
+// @Router /person/share [post]
+func PostPersonShare(c *gin.Context) {
+
+ share := c.PostForm("share")
+
+ if len(share) == 0 {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+ return
+ }
+
+ var list []string
+ json.Unmarshal([]byte(share), &list)
+
+ if len(list) == 0 {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+ return
+ }
+ for _, v := range list {
+ if !file.Exists(v) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_ALREADY_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)})
+ return
+ }
+ }
+
+ config.Cfg.Section("file").Key("ShareDir").SetValue(strings.Join(list, "|"))
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ config.FileSettingInfo.ShareDir = list
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
+}
+
+// @Summary Get the shared directory
+// @Produce application/json
+// @Accept application/json
+// @Tags person
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /person/share [get]
+func GetPersonShare(c *gin.Context) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: config.FileSettingInfo.ShareDir})
+}
+
+// @Summary Modify disabled status
+// @Produce application/json
+// @Accept application/json
+// @Tags person
+// @Param block formData bool false "Disable or not,Default:false "
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /person/block/{shareid} [put]
+func PutPersonBlock(c *gin.Context) {
+ token := c.Param("shareid")
+ _, err := uuid.FromString(token)
+ block, _ := strconv.ParseBool(c.PostForm("block"))
+ if err != nil {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+ return
+ }
+ friend := model2.FriendModel{}
+ friend.Token = token
+ friend.Block = block
+ service.MyService.Friend().EditFriendBlock(friend)
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
+}
+
+// @Summary Delete my friend
+// @Produce application/json
+// @Accept application/json
+// @Tags person
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /person/user/{shareid} [delete]
+func DeletePersonFriend(c *gin.Context) {
+ token := c.Param("shareid")
+ _, err := uuid.FromString(token)
+ if err != nil {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+ return
+ }
+ friend := model2.FriendModel{}
+ friend.Token = token
+
+ service.MyService.Friend().DeleteFriend(friend)
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
+}
+
+// @Summary Get public person
+// @Produce application/json
+// @Accept application/json
+// @Tags person
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /person/public [delete]
+func GetPersonPublic(c *gin.Context) {
+ list := service.MyService.Casa().GetPersonPublic()
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
+}
diff --git a/route/v1/system.go b/route/v1/system.go
index 472acdd..d30e93a 100644
--- a/route/v1/system.go
+++ b/route/v1/system.go
@@ -251,6 +251,60 @@ func PostKillCasaOS(c *gin.Context) {
os.Exit(0)
}
+// @Summary Turn off usb auto-mount
+// @Produce application/json
+// @Accept application/json
+// @Tags sys
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /sys/usg/off [put]
+func PutSystemOffUSBAutoMount(c *gin.Context) {
+ service.MyService.System().UpdateUSBAutoMount("False")
+ service.MyService.System().ExecUSBAutoMountShell("False")
+ c.JSON(http.StatusOK,
+ model.Result{
+ Success: oasis_err.SUCCESS,
+ Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+ })
+}
+
+// @Summary Turn off usb auto-mount
+// @Produce application/json
+// @Accept application/json
+// @Tags sys
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /sys/usb [get]
+func GetSystemUSBAutoMount(c *gin.Context) {
+ state := "True"
+ if config.ServerInfo.USBAutoMount == "False" {
+ state = "False"
+ }
+ c.JSON(http.StatusOK,
+ model.Result{
+ Success: oasis_err.SUCCESS,
+ Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+ Data: state,
+ })
+}
+
+// @Summary Turn off usb auto-mount
+// @Produce application/json
+// @Accept application/json
+// @Tags sys
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /sys/usb/on [put]
+func PutSystemOnUSBAutoMount(c *gin.Context) {
+ service.MyService.System().UpdateUSBAutoMount("True")
+ service.MyService.System().ExecUSBAutoMountShell("True")
+ c.JSON(http.StatusOK,
+ model.Result{
+ Success: oasis_err.SUCCESS,
+ Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+ })
+}
+
// @Summary system info
// @Produce application/json
// @Accept application/json
@@ -374,7 +428,7 @@ func Info(c *gin.Context) {
if n.Name == netCardName {
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))
- item.DateTime = time.Now()
+ item.Time = time.Now().Unix()
newNet = append(newNet, item)
break
}
diff --git a/route/v1/user.go b/route/v1/user.go
index a4d3a42..0ff05cd 100644
--- a/route/v1/user.go
+++ b/route/v1/user.go
@@ -121,7 +121,7 @@ func PostUserHead(c *gin.Context) {
// @Param oldname formData string true "Old user name"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /user/changusername [put]
+// @Router /user/username [put]
func PutUserName(c *gin.Context) {
if config.ServerInfo.LockAccount {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ACCOUNT_LOCK, Message: oasis_err2.GetMsg(oasis_err2.ACCOUNT_LOCK)})
@@ -142,14 +142,14 @@ func PutUserName(c *gin.Context) {
// @Accept multipart/form-data
// @Tags user
// @Param pwd formData string true "Password"
-// @Param oldpwd formData string true "Old password"
+// @Param old_pwd formData string true "Old password"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /user/changuserpwd [put]
+// @Router /user/password [put]
func PutUserPwd(c *gin.Context) {
- oldpwd := c.PostForm("oldpwd")
+ oldPwd := c.PostForm("old_pwd")
pwd := c.PostForm("pwd")
- if config.UserInfo.PWD != oldpwd {
+ if config.UserInfo.PWD != oldPwd {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PWD_INVALID_OLD, Message: oasis_err2.GetMsg(oasis_err2.PWD_INVALID_OLD)})
return
}
@@ -199,7 +199,7 @@ func PostUserChangeInfo(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
}
-// @Summary edit user info
+// @Summary edit user nick
// @Produce application/json
// @Accept multipart/form-data
// @Tags user
@@ -211,17 +211,18 @@ func PutUserChangeNick(c *gin.Context) {
nickName := c.PostForm("nick_name")
- if len(nickName) > 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PWD_INVALID, Message: oasis_err2.GetMsg(oasis_err2.PWD_INVALID)})
+ if len(nickName) == 0 {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
user_service.SetUser("", "", "", "", "", nickName)
data := make(map[string]string, 1)
data["nick_name"] = config.UserInfo.NickName
+ go service.MyService.Casa().PushUserInfo()
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
}
-// @Summary edit user info
+// @Summary edit user description
// @Produce application/json
// @Accept multipart/form-data
// @Tags user
@@ -232,13 +233,38 @@ func PutUserChangeNick(c *gin.Context) {
func PutUserChangeDesc(c *gin.Context) {
desc := c.PostForm("description")
- if len(desc) > 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.PWD_INVALID, Message: oasis_err2.GetMsg(oasis_err2.PWD_INVALID)})
+ if len(desc) == 0 {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
return
}
user_service.SetUser("", "", "", "", desc, "")
data := make(map[string]string, 1)
data["description"] = config.UserInfo.Description
+ go service.MyService.Casa().PushUserInfo()
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
+}
+
+// @Summary Modify user person information (Initialization use)
+// @Produce application/json
+// @Accept multipart/form-data
+// @Tags user
+// @Param nick_name formData string false "user nick name"
+// @Param description formData string false "Description"
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /user/person/info [post]
+func PostUserPersonInfo(c *gin.Context) {
+ desc := c.PostForm("description")
+ nickName := c.PostForm("nick_name")
+ if len(desc) == 0 || len(nickName) == 0 {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+ return
+ }
+ user_service.SetUser("", "", "", "", desc, nickName)
+ data := make(map[string]string, 2)
+ data["description"] = config.UserInfo.Description
+ data["nick_name"] = config.UserInfo.NickName
+ go service.MyService.Casa().PushUserInfo()
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
}
@@ -262,3 +288,14 @@ func GetUserInfo(c *gin.Context) {
Data: u,
})
}
+
+// @Summary Get my shareId
+// @Produce application/json
+// @Accept application/json
+// @Tags user
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /user/shareid [get]
+func GetUserShareID(c *gin.Context) {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: config.ServerInfo.Token})
+}
diff --git a/route/v1/zerotier.go b/route/v1/zerotier.go
deleted file mode 100644
index 0966ef9..0000000
--- a/route/v1/zerotier.go
+++ /dev/null
@@ -1,475 +0,0 @@
-package v1
-
-import (
- json2 "encoding/json"
- "net/http"
-
- "github.com/IceWhaleTech/CasaOS/model"
- "github.com/IceWhaleTech/CasaOS/pkg/config"
- oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
- "github.com/IceWhaleTech/CasaOS/service"
- "github.com/gin-gonic/gin"
-)
-
-// @Summary 登录zerotier获取token
-// @Produce application/json
-// @Accept multipart/form-data
-// @Tags zerotier
-// @Param username formData string true "User name"
-// @Param pwd formData string true "password"
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /zerotier/login [post]
-func ZeroTierGetToken(c *gin.Context) {
- username := c.PostForm("username")
- pwd := c.PostForm("pwd")
- if len(username) == 0 || len(pwd) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- errInfo := service.MyService.ZeroTier().GetToken(username, pwd)
-
- if len(errInfo) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.GET_TOKEN_ERROR)})
- } else {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
- }
-}
-
-// @Summary 注册zerotier
-// @Produce application/json
-// @Accept multipart/form-data
-// @Tags zerotier
-// @Param firstName formData string true "first name"
-// @Param pwd formData string true "password"
-// @Param email formData string true "email"
-// @Param lastName formData string true "last name"
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /zerotier/register [post]
-func ZeroTierRegister(c *gin.Context) {
- firstName := c.PostForm("firstName")
- pwd := c.PostForm("pwd")
- email := c.PostForm("email")
- lastName := c.PostForm("lastName")
- if len(firstName) == 0 || len(pwd) == 0 || len(email) == 0 || len(lastName) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- errInfo := service.MyService.ZeroTier().ZeroTierRegister(email, lastName, firstName, pwd)
- if len(errInfo) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
- } else {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: errInfo})
- }
-}
-
-// @Summary 是否需要登录zerotier
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Success 200 {string} string "false:需要登录,true:不需要登录"
-// @Router /zerotier/islogin [get]
-func ZeroTierIsNeedLogin(c *gin.Context) {
- if len(config.ZeroTierInfo.Token) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: false})
- } else {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: true})
- }
-}
-
-// @Summary 获取zerotier网络列表
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /zerotier/list [get]
-func ZeroTierGetNetworkList(c *gin.Context) {
- jsonList, joined := service.MyService.ZeroTier().ZeroTierNetworkList(config.ZeroTierInfo.Token)
- rdata := make(map[string]interface{})
- rdata["network_list"] = jsonList
- rdata["joined"] = joined
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: rdata})
-}
-
-// @Summary 获取zerotier网络详情
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Param id path string true "network id"
-// @Success 200 {string} string "ok"
-// @Router /zerotier/info/{id} [get]
-func ZeroTierGetNetworkGetInfo(c *gin.Context) {
- id := c.Param("id")
- if len(id) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- info, joined := service.MyService.ZeroTier().ZeroTierGetInfo(config.ZeroTierInfo.Token, id)
- rdata := make(map[string]interface{})
- rdata["info"] = info
- rdata["joined"] = joined
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: rdata})
-}
-
-//// @Summary 获取zerotier网络状态
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/status [get]
-//func ZeroTierGetNetworkGetStatus(c *gin.Context) {
-// status := service.MyService.ZeroTier().ZeroTierGetStatus(config.ZeroTierInfo.Token)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: status})
-//}
-
-//// @Summary 修改网络类型
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Param id path string true "network id"
-//// @Param type formData string true "Private true/false"
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/type/{id} [put]
-//func ZeroTierEditType(c *gin.Context) {
-// id := c.Param("id")
-// t := c.PostForm("type")
-// if len(id) == 0 || len(t) == 0 {
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-// return
-// }
-// postData := `{"config":{"private":` + t + `}}`
-// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-//}
-
-//// @Summary 修改名称
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Param id path string true "network id"
-//// @Param name formData string true "需要过滤特殊字符串"
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/name/{id} [put]
-//func ZeroTierEditName(c *gin.Context) {
-// id := c.Param("id")
-// name := c.PostForm("name")
-// if len(id) == 0 || len(name) == 0 {
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-// return
-// }
-// postData := `{"config":{"name":"` + name + `"}}`
-// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-//}
-
-//// @Summary V6Assign (注意三个属性需要一起传过来,不传的会被zerotier设置成false)
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Param id path string true "network id"
-//// @Param v6plan formData string false "true/false"
-//// @Param rfc formData string false "true/false"
-//// @Param auto formData string false "true/false"
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/v6assign/{id} [put]
-//func ZeroTierEditV6Assign(c *gin.Context) {
-// id := c.Param("id")
-// v6plan := c.PostForm("v6plan")
-// rfc := c.PostForm("rfc")
-// auto := c.PostForm("auto")
-// if len(id) == 0 {
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-// return
-// }
-// var spicing string
-// if len(v6plan) > 0 {
-// spicing = `"6plane":` + v6plan
-// }
-// if len(rfc) > 0 {
-// if len(spicing) > 0 {
-// spicing += ","
-// }
-// spicing += `"rfc4193":` + rfc
-// }
-//
-// if len(auto) > 0 {
-// if len(spicing) > 0 {
-// spicing += ","
-// }
-// spicing += `"zt":` + auto
-// }
-// postData := `{"config":{"v6AssignMode":{` + spicing + `}}}`
-// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-//}
-
-//// @Summary Broadcast
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Param id path string true "network id"
-//// @Param broadcast formData string true "true/false"
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/broadcast/{id} [put]
-//func ZeroTierEditBroadcast(c *gin.Context) {
-// id := c.Param("id")
-// broadcast := c.PostForm("broadcast")
-// if len(id) == 0 || len(broadcast) == 0 {
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-// return
-// }
-// postData := `{"config":{"enableBroadcast":` + broadcast + `}}`
-// info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, postData, id)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-//}
-
-// @Summary 网络列表
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Param id path string true "network id"
-// @Success 200 {string} string "ok"
-// @Router /zerotier/member/{id} [get]
-func ZeroTierMemberList(c *gin.Context) {
- id := c.Param("id")
- if len(id) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- info := service.MyService.ZeroTier().MemberList(config.ZeroTierInfo.Token, id)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-}
-
-// @Summary create new network
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /zerotier/create [post]
-func ZeroTierCreateNetwork(c *gin.Context) {
- info := service.MyService.ZeroTier().CreateNetwork(config.ZeroTierInfo.Token)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-}
-
-//// @Summary 通过/拒绝客户端
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Param id path string true "network id"
-//// @Param mId path string true "member_id"
-//// @Param auth formData string true "true/false"
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/member/{id}/auth/{mId} [put]
-//func ZeroTierMemberAuth(c *gin.Context) {
-// id := c.Param("id")
-// mId := c.Param("mId")
-// auth := c.PostForm("auth")
-// if len(id) == 0 || len(mId) == 0 || len(auth) == 0 {
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-// return
-// }
-// postData := `{"config":{"authorized":` + auth + `}}`
-// info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, postData, id, mId)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-//}
-
-//// @Summary 修改名字
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Param id path string true "network id"
-//// @Param mId path string true "member_id"
-//// @Param name formData string true "name"
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/member/{id}/name/{mId} [put]
-//func ZeroTierMemberName(c *gin.Context) {
-// id := c.Param("id")
-// mId := c.Param("mId")
-// name := c.PostForm("name")
-// if len(id) == 0 || len(mId) == 0 || len(name) == 0 {
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-// return
-// }
-// postData := `{"name":"` + name + `"}`
-// info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, postData, id, mId)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-//}
-
-//// @Summary 修改桥接
-//// @Produce application/json
-//// @Accept application/json
-//// @Tags zerotier
-//// @Security ApiKeyAuth
-//// @Param id path string true "network id"
-//// @Param mId path string true "member_id"
-//// @Param bridge formData string true "true/false"
-//// @Success 200 {string} string "ok"
-//// @Router /zerotier/member/{id}/bridge/{mId} [put]
-//func ZeroTierMemberBridge(c *gin.Context) {
-// id := c.Param("id")
-// mId := c.Param("mId")
-// bridge := c.PostForm("bridge")
-// if len(id) == 0 || len(mId) == 0 || len(bridge) == 0 {
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-// return
-// }
-// postData := `{"config":{"activeBridge":` + bridge + `}}`
-// info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, postData, id, mId)
-// c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-//}
-
-// @Summary 修改网络
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Param id path string true "network id"
-// @Param json formData string true "json数据"
-// @Success 200 {string} string "ok"
-// @Router /zerotier/edit/{id} [put]
-func ZeroTierEdit(c *gin.Context) {
- id := c.Param("id")
- json := c.PostForm("json")
- if len(id) == 0 || len(json) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- info := service.MyService.ZeroTier().EditNetwork(config.ZeroTierInfo.Token, json, id)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-}
-
-// @Summary 获取已加入的网络
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /zerotier/joined/list [get]
-func ZeroTierJoinedList(c *gin.Context) {
- info := service.MyService.ZeroTier().GetJoinNetworks()
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: json2.RawMessage(info)})
-}
-
-// @Summary 修改网络用户信息
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Param id path string true "network id"
-// @Param mId path string true "mId"
-// @Param json formData string true "json数据"
-// @Success 200 {string} string "ok"
-// @Router /zerotier/member/{id}/edit/{mId} [put]
-func ZeroTierMemberEdit(c *gin.Context) {
- id := c.Param("id")
- mId := c.Param("mId")
- json := c.PostForm("json")
- if len(id) == 0 || len(json) == 0 || len(mId) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- info := service.MyService.ZeroTier().EditNetworkMember(config.ZeroTierInfo.Token, json, id, mId)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-}
-
-// @Summary 删除网络中的用户
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Param id path string true "network id"
-// @Param mId path string true "member_id"
-// @Success 200 {string} string "ok"
-// @Router /zerotier/member/{id}/del/{mId} [delete]
-func ZeroTierMemberDelete(c *gin.Context) {
- id := c.Param("id")
- mId := c.Param("mId")
- if len(id) == 0 || len(mId) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- info := service.MyService.ZeroTier().DeleteMember(config.ZeroTierInfo.Token, id, mId)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-}
-
-// @Summary 删除网络
-// @Produce application/json
-// @Accept application/json
-// @Tags zerotier
-// @Security ApiKeyAuth
-// @Param id path string true "network id"
-// @Success 200 {string} string "ok"
-// @Router /zerotier/network/{id}/del [delete]
-func ZeroTierDeleteNetwork(c *gin.Context) {
- id := c.Param("id")
- if len(id) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- info := service.MyService.ZeroTier().DeleteNetwork(config.ZeroTierInfo.Token, id)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
-}
-
-// @Summary 加入网络
-// @Produce application/json
-// @Accept multipart/form-data
-// @Tags zerotier
-// @Param id path string true "network id"
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /zerotier/join/{id} [post]
-func ZeroTierJoinNetwork(c *gin.Context) {
- networkId := c.Param("id")
- if len(networkId) != 16 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- for _, v := range networkId {
- if !service.MyService.ZeroTier().NetworkIdFilter(v) {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- }
- service.MyService.ZeroTier().ZeroTierJoinNetwork(networkId)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
-}
-
-// @Summary 获取zerotier网络列表
-// @Produce application/json
-// @Accept multipart/form-data
-// @Tags zerotier
-// @Param id path string true "network id"
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /zerotier/leave/{id} [post]
-func ZeroTierLeaveNetwork(c *gin.Context) {
- networkId := c.Param("id")
-
- if len(networkId) != 16 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
-
- for _, v := range networkId {
- if !service.MyService.ZeroTier().NetworkIdFilter(v) {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
- }
- service.MyService.ZeroTier().ZeroTierLeaveNetwork(networkId)
-
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
-}
diff --git a/route/v1/zima_info.go b/route/v1/zima_info.go
index fa7ba9e..91bfda6 100644
--- a/route/v1/zima_info.go
+++ b/route/v1/zima_info.go
@@ -73,7 +73,7 @@ func NetInfo(c *gin.Context) {
if n.Name == netCardName {
item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))
- item.DateTime = time.Now()
+ item.Time = time.Now().Unix()
newNet = append(newNet, item)
break
}
diff --git a/service/casa.go b/service/casa.go
index 62c890f..1c51da9 100644
--- a/service/casa.go
+++ b/service/casa.go
@@ -22,6 +22,9 @@ type CasaService interface {
PushHeart(id, t string, language string)
PushAppAnalyse(uuid, t string, name, language string)
PushConnectionStatus(uuid, err string, from, to, event string)
+ PushUserInfo()
+ GetUserInfoByShareId(shareId string) model.UserInfo
+ GetPersonPublic() (list []model.FriendsModel)
}
type casaService struct {
@@ -118,7 +121,6 @@ func GetToken() string {
}
go func() {
str := httper2.Get(config.ServerInfo.ServerApi+"/token", nil)
-
t <- gjson.Get(str, "data").String()
}()
auth = <-t
@@ -178,13 +180,54 @@ func (o *casaService) PushConnectionStatus(uuid, err string, from, to, event str
head["Authorization"] = GetToken()
- infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/app", b, "application/json", head)
+ infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/analyse/connect", b, "application/json", head)
+
+ info := model.ServerAppList{}
+ json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
+
+}
+func (o *casaService) PushUserInfo() {
+ m := model.UserInfo{}
+ m.Desc = config.UserInfo.Description
+ m.Avatar = config.UserInfo.Avatar
+ m.NickName = config.UserInfo.NickName
+ m.ShareId = config.ServerInfo.Token
+ b, _ := json.Marshal(m)
+
+ head := make(map[string]string)
+
+ head["Authorization"] = GetToken()
+
+ infoS := httper2.Post(config.ServerInfo.ServerApi+"/v1/user/info", b, "application/json", head)
info := model.ServerAppList{}
json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
}
+func (o *casaService) GetUserInfoByShareId(shareId string) model.UserInfo {
+
+ head := make(map[string]string)
+
+ head["Authorization"] = GetToken()
+
+ infoS := httper2.Get(config.ServerInfo.ServerApi+"/v1/user/info/"+shareId, head)
+
+ info := model.UserInfo{}
+ json2.Unmarshal([]byte(gjson.Get(infoS, "data").String()), &info)
+ return info
+}
+func (o *casaService) GetPersonPublic() (list []model.FriendsModel) {
+ head := make(map[string]string)
+
+ head["Authorization"] = GetToken()
+
+ listS := httper2.Get(config.ServerInfo.ServerApi+"/v1/person/public", head)
+
+ json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list)
+
+ return list
+}
func NewCasaService() CasaService {
return &casaService{}
}
diff --git a/service/download.go b/service/download.go
index d007c31..b2b2c46 100644
--- a/service/download.go
+++ b/service/download.go
@@ -6,43 +6,51 @@ import (
)
type DownloadService interface {
- AddDownloadTask(m model2.PersionDownloadDBModel) //添加下载任务
- EditDownloadState(m model2.PersionDownloadDBModel) //只修改状态
- SaveDownload(m model2.PersionDownloadDBModel)
+ AddDownloadTask(m model2.PersonDownloadDBModel) //添加下载任务
+ EditDownloadState(m model2.PersonDownloadDBModel) //只修改状态
+ SaveDownload(m model2.PersonDownloadDBModel)
DelDownload(uuid string)
- GetDownloadById(uuid string) model2.PersionDownloadDBModel
- GetDownloadListByState(state string) []model2.PersionDownloadDBModel
- SetDownloadError(m model2.PersionDownloadDBModel)
+ GetDownloadById(uuid string) model2.PersonDownloadDBModel
+ GetDownloadListByState(state string) []model2.PersonDownloadDBModel
+ SetDownloadError(m model2.PersonDownloadDBModel)
+ GetDownloadListByPath(m model2.PersonDownloadDBModel) int
}
type downloadService struct {
db *gorm.DB
}
-func (d *downloadService) AddDownloadTask(m model2.PersionDownloadDBModel) {
+func (d *downloadService) GetDownloadListByPath(m model2.PersonDownloadDBModel) int {
+ var list []model2.PersonDownloadDBModel
+ d.db.Select("path").Where("path = ? AND `from` = ? AND state = 0", m.Path, m.From).Find(&list)
+ return len(list)
+}
+
+func (d *downloadService) AddDownloadTask(m model2.PersonDownloadDBModel) {
+
d.db.Create(&m)
}
-func (d *downloadService) EditDownloadState(m model2.PersionDownloadDBModel) {
+func (d *downloadService) EditDownloadState(m model2.PersonDownloadDBModel) {
+
d.db.Model(&m).Where("uuid = ?", m.UUID).Update("state", m.State)
}
//failed during download
-func (d *downloadService) SetDownloadError(m model2.PersionDownloadDBModel) {
+func (d *downloadService) SetDownloadError(m model2.PersonDownloadDBModel) {
d.db.Model(&m).Updates(m)
}
func (d *downloadService) DelDownload(uuid string) {
- var m model2.PersionDownloadDBModel
+ var m model2.PersonDownloadDBModel
d.db.Where("uuid = ?", uuid).Delete(&m)
}
-func (d *downloadService) GetDownloadById(uuid string) model2.PersionDownloadDBModel {
- var m model2.PersionDownloadDBModel
+func (d *downloadService) GetDownloadById(uuid string) model2.PersonDownloadDBModel {
+ var m model2.PersonDownloadDBModel
d.db.Model(m).Where("uuid = ?", uuid).First(&m)
return m
}
-func (d *downloadService) GetDownloadListByState(state string) (list []model2.PersionDownloadDBModel) {
+func (d *downloadService) GetDownloadListByState(state string) (list []model2.PersonDownloadDBModel) {
if len(state) == 0 {
d.db.Find(&list)
-
} else {
d.db.Where("state = ?", state).Find(&list)
}
@@ -50,7 +58,7 @@ func (d *downloadService) GetDownloadListByState(state string) (list []model2.Pe
return
}
-func (d *downloadService) SaveDownload(m model2.PersionDownloadDBModel) {
+func (d *downloadService) SaveDownload(m model2.PersonDownloadDBModel) {
d.db.Save(&m)
}
func NewDownloadService(db *gorm.DB) DownloadService {
diff --git a/service/friend.go b/service/friend.go
index 7a19ff0..23e7ad9 100644
--- a/service/friend.go
+++ b/service/friend.go
@@ -10,7 +10,8 @@ import (
type FriendService interface {
AddFriend(m model2.FriendModel)
DeleteFriend(m model2.FriendModel)
- EditFriendNick(m model2.FriendModel)
+ EditFriendMark(m model2.FriendModel)
+ EditFriendBlock(m model2.FriendModel)
GetFriendById(m model2.FriendModel) model2.FriendModel
GetFriendList() (list []model2.FriendModel)
UpdateAddFriendType(m model2.FriendModel)
@@ -27,17 +28,19 @@ func (p *friendService) AddFriend(m model2.FriendModel) {
func (p *friendService) DeleteFriend(m model2.FriendModel) {
p.db.Where("token = ?", m.Token).Delete(&m)
}
-func (p *friendService) EditFriendNick(m model2.FriendModel) {
- p.db.Model(&m).Where("token = ?", m.Token).Update("nick_name", m.NickName)
+func (p *friendService) EditFriendMark(m model2.FriendModel) {
+ p.db.Model(&m).Where("token = ?", m.Token).Update("mark", m.Mark)
+}
+func (p *friendService) EditFriendBlock(m model2.FriendModel) {
+ p.db.Model(&m).Where("token = ?", m.Token).Update("block", m.Block)
}
-
func (p *friendService) GetFriendById(m model2.FriendModel) model2.FriendModel {
p.db.Model(m).Where("token = ?", m.Token).First(&m)
return m
}
func (p *friendService) GetFriendList() (list []model2.FriendModel) {
- p.db.Select("nick_name", "avatar", "name", "profile", "token", "state").Find(&list)
+ p.db.Select("nick_name", "avatar", "profile", "token", "state", "mark", "block", "version").Find(&list)
return list
}
diff --git a/service/model/o_download.go b/service/model/o_download.go
index f9af0c5..5c8b1a4 100644
--- a/service/model/o_download.go
+++ b/service/model/o_download.go
@@ -1,21 +1,24 @@
package model
-type PersionDownloadDBModel struct {
+type PersonDownloadDBModel struct {
UUID string `gorm:"column:uuid;primary_key" json:"uuid"`
- State int `json:"state"` //
- Type int `json:"type"` //defult 1
- Name string `json:"name"` //file name
- Size int64 `json:"size"` //file size
- BlockSize int `json:"block_size"`
- Length int `json:"length"` //slice length
- Hash string `json:"hash"`
- Error string `json:"error"`
- From string `json:"from"`
- Already int `json:"already" gorm:"-"`
- CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
- UpdatedAt int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated_at"`
+ State int `json:"state"` //
+ Type int `json:"type"` //defult 1
+ Name string `json:"name"` //file name
+ Size int64 `json:"size"` //file size
+ BlockSize int `json:"block_size"` //Size of each file block
+ Length int `json:"length"` //slice length
+ Hash string `json:"hash"` //File hash value
+ Error string `json:"error"` //
+ From string `json:"from"` //Error message
+ Path string `json:"path"` //Full path to the file
+ Already int `json:"already" gorm:"-"` //Folder blocks that have been downloaded
+ LocalPath string `json:"local_path"` //The address where the file is saved after download
+ Duration int64 `json:"duration" gorm:"-"` //Length of time
+ Created int64 `gorm:"autoCreateTime" json:"created"`
+ Updated int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated"`
}
-func (p *PersionDownloadDBModel) TableName() string {
- return "o_persion_download"
+func (p *PersonDownloadDBModel) TableName() string {
+ return "o_person_download"
}
diff --git a/service/model/o_friend.go b/service/model/o_friend.go
index 56693bc..3d59aa9 100644
--- a/service/model/o_friend.go
+++ b/service/model/o_friend.go
@@ -1,15 +1,17 @@
package model
type FriendModel struct {
- State int `json:"state"` //备用
+ State int `json:"state"` //Reserved
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at"`
UpdatedAt int64 `gorm:"autoCreateTime;autoUpdateTime" json:"updated_at"`
- NickName string `json:"nick_name"` //custom name
- Avatar string `json:"avatar"` //头像
- Name string `json:"name"`
+ NickName string `json:"nick_name"`
+ Mark string `json:"mark"` //Remarks
+ Block bool `json:"block"` //Disable or not
+ Avatar string `json:"avatar"` //User avatar
Token string `gorm:"column:token;primary_key" json:"token"`
- Profile string `json:"profile"`
+ Profile string `json:"profile"` //Description
OnLine bool `json:"on_line" gorm:"-"`
+ Version int `json:"version"`
}
func (p *FriendModel) TableName() string {
diff --git a/service/notify.go b/service/notify.go
index 33aa539..fb56c76 100644
--- a/service/notify.go
+++ b/service/notify.go
@@ -18,6 +18,7 @@ type NotifyServer interface {
DelLog(id string)
GetList(c int) (list []model.AppNotify)
MarkRead(id string, state int)
+ SendText(m model.AppNotify)
}
type notifyServer struct {
@@ -102,6 +103,26 @@ func SendMeg() {
// }
}
+func (i notifyServer) SendText(m model.AppNotify) {
+ list := []model.AppNotify{}
+ list = append(list, m)
+ json, _ := json2.Marshal(list)
+ var temp []*websocket.Conn
+ for _, v := range WebSocketConns {
+
+ err := v.WriteMessage(1, json)
+ if err == nil {
+ temp = append(temp, v)
+ }
+ }
+ WebSocketConns = temp
+
+ if len(WebSocketConns) == 0 {
+ SocketRun = false
+ }
+
+}
+
func NewNotifyService(db *gorm.DB) NotifyServer {
return ¬ifyServer{db: db}
}
diff --git a/service/person.go b/service/person.go
index 5a3695d..25273ed 100644
--- a/service/person.go
+++ b/service/person.go
@@ -17,6 +17,7 @@ import (
"github.com/IceWhaleTech/CasaOS/pkg/quic_helper"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
+ port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/lucas-clemente/quic-go"
@@ -32,6 +33,7 @@ type personService struct {
}
var IpInfo model.PersionModel
+var CancelList map[string]string
func PushIpInfo(token string) {
@@ -63,9 +65,16 @@ var StreamList map[string]quic.Stream
var ServiceMessage chan model.MessageModel
func UDPService() {
+ port := 0
+ if len(config.ServerInfo.UDPPort) > 0 {
+ port, _ = strconv.Atoi(config.ServerInfo.UDPPort)
+ if port != 0 && !port2.IsPortAvailable(port, "udp") {
+ port = 0
+ }
+ }
srcAddr := &net.UDPAddr{
- IP: net.IPv4zero, Port: 9904}
+ IP: net.IPv4zero, Port: port}
var err error
UDPConn, err = net.ListenUDP("udp", srcAddr)
if err != nil {
@@ -146,6 +155,7 @@ func ProcessingContent(stream quic.Stream) {
prefixByte := make([]byte, 6)
_, err := io.ReadFull(stream, prefixByte)
if err != nil {
+ fmt.Println(err)
return
}
prefixLength, err := strconv.Atoi(string(prefixByte))
@@ -166,14 +176,22 @@ func ProcessingContent(stream quic.Stream) {
//nothing
continue
} else if m.Type == types.PERSONDIRECTORY {
+ friend := model2.FriendModel{}
+ friend.Token = m.From
var list []model.Path
- if m.Data.(string) == "" || m.Data.(string) == "/" {
- for _, v := range config.FileSettingInfo.ShareDir {
- tempList := MyService.ZiMa().GetDirPath(v)
- list = append(list, tempList...)
+ rFriend := MyService.Friend().GetFriendById(friend)
+ if !reflect.DeepEqual(rFriend, model2.FriendModel{Token: m.From}) && !rFriend.Block {
+ if m.Data.(string) == "" || m.Data.(string) == "/" {
+ for _, v := range config.FileSettingInfo.ShareDir {
+ //tempList := MyService.ZiMa().GetDirPath(v)
+ temp := MyService.ZiMa().GetDirPathOne(v)
+ list = append(list, temp)
+ }
+ } else {
+ list = MyService.ZiMa().GetDirPath(m.Data.(string))
}
} else {
- list = MyService.ZiMa().GetDirPath(m.Data.(string))
+ list = []model.Path{}
}
m.To = m.From
m.Data = list
@@ -185,6 +203,7 @@ func ProcessingContent(stream quic.Stream) {
SendFileData(stream, m.Data.(string), m.From, m.UUId)
break
} else if m.Type == types.PERSONADDFRIEND {
+ fmt.Println("有用户来请求加好友", m)
friend := model2.FriendModel{}
dataModelByte, _ := json.Marshal(m.Data)
err := json.Unmarshal(dataModelByte, &friend)
@@ -196,7 +215,7 @@ func ProcessingContent(stream quic.Stream) {
mi := model2.FriendModel{}
mi.Avatar = config.UserInfo.Avatar
mi.Profile = config.UserInfo.Description
- mi.Name = config.UserInfo.NickName
+ mi.NickName = config.UserInfo.NickName
m.To = m.From
m.Data = mi
m.Type = types.PERSONADDFRIEND
@@ -210,19 +229,34 @@ func ProcessingContent(stream quic.Stream) {
} else {
delete(UDPAddressMap, m.From)
}
- mi := model2.FriendModel{}
- mi.Avatar = config.UserInfo.Avatar
- mi.Profile = config.UserInfo.Description
- mi.Name = config.UserInfo.NickName
- mi.Token = config.ServerInfo.Token
+ // mi := model2.FriendModel{}
+ // mi.Avatar = config.UserInfo.Avatar
+ // mi.Profile = config.UserInfo.Description
+ // mi.NickName = config.UserInfo.NickName
+ // mi.Token = config.ServerInfo.Token
+
+ user := MyService.Casa().GetUserInfoByShareId(m.From)
+
+ friend := model2.FriendModel{}
+ friend.Token = m.From
+ friend.Avatar = user.Avatar
+ friend.Block = false
+ friend.NickName = user.NickName
+ friend.Profile = user.Avatar
+ friend.Version = user.Version
+ MyService.Friend().AddFriend(friend)
+
msg := model.MessageModel{}
- msg.Type = types.PERSONADDFRIEND
- msg.Data = mi
+ msg.Type = types.PERSONHELLO
+ msg.Data = ""
msg.To = m.From
msg.From = config.ServerInfo.Token
msg.UUId = m.UUId
Dial(msg, false)
+ break
+ } else if m.Type == types.PERSONCANCEL {
+ CancelList[m.UUId] = "cancel"
break
} else {
//不应有不做返回的数据
@@ -289,6 +323,9 @@ func SendFileData(stream quic.Stream, filePath, to, uuid string) error {
bufferedReader := bufio.NewReader(f)
buf := make([]byte, blockSize)
+
+ defer stream.Close()
+
for i := 0; i < length; i++ {
tran := model.TranFileModel{}
@@ -313,8 +350,11 @@ func SendFileData(stream quic.Stream, filePath, to, uuid string) error {
prefixLength := file.PrefixLength(len(b))
dataLength := file.DataLength(len(buf[:n]))
data := append(append(append(prefixLength, b...), dataLength...), buf[:n]...)
+ if _, ok := CancelList[uuid]; ok {
+ delete(CancelList, uuid)
+ return nil
+ }
stream.Write(data)
}
- defer stream.Close()
return nil
}
diff --git a/service/service.go b/service/service.go
index c72a91c..8eb681d 100644
--- a/service/service.go
+++ b/service/service.go
@@ -21,7 +21,6 @@ type Repository interface {
User() UserService
Docker() DockerService
//Redis() RedisService
- ZeroTier() ZeroTierService
ZiMa() ZiMaService
Casa() CasaService
Disk() DiskService
@@ -45,7 +44,6 @@ func NewService(db *gorm.DB, log loger2.OLog) Repository {
user: NewUserService(),
docker: NewDockerService(log),
//redis: NewRedisService(rp),
- zerotier: NewZeroTierService(),
zima: NewZiMaService(),
casa: NewCasaService(),
disk: NewDiskService(log, db),
@@ -68,7 +66,6 @@ type store struct {
ddns DDNSService
user UserService
docker DockerService
- zerotier ZeroTierService
zima ZiMaService
casa CasaService
disk DiskService
@@ -123,9 +120,6 @@ func (c *store) Docker() DockerService {
return c.docker
}
-func (c *store) ZeroTier() ZeroTierService {
- return c.zerotier
-}
func (c *store) ZiMa() ZiMaService {
return c.zima
}
diff --git a/service/system.go b/service/system.go
index 8e35d83..bf92a43 100644
--- a/service/system.go
+++ b/service/system.go
@@ -18,6 +18,8 @@ type SystemService interface {
UpdateAssist()
UpSystemPort(port string)
GetTimeZone() string
+ UpdateUSBAutoMount(state string)
+ ExecUSBAutoMountShell(state string)
}
type systemService struct {
log loger.OLog
@@ -37,6 +39,15 @@ func (s *systemService) GetTimeZone() string {
return command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetTimeZone")
}
+func (s *systemService) ExecUSBAutoMountShell(state string) {
+ if state == "False" {
+ command2.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;USB_Remove_File")
+ } else {
+ command2.OnlyExec("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;USB_Move_File")
+ }
+
+}
+
func (s *systemService) GetSystemConfigDebug() []string {
return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetSysInfo")
}
@@ -51,6 +62,11 @@ func (s *systemService) UpSystemConfig(str string, widget string) {
}
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
+func (s *systemService) UpdateUSBAutoMount(state string) {
+ config.ServerInfo.USBAutoMount = state
+ config.Cfg.Section("system").Key("USBAutoMount").SetValue(state)
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+}
func (s *systemService) UpSystemPort(port string) {
if len(port) > 0 && port != config.ServerInfo.HttpPort {
config.Cfg.Section("server").Key("HttpPort").SetValue(port)
diff --git a/service/udpconn.go b/service/udpconn.go
index 95ab2bc..90e3a25 100644
--- a/service/udpconn.go
+++ b/service/udpconn.go
@@ -10,6 +10,7 @@ import (
"io/ioutil"
"net"
"os"
+ path2 "path"
"strconv"
"time"
@@ -32,29 +33,52 @@ func Dial(msg model.MessageModel, server bool) (m model.MessageModel, err error)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
Message = make(chan model.MessageModel)
-
+ _, port, err := net.SplitHostPort(UDPConn.LocalAddr().String())
+ if config.ServerInfo.UDPPort != port {
+ config.ServerInfo.UDPPort = port
+ config.Cfg.Section("server").Key("UDPPort").SetValue(port)
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ }
+ p, err := strconv.Atoi(port)
srcAddr := &net.UDPAddr{
- IP: net.IPv4zero, Port: 9904} //注意端口必须固定
+ IP: net.IPv4zero, Port: p} //注意端口必须固定
addr := UDPAddressMap[msg.To]
- ticker := msg.To
+ ticket := msg.To
if server {
addr = config.ServerInfo.Handshake + ":9527"
- ticker = "bench"
+ ticket = "bench"
}
dstAddr, err := net.ResolveUDPAddr("udp", addr)
//DialTCP在网络协议net上连接本地地址laddr和远端地址raddr。net必须是"udp"、"udp4"、"udp6";如果laddr不是nil,将使用它作为本地地址,否则自动选择一个本地地址。
//(conn)UDPConn代表一个UDP网络连接,实现了Conn和PacketConn接口
- session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticker), quic_helper.GetQUICConfig())
+ session, err := quic.DialContext(ctx, UDPConn, dstAddr, srcAddr.String(), quic_helper.GetClientTlsConfig(ticket), quic_helper.GetQUICConfig())
if err != nil {
- go MyService.Casa().PushConnectionStatus(m.UUId, err.Error(), m.From, m.To, m.Type)
+ if msg.Type == types.PERSONDOWNLOAD {
+ task := MyService.Download().GetDownloadById(msg.UUId)
+ task.Error = err.Error()
+ task.State = types.DOWNLOADERROR
+ MyService.Download().SetDownloadError(task)
+ }
+ if config.SystemConfigInfo.Analyse != "False" {
+ go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type)
+ }
+
return m, err
}
stream, err := session.OpenStreamSync(ctx)
if err != nil {
- go MyService.Casa().PushConnectionStatus(m.UUId, err.Error(), m.From, m.To, m.Type)
+ if msg.Type == types.PERSONDOWNLOAD {
+ task := MyService.Download().GetDownloadById(msg.UUId)
+ task.Error = err.Error()
+ task.State = types.DOWNLOADERROR
+ MyService.Download().SetDownloadError(task)
+ }
+ if config.SystemConfigInfo.Analyse != "False" {
+ go MyService.Casa().PushConnectionStatus(msg.UUId, err.Error(), msg.From, msg.To, msg.Type)
+ }
session.CloseWithError(1, err.Error())
return m, err
}
@@ -66,7 +90,9 @@ func Dial(msg model.MessageModel, server bool) (m model.MessageModel, err error)
go ReadContent(stream)
result := <-Message
stream.Close()
- go MyService.Casa().PushConnectionStatus(m.UUId, "OK", m.From, m.To, m.Type)
+ if config.SystemConfigInfo.Analyse != "False" {
+ go MyService.Casa().PushConnectionStatus(msg.UUId, "OK", msg.From, msg.To, msg.Type)
+ }
return result, nil
}
@@ -88,8 +114,6 @@ func SendData(stream quic.Stream, m model.MessageModel) {
stream.Write(data)
}
-var Summary map[string]model.FileSummaryModel
-
//读取数据
func ReadContent(stream quic.Stream) {
for {
@@ -97,6 +121,12 @@ func ReadContent(stream quic.Stream) {
_, err := io.ReadFull(stream, prefixByte)
if err != nil {
fmt.Println(err)
+ time.Sleep(time.Second * 1)
+ for k, v := range CancelList {
+ tempPath := config.AppInfo.RootPath + "/temp" + "/" + v
+ fmt.Println(file.RMDir(tempPath))
+ delete(CancelList, k)
+ }
break
}
prefixLength, err := strconv.Atoi(string(prefixByte))
@@ -112,12 +142,14 @@ func ReadContent(stream quic.Stream) {
}
m := model.MessageModel{}
err = json.Unmarshal(messageByte, &m)
+ fmt.Println("客户端", m)
if err != nil {
fmt.Println(err)
break
}
if m.Type == types.PERSONDOWNLOAD {
+
dataModelByte, _ := json.Marshal(m.Data)
dataModel := model.TranFileModel{}
err := json.Unmarshal(dataModelByte, &dataModel)
@@ -149,29 +181,32 @@ func ReadContent(stream quic.Stream) {
fmt.Println("hash不匹配", hash, dataModel.Hash)
continue
}
-
tempPath := config.AppInfo.RootPath + "/temp" + "/" + m.UUId
file.IsNotExistMkDir(tempPath)
filepath := tempPath + "/" + strconv.Itoa(dataModel.Index)
- tempFile, err := os.Stat(filepath)
+ _, err = os.Stat(filepath)
- if os.IsNotExist(err) || tempFile.Size() == 0 {
+ if os.IsNotExist(err) {
err = ioutil.WriteFile(filepath, dataByte, 0644)
- task := model2.PersionDownloadDBModel{}
+ task := model2.PersonDownloadDBModel{}
task.UUID = m.UUId
- task.Error = err.Error()
- task.State = types.DOWNLOADERROR
- MyService.Download().SetDownloadError(task)
+ if err != nil {
+ task.Error = err.Error()
+ task.State = types.DOWNLOADERROR
+ MyService.Download().SetDownloadError(task)
+ }
} else {
if file.GetHashByPath(filepath) != dataModel.Hash {
os.Remove(filepath)
err = ioutil.WriteFile(filepath, dataByte, 0644)
- task := model2.PersionDownloadDBModel{}
+ task := model2.PersonDownloadDBModel{}
task.UUID = m.UUId
- task.Error = err.Error()
- task.State = types.DOWNLOADERROR
- MyService.Download().SetDownloadError(task)
+ if err != nil {
+ task.Error = err.Error()
+ task.State = types.DOWNLOADERROR
+ MyService.Download().SetDownloadError(task)
+ }
}
}
@@ -181,21 +216,21 @@ func ReadContent(stream quic.Stream) {
continue
}
if len(files) >= dataModel.Length {
- summary := Summary[m.UUId]
- file.SpliceFiles(tempPath, config.FileSettingInfo.DownloadDir+"/"+summary.Name, dataModel.Length, 0)
- if file.GetHashByPath(config.FileSettingInfo.DownloadDir+"/"+summary.Name) == summary.Hash {
+ summary := MyService.Download().GetDownloadById(m.UUId)
+ summary.State = types.DOWNLOADFINISH
+ MyService.Download().EditDownloadState(summary)
+ fullPath := file.GetNoDuplicateFileName(path2.Join(summary.LocalPath, summary.Name))
+ file.SpliceFiles(tempPath, fullPath, dataModel.Length, 0)
+ if file.GetHashByPath(fullPath) == summary.Hash {
file.RMDir(tempPath)
- task := model2.PersionDownloadDBModel{}
- task.UUID = m.UUId
- task.State = types.DOWNLOADFINISH
- MyService.Download().EditDownloadState(task)
- delete(Summary, m.UUId)
+ summary.State = types.DOWNLOADFINISHED
+ MyService.Download().EditDownloadState(summary)
} else {
os.Remove(config.FileSettingInfo.DownloadDir + "/" + summary.Name)
- task := model2.PersionDownloadDBModel{}
- task.UUID = m.UUId
- task.State = types.DOWNLOADERROR
- MyService.Download().EditDownloadState(task)
+
+ summary.State = types.DOWNLOADERROR
+ summary.Error = "hash mismatch"
+ MyService.Download().SetDownloadError(summary)
}
break
@@ -205,42 +240,55 @@ func ReadContent(stream quic.Stream) {
dataModel := model.FileSummaryModel{}
dataModelByte, _ := json.Marshal(m.Data)
err := json.Unmarshal(dataModelByte, &dataModel)
- fmt.Println(err)
+ if err != nil {
+ fmt.Println(err)
+ }
- task := model2.PersionDownloadDBModel{}
- task.UUID = m.UUId
- task.Name = dataModel.Name
- task.Length = dataModel.Length
- task.Size = dataModel.Size
+ task := MyService.Download().GetDownloadById(m.UUId)
+ fullPath := path2.Join(task.LocalPath, task.Name)
task.State = types.DOWNLOADING
- task.BlockSize = dataModel.BlockSize
- task.Hash = dataModel.Hash
- task.Type = 0
- task.From = m.From
if len(dataModel.Message) > 0 {
task.State = types.DOWNLOADERROR
task.Error = dataModel.Message
}
+ if file.Exists(fullPath) && file.GetHashByPath(fullPath) == dataModel.Hash {
+ task.State = types.DOWNLOADFINISHED
+ go func(from, uuid string) {
+ m := model.MessageModel{}
+ m.Data = ""
+ m.From = config.ServerInfo.Token
+ m.To = from
+ m.Type = types.PERSONCANCEL
+ m.UUId = uuid
+ CancelList[uuid] = uuid
+ Dial(m, false)
+ }(task.From, task.UUID)
+ }
+ task.UUID = m.UUId
+ task.Name = dataModel.Name
+ task.Length = dataModel.Length
+ task.Size = dataModel.Size
+ task.BlockSize = dataModel.BlockSize
+ task.Hash = dataModel.Hash
+ task.Type = 0
+ task.From = m.From
MyService.Download().SaveDownload(task)
- Summary[m.UUId] = dataModel
-
} else if m.Type == types.PERSONCONNECTION {
-
if len(m.Data.(string)) > 0 {
UDPAddressMap[m.From] = m.Data.(string)
} else {
delete(UDPAddressMap, m.From)
}
- mi := model2.FriendModel{}
- mi.Avatar = config.UserInfo.Avatar
- mi.Profile = config.UserInfo.Description
- mi.Name = config.UserInfo.NickName
- mi.Token = config.ServerInfo.Token
+ // mi := model2.FriendModel{}
+ // mi.Avatar = config.UserInfo.Avatar
+ // mi.Profile = config.UserInfo.Description
+ // mi.NickName = config.UserInfo.NickName
+ // mi.Token = config.ServerInfo.Token
msg := model.MessageModel{}
- msg.Type = types.PERSONADDFRIEND
- msg.Data = mi
+ msg.Type = types.PERSONHELLO
+ msg.Data = ""
msg.To = m.From
msg.From = config.ServerInfo.Token
msg.UUId = m.UUId
@@ -248,10 +296,21 @@ func ReadContent(stream quic.Stream) {
Message <- m
break
} else if m.Type == "get_ip" {
+ notify := model2.AppNotify{}
+ notify.CustomId = m.From
if len(m.Data.(string)) == 0 {
+ if _, ok := UDPAddressMap[m.From]; ok {
+ notify.Type = types.NOTIFY_TYPE_PERSION_FIRNED_LEAVE
+ go MyService.Notify().SendText(notify)
+ }
delete(UDPAddressMap, m.From)
+ Message <- m
break
}
+ if _, ok := UDPAddressMap[m.From]; !ok {
+ notify.Type = types.NOTIFY_TYPE_PERSION_FIRNED_LIVE
+ go MyService.Notify().SendText(notify)
+ }
UDPAddressMap[m.From] = m.Data.(string)
Message <- m
break
@@ -264,7 +323,7 @@ func ReadContent(stream quic.Stream) {
func SendIPToServer() {
msg := model.MessageModel{}
- msg.Type = "hello"
+ msg.Type = types.PERSONHELLO
msg.Data = ""
msg.From = config.ServerInfo.Token
msg.To = config.ServerInfo.Token
@@ -282,9 +341,10 @@ func LoopFriend() {
msg.From = config.ServerInfo.Token
msg.To = list[i].Token
msg.UUId = uuid.NewV4().String()
+
Dial(msg, true)
- msg.Type = "hello"
+ msg.Type = types.PERSONHELLO
msg.Data = ""
msg.From = config.ServerInfo.Token
msg.To = list[i].Token
@@ -292,6 +352,19 @@ func LoopFriend() {
if _, ok := UDPAddressMap[list[i].Token]; ok {
go Dial(msg, false)
}
+ go func(shareId string) {
+ user := MyService.Casa().GetUserInfoByShareId(shareId)
+ m := model2.FriendModel{}
+ m.Token = shareId
+ friend := MyService.Friend().GetFriendById(m)
+ if friend.Version != user.Version {
+ friend.Avatar = user.Avatar
+ friend.NickName = user.NickName
+ friend.Profile = user.Desc
+ friend.Version = user.Version
+ MyService.Friend().UpdateOrCreate(friend)
+ }
+ }(list[i].Token)
}
}
diff --git a/service/zerotier.go b/service/zerotier.go
deleted file mode 100644
index d1b7862..0000000
--- a/service/zerotier.go
+++ /dev/null
@@ -1,353 +0,0 @@
-package service
-
-import (
- "bytes"
- "errors"
- "fmt"
- "io/ioutil"
- "math/rand"
- "net/http"
- "strconv"
- "strings"
- "time"
- "unicode"
-
- "github.com/IceWhaleTech/CasaOS/pkg/config"
- command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
- httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
- "github.com/IceWhaleTech/CasaOS/pkg/zerotier"
- "github.com/PuerkitoBio/goquery"
- "github.com/tidwall/gjson"
-)
-
-type ZeroTierService interface {
- GetToken(username, pwd string) string
- ZeroTierRegister(email, lastName, firstName, password string) string
- ZeroTierNetworkList(token string) (interface{}, []string)
- ZeroTierJoinNetwork(networkId string)
- ZeroTierLeaveNetwork(networkId string)
- ZeroTierGetInfo(token, id string) (interface{}, []string)
- ZeroTierGetStatus(token string) interface{}
- EditNetwork(token string, data string, id string) interface{}
- CreateNetwork(token string) interface{}
- MemberList(token string, id string) interface{}
- EditNetworkMember(token string, data string, id, mId string) interface{}
- DeleteMember(token string, id, mId string) interface{}
- DeleteNetwork(token, id string) interface{}
- GetJoinNetworks() string
- NetworkIdFilter(letter rune) bool
-}
-type zerotierStruct struct {
-}
-
-var client http.Client
-
-func (c *zerotierStruct) ZeroTierJoinNetwork(networkId string) {
- command2.OnlyExec(`zerotier-cli join ` + networkId)
-}
-func (c *zerotierStruct) ZeroTierLeaveNetwork(networkId string) {
- command2.OnlyExec(`zerotier-cli leave ` + networkId)
-}
-
-//登录并获取token
-func (c *zerotierStruct) GetToken(username, pwd string) string {
- if len(config.ZeroTierInfo.Token) > 0 {
- return config.ZeroTierInfo.Token
- } else {
- return LoginGetToken(username, pwd)
- }
-}
-
-func (c *zerotierStruct) ZeroTierRegister(email, lastName, firstName, password string) string {
-
- url := "https://accounts.zerotier.com/auth/realms/zerotier/protocol/openid-connect/registrations?client_id=zt-central&redirect_uri=https%3A%2F%2Fmy.zerotier.com%2Fapi%2F_auth%2Foidc%2Fcallback&response_type=code&scope=openid+profile+email+offline_access&state=state"
-
- action, cookies, _ := ZeroTierGet(url, nil, 4)
- var buff bytes.Buffer
- buff.WriteString("email=")
- buff.WriteString(email)
- buff.WriteString("&password=")
- buff.WriteString(password)
- buff.WriteString("&password-confirm=")
- buff.WriteString(password)
- buff.WriteString("&user.attributes.marketingOptIn=true")
- buff.WriteString("&firstName")
- buff.WriteString(firstName)
- buff.WriteString("&lastName")
- buff.WriteString(lastName)
-
- action, errInfo, _ := ZeroTierPost(buff, action, cookies, false)
- if len(errInfo) > 0 {
- return errInfo
- }
- action, _, _ = ZeroTierGet(action, cookies, 5)
- return ""
-}
-
-//固定请求head
-func GetHead() map[string]string {
- var head = make(map[string]string, 4)
- head["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
- head["Accept-Language"] = "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"
- head["Connection"] = "keep-alive"
- head["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36"
- return head
-}
-
-//登录并获取token,会出现账号密码错误,和邮箱未验证情况,目前未出现其他情况
-func LoginGetToken(username, pwd string) string {
- //拿到登录的action
- var loginUrl = "https://accounts.zerotier.com/auth/realms/zerotier/protocol/openid-connect/auth?client_id=zt-central&redirect_uri=https%3A%2F%2Fmy.zerotier.com%2Fapi%2F_auth%2Foidc%2Fcallback&response_type=code&scope=openid+profile+email+offline_access&state=states"
- action, cookies, _ := ZeroTierGet(loginUrl, nil, 1)
- if len(action) == 0 {
- //没有拿到action,页面结构变了
- return ""
- }
- //登录
- var str bytes.Buffer
- str.WriteString("username=")
- str.WriteString(username)
- str.WriteString("&password=")
- str.WriteString(pwd)
- str.WriteString("&credentialId=&login=Log+In")
- url, logingErrInfo, _ := ZeroTierPost(str, action, cookies, true)
-
- action, cookies, isLoginOk := ZeroTierGet(url, cookies, 2)
-
- if isLoginOk {
- //登录成功,可以继续调用api
- randomTokenUrl := "https://my.zerotier.com/api/randomToken"
- json, _, _ := ZeroTierGet(randomTokenUrl, cookies, 3)
- //获取一个随机token
- token := gjson.Get(json, "token")
-
- userInfoUrl := "https://my.zerotier.com/api/status"
- json, _, _ = ZeroTierGet(userInfoUrl, cookies, 3)
- //拿到用户id
- userId := gjson.Get(json, "user.id")
-
- //设置新token
- addTokenUrl := "https://my.zerotier.com/api/user/" + userId.String() + "/token"
- data := make(map[string]string)
- rand.Seed(time.Now().UnixNano())
- data["tokenName"] = "oasis-token-" + strconv.Itoa(rand.Intn(1000))
- data["token"] = token.String()
- head := make(map[string]string)
- head["Content-Type"] = "application/json"
- _, statusCode := httper2.ZeroTierPost(addTokenUrl, data, head, cookies)
- if statusCode == http.StatusOK {
- config.Cfg.Section("zerotier").Key("Token").SetValue(token.String())
- config.Cfg.SaveTo("conf/conf.ini")
- config.ZeroTierInfo.Token = token.String()
- }
- } else {
- //登录错误信息
- if len(logingErrInfo) > 0 {
- return logingErrInfo
- } else {
- //验证邮箱
- action, _, _ = ZeroTierGet(url, cookies, 5)
- return "You need to verify your email address to activate your account."
- }
- }
- return ""
-}
-
-// t 1:获取action,2:登录成功后拿session(可能需要验证有了或登录失败) 3:随机生成token 4:注册页面拿action 5:注册成功后拿验证邮箱的地址
-func ZeroTierGet(url string, cookies []*http.Cookie, t uint8) (action string, c []*http.Cookie, isExistSession bool) {
- isExistSession = false
- action = ""
- c = []*http.Cookie{}
- request, _ := http.NewRequest(http.MethodGet, url, nil)
- for k, v := range GetHead() {
- request.Header.Add(k, v)
- }
- for _, cookie := range cookies {
- request.AddCookie(cookie)
- }
- resp, err := client.Do(request)
- if err != nil {
- return
- }
- defer resp.Body.Close()
- c = resp.Cookies()
- if t == 1 {
- doc, err := goquery.NewDocumentFromReader(resp.Body)
- if err != nil {
- return
- }
- action, _ = doc.Find("#kc-form-login").Attr("action")
- return
- } else if t == 2 {
- for _, cookie := range resp.Cookies() {
- if cookie.Name == "pgx-session" {
- isExistSession = true
- break
- }
- }
- //判断是否登录成功,如果需要验证邮箱,则返回验证邮箱的地址。
- if resp.StatusCode == http.StatusFound && len(resp.Header.Get("Location")) > 0 {
- action = resp.Header.Get("Location")
- }
- return
- } else if t == 3 {
- //返回获取到的字符串
- byteArr, _ := ioutil.ReadAll(resp.Body)
- action = string(byteArr)
- } else if t == 4 {
- doc, err := goquery.NewDocumentFromReader(resp.Body)
- if err != nil {
- return
- }
- action, _ = doc.Find("#kc-register-form").Attr("action")
- return
-
- } else if t == 5 {
- doc, _ := goquery.NewDocumentFromReader(resp.Body)
- fmt.Println(doc.Html())
- action, _ = doc.Find("#kc-info-wrapper a").Attr("href")
- return
- }
-
- return
-}
-
-//模拟提交表单
-func ZeroTierPost(str bytes.Buffer, action string, cookies []*http.Cookie, isLogin bool) (url, errInfo string, err error) {
- req, err := http.NewRequest(http.MethodPost, action, strings.NewReader(str.String()))
- if err != nil {
- return "", "", errors.New("newrequest error")
- }
- for k, v := range GetHead() {
- req.Header.Set(k, v)
- }
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- for _, cookie := range cookies {
- req.AddCookie(cookie)
- }
- res, err := client.Do(req)
- defer res.Body.Close()
- if err != nil {
- return "", "", errors.New("request error")
- }
- if !isLogin {
- //注册成功
- if res.StatusCode == http.StatusFound && len(res.Header.Get("Location")) > 0 {
- return res.Header.Get("Location"), "", nil
- } else {
- register, _ := goquery.NewDocumentFromReader(res.Body)
- firstErr := strings.TrimSpace(register.Find("#input-error-firstname").Text())
- lastErr := strings.TrimSpace(register.Find("#input-error-lastname").Text())
- emailErr := strings.TrimSpace(register.Find("#input-error-email").Text())
- pwdErr := strings.TrimSpace(register.Find("#input-error-password").Text())
- var errD strings.Builder
- if len(firstErr) > 0 {
- errD.WriteString(firstErr + ",")
- }
- if len(lastErr) > 0 {
- errD.WriteString(lastErr + ",")
- }
- if len(emailErr) > 0 {
- errD.WriteString(emailErr + ",")
- }
- if len(pwdErr) > 0 {
- errD.WriteString(pwdErr + ",")
- }
- return "", errD.String(), nil
- }
-
- } else {
- if res.StatusCode == http.StatusFound && len(res.Header.Get("Location")) > 0 {
- return res.Header.Get("Location"), "", nil
- }
- doc, err := goquery.NewDocumentFromReader(res.Body)
- if err != nil {
- return "", "", errors.New("request error")
- }
-
- errDesc := doc.Find("#input-error").Text()
- if len(errDesc) > 0 {
- return "", strings.TrimSpace(errDesc), nil
- }
-
- }
-
- return "", "", nil
-}
-
-//获取zerotile网络列表和本地用户已加入的网络
-func (c *zerotierStruct) ZeroTierNetworkList(token string) (interface{}, []string) {
- url := "https://my.zerotier.com/api/network"
- return zerotier.GetData(url, token), command2.ExecResultStrArray(`zerotier-cli listnetworks | awk 'NR>1 {print $3} {line=$0}'`)
-}
-
-// get network info
-func (c *zerotierStruct) ZeroTierGetInfo(token, id string) (interface{}, []string) {
- url := "https://my.zerotier.com/api/network/" + id
- info := zerotier.GetData(url, token)
- return info, command2.ExecResultStrArray(`zerotier-cli listnetworks | awk 'NR>1 {print $3} {line=$0}'`)
-}
-
-//get status
-func (c *zerotierStruct) ZeroTierGetStatus(token string) interface{} {
- url := "https://my.zerotier.com/api/v1/status"
- info := zerotier.GetData(url, token)
- return info
-}
-
-func (c *zerotierStruct) EditNetwork(token string, data string, id string) interface{} {
- url := "https://my.zerotier.com/api/v1/network/" + id
- info := zerotier.PostData(url, token, data)
- return info
-}
-
-func (c *zerotierStruct) EditNetworkMember(token string, data string, id, mId string) interface{} {
- url := "https://my.zerotier.com/api/v1/network/" + id + "/member/" + mId
- info := zerotier.PostData(url, token, data)
- return info
-}
-
-func (c *zerotierStruct) MemberList(token string, id string) interface{} {
- url := "https://my.zerotier.com/api/v1/network/" + id + "/member"
- info := zerotier.GetData(url, token)
- return info
-}
-
-func (c *zerotierStruct) DeleteMember(token string, id, mId string) interface{} {
- url := "https://my.zerotier.com/api/v1/network/" + id + "/member/" + mId
- info := zerotier.DeleteMember(url, token)
- return info
-}
-
-func (c *zerotierStruct) DeleteNetwork(token, id string) interface{} {
- url := "https://my.zerotier.com/api/v1/network/" + id
- info := zerotier.DeleteMember(url, token)
- return info
-}
-
-func (c *zerotierStruct) CreateNetwork(token string) interface{} {
- url := "https://my.zerotier.com/api/v1/network"
- info := zerotier.PostData(url, token, "{}")
- return info
-}
-
-func (c *zerotierStruct) GetJoinNetworks() string {
- json := command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetLocalJoinNetworks")
- return json
-}
-
-func (c *zerotierStruct) NetworkIdFilter(letter rune) bool {
- if unicode.IsNumber(letter) || unicode.IsLetter(letter) {
- return true
- } else {
- return false
- }
-}
-func NewZeroTierService() ZeroTierService {
- //初始化client
- client = http.Client{Timeout: 30 * time.Second, CheckRedirect: func(req *http.Request, via []*http.Request) error {
- return http.ErrUseLastResponse //禁止重定向
- },
- }
- return &zerotierStruct{}
-}
diff --git a/service/zima_info.go b/service/zima_info.go
index 49c1667..0ff66c5 100644
--- a/service/zima_info.go
+++ b/service/zima_info.go
@@ -4,10 +4,12 @@ import (
"fmt"
"io/ioutil"
"os"
+ "path/filepath"
"runtime"
"strconv"
"strings"
"time"
+ "unsafe"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
@@ -32,12 +34,15 @@ type ZiMaService interface {
GetNetState(name string) string
GetSysInfo() host.InfoStat
GetDirPath(path string) []model.Path
+ GetDirPathOne(path string) (m model.Path)
MkdirAll(path string) (int, error)
CreateFile(path string) (int, error)
RenameFile(oldF, newF string) (int, error)
GetCpuInfo() []cpu.InfoStat
}
+var NetArray [][]model.IOCountersStat
+
type zima struct {
}
@@ -84,10 +89,19 @@ func (c *zima) GetDirPath(path string) []model.Path {
ls, _ := ioutil.ReadDir(path)
dirs := []model.Path{}
-
if len(path) > 0 {
for _, l := range ls {
- dirs = append(dirs, model.Path{Name: l.Name(), Path: path + "/" + l.Name(), IsDir: l.IsDir(), Date: l.ModTime(), Size: l.Size()})
+ filePath := filepath.Join(path, l.Name())
+ link, err := filepath.EvalSymlinks(filePath)
+ if err != nil {
+ link = filePath
+ }
+ temp := model.Path{Name: l.Name(), Path: filePath, IsDir: l.IsDir(), Date: l.ModTime(), Size: l.Size()}
+ if filePath != link {
+ file, _ := os.Stat(link)
+ temp.IsDir = file.IsDir()
+ }
+ dirs = append(dirs, temp)
}
} else {
dirs = append(dirs, model.Path{Name: "DATA", Path: "/DATA/", IsDir: true, Date: time.Now()})
@@ -95,6 +109,21 @@ func (c *zima) GetDirPath(path string) []model.Path {
return dirs
}
+func (c *zima) GetDirPathOne(path string) (m model.Path) {
+
+ f, err := os.Stat(path)
+
+ if err != nil {
+ return
+ }
+ m.IsDir = f.IsDir()
+ m.Name = f.Name()
+ m.Path = path
+ m.Size = f.Size()
+ m.Date = f.ModTime()
+ return
+}
+
//获取系统信息
func (c *zima) GetSysInfo() host.InfoStat {
info, _ := host.Info()
@@ -174,3 +203,41 @@ func (c *zima) RenameFile(oldF, newF string) (int, error) {
func NewZiMaService() ZiMaService {
return &zima{}
}
+
+func LoopNet() {
+ netList := MyService.ZiMa().GetNetInfo()
+
+ nets := MyService.ZiMa().GetNet(true)
+ num := 0
+ for i := 0; i < len(netList); i++ {
+
+ for _, netCardName := range nets {
+
+ if netList[i].Name == netCardName {
+ var netArray []model.IOCountersStat
+ if len(NetArray) < (num + 1) {
+ netArray = []model.IOCountersStat{}
+ } else {
+ netArray = NetArray[num]
+ }
+ item := *(*model.IOCountersStat)(unsafe.Pointer(&netList[i]))
+ item.State = strings.TrimSpace(MyService.ZiMa().GetNetState(netList[i].Name))
+ item.Time = time.Now().Unix()
+
+ if len(netArray) >= 60 {
+ netArray = netArray[1:]
+ }
+ netArray = append(netArray, item)
+ if len(NetArray) < (num + 1) {
+ NetArray = append(NetArray, []model.IOCountersStat{})
+ }
+
+ NetArray[num] = netArray
+
+ num++
+ break
+ }
+ }
+
+ }
+}
diff --git a/shell/assist.sh b/shell/assist.sh
index d4fbe1d..a1686e8 100644
--- a/shell/assist.sh
+++ b/shell/assist.sh
@@ -1,13 +1,6 @@
#!/bin/bash
-#add in v0.2.3
-version_0_2_3() {
- ((EUID)) && sudo_cmd="sudo"
- $sudo_cmd cp -rf /casaOS/server/shell/11-usb-mount.rules /etc/udev/rules.d/
- $sudo_cmd chmod +x /casaOS/server/shell/usb-mount.sh
- $sudo_cmd cp -rf /casaOS/server/shell/usb-mount@.service /etc/systemd/system/
-}
# add in v0.2.5
@@ -16,7 +9,9 @@ readonly CASA_DEPANDS="curl smartmontools parted fdisk ntfs-3g"
version_0_2_5() {
install_depends "$CASA_DEPANDS"
}
-
+version_0_2_11() {
+ sysctl -w net.core.rmem_max=2500000
+}
#Install Depends
install_depends() {
@@ -35,6 +30,6 @@ install_depends() {
fi
}
-version_0_2_3
-
version_0_2_5
+
+version_0_2_11
diff --git a/shell/helper.sh b/shell/helper.sh
index b48061f..dad3742 100644
--- a/shell/helper.sh
+++ b/shell/helper.sh
@@ -245,9 +245,13 @@ do_umount() {
if [[ -z ${MOUNT_POINT} ]]; then
${log} "Warning: ${DEVICE} is not mounted"
else
+ /bin/kill -9 $(lsof ${MOUNT_POINT})
umount -l ${DEVICE}
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
- /bin/rmdir "${MOUNT_POINT}"
+ if [ "`ls -A ${MOUNT_POINT}`" = "" ]; then
+ /bin/rm -fr "${MOUNT_POINT}"
+ fi
+
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
fi
@@ -325,3 +329,16 @@ TarFolder() {
#查看固定文件夹大小
du -sh /DATA
}
+
+USB_Move_File() {
+ ((EUID)) && sudo_cmd="sudo"
+ $sudo_cmd cp -rf /casaOS/server/shell/11-usb-mount.rules /etc/udev/rules.d/
+ $sudo_cmd chmod +x /casaOS/server/shell/usb-mount.sh
+ $sudo_cmd cp -rf /casaOS/server/shell/usb-mount@.service /etc/systemd/system/
+}
+
+USB_Remove_File() {
+ ((EUID)) && sudo_cmd="sudo"
+ $sudo_cmd rm -fr /etc/udev/rules.d/11-usb-mount.rules
+ $sudo_cmd rm -fr /etc/systemd/system/usb-mount@.service
+}
\ No newline at end of file
diff --git a/shell/usb-mount.sh b/shell/usb-mount.sh
index 0376bb9..f6b6139 100644
--- a/shell/usb-mount.sh
+++ b/shell/usb-mount.sh
@@ -12,7 +12,7 @@ DEVBASE=$2
DEVICE="/dev/${DEVBASE}"
# See if this drive is already mounted, and if so where
-MOUNT_POINT=$(lsblk -o name,mountpoint | grep ${DEVICE} | awk '{print $2}')
+MOUNT_POINT=$(lsblk -l -p -o name,mountpoint | grep ${DEVICE} | awk '{print $2}')
do_mount() {
@@ -112,9 +112,12 @@ do_umount() {
if [[ -z ${MOUNT_POINT} ]]; then
${log} "Warning: ${DEVICE} is not mounted"
else
+ #/bin/kill -9 $(lsof ${MOUNT_POINT})
umount -l ${DEVICE}
${log} "Unmounted ${DEVICE} from ${MOUNT_POINT}"
- /bin/rmdir "${MOUNT_POINT}"
+ if [ "`ls -A ${MOUNT_POINT}`" = "" ]; then
+ /bin/rm -fr "${MOUNT_POINT}"
+ fi
sed -i.bak "\@${MOUNT_POINT}@d" /var/log/usb-mount.track
fi
diff --git a/types/notify.go b/types/notify.go
index 98999ca..1b7f1df 100644
--- a/types/notify.go
+++ b/types/notify.go
@@ -10,6 +10,8 @@ const (
NOTIFY_TYPE_NEED_CONFIRM
NOTIFY_TYPE_ERROR
NOTIFY_TYPE_INSTALL_LOG
+ NOTIFY_TYPE_PERSION_FIRNED_LEAVE
+ NOTIFY_TYPE_PERSION_FIRNED_LIVE
)
const (
diff --git a/types/persion.go b/types/person.go
similarity index 81%
rename from types/persion.go
rename to types/person.go
index 440de5c..7e6e1a8 100644
--- a/types/persion.go
+++ b/types/person.go
@@ -6,3 +6,4 @@ const PERSONSUMMARY = "summary"
const PERSONCONNECTION = "connection"
const PERSONDIRECTORY = "directory"
const PERSONHELLO = "hello"
+const PERSONCANCEL = "cancel" // Cancel Download
diff --git a/types/persion_download.go b/types/person_download.go
similarity index 87%
rename from types/persion_download.go
rename to types/person_download.go
index c0a5f82..01aeb6e 100644
--- a/types/persion_download.go
+++ b/types/person_download.go
@@ -6,4 +6,5 @@ const (
DOWNLOADPAUSE
DOWNLOADFINISH
DOWNLOADERROR
+ DOWNLOADFINISHED
)
diff --git a/types/system.go b/types/system.go
index f9d3235..54bf050 100644
--- a/types/system.go
+++ b/types/system.go
@@ -1,5 +1,5 @@
package types
-const CURRENTVERSION = "0.2.10"
+const CURRENTVERSION = "0.3.0"
-const BODY = "
Added CasaOS own file managerFixed the problem of failed to create storage space"
+const BODY = "Add CasaConnect function, now you can share private files peer-to-peer with your friends.Add a widget for network traffic monitoringUpdated the initial directory of Files to the Root directoryFix the application ipv6 opening problem"
diff --git a/web/img/1-small.1b74d2ba.png b/web/img/1-small.1b74d2ba.png
new file mode 100644
index 0000000..406d0ba
Binary files /dev/null and b/web/img/1-small.1b74d2ba.png differ
diff --git a/web/img/folder-publicshare.0219e0d4.svg b/web/img/folder-publicshare.0219e0d4.svg
new file mode 100644
index 0000000..8d5b97b
--- /dev/null
+++ b/web/img/folder-publicshare.0219e0d4.svg
@@ -0,0 +1,55 @@
+
+
diff --git a/web/img/folder.c8ff81f3.png b/web/img/folder.c8ff81f3.png
deleted file mode 100644
index 7610989..0000000
Binary files a/web/img/folder.c8ff81f3.png and /dev/null differ
diff --git a/web/img/xfile.402f9e59.png b/web/img/xfile.402f9e59.png
deleted file mode 100644
index ee02ec8..0000000
Binary files a/web/img/xfile.402f9e59.png and /dev/null differ
diff --git a/web/index.html b/web/index.html
index 93bd501..5e67b80 100644
--- a/web/index.html
+++ b/web/index.html
@@ -20,7 +20,7 @@
CasaOS
-
+