Add merge json (#1079)

This commit is contained in:
link 2023-05-15 11:01:21 +08:00 committed by GitHub
parent 538639b623
commit 280ad4fcf9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 281 additions and 76 deletions

71
main.go
View file

@ -5,21 +5,27 @@ package main
import (
"context"
_ "embed"
"encoding/base64"
"encoding/json"
"flag"
"fmt"
"net"
"net/http"
"path/filepath"
"strconv"
"time"
"github.com/IceWhaleTech/CasaOS-Common/model"
"github.com/IceWhaleTech/CasaOS-Common/utils/constants"
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
"github.com/tidwall/gjson"
"golang.org/x/net/websocket"
util_http "github.com/IceWhaleTech/CasaOS-Common/utils/http"
"github.com/IceWhaleTech/CasaOS/codegen/message_bus"
"github.com/IceWhaleTech/CasaOS/common"
model2 "github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/cache"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
@ -80,7 +86,8 @@ func init() {
service.GetCPUThermalZone()
route.InitFunction()
go SendToSocket(service.MyService.System().GetDeviceInfo())
service.MyService.System().GenreateSystemEntry()
///
//service.MountLists = make(map[string]*mountlib.MountPoint)
//configfile.Install()
@ -101,7 +108,7 @@ func main() {
if *versionFlag {
return
}
go Special(service.MyService)
v1Router := route.InitV1Router()
v2Router := route.InitV2Router()
@ -229,3 +236,63 @@ func main() {
panic(err)
}
}
func Special(myservice service.Repository) {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "*")
m := myservice.System().GetDeviceInfo()
jsonData, err := json.Marshal(m)
if err != nil {
fmt.Println("Error:", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
fmt.Fprintln(w, string(jsonData))
})
if err := http.ListenAndServe(":9527", nil); err != nil {
fmt.Println("Error:", err)
}
}
func SendToSocket(m model2.DeviceInfo) {
if len(m.DeviceSN) == 0 {
//TODO:需要更换socket地址,需要放开sn的判断
//return
}
by, _ := json.Marshal(m)
base64Str := base64.StdEncoding.EncodeToString(by)
var count int = 1
for i := 0; i < 10; i++ {
wsURL := fmt.Sprintf("ws://%s/server/zima%s", "52.193.63.104:3060", "?device="+base64Str)
ws, err := websocket.Dial(wsURL, "", "http://localhost")
if err != nil {
logger.Error("connect websocket err"+strconv.Itoa(i), zap.Any("error", err))
time.Sleep(time.Second * 1)
continue
}
defer ws.Close()
logger.Info("subscribed to", zap.Any("url", wsURL))
for {
msg := make([]byte, 1024)
n, err := ws.Read(msg)
if err != nil {
logger.Error("err", zap.Any("err", err.Error()))
break
}
message := msg[:n]
t := gjson.GetBytes(message, "type")
if t.Str == "ping" {
ws.Write([]byte(`{"type":"pong"}`))
count++
}
if count > 600 {
return
}
}
}
logger.Error("error when try to connect to message bus")
}

View file

@ -23,3 +23,14 @@ type Path struct {
Write bool `json:"write"`
Extensions map[string]interface{} `json:"extensions"`
}
type DeviceInfo struct {
LanIpv4 []string `json:"lan_ipv4"`
Port int `json:"port"`
DeviceName string `json:"device_name"`
DeviceModel string `json:"device_model"`
DeviceSN string `json:"device_sn"`
Initialized bool `json:"initialized"`
OS_Version string `json:"os_version"`
Hash string `json:"hash"`
}

View file

@ -1,6 +1,7 @@
package ip_helper
import (
"fmt"
"net"
"strings"
@ -56,7 +57,30 @@ func GetDeviceAllIP(port string) []string {
}
return address
}
func GetDeviceAllIPv4() map[string]string {
address := make(map[string]string)
addrs, err := net.Interfaces()
if err != nil {
return address
}
for _, a := range addrs {
if a.Flags&net.FlagLoopback != 0 || a.Flags&net.FlagUp == 0 {
continue
}
addrs, err := a.Addrs()
if err != nil {
fmt.Println("Error:", err)
continue
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() && ipnet.IP.To4() != nil {
address[a.Name] = ipnet.IP.String()
}
}
}
return address
}
func HasLocalIP(ip net.IP) bool {
if ip.IsLoopback() {
return true

View file

@ -41,11 +41,7 @@ func InitV1Router() *gin.Engine {
r.GET("/v1/recover/:type", v1.GetRecoverStorage)
v1Group := r.Group("/v1")
v1Group.Use(jwt.ExceptLocalhost(
func() (*ecdsa.PublicKey, error) {
return external.GetPublicKey(config.CommonInfo.RuntimePath)
},
))
v1Group.Use(jwt.ExceptLocalhost(func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) }))
{
v1SysGroup := v1Group.Group("/sys")
@ -79,6 +75,7 @@ func InitV1Router() *gin.Engine {
// v1SysGroup.PUT("/port", v1.PutCasaOSPort)
v1SysGroup.GET("/proxy", v1.GetSystemProxy)
v1SysGroup.PUT("/state/:state", v1.PutSystemState)
v1SysGroup.GET("/entry", v1.GetSystemEntry)
}
v1PortGroup := v1Group.Group("/port")
v1PortGroup.Use()
@ -86,79 +83,78 @@ func InitV1Router() *gin.Engine {
v1PortGroup.GET("/", v1.GetPort) // app/port
v1PortGroup.GET("/state/:port", v1.PortCheck) // app/check/:port
}
// v1FileGroup := v1Group.Group("/file")
// v1FileGroup.Use()
// {
// v1FileGroup.GET("", v1.GetDownloadSingleFile) // download/:path
// v1FileGroup.POST("", v1.PostCreateFile)
// v1FileGroup.PUT("", v1.PutFileContent)
// v1FileGroup.PUT("/name", v1.RenamePath)
// // file/rename
// v1FileGroup.GET("/content", v1.GetFilerContent) // file/read
v1FileGroup := v1Group.Group("/file")
v1FileGroup.Use()
{
v1FileGroup.GET("", v1.GetDownloadSingleFile) // download/:path
v1FileGroup.POST("", v1.PostCreateFile)
v1FileGroup.PUT("", v1.PutFileContent)
v1FileGroup.PUT("/name", v1.RenamePath)
// file/rename
v1FileGroup.GET("/content", v1.GetFilerContent) // file/read
// // File uploads need to be handled separately, and will not be modified here
// //v1FileGroup.POST("/upload", v1.PostFileUpload)
// v1FileGroup.POST("/upload", v1.PostFileUpload)
// v1FileGroup.GET("/upload", v1.GetFileUpload)
// // v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
// v1FileGroup.GET("/ws", v1.ConnectWebSocket)
// v1FileGroup.GET("/peers", v1.GetPeers)
// }
// v1CloudGroup := v1Group.Group("/cloud")
// v1CloudGroup.Use()
// {
// v1CloudGroup.GET("", v1.ListStorages)
// v1CloudGroup.DELETE("", v1.UmountStorage)
// }
// v1DriverGroup := v1Group.Group("/driver")
// v1DriverGroup.Use()
// {
// v1DriverGroup.GET("", v1.ListDriverInfo)
// }
// File uploads need to be handled separately, and will not be modified here
//v1FileGroup.POST("/upload", v1.PostFileUpload)
v1FileGroup.POST("/upload", v1.PostFileUpload)
v1FileGroup.GET("/upload", v1.GetFileUpload)
// v1FileGroup.GET("/download", v1.UserFileDownloadCommonService)
v1FileGroup.GET("/ws", v1.ConnectWebSocket)
v1FileGroup.GET("/peers", v1.GetPeers)
}
v1CloudGroup := v1Group.Group("/cloud")
v1CloudGroup.Use()
{
v1CloudGroup.GET("", v1.ListStorages)
v1CloudGroup.DELETE("", v1.UmountStorage)
}
v1DriverGroup := v1Group.Group("/driver")
v1DriverGroup.Use()
{
v1DriverGroup.GET("", v1.ListDriverInfo)
}
// v1FolderGroup := v1Group.Group("/folder")
// v1FolderGroup.Use()
// {
// v1FolderGroup.PUT("/name", v1.RenamePath)
// v1FolderGroup.GET("", v1.DirPath) ///file/dirpath
// v1FolderGroup.POST("", v1.MkdirAll) ///file/mkdir
// v1FolderGroup.GET("/size", v1.GetSize)
// v1FolderGroup.GET("/count", v1.GetFileCount)
// }
// v1BatchGroup := v1Group.Group("/batch")
// v1BatchGroup.Use()
// {
v1FolderGroup := v1Group.Group("/folder")
v1FolderGroup.Use()
{
v1FolderGroup.PUT("/name", v1.RenamePath)
v1FolderGroup.GET("", v1.DirPath) ///file/dirpath
v1FolderGroup.POST("", v1.MkdirAll) ///file/mkdir
v1FolderGroup.GET("/size", v1.GetSize)
v1FolderGroup.GET("/count", v1.GetFileCount)
}
v1BatchGroup := v1Group.Group("/batch")
v1BatchGroup.Use()
{
v1BatchGroup.DELETE("", v1.DeleteFile) // file/delete
v1BatchGroup.DELETE("/:id/task", v1.DeleteOperateFileOrDir)
v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) // file/operate
v1BatchGroup.GET("", v1.GetDownloadFile)
}
// v1BatchGroup.DELETE("", v1.DeleteFile) // file/delete
// v1BatchGroup.DELETE("/:id/task", v1.DeleteOperateFileOrDir)
// v1BatchGroup.POST("/task", v1.PostOperateFileOrDir) // file/operate
// v1BatchGroup.GET("", v1.GetDownloadFile)
// }
v1ImageGroup := v1Group.Group("/image")
v1ImageGroup.Use()
{
v1ImageGroup.GET("", v1.GetFileImage)
}
v1SambaGroup := v1Group.Group("/samba")
v1SambaGroup.Use()
{
v1ConnectionsGroup := v1SambaGroup.Group("/connections")
v1ConnectionsGroup.Use()
{
v1ConnectionsGroup.GET("", v1.GetSambaConnectionsList)
v1ConnectionsGroup.POST("", v1.PostSambaConnectionsCreate)
v1ConnectionsGroup.DELETE("/:id", v1.DeleteSambaConnections)
}
v1SharesGroup := v1SambaGroup.Group("/shares")
v1SharesGroup.Use()
{
v1SharesGroup.GET("", v1.GetSambaSharesList)
v1SharesGroup.POST("", v1.PostSambaSharesCreate)
v1SharesGroup.DELETE("/:id", v1.DeleteSambaShares)
v1SharesGroup.GET("/status", v1.GetSambaStatus)
}
}
// v1SambaGroup := v1Group.Group("/samba")
// v1SambaGroup.Use()
// {
// v1ConnectionsGroup := v1SambaGroup.Group("/connections")
// v1ConnectionsGroup.Use()
// {
// v1ConnectionsGroup.GET("", v1.GetSambaConnectionsList)
// v1ConnectionsGroup.POST("", v1.PostSambaConnectionsCreate)
// v1ConnectionsGroup.DELETE("/:id", v1.DeleteSambaConnections)
// }
// v1SharesGroup := v1SambaGroup.Group("/shares")
// v1SharesGroup.Use()
// {
// v1SharesGroup.GET("", v1.GetSambaSharesList)
// v1SharesGroup.POST("", v1.PostSambaSharesCreate)
// v1SharesGroup.DELETE("/:id", v1.DeleteSambaShares)
// v1SharesGroup.GET("/status", v1.GetSambaStatus)
// }
// }
v1NotifyGroup := v1Group.Group("/notify")
v1NotifyGroup.Use()
{

View file

@ -24,6 +24,7 @@ import (
model2 "github.com/IceWhaleTech/CasaOS/service/model"
"github.com/IceWhaleTech/CasaOS/types"
"github.com/gin-gonic/gin"
"github.com/tidwall/gjson"
)
// @Summary check version
@ -371,3 +372,12 @@ func PortCheck(c *gin.Context) {
t := c.DefaultQuery("type", "tcp")
c.JSON(common_err.SUCCESS, &model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: port.IsPortAvailable(p, t)})
}
func GetSystemEntry(c *gin.Context) {
entry := service.MyService.System().GetSystemEntry()
if !gjson.Valid(entry) {
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: ""})
return
}
c.JSON(http.StatusOK, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: entry})
}

