diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2831d80..92c1724 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,15 +9,36 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
-- Connect and file add image thumbnail function
+### Changed
+
+### Removed
+
+### Security
+
+### Fixed
+
+## [0.3.1-pre] - 2022-05-13
+
+### Added
+
+- CasaConnect and file add image thumbnail function
- Import of docker applications
-- Apply manual upgrades
+- List support custom sorting function
- CasaConnect gives priority to LAN connections
+- USB auto-mount switch (Raspberry Pi is off by default)
+- Application custom installation supports Docker Compose configuration import in YAML format
+- You will see the new version changelog from the next version
+- Added live preview for icons in custom installed applications
### Changed
- Application data is no longer saved to the database
- Optimize app store speed issues
+- Optimize the way WebUI is filled in
+- Image preview has been completely upgraded and now supports switching between all images in the same folder, as well as dragging, zooming, rotating and resetting.
+- Added color levels to the CPU and RAM charts
+- Optimized the display of the Connect friends list right-click menu
+- Change the initial display directory to /DATA
### Removed
@@ -27,6 +48,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
+- Fixed the problem that some Docker CLI commands failed to import
+- Fix the problem that the application is not easily recognized in /DATA/AppData directory and docker command line after installation, it will be shown as application name
+- Fix Pi-hole installation failure
+- Fixed the issue that the app could not be updated using WatchTower
+- Fixed the problem that the task status was lost after closing Files when there was an upload task
+
## [0.3.0] - 2022-04-08
### Added
diff --git a/UI b/UI
index 4a8f157..2f6deb2 160000
--- a/UI
+++ b/UI
@@ -1 +1 @@
-Subproject commit 4a8f15711ee5520f6bb644107f1eb25f252689b1
+Subproject commit 2f6deb2253df1d0247d5329cb0ea1aa983053a2e
diff --git a/conf/conf.ini.sample b/conf/conf.ini.sample
index f4eb0ce..7f5063b 100644
--- a/conf/conf.ini.sample
+++ b/conf/conf.ini.sample
@@ -19,11 +19,11 @@ RunMode = release
ServerApi = https://api.casaos.io
Handshake = socket.casaos.io
Token =
-USBAutoMount = true
+USBAutoMount =
[user]
-UserName = admin
-PWD = zimaboard
+UserName =
+PWD =
Email = user@gmail.com
Description = description
Initialized = false
@@ -31,18 +31,12 @@ Avatar =
NickName =
PublicKey =
-[redis]
-Host = 127.0.0.1:6379
-Password =
-MaxIdle = 30
-MaxActive = 30
-IdleTimeout = 200
-
[system]
ConfigStr =
WidgetList =
Analyse =
+
[file]
ShareDir =
DownloadDir =
\ No newline at end of file
diff --git a/github.com/IceWhaleTech/CasaOS-linux-amd64 b/github.com/IceWhaleTech/CasaOS-linux-amd64
new file mode 100755
index 0000000..e194858
Binary files /dev/null and b/github.com/IceWhaleTech/CasaOS-linux-amd64 differ
diff --git a/github.com/IceWhaleTech/CasaOS-linux-arm64 b/github.com/IceWhaleTech/CasaOS-linux-arm64
new file mode 100755
index 0000000..96b5f62
Binary files /dev/null and b/github.com/IceWhaleTech/CasaOS-linux-arm64 differ
diff --git a/go.mod b/go.mod
index 0150514..5f58773 100644
--- a/go.mod
+++ b/go.mod
@@ -3,6 +3,7 @@ module github.com/IceWhaleTech/CasaOS
go 1.16
require (
+ github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d
github.com/Microsoft/go-winio v0.5.0 // indirect
github.com/Microsoft/hcsshim v0.8.22 // indirect
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
@@ -13,9 +14,8 @@ require (
github.com/docker/distribution v2.8.0+incompatible // indirect
github.com/docker/docker v20.10.7+incompatible
github.com/docker/go-connections v0.4.0
- github.com/dsoprea/go-exif v0.0.0-20210625224831-a6301f85c82b
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b
- github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd
+ github.com/dsoprea/go-logging v0.0.0-20200710184922-b02d349568dd // indirect
github.com/forease/gotld v0.0.0-20190808124948-c50ff635576b
github.com/gin-contrib/gzip v0.0.2
github.com/gin-gonic/gin v1.7.2
diff --git a/go.sum b/go.sum
index 34d4f38..ba51340 100644
--- a/go.sum
+++ b/go.sum
@@ -56,6 +56,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d h1:62lEBImTxZ83pgzywgDNIrPPuQ+j4ep9QjqrWBn1hrU=
+github.com/Curtis-Milo/nat-type-identifier-go v0.0.0-20220215191915-18d42168c63d/go.mod h1:lW9x+yEjqKdPbE3+cf2fGPJXCw/hChX3Omi9QHTLFsQ=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
@@ -287,8 +289,6 @@ github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/dsoprea/go-exif v0.0.0-20210625224831-a6301f85c82b h1:hoVHc4m/v8Al8mbWyvKJWr4Z37yM4QUSVh/NY6A5Sbc=
-github.com/dsoprea/go-exif v0.0.0-20210625224831-a6301f85c82b/go.mod h1:lOaOt7+UEppOgyvRy749v3do836U/hw0YVJNjoyPaEs=
github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
github.com/dsoprea/go-exif/v3 v3.0.0-20210625224831-a6301f85c82b h1:NgNuLvW/gAFKU30ULWW0gtkCt56JfB7FrZ2zyo0wT8I=
diff --git a/main.go b/main.go
index b6296e0..dd32fa6 100644
--- a/main.go
+++ b/main.go
@@ -49,8 +49,8 @@ func init() {
route.InitFunction()
go service.SendIPToServer()
- go service.LoopFriend()
- go service.MyService.App().CheckNewImage()
+ // go service.LoopFriend()
+ // go service.MyService.App().CheckNewImage()
}
diff --git a/model/app-analyse.go b/model/app-analyse.go
index c1ad134..70ce46c 100644
--- a/model/app-analyse.go
+++ b/model/app-analyse.go
@@ -1,3 +1,13 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-03-18 11:40:55
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-13 14:48:01
+ * @FilePath: /CasaOS/model/app-analyse.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
package model
type AppAnalyse struct {
@@ -5,6 +15,7 @@ type AppAnalyse struct {
Type string `json:"type"`
UUId string `json:"uuid"`
Language string `json:"language"`
+ Version string `json:"version"`
}
type ConnectionStatus struct {
diff --git a/model/manifest.go b/model/manifest.go
index 4991485..8254205 100644
--- a/model/manifest.go
+++ b/model/manifest.go
@@ -104,6 +104,7 @@ func (p *PathArray) Scan(input interface{}) error {
//}
type CustomizationPostData struct {
+ CustomId string `json:"custom_id"`
Origin string `json:"origin"`
NetworkModel string `json:"network_model"`
Index string `json:"index"`
diff --git a/model/receive/app.go b/model/receive/app.go
new file mode 100644
index 0000000..3ccae50
--- /dev/null
+++ b/model/receive/app.go
@@ -0,0 +1 @@
+package receive
diff --git a/pkg/config/init.go b/pkg/config/init.go
index 38680c0..5dc371a 100644
--- a/pkg/config/init.go
+++ b/pkg/config/init.go
@@ -22,8 +22,7 @@ var UserInfo = &model.UserModel{}
//用户相关
var AppInfo = &model.APPModel{}
-//redis相关配置
-var RedisInfo = &model.RedisModel{}
+//var RedisInfo = &model.RedisModel{}
//server相关
var ServerInfo = &model.ServerModel{}
@@ -53,7 +52,7 @@ func InitSetup(config string) {
mapTo("user", UserInfo)
mapTo("app", AppInfo)
- mapTo("redis", RedisInfo)
+ //mapTo("redis", RedisInfo)
mapTo("server", ServerInfo)
mapTo("system", SystemConfigInfo)
mapTo("file", FileSettingInfo)
diff --git a/pkg/utils/file/file.go b/pkg/utils/file/file.go
index 069b2c0..6c8b2ac 100644
--- a/pkg/utils/file/file.go
+++ b/pkg/utils/file/file.go
@@ -283,7 +283,6 @@ func CopyDir(src string, dst string) error {
return nil
}
-//文件写入临时目录
func WriteToPath(data []byte, path, name string) error {
fullPath := path
if strings.HasSuffix(path, "/") {
diff --git a/pkg/utils/file/image.go b/pkg/utils/file/image.go
index ec1031b..45b60f2 100644
--- a/pkg/utils/file/image.go
+++ b/pkg/utils/file/image.go
@@ -42,7 +42,9 @@ func GetThumbnailByOwnerPhotos(path string) ([]byte, error) {
break
}
}
-
+ if err != nil {
+ return nil, err
+ }
im, err := exifcommon.NewIfdMappingWithStandard()
if err != nil {
return nil, err
@@ -54,8 +56,8 @@ func GetThumbnailByOwnerPhotos(path string) ([]byte, error) {
}
ifd := index.RootIfd.NextIfd()
- if err != nil {
- return nil, err
+ if ifd == nil {
+ return nil, exif.ErrNoThumbnail
}
thumbnail, err := ifd.Thumbnail()
if err != nil {
diff --git a/pkg/utils/httper/httper.go b/pkg/utils/httper/httper.go
index 743552f..da96388 100644
--- a/pkg/utils/httper/httper.go
+++ b/pkg/utils/httper/httper.go
@@ -27,6 +27,7 @@ func Get(url string, head map[string]string) (response string) {
}
resp, err := client.Do(req)
if err != nil {
+ fmt.Println(err)
//需要错误日志的处理
//loger.Error(error)
return ""
diff --git a/pkg/utils/network_detection.go b/pkg/utils/network_detection.go
new file mode 100644
index 0000000..1f6ffe9
--- /dev/null
+++ b/pkg/utils/network_detection.go
@@ -0,0 +1,30 @@
+/*
+ * @Author: LinkLeong a624669980@163.com
+ * @Date: 2022-05-08 14:58:46
+ * @LastEditors: LinkLeong a624669980@163.com
+ * @LastEditTime: 2022-05-09 13:42:26
+ * @FilePath: /CasaOS/pkg/utils/network_detection.go
+ * @Description:
+ *
+ * Copyright (c) 2022 by LinkLeong a624669980@163.com, All Rights Reserved.
+ */
+package utils
+
+import natType "github.com/Curtis-Milo/nat-type-identifier-go"
+
+/**
+ * @description:
+ * @param {chanstring} data
+ * @param {string} url
+ * @return {*}
+ */
+func GetNetWorkTypeDetection(data chan string, url string) {
+ // fmt.Println("url:", url)
+ // httper.Get(url, nil)
+ // aaa <- url
+ result, err := natType.GetDeterminedNatType(true, 5, url)
+ if err == nil {
+ data <- result
+ }
+
+}
diff --git a/pkg/utils/network_detection_test.go b/pkg/utils/network_detection_test.go
new file mode 100644
index 0000000..c4cb8aa
--- /dev/null
+++ b/pkg/utils/network_detection_test.go
@@ -0,0 +1,29 @@
+/*
+ * @Author: LinkLeong a624669980@163.com
+ * @Date: 2022-05-08 15:07:31
+ * @LastEditors: LinkLeong a624669980@163.com
+ * @LastEditTime: 2022-05-09 11:43:30
+ * @FilePath: /CasaOS/pkg/utils/network_detection_test.go
+ * @Description:
+ *
+ * Copyright (c) 2022 by LinkLeong a624669980@163.com, All Rights Reserved.
+ */
+
+package utils
+
+import (
+ "fmt"
+ "testing"
+)
+
+func TestGetResultTest(t *testing.T) {
+ list := []string{"https://www.google.com", "https://www.bing.com", "https://www.baidu.com"}
+ data := make(chan string)
+ //data <- "init"
+ for _, v := range list {
+ go GetNetWorkTypeDetection(data, v)
+ }
+ result := <-data
+ close(data)
+ fmt.Println(result)
+}
diff --git a/pkg/utils/sort/app_info_dev.go b/pkg/utils/sort/app_info_dev.go
deleted file mode 100644
index 9f14a6f..0000000
--- a/pkg/utils/sort/app_info_dev.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package sort
-
-import (
- "github.com/IceWhaleTech/CasaOS/model"
- "sort"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type devSorter struct {
- dev []model.Devices
- less []lessFuncDev
-}
-
-// sort接口方法之一(Less)
-type lessFuncDev func(p1, p2 *model.Devices) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *devSorter) Sort(dev []model.Devices) {
- ms.dev = dev
- sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func DevSort(less ...lessFuncDev) *devSorter {
- return &devSorter{
- less: less,
- }
-}
-
-// Len 为sort接口方法之一
-func (ms *devSorter) Len() int {
- return len(ms.dev)
-}
-
-// Swap 为sort接口方法之一
-func (ms *devSorter) Swap(i, j int) {
- ms.dev[i], ms.dev[j] = ms.dev[j], ms.dev[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *devSorter) Less(i, j int) bool {
- temp := ms.dev
- p, q := &temp[i], &temp[j]
- // Try all but the last comparison.
- var k int
- // 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
- // 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
- for k = 0; k < len(ms.less)-1; k++ {
- // 提取比较函数, 将函数赋值到新的变量中以便调用
- less := ms.less[k]
- switch {
- case less(p, q):
- // 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- // 如果 p > q, 返回值为false, 则调到下一个case中处理
- return true
- case less(q, p):
- // 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- return false
- }
- // 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
- continue
- }
- // 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
- // 直接返回最后一次的比较结果数据即可
- return ms.less[k](p, q)
-}
diff --git a/pkg/utils/sort/app_info_evn.go b/pkg/utils/sort/app_info_evn.go
deleted file mode 100644
index 40741e5..0000000
--- a/pkg/utils/sort/app_info_evn.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package sort
-
-import (
- "sort"
-
- "github.com/IceWhaleTech/CasaOS/model"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type evnSorter struct {
- evn []model.Envs
- less []lessFuncEnv
-}
-
-// sort接口方法之一(Less)
-type lessFuncEnv func(p1, p2 *model.Envs) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *evnSorter) Sort(env []model.Envs) {
- ms.evn = env
- sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func EnvSort(less ...lessFuncEnv) *evnSorter {
- return &evnSorter{
- less: less,
- }
-}
-
-// Len 为sort接口方法之一
-func (ms *evnSorter) Len() int {
- return len(ms.evn)
-}
-
-// Swap 为sort接口方法之一
-func (ms *evnSorter) Swap(i, j int) {
- ms.evn[i], ms.evn[j] = ms.evn[j], ms.evn[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *evnSorter) Less(i, j int) bool {
- temp := ms.evn
- p, q := &temp[i], &temp[j]
- // Try all but the last comparison.
- var k int
- // 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
- // 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
- for k = 0; k < len(ms.less)-1; k++ {
- // 提取比较函数, 将函数赋值到新的变量中以便调用
- less := ms.less[k]
- switch {
- case less(p, q):
- // 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- // 如果 p > q, 返回值为false, 则调到下一个case中处理
- return true
- case less(q, p):
- // 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- return false
- }
- // 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
- continue
- }
- // 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
- // 直接返回最后一次的比较结果数据即可
- return ms.less[k](p, q)
-}
diff --git a/pkg/utils/sort/app_info_port.go b/pkg/utils/sort/app_info_port.go
deleted file mode 100644
index 8198b4c..0000000
--- a/pkg/utils/sort/app_info_port.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package sort
-
-import (
- "github.com/IceWhaleTech/CasaOS/model"
- "sort"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type multiSorter struct {
- ports []model.Ports
- less []lessFunc
-}
-
-// sort接口方法之一(Less)
-type lessFunc func(p1, p2 *model.Ports) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *multiSorter) Sort(ports []model.Ports) {
- ms.ports = ports
- sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func PortsSort(less ...lessFunc) *multiSorter {
- return &multiSorter{
- less: less,
- }
-}
-
-// Len 为sort接口方法之一
-func (ms *multiSorter) Len() int {
- return len(ms.ports)
-}
-
-// Swap 为sort接口方法之一
-func (ms *multiSorter) Swap(i, j int) {
- ms.ports[i], ms.ports[j] = ms.ports[j], ms.ports[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *multiSorter) Less(i, j int) bool {
- port := ms.ports
- p, q := &port[i], &port[j]
- // Try all but the last comparison.
- var k int
- // 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
- // 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
- for k = 0; k < len(ms.less)-1; k++ {
- // 提取比较函数, 将函数赋值到新的变量中以便调用
- less := ms.less[k]
- switch {
- case less(p, q):
- // 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- // 如果 p > q, 返回值为false, 则调到下一个case中处理
- return true
- case less(q, p):
- // 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- return false
- }
- // 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
- continue
- }
- // 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
- // 直接返回最后一次的比较结果数据即可
- return ms.less[k](p, q)
-}
diff --git a/pkg/utils/sort/app_info_vol.go b/pkg/utils/sort/app_info_vol.go
deleted file mode 100644
index 1a07fb8..0000000
--- a/pkg/utils/sort/app_info_vol.go
+++ /dev/null
@@ -1,73 +0,0 @@
-package sort
-
-import (
- "github.com/IceWhaleTech/CasaOS/model"
- "sort"
-)
-
-// 数据集类型, 与上一篇排序文章(多字段单独排序)比较, less字段的数据类型不再是 func(p1, p2 *Change) bool
-// 而是 []func(p1, p2 *Change) bool 因为在第一个比较的值相等的情况下, 还要比较第二个值, 所以这里需要多个比较函数
-type volSorter struct {
- vol []model.Volume
- less []lessFuncVol
-}
-
-// sort接口方法之一(Less)
-type lessFuncVol func(p1, p2 *model.Volume) bool
-
-// Sort 函数有两个作用
-// 第一, 将参数(实际的数据集)赋值给ms对象
-// 第二, 调用内置sort函数进行排序操作
-func (ms *volSorter) Sort(vol []model.Volume) {
- ms.vol = vol
- sort.Sort(ms)
-}
-
-// OrderedBy 函数的作用是返回一个multiSorter实例, 并将所有的实际排序函数赋值给实例的less字段,
-// 上面已经为multiSorter结构体定义了Sort方法, 所以该函数的返回值可以直接调用Sort方法进行排序
-// 该函数中, 为multiSorter结构体中的less字段赋值, Sort方法中又将实际数据集传入, 赋值给multiSorter的ports字段
-// 一个函数, 一个方法调用过后, multiSorter实例中两个字段就已经全部被正确赋值, 可以调用系统sort函数进行排序
-// 该函数也可看作是一个工厂方法, 用来生成less字段已经被赋值的multiSorter实例
-func VolSort(less ...lessFuncVol) *volSorter {
- return &volSorter{
- less: less,
- }
-}
-
-// Len 为sort接口方法之一
-func (ms *volSorter) Len() int {
- return len(ms.vol)
-}
-
-// Swap 为sort接口方法之一
-func (ms *volSorter) Swap(i, j int) {
- ms.vol[i], ms.vol[j] = ms.vol[j], ms.vol[i]
-}
-
-// Less 为sort接口方法之一
-func (ms *volSorter) Less(i, j int) bool {
- temp := ms.vol
- p, q := &temp[i], &temp[j]
- // Try all but the last comparison.
- var k int
- // 由于可能有多个需要排序的字段, 也就对应了多个less函数, 当第一个字段的值相等时,
- // 需要依次尝试比对后续其他字段的值得大小, 所以这里需要获取比较函数的长度, 以便遍历比较
- for k = 0; k < len(ms.less)-1; k++ {
- // 提取比较函数, 将函数赋值到新的变量中以便调用
- less := ms.less[k]
- switch {
- case less(p, q):
- // 如果 p < q, 返回值为true, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- // 如果 p > q, 返回值为false, 则调到下一个case中处理
- return true
- case less(q, p):
- // 如果 p > q, 返回值为false, 不存在两个值相等需要比较后续字段的情况, 所以这里直接返回
- return false
- }
- // 如果代码走到这里, 说明ms.less[k]函数比较后 p == q; 重新开始下一次循环, 更换到下一个比较函数处理
- continue
- }
- // 如果代码走到这里, 说明所有的比较函数执行过后, 所有比较的值都相等
- // 直接返回最后一次的比较结果数据即可
- return ms.less[k](p, q)
-}
diff --git a/route/init.go b/route/init.go
index bc0d8f5..9481ce5 100644
--- a/route/init.go
+++ b/route/init.go
@@ -1,17 +1,16 @@
package route
import (
- "encoding/json"
"encoding/xml"
"fmt"
"runtime"
"strconv"
+ "strings"
"time"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/model/system_app"
"github.com/IceWhaleTech/CasaOS/pkg/config"
- "github.com/IceWhaleTech/CasaOS/pkg/docker"
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@@ -105,7 +104,8 @@ func installSyncthing(appId string) {
m.Ports = appInfo.Ports
m.Restart = "always"
m.Volumes = appInfo.Volumes
-
+ m.Label = id
+ m.CustomId = id
containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m, appInfo.NetworkModel)
if err != nil {
fmt.Println("container create error", err)
@@ -114,83 +114,46 @@ func installSyncthing(appId string) {
}
//step:start container
- err = service.MyService.Docker().DockerContainerStart(id)
+ err = service.MyService.Docker().DockerContainerStart(containerId)
if err != nil {
//start container error
return
}
- portsStr, _ := json.Marshal(appInfo.Ports)
- envsStr, _ := json.Marshal(appInfo.Envs)
- volumesStr, _ := json.Marshal(appInfo.Volumes)
- devicesStr, _ := json.Marshal(appInfo.Devices)
- //step: 保存数据到数据库
- md := model2.AppListDBModel{
- CustomId: id,
- Title: appInfo.Title,
- //ScreenshotLink: appInfo.ScreenshotLink,
- Slogan: appInfo.Tagline,
- Description: appInfo.Description,
- //Tags: appInfo.Tags,
- Icon: appInfo.Icon,
- Version: dockerImageVersion,
- ContainerId: containerId,
- Image: dockerImage,
- Index: appInfo.Index,
- PortMap: appInfo.PortMap,
- Label: appInfo.Title,
- EnableUPNP: false,
- Ports: string(portsStr),
- Envs: string(envsStr),
- Volumes: string(volumesStr),
- Position: true,
- NetModel: appInfo.NetworkModel,
- Restart: m.Restart,
- CpuShares: 50,
- Memory: int64(appInfo.MaxMemory),
- Devices: string(devicesStr),
- Origin: m.Origin,
- CreatedAt: strconv.FormatInt(time.Now().Unix(), 10),
- UpdatedAt: strconv.FormatInt(time.Now().Unix(), 10),
- }
- service.MyService.App().SaveContainer(md)
-
checkSystemApp()
}
// check if the system application is installed
func checkSystemApp() {
list := service.MyService.App().GetSystemAppList()
- for _, v := range *list {
- if v.Image == "linuxserver/syncthing" {
+ for _, v := range list {
+ info, err := service.MyService.Docker().DockerContainerInfo(v.ID)
+ if err != nil {
+ continue
+ }
+ if strings.Contains(info.Config.Image, "linuxserver/syncthing") {
if v.State != "running" {
//step:start container
- service.MyService.Docker().DockerContainerStart(v.CustomId)
+ service.MyService.Docker().DockerContainerStart(v.ID)
}
syncIsExistence = true
- if config.SystemConfigInfo.SyncPort != v.Port {
- config.SystemConfigInfo.SyncPort = v.Port
+ if config.SystemConfigInfo.SyncPort != v.Labels["web"] {
+ config.SystemConfigInfo.SyncPort = v.Labels["web"]
}
- var paths []model.PathMap
- json.Unmarshal([]byte(v.Volumes), &paths)
+
path := ""
- for _, i := range paths {
- if i.ContainerPath == "/config" {
- path = docker.GetDir(v.CustomId, i.Path) + "/config.xml"
- for i := 0; i < 10; i++ {
- if file.CheckNotExist(path) {
- time.Sleep(1 * time.Second)
- } else {
- break
- }
- }
+ for _, i := range info.HostConfig.Mounts {
+ if i.Target == "/config" {
+ path = i.Source
+
break
}
}
- content := file.ReadFullFile(path)
+ content := file.ReadFullFile(path + "config.xml")
syncConfig := &system_app.SyncConfig{}
xml.Unmarshal(content, &syncConfig)
config.SystemConfigInfo.SyncKey = syncConfig.Key
+ break
}
}
if !syncIsExistence {
@@ -283,7 +246,10 @@ func CheckToken2_11() {
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
- service.MyService.System().ExecUSBAutoMountShell(config.ServerInfo.USBAutoMount)
+ if service.MyService.ZiMa().GetSysInfo().KernelArch == "aarch64" && config.ServerInfo.USBAutoMount != "True" && strings.Contains(service.MyService.ZiMa().GetDeviceTree(), "Raspberry Pi") {
+ service.MyService.System().UpdateUSBAutoMount("False")
+ service.MyService.System().ExecUSBAutoMountShell("False")
+ }
// str := []string{}
// str = append(str, "ddd")
@@ -301,10 +267,14 @@ func ImportApplications() {
// 0.3.1
func ChangeAPIUrl() {
- newAPIUrl := "https://api.casaos.io"
- config.ServerInfo.ServerApi = newAPIUrl
- config.Cfg.Section("server").Key("ServerApi").SetValue(newAPIUrl)
- config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+
+ newAPIUrl := "https://api.casaos.io/casaos-api"
+ if config.ServerInfo.ServerApi == "https://api.casaos.zimaboard.com" {
+ config.ServerInfo.ServerApi = newAPIUrl
+ config.Cfg.Section("server").Key("ServerApi").SetValue(newAPIUrl)
+ config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+ }
+
}
// 0.3.1
@@ -313,15 +283,15 @@ func InitSystemApplication() {
if len(list) != 2 {
application := model2.ApplicationModel{}
application.Name = "Files"
- application.Icon = "http://demo.casaos.io/ui/img/folder-open.d382f130.svg"
+ application.Icon = "/ui/img/Files.svg"
application.Type = "system"
- application.Index = 0
+ application.Order = 0
service.MyService.App().CreateApplication(application)
application.Name = "CasaConnect"
- application.Icon = "http://demo.casaos.io/ui/img/folder-publicshare.0219e0d4.svg"
+ application.Icon = "/ui/img/CasaConnect.svg"
application.Type = "system"
- application.Index = 0
+ application.Order = 0
service.MyService.App().CreateApplication(application)
}
diff --git a/route/route.go b/route/route.go
index d2de285..f2b8459 100644
--- a/route/route.go
+++ b/route/route.go
@@ -118,7 +118,8 @@ func InitRouter() *gin.Engine {
v1AppGroup.GET("/category", v1.CategoryList)
//容器相关
v1AppGroup.GET("/terminal/:id", v1.DockerTerminal)
- v1AppGroup.PUT("/index/:id", v1.PutAppIndex)
+ v1AppGroup.GET("/order", v1.GetAppOrder)
+ v1AppGroup.POST("/order", v1.PostAppOrder)
//app容器详情
v1AppGroup.GET("/info/:id", v1.ContainerInfo)
//app容器日志
@@ -146,11 +147,10 @@ func InitRouter() *gin.Engine {
v1SysGroup := v1Group.Group("/sys")
v1SysGroup.Use()
{
- //获取检查版本是否需要升级
v1SysGroup.GET("/check", v1.CheckVersion)
+ v1SysGroup.GET("/hardware/info", v1.GetSystemHardwareInfo)
v1SysGroup.GET("/client/version", v1.GetClientVersion)
v1SysGroup.POST("/update", v1.SystemUpdate)
- v1SysGroup.GET("/sys", v1.Sys)
v1SysGroup.GET("/wsssh", v1.WsSsh)
v1SysGroup.GET("/config", v1.GetSystemConfig)
v1SysGroup.GET("/error/logs", v1.GetCasaOSErrorLogs)
@@ -162,13 +162,12 @@ func InitRouter() *gin.Engine {
v1SysGroup.POST("/kill", v1.PostKillCasaOS)
v1SysGroup.GET("/info", v1.Info)
v1SysGroup.PUT("/usb/off", v1.PutSystemOffUSBAutoMount)
- v1SysGroup.GET("/usb/on", v1.PutSystemOnUSBAutoMount)
+ v1SysGroup.PUT("/usb/on", v1.PutSystemOnUSBAutoMount)
v1SysGroup.GET("/usb", v1.GetSystemUSBAutoMount)
}
v1FileGroup := v1Group.Group("/file")
v1FileGroup.Use()
{
- //修改文件名称/目录名称
v1FileGroup.PUT("/rename", v1.RenamePath)
v1FileGroup.GET("/read", v1.GetFilerContent)
v1FileGroup.POST("/upload", v1.PostFileUpload)
@@ -246,6 +245,7 @@ func InitRouter() *gin.Engine {
v1PersonGroup := v1Group.Group("/person")
v1PersonGroup.Use()
{
+ v1PersonGroup.GET("/detection", v1.GetPersonDetection)
v1PersonGroup.GET("/users", v1.GetPersonFriend)
v1PersonGroup.POST("/user/:shareids", v1.PostAddPersonFriend)
v1PersonGroup.DELETE("/user/:shareid", v1.DeletePersonFriend)
diff --git a/route/v1/docker.go b/route/v1/docker.go
index 2a950a1..0b74300 100644
--- a/route/v1/docker.go
+++ b/route/v1/docker.go
@@ -16,6 +16,7 @@ import (
upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
ip_helper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
+ "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
port2 "github.com/IceWhaleTech/CasaOS/pkg/utils/port"
"github.com/IceWhaleTech/CasaOS/pkg/utils/random"
@@ -155,15 +156,25 @@ func InstallApp(c *gin.Context) {
var dockerImageVersion string
//check app name is exist
- if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil {
- if m.Origin != "custom" {
- m.Label = m.Label + "_" + time.Now().Local().Format("02150405")
- } else {
+
+ if m.Origin != "custom" {
+ oldName := m.Label
+ for i := 0; true; i++ {
+ if i != 0 {
+ m.Label = oldName + "-" + strconv.Itoa(i)
+ }
+ if _, err := service.MyService.Docker().DockerListByName(m.Label); err != nil {
+ break
+ }
+ }
+ } else {
+ if _, err := service.MyService.Docker().DockerListByName(m.Label); err == nil {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR_APP_NAME_EXIST, Message: oasis_err2.GetMsg(oasis_err2.ERROR_APP_NAME_EXIST)})
return
}
}
+
//检查端口
if len(m.PortMap) > 0 && m.PortMap != "0" {
//c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
@@ -257,8 +268,8 @@ func InstallApp(c *gin.Context) {
//if len(privileged) > 0 {
//
//}
- //id := uuid.NewV4().String()
-
+ id := uuid.NewV4().String()
+ m.CustomId = id
var relyMap = make(map[string]string)
go func() {
installLog := model2.AppNotify{}
@@ -918,8 +929,10 @@ func UpdateSetting(c *gin.Context) {
// return
// }
+ service.MyService.Docker().DockerContainerStop(id)
portMap, _ := strconv.Atoi(m.PortMap)
if !port2.IsPortAvailable(portMap, "tcp") {
+ service.MyService.Docker().DockerContainerStart(id)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + m.PortMap})
return
}
@@ -929,32 +942,34 @@ func UpdateSetting(c *gin.Context) {
if u.Protocol == "udp" {
t, _ := strconv.Atoi(u.CommendPort)
if !port2.IsPortAvailable(t, "udp") {
+ service.MyService.Docker().DockerContainerStart(id)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
return
}
} else if u.Protocol == "tcp" {
te, _ := strconv.Atoi(u.CommendPort)
if !port2.IsPortAvailable(te, "tcp") {
+ service.MyService.Docker().DockerContainerStart(id)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
return
}
} else if u.Protocol == "both" {
t, _ := strconv.Atoi(u.CommendPort)
if !port2.IsPortAvailable(t, "udp") {
+ service.MyService.Docker().DockerContainerStart(id)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
return
}
te, _ := strconv.Atoi(u.CommendPort)
if !port2.IsPortAvailable(te, "tcp") {
+ service.MyService.Docker().DockerContainerStart(id)
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: "Duplicate port:" + u.CommendPort})
return
}
}
}
-
- service.MyService.Docker().DockerContainerStop(id)
service.MyService.Docker().DockerContainerUpdateName(id, id)
//service.MyService.Docker().DockerContainerRemove(id, true)
@@ -1100,59 +1115,34 @@ func PutAppUpdate(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
-// @Summary update app index
+// @Summary get app index
// @Produce application/json
-// @Accept multipart/form-data
+// @Accept application/json
// @Tags app
-// @Param id path string true "app id"
-// @Param index query int true "app index"
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /app/index/{id} [put]
-func PutAppIndex(c *gin.Context) {
- id := c.Param("id")
- index, _ := strconv.Atoi(c.Query("index"))
+// @Router /app/order [get]
+func GetAppOrder(c *gin.Context) {
+ data := service.MyService.System().GetAppOrderFile()
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: json.RawMessage(data)})
+}
- if len(id) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
- return
- }
-
- inspect, err := service.MyService.Docker().DockerContainerInfo(id)
- if err != nil {
- if len(service.MyService.App().GetApplicationById(id).Name) == 0 {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
- return
- } else {
- service.MyService.App().UpdateApplicationIndexById(id, index)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
- return
- }
-
- }
- service.MyService.Docker().DockerContainerStop(id)
- service.MyService.Docker().DockerContainerUpdateName(id, id)
-
- inspect.Config.Labels["index"] = strconv.Itoa(index)
-
- containerId, err := service.MyService.Docker().DockerContainerCopyCreate(inspect)
- if err != nil {
- service.MyService.Docker().DockerContainerUpdateName(inspect.Name, id)
- service.MyService.Docker().DockerContainerStart(id)
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)})
- return
- }
-
- //step:启动容器
- err = service.MyService.Docker().DockerContainerStart(containerId)
-
- if err != nil {
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR)})
- return
- }
- service.MyService.Docker().DockerContainerRemove(id, true)
-
- c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
+// @Summary update app index
+// @Produce application/json
+// @Accept application/json
+// @Tags app
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /app/order [post]
+func PostAppOrder(c *gin.Context) {
+ data := c.PostForm("data")
+ service.MyService.System().UpAppOrderFile(data)
+ c.JSON(http.StatusOK,
+ model.Result{
+ Success: oasis_err.SUCCESS,
+ Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+ Data: json.RawMessage(data),
+ })
}
// @Summary 获取容器详情
@@ -1298,14 +1288,16 @@ func ContainerUpdateInfo(c *gin.Context) {
}
m := model.CustomizationPostData{}
- m.Index = ""
m.Icon = info.Config.Labels["icon"]
m.Ports = port
- m.Image = info.Image
+ m.Image = info.Config.Image
m.Origin = info.Config.Labels["origin"]
+ if len(m.Origin) == 0 {
+ m.Origin = "local"
+ }
m.NetworkModel = string(info.HostConfig.NetworkMode)
m.Description = info.Config.Labels["desc"]
- m.Label = info.Name
+ m.Label = strings.ReplaceAll(info.Name, "/", "")
m.PortMap = info.Config.Labels["web"]
m.Devices = driver
m.Envs = envs
@@ -1314,8 +1306,12 @@ func ContainerUpdateInfo(c *gin.Context) {
m.Volumes = vol //appInfo.Volumes
m.Restart = info.HostConfig.RestartPolicy.Name
m.EnableUPNP = false
+ m.Index = info.Config.Labels["index"]
m.Position = false
-
+ m.CustomId = info.Config.Labels["custom_id"]
+ if len(m.CustomId) == 0 {
+ m.CustomId = uuid.NewV4().String()
+ }
m.CapAdd = info.HostConfig.CapAdd
m.Cmd = info.Config.Cmd
m.HostName = info.Config.Hostname
diff --git a/route/v1/file.go b/route/v1/file.go
index 8217519..5dc7970 100644
--- a/route/v1/file.go
+++ b/route/v1/file.go
@@ -225,10 +225,10 @@ func DirPath(c *gin.Context) {
path := c.DefaultQuery("path", "")
info := service.MyService.ZiMa().GetDirPath(path)
if path == "/DATA/AppData" {
- list := service.MyService.App().GetAllDBApps()
+ list := service.MyService.Docker().DockerContainerList()
apps := make(map[string]string, len(list))
for _, v := range list {
- apps[v.CustomId] = v.Label
+ apps[strings.ReplaceAll(v.Names[0], "/", "")] = strings.ReplaceAll(v.Names[0], "/", "")
}
for i := 0; i < len(info); i++ {
if v, ok := apps[info[i].Name]; ok {
diff --git a/route/v1/person.go b/route/v1/person.go
index fc9c8ae..307e6b8 100644
--- a/route/v1/person.go
+++ b/route/v1/person.go
@@ -5,7 +5,6 @@ import (
"encoding/base64"
"encoding/gob"
"encoding/json"
- "fmt"
"io/ioutil"
"net"
"net/http"
@@ -15,8 +14,7 @@ import (
"strings"
"time"
- path2 "path"
-
+ natType "github.com/Curtis-Milo/nat-type-identifier-go"
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@@ -282,9 +280,6 @@ func GetPersonImageThumbnail(c *gin.Context) {
c.JSON(http.StatusInternalServerError, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
return
}
- filesuffix := strings.Split(path2.Ext(path), ".")[1]
-
- fmt.Println("data:image/" + filesuffix + ";base64," + img.Data.(string))
imageBuffer, _ := base64.StdEncoding.DecodeString(img.Data.(string))
c.Writer.WriteString(string(imageBuffer))
@@ -304,7 +299,6 @@ func GetPersonFriend(c *gin.Context) {
for i := 0; i < len(list); i++ {
if v, ok := service.UDPAddressMap[list[i].Token]; ok && len(v) > 0 {
list[i].OnLine = true
- list[i].Avatar = v
if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) {
list[i].LocalIP = strings.Split(v, ":")[0]
}
@@ -313,6 +307,31 @@ func GetPersonFriend(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: list})
}
+// @Summary network type detection
+// @Produce application/json
+// @Accept application/json
+// @Tags person
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /person/detection [get]
+func GetPersonDetection(c *gin.Context) {
+ // - Blocked
+ // - Open Internet
+ // - Full Cone
+ // - Symmetric UDP Firewall
+ // - Restric NAT
+ // - Restric Port NAT
+ // - Symmetric NAT
+
+ result, err := natType.GetDeterminedNatType(true, 5, "stun.l.google.com")
+ if err != nil {
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
+ return
+ }
+ //result := service.MyService.Person().GetPersionNetWorkTypeDetection()
+ c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: result})
+}
+
// @Summary add friend
// @Produce application/json
// @Accept application/json
@@ -571,7 +590,7 @@ func DeletePersonFriend(c *gin.Context) {
// @Tags person
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /person/public [delete]
+// @Router /person/public [get]
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 3193c96..d63afa7 100644
--- a/route/v1/system.go
+++ b/route/v1/system.go
@@ -141,7 +141,7 @@ func GetSystemConfigDebug(c *gin.Context) {
systemAppStatus += "Sync img: " + strconv.FormatBool(images) + "\n\t"
list := service.MyService.App().GetSystemAppList()
- for _, v := range *list {
+ for _, v := range list {
systemAppStatus += v.Image + ",\n\t"
}
@@ -162,9 +162,6 @@ func GetSystemConfigDebug(c *gin.Context) {
c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: bugContent})
}
-func Sys(c *gin.Context) {
- service.DockerPull()
-}
//widget配置
func GetWidgetConfig(c *gin.Context) {
@@ -181,9 +178,7 @@ func GetWidgetConfig(c *gin.Context) {
func PostSetWidgetConfig(c *gin.Context) {
buf := make([]byte, 1024)
n, _ := c.Request.Body.Read(buf)
- fmt.Println("错误", strconv.Itoa(n))
service.MyService.System().UpSystemConfig("", string(buf[0:n]))
- fmt.Println("错误1", string(buf[0:n]))
c.JSON(http.StatusOK,
model.Result{
Success: oasis_err.SUCCESS,
@@ -283,7 +278,7 @@ func PostKillCasaOS(c *gin.Context) {
// @Tags sys
// @Security ApiKeyAuth
// @Success 200 {string} string "ok"
-// @Router /sys/usg/off [put]
+// @Router /sys/usb/off [put]
func PutSystemOffUSBAutoMount(c *gin.Context) {
service.MyService.System().UpdateUSBAutoMount("False")
service.MyService.System().ExecUSBAutoMountShell("False")
@@ -306,6 +301,7 @@ func GetSystemUSBAutoMount(c *gin.Context) {
if config.ServerInfo.USBAutoMount == "False" {
state = "False"
}
+
c.JSON(http.StatusOK,
model.Result{
Success: oasis_err.SUCCESS,
@@ -314,6 +310,25 @@ func GetSystemUSBAutoMount(c *gin.Context) {
})
}
+// @Summary get system hardware info
+// @Produce application/json
+// @Accept application/json
+// @Tags sys
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /sys/hardware/info [get]
+func GetSystemHardwareInfo(c *gin.Context) {
+
+ data := make(map[string]string, 1)
+ data["drive_model"] = service.MyService.ZiMa().GetDeviceTree()
+ c.JSON(http.StatusOK,
+ model.Result{
+ Success: oasis_err.SUCCESS,
+ Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+ Data: data,
+ })
+}
+
// @Summary Turn off usb auto-mount
// @Produce application/json
// @Accept application/json
diff --git a/service/app.go b/service/app.go
index d6ede1e..cbcf52a 100644
--- a/service/app.go
+++ b/service/app.go
@@ -21,15 +21,17 @@ import (
"github.com/docker/docker/api/types/filters"
client2 "github.com/docker/docker/client"
"github.com/pkg/errors"
+ uuid "github.com/satori/go.uuid"
"gorm.io/gorm"
)
type AppService interface {
- CreateApplication(m model2.ApplicationModel)
+ CreateApplication(m model2.ApplicationModel) model2.ApplicationModel
GetApplicationList() (m []model2.ApplicationModel)
GetApplicationById(id string) (m model2.ApplicationModel)
- UpdateApplicationIndexById(id string, index int)
+ UpdateApplicationOrderById(id string, order int)
GetMyList(index, size int, position bool) (*[]model2.MyAppList, *[]model2.MyAppList)
+ GetCasaOSCount() int
SaveContainer(m model2.AppListDBModel)
GetUninstallInfo(id string) model2.AppListDBModel
DeleteApp(id string)
@@ -38,7 +40,7 @@ type AppService interface {
UpdateApp(m model2.AppListDBModel)
GetSimpleContainerInfo(name string) (types.Container, error)
DelAppConfigDir(path string)
- GetSystemAppList() *[]model2.MyAppList
+ GetSystemAppList() []types.Container
GetHardwareUsageSteam()
GetHardwareUsage() []model.DockerStatsModel
GetAppStats(id string) string
@@ -57,12 +59,13 @@ func (a *appStruct) GetApplicationById(id string) (m model2.ApplicationModel) {
return
}
-func (a *appStruct) UpdateApplicationIndexById(id string, index int) {
- a.db.Model(&model2.ApplicationModel{}).Where("id = ?", id).Update("index", index)
+func (a *appStruct) UpdateApplicationOrderById(id string, order int) {
+ a.db.Model(&model2.ApplicationModel{}).Where("id = ?", id).Update("order", order)
}
-func (a *appStruct) CreateApplication(m model2.ApplicationModel) {
+func (a *appStruct) CreateApplication(m model2.ApplicationModel) model2.ApplicationModel {
a.db.Create(&m)
+ return m
}
func (a *appStruct) GetApplicationList() (m []model2.ApplicationModel) {
a.db.Find(&m)
@@ -99,6 +102,8 @@ func (a *appStruct) ImportApplications(casaApp bool) {
info.Config.Labels["web"] = app.PortMap
info.Config.Labels["icon"] = app.Icon
info.Config.Labels["desc"] = app.Description
+ info.Config.Labels["index"] = app.Index
+ info.Config.Labels["custom_id"] = app.CustomId
info.Name = app.Title
container_id, err := MyService.Docker().DockerContainerCopyCreate(info)
if err != nil {
@@ -122,6 +127,8 @@ func (a *appStruct) ImportApplications(casaApp bool) {
info.Config.Labels["web"] = ""
info.Config.Labels["icon"] = ""
info.Config.Labels["desc"] = ""
+ info.Config.Labels["index"] = ""
+ info.Config.Labels["custom_id"] = uuid.NewV4().String()
_, err = MyService.Docker().DockerContainerCopyCreate(info)
if err != nil {
@@ -131,6 +138,46 @@ func (a *appStruct) ImportApplications(casaApp bool) {
}
}
+ // allcontainer := MyService.Docker().DockerContainerList()
+ // for _, app := range allcontainer {
+ // info, err := MyService.Docker().DockerContainerInfo(app.ID)
+ // if err != nil {
+ // continue
+ // }
+ // MyService.Docker().DockerContainerStop(app.ID)
+ // MyService.Docker().DockerContainerRemove(app.ID, false)
+ // //info.NetworkSettings
+ // info.Config.Labels["custom_id"] = uuid.NewV4().String()
+ // container_id, err := MyService.Docker().DockerContainerCopyCreate(info)
+ // if err != nil {
+ // fmt.Println(err)
+ // continue
+ // }
+ // MyService.Docker().DockerContainerStart(container_id)
+ //}
+
+}
+
+func (a *appStruct) GetCasaOSCount() int {
+ //获取docker应用
+ cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5))
+ if err != nil {
+ a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
+ return 0
+ }
+ defer cli.Close()
+ fts := filters.NewArgs()
+ fts.Add("label", "casaos=casaos")
+ //fts.Add("label", "casaos:casaos")
+
+ containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: fts, Limit: 200})
+ if err != nil {
+ a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
+ return 0
+ }
+
+ systemApp := MyService.App().GetApplicationList()
+ return len(containers) + len(systemApp)
}
//获取我的应用列表
@@ -154,51 +201,59 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
unTranslation := []model2.MyAppList{}
list := []model2.MyAppList{}
- for _, m := range containers {
- _, newVersion := NewVersionApp[m.ID]
+ systemApp := MyService.App().GetApplicationList()
+ for _, v := range systemApp {
+ list = append(list, model2.MyAppList{
+ Name: v.Name,
+ Icon: v.Icon,
+ State: strconv.Itoa(v.State),
+ Id: strconv.Itoa(v.Id),
+ CustomId: strconv.Itoa(v.Id),
+ Port: "",
+ //Order: strconv.Itoa(v.Order),
+ Index: "/",
+ Image: "",
+ Type: v.Type,
+ NewVersion: false,
+ })
+ }
+
+ for _, m := range containers {
if m.Labels["casaos"] == "casaos" {
+ if m.Labels["origin"] == "system" {
+ continue
+ }
+ _, newVersion := NewVersionApp[m.ID]
list = append(list, model2.MyAppList{
- Name: m.Names[0],
+ Name: strings.ReplaceAll(m.Names[0], "/", ""),
Icon: m.Labels["icon"],
State: m.State,
- CustomId: m.ID,
+ CustomId: m.Labels["custom_id"],
+ Id: m.ID,
Port: m.Labels["web"],
Index: m.Labels["index"],
- //UpTime: tm,
+ //Order: m.Labels["order"],
Image: m.Image,
NewVersion: newVersion,
+ Type: m.Labels["origin"],
//Slogan: m.Slogan,
//Rely: m.Rely,
})
} else {
unTranslation = append(unTranslation, model2.MyAppList{
- Name: m.Names[0],
+ Name: strings.ReplaceAll(m.Names[0], "/", ""),
Icon: "",
State: m.State,
CustomId: m.ID,
+ Id: m.ID,
Port: "",
- NewVersion: newVersion,
+ NewVersion: false,
Image: m.Image,
})
}
}
- systemApp := MyService.App().GetApplicationList()
- for _, v := range systemApp {
- list = append(list, model2.MyAppList{
- Name: "/" + v.Name,
- Icon: v.Icon,
- State: strconv.Itoa(v.State),
- CustomId: strconv.Itoa(v.Id),
- Port: "",
- Index: strconv.Itoa(v.Index),
- Image: "",
- Type: v.Type,
- NewVersion: false,
- })
- }
-
//lMap := make(map[string]interface{})
// for _, dbModel := range lm {
// if position {
@@ -245,7 +300,7 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
}
//system application list
-func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
+func (a *appStruct) GetSystemAppList() []types.Container {
//获取docker应用
cli, err := client2.NewClientWithOpts(client2.FromEnv)
if err != nil {
@@ -261,46 +316,16 @@ func (a *appStruct) GetSystemAppList() *[]model2.MyAppList {
//获取本地数据库应用
- var lm []model2.AppListDBModel
- a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan,image,volumes").Find(&lm)
+ // var lm []model2.AppListDBModel
+ // a.db.Table(model2.CONTAINERTABLENAME).Select("title,icon,port_map,`index`,container_id,position,label,slogan,image,volumes").Find(&lm)
- list := []model2.MyAppList{}
- lMap := make(map[string]interface{})
- for _, dbModel := range lm {
- lMap[dbModel.ContainerId] = dbModel
- }
- for _, container := range containers {
+ //list := []model2.MyAppList{}
+ //lMap := make(map[string]interface{})
+ // for _, dbModel := range lm {
+ // lMap[dbModel.ContainerId] = dbModel
+ // }
- if lMap[container.ID] != nil {
- m := lMap[container.ID].(model2.AppListDBModel)
- if len(m.Label) == 0 {
- m.Label = m.Title
- }
-
- info, err := cli.ContainerInspect(context.Background(), container.ID)
- var tm string
- if err != nil {
- tm = time.Now().String()
- } else {
- tm = info.State.StartedAt
- }
- list = append(list, model2.MyAppList{
- Name: m.Label,
- Icon: m.Icon,
- State: container.State,
- CustomId: strings.ReplaceAll(container.Names[0], "/", ""),
- Port: m.PortMap,
- Index: m.Index,
- UpTime: tm,
- Image: m.Image,
- Slogan: m.Slogan,
- //Volumes: m.Volumes,
- //Rely: m.Rely,
- })
- }
- }
-
- return &list
+ return containers
}
func (a *appStruct) GetAllDBApps() []model2.AppListDBModel {
@@ -471,7 +496,7 @@ func (a *appStruct) GetHardwareUsageSteam() {
}
dockerStats.Data = data
dockerStats.Icon = v.Labels["icon"]
- dockerStats.Title = v.Names[0]
+ dockerStats.Title = strings.ReplaceAll(v.Names[0], "/", "")
dataStats.Store(v.ID, dockerStats)
if i == 99 {
stats.Body.Close()
diff --git a/service/app_test.go b/service/app_test.go
new file mode 100644
index 0000000..e5213f4
--- /dev/null
+++ b/service/app_test.go
@@ -0,0 +1,9 @@
+package service
+
+import (
+ "testing"
+)
+
+func TestGetCasaOSCount(t *testing.T) {
+
+}
diff --git a/service/casa.go b/service/casa.go
index 1c51da9..ff7aa9d 100644
--- a/service/casa.go
+++ b/service/casa.go
@@ -10,6 +10,7 @@ import (
"github.com/IceWhaleTech/CasaOS/pkg/config"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
model2 "github.com/IceWhaleTech/CasaOS/service/model"
+ "github.com/IceWhaleTech/CasaOS/types"
"github.com/tidwall/gjson"
)
@@ -154,6 +155,7 @@ func (o *casaService) PushAppAnalyse(uuid, t string, name, language string) {
m.Type = t
m.Name = name
m.Language = language
+ m.Version = types.CURRENTVERSION
b, _ := json.Marshal(m)
head := make(map[string]string)
diff --git a/service/docker.go b/service/docker.go
index 31cf367..2fa4f06 100644
--- a/service/docker.go
+++ b/service/docker.go
@@ -135,10 +135,7 @@ func DockerPull() {
cli, _ := client2.NewClientWithOpts(client2.FromEnv)
defer cli.Close()
- authConfig := types.AuthConfig{
- Username: "cn-north-4@M4OW0IULZ3U6PCQPBUZC",
- Password: "7390181a1565f90927bbd98038436b57d6ebc66a3828d7a11dfda42b9c19d91d",
- }
+ authConfig := types.AuthConfig{}
encodedJSON, err := json2.Marshal(authConfig)
fmt.Println(err)
@@ -531,6 +528,9 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
config.Labels["web"] = m.PortMap
config.Labels["icon"] = m.Icon
config.Labels["desc"] = m.Description
+ config.Labels["index"] = m.Index
+ config.Labels["custom_id"] = m.CustomId
+ //config.Labels["order"] = strconv.Itoa(MyService.App().GetCasaOSCount() + 1)
hostConfig := &container.HostConfig{Resources: res, Mounts: volumes, RestartPolicy: rp, NetworkMode: container.NetworkMode(net), Privileged: m.Privileged, CapAdd: m.CapAdd}
//if net != "host" {
config.ExposedPorts = ports
diff --git a/service/model/o_application.go b/service/model/o_application.go
index b7edf35..e3522fb 100644
--- a/service/model/o_application.go
+++ b/service/model/o_application.go
@@ -10,7 +10,7 @@ type ApplicationModel struct {
Icon string `json:"icon"`
State int `json:"state"`
Type string `json:"type"`
- Index int `json:"index"`
+ Order int `json:"order"`
CreatedAt time.Time `gorm:"<-:create" json:"created_at"`
UpdatedAt time.Time `gorm:"<-:create;<-:update" json:"updated_at"`
}
diff --git a/service/model/o_container.go b/service/model/o_container.go
index 436b0f8..5f868a6 100644
--- a/service/model/o_container.go
+++ b/service/model/o_container.go
@@ -49,15 +49,17 @@ func (p *AppListDBModel) TableName() string {
}
type MyAppList struct {
+ Id string `json:"id"`
Name string `json:"name"`
Icon string `json:"icon"`
State string `json:"state"`
CustomId string `gorm:"column:custom_id;primary_key" json:"custom_id"`
Index string `json:"index"`
- Port string `json:"port"`
- UpTime string `json:"up_time"`
- Slogan string `json:"slogan"`
- Type string `json:"type"`
+ //Order string `json:"order"`
+ Port string `json:"port"`
+ UpTime string `json:"up_time"`
+ Slogan string `json:"slogan"`
+ Type string `json:"type"`
//Rely model.MapStrings `json:"rely"` //[{"mysql":"id"},{"mysql":"id"}]
Image string `json:"image"`
Volumes string `json:"volumes"`
diff --git a/service/person.go b/service/person.go
index 44eaa76..011a2c7 100644
--- a/service/person.go
+++ b/service/person.go
@@ -15,6 +15,7 @@ import (
"github.com/IceWhaleTech/CasaOS/model"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/quic_helper"
+ "github.com/IceWhaleTech/CasaOS/pkg/utils"
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
"github.com/IceWhaleTech/CasaOS/pkg/utils/ip_helper"
@@ -27,6 +28,7 @@ import (
type PersonService interface {
GetPersionInfo(token string) (m model.PersionModel, err error)
+ GetPersionNetWorkTypeDetection() string
}
type personService struct {
@@ -56,6 +58,16 @@ func (p *personService) GetPersionInfo(token string) (m model.PersionModel, err
err = json.Unmarshal([]byte(infoS), &m)
return
}
+func (p *personService) GetPersionNetWorkTypeDetection() string {
+ data := make(chan string)
+ list := []string{"stun.l.google.com", "stun1.l.google.com", "stun2.l.google.com", "stun.sipgate.net"}
+ for _, v := range list {
+ go utils.GetNetWorkTypeDetection(data, v)
+ }
+ result := <-data
+ close(data)
+ return result
+}
func NewPersonService(db *gorm.DB) PersonService {
return &personService{db: db}
diff --git a/service/system.go b/service/system.go
index bf92a43..75fd129 100644
--- a/service/system.go
+++ b/service/system.go
@@ -7,6 +7,7 @@ import (
"github.com/IceWhaleTech/CasaOS/pkg/config"
command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
+ "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
)
@@ -20,6 +21,8 @@ type SystemService interface {
GetTimeZone() string
UpdateUSBAutoMount(state string)
ExecUSBAutoMountShell(state string)
+ UpAppOrderFile(str string)
+ GetAppOrderFile() []byte
}
type systemService struct {
log loger.OLog
@@ -62,9 +65,15 @@ func (s *systemService) UpSystemConfig(str string, widget string) {
}
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
+func (s *systemService) UpAppOrderFile(str string) {
+ file.WriteToPath([]byte(str), config.AppInfo.ProjectPath+"/conf", "app_order.json")
+}
+func (s *systemService) GetAppOrderFile() []byte {
+ return file.ReadFullFile(config.AppInfo.ProjectPath + "/conf/app_order.json")
+}
func (s *systemService) UpdateUSBAutoMount(state string) {
config.ServerInfo.USBAutoMount = state
- config.Cfg.Section("system").Key("USBAutoMount").SetValue(state)
+ config.Cfg.Section("server").Key("USBAutoMount").SetValue(state)
config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
}
func (s *systemService) UpSystemPort(port string) {
diff --git a/service/udpconn.go b/service/udpconn.go
index d818926..3bee999 100644
--- a/service/udpconn.go
+++ b/service/udpconn.go
@@ -208,7 +208,6 @@ func ReadContent(stream quic.Stream) {
fmt.Println(err)
break
}
- fmt.Println(m)
if m.Type == types.PERSONDOWNLOAD {
r := SaveFile(m, stream)
if r {
@@ -218,7 +217,6 @@ func ReadContent(stream quic.Stream) {
Summary(m, "download")
} else if m.Type == types.PERSONCONNECTION {
if len(m.Data.(string)) > 0 {
- fmt.Println("设置ip", m.Data.(string))
UDPAddressMap[m.From] = m.Data.(string)
} else {
delete(UDPAddressMap, m.From)
@@ -253,12 +251,7 @@ func ReadContent(stream quic.Stream) {
notify.Type = types.NOTIFY_TYPE_PERSION_FIRNED_LIVE
go MyService.Notify().SendText(notify)
}
- fmt.Println("设置ip", m.Data.(string))
UDPAddressMap[m.From] = m.Data.(string)
- fmt.Println(config.ServerInfo.Token != m.From)
- fmt.Println(strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0])
- fmt.Println(strings.Split(m.Data.(string), ":")[0])
- fmt.Println(strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0])
if config.ServerInfo.Token != m.From && strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0] {
msg := model.MessageModel{}
msg.Type = types.PERSONINTERNALINSPECTION
@@ -304,7 +297,6 @@ func SendIPToServer() {
func LoopFriend() {
list := MyService.Friend().GetFriendList()
- //list := MyService.Friend().GetFriendListRemote()
msg := model.MessageModel{}
msg.Type = types.PERSONGETIP
msg.Data = ""
@@ -333,14 +325,10 @@ func LoopFriend() {
if v, ok := UDPAddressMap[list[i].Token]; ok {
if ip_helper.HasLocalIP(net.ParseIP(strings.Split(v, ":")[0])) {
msg.Data = ip_helper.GetDeviceAllIP(config.ServerInfo.UDPPort)
- fmt.Println("判断为内网ip,设置自己的ip地址", msg.Data)
}
- fmt.Println("ping的数据", UDPAddressMap[list[i].Token])
oldIP := UDPAddressMap[list[i].Token]
- fmt.Println("old ip", oldIP)
data, err := Dial(msg, false)
if err != nil || reflect.DeepEqual(data, model.MessageModel{}) || len(data.Data.(string)) == 0 {
- fmt.Println("ping失败", list[i].Token, err, data, UDPAddressMap[list[i].Token])
if oldIP == UDPAddressMap[list[i].Token] {
notify := model2.AppNotify{}
notify.CustomId = data.From
diff --git a/service/zima_info.go b/service/zima_info.go
index a78cd30..ceb2545 100644
--- a/service/zima_info.go
+++ b/service/zima_info.go
@@ -39,6 +39,7 @@ type ZiMaService interface {
CreateFile(path string) (int, error)
RenameFile(oldF, newF string) (int, error)
GetCpuInfo() []cpu.InfoStat
+ GetDeviceTree() string
}
var NetArray [][]model.IOCountersStat
@@ -149,6 +150,10 @@ func (c *zima) GetNet(physics bool) []string {
return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetNetCard " + t)
}
+func (c *zima) GetDeviceTree() string {
+ return command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetDeviceTree")
+}
+
//shell脚本参数 { 网卡名称 }
func (c *zima) GetNetState(name string) string {
return command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;CatNetCardState " + name)
diff --git a/shell/helper.sh b/shell/helper.sh
index dad3742..930dd97 100644
--- a/shell/helper.sh
+++ b/shell/helper.sh
@@ -32,7 +32,7 @@ GetNetCard() {
GetTimeZone(){
- timedatectl | grep "Time zone" | awk '{print $3}'
+ timedatectl | grep "Time zone" | awk '{printf $3}'
}
#查看网卡状态
@@ -341,4 +341,8 @@ 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
+}
+
+GetDeviceTree(){
+ cat /proc/device-tree/model
+}
diff --git a/types/system.go b/types/system.go
index 54bf050..2ca0f19 100644
--- a/types/system.go
+++ b/types/system.go
@@ -1,5 +1,15 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-02-17 18:53:22
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-13 18:08:25
+ * @FilePath: /CasaOS/types/system.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
package types
-const CURRENTVERSION = "0.3.0"
+const CURRENTVERSION = "0.3.1"
-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"
+const BODY = ""
diff --git a/web/browserconfig.xml b/web/browserconfig.xml
index a02d62e..a221792 100644
--- a/web/browserconfig.xml
+++ b/web/browserconfig.xml
@@ -1,9 +1,9 @@
-
-
-
-
-
- #da532c
-
-
-
+
+
+
+
+
+ #da532c
+
+
+
diff --git a/web/favicon.svg b/web/favicon.svg
index 8d176f0..9760ab7 100644
--- a/web/favicon.svg
+++ b/web/favicon.svg
@@ -1,14 +1,14 @@
-
-
-
+
+
+
diff --git a/web/fonts/materialdesignicons-webfont.0fb040cb.woff2 b/web/fonts/materialdesignicons-webfont.0fb040cb.woff2
new file mode 100644
index 0000000..207bcdf
Binary files /dev/null and b/web/fonts/materialdesignicons-webfont.0fb040cb.woff2 differ
diff --git a/web/fonts/materialdesignicons-webfont.1514bb9f.ttf b/web/fonts/materialdesignicons-webfont.1514bb9f.ttf
new file mode 100644
index 0000000..b813f15
Binary files /dev/null and b/web/fonts/materialdesignicons-webfont.1514bb9f.ttf differ
diff --git a/web/fonts/materialdesignicons-webfont.5a409f9f.woff b/web/fonts/materialdesignicons-webfont.5a409f9f.woff
new file mode 100644
index 0000000..7d3f0db
Binary files /dev/null and b/web/fonts/materialdesignicons-webfont.5a409f9f.woff differ
diff --git a/web/fonts/materialdesignicons-webfont.ff90567b.eot b/web/fonts/materialdesignicons-webfont.ff90567b.eot
new file mode 100644
index 0000000..f1ee489
Binary files /dev/null and b/web/fonts/materialdesignicons-webfont.ff90567b.eot differ
diff --git a/web/img/folder-publicshare.0219e0d4.svg b/web/img/CasaConnect.svg
similarity index 100%
rename from web/img/folder-publicshare.0219e0d4.svg
rename to web/img/CasaConnect.svg
diff --git a/web/img/Files.svg b/web/img/Files.svg
new file mode 100644
index 0000000..e5924aa
--- /dev/null
+++ b/web/img/Files.svg
@@ -0,0 +1,67 @@
+
+
diff --git a/web/img/add_button.76237e85.svg b/web/img/add_button.07d47199.svg
similarity index 98%
rename from web/img/add_button.76237e85.svg
rename to web/img/add_button.07d47199.svg
index be6c60a..5618a52 100644
--- a/web/img/add_button.76237e85.svg
+++ b/web/img/add_button.07d47199.svg
@@ -1,11 +1,11 @@
-
+
diff --git a/web/img/android.149f5693.svg b/web/img/android.48a6cf16.svg
similarity index 98%
rename from web/img/android.149f5693.svg
rename to web/img/android.48a6cf16.svg
index 1c71253..2ad3eb1 100644
--- a/web/img/android.149f5693.svg
+++ b/web/img/android.48a6cf16.svg
@@ -1,25 +1,25 @@
-
-
-
-
+
+
+
+
diff --git a/web/img/application-x-apple.500bd1f9.svg b/web/img/application-x-apple.5eb295b2.svg
similarity index 98%
rename from web/img/application-x-apple.500bd1f9.svg
rename to web/img/application-x-apple.5eb295b2.svg
index 58022ef..d0b946b 100644
--- a/web/img/application-x-apple.500bd1f9.svg
+++ b/web/img/application-x-apple.5eb295b2.svg
@@ -1,28 +1,28 @@
-
-
-
+
+
+
diff --git a/web/img/bg3_blur.f7b30d87.jpg b/web/img/bg3_blur.f7b30d87.jpg
deleted file mode 100644
index 2250d0c..0000000
Binary files a/web/img/bg3_blur.f7b30d87.jpg and /dev/null differ
diff --git a/web/img/casa-white.2579f069.svg b/web/img/casa-white.f250568a.svg
similarity index 98%
rename from web/img/casa-white.2579f069.svg
rename to web/img/casa-white.f250568a.svg
index 33a2f35..7cbc964 100644
--- a/web/img/casa-white.2579f069.svg
+++ b/web/img/casa-white.f250568a.svg
@@ -1,11 +1,11 @@
-
-
-
+
+
+
diff --git a/web/img/default-avatar.ab3b9bda.svg b/web/img/default-avatar.d92cd43a.svg
similarity index 98%
rename from web/img/default-avatar.ab3b9bda.svg
rename to web/img/default-avatar.d92cd43a.svg
index b217e0d..033868e 100644
--- a/web/img/default-avatar.ab3b9bda.svg
+++ b/web/img/default-avatar.d92cd43a.svg
@@ -1,39 +1,39 @@
-
-
-
+
+
+
diff --git a/web/img/folder-hdd.adcf549a.svg b/web/img/folder-hdd.42e0a4ee.svg
similarity index 98%
rename from web/img/folder-hdd.adcf549a.svg
rename to web/img/folder-hdd.42e0a4ee.svg
index c9fce2a..c90fc32 100644
--- a/web/img/folder-hdd.adcf549a.svg
+++ b/web/img/folder-hdd.42e0a4ee.svg
@@ -1,121 +1,121 @@
-
-
-
+
+
+
diff --git a/web/img/folder-usb.84d5b55d.svg b/web/img/folder-usb.1011b135.svg
similarity index 98%
rename from web/img/folder-usb.84d5b55d.svg
rename to web/img/folder-usb.1011b135.svg
index 253d168..4ef3d15 100644
--- a/web/img/folder-usb.84d5b55d.svg
+++ b/web/img/folder-usb.1011b135.svg
@@ -1,113 +1,113 @@
-
-
-
+
+
+
diff --git a/web/img/gradient.6c5a7f30.png b/web/img/gradient.6c5a7f30.png
new file mode 100644
index 0000000..8e5bea9
Binary files /dev/null and b/web/img/gradient.6c5a7f30.png differ
diff --git a/web/img/icon/safari-pinned-tab.svg b/web/img/icon/safari-pinned-tab.svg
index e750780..af12e15 100644
--- a/web/img/icon/safari-pinned-tab.svg
+++ b/web/img/icon/safari-pinned-tab.svg
@@ -1,25 +1,25 @@
-
-
-
+
+
+
diff --git a/web/img/macos.da8469ce.svg b/web/img/macos.6403eda3.svg
similarity index 97%
rename from web/img/macos.da8469ce.svg
rename to web/img/macos.6403eda3.svg
index 0d2f3ae..2645549 100644
--- a/web/img/macos.da8469ce.svg
+++ b/web/img/macos.6403eda3.svg
@@ -1,159 +1,159 @@
-
-