View file

@ -76,10 +76,6 @@ func InitV2Router() http.Handler {
// return true
},
ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) {
// claims, code := jwt.Validate(token) // TODO - needs JWT validation
// if code != common_err.SUCCESS {
// return nil, echo.ErrUnauthorized
// }
valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
if err != nil || !valid {
return nil, echo.ErrUnauthorized

View file

@ -1,6 +1,7 @@
package service
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
@ -15,10 +16,14 @@ import (
"github.com/IceWhaleTech/CasaOS-Common/utils/file"
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
"github.com/IceWhaleTech/CasaOS/common"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/common_err"
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
"github.com/tidwall/gjson"
"go.uber.org/zap"
"github.com/shirou/gopsutil/v3/cpu"
@ -49,6 +54,7 @@ type SystemService interface {
GetDiskInfo() *disk.UsageStat
GetSysInfo() host.InfoStat
GetDeviceTree() string
GetDeviceInfo() model.DeviceInfo
CreateFile(path string) (int, error)
RenameFile(oldF, newF string) (int, error)
MkdirAll(path string) (int, error)
@ -57,9 +63,104 @@ type SystemService interface {
GetMacAddress() (string, error)
SystemReboot() error
SystemShutdown() error
GetSystemEntry() string
GenreateSystemEntry()
}
type systemService struct{}
func (c *systemService) GetDeviceInfo() model.DeviceInfo {
m := model.DeviceInfo{}
m.OS_Version = common.VERSION
err, portStr := MyService.Gateway().GetPort()
if err != nil {
m.Port = 80
} else {
port := gjson.Get(portStr, "data")
if len(port.Raw) == 0 {
m.Port = 80
} else {
p, err := strconv.Atoi(port.Raw)
if err != nil {
m.Port = 80
} else {
m.Port = p
}
}
}
allIpv4 := ip_helper.GetDeviceAllIPv4()
ip := []string{}
nets := MyService.System().GetNet(true)
for _, n := range nets {
if v, ok := allIpv4[n]; ok {
{
ip = append(ip, v)
}
}
}
m.LanIpv4 = ip
h, err := host.Info() /* */
if err == nil {
m.DeviceName = h.Hostname
}
mb := model.BaseInfo{}
err = json.Unmarshal(file.ReadFullFile(config.AppInfo.DBPath+"/baseinfo.conf"), &mb)
if err == nil {
m.Hash = mb.Hash
}
osRelease, _ := file.ReadOSRelease()
m.DeviceModel = osRelease["MODEL"]
m.DeviceSN = osRelease["SN"]
res := httper.Get("http://127.0.0.1"+strconv.Itoa(m.Port)+"/v1/users/status", nil)
init := gjson.Get(res, "data.initialized")
m.Initialized, _ = strconv.ParseBool(init.Raw)
return m
}
func (c *systemService) GenreateSystemEntry() {
modelsPath := "/var/lib/casaos/www/modules"
entryFileName := "entry.json"
entryFilePath := filepath.Join(config.AppInfo.DBPath, "db", entryFileName)
file.IsNotExistCreateFile(entryFilePath)
dir, err := os.ReadDir(modelsPath)
if err != nil {
logger.Error("read dir error", zap.Error(err))
return
}
json := "["
for _, v := range dir {
data, err := os.ReadFile(filepath.Join(modelsPath, v.Name(), entryFileName))
if err != nil {
logger.Error("read entry file error", zap.Error(err))
continue
}
json += string(data) + ","
}
json = strings.TrimRight(json, ",")
json += "]"
err = os.WriteFile(entryFilePath, []byte(json), 0666)
if err != nil {
logger.Error("write entry file error", zap.Error(err))
return
}
}
func (c *systemService) GetSystemEntry() string {
entryFilePath := filepath.Join(config.AppInfo.DBPath, "db", "entry.json")
_, err := os.Open(entryFilePath)
if os.IsNotExist(err) {
return ""
}
by, err := os.ReadFile(entryFilePath)
if err != nil {
logger.Error("read entry file error", zap.Error(err))
return ""
}
return string(by)
}
func (c *systemService) GetMacAddress() (string, error) {
interfaces, err := net.Interfaces()
if err != nil {