Browse Source

Dev (#261)

* fix bug

* updata UI

* 0.3.2

### Added

- [Files] Files can now be selected multiple files and downloaded, deleted, moved, etc.
- [Apps] Support to modify the application opening address.([#204](https://github.com/IceWhaleTech/CasaOS/issues/204))

### Changed

- [Apps] Hide the display of non-essential environment variables in the application.
- [System] Network, disk, cpu, memory, etc. information is modified to be pushed via socket.
- [System] Optimize opening speed.([#214](https://github.com/IceWhaleTech/CasaOS/issues/214))
### Fixed

- [System] Fixed the problem that sync data cannot submit the device ID ([#68](https://github.com/IceWhaleTech/CasaOS/issues/68))
- [Files] Fixed the code editor center alignment display problem.([#210](https://github.com/IceWhaleTech/CasaOS/issues/210))
- [Files] Fixed the problem of wrong name when downloading files.([#240](https://github.com/IceWhaleTech/CasaOS/issues/240))
- [System] Fixed the network display as a negative number problem.([#224](https://github.com/IceWhaleTech/CasaOS/issues/224))

* Modify log help class

* Fix some bugs in 0.3.2

* Solve the operation file queue problem

* Exclude web folders

* update UI
link 3 years ago
parent
commit
d4bed3e5c7
100 changed files with 1836 additions and 1814 deletions
  1. 1 0
      .gitignore
  2. 29 0
      CHANGELOG.md
  3. 1 1
      UI
  4. 7 1
      go.mod
  5. 39 1
      go.sum
  6. 27 14
      main.go
  7. 12 6
      middleware/gin.go
  8. 13 0
      model/category.go
  9. 31 0
      model/file.go
  10. 2 0
      model/manifest.go
  11. 21 0
      model/notify/application.go
  12. 22 0
      model/notify/file.go
  13. 20 0
      model/notify/message.go
  14. 16 0
      model/notify/person.go
  15. 18 0
      model/notify/result.go
  16. 11 0
      model/sys_common.go
  17. 150 0
      pkg/utils/file/file.go
  18. 64 81
      pkg/utils/loger/log.go
  19. 109 0
      pkg/utils/loger/log_old.go
  20. 12 25
      pkg/utils/version/version.go
  21. 6 8
      route/init.go
  22. 155 0
      route/periodical.go
  23. 8 47
      route/route.go
  24. 60 0
      route/socket.go
  25. 1 1
      route/v1/app.go
  26. 128 186
      route/v1/docker.go
  27. 185 124
      route/v1/file.go
  28. 1 58
      route/v1/notify.go
  29. 62 0
      route/v1/notify_old.go
  30. 23 32
      route/v1/system.go
  31. 15 5
      route/v1/zima_info.go
  32. 20 16
      service/app.go
  33. 53 5
      service/casa.go
  34. 14 50
      service/disk.go
  35. 25 16
      service/docker.go
  36. 103 28
      service/file.go
  37. 12 0
      service/model/o_container.go
  38. 237 17
      service/notify.go
  39. 13 5
      service/rely.go
  40. 8 10
      service/service.go
  41. 9 8
      service/share_directory.go
  42. 44 5
      service/system.go
  43. 3 5
      service/task.go
  44. 12 11
      service/udpconn.go
  45. 31 74
      service/zima_info.go
  46. 3 3
      types/system.go
  47. 0 96
      web/8ee7a98310ee94717fe1.worker.js
  48. 0 17
      web/img/android-package-archive.c32c4fdb.svg
  49. 0 17
      web/img/application-apk.319706c4.svg
  50. 0 21
      web/img/application-certificate.64a6804d.svg
  51. 0 11
      web/img/application-dicom.fbef31c7.svg
  52. 0 13
      web/img/application-epub+zip.73eef8b2.svg
  53. 0 13
      web/img/application-illustrator.2ea791ae.svg
  54. 0 22
      web/img/application-json.eea7b6c3.svg
  55. 0 13
      web/img/application-msonenote.4772ddbe.svg
  56. 0 18
      web/img/application-msoutlook.0c2789ef.svg
  57. 0 16
      web/img/application-msword-template.5500dd0c.svg
  58. 0 26
      web/img/application-octet-stream.4dbc6148.svg
  59. 0 21
      web/img/application-ogg.776137df.svg
  60. 0 13
      web/img/application-pdf.319df017.svg
  61. 0 13
      web/img/application-pgp-signature.a482d859.svg
  62. 0 11
      web/img/application-pgp.ef9a65ff.svg
  63. 0 13
      web/img/application-photoshop.20ed858b.svg
  64. 0 13
      web/img/application-postscript.7a2e596a.svg
  65. 0 14
      web/img/application-rss_xml.5d705f41.svg
  66. 0 16
      web/img/application-sql.e76bf92b.svg
  67. 0 19
      web/img/application-vnd.appimage.50730ff3.svg
  68. 0 13
      web/img/application-vnd.flatpak.8a781de6.svg
  69. 0 21
      web/img/application-vnd.flatpak.ref.26e20d79.svg
  70. 0 13
      web/img/application-vnd.iccprofile.0c017bee.svg
  71. 0 29
      web/img/application-vnd.kde.bluedevil-sendfile.a912311c.svg
  72. 0 13
      web/img/application-vnd.ms-access.785a7627.svg
  73. 0 32
      web/img/application-vnd.ms-cab-compressed.011f2e86.svg
  74. 0 16
      web/img/application-vnd.ms-excel.ec28c59f.svg
  75. 0 16
      web/img/application-vnd.ms-excel.template.macroenabled.12.8ee75839.svg
  76. 0 24
      web/img/application-vnd.ms-htmlhelp.c8fb9bfd.svg
  77. 0 13
      web/img/application-vnd.ms-infopath.c0a76ad3.svg
  78. 0 16
      web/img/application-vnd.ms-powerpoint.b1a13336.svg
  79. 0 16
      web/img/application-vnd.ms-powerpoint.template.macroenabled.12.0409b2fe.svg
  80. 0 13
      web/img/application-vnd.ms-publisher.32dbb1c3.svg
  81. 0 16
      web/img/application-vnd.ms-word.0209c533.svg
  82. 0 13
      web/img/application-vnd.oasis.opendocument.chart.91c53f93.svg
  83. 0 13
      web/img/application-vnd.oasis.opendocument.formula-template.d5dbf3d8.svg
  84. 0 13
      web/img/application-vnd.oasis.opendocument.formula.a4bc6018.svg
  85. 0 13
      web/img/application-vnd.oasis.opendocument.presentation-template.5b2c8be4.svg
  86. 0 13
      web/img/application-vnd.oasis.opendocument.spreadsheet-template.a3256fa8.svg
  87. 0 13
      web/img/application-vnd.oasis.opendocument.text-template.4e634bfe.svg
  88. 0 11
      web/img/application-vnd.oasis.opendocument.web-template.5d282765.svg
  89. 0 13
      web/img/application-vnd.snap.72d9809b.svg
  90. 0 13
      web/img/application-vnd.visio.90d89058.svg
  91. 0 16
      web/img/application-x-ace.03fa0685.svg
  92. 0 23
      web/img/application-x-addon.4a1bb379.svg
  93. 0 16
      web/img/application-x-ar.3c76d5a5.svg
  94. 0 16
      web/img/application-x-arc.c4348636.svg
  95. 0 26
      web/img/application-x-archive.3ecaf965.svg
  96. 0 16
      web/img/application-x-arj.020953b3.svg
  97. 0 23
      web/img/application-x-bittorrent.0e44cdf9.svg
  98. 0 21
      web/img/application-x-blender.1a5d4c35.svg
  99. 0 16
      web/img/application-x-bzdvi.ddea8a90.svg
  100. 0 16
      web/img/application-x-bzip-compressed-tar.b40885da.svg

+ 1 - 0
.gitignore

@@ -29,6 +29,7 @@ gen
 /out/
 /db/
 /docs/
+/web/
 /conf/conf.ini
 __debug_bin
 main

+ 29 - 0
CHANGELOG.md

@@ -11,12 +11,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Changed
 
+
 ### Removed
 
 ### Security
 
 ### Fixed
 
+## [0.3.2-pre]
+
+### Added
+
+- [Files] Files can now be selected multiple files and downloaded, deleted, moved, etc.
+- [Apps] Support to modify the application opening address.([#204](https://github.com/IceWhaleTech/CasaOS/issues/204))
+
+### Changed
+
+- [Apps] Hide the display of non-essential environment variables in the application.([#196](https://github.com/IceWhaleTech/CasaOS/issues/196))
+- [System] Network, disk, cpu, memory, etc. information is modified to be pushed via socket.
+- [System] Optimize opening speed.([#214](https://github.com/IceWhaleTech/CasaOS/issues/214))
+- [Language] Update language pack [zarevskaya](https://github.com/zarevskaya) [patrickhilker](https://github.com/patrickhilker)
+- [System] Interface path adjustment
+
+### Removed
+
+- [Files] Remove the online preview function of PDF files
+
+### Fixed
+
+- [System] Fixed the problem that sync data cannot submit the device ID ([#68](https://github.com/IceWhaleTech/CasaOS/issues/68))
+- [Files] Fixed the code editor center alignment display problem.([#210](https://github.com/IceWhaleTech/CasaOS/issues/210))
+- [Files] Fixed the problem of wrong name when downloading files.([#240](https://github.com/IceWhaleTech/CasaOS/issues/240))
+- [System] Fixed the network display as a negative number problem.([#224](https://github.com/IceWhaleTech/CasaOS/issues/224))
+- [System] Fixed the problem of wireless network card traffic display.([#222](https://github.com/IceWhaleTech/CasaOS/issues/222))
+
+
 ## [0.3.1.1] - 2022-05-17
 
 ### Fixed

+ 1 - 1
UI

@@ -1 +1 @@
-Subproject commit 16e62b4cf09537cf2c0a3816c3da43bd3af373a1
+Subproject commit d164d2f5e411e7267f88858ea6e9e24ff81c80b3

+ 7 - 1
go.mod

@@ -7,6 +7,9 @@ require (
 	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
+	github.com/ambelovsky/go-structs v1.1.0 // indirect
+	github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109
+	github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19 // indirect
 	github.com/bits-and-blooms/bitset v1.2.1 // indirect
 	github.com/containerd/containerd v1.5.7
 	github.com/containerd/continuity v0.2.0 // indirect
@@ -29,6 +32,7 @@ require (
 	github.com/gomodule/redigo v1.8.5
 	github.com/google/go-github/v36 v36.0.0
 	github.com/google/uuid v1.3.0 // indirect
+	github.com/googollee/go-socket.io v1.6.2
 	github.com/gorilla/mux v1.8.0 // indirect
 	github.com/gorilla/websocket v1.4.2
 	github.com/jinzhu/copier v0.3.2
@@ -39,6 +43,7 @@ require (
 	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/mattn/go-isatty v0.0.14 // indirect
 	github.com/mattn/go-sqlite3 v1.14.11 // indirect
+	github.com/mholt/archiver/v3 v3.5.1
 	github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
 	github.com/morikuni/aec v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.0.2 // indirect
@@ -53,13 +58,13 @@ 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
 	github.com/tklauser/go-sysconf v0.3.6 // indirect
 	github.com/ugorji/go v1.2.6 // indirect
 	go.opencensus.io v0.23.0 // indirect
+	go.uber.org/zap v1.10.0
 	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
 	golang.org/x/mod v0.5.0 // indirect
 	golang.org/x/net v0.0.0-20211020060615-d418f374d309 // indirect
@@ -73,6 +78,7 @@ require (
 	google.golang.org/grpc v1.41.0 // indirect
 	gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
 	gopkg.in/ini.v1 v1.62.0 // indirect
+	gopkg.in/natefinch/lumberjack.v2 v2.0.0
 	gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
 	gorm.io/driver/sqlite v1.2.6
 	gorm.io/gorm v1.22.5

+ 39 - 1
go.sum

@@ -54,6 +54,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935
 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
 github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 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=
@@ -99,6 +100,14 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
+github.com/ambelovsky/go-structs v1.1.0 h1:LXj4/mHnYw0qhXQhOo96+ULGQ88H8qMcZd5SHef8boY=
+github.com/ambelovsky/go-structs v1.1.0/go.mod h1:zN3RBXQvxgjjq/Q/WZS7p5AEK+qC9mNg7ycnvoQ63Ak=
+github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109 h1:Tp8GVfUOEmJftBqi4+/aXTwJzm24POo6wIHeuTqaT+Y=
+github.com/ambelovsky/gosf v0.0.0-20201109201340-237aea4d6109/go.mod h1:MUREokfMKREm1fOm2babarrkYdk/dGHWY+ITC3qHHPQ=
+github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19 h1:suVCm9PiIhz7ftTbWQNe7u2YjVfr8AEuUiNWKWApdMM=
+github.com/ambelovsky/gosf-socketio v0.0.0-20201109193639-add9d32f8b19/go.mod h1:o0+8DH+3X+FEOgSdNud0+8jJAsjtR9H3hF+O10Zcj/c=
+github.com/andybalholm/brotli v1.0.1 h1:KqhlKozYbRtJvsPrrEeXcO+N2l6NYT5A2QAFmSULpEc=
+github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
 github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@@ -289,6 +298,9 @@ 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/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
+github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
+github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
 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=
@@ -401,6 +413,7 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
 github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
 github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
 github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
 github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
@@ -453,6 +466,9 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/snappy v0.0.2 h1:aeE13tS0IiQgFjYdoL8qN3K1N2bXXtI6Vi51/y7BpMw=
+github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/gomodule/redigo v1.8.4/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
 github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
 github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -499,6 +515,8 @@ github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE0
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
+github.com/googollee/go-socket.io v1.6.2 h1:olKLLHJtHz1IkL/OrTyNriZZvVQYEORNkJAqsOwPask=
+github.com/googollee/go-socket.io v1.6.2/go.mod h1:0vGP8/dXR9SZUMMD4+xxaGo/lohOw3YWMh2WRiWeKxg=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
@@ -563,10 +581,15 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
 github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
+github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
 github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
 github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
+github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
+github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
+github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -619,10 +642,13 @@ github.com/mattn/go-sqlite3 v1.14.11 h1:gt+cp9c0XGqe9S/wAHTL3n/7MqY+siPWgWJgqdsF
 github.com/mattn/go-sqlite3 v1.14.11/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
+github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
 github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
 github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
 github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
 github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
@@ -651,6 +677,8 @@ github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/
 github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
 github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
+github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
+github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
 github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
 github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
@@ -711,6 +739,8 @@ github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTK
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
+github.com/pierrec/lz4/v4 v4.1.2 h1:qvY3YFXRQE/XB8MlLzJH7mSzBs74eA2gg52YTk6jUPM=
+github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -813,7 +843,6 @@ 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=
@@ -875,6 +904,9 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
 github.com/ugorji/go/codec v1.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
 github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
 github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
+github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/ulikunitz/xz v0.5.9 h1:RsKRIA2MO8x56wkkcd3LbtcE/uMszhb6DpRf+3uwa3I=
+github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
 github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
@@ -893,6 +925,8 @@ github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr
 github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
 github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
+github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
+github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -919,8 +953,11 @@ go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
 go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/atomic v1.4.0 h1:cxzIVoETapQEqDhQu3QfnvXAV4AlzcvUCxkVUFw3+EU=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
@@ -1350,6 +1387,7 @@ gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/R
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
 gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
 gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=

+ 27 - 14
main.go

@@ -6,14 +6,13 @@ import (
 	"net/http"
 	"time"
 
+	"github.com/IceWhaleTech/CasaOS/model/notify"
 	"github.com/IceWhaleTech/CasaOS/pkg/cache"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/sqlite"
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	"github.com/IceWhaleTech/CasaOS/route"
 	"github.com/IceWhaleTech/CasaOS/service"
-	model2 "github.com/IceWhaleTech/CasaOS/service/model"
-	"github.com/IceWhaleTech/CasaOS/types"
 
 	"github.com/robfig/cron"
 	"gorm.io/gorm"
@@ -29,18 +28,18 @@ func init() {
 	flag.Parse()
 	config.InitSetup(*configFlag)
 	config.UpdateSetup()
-	loger2.LogSetup()
+	loger.LogInit()
 	if len(*dbFlag) == 0 {
 		*dbFlag = config.AppInfo.ProjectPath + "/db"
 	}
 	sqliteDB = sqlite.GetDb(*dbFlag)
 	//gredis.GetRedisConn(config.RedisInfo),
-	service.MyService = service.NewService(sqliteDB, loger2.NewOLoger())
+	service.MyService = service.NewService(sqliteDB)
 	service.Cache = cache.Init()
 
 	go service.UDPService()
 
-	fmt.Println("token", service.GetToken())
+	fmt.Println("t", service.GetToken())
 	service.UDPAddressMap = make(map[string]string)
 	//go service.SocketConnect()
 	service.CancelList = make(map[string]string)
@@ -66,12 +65,22 @@ func init() {
 // @name Authorization
 // @BasePath /v1
 func main() {
+	service.NotifyMsg = make(chan notify.Message, 10)
 	if *showUserInfo {
 		fmt.Println("CasaOS User Info")
 		fmt.Println("UserName:" + config.UserInfo.UserName)
 		fmt.Println("Password:" + config.UserInfo.PWD)
 		return
 	}
+
+	go route.SocketInit(service.NotifyMsg)
+	go func() {
+		for i := 0; i < 1000; i++ {
+			time.Sleep(2 * time.Second)
+			//service.NotifyMsg <- strconv.Itoa(i)
+		}
+	}()
+
 	//model.Setup()
 	//gredis.Setup()
 	r := route.InitRouter()
@@ -86,18 +95,19 @@ func main() {
 		service.SendIPToServer()
 
 		service.LoopFriend()
-		service.MyService.App().CheckNewImage()
+		//service.MyService.App().CheckNewImage()
 	})
 	if err != nil {
 		fmt.Println(err)
 	}
-	err = cron2.AddFunc("0/1 * * * * *", func() {
-		notify := model2.AppNotify{}
-		notify.CustomId = ""
-		notify.Type = types.NOTIFY_TYPE_HEALTH_CHECK
-
-		go service.MyService.Notify().SendText(notify)
-
+	err = cron2.AddFunc("0/3 * * * * *", func() {
+		if service.ClientCount > 0 {
+			route.SendNetINfoBySocket()
+			route.SendCPUBySocket()
+			route.SendMemBySocket()
+			route.SendDiskBySocket()
+			route.SendUSBBySocket()
+		}
 	})
 	if err != nil {
 		fmt.Println(err)
@@ -114,4 +124,7 @@ func main() {
 
 	s.ListenAndServe()
 
+	// if err := r.Run(fmt.Sprintf(":%v", config.ServerInfo.HttpPort)); err != nil {
+	// 	fmt.Println("failed run app: ", err)
+	// }
 }

+ 12 - 6
middleware/gin.go

@@ -1,3 +1,13 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2021-10-08 10:29:08
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-25 19:17:45
+ * @FilePath: /CasaOS/middleware/gin.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package middleware
 
 import (
@@ -10,20 +20,16 @@ import (
 func Cors() gin.HandlerFunc {
 	return func(c *gin.Context) {
 		method := c.Request.Method
-		//origin := c.Request.Header.Get("Origin") //请求头部
-		//if origin != "" {
-		//接收客户端发送的origin (重要!)
-		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
+
 		c.Header("Access-Control-Allow-Origin", "*")
-		//服务器支持的所有跨域请求的方法
 		c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
 		//允许跨域设置可以返回其他子段,可以自定义字段
 		c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,Language")
 		// 允许浏览器(客户端)可以解析的头部 (重要)
 		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
+		//c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")
 		//设置缓存时间
 		c.Header("Access-Control-Max-Age", "172800")
-		//允许客户端传递校验信息比如 cookie (重要)
 		c.Header("Access-Control-Allow-Credentials", "true")
 		c.Set("content-type", "application/json")
 		//}

+ 13 - 0
model/category.go

@@ -1,5 +1,18 @@
+/*
+ * @Author: link a624669980@163.com
+ * @Date: 2022-05-16 17:37:08
+ * @LastEditors: link a624669980@163.com
+ * @LastEditTime: 2022-06-07 17:12:30
+ * @FilePath: \CasaOS\model\category.go
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+
+ */
 package model
 
+// type ServerCategoryList struct {
+// 	Version string         `json:"version"`
+// 	Item    []CategoryList `json:"item"`
+// }
 type ServerCategoryList struct {
 	Id uint `gorm:"column:id;primary_key" json:"id"`
 	//CreatedAt time.Time `json:"created_at"`

+ 31 - 0
model/file.go

@@ -0,0 +1,31 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-20 16:27:12
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-06-08 15:40:33
+ * @FilePath: /CasaOS/model/file.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+package model
+
+type FileOperate struct {
+	Type          string     `json:"type" binding:"required"`
+	Item          []FileItem `json:"item" binding:"required"`
+	TotalSize     int64      `json:"total_size"`
+	ProcessedSize int64      `json:"processed_size"`
+	To            string     `json:"to" binding:"required"`
+}
+
+type FileItem struct {
+	From          string `json:"from" binding:"required"`
+	Finished      bool   `json:"finished"`
+	Size          int64  `json:"size"`
+	ProcessedSize int64  `json:"processed_size"`
+}
+
+type FileUpdate struct {
+	FilePath    string `json:"path" binding:"required"`
+	FileContent string `json:"content" binding:"required"`
+}

+ 2 - 0
model/manifest.go

@@ -127,4 +127,6 @@ type CustomizationPostData struct {
 	Privileged  bool     `json:"privileged"`
 	CapAdd      []string `json:"cap_add"`
 	Cmd         []string `json:"cmd"`
+	Protocol    string   `json:"protocol"`
+	Host        string   `json:"host"`
 }

+ 21 - 0
model/notify/application.go

@@ -0,0 +1,21 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-27 15:01:58
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-31 14:51:21
+ * @FilePath: /CasaOS/model/notify/application.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+package notify
+
+type Application struct {
+	Name     string `json:"name"`
+	State    string `json:"state"`
+	Type     string `json:"type"`
+	Icon     string `json:"icon"`
+	Message  string `json:"message"`
+	Finished bool   `json:"finished"`
+	Success  bool   `json:"success"`
+}

+ 22 - 0
model/notify/file.go

@@ -0,0 +1,22 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-26 14:21:57
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-06-02 11:14:15
+ * @FilePath: /CasaOS/model/notify/file.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+package notify
+
+type File struct {
+	Finished       bool   `json:"finished"`
+	ProcessedSize  int64  `json:"processed_size"`
+	ProcessingPath string `json:"processing_path"`
+	Status         string `json:"status"`
+	TotalSize      int64  `json:"total_size"`
+	Id             string `json:"id"`
+	To             string `json:"to"`
+	Type           string `json:"type"`
+}

+ 20 - 0
model/notify/message.go

@@ -0,0 +1,20 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-26 14:39:22
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-26 19:08:52
+ * @FilePath: /CasaOS/model/notify/message.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+package notify
+
+import (
+	f "github.com/ambelovsky/gosf"
+)
+
+type Message struct {
+	Path string    `json:"path"`
+	Msg  f.Message `json:"msg"`
+}

+ 16 - 0
model/notify/person.go

@@ -0,0 +1,16 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-27 18:42:42
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-27 18:43:08
+ * @FilePath: /CasaOS/model/notify/person.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+package notify
+
+type Person struct {
+	ShareId string `json:"share_id"`
+	Type    string `json:"type"`
+}

+ 18 - 0
model/notify/result.go

@@ -0,0 +1,18 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-26 14:21:11
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-27 11:15:59
+ * @FilePath: /CasaOS/model/notify/result.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+
+package notify
+
+// Notify struct for Notify
+type NotifyModel struct {
+	Data  interface{} `json:"data"`
+	State string      `json:"state"`
+}

+ 11 - 0
model/sys_common.go

@@ -1,3 +1,13 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-13 18:15:46
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-30 16:43:59
+ * @FilePath: /CasaOS/model/sys_common.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package model
 
 import "time"
@@ -31,6 +41,7 @@ type ServerModel struct {
 	Token        string
 	UDPPort      string
 	USBAutoMount string
+	SocketPort   string
 }
 
 //服务配置

+ 150 - 0
pkg/utils/file/file.go

@@ -2,9 +2,11 @@ package file
 
 import (
 	"bufio"
+	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
+	"log"
 	"mime/multipart"
 	"os"
 	"path"
@@ -12,6 +14,8 @@ import (
 	"path/filepath"
 	"strconv"
 	"strings"
+
+	"github.com/mholt/archiver/v3"
 )
 
 // GetSize get the file size
@@ -332,3 +336,149 @@ func SpliceFiles(dir, path string, length int, startPoint int) error {
 
 	return nil
 }
+
+func GetCompressionAlgorithm(t string) (string, archiver.Writer, error) {
+
+	switch t {
+	case "zip", "":
+		return ".zip", archiver.NewZip(), nil
+	case "tar":
+		return ".tar", archiver.NewTar(), nil
+	case "targz":
+		return ".tar.gz", archiver.NewTarGz(), nil
+	case "tarbz2":
+		return ".tar.bz2", archiver.NewTarBz2(), nil
+	case "tarxz":
+		return ".tar.xz", archiver.NewTarXz(), nil
+	case "tarlz4":
+		return ".tar.lz4", archiver.NewTarLz4(), nil
+	case "tarsz":
+		return ".tar.sz", archiver.NewTarSz(), nil
+	default:
+		return "", nil, errors.New("format not implemented")
+	}
+}
+func AddFile(ar archiver.Writer, path, commonPath string) error {
+
+	info, err := os.Stat(path)
+	if err != nil {
+		return err
+	}
+
+	if !info.IsDir() && !info.Mode().IsRegular() {
+		return nil
+	}
+
+	file, err := os.Open(path)
+	if err != nil {
+		return err
+	}
+	defer file.Close()
+
+	if path != commonPath {
+		filename := info.Name()
+		err = ar.Write(archiver.File{
+			FileInfo: archiver.FileInfo{
+				FileInfo:   info,
+				CustomName: filename,
+			},
+			ReadCloser: file,
+		})
+		if err != nil {
+			return err
+		}
+	}
+
+	if info.IsDir() {
+		names, err := file.Readdirnames(0)
+		if err != nil {
+			return err
+		}
+
+		for _, name := range names {
+			err = AddFile(ar, filepath.Join(path, name), commonPath)
+			if err != nil {
+				log.Printf("Failed to archive %v", err)
+			}
+		}
+	}
+
+	return nil
+}
+func CommonPrefix(sep byte, paths ...string) string {
+	// Handle special cases.
+	switch len(paths) {
+	case 0:
+		return ""
+	case 1:
+		return path.Clean(paths[0])
+	}
+
+	// Note, we treat string as []byte, not []rune as is often
+	// done in Go. (And sep as byte, not rune). This is because
+	// most/all supported OS' treat paths as string of non-zero
+	// bytes. A filename may be displayed as a sequence of Unicode
+	// runes (typically encoded as UTF-8) but paths are
+	// not required to be valid UTF-8 or in any normalized form
+	// (e.g. "é" (U+00C9) and "é" (U+0065,U+0301) are different
+	// file names.
+	c := []byte(path.Clean(paths[0]))
+
+	// We add a trailing sep to handle the case where the
+	// common prefix directory is included in the path list
+	// (e.g. /home/user1, /home/user1/foo, /home/user1/bar).
+	// path.Clean will have cleaned off trailing / separators with
+	// the exception of the root directory, "/" (in which case we
+	// make it "//", but this will get fixed up to "/" bellow).
+	c = append(c, sep)
+
+	// Ignore the first path since it's already in c
+	for _, v := range paths[1:] {
+		// Clean up each path before testing it
+		v = path.Clean(v) + string(sep)
+
+		// Find the first non-common byte and truncate c
+		if len(v) < len(c) {
+			c = c[:len(v)]
+		}
+		for i := 0; i < len(c); i++ {
+			if v[i] != c[i] {
+				c = c[:i]
+				break
+			}
+		}
+	}
+
+	// Remove trailing non-separator characters and the final separator
+	for i := len(c) - 1; i >= 0; i-- {
+		if c[i] == sep {
+			c = c[:i]
+			break
+		}
+	}
+
+	return string(c)
+}
+
+func GetFileOrDirSize(path string) (int64, error) {
+	fileInfo, err := os.Stat(path)
+	if err != nil {
+		return 0, err
+	}
+	if fileInfo.IsDir() {
+		return DirSizeB(path + "/")
+	}
+	return fileInfo.Size(), nil
+}
+
+//getFileSize get file size by path(B)
+func DirSizeB(path string) (int64, error) {
+	var size int64
+	err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
+		if !info.IsDir() {
+			size += info.Size()
+		}
+		return err
+	})
+	return size, err
+}

+ 64 - 81
pkg/utils/loger/log.go

@@ -1,109 +1,92 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-06-02 15:09:38
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-06-02 17:43:38
+ * @FilePath: /CasaOS/pkg/utils/loger/log.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package loger
 
 import (
 	"fmt"
-	"log"
 	"os"
+	"path"
 	"path/filepath"
 	"runtime"
-	
+
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
-	file2 "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
+	"go.uber.org/zap"
+	"go.uber.org/zap/zapcore"
+	"gopkg.in/natefinch/lumberjack.v2"
 )
 
-//定义一个int的别名
-type Level int
-
-type OLog interface {
-	Debug(v ...interface{})
-	Info(v ...interface{})
-	Warn(v ...interface{})
-	Error(v ...interface{})
-	Fatal(v ...interface{})
-	Path() string
-}
+var loggers *zap.Logger
+
+func getFileLogWriter() (writeSyncer zapcore.WriteSyncer) {
+	// 使用 lumberjack 实现 log rotate
+	lumberJackLogger := &lumberjack.Logger{
+		Filename: filepath.Join(config.AppInfo.LogSavePath, fmt.Sprintf("%s.%s",
+			config.AppInfo.LogSaveName,
+			config.AppInfo.LogFileExt,
+		)),
+		MaxSize:    100,
+		MaxBackups: 60,
+		MaxAge:     1,
+		Compress:   true,
+	}
 
-type oLog struct {
+	return zapcore.AddSync(lumberJackLogger)
 }
 
-var (
-	F                  *os.File
-	DefaultPrefix      = ""
-	DefaultCallerDepth = 2
-	logger             *log.Logger
-	logPrefix          = ""
-	levelFlags         = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
-)
-
-//iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。
-const (
-	DEBUG Level = iota
-	INFO
-	WARN
-	ERROR
-	FATAL
-)
-
-//日志初始化
-func LogSetup() {
-	var err error
-	filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
-	fileName := fmt.Sprintf("%s.%s",
-		config.AppInfo.LogSaveName,
-		config.AppInfo.LogFileExt,
+func LogInit() {
+	encoderConfig := zap.NewProductionEncoderConfig()
+	encoderConfig.EncodeTime = zapcore.EpochTimeEncoder
+	encoder := zapcore.NewJSONEncoder(encoderConfig)
+	fileWriteSyncer := getFileLogWriter()
+	core := zapcore.NewTee(
+		zapcore.NewCore(encoder, zapcore.AddSync(os.Stdout), zapcore.DebugLevel),
+		zapcore.NewCore(encoder, fileWriteSyncer, zapcore.DebugLevel),
 	)
-	F, err = file2.MustOpen(fileName, filePath)
-	if err != nil {
-		log.Fatalf("logging.Setup err: %v", err)
-	}
-
-	logger = log.New(F, DefaultPrefix, log.LstdFlags)
+	loggers = zap.New(core)
 
 }
-func (o *oLog) Path() string {
-	filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
-	fileName := fmt.Sprintf("%s.%s",
-		config.AppInfo.LogSaveName,
-		config.AppInfo.LogFileExt,
-	)
-	return filePath + fileName
-}
-func (o *oLog) Debug(v ...interface{}) {
-	setPrefix(DEBUG)
-	logger.Println(v)
-}
 
-func (o *oLog) Info(v ...interface{}) {
-	setPrefix(INFO)
-	logger.Println(v)
+func Info(message string, fields ...zap.Field) {
+	callerFields := getCallerInfoForLog()
+	fields = append(fields, callerFields...)
+	loggers.Info(message, fields...)
 }
 
-func (o *oLog) Warn(v ...interface{}) {
-	setPrefix(WARN)
-	logger.Println(v)
+func Debug(message string, fields ...zap.Field) {
+	callerFields := getCallerInfoForLog()
+	fields = append(fields, callerFields...)
+	loggers.Debug(message, fields...)
 }
 
-func (o *oLog) Error(v ...interface{}) {
-	setPrefix(ERROR)
-	logger.Println(v)
+func Error(message string, fields ...zap.Field) {
+	callerFields := getCallerInfoForLog()
+	fields = append(fields, callerFields...)
+	loggers.Error(message, fields...)
 }
 
-func (o *oLog) Fatal(v ...interface{}) {
-	setPrefix(FATAL)
-	logger.Println(v)
+func Warn(message string, fields ...zap.Field) {
+	callerFields := getCallerInfoForLog()
+	fields = append(fields, callerFields...)
+	loggers.Warn(message, fields...)
 }
 
-func setPrefix(level Level) {
-	_, file, line, ok := runtime.Caller(DefaultCallerDepth)
-	if ok {
-		logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line)
-	} else {
-		logPrefix = fmt.Sprintf("[%s]", levelFlags[level])
-	}
+func getCallerInfoForLog() (callerFields []zap.Field) {
 
-	logger.SetPrefix(logPrefix)
-}
+	pc, file, line, ok := runtime.Caller(2) // 回溯两层,拿到写日志的调用方的函数信息
+	if !ok {
+		return
+	}
+	funcName := runtime.FuncForPC(pc).Name()
+	funcName = path.Base(funcName) //Base函数返回路径的最后一个元素,只保留函数名
 
-func NewOLoger() OLog {
-	return &oLog{}
+	callerFields = append(callerFields, zap.String("func", funcName), zap.String("file", file), zap.Int("line", line))
+	return
 }

+ 109 - 0
pkg/utils/loger/log_old.go

@@ -0,0 +1,109 @@
+package loger
+
+import (
+	"fmt"
+	"log"
+	"os"
+	"path/filepath"
+	"runtime"
+
+	"github.com/IceWhaleTech/CasaOS/pkg/config"
+	file2 "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
+)
+
+//定义一个int的别名
+type Level int
+
+type OLog interface {
+	Debug(v ...interface{})
+	Info(v ...interface{})
+	Warn(v ...interface{})
+	Error(v ...interface{})
+	Fatal(v ...interface{})
+	Path() string
+}
+
+type oLog struct {
+}
+
+var (
+	F                  *os.File
+	DefaultPrefix      = ""
+	DefaultCallerDepth = 2
+	logger             *log.Logger
+	logPrefix          = ""
+	levelFlags         = []string{"DEBUG", "INFO", "WARN", "ERROR", "FATAL"}
+)
+
+//iota在const关键字出现时将被重置为0(const内部的第一行之前),const中每新增一行常量声明将使iota计数一次(iota可理解为const语句块中的行索引)。
+const (
+	DEBUG Level = iota
+	INFO
+	WARN
+	ERROR
+	FATAL
+)
+
+//日志初始化
+func LogSetupOld() {
+	var err error
+	filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
+	fileName := fmt.Sprintf("%s.%s",
+		config.AppInfo.LogSaveName,
+		config.AppInfo.LogFileExt,
+	)
+	F, err = file2.MustOpen(fileName, filePath)
+	if err != nil {
+		log.Fatalf("logging.Setup err: %v", err)
+	}
+
+	logger = log.New(F, DefaultPrefix, log.LstdFlags)
+
+}
+func (o *oLog) Path() string {
+	filePath := fmt.Sprintf("%s", config.AppInfo.LogSavePath)
+	fileName := fmt.Sprintf("%s.%s",
+		config.AppInfo.LogSaveName,
+		config.AppInfo.LogFileExt,
+	)
+	return filePath + fileName
+}
+func (o *oLog) Debug(v ...interface{}) {
+	setPrefix(DEBUG)
+	logger.Println(v)
+}
+
+func (o *oLog) Info(v ...interface{}) {
+	setPrefix(INFO)
+	logger.Println(v)
+}
+
+func (o *oLog) Warn(v ...interface{}) {
+	setPrefix(WARN)
+	logger.Println(v)
+}
+
+func (o *oLog) Error(v ...interface{}) {
+	setPrefix(ERROR)
+	logger.Println(v)
+}
+
+func (o *oLog) Fatal(v ...interface{}) {
+	setPrefix(FATAL)
+	logger.Println(v)
+}
+
+func setPrefix(level Level) {
+	_, file, line, ok := runtime.Caller(DefaultCallerDepth)
+	if ok {
+		logPrefix = fmt.Sprintf("[%s][%s:%d]", levelFlags[level], filepath.Base(file), line)
+	} else {
+		logPrefix = fmt.Sprintf("[%s]", levelFlags[level])
+	}
+
+	logger.SetPrefix(logPrefix)
+}
+
+func NewOLoger() OLog {
+	return &oLog{}
+}

+ 12 - 25
pkg/utils/version/version.go

@@ -1,3 +1,13 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-13 18:15:46
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-06-02 17:41:47
+ * @FilePath: /CasaOS/pkg/utils/version/version.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package version
 
 import (
@@ -32,31 +42,8 @@ func IsNeedUpdate() (bool, model.Version) {
 		b, _ := strconv.Atoi(v2[i])
 		if a > b {
 			return true, version
-		}
-	}
-	return false, version
-}
-
-func IsClientNeedUpdate() (bool, model.Version) {
-	var version model.Version
-	v := httper.OasisGet(config.ServerInfo.ServerApi + "/v1/sys/client/version")
-	data := gjson.Get(v, "data")
-	json2.Unmarshal([]byte(data.String()), &version)
-
-	v1 := strings.Split(version.Version, ".")
-	v2 := strings.Split(types.CURRENTVERSION, ".")
-
-	for len(v1) < len(v2) {
-		v1 = append(v1, "0")
-	}
-	for len(v2) < len(v1) {
-		v2 = append(v2, "0")
-	}
-	for i := 0; i < len(v1); i++ {
-		a, _ := strconv.Atoi(v1[i])
-		b, _ := strconv.Atoi(v2[i])
-		if a > b {
-			return true, version
+		} else {
+			return false, version
 		}
 	}
 	return false, version

+ 6 - 8
route/init.go

@@ -3,6 +3,7 @@ package route
 import (
 	"encoding/xml"
 	"fmt"
+	"path/filepath"
 	"runtime"
 	"strconv"
 	"strings"
@@ -79,14 +80,12 @@ func installSyncthing(appId string) {
 		appInfo.Tip = env_helper.ReplaceStringDefaultENV(appInfo.Tip)
 	}
 
-	appInfo.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20
+	appInfo.MaxMemory = service.MyService.System().GetMemInfo().Total >> 20
 
 	id := uuid.NewV4().String()
 
-	installLog := model2.AppNotify{}
-
 	// step:下载镜像
-	err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
+	err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, "", "")
 	if err != nil {
 		//pull image error
 		fmt.Println("pull image error", err, dockerImage, dockerImageVersion)
@@ -142,14 +141,13 @@ func checkSystemApp() {
 			}
 
 			path := ""
-			for _, i := range info.HostConfig.Mounts {
-				if i.Target == "/config" {
+			for _, i := range info.Mounts {
+				if i.Destination == "/config" {
 					path = i.Source
-
 					break
 				}
 			}
-			content := file.ReadFullFile(path + "config.xml")
+			content := file.ReadFullFile(filepath.Join(path, "config.xml"))
 			syncConfig := &system_app.SyncConfig{}
 			xml.Unmarshal(content, &syncConfig)
 			config.SystemConfigInfo.SyncKey = syncConfig.Key

+ 155 - 0
route/periodical.go

@@ -0,0 +1,155 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-27 15:55:36
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-27 18:57:40
+ * @FilePath: /CasaOS/route/periodical.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+package route
+
+import (
+	"reflect"
+	"strconv"
+	"strings"
+	"time"
+	"unsafe"
+
+	"github.com/IceWhaleTech/CasaOS/model"
+	"github.com/IceWhaleTech/CasaOS/service"
+)
+
+func SendNetINfoBySocket() {
+	netList := service.MyService.System().GetNetInfo()
+	newNet := []model.IOCountersStat{}
+	nets := service.MyService.System().GetNet(true)
+	for _, n := range netList {
+		for _, netCardName := range nets {
+			if n.Name == netCardName {
+				item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
+				item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))
+				item.Time = time.Now().Unix()
+				newNet = append(newNet, item)
+				break
+			}
+		}
+	}
+	service.MyService.Notify().SendNetInfoBySocket(newNet)
+}
+
+func SendCPUBySocket() {
+	cpu := service.MyService.System().GetCpuPercent()
+	num := service.MyService.System().GetCpuCoreNum()
+	cpuData := make(map[string]interface{})
+	cpuData["percent"] = cpu
+	cpuData["num"] = num
+	service.MyService.Notify().SendCPUInfoBySocket(cpuData)
+}
+
+func SendMemBySocket() {
+	service.MyService.Notify().SendMemInfoBySocket(service.MyService.System().GetMemInfo())
+}
+
+func SendDiskBySocket() {
+	list := service.MyService.Disk().LSBLK(true)
+
+	summary := model.Summary{}
+	healthy := true
+	findSystem := 0
+
+	for i := 0; i < len(list); i++ {
+		if len(list[i].Children) > 0 && findSystem == 0 {
+
+			for j := 0; j < len(list[i].Children); j++ {
+
+				if len(list[i].Children[j].Children) > 0 {
+					for _, v := range list[i].Children[j].Children {
+						if v.MountPoint == "/" {
+							s, _ := strconv.ParseUint(v.FSSize, 10, 64)
+							a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
+							u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
+							summary.Size += s
+							summary.Avail += a
+							summary.Used += u
+							findSystem = 1
+							break
+						}
+					}
+				} else {
+					if list[i].Children[j].MountPoint == "/" {
+						s, _ := strconv.ParseUint(list[i].Children[j].FSSize, 10, 64)
+						a, _ := strconv.ParseUint(list[i].Children[j].FSAvail, 10, 64)
+						u, _ := strconv.ParseUint(list[i].Children[j].FSUsed, 10, 64)
+						summary.Size += s
+						summary.Avail += a
+						summary.Used += u
+						findSystem = 1
+						break
+					}
+				}
+			}
+
+		}
+		if findSystem == 1 {
+			findSystem += 1
+			continue
+		}
+		if list[i].Tran == "sata" || list[i].Tran == "nvme" || list[i].Tran == "spi" || list[i].Tran == "sas" {
+			temp := service.MyService.Disk().SmartCTL(list[i].Path)
+			if reflect.DeepEqual(temp, model.SmartctlA{}) {
+				continue
+			}
+
+			//list[i].Temperature = temp.Temperature.Current
+			if !temp.SmartStatus.Passed {
+				healthy = false
+			}
+			if len(list[i].Children) > 0 {
+				for _, v := range list[i].Children {
+					s, _ := strconv.ParseUint(v.FSSize, 10, 64)
+					a, _ := strconv.ParseUint(v.FSAvail, 10, 64)
+					u, _ := strconv.ParseUint(v.FSUsed, 10, 64)
+					summary.Size += s
+					summary.Avail += a
+					summary.Used += u
+				}
+			}
+
+		}
+	}
+
+	summary.Health = healthy
+	service.MyService.Notify().SendDiskInfoBySocket(summary)
+}
+
+func SendUSBBySocket() {
+	usbList := service.MyService.Disk().LSBLK(false)
+	usb := []model.DriveUSB{}
+	for _, v := range usbList {
+		if v.Tran == "usb" {
+			temp := model.DriveUSB{}
+			temp.Model = v.Model
+			temp.Name = v.Name
+			temp.Size = v.Size
+			mountTemp := true
+			if len(v.Children) == 0 {
+				mountTemp = false
+			}
+			for _, child := range v.Children {
+				if len(child.MountPoint) > 0 {
+					avail, _ := strconv.ParseUint(child.FSAvail, 10, 64)
+					temp.Avail += avail
+					used, _ := strconv.ParseUint(child.FSUsed, 10, 64)
+					temp.Used += used
+				} else {
+					mountTemp = false
+				}
+			}
+			temp.Mount = mountTemp
+			usb = append(usb, temp)
+		}
+	}
+	service.MyService.Notify().SendUSBInfoBySocket(usb)
+}

+ 8 - 47
route/route.go

@@ -31,7 +31,6 @@ func InitRouter() *gin.Engine {
 	if swagHandler != nil {
 		r.GET("/swagger/*any", swagHandler)
 	}
-
 	r.POST("/v1/user/login", v1.Login)
 
 	r.GET("/v1/guide/check", v1.GetGuideCheck)
@@ -43,6 +42,7 @@ func InitRouter() *gin.Engine {
 	r.GET("/v1/user/info", v1.GetUserInfo)
 	//get user info
 	r.GET("/v1/person/shareid", v1.GetPersonShareId)
+	r.GET("/v1/sys/socket/port", v1.GetSystemSocketPort)
 	v1Group := r.Group("/v1")
 
 	v1Group.Use(jwt2.JWT(swagHandler))
@@ -66,39 +66,6 @@ func InitRouter() *gin.Engine {
 			v1UserGroup.GET("/shareid", v1.GetUserShareID)
 
 		}
-
-		v1ZiMaGroup := v1Group.Group("/zima")
-		v1ZiMaGroup.Use()
-		{
-			//获取cpu信息
-			v1ZiMaGroup.GET("/getcpuinfo", v1.CupInfo)
-			//获取内存信息
-			v1ZiMaGroup.GET("/getmeminfo", v1.MemInfo)
-			//获取硬盘信息
-			v1ZiMaGroup.GET("/getdiskinfo", v1.DiskInfo)
-
-			//获取网络信息
-			v1ZiMaGroup.GET("/getnetinfo", v1.NetInfo)
-
-			//获取系统信息
-			v1ZiMaGroup.GET("/sysinfo", v1.SysInfo)
-		}
-		v1DDNSGroup := v1Group.Group("/ddns")
-		v1DDNSGroup.Use()
-		{
-			//获取ddns列表
-			v1DDNSGroup.GET("/getlist", v1.DDNSGetDomainList)
-			//测试连接性
-			v1DDNSGroup.GET("/ping/:api_host", v1.DDNSPing)
-			//获取ip
-			v1DDNSGroup.GET("/ip", v1.DDNSGetIP)
-			//设置ddns
-			v1DDNSGroup.POST("/set", v1.DDNSAddConfig)
-			//获取ddns
-			v1DDNSGroup.GET("/list", v1.DDNSConfigList)
-			//获取ddns
-			v1DDNSGroup.DELETE("/delete/:id", v1.DDNSDelete)
-		}
 		v1AppGroup := v1Group.Group("/app")
 		v1AppGroup.Use()
 		{
@@ -127,11 +94,9 @@ func InitRouter() *gin.Engine {
 			//暂停或启动容器
 			v1AppGroup.PUT("/state/:id", v1.ChangAppState)
 			//安装app
-			v1AppGroup.POST("/install/:id", v1.InstallApp)
+			v1AppGroup.POST("/install", v1.InstallApp)
 			//卸载app
 			v1AppGroup.DELETE("/uninstall/:id", v1.UnInstallApp)
-			//获取安装进度
-			v1AppGroup.GET("/speed/:id", v1.GetInstallSpeed)
 			//获取进度
 			v1AppGroup.GET("/state/:id", v1.GetContainerState)
 			//更新容器配置
@@ -149,7 +114,6 @@ func InitRouter() *gin.Engine {
 		{
 			v1SysGroup.GET("/check", v1.CheckVersion)
 			v1SysGroup.GET("/hardware/info", v1.GetSystemHardwareInfo)
-			v1SysGroup.GET("/client/version", v1.GetClientVersion)
 			v1SysGroup.POST("/update", v1.SystemUpdate)
 			v1SysGroup.GET("/wsssh", v1.WsSsh)
 			v1SysGroup.GET("/config", v1.GetSystemConfig)
@@ -164,6 +128,11 @@ func InitRouter() *gin.Engine {
 			v1SysGroup.PUT("/usb/off", v1.PutSystemOffUSBAutoMount)
 			v1SysGroup.PUT("/usb/on", v1.PutSystemOnUSBAutoMount)
 			v1SysGroup.GET("/usb", v1.GetSystemUSBAutoMount)
+			v1SysGroup.GET("/cpu", v1.CupInfo)
+			v1SysGroup.GET("/mem", v1.MemInfo)
+			v1SysGroup.GET("/disk", v1.DiskInfo)
+			v1SysGroup.GET("/network", v1.NetInfo)
+
 		}
 		v1FileGroup := v1Group.Group("/file")
 		v1FileGroup.Use()
@@ -178,7 +147,7 @@ func InitRouter() *gin.Engine {
 			v1FileGroup.POST("/create", v1.PostCreateFile)
 
 			v1FileGroup.GET("/download", v1.GetDownloadFile)
-			v1FileGroup.GET("/new/download", v1.GetFileDownloadNew)
+			v1FileGroup.GET("/download/*path", v1.GetDownloadSingleFile)
 			v1FileGroup.POST("/operate", v1.PostOperateFileOrDir)
 			v1FileGroup.DELETE("/delete", v1.DeleteFile)
 			v1FileGroup.PUT("/update", v1.PutFileContent)
@@ -232,14 +201,6 @@ func InitRouter() *gin.Engine {
 			v1TaskGroup.PUT("/update", v1.PutTaskUpdate)
 			v1TaskGroup.POST("/add", v1.PostTaskAdd)
 			v1TaskGroup.PUT("/completion/:id", v1.PutTaskMarkerCompletion)
-
-		}
-
-		v1NotifyGroup := v1Group.Group("/notify")
-		v1NotifyGroup.Use()
-		{
-			v1NotifyGroup.GET("/ws", v1.NotifyWS)
-			v1NotifyGroup.PUT("/read/:id", v1.PutNotifyRead)
 		}
 
 		v1PersonGroup := v1Group.Group("/person")

+ 60 - 0
route/socket.go

@@ -0,0 +1,60 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-23 17:18:56
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-06-08 16:31:24
+ * @FilePath: /CasaOS/route/socket.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
+package route
+
+import (
+	"strconv"
+	"time"
+
+	"github.com/IceWhaleTech/CasaOS/model/notify"
+	"github.com/IceWhaleTech/CasaOS/pkg/config"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/port"
+	"github.com/IceWhaleTech/CasaOS/service"
+	f "github.com/ambelovsky/gosf"
+)
+
+func SocketInit(msg chan notify.Message) {
+
+	// set socket port
+	socketPort := 0
+	if len(config.ServerInfo.SocketPort) == 0 {
+		socketPort, _ = port.GetAvailablePort("tcp")
+		config.ServerInfo.SocketPort = strconv.Itoa(socketPort)
+		config.Cfg.Section("server").Key("SocketPort").SetValue(strconv.Itoa(socketPort))
+		config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+	} else {
+		socketPort, _ = strconv.Atoi(config.ServerInfo.SocketPort)
+		if !port.IsPortAvailable(socketPort, "tcp") {
+			socketPort, _ := port.GetAvailablePort("tcp")
+			config.ServerInfo.SocketPort = strconv.Itoa(socketPort)
+			config.Cfg.Section("server").Key("SocketPort").SetValue(strconv.Itoa(socketPort))
+			config.Cfg.SaveTo(config.SystemConfigInfo.ConfigPath)
+		}
+	}
+
+	f.OnConnect(func(c *f.Client, request *f.Request) {
+		service.ClientCount += 1
+	})
+	f.OnDisconnect(func(c *f.Client, request *f.Request) {
+		service.ClientCount -= 1
+	})
+	go func(msg chan notify.Message) {
+		for v := range msg {
+			f.Broadcast("", v.Path, &v.Msg)
+			time.Sleep(time.Millisecond * 300)
+		}
+
+	}(msg)
+
+	f.Startup(map[string]interface{}{
+		"port": socketPort})
+
+}

+ 1 - 1
route/v1/app.go

@@ -209,7 +209,7 @@ func AppInfo(c *gin.Context) {
 	// sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap))
 	// sort.DevSort(devOrder).Sort(info.Devices)
 
-	info.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20
+	info.MaxMemory = service.MyService.System().GetMemInfo().Total >> 20
 
 	c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
 }

+ 128 - 186
route/v1/docker.go

@@ -4,13 +4,14 @@ import (
 	"bytes"
 	"encoding/json"
 	json2 "encoding/json"
-	"fmt"
 	"net/http"
+	"path/filepath"
 	"strconv"
 	"strings"
 	"time"
 
 	"github.com/IceWhaleTech/CasaOS/model"
+	"github.com/IceWhaleTech/CasaOS/model/notify"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	upnp2 "github.com/IceWhaleTech/CasaOS/pkg/upnp"
@@ -143,10 +144,8 @@ func SpeedPush(c *gin.Context) {
 // @Param  env formData string false "环境变量"
 // @Security ApiKeyAuth
 // @Success 200 {string} string "ok"
-// @Router /app/install/{id} [post]
+// @Router /app/install [post]
 func InstallApp(c *gin.Context) {
-	appId := c.Param("id")
-	language := c.GetHeader("Language")
 	var appInfo model.ServerAppList
 	m := model.CustomizationPostData{}
 	c.BindJSON(&m)
@@ -156,7 +155,9 @@ func InstallApp(c *gin.Context) {
 	var dockerImageVersion string
 
 	//check app name is exist
-
+	if len(m.Protocol) == 0 {
+		m.Protocol = "http"
+	}
 	if m.Origin != "custom" {
 		oldName := m.Label
 		for i := 0; true; i++ {
@@ -175,7 +176,7 @@ func InstallApp(c *gin.Context) {
 
 	}
 
-	//检查端口
+	//check port
 	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)})
 		portMap, _ := strconv.Atoi(m.PortMap)
@@ -196,21 +197,6 @@ func InstallApp(c *gin.Context) {
 		dockerImage = m.Image
 		dockerImageVersion = "latest"
 	}
-	if m.Origin != "custom" {
-		appInfo = service.MyService.Casa().GetServerAppInfo(appId, "", language)
-
-	} else {
-
-		appInfo.Title = m.Label
-		appInfo.Description = m.Description
-		appInfo.Icon = m.Icon
-		appInfo.ScreenshotLink = model.Strings{}
-		appInfo.NetworkModel = m.NetworkModel
-		appInfo.Tags = model.Strings{}
-		appInfo.Tagline = ""
-		appInfo.Index = m.Index
-
-	}
 
 	for _, u := range m.Ports {
 
@@ -272,16 +258,16 @@ func InstallApp(c *gin.Context) {
 	m.CustomId = id
 	var relyMap = make(map[string]string)
 	go func() {
-		installLog := model2.AppNotify{}
-		installLog.State = 0
-		installLog.CustomId = m.Label
-		installLog.Message = "installing rely"
-		installLog.Class = types.NOTIFY_APP
-		installLog.Type = types.NOTIFY_TYPE_UNIMPORTANT
-		installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
-		installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
-		installLog.Id = uuid.NewV4().String()
-		service.MyService.Notify().AddLog(installLog)
+		// installLog := model2.AppNotify{}
+		// installLog.State = 0
+		// installLog.CustomId = m.Label
+		// installLog.Message = "installing rely"
+		// installLog.Class = types.NOTIFY_APP
+		// installLog.Type = types.NOTIFY_TYPE_UNIMPORTANT
+		// installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
+		// installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
+		// installLog.Id = uuid.NewV4().String()
+		// service.MyService.Notify().AddLog(installLog)
 		if m.Origin != "custom" {
 			for _, plugin := range appInfo.Plugins {
 				if plugin == "mysql" {
@@ -314,24 +300,26 @@ func InstallApp(c *gin.Context) {
 
 					} else {
 						docker_base.MysqlDelete(mysqlContainerId)
-						installLog.State = 0
-						installLog.Message = err.Error()
-						service.MyService.Notify().UpdateLog(installLog)
+						// installLog.State = 0
+						// installLog.Message = err.Error()
+						// service.MyService.Notify().UpdateLog(installLog)
 					}
 				}
 			}
 		}
 
-		installLog.Message = "pulling"
-		service.MyService.Notify().UpdateLog(installLog)
-
 		// step:下载镜像
-		err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, installLog)
+		err := service.MyService.Docker().DockerPullImage(dockerImage+":"+dockerImageVersion, m.Icon, m.Label)
 		if err != nil {
-			installLog.State = 0
-			installLog.Message = err.Error()
-			installLog.Type = types.NOTIFY_TYPE_ERROR
-			service.MyService.Notify().UpdateLog(installLog)
+			notify := notify.Application{}
+			notify.Icon = m.Icon
+			notify.Name = m.Label
+			notify.State = "PULLING"
+			notify.Type = "INSTALL"
+			notify.Success = false
+			notify.Finished = false
+			notify.Message = err.Error()
+			service.MyService.Notify().SendInstallAppBySocket(notify)
 			return
 		}
 
@@ -339,35 +327,28 @@ func InstallApp(c *gin.Context) {
 			time.Sleep(time.Second)
 		}
 
-		//if  {
-
-		//}
-
-		//step:创建容器
-		// networkName, err := service.MyService.Docker().GetNetWorkNameByNetWorkID(appInfo.NetworkModel)
-		// if err != nil {
-		// 	//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
-		// 	installLog.State = 0
-		// 	installLog.Speed = 75
-		// 	installLog.Type = types.NOTIFY_TYPE_ERROR
-		// 	installLog.Message = err.Error()
-		// 	service.MyService.Notify().UpdateLog(installLog)
-		// 	return
-		// }
-		containerId, err := service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m, appInfo.NetworkModel)
-		installLog.Name = appInfo.Title
-		installLog.Icon = appInfo.Icon
+		_, err = service.MyService.Docker().DockerContainerCreate(dockerImage+":"+dockerImageVersion, m, appInfo.NetworkModel)
 		if err != nil {
 			//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":80}", 100)
-			installLog.State = 0
-			installLog.Type = types.NOTIFY_TYPE_ERROR
-			installLog.Message = err.Error()
-			service.MyService.Notify().UpdateLog(installLog)
+			notify := notify.Application{}
+			notify.Icon = m.Icon
+			notify.Name = m.Label
+			notify.State = "STARTING"
+			notify.Type = "INSTALL"
+			notify.Success = false
+			notify.Finished = false
+			notify.Message = err.Error()
+			service.MyService.Notify().SendInstallAppBySocket(notify)
 			return
 		} else {
-			//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"starting\",\"speed\":80}", 100)
-			installLog.Message = "starting"
-			service.MyService.Notify().UpdateLog(installLog)
+			notify := notify.Application{}
+			notify.Icon = m.Icon
+			notify.Name = m.Label
+			notify.State = "STARTING"
+			notify.Type = "INSTALL"
+			notify.Success = true
+			notify.Finished = false
+			service.MyService.Notify().SendInstallAppBySocket(notify)
 		}
 
 		//		echo -e "hellow\nworld" >>
@@ -376,23 +357,27 @@ func InstallApp(c *gin.Context) {
 		err = service.MyService.Docker().DockerContainerStart(m.Label)
 		if err != nil {
 			//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":90}", 100)
-			installLog.State = 0
-			installLog.Type = types.NOTIFY_TYPE_ERROR
-			installLog.Message = err.Error()
-			service.MyService.Notify().UpdateLog(installLog)
+			notify := notify.Application{}
+			notify.Icon = m.Icon
+			notify.Name = m.Label
+			notify.State = "STARTING"
+			notify.Type = "INSTALL"
+			notify.Success = false
+			notify.Finished = false
+			notify.Message = err.Error()
+			service.MyService.Notify().SendInstallAppBySocket(notify)
 			return
 		} else {
-			//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"setting upnp\",\"speed\":90}", 100)
-			if m.Origin != CUSTOM {
-				installLog.Message = "setting upnp"
-			} else {
-				installLog.Message = "nearing completion"
-			}
-			service.MyService.Notify().UpdateLog(installLog)
+			// if m.Origin != CUSTOM {
+			// 	installLog.Message = "setting upnp"
+			// } else {
+			// 	installLog.Message = "nearing completion"
+			// }
+			// service.MyService.Notify().UpdateLog(installLog)
 		}
 
 		if m.Origin != CUSTOM {
-			//step:启动upnp
+			//step:enable upnp
 			if m.EnableUPNP {
 				upnp, err := upnp2.Gateway()
 				if err == nil {
@@ -424,89 +409,49 @@ func InstallApp(c *gin.Context) {
 					}
 
 				}
-				if err != nil {
-					//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":95}", 100)
-					installLog.State = 0
-					installLog.Type = types.NOTIFY_TYPE_ERROR
-					installLog.Message = err.Error()
-					service.MyService.Notify().UpdateLog(installLog)
-				} else {
-					//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"checking\",\"speed\":95}", 100)
-					installLog.Message = "checking"
-					service.MyService.Notify().UpdateLog(installLog)
-				}
+				// if err != nil {
+				// 	//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":95}", 100)
+				// 	installLog.State = 0
+				// 	installLog.Type = types.NOTIFY_TYPE_ERROR
+				// 	installLog.Message = err.Error()
+				// 	service.MyService.Notify().UpdateLog(installLog)
+				// } else {
+				// 	//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"checking\",\"speed\":95}", 100)
+				// 	installLog.Message = "checking"
+				// 	service.MyService.Notify().UpdateLog(installLog)
+				// }
 			}
 		}
 
 		//step: 启动成功     检查容器状态确认启动成功
 		container, err := service.MyService.Docker().DockerContainerInfo(m.Label)
 		if err != nil && container.ContainerJSONBase.State.Running {
-			//service.MyService.Redis().Set(id, "{\"id\"\""+id+"\",\"state\":false,\"message\":\""+err.Error()+"\",\"speed\":100}", 100)
-			installLog.State = 0
-			installLog.Type = types.NOTIFY_TYPE_ERROR
-			installLog.Message = err.Error()
-			service.MyService.Notify().UpdateLog(installLog)
+			notify := notify.Application{}
+			notify.Icon = m.Icon
+			notify.Name = m.Label
+			notify.State = "INSTALLED"
+			notify.Type = "INSTALL"
+			notify.Success = false
+			notify.Finished = true
+			notify.Message = err.Error()
+			service.MyService.Notify().SendInstallAppBySocket(notify)
 			return
 		} else {
-			//service.MyService.Redis().Set(id, "{\"id\":\""+id+"\",\"state\":true,\"message\":\"installed\",\"speed\":100}", 100)
-			installLog.Message = "installed"
-			service.MyService.Notify().UpdateLog(installLog)
+			notify := notify.Application{}
+			notify.Icon = m.Icon
+			notify.Name = m.Label
+			notify.State = "INSTALLED"
+			notify.Type = "INSTALL"
+			notify.Success = true
+			notify.Finished = true
+			service.MyService.Notify().SendInstallAppBySocket(notify)
 		}
 
-		rely := model.MapStrings{}
-
-		copier.Copy(&rely, &relyMap)
 		// if m.Origin != "custom" {
 		// 	for i := 0; i < len(m.Volumes); i++ {
 		// 		m.Volumes[i].Path = docker.GetDir(id, m.Volumes[i].Path)
 		// 	}
 		// }
-
-		portsStr, _ := json2.Marshal(m.Ports)
-		envsStr, _ := json2.Marshal(m.Envs)
-		volumesStr, _ := json2.Marshal(m.Volumes)
-		devicesStr, _ := json2.Marshal(m.Devices)
-		cmd, _ := json2.Marshal(m.Cmd)
-		capAdd, _ := json.Marshal(m.CapAdd)
-		//step: 保存数据到数据库
-		md := model2.AppListDBModel{
-			CustomId: "",
-			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,
-			//Port:           m.Port,
-			PortMap:    m.PortMap,
-			Label:      m.Label,
-			EnableUPNP: m.EnableUPNP,
-			Ports:      string(portsStr),
-			Envs:       string(envsStr),
-			Volumes:    string(volumesStr),
-			Position:   m.Position,
-			NetModel:   appInfo.NetworkModel,
-			Restart:    m.Restart,
-			CpuShares:  m.CpuShares,
-			Memory:     m.Memory,
-			Devices:    string(devicesStr),
-			//Rely:       rely,
-			Origin:     m.Origin,
-			CreatedAt:  strconv.FormatInt(time.Now().Unix(), 10),
-			UpdatedAt:  strconv.FormatInt(time.Now().Unix(), 10),
-			Cmd:        string(cmd),
-			CapAdd:     string(capAdd),
-			HostName:   m.HostName,
-			Privileged: m.Privileged,
-		}
-		//if appInfo.NetworkModel == "host" {
-		//	m.PortMap = m.Port
-		//}
-		fmt.Println(md)
 		//service.MyService.App().SaveContainer(md)
 		config.CasaOSGlobalVariables.AppChange = true
 
@@ -728,25 +673,21 @@ func UnInstallApp(c *gin.Context) {
 		return
 	}
 
-	//step:删除容器
 	err = service.MyService.Docker().DockerContainerRemove(appId, false)
 	if err != nil {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.UNINSTALL_APP_ERROR, Message: oasis_err2.GetMsg(oasis_err2.UNINSTALL_APP_ERROR), Data: err.Error()})
 		return
 	}
 
-	//存在镜像正在使用的情况
-	// step:删除镜像
-	service.MyService.Docker().DockerImageRemove(info.Image)
+	// step:remove image
+	service.MyService.Docker().DockerImageRemove(info.Config.Image)
 
-	//step: 删除本地数据
-	//service.MyService.App().RemoveContainerById(appId)
 	if info.Config.Labels["origin"] != "custom" {
-		fmt.Println(info.HostConfig.Mounts)
 		//step: 删除文件夹
-		for _, v := range info.HostConfig.Mounts {
+		for _, v := range info.Mounts {
 			if strings.Contains(v.Source, info.Name) {
-				service.MyService.App().DelAppConfigDir(v.Source)
+				path := filepath.Join(strings.Split(v.Source, info.Name)[0], info.Name)
+				service.MyService.App().DelAppConfigDir(path)
 			}
 		}
 
@@ -791,13 +732,14 @@ func UnInstallApp(c *gin.Context) {
 		//}
 	}
 	config.CasaOSGlobalVariables.AppChange = true
-	unInstallLog := model2.AppNotify{}
-	unInstallLog.State = 0
-	unInstallLog.CustomId = appId
-	unInstallLog.Message = "uninstalled"
-	unInstallLog.Id = uuid.NewV4().String()
-	service.MyService.Notify().UpdateLog(unInstallLog)
-
+	notify := notify.Application{}
+	notify.Icon = info.Config.Labels["icon"]
+	notify.Name = strings.ReplaceAll(info.Name, "/", "")
+	notify.State = "FINISHED"
+	notify.Type = "UNINSTALL"
+	notify.Success = true
+	notify.Finished = true
+	service.MyService.Notify().SendUninstallAppBySocket(notify)
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
 
 }
@@ -849,20 +791,6 @@ func ContainerLog(c *gin.Context) {
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: log})
 }
 
-// @Summary 获取安装进度
-// @Produce  application/json
-// @Accept application/json
-// @Tags app
-// @Param  id path string true "容器id"
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /app/speed/{id} [get]
-func GetInstallSpeed(c *gin.Context) {
-	id := c.Param("id")
-	b := service.MyService.Notify().GetLog(id)
-	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: b})
-}
-
 // @Summary 获取容器状态
 // @Produce  application/json
 // @Accept application/json
@@ -1083,7 +1011,7 @@ func PutAppUpdate(c *gin.Context) {
 
 	}
 	imageLatest := strings.Split(inspect.Config.Image, ":")[0] + ":latest"
-	err = service.MyService.Docker().DockerPullImage(imageLatest, model2.AppNotify{})
+	err = service.MyService.Docker().DockerPullImage(imageLatest, "", "")
 	if err != nil {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
 		return
@@ -1182,7 +1110,7 @@ func ContainerInfo(c *gin.Context) {
 	data := make(map[string]interface{}, 5)
 	data["app"] = appInfo
 	data["cpu"] = cpuModel
-	data["memory"] = service.MyService.ZiMa().GetMemInfo().Total
+	data["memory"] = service.MyService.System().GetMemInfo().Total
 	data["container"] = json2.RawMessage(containerInfo)
 	data["info"] = con
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
@@ -1205,7 +1133,7 @@ func GetDockerInstallConfig(c *gin.Context) {
 		}
 	}
 	data["networks"] = list
-	data["memory"] = service.MyService.ZiMa().GetMemInfo()
+	data["memory"] = service.MyService.System().GetMemInfo()
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
 }
 
@@ -1236,7 +1164,7 @@ func ContainerUpdateInfo(c *gin.Context) {
 	//appInfo := service.MyService.App().GetAppDBInfo(appId)
 	info, err := service.MyService.Docker().DockerContainerInfo(appId)
 	if err != nil {
-		//todo 需要自定义错误
+
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: err.Error()})
 		return
 	}
@@ -1257,12 +1185,20 @@ func ContainerUpdateInfo(c *gin.Context) {
 	// json2.Unmarshal([]byte(appInfo.Envs), &envs)
 
 	for _, v := range info.Config.Env {
-
-		temp := model.Env{
-			Name:  strings.Split(v, "=")[0],
-			Value: strings.Split(v, "=")[1],
+		showENV := info.Config.Labels["show_env"]
+		showENVList := strings.Split(showENV, ",")
+		showENVMap := make(map[string]string)
+		for _, name := range showENVList {
+			showENVMap[name] = "1"
 		}
-		envs = append(envs, temp)
+		if _, ok := showENVMap[v]; ok {
+			temp := model.Env{
+				Name:  strings.Split(v, "=")[0],
+				Value: strings.Split(v, "=")[1],
+			}
+			envs = append(envs, temp)
+		}
+
 	}
 
 	var vol model.PathArray
@@ -1309,6 +1245,7 @@ func ContainerUpdateInfo(c *gin.Context) {
 	m.Index = info.Config.Labels["index"]
 	m.Position = false
 	m.CustomId = info.Config.Labels["custom_id"]
+	m.Host = info.Config.Labels["host"]
 	if len(m.CustomId) == 0 {
 		m.CustomId = uuid.NewV4().String()
 	}
@@ -1317,6 +1254,11 @@ func ContainerUpdateInfo(c *gin.Context) {
 	m.HostName = info.Config.Hostname
 	m.Privileged = info.HostConfig.Privileged
 
+	m.Protocol = info.Config.Labels["protocol"]
+	if m.Protocol == "" {
+		m.Protocol = "http"
+	}
+
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: m})
 }
 

+ 185 - 124
route/v1/file.go

@@ -6,20 +6,24 @@ import (
 	"fmt"
 	"io"
 	"io/ioutil"
+	"log"
 	"net/http"
+	"net/url"
 	url2 "net/url"
 	"os"
 	"path"
+	"path/filepath"
 	"strconv"
 	"strings"
 
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
 	oasis_err2 "github.com/IceWhaleTech/CasaOS/pkg/utils/oasis_err"
 	"github.com/IceWhaleTech/CasaOS/service"
 	"github.com/gin-gonic/gin"
-	"github.com/spf13/afero"
+	uuid "github.com/satori/go.uuid"
 )
 
 func downloadReadFile(c *gin.Context) {
@@ -48,24 +52,6 @@ func downloadReadFile(c *gin.Context) {
 	}
 }
 
-func downloadWriteFile(c *gin.Context) {
-	//写文件
-	var filename = "./output1.csv"
-
-	file, err := os.Create(filename) //创建文件
-	if err != nil {
-		c.String(400, err.Error())
-		return
-	}
-	buf := bufio.NewWriter(file) //创建新的 Writer 对象
-	buf.WriteString("test")
-	buf.Flush()
-	defer file.Close()
-
-	//返回文件流
-	c.File(filename)
-}
-
 // @Summary 读取文件
 // @Produce  application/json
 // @Accept application/json
@@ -135,82 +121,106 @@ func GetLocalFile(c *gin.Context) {
 // @Accept application/json
 // @Tags file
 // @Security ApiKeyAuth
-// @Param path query string true "path of file"
+// @Param t query string false "Compression format" Enums(zip,tar,targz)
+// @Param files query string true "file list eg: filename1,filename2,filename3 "
 // @Success 200 {string} string "ok"
 // @Router /file/download [get]
 func GetDownloadFile(c *gin.Context) {
-	filePath := c.Query("path")
-	if len(filePath) == 0 {
+
+	t := c.Query("t")
+
+	files := c.Query("files")
+
+	if len(files) == 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
+	list := strings.Split(files, ",")
+	for _, v := range list {
+		if !file.Exists(v) {
+			c.JSON(http.StatusOK, model.Result{
+				Success: oasis_err2.FILE_DOES_NOT_EXIST,
+				Message: oasis_err2.GetMsg(oasis_err2.FILE_DOES_NOT_EXIST),
+			})
+			return
+		}
 	}
-	//打开文件
-	fileTmp, _ := os.Open(filePath)
-	defer fileTmp.Close()
-	//获取文件的名称
-	fileName := path.Base(filePath)
 	c.Header("Content-Type", "application/octet-stream")
-	c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
 	c.Header("Content-Transfer-Encoding", "binary")
 	c.Header("Cache-Control", "no-cache")
+	// handles only single files not folders and multiple files
+	if len(list) == 1 {
 
-	c.File(filePath)
-}
+		filePath := list[0]
+		info, err := os.Stat(filePath)
+		if err != nil {
+			c.JSON(http.StatusOK, model.Result{
+				Success: oasis_err2.FILE_DOES_NOT_EXIST,
+				Message: oasis_err2.GetMsg(oasis_err2.FILE_DOES_NOT_EXIST),
+			})
+			return
+		}
+		if !info.IsDir() {
 
-// @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 {
+			//打开文件
+			fileTmp, _ := os.Open(filePath)
+			defer fileTmp.Close()
+
+			//获取文件的名称
+			fileName := path.Base(filePath)
+			c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
+			c.File(filePath)
+			return
+		}
+	}
+
+	extension, ar, err := file.GetCompressionAlgorithm(t)
+	if err != nil {
 		c.JSON(http.StatusOK, model.Result{
 			Success: oasis_err2.INVALID_PARAMS,
 			Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS),
 		})
 		return
 	}
-	if !file.Exists(filePath) {
+
+	err = ar.Create(c.Writer)
+	if err != nil {
 		c.JSON(http.StatusOK, model.Result{
-			Success: oasis_err2.FILE_DOES_NOT_EXIST,
-			Message: oasis_err2.GetMsg(oasis_err2.FILE_DOES_NOT_EXIST),
+			Success: oasis_err.ERROR,
+			Message: oasis_err2.GetMsg(oasis_err2.ERROR),
+			Data:    err.Error(),
 		})
 		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) + `"`,
-	// }
+	defer ar.Close()
+	commonDir := file.CommonPrefix(filepath.Separator, list...)
 
-	//c.Header("Cache-Control", "private")
-	//c.Header("Content-Type", "application/octet-stream")
+	currentPath := filepath.Base(commonDir)
+
+	name := "_" + currentPath
+	name += extension
+	c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
+	for _, fname := range list {
+		err = file.AddFile(ar, fname, commonDir)
+		if err != nil {
+			log.Printf("Failed to archive %s: %v", fname, err)
+		}
+	}
+
+}
+
+func GetDownloadSingleFile(c *gin.Context) {
+	filePath := c.Param("path")
+	fileTmp, _ := os.Open(filePath)
+	defer fileTmp.Close()
 
-	http.ServeContent(c.Writer, c.Request, fileStat.Name(), fileStat.ModTime(), fileT)
+	fileName := path.Base(filePath)
+	//c.Header("Content-Disposition", "inline")
+	c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
+	c.File(filePath)
 }
 
 // @Summary 获取目录列表
@@ -264,7 +274,27 @@ func DirPath(c *gin.Context) {
 		}
 	}
 
-	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
+	//Hide the files or folders in operation
+	fileQueue := make(map[string]string)
+	for _, v := range service.OpStrArr {
+		v, ok := service.FileQueue.Load(v)
+		if !ok {
+			continue
+		}
+		vt := v.(model.FileOperate)
+		for _, i := range vt.Item {
+			lastPath := i.From[strings.LastIndex(i.From, "/")+1:]
+			fileQueue[vt.To+"/"+lastPath] = i.From
+		}
+	}
+	pathList := []model.Path{}
+	for i := 0; i < len(info); i++ {
+		if _, ok := fileQueue[info[i].Path]; !ok {
+			pathList = append(pathList, info[i])
+		}
+	}
+
+	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: pathList})
 }
 
 // @Summary rename file or dir
@@ -272,13 +302,15 @@ func DirPath(c *gin.Context) {
 // @Accept application/json
 // @Tags file
 // @Security ApiKeyAuth
-// @Param oldpath formData string true "path of old"
-// @Param newpath formData string true "path of new"
+// @Param oldpath body string true "path of old"
+// @Param newpath body string true "path of new"
 // @Success 200 {string} string "ok"
 // @Router /file/rename [put]
 func RenamePath(c *gin.Context) {
-	op := c.PostForm("oldpath")
-	np := c.PostForm("newpath")
+	json := make(map[string]string)
+	c.BindJSON(&json)
+	op := json["oldpath"]
+	np := json["newpath"]
 	if len(op) == 0 || len(np) == 0 {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
 		return
@@ -289,45 +321,59 @@ func RenamePath(c *gin.Context) {
 
 // @Summary create folder
 // @Produce  application/json
-// @Accept  multipart/form-data
+// @Accept  application/json
 // @Tags file
 // @Security ApiKeyAuth
-// @Param path formData string true "path of folder"
+// @Param path body string true "path of folder"
 // @Success 200 {string} string "ok"
 // @Router /file/mkdir [post]
 func MkdirAll(c *gin.Context) {
-	path := c.PostForm("path")
+	json := make(map[string]string)
+	c.BindJSON(&json)
+	path := json["path"]
 	var code int
 	if len(path) == 0 {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
 		return
 	}
+	// decodedPath, err := url.QueryUnescape(path)
+	// if err != nil {
+	// 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+	// 	return
+	// }
 	code, _ = service.MyService.ZiMa().MkdirAll(path)
 	c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
 }
 
 // @Summary create file
 // @Produce  application/json
-// @Accept  multipart/form-data
+// @Accept  application/json
 // @Tags file
 // @Security ApiKeyAuth
-// @Param path formData string false "路径"
+// @Param path body string true "path of folder (path need to url encode)"
 // @Success 200 {string} string "ok"
 // @Router /file/create [post]
 func PostCreateFile(c *gin.Context) {
-	path := c.PostForm("path")
+	json := make(map[string]string)
+	c.BindJSON(&json)
+	path := json["path"]
 	var code int
 	if len(path) == 0 {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
 		return
 	}
+	// decodedPath, err := url.QueryUnescape(path)
+	// if err != nil {
+	// 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
+	// 	return
+	// }
 	code, _ = service.MyService.ZiMa().CreateFile(path)
 	c.JSON(http.StatusOK, model.Result{Success: code, Message: oasis_err2.GetMsg(code)})
 }
 
 // @Summary upload file
 // @Produce  application/json
-// @Accept  multipart/form-data
+// @Accept  application/json
 // @Tags file
 // @Security ApiKeyAuth
 // @Param path formData string false "file path"
@@ -432,92 +478,107 @@ func PostFileUpload(c *gin.Context) {
 
 // @Summary copy or move file
 // @Produce  application/json
-// @Accept  multipart/form-data
+// @Accept  application/json
 // @Tags file
 // @Security ApiKeyAuth
-// @Param from formData string true "from path"
-// @Param to formData string true "to path"
-// @Param type formData string true "action" Enums(move,copy)
+// @Param body body model.FileOperate true "type:move,copy"
 // @Success 200 {string} string "ok"
 // @Router /file/operate [post]
 func PostOperateFileOrDir(c *gin.Context) {
-	from := c.PostForm("from")
-	to := c.PostForm("to")
-	t := c.PostForm("type")
-	if len(from) == 0 || len(t) == 0 || len(to) == 0 {
+
+	list := model.FileOperate{}
+	c.BindJSON(&list)
+
+	if len(list.Item) == 0 {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
 		return
 	}
-	if t == "move" {
-		lastPath := from[strings.LastIndex(from, "/")+1:]
-		if !file.CheckNotExist(to + "/" + lastPath) {
-			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_OR_DIR_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)})
-			return
-		}
-		err := os.Rename(from, to+"/"+lastPath)
-		if err != nil {
-			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
-			return
-		}
-	} else if t == "copy" {
-		err := file.CopyDir(from, to)
+	var total int64 = 0
+	for i := 0; i < len(list.Item); i++ {
+
+		size, err := file.GetFileOrDirSize(list.Item[i].From)
 		if err != nil {
-			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err.Error()})
-			return
+			continue
 		}
-	} else {
-		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
-		return
+		list.Item[i].Size = size
+		total += size
+	}
+
+	list.TotalSize = total
+	list.ProcessedSize = 0
+
+	uid := uuid.NewV4().String()
+	service.FileQueue.Store(uid, list)
+	service.OpStrArr = append(service.OpStrArr, uid)
+
+	if len(service.OpStrArr) == 1 {
+		go service.ExecOpFile()
+		go service.CheckFileStatus()
+		go service.MyService.Notify().SendFileOperateNotify()
 	}
+
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
 }
 
 // @Summary delete file
 // @Produce  application/json
-// @Accept  multipart/form-data
+// @Accept  application/json
 // @Tags file
 // @Security ApiKeyAuth
-// @Param path query string true "path"
+// @Param body body string true "paths eg ["/a/b/c","/d/e/f"]"
 // @Success 200 {string} string "ok"
 // @Router /file/delete [delete]
 func DeleteFile(c *gin.Context) {
-	path := c.Query("path")
-	//err := os.Remove(path)
-	err := os.RemoveAll(path)
-	if err != nil {
-		fmt.Println(err)
-		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_DELETE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.FILE_DELETE_ERROR), Data: err})
+
+	paths := []string{}
+	c.BindJSON(&paths)
+	if len(paths) == 0 {
+		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
 		return
 	}
+	//	path := c.Query("path")
+
+	//	paths := strings.Split(path, ",")
+
+	for _, v := range paths {
+		err := os.RemoveAll(v)
+		if err != nil {
+			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_DELETE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.FILE_DELETE_ERROR), Data: err})
+			return
+		}
+	}
+
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
 }
 
 // @Summary update file
 // @Produce  application/json
-// @Accept  multipart/form-data
+// @Accept  application/json
 // @Tags file
 // @Security ApiKeyAuth
-// @Param path formData string true "path"
-// @Param content formData string true "content"
+// @Param path body string true "path"
+// @Param content body string true "content"
 // @Success 200 {string} string "ok"
 // @Router /file/update [put]
 func PutFileContent(c *gin.Context) {
-	path := c.PostForm("path")
-	content := c.PostForm("content")
-	if !file.Exists(path) {
+
+	fi := model.FileUpdate{}
+	c.BindJSON(&fi)
+
+	// path := c.PostForm("path")
+	// content := c.PostForm("content")
+	if !file.Exists(fi.FilePath) {
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_ALREADY_EXISTS, Message: oasis_err2.GetMsg(oasis_err2.FILE_ALREADY_EXISTS)})
 		return
 	}
 	//err := os.Remove(path)
-	err := os.RemoveAll(path)
+	err := os.RemoveAll(fi.FilePath)
 	if err != nil {
-		fmt.Println(err)
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.FILE_DELETE_ERROR, Message: oasis_err2.GetMsg(oasis_err2.FILE_DELETE_ERROR), Data: err})
 		return
 	}
-	err = file.CreateFileAndWriteContent(path, content)
+	err = file.CreateFileAndWriteContent(fi.FilePath, fi.FileContent)
 	if err != nil {
-		fmt.Println(err)
 		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.ERROR, Message: oasis_err2.GetMsg(oasis_err2.ERROR), Data: err})
 		return
 	}

+ 1 - 58
route/v1/notify.go

@@ -1,62 +1,5 @@
 package v1
 
-import (
-	"fmt"
-	"net/http"
+func aaa() {
 
-	"github.com/IceWhaleTech/CasaOS/service"
-	"github.com/IceWhaleTech/CasaOS/types"
-	"github.com/gin-gonic/gin"
-	"github.com/gorilla/websocket"
-)
-
-var upGrader = websocket.Upgrader{
-	CheckOrigin: func(r *http.Request) bool {
-		return true
-	},
-}
-
-// @Summary websocket 接口,连接成功后发送一个"notify"字符串
-// @Produce  application/json
-// @Accept application/json
-// @Tags notify
-// @Security ApiKeyAuth
-// @Param token path string true "token"
-// @Success 200 {string} string "ok"
-// @Router /notify/ws [get]
-func NotifyWS(c *gin.Context) {
-	//升级get请求为webSocket协议
-	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
-	if err != nil {
-		return
-	}
-	defer ws.Close()
-	service.WebSocketConns = append(service.WebSocketConns, ws)
-
-	if !service.SocketRun {
-		service.SocketRun = true
-		service.SendMeg()
-	}
-	for {
-		mt, message, err := ws.ReadMessage()
-		fmt.Println(mt, message, err)
-	}
-
-}
-
-// @Summary 标记notify已读
-// @Produce  application/json
-// @Accept application/json
-// @Tags notify
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /notify/read/{id} [put]
-func PutNotifyRead(c *gin.Context) {
-	id := c.Param("id")
-	// if len(id) == 0 {
-	// 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
-	// 	return
-	// }
-	fmt.Println(id)
-	service.MyService.Notify().MarkRead(id, types.NOTIFY_READ)
 }

+ 62 - 0
route/v1/notify_old.go

@@ -0,0 +1,62 @@
+package v1
+
+import (
+	"fmt"
+	"net/http"
+
+	"github.com/IceWhaleTech/CasaOS/service"
+	"github.com/IceWhaleTech/CasaOS/types"
+	"github.com/gin-gonic/gin"
+	"github.com/gorilla/websocket"
+)
+
+var upGrader = websocket.Upgrader{
+	CheckOrigin: func(r *http.Request) bool {
+		return true
+	},
+}
+
+// @Summary websocket 接口,连接成功后发送一个"notify"字符串
+// @Produce  application/json
+// @Accept application/json
+// @Tags notify
+// @Security ApiKeyAuth
+// @Param token path string true "token"
+// @Success 200 {string} string "ok"
+// @Router /notify/ws [get]
+func NotifyWS(c *gin.Context) {
+	//升级get请求为webSocket协议
+	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
+	if err != nil {
+		return
+	}
+	defer ws.Close()
+	service.WebSocketConns = append(service.WebSocketConns, ws)
+
+	if !service.SocketRun {
+		service.SocketRun = true
+		service.SendMeg()
+	}
+	for {
+		mt, message, err := ws.ReadMessage()
+		fmt.Println(mt, message, err)
+	}
+
+}
+
+// @Summary 标记notify已读
+// @Produce  application/json
+// @Accept application/json
+// @Tags notify
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /notify/read/{id} [put]
+func PutNotifyRead(c *gin.Context) {
+	id := c.Param("id")
+	// if len(id) == 0 {
+	// 	c.JSON(http.StatusOK, model.Result{Success: oasis_err.INVALID_PARAMS, Message: oasis_err.GetMsg(oasis_err.INVALID_PARAMS)})
+	// 	return
+	// }
+	fmt.Println(id)
+	service.MyService.Notify().MarkRead(id, types.NOTIFY_READ)
+}

+ 23 - 32
route/v1/system.go

@@ -29,7 +29,7 @@ import (
 // @Tags sys
 // @Security ApiKeyAuth
 // @Success 200 {string} string "ok"
-// @Router /sys/chackversion [get]
+// @Router /sys/check [get]
 func CheckVersion(c *gin.Context) {
 	need, version := version.IsNeedUpdate()
 	if need {
@@ -50,32 +50,6 @@ func CheckVersion(c *gin.Context) {
 	return
 }
 
-// @Summary check client version
-// @Produce  application/json
-// @Accept application/json
-// @Tags sys
-// @Security ApiKeyAuth
-// @Success 200 {string} string "ok"
-// @Router /sys/client/version [get]
-func GetClientVersion(c *gin.Context) {
-	need, version := version.IsClientNeedUpdate()
-	if need {
-		installLog := model2.AppNotify{}
-		installLog.State = 0
-		installLog.Message = "New version " + version.Version + " is ready, ready to upgrade"
-		installLog.Type = types.NOTIFY_TYPE_NEED_CONFIRM
-		installLog.CreatedAt = strconv.FormatInt(time.Now().Unix(), 10)
-		installLog.UpdatedAt = strconv.FormatInt(time.Now().Unix(), 10)
-		installLog.Name = "CasaOS System"
-		service.MyService.Notify().AddLog(installLog)
-	}
-	data := make(map[string]interface{}, 1)
-	data["is_need"] = need
-	data["version"] = version
-	data["current_version"] = types.CURRENTVERSION
-	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
-}
-
 // @Summary 系统信息
 // @Produce  application/json
 // @Accept application/json
@@ -452,18 +426,18 @@ func Info(c *gin.Context) {
 		}
 	}
 	data["usb"] = usb
-	cpu := service.MyService.ZiMa().GetCpuPercent()
-	num := service.MyService.ZiMa().GetCpuCoreNum()
+	cpu := service.MyService.System().GetCpuPercent()
+	num := service.MyService.System().GetCpuCoreNum()
 	cpuData := make(map[string]interface{})
 	cpuData["percent"] = cpu
 	cpuData["num"] = num
 	data["cpu"] = cpuData
-	data["mem"] = service.MyService.ZiMa().GetMemInfo()
+	data["mem"] = service.MyService.System().GetMemInfo()
 
 	//拼装网络信息
-	netList := service.MyService.ZiMa().GetNetInfo()
+	netList := service.MyService.System().GetNetInfo()
 	newNet := []model.IOCountersStat{}
-	nets := service.MyService.ZiMa().GetNet(true)
+	nets := service.MyService.System().GetNet(true)
 	for _, n := range netList {
 		for _, netCardName := range nets {
 			if n.Name == netCardName {
@@ -480,3 +454,20 @@ func Info(c *gin.Context) {
 
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
 }
+
+// @Summary Get notification port
+// @Produce  application/json
+// @Accept application/json
+// @Tags sys
+// @Security ApiKeyAuth
+// @Success 200 {string} string "ok"
+// @Router /sys/socket/port [get]
+func GetSystemSocketPort(c *gin.Context) {
+
+	c.JSON(http.StatusOK,
+		model.Result{
+			Success: oasis_err.SUCCESS,
+			Message: oasis_err.GetMsg(oasis_err.SUCCESS),
+			Data:    config.ServerInfo.SocketPort,
+		})
+}

+ 15 - 5
route/v1/zima_info.go

@@ -1,3 +1,13 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2021-09-30 18:18:14
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-27 18:07:13
+ * @FilePath: /CasaOS/route/v1/zima_info.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package v1
 
 import (
@@ -21,8 +31,8 @@ import (
 // @Router /zima/getcpuinfo [get]
 func CupInfo(c *gin.Context) {
 	//检查参数是否正确
-	cpu := service.MyService.ZiMa().GetCpuPercent()
-	num := service.MyService.ZiMa().GetCpuCoreNum()
+	cpu := service.MyService.System().GetCpuPercent()
+	num := service.MyService.System().GetCpuCoreNum()
 	data := make(map[string]interface{})
 	data["percent"] = cpu
 	data["num"] = num
@@ -40,7 +50,7 @@ func CupInfo(c *gin.Context) {
 func MemInfo(c *gin.Context) {
 
 	//检查参数是否正确
-	mem := service.MyService.ZiMa().GetMemInfo()
+	mem := service.MyService.System().GetMemInfo()
 	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: mem})
 
 }
@@ -65,11 +75,11 @@ func DiskInfo(c *gin.Context) {
 // @Success 200 {string} string "ok"
 // @Router /zima/getnetinfo [get]
 func NetInfo(c *gin.Context) {
-	netList := service.MyService.ZiMa().GetNetInfo()
+	netList := service.MyService.System().GetNetInfo()
 
 	newNet := []model.IOCountersStat{}
 	for _, n := range netList {
-		for _, netCardName := range service.MyService.ZiMa().GetNet(true) {
+		for _, netCardName := range service.MyService.System().GetNet(true) {
 			if n.Name == netCardName {
 				item := *(*model.IOCountersStat)(unsafe.Pointer(&n))
 				item.State = strings.TrimSpace(service.MyService.ZiMa().GetNetState(n.Name))

+ 20 - 16
service/app.go

@@ -15,13 +15,14 @@ import (
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	model2 "github.com/IceWhaleTech/CasaOS/service/model"
 	"github.com/docker/docker/api/types"
 	"github.com/docker/docker/api/types/filters"
 	client2 "github.com/docker/docker/client"
 	"github.com/pkg/errors"
 	uuid "github.com/satori/go.uuid"
+	"go.uber.org/zap"
 	"gorm.io/gorm"
 )
 
@@ -50,8 +51,7 @@ type AppService interface {
 }
 
 type appStruct struct {
-	db  *gorm.DB
-	log loger2.OLog
+	db *gorm.DB
 }
 
 func (a *appStruct) GetApplicationById(id string) (m model2.ApplicationModel) {
@@ -159,10 +159,9 @@ func (a *appStruct) ImportApplications(casaApp bool) {
 }
 
 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)
+		loger.Error("Failed to init client", zap.Any("err", err))
 		return 0
 	}
 	defer cli.Close()
@@ -172,7 +171,7 @@ func (a *appStruct) GetCasaOSCount() int {
 
 	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{Filters: fts, Limit: 200})
 	if err != nil {
-		a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
+		loger.Error("failed to get container_list", zap.Any("err", err))
 		return 0
 	}
 
@@ -182,10 +181,9 @@ func (a *appStruct) GetCasaOSCount() int {
 
 //获取我的应用列表
 func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppList, *[]model2.MyAppList) {
-	//获取docker应用
 	cli, err := client2.NewClientWithOpts(client2.FromEnv, client2.WithTimeout(time.Second*5))
 	if err != nil {
-		a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
+		loger.Error("Failed to init client", zap.Any("err", err))
 	}
 	defer cli.Close()
 	// fts := filters.NewArgs()
@@ -194,7 +192,7 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
 	//fts.Add("casaos", "casaos")
 	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true})
 	if err != nil {
-		a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
+		loger.Error("Failed to get container_list", zap.Any("err", err))
 	}
 	//获取本地数据库应用
 
@@ -215,6 +213,8 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
 			Index:      "/",
 			Image:      "",
 			Type:       v.Type,
+			Host:       "",
+			Protocol:   "",
 			NewVersion: false,
 		})
 	}
@@ -239,6 +239,8 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
 				Type:       m.Labels["origin"],
 				//Slogan: m.Slogan,
 				//Rely:     m.Rely,
+				Host:     m.Labels["host"],
+				Protocol: m.Labels["protocol"],
 			})
 		} else {
 			unTranslation = append(unTranslation, model2.MyAppList{
@@ -249,6 +251,8 @@ func (a *appStruct) GetMyList(index, size int, position bool) (*[]model2.MyAppLi
 				Id:         m.ID,
 				Port:       "",
 				NewVersion: false,
+				Host:       "",
+				Protocol:   "",
 				Image:      m.Image,
 			})
 		}
@@ -304,14 +308,14 @@ func (a *appStruct) GetSystemAppList() []types.Container {
 	//获取docker应用
 	cli, err := client2.NewClientWithOpts(client2.FromEnv)
 	if err != nil {
-		a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
+		loger.Error("Failed to init client", zap.Any("err", err))
 	}
 	defer cli.Close()
 	fts := filters.NewArgs()
 	fts.Add("label", "origin=system")
 	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
 	if err != nil {
-		a.log.Error("获取docker容器失败", "app.sys", "line:123", err)
+		loger.Error("Failed to get container_list", zap.Any("err", err))
 	}
 
 	//获取本地数据库应用
@@ -339,13 +343,13 @@ func (a *appStruct) GetContainerInfo(name string) (types.Container, error) {
 	//获取docker应用
 	cli, err := client2.NewClientWithOpts(client2.FromEnv)
 	if err != nil {
-		a.log.Error("初始化client失败", "app.getmylist", "line:36", err)
+		loger.Error("Failed to init client", zap.Any("err", err))
 	}
 	filters := filters.NewArgs()
 	filters.Add("name", name)
 	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: filters})
 	if err != nil {
-		a.log.Error("获取docker容器失败", "app.getcontainerinfo", "line:182", err)
+		loger.Error("Failed to get container_list", zap.Any("err", err))
 	}
 
 	if len(containers) > 0 {
@@ -464,7 +468,7 @@ func (a *appStruct) GetHardwareUsageSteam() {
 	//fts.Add("casaos", "casaos")
 	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{All: true, Filters: fts})
 	if err != nil {
-		a.log.Error("获取docker容器失败", "app.getmylist", "line:42", err)
+		loger.Error("Failed to get container_list", zap.Any("err", err))
 	}
 	for i := 0; i < 100; i++ {
 		if config.CasaOSGlobalVariables.AppChange {
@@ -511,6 +515,6 @@ func (a *appStruct) GetHardwareUsageSteam() {
 	cancel()
 }
 
-func NewAppService(db *gorm.DB, logger loger2.OLog) AppService {
-	return &appStruct{db: db, log: logger}
+func NewAppService(db *gorm.DB) AppService {
+	return &appStruct{db: db}
 }

+ 53 - 5
service/casa.go

@@ -5,6 +5,7 @@ import (
 	json2 "encoding/json"
 	"fmt"
 	"strconv"
+	"time"
 
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
@@ -78,24 +79,71 @@ func (o *casaService) GetServerList(index, size, tp, categoryId, key, language s
 	json2.Unmarshal([]byte(gjson.Get(listS, "data.community").String()), &community)
 
 	if len(list) > 0 {
-		Cache.SetDefault(keyName, listS)
+		Cache.Set(keyName, listS, time.Hour*24)
 	}
 	return
 }
 
-func (o *casaService) GetServerCategoryList() []model.ServerCategoryList {
+func (o *casaService) GetServerCategoryList() (list []model.ServerCategoryList) {
+
+	keyName := fmt.Sprintf("category_list")
+	if result, ok := Cache.Get(keyName); ok {
+		res, ok := result.(string)
+		if ok {
+			json2.Unmarshal([]byte(gjson.Get(res, "data").String()), &list)
+			return list
+		}
+	}
 
 	head := make(map[string]string)
 	head["Authorization"] = GetToken()
 
 	listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head)
 
-	list := []model.ServerCategoryList{}
-
 	json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &list)
-
+	if len(list) > 0 {
+		Cache.Set(keyName, listS, time.Hour*24)
+	}
 	return list
 }
+
+// func (o *casaService) GetServerCategoryList() (list model.ServerCategoryList) {
+
+// 	results := file.ReadFullFile(config.AppInfo.ProjectPath + "/conf/app_category.json")
+// 	err := json2.Unmarshal(results, &list)
+// 	if err != nil {
+// 		loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
+// 	}
+// 	return list
+// }
+
+// func (o *casaService) AsyncGetServerCategoryList() {
+// 	list := model.ServerCategoryList{}
+// 	results := file.ReadFullFile(config.AppInfo.ProjectPath + "/conf/app_category.json")
+// 	err := json2.Unmarshal(results, &list)
+// 	if err != nil {
+// 		loger.Error("marshal error", zap.Any("err", err), zap.Any("content", string(results)))
+// 	}
+
+// 	if list.Version == GetAppVersion() {
+// 		return
+// 	}
+// 	item := []model.CategoryList{}
+// 	head := make(map[string]string)
+// 	head["Authorization"] = GetToken()
+// 	listS := httper2.Get(config.ServerInfo.ServerApi+"/v2/app/category", head)
+// 	json2.Unmarshal([]byte(gjson.Get(listS, "data").String()), &item)
+// 	if len(item) > 0 {
+// 		list.Version = GetAppVersion()
+// 		list.Item = item
+// 		by, err := json.Marshal(list)
+// 		if err != nil {
+// 			loger.Error("marshal error", zap.Any("err", err))
+// 		}
+// 		file.WriteToPath(by, config.AppInfo.ProjectPath+"/conf", "app_category.json")
+// 	}
+// }
+
 func (o *casaService) GetServerAppInfo(id, t string, language string) model.ServerAppList {
 
 	head := make(map[string]string)

+ 14 - 50
service/disk.go

@@ -11,10 +11,11 @@ import (
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	model2 "github.com/IceWhaleTech/CasaOS/service/model"
 	"github.com/shirou/gopsutil/v3/disk"
 	"github.com/tidwall/gjson"
+	"go.uber.org/zap"
 	"gorm.io/gorm"
 )
 
@@ -37,8 +38,7 @@ type DiskService interface {
 	RemoveLSBLKCache()
 }
 type diskService struct {
-	log loger2.OLog
-	db  *gorm.DB
+	db *gorm.DB
 }
 
 func (d *diskService) RemoveLSBLKCache() {
@@ -58,13 +58,13 @@ func (d *diskService) SmartCTL(path string) model.SmartctlA {
 	var m model.SmartctlA
 	str := command2.ExecSmartCTLByPath(path)
 	if str == nil {
-		d.log.Error("smartctl exec error,smartctl")
+		loger.Error("failed to  exec shell ", zap.Any("err", "smartctl exec error"))
 		return m
 	}
 
 	err := json2.Unmarshal([]byte(str), &m)
 	if err != nil {
-		d.log.Error("json ummarshal error", err)
+		loger.Error("Failed to unmarshal json", zap.Any("err", err))
 	}
 	if !reflect.DeepEqual(m, model.SmartctlA{}) {
 		Cache.Add(key, m, time.Second*10)
@@ -133,47 +133,13 @@ func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel {
 
 	str := command2.ExecLSBLK()
 	if str == nil {
-		d.log.Error("lsblk exec error,lsblk")
+		loger.Error("Failed to exec shell", zap.Any("err", "lsblk exec error"))
 		return nil
 	}
 	var m []model.LSBLKModel
-	// strStr := `{
-	// 	"blockdevices": [
-	// 	   {"name":"loop0", "kname":"loop0", "path":"/dev/loop0", "maj:min":"7:0", "fsavail":"0", "fssize":"62M", "fstype":"squashfs", "fsused":"62M", "fsuse%":"100%", "fsver":"4.0", "mountpoint":"/snap/core20/1405", "label":null, "uuid":null, "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":true, "rm":false, "hotplug":false, "model":null, "serial":null, "size":619, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "type":"loop", "disc-aln":0, "disc-gran":"4K", "disc-max":"4G", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":null, "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 	   {"name":"loop1", "kname":"loop1", "path":"/dev/loop1", "maj:min":"7:1", "fsavail":"0", "fssize":"55.6M", "fstype":"squashfs", "fsused":"55.6M", "fsuse%":"100%", "fsver":"4.0", "mountpoint":"/snap/core18/2344", "label":null, "uuid":null, "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":true, "rm":false, "hotplug":false, "model":null, "serial":null, "size":55, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "type":"loop", "disc-aln":0, "disc-gran":"4K", "disc-max":"4G", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":null, "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 	   {"name":"loop2", "kname":"loop2", "path":"/dev/loop2", "maj:min":"7:2", "fsavail":"0", "fssize":"44.8M", "fstype":"squashfs", "fsused":"44.8M", "fsuse%":"100%", "fsver":"4.0", "mountpoint":"/snap/snapd/15314", "label":null, "uuid":null, "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":true, "rm":false, "hotplug":false, "model":null, "serial":null, "size":446, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "type":"loop", "disc-aln":0, "disc-gran":"4K", "disc-max":"4G", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":null, "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 	   {"name":"loop3", "kname":"loop3", "path":"/dev/loop3", "maj:min":"7:3", "fsavail":"0", "fssize":"78.9M", "fstype":"squashfs", "fsused":"78.9M", "fsuse%":"100%", "fsver":"4.0", "mountpoint":"/snap/lxd/22754", "label":null, "uuid":null, "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":true, "rm":false, "hotplug":false, "model":null, "serial":null, "size":788, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "type":"loop", "disc-aln":0, "disc-gran":"4K", "disc-max":"4G", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":null, "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 	   {"name":"loop4", "kname":"loop4", "path":"/dev/loop4", "maj:min":"7:4", "fsavail":"0", "fssize":"43.8M", "fstype":"squashfs", "fsused":"43.8M", "fsuse%":"100%", "fsver":"4.0", "mountpoint":"/snap/snapd/15177", "label":null, "uuid":null, "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":true, "rm":false, "hotplug":false, "model":null, "serial":null, "size":436, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "type":"loop", "disc-aln":0, "disc-gran":"4K", "disc-max":"4G", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":null, "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 	   {"name":"loop5", "kname":"loop5", "path":"/dev/loop5", "maj:min":"7:5", "fsavail":"0", "fssize":"55.5M", "fstype":"squashfs", "fsused":"55.5M", "fsuse%":"100%", "fsver":"4.0", "mountpoint":"/snap/core18/1997", "label":null, "uuid":null, "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":true, "rm":false, "hotplug":false, "model":null, "serial":null, "size":554, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "type":"loop", "disc-aln":0, "disc-gran":"4K", "disc-max":"4G", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":null, "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 	   {"name":"loop6", "kname":"loop6", "path":"/dev/loop6", "maj:min":"7:6", "fsavail":"0", "fssize":"80M", "fstype":"squashfs", "fsused":"80M", "fsuse%":"100%", "fsver":"4.0", "mountpoint":"/snap/lxd/22826", "label":null, "uuid":null, "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":true, "rm":false, "hotplug":false, "model":null, "serial":null, "size":799, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "type":"loop", "disc-aln":0, "disc-gran":"4K", "disc-max":"4G", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":null, "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 	   {"name":"sda", "kname":"sda", "path":"/dev/sda", "maj:min":"8:0", "fsavail":null, "fssize":null, "fstype":null, "fsused":null, "fsuse%":null, "fsver":null, "mountpoint":null, "label":null, "uuid":null, "ptuuid":"1596101a-e20d-4296-96e2-0870efce554a", "pttype":"gpt", "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":"ST1000DM003-1ER1", "serial":"Z4YCS1B6", "size":9315, "state":"running", "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":4096, "opt-io":0, "phy-sec":4096, "log-sec":512, "rota":true, "sched":"mq-deadline", "rq-size":64, "type":"disk", "disc-aln":0, "disc-gran":"0B", "disc-max":"0B", "disc-zero":false, "wsame":"0B", "wwn":"0x5000c50090db103a", "rand":true, "pkname":null, "hctl":"0:0:0:0", "tran":"sata", "subsystems":"block:scsi:pci", "rev":"CC61", "vendor":"ATA     ", "zoned":"none", "dax":false,
-	// 		  "children": [
-	// 			 {"name":"sda1", "kname":"sda1", "path":"/dev/sda1", "maj:min":"8:1", "fsavail":null, "fssize":null, "fstype":null, "fsused":null, "fsuse%":null, "fsver":null, "mountpoint":null, "label":null, "uuid":null, "ptuuid":"1596101a-e20d-4296-96e2-0870efce554a", "pttype":"gpt", "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":null, "serial":null, "size":9315, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":3072, "min-io":4096, "opt-io":0, "phy-sec":4096, "log-sec":512, "rota":true, "sched":"mq-deadline", "rq-size":64, "type":"part", "disc-aln":0, "disc-gran":"0B", "disc-max":"0B", "disc-zero":false, "wsame":"0B", "wwn":"0x5000c50090db103a", "rand":true, "pkname":"sda", "hctl":null, "tran":null, "subsystems":"block:scsi:pci", "rev":null, "vendor":null, "zoned":"none", "dax":false}
-	// 		  ]
-	// 	   },
-	// 	   {"name":"sdb", "kname":"sdb", "path":"/dev/sdb", "maj:min":"8:16", "fsavail":null, "fssize":null, "fstype":null, "fsused":null, "fsuse%":null, "fsver":null, "mountpoint":null, "label":null, "uuid":null, "ptuuid":"baed02d0-e92d-4a00-9609-f94f31271a0e", "pttype":"gpt", "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":"ST1000DM003-1ER1", "serial":"W4Y51MFH", "size":9315, "state":"running", "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":4096, "opt-io":0, "phy-sec":4096, "log-sec":512, "rota":true, "sched":"mq-deadline", "rq-size":64, "type":"disk", "disc-aln":0, "disc-gran":"0B", "disc-max":"0B", "disc-zero":false, "wsame":"0B", "wwn":"0x5000c5008acd2f00", "rand":true, "pkname":null, "hctl":"1:0:0:0", "tran":"sata", "subsystems":"block:scsi:pci", "rev":"CC46", "vendor":"ATA     ", "zoned":"none", "dax":false,
-	// 		  "children": [
-	// 			 {"name":"sdb1", "kname":"sdb1", "path":"/dev/sdb1", "maj:min":"8:17", "fsavail":null, "fssize":null, "fstype":"zfs_member", "fsused":null, "fsuse%":null, "fsver":"5000", "mountpoint":null, "label":null, "uuid":null, "ptuuid":"baed02d0-e92d-4a00-9609-f94f31271a0e", "pttype":"gpt", "parttype":"0fc63daf-8483-4772-8e79-3d69d8477de4", "parttypename":"Linux filesystem", "partlabel":"primary", "partuuid":"57880cc0-2695-41c3-bf14-7161693e5bff", "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":null, "serial":null, "size":9315, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":3072, "min-io":4096, "opt-io":0, "phy-sec":4096, "log-sec":512, "rota":true, "sched":"mq-deadline", "rq-size":64, "type":"part", "disc-aln":0, "disc-gran":"0B", "disc-max":"0B", "disc-zero":false, "wsame":"0B", "wwn":"0x5000c5008acd2f00", "rand":true, "pkname":"sdb", "hctl":null, "tran":null, "subsystems":"block:scsi:pci", "rev":null, "vendor":null, "zoned":"none", "dax":false}
-	// 		  ]
-	// 	   },
-	// 	   {"name":"nvme0n1", "kname":"nvme0n1", "path":"/dev/nvme0n1", "maj:min":"259:0", "fsavail":null, "fssize":null, "fstype":null, "fsused":null, "fsuse%":null, "fsver":null, "mountpoint":null, "label":null, "uuid":null, "ptuuid":"338abc31-a3d4-4af2-9342-b53268d9e5ac", "pttype":"gpt", "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":"LITEON CL1-8D128-HP", "serial":"UJDJA01PJDH3UI", "size":1192, "state":"live", "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"none", "rq-size":255, "type":"disk", "disc-aln":0, "disc-gran":"512B", "disc-max":"2T", "disc-zero":false, "wsame":"0B", "wwn":"eui.0023035630392fe7", "rand":false, "pkname":null, "hctl":null, "tran":"nvme", "subsystems":"block:nvme:pci", "rev":null, "vendor":null, "zoned":"none", "dax":false,
-	// 		  "children": [
-	// 			 {"name":"nvme0n1p1", "kname":"nvme0n1p1", "path":"/dev/nvme0n1p1", "maj:min":"259:1", "fsavail":null, "fssize":null, "fstype":null, "fsused":null, "fsuse%":null, "fsver":null, "mountpoint":null, "label":null, "uuid":null, "ptuuid":"338abc31-a3d4-4af2-9342-b53268d9e5ac", "pttype":"gpt", "parttype":"21686148-6449-6e6f-744e-656564454649", "parttypename":"BIOS boot", "partlabel":null, "partuuid":"b2bac638-9468-449f-9669-79be44e3c80d", "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":null, "serial":null, "size":1, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"none", "rq-size":255, "type":"part", "disc-aln":0, "disc-gran":"512B", "disc-max":"2T", "disc-zero":false, "wsame":"0B", "wwn":"eui.0023035630392fe7", "rand":false, "pkname":"nvme0n1", "hctl":null, "tran":"nvme", "subsystems":"block:nvme:pci", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 			 {"name":"nvme0n1p2", "kname":"nvme0n1p2", "path":"/dev/nvme0n1p2", "maj:min":"259:2", "fsavail":"1.2G", "fssize":"1.4G", "fstype":"ext4", "fsused":"131.5M", "fsuse%":"9%", "fsver":"1.0", "mountpoint":"/boot", "label":null, "uuid":"cd8164e9-bf7a-4684-8a3b-1d9f209b4930", "ptuuid":"338abc31-a3d4-4af2-9342-b53268d9e5ac", "pttype":"gpt", "parttype":"0fc63daf-8483-4772-8e79-3d69d8477de4", "parttypename":"Linux filesystem", "partlabel":null, "partuuid":"42ed9ed6-1221-4bea-901a-bc2f7b7cb9e1", "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":null, "serial":null, "size":15, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"none", "rq-size":255, "type":"part", "disc-aln":0, "disc-gran":"512B", "disc-max":"2T", "disc-zero":false, "wsame":"0B", "wwn":"eui.0023035630392fe7", "rand":false, "pkname":"nvme0n1", "hctl":null, "tran":"nvme", "subsystems":"block:nvme:pci", "rev":null, "vendor":null, "zoned":"none", "dax":false},
-	// 			 {"name":"nvme0n1p3", "kname":"nvme0n1p3", "path":"/dev/nvme0n1p3", "maj:min":"259:3", "fsavail":null, "fssize":null, "fstype":"LVM2_member", "fsused":null, "fsuse%":null, "fsver":"LVM2 001", "mountpoint":null, "label":null, "uuid":"0G7ryL-p2Ks-i9HS-wvEO-lXHs-oyZX-1KIlZO", "ptuuid":"338abc31-a3d4-4af2-9342-b53268d9e5ac", "pttype":"gpt", "parttype":"0fc63daf-8483-4772-8e79-3d69d8477de4", "parttypename":"Linux filesystem", "partlabel":null, "partuuid":"f6ae2e8c-14ae-4d94-89f1-2c154e909843", "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":null, "serial":null, "size":1177, "state":null, "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"none", "rq-size":255, "type":"part", "disc-aln":0, "disc-gran":"512B", "disc-max":"2T", "disc-zero":false, "wsame":"0B", "wwn":"eui.0023035630392fe7", "rand":false, "pkname":"nvme0n1", "hctl":null, "tran":"nvme", "subsystems":"block:nvme:pci", "rev":null, "vendor":null, "zoned":"none", "dax":false,
-	// 				"children": [
-	// 				   {"name":"ubuntu--vg-ubuntu--lv", "kname":"dm-0", "path":"/dev/mapper/ubuntu--vg-ubuntu--lv", "maj:min":"253:0", "fsavail":"78.6G", "fssize":"115.4G", "fstype":"ext4", "fsused":"30.9G", "fsuse%":"27%", "fsver":"1.0", "mountpoint":"/", "label":null, "uuid":"e8a9082f-3643-4820-a5e5-05817d7738c6", "ptuuid":null, "pttype":null, "parttype":null, "parttypename":null, "partlabel":null, "partuuid":null, "partflags":null, "ra":128, "ro":false, "rm":false, "hotplug":false, "model":null, "serial":null, "size":1177, "state":"running", "owner":"root", "group":"disk", "mode":"brw-rw----", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":null, "rq-size":128, "type":"lvm", "disc-aln":0, "disc-gran":"512B", "disc-max":"2T", "disc-zero":false, "wsame":"0B", "wwn":null, "rand":false, "pkname":"nvme0n1p3", "hctl":null, "tran":null, "subsystems":"block", "rev":null, "vendor":null, "zoned":"none", "dax":false}
-	// 				]
-	// 			 }
-	// 		  ]
-	// 	   }
-	// 	]
-	//  }`
-	// fmt.Println(gjson.Get(strStr, "blockdevices").String())
 	err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &m)
 	if err != nil {
-		fmt.Println(err)
-		d.log.Error("json ummarshal error", err)
+		loger.Error("Failed to unmarshal json", zap.Any("err", err))
 	}
 
 	var c []model.LSBLKModel
@@ -206,7 +172,7 @@ func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel {
 			if fsused > 0 {
 				i.UsedPercent, err = strconv.ParseFloat(fmt.Sprintf("%.4f", float64(fsused)/float64(i.Size)), 64)
 				if err != nil {
-					d.log.Fatal("diskservice_lsblk_fsused", err)
+					loger.Error("Failed to parse float", zap.Any("err", err))
 				}
 			}
 			n = append(n, i)
@@ -224,15 +190,14 @@ func (d *diskService) LSBLK(isUseCache bool) []model.LSBLKModel {
 func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
 	str := command2.ExecLSBLKByPath(path)
 	if str == nil {
-		d.log.Error("lsblk exec error,str")
+		loger.Error("Failed to exec shell", zap.Any("err", "lsblk exec error"))
 		return model.LSBLKModel{}
 	}
 
 	var ml []model.LSBLKModel
 	err := json2.Unmarshal([]byte(gjson.Get(string(str), "blockdevices").String()), &ml)
 	if err != nil {
-		d.log.Info(string(str))
-		d.log.Error("json ummarshal error", err)
+		loger.Error("Failed to unmarshal json", zap.Any("err", err))
 		return model.LSBLKModel{}
 	}
 
@@ -245,8 +210,7 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
 	chiArr := make(map[string]string)
 	chiList := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetPartitionSectors " + m.Path)
 	if len(chiList) == 0 {
-		d.log.Error(m.Path, chiList)
-		d.log.Error("chiList length error")
+		loger.Error("chiList length error", zap.Any("err", "chiList length error"))
 	}
 	for i := 0; i < len(chiList); i++ {
 		tempArr := strings.Split(chiList[i], ",")
@@ -265,7 +229,7 @@ func (d *diskService) GetDiskInfo(path string) model.LSBLKModel {
 	diskEndSector := command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetDiskSizeAndSectors " + m.Path)
 
 	if len(diskEndSector) < 2 {
-		d.log.Error("diskEndSector length error")
+		loger.Error("diskEndSector length error", zap.Any("err", "diskEndSector length error"))
 	}
 	diskEndSectorInt, _ := strconv.ParseUint(diskEndSector[len(diskEndSector)-1], 10, 64)
 	if (diskEndSectorInt-maxSector)*m.MinIO/1024/1024 > 100 {
@@ -309,6 +273,6 @@ func (d *diskService) GetSerialAll() []model2.SerialDisk {
 	return m
 }
 
-func NewDiskService(log loger2.OLog, db *gorm.DB) DiskService {
-	return &diskService{log: log, db: db}
+func NewDiskService(db *gorm.DB) DiskService {
+	return &diskService{db: db}
 }

+ 25 - 16
service/docker.go

@@ -7,23 +7,22 @@ import (
 	"encoding/binary"
 	json2 "encoding/json"
 	"fmt"
-	"reflect"
 	"syscall"
 
-	model2 "github.com/IceWhaleTech/CasaOS/service/model"
-	types2 "github.com/IceWhaleTech/CasaOS/types"
+	"github.com/IceWhaleTech/CasaOS/model/notify"
 	"github.com/containerd/containerd"
 	"github.com/containerd/containerd/cio"
 	"github.com/containerd/containerd/namespaces"
 	"github.com/containerd/containerd/oci"
 	"github.com/pkg/errors"
+	"go.uber.org/zap"
 
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/docker"
 	command2 "github.com/IceWhaleTech/CasaOS/pkg/utils/command"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/env_helper"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 
 	//"github.com/containerd/containerd/oci"
 	"io"
@@ -44,7 +43,7 @@ import (
 )
 
 type DockerService interface {
-	DockerPullImage(imageName string, m model2.AppNotify) error
+	DockerPullImage(imageName string, icon, name string) error
 	IsExistImage(imageName string) bool
 	DockerContainerCreate(imageName string, m model.CustomizationPostData, net string) (containerId string, err error)
 	DockerContainerCopyCreate(info *types.ContainerJSON) (containerId string, err error)
@@ -69,7 +68,6 @@ type DockerService interface {
 
 type dockerService struct {
 	rootDir string
-	log     loger2.OLog
 }
 
 func (ds *dockerService) DockerContainerList() []types.Container {
@@ -319,7 +317,7 @@ func (ds *dockerService) IsExistImage(imageName string) bool {
 }
 
 //安装镜像
-func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) error {
+func (ds *dockerService) DockerPullImage(imageName string, icon, name string) error {
 	cli, err := client2.NewClientWithOpts(client2.FromEnv)
 	if err != nil {
 		return err
@@ -334,7 +332,8 @@ func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) e
 
 		return err
 	}
-	buf := make([]byte, 256)
+	//io.Copy()
+	buf := make([]byte, 2048*4)
 	for {
 		n, err := out.Read(buf)
 		if err != nil {
@@ -343,11 +342,16 @@ func (ds *dockerService) DockerPullImage(imageName string, m model2.AppNotify) e
 			}
 			break
 		}
-		if !reflect.DeepEqual(m, model2.AppNotify{}) {
-			m.Type = types2.NOTIFY_TYPE_INSTALL_LOG
-			m.State = 0
-			m.Message = string(buf[:n])
-			MyService.Notify().UpdateLog(m)
+		if len(icon) > 0 && len(name) > 0 {
+			notify := notify.Application{}
+			notify.Icon = icon
+			notify.Name = name
+			notify.State = "PULLING"
+			notify.Type = "INSTALL"
+			notify.Finished = false
+			notify.Success = true
+			notify.Message = string(buf[:n])
+			MyService.Notify().SendInstallAppBySocket(notify)
 		}
 
 	}
@@ -433,12 +437,14 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
 	}
 
 	var envArr []string
+	var showENV []string
 	for _, e := range m.Envs {
 		if strings.HasPrefix(e.Value, "$") {
 			envArr = append(envArr, e.Name+"="+env_helper.ReplaceDefaultENV(e.Value, MyService.System().GetTimeZone()))
 			continue
 		}
 		if len(e.Value) > 0 {
+			showENV = append(showENV, e.Name)
 			if e.Value == "port_map" {
 				envArr = append(envArr, e.Name+"="+m.PortMap)
 				continue
@@ -476,7 +482,7 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
 		//if len(result1) == 0 {
 		err = file.IsNotExistMkDir(path)
 		if err != nil {
-			ds.log.Error("mkdir error", err)
+			loger.Error("Failed to create a folder", zap.Any("err", err))
 			continue
 		}
 		//}
@@ -530,6 +536,9 @@ func (ds *dockerService) DockerContainerCreate(imageName string, m model.Customi
 	config.Labels["desc"] = m.Description
 	config.Labels["index"] = m.Index
 	config.Labels["custom_id"] = m.CustomId
+	config.Labels["show_env"] = strings.Join(showENV, ",")
+	config.Labels["protocol"] = m.Protocol
+	config.Labels["host"] = m.Host
 	//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" {
@@ -827,8 +836,8 @@ func (ds *dockerService) DockerNetworkModelList() []types.NetworkResource {
 	networks, _ := cli.NetworkList(context.Background(), types.NetworkListOptions{})
 	return networks
 }
-func NewDockerService(log loger2.OLog) DockerService {
-	return &dockerService{rootDir: command2.ExecResultStr(`source ./shell/helper.sh ;GetDockerRootDir`), log: log}
+func NewDockerService() DockerService {
+	return &dockerService{rootDir: command2.ExecResultStr(`source ./shell/helper.sh ;GetDockerRootDir`)}
 }
 
 //   ---------------------------------------test------------------------------------

+ 103 - 28
service/file.go

@@ -1,38 +1,31 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2021-12-20 14:15:46
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-06-08 15:46:36
+ * @FilePath: /CasaOS/service/file.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package service
 
 import (
 	"context"
 	"io"
+	"os"
+	"path/filepath"
+	"strings"
+	"sync"
+	"time"
+
+	"github.com/IceWhaleTech/CasaOS/model"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
 )
 
-// type InteruptReader struct {
-// 	r        io.Reader
-// 	interupt chan int
-// }
-
-// func NewInteruptReader(r io.Reader) InteruptReader {
-// 	return InteruptReader{
-// 		r,
-// 		make(chan int),
-// 	}
-// }
-
-// func (r InteruptReader) Read(p []byte) (n int, err error) {
-// 	if r.r == nil {
-// 		return 0, io.EOF
-// 	}
-// 	select {
-// 	case <-r.interupt:
-// 		return r.r.Read(p)
-// 	default:
-// 		r.r = nil
-// 		return 0, io.EOF
-// 	}
-// }
-
-// func (r InteruptReader) Cancel() {
-// 	r.interupt <- 0
-// }
+var FileQueue sync.Map
+
+var OpStrArr []string
 
 type reader struct {
 	ctx context.Context
@@ -83,3 +76,85 @@ func (w *writer) Write(p []byte) (n int, err error) {
 		return w.w.Write(p)
 	}
 }
+func FileOperate(k string) {
+
+	list, ok := FileQueue.Load(k)
+	if !ok {
+		return
+	}
+
+	temp := list.(model.FileOperate)
+	if temp.ProcessedSize > 0 {
+		return
+	}
+	for _, v := range temp.Item {
+		if temp.Type == "move" {
+			lastPath := v.From[strings.LastIndex(v.From, "/")+1:]
+			if !file.CheckNotExist(temp.To + "/" + lastPath) {
+				continue
+			}
+			err := os.Rename(v.From, temp.To+"/"+lastPath)
+			if err != nil {
+				continue
+			}
+		} else if temp.Type == "copy" {
+			err := file.CopyDir(v.From, temp.To)
+			if err != nil {
+				continue
+			}
+		} else {
+			continue
+		}
+	}
+
+}
+
+func ExecOpFile() {
+	len := len(OpStrArr)
+	if len == 0 {
+		return
+	}
+	if len > 1 {
+		len = 1
+	}
+	for i := 0; i < len; i++ {
+		go FileOperate(OpStrArr[i])
+	}
+}
+
+// file move or copy and send notify
+func CheckFileStatus() {
+	for {
+		if len(OpStrArr) == 0 {
+			return
+		}
+		for _, v := range OpStrArr {
+			var total int64 = 0
+			item, ok := FileQueue.Load(v)
+			if !ok {
+				continue
+			}
+			temp := item.(model.FileOperate)
+			for i := 0; i < len(temp.Item); i++ {
+
+				if !temp.Item[i].Finished {
+					size, err := file.GetFileOrDirSize(temp.To + "/" + filepath.Base(temp.Item[i].From))
+					if err != nil {
+						continue
+					}
+					temp.Item[i].ProcessedSize = size
+					if size == temp.Item[i].Size {
+						temp.Item[i].Finished = true
+					}
+					total += size
+				} else {
+					total += temp.Item[i].ProcessedSize
+				}
+
+			}
+			temp.ProcessedSize = total
+			FileQueue.Store(v, temp)
+		}
+		time.Sleep(time.Second * 3)
+	}
+}

+ 12 - 0
service/model/o_container.go

@@ -1,3 +1,13 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2022-05-13 18:15:46
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-05-30 17:33:21
+ * @FilePath: /CasaOS/service/model/o_container.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package model
 
 const CONTAINERTABLENAME = "o_container"
@@ -64,4 +74,6 @@ type MyAppList struct {
 	Image      string `json:"image"`
 	Volumes    string `json:"volumes"`
 	NewVersion bool   `json:"new_version"`
+	Host       string `json:"host"`
+	Protocol   string `json:"protocol"`
 }

+ 237 - 17
service/notify.go

@@ -2,14 +2,23 @@ package service
 
 import (
 	json2 "encoding/json"
+	"fmt"
 	"time"
 
+	model2 "github.com/IceWhaleTech/CasaOS/model"
+	"github.com/IceWhaleTech/CasaOS/model/notify"
 	"github.com/IceWhaleTech/CasaOS/service/model"
 	"github.com/IceWhaleTech/CasaOS/types"
+	"github.com/ambelovsky/gosf"
+	socketio "github.com/googollee/go-socket.io"
 	"github.com/gorilla/websocket"
+	"github.com/shirou/gopsutil/v3/mem"
 	"gorm.io/gorm"
 )
 
+var NotifyMsg chan notify.Message
+var ClientCount int = 0
+
 type NotifyServer interface {
 	GetLog(id string) model.AppNotify
 	AddLog(log model.AppNotify)
@@ -18,13 +27,224 @@ type NotifyServer interface {
 	DelLog(id string)
 	GetList(c int) (list []model.AppNotify)
 	MarkRead(id string, state int)
-	SendText(m model.AppNotify)
+	//	SendText(m model.AppNotify)
+	SendUninstallAppBySocket(app notify.Application)
+	SendNetInfoBySocket(netList []model2.IOCountersStat)
+	SendCPUInfoBySocket(cpu map[string]interface{})
+	SendMemInfoBySocket(mem *mem.VirtualMemoryStat)
+	SendUSBInfoBySocket(list []model2.DriveUSB)
+	SendDiskInfoBySocket(disk model2.Summary)
+	SendPersonStatusBySocket(status notify.Person)
+	SendFileOperateNotify()
+	SendInstallAppBySocket(app notify.Application)
 }
 
 type notifyServer struct {
 	db *gorm.DB
 }
 
+// Send periodic broadcast messages
+func (i *notifyServer) SendFileOperateNotify() {
+	for {
+
+		len := 0
+		FileQueue.Range(func(k, v interface{}) bool {
+			len++
+			return true
+		})
+		if len == 0 {
+			return
+		}
+		listMsg := make(map[string]interface{})
+		model := notify.NotifyModel{}
+		model.State = "NORMAL"
+		list := []notify.File{}
+		OpStrArrbak := OpStrArr
+
+		for _, v := range OpStrArrbak {
+			tempItem, ok := FileQueue.Load(v)
+			temp := tempItem.(model2.FileOperate)
+			if !ok {
+				continue
+			}
+			task := notify.File{}
+			task.Id = v
+			task.ProcessedSize = temp.ProcessedSize
+			task.TotalSize = temp.TotalSize
+			task.To = temp.To
+			task.Type = temp.Type
+			if task.ProcessedSize == 0 {
+				task.Status = "STARTING"
+			} else {
+				task.Status = "PROCESSING"
+			}
+			if temp.ProcessedSize == temp.TotalSize {
+				task.Finished = true
+				task.Status = "FINISHED"
+				FileQueue.Delete(v)
+				OpStrArr = OpStrArr[1:]
+				go ExecOpFile()
+				list = append(list, task)
+				continue
+			}
+			for _, v := range temp.Item {
+				if v.Size != v.ProcessedSize {
+					task.ProcessingPath = v.From
+					break
+				}
+			}
+
+			list = append(list, task)
+		}
+		model.Data = list
+
+		listMsg["file_operate"] = model
+
+		msg := gosf.Message{}
+		msg.Success = true
+		msg.Body = listMsg
+		msg.Text = "file_operate"
+
+		notify := notify.Message{}
+		notify.Path = "file_operate"
+		notify.Msg = msg
+		NotifyMsg <- notify
+		time.Sleep(time.Second * 3)
+	}
+}
+
+func (i *notifyServer) SendPersonStatusBySocket(status notify.Person) {
+	body := make(map[string]interface{})
+	body["data"] = status
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "person_status"
+
+	notify := notify.Message{}
+	notify.Path = "person_status"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+
+func (i *notifyServer) SendDiskInfoBySocket(disk model2.Summary) {
+	body := make(map[string]interface{})
+	body["data"] = disk
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "sys_disk"
+
+	notify := notify.Message{}
+	notify.Path = "sys_disk"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+
+func (i *notifyServer) SendUSBInfoBySocket(list []model2.DriveUSB) {
+	body := make(map[string]interface{})
+	body["data"] = list
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "sys_usb"
+
+	notify := notify.Message{}
+	notify.Path = "sys_usb"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+
+func (i *notifyServer) SendMemInfoBySocket(mem *mem.VirtualMemoryStat) {
+	body := make(map[string]interface{})
+	body["data"] = mem
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "sys_mem"
+
+	notify := notify.Message{}
+	notify.Path = "sys_mem"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+
+func (i *notifyServer) SendInstallAppBySocket(app notify.Application) {
+	body := make(map[string]interface{})
+	body["data"] = app
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "app_install"
+
+	notify := notify.Message{}
+	notify.Path = "app_install"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+
+func (i *notifyServer) SendCPUInfoBySocket(cpu map[string]interface{}) {
+	body := make(map[string]interface{})
+	body["data"] = cpu
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "sys_cpu"
+
+	notify := notify.Message{}
+	notify.Path = "sys_cpu"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+func (i *notifyServer) SendNetInfoBySocket(netList []model2.IOCountersStat) {
+	body := make(map[string]interface{})
+	body["data"] = netList
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "sys_net"
+
+	notify := notify.Message{}
+	notify.Path = "sys_net"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+
+func (i *notifyServer) SendUninstallAppBySocket(app notify.Application) {
+	body := make(map[string]interface{})
+	body["data"] = app
+
+	msg := gosf.Message{}
+	msg.Body = body
+	msg.Success = true
+	msg.Text = "app_uninstall"
+
+	notify := notify.Message{}
+	notify.Path = "app_uninstall"
+	notify.Msg = msg
+
+	NotifyMsg <- notify
+}
+
+func (i *notifyServer) SSR() {
+	server := socketio.NewServer(nil)
+	fmt.Println(server)
+}
+
 func (i notifyServer) GetList(c int) (list []model.AppNotify) {
 	i.db.Where("class = ?", c).Where(i.db.Where("state = ?", types.NOTIFY_DYNAMICE).Or("state = ?", types.NOTIFY_UNREAD)).Find(&list)
 	return
@@ -103,25 +323,25 @@ 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 {
+// 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
+// 		err := v.WriteMessage(1, json)
+// 		if err == nil {
+// 			temp = append(temp, v)
+// 		}
+// 	}
+// 	WebSocketConns = temp
 
-	if len(WebSocketConns) == 0 {
-		SocketRun = false
-	}
+// 	if len(WebSocketConns) == 0 {
+// 		SocketRun = false
+// 	}
 
-}
+// }
 
 func NewNotifyService(db *gorm.DB) NotifyServer {
 	return &notifyServer{db: db}

+ 13 - 5
service/rely.go

@@ -1,7 +1,16 @@
+/*
+ * @Author: LinkLeong link@icewhale.com
+ * @Date: 2021-09-30 18:18:14
+ * @LastEditors: LinkLeong
+ * @LastEditTime: 2022-06-02 18:00:57
+ * @FilePath: /CasaOS/service/rely.go
+ * @Description:
+ * @Website: https://www.casaos.io
+ * Copyright (c) 2022 by icewhale, All Rights Reserved.
+ */
 package service
 
 import (
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	model2 "github.com/IceWhaleTech/CasaOS/service/model"
 	"gorm.io/gorm"
 )
@@ -13,8 +22,7 @@ type RelyService interface {
 }
 
 type relyService struct {
-	db  *gorm.DB
-	log loger2.OLog
+	db *gorm.DB
 }
 
 func (r *relyService) Create(rely model2.RelyDBModel) {
@@ -35,6 +43,6 @@ func (r *relyService) Delete(id string) {
 	r.db.Where("custom_id = ?", id).Delete(&c)
 }
 
-func NewRelyService(db *gorm.DB, log loger2.OLog) RelyService {
-	return &relyService{db: db, log: log}
+func NewRelyService(db *gorm.DB) RelyService {
+	return &relyService{db: db}
 }

+ 8 - 10
service/service.go

@@ -1,7 +1,6 @@
 package service
 
 import (
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	"github.com/gorilla/websocket"
 	"github.com/patrickmn/go-cache"
 	"gorm.io/gorm"
@@ -37,22 +36,21 @@ type Repository interface {
 	DownRecord() DownRecordService
 }
 
-func NewService(db *gorm.DB, log loger2.OLog) Repository {
+func NewService(db *gorm.DB) Repository {
 
 	return &store{
-		app:    NewAppService(db, log),
-		ddns:   NewDDNSService(db, log),
+		app:    NewAppService(db),
 		user:   NewUserService(),
-		docker: NewDockerService(log),
+		docker: NewDockerService(),
 		//redis:      NewRedisService(rp),
 		zima:           NewZiMaService(),
 		casa:           NewCasaService(),
-		disk:           NewDiskService(log, db),
+		disk:           NewDiskService(db),
 		notify:         NewNotifyService(db),
-		shareDirectory: NewShareDirService(db, log),
-		task:           NewTaskService(db, log),
-		rely:           NewRelyService(db, log),
-		system:         NewSystemService(log),
+		shareDirectory: NewShareDirService(db),
+		task:           NewTaskService(db),
+		rely:           NewRelyService(db),
+		system:         NewSystemService(),
 		shortcuts:      NewShortcutsService(db),
 		search:         NewSearchService(),
 		person:         NewPersonService(db),

+ 9 - 8
service/share_directory.go

@@ -1,13 +1,15 @@
 package service
 
 import (
+	"os"
+	"strconv"
+
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
+	"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	"github.com/IceWhaleTech/CasaOS/service/model"
+	"go.uber.org/zap"
 	"gorm.io/gorm"
-	"os"
-	"strconv"
 )
 
 type ShareDirService interface {
@@ -20,8 +22,7 @@ type ShareDirService interface {
 }
 
 type shareDirService struct {
-	db  *gorm.DB
-	log loger2.OLog
+	db *gorm.DB
 }
 
 func (s *shareDirService) List(desc bool) []model.ShareDirDBModel {
@@ -305,7 +306,7 @@ func (s *shareDirService) UpConfig() {
 	// /etc/samba/smb.conf
 	f, err := os.OpenFile("/etc/samba/smb.conf", os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
 	if err != nil {
-		s.log.Error("file create failed. err: " + err.Error())
+		loger.Error("Failed to create file", zap.Any("err", err))
 	} else {
 		defer f.Close()
 		f.WriteString(str)
@@ -318,6 +319,6 @@ func (s *shareDirService) Info(id string) model.ShareDirDBModel {
 	return m
 }
 
-func NewShareDirService(db *gorm.DB, log loger2.OLog) ShareDirService {
-	return &shareDirService{db: db, log: log}
+func NewShareDirService(db *gorm.DB) ShareDirService {
+	return &shareDirService{db: db}
 }

+ 44 - 5
service/system.go

@@ -1,14 +1,19 @@
 package service
 
 import (
+	"fmt"
 	"io/ioutil"
-	"net"
+	net2 "net"
 	"os"
+	"strconv"
 
 	"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"
+	"github.com/shirou/gopsutil/v3/cpu"
+	"github.com/shirou/gopsutil/v3/mem"
+	"github.com/shirou/gopsutil/v3/net"
 )
 
 type SystemService interface {
@@ -23,11 +28,45 @@ type SystemService interface {
 	ExecUSBAutoMountShell(state string)
 	UpAppOrderFile(str string)
 	GetAppOrderFile() []byte
+	GetNet(physics bool) []string
+	GetNetInfo() []net.IOCountersStat
+	GetCpuCoreNum() int
+	GetCpuPercent() float64
+	GetMemInfo() *mem.VirtualMemoryStat
 }
 type systemService struct {
 	log loger.OLog
 }
 
+func (c *systemService) GetMemInfo() *mem.VirtualMemoryStat {
+	memInfo, _ := mem.VirtualMemory()
+	memInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", memInfo.UsedPercent), 64)
+	return memInfo
+}
+
+func (c *systemService) GetCpuPercent() float64 {
+	percent, _ := cpu.Percent(0, false)
+	value, _ := strconv.ParseFloat(fmt.Sprintf("%.1f", percent[0]), 64)
+	return value
+}
+
+func (c *systemService) GetCpuCoreNum() int {
+	count, _ := cpu.Counts(false)
+	return count
+}
+
+func (c *systemService) GetNetInfo() []net.IOCountersStat {
+	parts, _ := net.IOCounters(true)
+	return parts
+}
+func (c *systemService) GetNet(physics bool) []string {
+	t := "1"
+	if physics {
+		t = "2"
+	}
+	return command2.ExecResultStrArray("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;GetNetCard " + t)
+}
+
 func (s *systemService) UpdateSystemVersion(version string) {
 	//command2.OnlyExec(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
 	//s.log.Error(config.AppInfo.ProjectPath + "/shell/tool.sh -r " + version)
@@ -99,12 +138,12 @@ func (s *systemService) GetCasaOSLogs(lineNumber int) string {
 
 func GetDeviceAllIP() []string {
 	var address []string
-	addrs, err := net.InterfaceAddrs()
+	addrs, err := net2.InterfaceAddrs()
 	if err != nil {
 		return address
 	}
 	for _, a := range addrs {
-		if ipNet, ok := a.(*net.IPNet); ok && !ipNet.IP.IsLoopback() {
+		if ipNet, ok := a.(*net2.IPNet); ok && !ipNet.IP.IsLoopback() {
 			if ipNet.IP.To16() != nil {
 				address = append(address, ipNet.IP.String())
 			}
@@ -112,6 +151,6 @@ func GetDeviceAllIP() []string {
 	}
 	return address
 }
-func NewSystemService(log loger.OLog) SystemService {
-	return &systemService{log: log}
+func NewSystemService() SystemService {
+	return &systemService{}
 }

+ 3 - 5
service/task.go

@@ -6,7 +6,6 @@ import (
 
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	httper2 "github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
-	loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
 	"github.com/IceWhaleTech/CasaOS/service/model"
 	"github.com/IceWhaleTech/CasaOS/types"
 	"github.com/tidwall/gjson"
@@ -24,8 +23,7 @@ type TaskService interface {
 }
 
 type taskService struct {
-	db  *gorm.DB
-	log loger2.OLog
+	db *gorm.DB
 }
 
 func (s *taskService) List(desc bool) []model.TaskDBModel {
@@ -141,6 +139,6 @@ func SyncTask(db *gorm.DB) {
 		}
 	}(list)
 }
-func NewTaskService(db *gorm.DB, log loger2.OLog) TaskService {
-	return &taskService{db: db, log: log}
+func NewTaskService(db *gorm.DB) TaskService {
+	return &taskService{db: db}
 }

+ 12 - 11
service/udpconn.go

@@ -17,6 +17,7 @@ import (
 	"time"
 
 	"github.com/IceWhaleTech/CasaOS/model"
+	"github.com/IceWhaleTech/CasaOS/model/notify"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
 	"github.com/IceWhaleTech/CasaOS/pkg/quic_helper"
 	"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
@@ -92,7 +93,7 @@ func UDPSendData(msg model.MessageModel, localFilePath string) error {
 }
 
 func Dial(msg model.MessageModel, server bool) (m model.MessageModel, err error) {
-	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+	ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
 	defer cancel()
 	Message = make(chan model.MessageModel)
 	_, port, err := net.SplitHostPort(UDPConn.LocalAddr().String())
@@ -236,20 +237,20 @@ func ReadContent(stream quic.Stream) {
 			Message <- m
 			break
 		} else if m.Type == types.PERSONGETIP {
-			notify := model2.AppNotify{}
-			notify.CustomId = m.From
+			notify := notify.Person{}
+			notify.ShareId = 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)
+					notify.Type = "OFFLINE"
+					go MyService.Notify().SendPersonStatusBySocket(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)
+				notify.Type = "ONLINE"
+				go MyService.Notify().SendPersonStatusBySocket(notify)
 			}
 			UDPAddressMap[m.From] = m.Data.(string)
 			if config.ServerInfo.Token != m.From && strings.Split(m.Data.(string), ":")[0] == strings.Split(UDPAddressMap[config.ServerInfo.Token], ":")[0] {
@@ -330,10 +331,10 @@ func LoopFriend() {
 			data, err := Dial(msg, false)
 			if err != nil || reflect.DeepEqual(data, model.MessageModel{}) || len(data.Data.(string)) == 0 {
 				if oldIP == UDPAddressMap[list[i].Token] {
-					notify := model2.AppNotify{}
-					notify.CustomId = data.From
-					notify.Type = types.NOTIFY_TYPE_PERSION_FIRNED_LEAVE
-					go MyService.Notify().SendText(notify)
+					notify := notify.Person{}
+					notify.ShareId = data.From
+					notify.Type = "LEAVE"
+					go MyService.Notify().SendPersonStatusBySocket(notify)
 
 					delete(UDPAddressMap, list[i].Token)
 

+ 31 - 74
service/zima_info.go

@@ -9,7 +9,6 @@ import (
 	"strconv"
 	"strings"
 	"time"
-	"unsafe"
 
 	"github.com/IceWhaleTech/CasaOS/model"
 	"github.com/IceWhaleTech/CasaOS/pkg/config"
@@ -19,18 +18,12 @@ import (
 	"github.com/shirou/gopsutil/v3/cpu"
 	"github.com/shirou/gopsutil/v3/disk"
 	"github.com/shirou/gopsutil/v3/host"
-	"github.com/shirou/gopsutil/v3/mem"
-	"github.com/shirou/gopsutil/v3/net"
 )
 
 //系统信息
 type ZiMaService interface {
-	GetCpuPercent() float64
-	GetCpuCoreNum() int
-	GetMemInfo() *mem.VirtualMemoryStat
 	GetDiskInfo() *disk.UsageStat
-	GetNetInfo() []net.IOCountersStat
-	GetNet(physics bool) []string
+
 	GetNetState(name string) string
 	GetSysInfo() host.InfoStat
 	GetDirPath(path string) []model.Path
@@ -47,32 +40,12 @@ var NetArray [][]model.IOCountersStat
 type zima struct {
 }
 
-//获取cpu占用率
-func (c *zima) GetCpuPercent() float64 {
-	percent, _ := cpu.Percent(0, false)
-	value, _ := strconv.ParseFloat(fmt.Sprintf("%.1f", percent[0]), 64)
-	return value
-}
-
-//获取物理核心数
-func (c *zima) GetCpuCoreNum() int {
-	count, _ := cpu.Counts(false)
-	return count
-}
-
 //cpu详情
 func (c *zima) GetCpuInfo() []cpu.InfoStat {
 	info, _ := cpu.Info()
 	return info
 }
 
-//获取内存详情
-func (c *zima) GetMemInfo() *mem.VirtualMemoryStat {
-	memInfo, _ := mem.VirtualMemory()
-	memInfo.UsedPercent, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", memInfo.UsedPercent), 64)
-	return memInfo
-}
-
 //获取硬盘详情
 func (c *zima) GetDiskInfo() *disk.UsageStat {
 	path := "/"
@@ -141,15 +114,6 @@ func (c *zima) GetSysInfo() host.InfoStat {
 	return *info
 }
 
-//shell脚本参数 {1:虚拟网卡  2:物理网卡}
-func (c *zima) GetNet(physics bool) []string {
-	t := "1"
-	if physics {
-		t = "2"
-	}
-	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")
 }
@@ -159,13 +123,6 @@ func (c *zima) GetNetState(name string) string {
 	return command2.ExecResultStr("source " + config.AppInfo.ProjectPath + "/shell/helper.sh ;CatNetCardState " + name)
 }
 
-//网络信息
-func (c *zima) GetNetInfo() []net.IOCountersStat {
-	parts, _ := net.IOCounters(true)
-	//fmt.Println(net.ConntrackStatsWithContext(true))
-	return parts
-}
-
 //mkdir
 func (c *zima) MkdirAll(path string) (int, error) {
 	_, err := os.Stat(path)
@@ -219,40 +176,40 @@ func NewZiMaService() ZiMaService {
 	return &zima{}
 }
 
-func LoopNet() {
-	netList := MyService.ZiMa().GetNetInfo()
+// func LoopNet() {
+// 	netList := MyService.ZiMa().GetNetInfo()
 
-	nets := MyService.ZiMa().GetNet(true)
-	num := 0
-	for i := 0; i < len(netList); i++ {
+// 	nets := MyService.ZiMa().GetNet(true)
+// 	num := 0
+// 	for i := 0; i < len(netList); i++ {
 
-		for _, netCardName := range nets {
+// 		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 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{})
-				}
+// 				if len(netArray) >= 60 {
+// 					netArray = netArray[1:]
+// 				}
+// 				netArray = append(netArray, item)
+// 				if len(NetArray) < (num + 1) {
+// 					NetArray = append(NetArray, []model.IOCountersStat{})
+// 				}
 
-				NetArray[num] = netArray
+// 				NetArray[num] = netArray
 
-				num++
-				break
-			}
-		}
+// 				num++
+// 				break
+// 			}
+// 		}
 
-	}
-}
+// 	}
+// }

+ 3 - 3
types/system.go

@@ -2,7 +2,7 @@
  * @Author: LinkLeong link@icewhale.com
  * @Date: 2022-02-17 18:53:22
  * @LastEditors: LinkLeong
- * @LastEditTime: 2022-05-17 12:52:47
+ * @LastEditTime: 2022-06-02 20:40:36
  * @FilePath: /CasaOS/types/system.go
  * @Description:
  * @Website: https://www.casaos.io
@@ -10,6 +10,6 @@
  */
 package types
 
-const CURRENTVERSION = "0.3.1.1"
+const CURRENTVERSION = "0.3.2"
 
-const BODY = "<li>Fix the data loss problem when importing local applications</li>"
+const BODY = "<li></li>"

File diff suppressed because it is too large
+ 0 - 96
web/8ee7a98310ee94717fe1.worker.js


+ 0 - 17
web/img/android-package-archive.c32c4fdb.svg

@@ -1,17 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#9fda1e" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -89.043 4.424)" fill="#fff" opacity=".75">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
- <path d="m32.883 44.933 2.1667-2.1667c0.33333-0.33333 0.33333-0.85 0-1.1833-0.33333-0.33333-0.85-0.33333-1.1833 0l-2.4667 2.4667c-1.3166-0.66667-2.8166-1.05-4.4-1.05-1.6 0-3.1001 0.38333-4.4332 1.05l-2.4833-2.4667c-0.33333-0.33333-0.85-0.33333-1.1833 0-0.33333 0.33333-0.33333 0.85 0 1.1833l2.1833 2.1833c-2.4667 1.8167-4.0833 4.7334-4.0833 8.05h20c0-3.3166-1.6167-6.2501-4.1168-8.0667zm-9.4547 4.4953h-1.4286v-1.4286h1.4286zm8.5713 0h-1.4286v-1.4286h1.4286z" enable-background="new" fill="#fff" opacity=".75" stroke-width="1.6667"/>
-</svg>

+ 0 - 17
web/img/application-apk.319706c4.svg

@@ -1,17 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333 0 0 2.3333 -68.667 -72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#84c835" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-14.713 -.1522)">
-  <path d="m22.651 6.7667v1.7198c0 0.073288 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059001 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000" fill="#fff"/>
-  <path d="m23.18 1.2105h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000" fill="#fff"/>
-  <path d="m25.359 10.922 0.80255-0.80255c0.12347-0.12347 0.12347-0.31485 0-0.43832s-0.31485-0.12347-0.43832 0l-0.91368 0.91368c-0.4877-0.24694-1.0433-0.38893-1.6298-0.38893-0.59266 0-1.1483 0.14199-1.6421 0.38893l-0.91985-0.91368c-0.12347-0.12347-0.31485-0.12347-0.43832 0s-0.12347 0.31485 0 0.43832l0.80873 0.80873c-0.91368 0.67291-1.5125 1.7533-1.5125 2.9818h7.4082c0-1.2285-0.59883-2.3151-1.5249-2.988zm-3.5021 1.6651h-0.52916v-0.52916h0.52916zm3.1749 0h-0.52916v-0.52916h0.52916z" enable-background="new" fill="#0c2809" opacity=".5" stroke-width=".61735"/>
- </g>
-</svg>

+ 0 - 21
web/img/application-certificate.64a6804d.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333 0 0 2.3333 -68.667 -72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="8" y="4" width="48" height="56" ry="5" fill="#f55" style="paint-order:stroke fill markers"/>
- <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- <path d="m30.662 18.545-1.291 1.666-2.0508-0.4668-0.55664 2.0293-2.0742 0.35547 0.26367 2.0879-1.7812 1.123 1.0449 1.8281-1.2168 1.7188 1.6621 1.2891-0.46289 2.0527 2.0293 0.55469 0.35547 2.0742 0.8125-0.10352v10.404l4.5938-3.3418 4.5938 3.3418v-9.832l0.09766 0.02344 0.55664-2.0293 2.0742-0.35742-0.26562-2.0879 1.7812-1.1211-1.043-1.8301 1.2148-1.7168-1.6621-1.291 0.46484-2.0508-2.0293-0.55664-0.35547-2.0723-2.0879 0.26367-1.123-1.7812-1.8281 1.043zm1.3379 4.3066a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5z" color="#4d4d4d" color-rendering="auto" fill="#fff" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal"/>
-</svg>

File diff suppressed because it is too large
+ 0 - 11
web/img/application-dicom.fbef31c7.svg


+ 0 - 13
web/img/application-epub+zip.73eef8b2.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333 0 0 2.3333 -68.667 -72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#84c835" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m8.4664 10.961-2.4942-2.4944 2.4942-2.4941 0.83147 0.83132-1.6629 1.6627 0.83142 0.83147 2.4942-2.4941-2.1727-2.1727c-0.17742-0.17757-0.4652-0.17757-0.64277 0l-3.5142 3.5142c-0.17742 0.17742-0.17742 0.4652 0 0.64277l3.5142 3.5141c0.17757 0.17757 0.46535 0.17757 0.64277 0l3.5142-3.5141c0.17742-0.17757 0.17742-0.46535 0-0.64277l-0.51016-0.51001z" enable-background="new" fill="#fff" stroke-width=".050576"/>
-</svg>

+ 0 - 13
web/img/application-illustrator.2ea791ae.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#341c05" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".5" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path class="st1" d="m6.8166 9.7034-0.3832 1.4552c-0.0097 0.03881-0.02425 0.0485-0.07276 0.0485h-0.71304c-0.04851 0-0.05821-0.01455-0.04851-0.07276l1.3776-4.8215c0.02425-0.08731 0.0388-0.16492 0.04851-0.4026 0-0.03395 0.01455-0.0485 0.0388-0.0485h1.0186c0.03395 0 0.04851 0.0097 0.05821 0.0485l1.5425 5.2338c0.0097 0.03881 0 0.06306-0.0388 0.06306h-0.8052c-0.0388 0-0.06306-0.0097-0.07276-0.04366l-0.4026-1.46zm1.3485-0.7858c-0.13582-0.53842-0.45596-1.7123-0.57722-2.2798h-0.0097c-0.10186 0.56752-0.35894 1.5279-0.56267 2.2798zm2.1828-2.6969c0-0.31044 0.21828-0.49476 0.49476-0.49476 0.29589 0 0.49476 0.19887 0.49476 0.49476 0 0.32014-0.20858 0.49476-0.50446 0.49476-0.28134 0-0.48506-0.17462-0.48506-0.49476zm0.05821 1.1011c0-0.0388 0.01455-0.05821 0.05821-0.05821h0.76154c0.0388 0 0.05821 0.01455 0.05821 0.05821v3.8271c0 0.0388-0.0097 0.05821-0.05821 0.05821h-0.75185c-0.04851 0-0.06306-0.02425-0.06306-0.06306v-3.8223z" enable-background="new" fill="#ff7c00" stroke-width=".048506"/>
-</svg>

+ 0 - 22
web/img/application-json.eea7b6c3.svg

@@ -1,22 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
-  <linearGradient id="b" x1="-666.12" x2="-553.27" y1="413.04" y2="525.91" gradientTransform="matrix(.99884 0 0 .9987 689.01 -388.84)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
-  <linearGradient id="a">
-   <stop stop-color="#3b3b3b" offset="0"/>
-   <stop stop-color="#fff" offset="1"/>
-  </linearGradient>
-  <linearGradient id="c" x1="-553.27" x2="-666.12" y1="525.91" y2="413.05" gradientTransform="matrix(.99884 0 0 .9987 689.01 -388.84)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
-  <linearGradient id="d" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#f4f4f4" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#d)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(.049608 0 0 .049608 4.4978 4.4978)" enable-background="new" fill-rule="evenodd">
-  <path d="m79.865 119.1c35.398 48.255 70.04-13.469 69.989-50.587-0.0602-43.886-44.541-68.414-70.018-68.414-40.892 0-79.836 33.796-79.836 80.036 0 51.396 44.64 79.865 79.836 79.865-7.9645-1.1468-34.506-6.834-34.863-67.967-0.23987-41.347 13.488-57.866 34.805-50.599 0.47743 0.17707 23.514 9.2645 23.514 38.951 0 29.56-23.427 38.715-23.427 38.715z" color="#000000" fill="url(#b)"/>
-  <path d="m79.823 41.401c-23.39-8.0619-52.043 11.216-52.043 49.829 0 63.048 46.721 68.77 52.384 68.77 40.892 0 79.836-33.796 79.836-80.036 0-51.396-44.64-79.865-79.836-79.865 9.7481-1.35 52.541 10.55 52.541 69.037 0 38.141-31.953 58.905-52.735 50.033-0.47743-0.17707-23.514-9.2645-23.514-38.951 0-29.56 23.367-38.818 23.367-38.818z" color="#000000" fill="url(#c)"/>
- </g>
-</svg>

+ 0 - 13
web/img/application-msonenote.4772ddbe.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#994b91" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m22 21c-0.554 0-1 0.446-1 1v20c0 0.554 0.446 1 1 1h18c0.554 0 1-0.446 1-1v-1h1c0.554 0 1-0.446 1-1v-4c0-0.186-0.064344-0.351-0.15234-0.5 0.088-0.149 0.15234-0.314 0.15234-0.5v-4c0-0.186-0.064344-0.351-0.15234-0.5 0.088-0.149 0.15234-0.314 0.15234-0.5v-4c0-0.554-0.446-1-1-1h-1v-3c0-0.554-0.446-1-1-1h-18zm1 3h7v1h-7v-1zm9 0h7v1h-7v-1zm9 2h1v4h-1v-4zm-18 1h7v1h-7v-1zm9 0h7v1h-7v-1zm-9 3h7v1h-7v-1zm9 0h7v1h-7v-1zm9 1h1v4h-1v-4zm-18 2h7v1h-7v-1zm9 0h7v1h-7v-1zm-9 3h7v1h-7v-1zm9 0h7v1h-7v-1zm9 0h1v4h-1v-4zm-18 3h7v1h-7v-1zm9 0h7v1h-7v-1z" color="#000000" color-rendering="auto" fill="#fff" image-rendering="auto" opacity=".75" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal"/>
-</svg>

+ 0 - 18
web/img/application-msoutlook.0c2789ef.svg

@@ -1,18 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#576dab" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-52.837 -2.8601)">
-  <path transform="translate(52.837 2.8601)" d="m32 17.301-13.363 10.025c-0.02875 0.0187-0.054801 0.0418-0.082031 0.0625l-0.015626 0.011719v0.001953c-0.3259 0.2559-0.53906 0.64931-0.53906 1.0977v12.199c2e-6 2 1.5771 2 2 2h24s2 0 2-2v-12.199c0-0.45851-0.22189-0.86016-0.56055-1.1152l0.005859-0.007813-13.445-10.076zm0 6.3984a5 5 0 0 1 5 5v1.5c0 0.831-0.669 1.5-1.5 1.5-0.61296 0-1.1359-0.36612-1.3691-0.89062a3 3 0 0 1-2.1309 0.89062 3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3v1.5c0 0.277 0.223 0.5 0.5 0.5s0.5-0.223 0.5-0.5v-1.5a4 4 0 0 0-4-4 4 4 0 0 0-4 4 4 4 0 0 0 4 4h3.5c0.277 0 0.5 0.223 0.5 0.5s-0.223 0.5-0.5 0.5h-3.5a5 5 0 0 1-5-5 5 5 0 0 1 5-5zm0 3a2 2 0 0 0-2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2z" enable-background="new" fill="#fff" opacity=".75"/>
-  <path transform="translate(52.837 2.8601)" d="m22.5 20.699c-0.831 0-1.5 0.66967-1.5 1.5v15.002c0 0.83033 0.669 1.498 1.5 1.498h19c0.831 0 1.5-0.66772 1.5-1.498v-15.002c0-0.83033-0.669-1.5-1.5-1.5h-19zm9.5 3a5 5 0 0 1 5 5v1.5c0 0.831-0.669 1.5-1.5 1.5-0.61296 0-1.1359-0.36612-1.3691-0.89062a3 3 0 0 1-2.1309 0.89062 3 3 0 0 1-3-3 3 3 0 0 1 3-3 3 3 0 0 1 3 3v1.5c0 0.277 0.223 0.5 0.5 0.5s0.5-0.223 0.5-0.5v-1.5a4 4 0 0 0-4-4 4 4 0 0 0-4 4 4 4 0 0 0 4 4h3.5c0.277 0 0.5 0.223 0.5 0.5s-0.223 0.5-0.5 0.5h-3.5a5 5 0 0 1-5-5 5 5 0 0 1 5-5zm0 3a2 2 0 0 0-2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2z" enable-background="new" fill="#fff"/>
-  <path d="m70.837 31.36 26.6 18.2-24.6-2e-4c-1 0-2-0.5-2-2z" enable-background="new" fill="#e8ebf0"/>
-  <path d="m96.837 49.56c2-2e-5 2-2 2-2l-1e-5 -16.2-26.6 18.2z" enable-background="new" fill="#f2f2fa"/>
- </g>
-</svg>

+ 0 - 16
web/img/application-msword-template.5500dd0c.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#4747b5" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -75.6 4.949)" fill="#fff" stroke-width=".088193">
-  <path d="m28.768 3.453c-1.2902 0.22976-2.5811 0.53461-3.8713 0.76016 0 1.9626-8.5e-4 3.9261 0 5.8896 1.2835 0.22471 2.5677 0.52447 3.8486 0.75844h0.38441v-7.4082zm-0.49905 2.3996-0.5944 2.4951-0.48788-0.03847c-0.11193-0.55714-0.24233-1.1109-0.34248-1.6706-0.09847 0.54368-0.2265 1.0823-0.33928 1.6226-0.16159-0.0084-0.32392-0.01852-0.48635-0.02946-0.13971-0.74062-0.30388-1.4762-0.43432-2.2185 0.14392-0.0067 0.28868-0.01258 0.4326-0.01763 0.08668 0.53611 0.18512 1.0697 0.26087 1.6066 0.11867-0.55041 0.23994-1.1008 0.35777-1.6512 0.15991-0.0093 0.31979-0.01599 0.47969-0.02441 0.11193 0.56809 0.22634 1.1352 0.34753 1.7008 0.0951-0.58408 0.20033-1.1664 0.30217-1.7496 0.16832-0.0059 0.33662-0.01517 0.5041-0.02527z" enable-background="new"/>
-  <path d="m29.395 4.5113h2.6458v5.2916h-2.6458v-0.52916h2.1166v-0.26458h-2.1166v-0.52916h2.1166v-0.26458h-2.1166v-0.52916h2.1166v-0.26458h-2.1166v-0.52916h2.1166v-0.26458h-2.1166v-0.52823h2.1166v-0.2655h-2.1166v-0.52916h2.1166v-0.26458h-2.1166z" enable-background="new"/>
- </g>
-</svg>

+ 0 - 26
web/img/application-octet-stream.4dbc6148.svg

@@ -1,26 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#f4f4f4" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-1.4e-4,-1.5875)" fill="#b3b3b3">
-  <path d="m5.7553 8.1738h-0.30961v-1.6044q0-0.33776 0.014073-0.6333l-0.47849 0.40813-0.16888-0.2111 0.67552-0.53479h0.26739z"/>
-  <path d="m6.656 6.879q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61923-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513 0 0.66145-0.2111 0.9992-0.19703 0.32369-0.61923 0.32369-0.40813 0-0.61923-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61923 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m8.6404 6.879q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61923-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513 0 0.66145-0.2111 0.9992-0.19703 0.32369-0.61923 0.32369-0.40813 0-0.61923-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61923 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m10.625 6.879q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61922-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513 0 0.66145-0.2111 0.9992-0.19703 0.32369-0.61923 0.32369-0.40812 0-0.61922-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61923 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m4.6717 10.054q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61923-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513 0 0.66145-0.2111 0.9992-0.19703 0.32369-0.61923 0.32369-0.40813 0-0.61923-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61923 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m7.7397 11.349h-0.30961v-1.6044q0-0.33776 0.014073-0.6333l-0.47849 0.40813-0.16888-0.2111 0.67552-0.53479h0.26739z"/>
-  <path d="m8.6404 10.054q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61923-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513 0 0.66145-0.2111 0.9992-0.19703 0.32369-0.61923 0.32369-0.40813 0-0.61923-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61923 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m10.625 10.054q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61922-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513 0 0.66145-0.2111 0.9992-0.19703 0.32369-0.61923 0.32369-0.40812 0-0.61922-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61923 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m4.6617 13.229q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61923-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513t-0.2111 0.9992q-0.19703 0.32369-0.61923 0.32369-0.40813 0-0.61923-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61922 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m6.6461 13.229q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61923-0.33776 0.4222 0 0.61923 0.33776 0.2111 0.32369 0.2111 0.98513t-0.2111 0.9992q-0.19703 0.32369-0.61923 0.32369-0.40813 0-0.61923-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61922 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
-  <path d="m9.7141 14.524h-0.30961v-1.6044q0-0.33776 0.014073-0.6333l-0.47849 0.40813-0.16888-0.2111 0.67552-0.53478h0.26739z"/>
-  <path d="m10.615 13.229q0-0.66145 0.19703-0.98513 0.2111-0.33776 0.61923-0.33776 0.4222 0 0.61922 0.33776 0.2111 0.32369 0.2111 0.98513t-0.2111 0.9992q-0.19703 0.32369-0.61922 0.32369-0.40813 0-0.61923-0.32369-0.19703-0.33776-0.19703-0.9992zm1.3229 0q0-0.59108-0.14073-0.81625-0.12666-0.22517-0.36591-0.22517-0.22517 0-0.36591 0.22517-0.12666 0.2111-0.12666 0.81625 0 0.61922 0.12666 0.8444 0.14073 0.2111 0.36591 0.2111 0.23925 0 0.36591-0.22517 0.14073-0.22517 0.14073-0.83032z"/>
- </g>
-</svg>

+ 0 - 21
web/img/application-ogg.776137df.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="8" y="4" width="48" height="56" ry="5" fill="#f9d351" style="paint-order:stroke fill markers"/>
- <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- <path d="m41.001 20c-0.35521-0.0038-0.82743 0.05144-1.4557 0.14586l-10.455 1.5986c-2.5242 0.5375-2.5155 0.70467-2.5241 2.8372v17.303c-0.10526-0.07374-0.20912-0.1479-0.31794-0.22084v7.49e-4c-0.80196-0.53742-1.6567-0.91988-2.8047-0.91988-1.438 0-2.2955 0.55061-2.8147 1.2759-0.51913 0.72527-0.69129 1.6394-0.69129 2.3461 0 0.85215 0.29095 1.7616 0.92211 2.4546 0.63116 0.69303 1.6015 1.1784 2.9967 1.1784 1.5755 0 2.6837-0.43994 3.3103-1.2991 0.49328-0.67647 0.76605-1.5803 0.86337-2.695v-0.0032c0.01361-0.13524 0.02343-0.27417 0.03213-0.41727 0.01323-0.22035 0.0102-0.63259 0.0102-0.63259v-13.249c0-1.8927-9.1e-5 -2.0056 2.5248-2.4373l7.4349-1.1662c2.5294-0.33094 2.53-0.1008 2.53 1.3206v12.159c-0.10243-0.07178-0.20361-0.144-0.30947-0.21491v7.49e-4c-0.80196-0.53742-1.6563-0.91988-2.8044-0.91988-1.438 0-2.2959 0.55061-2.815 1.2759-0.51913 0.72523-0.69129 1.6394-0.69129 2.3461 0 0.85215 0.29133 1.7616 0.92245 2.4546 0.63116 0.69306 1.6015 1.1787 2.9967 1.1787 1.5755 0 2.6837-0.44032 3.3103-1.2995 0.49328-0.67647 0.76567-1.5799 0.863-2.6947v-0.0035c0.01361-0.13523 0.02343-0.27379 0.03213-0.41693 0.01323-0.22035 0.01058-0.63293 0.01058-0.63293v-18.432c0-1.66-0.01096-2.2097-1.0765-2.2216z" enable-background="new" fill="#fff" stroke-width="3.7796"/>
-</svg>

+ 0 - 13
web/img/application-pdf.319df017.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#e84f43" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m6.942 9.1745c0.26366-0.51679 0.56331-1.099 0.80315-1.6836l0.09483-0.23076c-0.31327-1.1921-0.50112-2.149-0.3333-2.7677 0.04518-0.16131 0.23201-0.25919 0.43176-0.25919l0.12172 0.0018h0.02234c0.27347-0.0042 0.40223 0.34367 0.41685 0.47892 0.02413 0.22525-0.08008 0.60646-0.08008 0.60646 0-0.15394 6e-3 -0.40268-0.09113-0.61733-0.1131-0.24837-0.22113-0.39674-0.31798-0.42026-0.0489 0.03266-0.09643 0.1003-0.11272 0.23041-0.03372 0.18243-0.04383 0.4127-0.04383 0.5314 0 0.41939 0.08258 0.97295 0.24486 1.5436 0.03061-0.08835 0.05755-0.17324 0.07897-0.25278 0.03328-0.12535 0.24483-0.95628 0.24483-0.95628s-0.05331 1.1061-0.12778 1.4408c-0.01596 0.07072-0.03356 0.14067-0.05189 0.21226 0.2676 0.7477 0.6988 1.415 1.2132 1.8953 0.20281 0.18954 0.45896 0.34238 0.70139 0.48168 0.52942-0.07565 1.0169-0.11138 1.4235-0.10688 0.53953 0.0071 0.93557 0.08691 1.0959 0.24488 0.07852 0.07678 0.11039 0.16951 0.12028 0.27346 0.0023 0.04044-0.01734 0.13546-0.02312 0.15931 0.0058-0.02887 0.0058-0.17083-0.42733-0.30908-0.34111-0.10904-0.9795-0.10565-1.7455-0.02411 0.88603 0.43348 1.7492 0.64886 2.0228 0.51974 0.06688-0.03259 0.148-0.14373 0.148-0.14373s-0.04822 0.21908-0.08284 0.27384c-0.04419 0.0595-0.13086 0.12396-0.21304 0.14569-0.43202 0.11526-1.5566-0.15146-2.537-0.71164-1.0953 0.16131-2.2982 0.45931-3.2625 0.77558-0.94754 1.6606-1.6599 2.4232-2.2394 2.1331l-0.21306-0.10714c-0.08661-0.04954-0.09983-0.17013-0.0798-0.26833 0.06757-0.33057 0.48208-0.82846 1.3147-1.3256 0.08962-0.05423 0.48884-0.26531 0.48884-0.26531s-0.29555 0.28605-0.36479 0.34219c-0.66458 0.5446-1.1551 1.2298-1.1428 1.4954l0.0024 0.02316c0.56454-0.08045 1.4111-1.2295 2.4995-3.3591m0.34492 0.17661c-0.18179 0.34238-0.35948 0.65982-0.52353 0.95129 0.90746-0.3802 1.8841-0.6235 2.8139-0.79634-0.12495-0.08628-0.24624-0.17764-0.36038-0.27422-0.51198-0.43346-0.90232-0.97424-1.1853-1.5433-0.17944 0.48342-0.39281 0.99712-0.7447 1.6626" enable-background="new" fill="#fff" stroke-width=".025916"/>
-</svg>

File diff suppressed because it is too large
+ 0 - 13
web/img/application-pgp-signature.a482d859.svg


+ 0 - 11
web/img/application-pgp.ef9a65ff.svg

@@ -1,11 +0,0 @@
-<svg width="64" height="64" version="1.1" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="8" y="4" width="48" height="56" ry="5" fill="#0093dd" style="paint-order:stroke fill markers"/>
- <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".2" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- <path d="M32 20c-4.432 0-8 3.568-8 8v4h-1v5.687l.406-.53c.582-.781 2.131-1.897 3.344-2.376.639-.252 2.173-.53 3.906-.719C33.267 33.77 38.2 34 40 32v-4c0-4.432-3.568-8-8-8zm.656.969c.38.022.751.066 1.125.156 1.345.323 1.496.634.188.375-2.06-.408-4.794.508-6.469 2.187-.5.503-1.133 1.334-1.406 1.844-.564 1.052-.475.374.125-.906 1.097-2.341 3.783-3.811 6.437-3.656zM32 24c2.216 0 4 1.784 4 4v4h-8v-4c0-2.216 1.784-4 4-4zm9 9.156l-1.063.875c-.577.492-1.48 1.164-2.03 1.5-1.126.688-3.795 1.656-4.595 1.656-.3 0-.476.073-.406.188.134.216 1.731.119 3.406-.219.55-.11 1.827-.61 2.844-1.125L41 35.094v-1.938zm0 2.156l-.563.782c-1.865 2.571-4.903 3.996-9.125 4.25-2.819.169-1.787.49 1.594.5 2.29.003 2.807-.067 4.188-.532.864-.29 1.581-.512 1.625-.468.157.157-1.533 1.556-2.469 2.031-1.793.91-3.014 1.165-6.25 1.312-2.299.105-3.243.224-3.688.47-.566.311-.192.333 7.032.343H41v-8.688z" fill="#fff" overflow="visible"/>
-</svg>

+ 0 - 13
web/img/application-photoshop.20ed858b.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#262626" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".5" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path class="st1" d="m5.4058 5.8326c0-0.03396 0.06791-0.05821 0.10671-0.05821 0.31044-0.01455 0.77124-0.02425 1.2515-0.02425 1.3436 0 1.8675 0.73729 1.8675 1.6832 0 1.2321-0.89251 1.7608-1.9887 1.7608-0.18432 0-0.24738-0.0097-0.37835-0.0097v1.8626c0 0.0388-0.01455 0.05821-0.05821 0.05821h-0.74214c-0.0388 0-0.05821-0.01455-0.05821-0.05821zm0.86341 2.5757c0.11156 0.0097 0.19888 0.0097 0.3929 0.0097 0.56752 0 1.1011-0.19887 1.1011-0.97012 0-0.61603-0.3832-0.92646-1.0283-0.92646-0.19402 0-0.37835 0.0097-0.46566 0.01455zm4.1715-0.57722c-0.3832 0-0.51416 0.19402-0.51416 0.35409 0 0.17462 0.08731 0.29589 0.60147 0.56267 0.76154 0.36865 0.99922 0.72274 0.99922 1.2418 0 0.7761-0.59177 1.1932-1.3921 1.1932-0.422 0-0.7858-0.08731-0.99437-0.20858-0.03395-0.01455-0.03881-0.0388-0.03881-0.07761v-0.71304c0-0.04851 0.02425-0.06306 0.05821-0.0388 0.30559 0.19888 0.65483 0.28618 0.97497 0.28618 0.3832 0 0.54327-0.16007 0.54327-0.37835 0-0.17462-0.11156-0.32984-0.60148-0.58207-0.68878-0.32984-0.97497-0.66453-0.97497-1.2224 0-0.62573 0.48991-1.1447 1.3388-1.1447 0.41715 0 0.70819 0.06306 0.86826 0.13582 0.03881 0.02425 0.04851 0.06306 0.04851 0.09701v0.66453c0 0.0388-0.02425 0.06306-0.07276 0.04851-0.21343-0.13582-0.52872-0.21828-0.844-0.21828z" enable-background="new" fill="#00c8ff" stroke-width=".048506"/>
-</svg>

+ 0 - 13
web/img/application-postscript.7a2e596a.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#eb253e" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m9.079 4.806-3.0219 3.5789c0.78705 0.12623 2.1162 1.1213 1.9157 2.4429 0.40838-0.9801-0.34159-2.1756-1.0618-2.6582l2.6359-3.1482c-0.14118-0.10395-0.25253-0.15596-0.46785-0.21536zm-1.0166 0.24952c-0.11754 4e-4 -0.20572 0.01781-0.20108 0.01781l-0.96522 1.1063c-0.54203 0.0297-1.0692 0.06686-1.5816 0.11883-0.36383 0.03712-0.6534 0.32669-0.70538 0.7128-0.07425 0.67568-0.11135 1.3885-0.11135 2.1236 0 0.73508 0.0371 1.4479 0.11135 2.131 0.05198 0.43075 0.34156 0.64607 0.70538 0.7128 1.0098 0.16335 2.4726 0.0074 2.4726-1.381 0-1.2994-2.131-1.8563-2.8587-1.4999l3.3635-4.0169c-0.07796-0.01949-0.15904-0.02544-0.22956-0.02522zm2.2194 1.1389s-1.8932 4.2026-2.0789 4.6333c-0.28215 0.63855-0.66826 1.1063-1.2251 1.2697 0.49005 0.02228 0.98007 0.02966 1.485 0.02966 1.1062 0 2.1607-0.05196 3.1482-0.14849 0.36372-0.03712 0.66083-0.33412 0.70538-0.7128 0.08178-0.6831 0.11876-1.3959 0.11876-2.131 0-0.73508-0.03699-1.4479-0.11876-2.1236-0.04455-0.3861-0.34155-0.67567-0.70538-0.7128-0.43065-0.04455-0.87618-0.08173-1.3292-0.10401z" clip-rule="evenodd" enable-background="new" fill="#fff" fill-rule="evenodd" stroke-width=".066145"/>
-</svg>

+ 0 - 14
web/img/application-rss_xml.5d705f41.svg

@@ -1,14 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#fc8f36" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m30.581 3.9566-3.1749-3.1749v1.852c0 0.73288 0.59001 1.3229 1.3229 1.3229z" fill="#fff" fill-rule="evenodd" opacity=".35" style="paint-order:stroke fill markers"/>
- <path d="m3.7381 13.706c0-0.163 0.056-0.3 0.169-0.41a0.56 0.56 0 0 1 0.411-0.168c0.159 0 0.293 0.056 0.403 0.168 0.112 0.11 0.168 0.247 0.168 0.41a0.554 0.554 0 0 1-0.168 0.406 0.548 0.548 0 0 1-0.403 0.165 0.565 0.565 0 0 1-0.411-0.165 0.548 0.548 0 0 1-0.169-0.406m-0.033-2.61v0.962c1.228 0 2.225 0.999 2.225 2.229h0.964c0-1.762-1.43-3.19-3.19-3.19zm1e-3 -2.102v1.063a4.229 4.229 0 0 1 4.224 4.23h1.066a5.294 5.294 0 0 0-5.29-5.293z" fill="#fff" font-size="13.59" font-weight="700"/>
-</svg>

+ 0 - 16
web/img/application-sql.e76bf92b.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="8" y="4" width="48" height="56" ry="5" fill="#f4f4f4" style="paint-order:stroke fill markers"/>
- <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- <g fill="#888">
-  <rect x="18" y="24" width="28" height="3" rx="0" ry="0" style="paint-order:markers stroke fill"/>
-  <rect x="18" y="31" width="28" height="3" rx="0" ry="0" style="paint-order:markers stroke fill"/>
-  <rect x="18" y="38" width="28" height="3" rx="0" ry="0" style="paint-order:markers stroke fill"/>
-  <rect x="18" y="45" width="28" height="3" rx="0" ry="0" style="paint-order:markers stroke fill"/>
- </g>
-</svg>

+ 0 - 19
web/img/application-vnd.appimage.50730ff3.svg

@@ -1,19 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#55c1ec" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(.90322 0 0 .90322 .81896 -.26851)" fill="#fff">
-  <path d="m8.467 6.238a3.44 3.44 0 0 0-3.44 3.44 3.44 3.44 0 0 0 3.44 3.439 3.44 3.44 0 0 0 3.44-3.44 3.44 3.44 0 0 0-3.44-3.44zm0 1.393a2.046 2.046 0 0 1 2.046 2.046 2.046 2.046 0 0 1-2.046 2.045 2.046 2.046 0 0 1-2.046-2.045 2.046 2.046 0 0 1 2.046-2.046z" opacity=".15" style="paint-order:stroke markers fill"/>
-  <g transform="translate(-4.2406e-8,-280.07)" style="paint-order:stroke markers fill">
-   <path d="m8.467 286.83a2.91 2.91 0 0 0-2.91 2.91 2.91 2.91 0 0 0 2.91 2.911 2.91 2.91 0 0 0 2.91-2.91 2.91 2.91 0 0 0-2.91-2.91zm0 1.323a1.587 1.587 0 0 1 1.587 1.588 1.587 1.587 0 0 1-1.587 1.587 1.587 1.587 0 0 1-1.588-1.587 1.587 1.587 0 0 1 1.588-1.588z"/>
-   <path d="m7.938 285.64h1.058v1.852h-1.058zm0 6.35h1.058v1.852h-1.058zm4.63-2.778v1.058h-1.852v-1.058zm-6.35 0v1.058h-1.852v-1.058zm5.522 3.055-0.747 0.748-1.31-1.31 0.748-0.748zm-4.49-4.49-0.747 0.748-1.31-1.31 0.748-0.748zm-1.309 5.238-0.748-0.748 1.31-1.31 0.748 0.748zm4.49-4.49-0.748-0.748 1.31-1.31 0.748 0.748z"/>
-  </g>
- </g>
-</svg>

+ 0 - 13
web/img/application-vnd.flatpak.8a781de6.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#40ace8" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m8.4665 4.3296-3.7041 1.9945v4.2847l3.7041 1.9945 3.7041-1.9945v-4.2847zm0 0.60098 2.8816 1.5516-2.8816 1.5516-2.8816-1.5516z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fff" fill-rule="evenodd" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</svg>

+ 0 - 21
web/img/application-vnd.flatpak.ref.26e20d79.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="8" y="4" width="48" height="56" ry="5" fill="#4d88cf" style="paint-order:stroke fill markers"/>
- <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- <path d="m31.934 16-13.88 8.012-0.054 15.976 14 8.012 14-7.998-0.06-15.99-14.007-8.012zm0 1.27v11.568l1.63 0.974-1.63 0.94-11.748-6.787zm13.066 7.562v14.633l-13 7.443v-14.635z" color="#000000" fill="#fff" overflow="visible" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal"/>
-</svg>

+ 0 - 13
web/img/application-vnd.iccprofile.0c017bee.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#fad65c" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m32 21c-1.876 7-7 11.134-7 15s3.134 7 7 7 7-3.134 7-7-5.124-8-7-15m4.8125 11.428c0.7688 1.0325 1.1851 2.285 1.1875 3.5723 0 3.3137-2.6863 6-6 6-1.2849-0.0025-2.535-0.41738-3.5664-1.1836 0.51355 0.12001 1.039 0.1816 1.5664 0.18359 3.866 0 7-3.134 7-7-0.0028-0.52949-0.06574-1.057-0.1875-1.5723" color="#4d4d4d" color-rendering="auto" fill="#fff" fill-rule="evenodd" image-rendering="auto" opacity=".9" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal"/>
-</svg>

+ 0 - 29
web/img/application-vnd.kde.bluedevil-sendfile.a912311c.svg

@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#567dd2" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m6.9643 6.9697 2.9935 2.9935-1.4968 1.4136v-5.8207l1.4968 1.4136-2.9935 2.6609" fill="none" stroke="#fff" stroke-linecap="square" stroke-width=".33261"/>
- <g fill="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width=".52916">
-  <circle cx="5.2916" cy="8.4665" r=".26458" style="paint-order:stroke fill markers"/>
-  <circle cx="6.3499" cy="8.4665" r=".26458" style="paint-order:stroke fill markers"/>
-  <circle cx="10.583" cy="8.4665" r=".26458" style="paint-order:stroke fill markers"/>
-  <circle cx="11.641" cy="8.4665" r=".26458" style="paint-order:stroke fill markers"/>
- </g>
-</svg>

+ 0 - 13
web/img/application-vnd.ms-access.785a7627.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#c92429" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m8.6318 4.7624c-1.2902 0.22976-2.5811 0.53459-3.8713 0.76014 0 1.9626-8.5e-4 3.9261 0 5.8896 1.2835 0.22471 2.5676 0.5245 3.8485 0.75847h0.38446v-7.4082zm1.5215 1.0251c-0.29991 0.0029-0.59981 0.02779-0.89515 0.06847v1.0954c0.82989 0.12523 1.6951 0.09973 2.495-0.17014 0.16933-0.07408 0.38355-0.1667 0.41883-0.37219-0.04762-0.25135-0.32974-0.34576-0.54052-0.42426-0.47844-0.14607-0.97833-0.20218-1.4782-0.19727zm2.0179 1.0475c-0.31397 0.25223-0.71884 0.33605-1.1069 0.39338-0.59883 0.07849-1.2074 0.07934-1.8062 0.0035v1.1429c0.74788 0.09613 1.516 0.09183 2.2524-0.08191 0.22577-0.06438 0.47632-0.1315 0.63419-0.31935 0.05644-0.3757 0.0071-0.75931 0.02648-1.1385zm-5.0809 0.25747c0.29544 0.98776 0.57597 1.9809 0.86789 2.9695-0.20372-0.01323-0.40755-0.02825-0.60951-0.04677-0.0538-0.22048-0.11103-0.44094-0.16924-0.66054-0.27075-8.75e-4 -0.54156-0.0098-0.81143-0.023-0.05203 0.20902-0.10498 0.41714-0.15877 0.62527-0.17286-0.01323-0.34478-0.02548-0.51675-0.03695 0.25752-0.92867 0.52557-1.8538 0.78133-2.7825 0.20549-0.01499 0.41012-0.02921 0.61649-0.04509zm-0.33163 0.52838c-0.05909 0.41892-0.19139 0.82191-0.28047 1.2347 0.19402 0.0017 0.38812 0.0026 0.58303 0.0035-0.10054-0.41274-0.22319-0.82011-0.30256-1.2381zm5.4125 0.62527c-0.3122 0.25135-0.71442 0.33515-1.1016 0.39247-0.60059 0.07938-1.2109 0.08112-1.8115 0.0044v1.1438c0.74964 0.09525 1.5204 0.09089 2.2586-0.08462 0.22489-0.06438 0.47533-0.1314 0.62967-0.32013 0.05203-0.3757 0.0072-0.75761 0.02481-1.136zm0 1.411c-0.31397 0.25135-0.71703 0.33603-1.1051 0.39247-0.59971 0.07938-1.2083 0.08112-1.808 0.0044 0 0.38011 0.0027 0.75933-0.0035 1.1394 0.6297 0.09084 1.2726 0.08915 1.9014-7e-3 0.34307-0.06967 0.73909-0.11994 0.98868-0.39157 0.05556-0.3757 8e-3 -0.75942 0.02648-1.1378z" enable-background="new" fill="#fff" stroke-width=".088193"/>
-</svg>

+ 0 - 32
web/img/application-vnd.ms-cab-compressed.011f2e86.svg

@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#eca973" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-26.734 1.1705)" fill="#fff" opacity=".75">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
- <path d="m3.7041 12.171v0.26458h3.1749v-0.26458zm0 0.52916v0.26458h2.6458v-0.26458zm0 0.52916v0.26458h3.1749v-0.26458zm0 0.52916v0.26458h2.1166v-0.26458z" color="#000000" fill="#d78a4d"/>
- <g transform="matrix(1.25 0 0 1.25 -.92603 -2.5796)" fill="#d78a4d" stroke-width=".034981" aria-label="CAB">
-  <path d="m4.5267 10.416v0.14553q-0.069689-0.06491-0.14894-0.09702-0.078571-0.03211-0.16739-0.03211-0.1749 0-0.26782 0.10727-0.092918 0.10658-0.092918 0.30882 0 0.20155 0.092918 0.30882 0.092918 0.10658 0.26782 0.10658 0.088819 0 0.16739-0.03211 0.079254-0.03211 0.14894-0.09702v0.14416q-0.072422 0.04919-0.15373 0.07379-0.08062 0.0246-0.17081 0.0246-0.23161 0-0.36484-0.14143-0.13323-0.14211-0.13323-0.38739 0-0.24596 0.13323-0.38739 0.13323-0.14211 0.36484-0.14211 0.091552 0 0.17217 0.0246 0.081304 0.02391 0.15236 0.07242z"/>
-  <path d="m5.0808 10.473-0.1872 0.50763h0.37509zm-0.077887-0.13596h0.15646l0.38875 1.0201h-0.14348l-0.092918-0.26167h-0.45981l-0.092918 0.26167h-0.14553z"/>
-  <path d="m5.8351 10.87v0.37372h0.22136q0.11137 0 0.16466-0.04578 0.053975-0.04646 0.053975-0.14143 0-0.09565-0.053975-0.14074-0.053291-0.04578-0.16466-0.04578zm0-0.4195v0.30745h0.20428q0.10112 0 0.15031-0.03758 0.049875-0.03826 0.049875-0.11615 0-0.0772-0.049875-0.11546-0.049192-0.03826-0.15031-0.03826zm-0.13801-0.11342h0.35254q0.15782 0 0.24323 0.06559 0.085403 0.06559 0.085403 0.18652 0 0.0936-0.043726 0.14894-0.043726 0.05534-0.12845 0.06901 0.1018 0.02186 0.15782 0.09155 0.056707 0.069 0.056707 0.17286 0 0.13664-0.092918 0.21112-0.092918 0.07447-0.26441 0.07447h-0.36621z"/>
- </g>
-</svg>

+ 0 - 16
web/img/application-vnd.ms-excel.ec28c59f.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#008a50" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-20.433 -.26906)" fill="#fff" stroke-width=".088193">
-  <path d="m29.199 5.0315c-1.2902 0.22976-2.5811 0.53459-3.8713 0.76014 0 1.9626-8.4e-4 3.9261 0 5.8896 1.2835 0.22471 2.5676 0.5245 3.8485 0.75847h0.38446v-7.4082zm-0.86117 2.3092c-0.22469 0.46033-0.45024 0.9207-0.67914 1.3793 0.23143 0.47127 0.46794 0.93908 0.7002 1.4104-0.20281-0.01178-0.40476-0.02445-0.60757-0.03876-0.14306-0.35093-0.31732-0.68998-0.41999-1.0569-0.11445 0.34167-0.27773 0.66395-0.40901 0.99889-0.1843-0.0025-0.36863-0.01013-0.55293-0.0177 0.21628-0.4233 0.425-0.85005 0.64801-1.2708-0.18935-0.4334-0.39722-0.8583-0.59246-1.2892 0.18514-0.01094 0.37037-0.02181 0.55551-0.03191 0.12539 0.32905 0.26248 0.6538 0.36599 0.99126 0.11108-0.35766 0.27687-0.69422 0.41909-1.0401 0.19019-0.01346 0.38127-0.02524 0.5723-0.03449z" enable-background="new"/>
-  <path d="m29.825 6.0898v0.52916h0.79373v0.52916h-0.79373v0.26458h0.79373v0.53006h-0.79373v0.26367h0.79373v0.52916h-0.79373v0.26458h0.79373v0.52916h-0.79373v0.26458h0.79373v0.52916h-0.79373v0.26458h0.79373v0.52916h-0.79373v0.52916h2.6458v-5.5561zm1.0583 0.52916h1.0583v0.52916h-1.0583zm0 0.79374h1.0583v0.53006h-1.0583zm0 0.79373h1.0583v0.52916h-1.0583zm0 0.79373h1.0583v0.52916h-1.0583zm0 0.79374h1.0583v0.52916h-1.0583zm0 0.79373h1.0583v0.52916h-1.0583z" enable-background="new"/>
- </g>
-</svg>

+ 0 - 16
web/img/application-vnd.ms-excel.template.macroenabled.12.8ee75839.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#3f755a" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796,0,0,3.7796,-77.229,-1.0169)" fill="#fff" stroke-width=".088193">
-  <path d="m29.199 5.0315c-1.2902 0.22976-2.5811 0.53459-3.8713 0.76014 0 1.9626-8.4e-4 3.9261 0 5.8896 1.2835 0.22471 2.5676 0.5245 3.8485 0.75847h0.38446v-7.4082zm-0.86117 2.3092c-0.22469 0.46033-0.45024 0.9207-0.67914 1.3793 0.23143 0.47127 0.46794 0.93908 0.7002 1.4104-0.20281-0.01178-0.40476-0.02445-0.60757-0.03876-0.14306-0.35093-0.31732-0.68998-0.41999-1.0569-0.11445 0.34167-0.27773 0.66395-0.40901 0.99889-0.1843-0.0025-0.36863-0.01013-0.55293-0.0177 0.21628-0.4233 0.425-0.85005 0.64801-1.2708-0.18935-0.4334-0.39722-0.8583-0.59246-1.2892 0.18514-0.01094 0.37037-0.02181 0.55551-0.03191 0.12539 0.32905 0.26248 0.6538 0.36599 0.99126 0.11108-0.35766 0.27687-0.69422 0.41909-1.0401 0.19019-0.01346 0.38127-0.02524 0.5723-0.03449z" enable-background="new"/>
-  <path d="m29.825 6.0898v0.52916h0.79373v0.52916h-0.79373v0.26458h0.79373v0.53006h-0.79373v0.26367h0.79373v0.52916h-0.79373v0.26458h0.79373v0.52916h-0.79373v0.26458h0.79373v0.52916h-0.79373v0.26458h0.79373v0.52916h-0.79373v0.52916h2.6458v-5.5561zm1.0583 0.52916h1.0583v0.52916h-1.0583zm0 0.79374h1.0583v0.53006h-1.0583zm0 0.79373h1.0583v0.52916h-1.0583zm0 0.79373h1.0583v0.52916h-1.0583zm0 0.79374h1.0583v0.52916h-1.0583zm0 0.79373h1.0583v0.52916h-1.0583z" enable-background="new"/>
- </g>
-</svg>

+ 0 - 24
web/img/application-vnd.ms-htmlhelp.c8fb9bfd.svg

@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#3fa7d7" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m8.4365 4.4978a3.9687 3.9687 0 0 0-3.9387 3.9687 3.9687 3.9687 0 0 0 3.9687 3.9687 3.9687 3.9687 0 0 0 3.9687-3.9687 3.9687 3.9687 0 0 0-3.9687-3.9687 3.9687 3.9687 0 0 0-0.029972 0zm0.027388 1.5875a2.3812 2.3812 0 0 1 0.00258 0 2.3812 2.3812 0 0 1 2.3812 2.3812 2.3812 2.3812 0 0 1-2.3812 2.3812 2.3812 2.3812 0 0 1-2.3812-2.3812 2.3812 2.3812 0 0 1 2.3786-2.3812z" fill="#ff6e65" stroke-linecap="round" stroke-linejoin="round" stroke-width=".61164" style="paint-order:stroke fill markers"/>
- <path d="m4.862 6.821a3.948 3.948 0 0 0-0.364 1.645c0 0.587 0.134 1.144 0.364 1.646l1.389-0.794a2.378 2.378 0 0 1-0.166-0.852c0-0.3 0.064-0.587 0.166-0.851m-1.39-0.794m7.211 0-1.39 0.794c0.102 0.264 0.166 0.55 0.166 0.851 0 0.301-0.064 0.587-0.165 0.852l1.389 0.794c0.229-0.502 0.363-1.059 0.363-1.646 0-0.587-0.134-1.144-0.363-1.645m-4.457 3.862-0.794 1.388c0.502 0.23 1.059 0.364 1.646 0.364 0.587 0 1.144-0.134 1.645-0.364l-0.794-1.389c-0.264 0.102-0.55 0.166-0.851 0.166-0.301 0-0.587-0.064-0.852-0.166m0.852-6.184c-0.587 0-1.144 0.134-1.646 0.363l0.794 1.39c0.265-0.102 0.55-0.166 0.852-0.166 0.3 0 0.587 0.064 0.851 0.165l0.794-1.389a3.948 3.948 0 0 0-1.645-0.363" fill="#fff"/>
-</svg>

+ 0 - 13
web/img/application-vnd.ms-infopath.c0a76ad3.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#8e50c7" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m38 18-4 4.5-1.26 1.5h3.26v3h-12v13h-3.238l1.238 1.5 4 4.5 4-4.5 1.26-1.5h-3.26v-3h12v-13h3.238l-1.238-1.5zm-10 13h8v2h-8z" color="#4d4d4d" color-rendering="auto" fill="#fff" image-rendering="auto" opacity=".75" shape-rendering="auto" solid-color="#000000" style="isolation:auto;mix-blend-mode:normal"/>
-</svg>

+ 0 - 16
web/img/application-vnd.ms-powerpoint.b1a13336.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#e34e2b" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-17.672 1.3286)" fill="#fff" stroke-width=".088193">
-  <path d="m26.438 3.4338c-1.2902 0.22976-2.5811 0.53459-3.8713 0.76014 0 1.9626-8.5e-4 3.9261 0 5.8896 1.2835 0.22471 2.5676 0.5245 3.8485 0.75847h0.38446v-7.4082zm-1.9413 2.3328c0.25455-0.0054 0.4988 0.03123 0.69723 0.21071 0.38011 0.46125 0.27959 1.3096-0.28396 1.5857-0.2002 0.1023-0.42953 0.08832-0.64736 0.08126-8.75e-4 0.34483-0.0018 0.68958-9e-4 1.0344-0.17462-0.01499-0.35001-0.02994-0.52463-0.04405-0.0079-0.9419-0.0098-1.8411 7.75e-4 -2.783 0.24834-0.03094 0.50431-0.07957 0.75885-0.08497zm-0.02933 0.51107c-0.06946-0.0018-0.14052 0.0045-0.20567 0.0075-0.0026 0.29633-0.0043 0.59169 0.01421 0.88714 0.1755-0.02117 0.40304-0.0035 0.50358-0.18513 0.08378-0.17815 0.08904-0.40578-0.0115-0.57864-0.07331-0.10197-0.18485-0.12777-0.30062-0.13087z" enable-background="new"/>
-  <path d="m27.065 4.4921v0.87939c0.124-0.02662 0.25872-0.0767 0.39674-0.085v1.19h1.1827c-0.04202 0.36101-0.20295 0.73206-0.52128 0.92073-0.3122 0.2099-0.70894 0.2126-1.0582 0.10413 8.75e-4 0.17286-8.75e-4 0.52205 0 0.6949h2.1165v0.26458h-2.1165v0.52916h2.1165v0.26458h-2.1165v0.79374h2.6457v-5.5561zm0.66132 0.63406c0.56254 0.05826 1.0277 0.52454 1.0889 1.0857h-1.0889z" enable-background="new"/>
- </g>
-</svg>

+ 0 - 16
web/img/application-vnd.ms-powerpoint.template.macroenabled.12.0409b2fe.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#813d17" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -66.793 5.0216)" fill="#fff" stroke-width=".088193">
-  <path d="m26.438 3.4338c-1.2902 0.22976-2.5811 0.53459-3.8713 0.76014 0 1.9626-8.5e-4 3.9261 0 5.8896 1.2835 0.22471 2.5676 0.5245 3.8485 0.75847h0.38446v-7.4082zm-1.9413 2.3328c0.25455-0.0054 0.4988 0.03123 0.69723 0.21071 0.38011 0.46125 0.27959 1.3096-0.28396 1.5857-0.2002 0.1023-0.42953 0.08832-0.64736 0.08126-8.75e-4 0.34483-0.0018 0.68958-9e-4 1.0344-0.17462-0.01499-0.35001-0.02994-0.52463-0.04405-0.0079-0.9419-0.0098-1.8411 7.75e-4 -2.783 0.24834-0.03094 0.50431-0.07957 0.75885-0.08497zm-0.02933 0.51107c-0.06946-0.0018-0.14052 0.0045-0.20567 0.0075-0.0026 0.29633-0.0043 0.59169 0.01421 0.88714 0.1755-0.02117 0.40304-0.0035 0.50358-0.18513 0.08378-0.17815 0.08904-0.40578-0.0115-0.57864-0.07331-0.10197-0.18485-0.12777-0.30062-0.13087z" enable-background="new"/>
-  <path d="m27.065 4.4921v0.87939c0.124-0.02662 0.25872-0.0767 0.39674-0.085v1.19h1.1827c-0.04202 0.36101-0.20295 0.73206-0.52128 0.92073-0.3122 0.2099-0.70894 0.2126-1.0582 0.10413 8.75e-4 0.17286-8.75e-4 0.52205 0 0.6949h2.1165v0.26458h-2.1165v0.52916h2.1165v0.26458h-2.1165v0.79374h2.6457v-5.5561zm0.66132 0.63406c0.56254 0.05826 1.0277 0.52454 1.0889 1.0857h-1.0889z" enable-background="new"/>
- </g>
-</svg>

+ 0 - 13
web/img/application-vnd.ms-publisher.32dbb1c3.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#56cc56" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m35 21c-0.554 0-1 0.446-1 1v2h-12c-0.554 0-1 0.446-1 1v17c0 0.554 0.446 1 1 1h17c0.554 0 1-0.446 1-1v-4h2c0.554 0 1-0.446 1-1v-15c0-0.554-0.446-1-1-1h-7zm0 1h7v15h-2v-12c0-0.554-0.446-1-1-1-1.556-0.611-4.061-0.985-4-2zm-12 5h15v4h-15v-4zm0 6h7v1h-7v-1zm8 0h7v1h-7v-1zm-8 3h7v1h-7v-1zm8 0h7v1h-7v-1zm-8 3h7v1h-7v-1zm8 0h7v1h-7v-1z" color="#000000" color-rendering="auto" fill="#fff" image-rendering="auto" opacity=".9" shape-rendering="auto" solid-color="#000000" stroke-width="2" style="isolation:auto;mix-blend-mode:normal"/>
-</svg>

+ 0 - 16
web/img/application-vnd.ms-word.0209c533.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#3374d4" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-20.002 1.3094)" fill="#fff" stroke-width=".088193">
-  <path d="m28.768 3.453c-1.2902 0.22976-2.5811 0.53461-3.8713 0.76016 0 1.9626-8.5e-4 3.9261 0 5.8896 1.2835 0.22471 2.5677 0.52447 3.8486 0.75844h0.38441v-7.4082zm-0.49905 2.3996-0.5944 2.4951-0.48788-0.03847c-0.11193-0.55714-0.24233-1.1109-0.34248-1.6706-0.09847 0.54368-0.2265 1.0823-0.33928 1.6226-0.16159-0.0084-0.32392-0.01852-0.48635-0.02946-0.13971-0.74062-0.30388-1.4762-0.43432-2.2185 0.14392-0.0067 0.28868-0.01258 0.4326-0.01763 0.08668 0.53611 0.18512 1.0697 0.26087 1.6066 0.11867-0.55041 0.23994-1.1008 0.35777-1.6512 0.15991-0.0093 0.31979-0.01599 0.47969-0.02441 0.11193 0.56809 0.22634 1.1352 0.34753 1.7008 0.0951-0.58408 0.20033-1.1664 0.30217-1.7496 0.16832-0.0059 0.33662-0.01517 0.5041-0.02527z" enable-background="new"/>
-  <path d="m29.395 4.5113h2.6458v5.2916h-2.6458v-0.52916h2.1166v-0.26458h-2.1166v-0.52916h2.1166v-0.26458h-2.1166v-0.52916h2.1166v-0.26458h-2.1166v-0.52916h2.1166v-0.26458h-2.1166v-0.52823h2.1166v-0.2655h-2.1166v-0.52916h2.1166v-0.26458h-2.1166z" enable-background="new"/>
- </g>
-</svg>

+ 0 - 13
web/img/application-vnd.oasis.opendocument.chart.91c53f93.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="8" y="4" width="48" height="56" ry="5" fill="#f4f4f4" style="paint-order:stroke fill markers"/>
- <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- <path d="m19 16h6v32h-6z" color="#bebebe" fill="#68b723" overflow="visible"/>
- <path d="m29 32h6v16h-6z" fill="#c6262e" overflow="visible"/>
- <path d="m39 24h6v24h-6z" color="#bebebe" fill="#3689e6" overflow="visible"/>
-</svg>

+ 0 - 13
web/img/application-vnd.oasis.opendocument.formula-template.d5dbf3d8.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#4d4d4d" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".35" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m40 24.505-8 4e-3 -4.441 7.691-1.555-2.695h-2v1h1.428l2.133 3.693 5.02-8.693h6.42v1h1zm-5 3c-1.662 0-3 1.338-3 3s1.338 3 3 3c0.773 0 1.469-0.298 2-0.775v0.775h1v-6h-1v0.775c-0.531-0.477-1.227-0.775-2-0.775m0 1c1.108 0 2 0.892 2 2s-0.892 2-2 2-2-0.892-2-2 0.892-2 2-2m-11.99 6.99c-6e-3 0-0.01 0.223-0.01 0.5s4e-3 0.5 0.01 0.5h17.98c6e-3 0 0.01-0.223 0.01-0.5s-4e-3 -0.5-0.01-0.5zm8 3c-6e-3 0-0.01 0.223-0.01 0.5s4e-3 0.5 0.01 0.5h1.98c6e-3 0 0.01-0.223 0.01-0.5s-4e-3 -0.5-0.01-0.5z" color="#000000" color-rendering="auto" fill="#afafaf" image-rendering="auto" shape-rendering="auto"/>
-</svg>

+ 0 - 13
web/img/application-vnd.oasis.opendocument.formula.a4bc6018.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#808080" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m40 24.505-8 4e-3 -4.441 7.691-1.555-2.695h-2v1h1.428l2.133 3.693 5.02-8.693h6.42v1h1zm-5 3c-1.662 0-3 1.338-3 3s1.338 3 3 3c0.773 0 1.469-0.298 2-0.775v0.775h1v-6h-1v0.775c-0.531-0.477-1.227-0.775-2-0.775m0 1c1.108 0 2 0.892 2 2s-0.892 2-2 2-2-0.892-2-2 0.892-2 2-2m-11.99 6.99c-6e-3 0-0.01 0.223-0.01 0.5s4e-3 0.5 0.01 0.5h17.98c6e-3 0 0.01-0.223 0.01-0.5s-4e-3 -0.5-0.01-0.5zm8 3c-6e-3 0-0.01 0.223-0.01 0.5s4e-3 0.5 0.01 0.5h1.98c6e-3 0 0.01-0.223 0.01-0.5s-4e-3 -0.5-0.01-0.5z" color="#000000" color-rendering="auto" fill="#fff" image-rendering="auto" opacity=".75" shape-rendering="auto"/>
-</svg>

+ 0 - 13
web/img/application-vnd.oasis.opendocument.presentation-template.5b2c8be4.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#84603e" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m24 28.667c-2.9454 0-5.333 2.3877-5.333 5.3334 0 2.9455 2.3878 5.3334 5.333 5.3334 2.9454 0 5.333-2.3877 5.333-5.3334h-5.333zm8.0003 1.333v2h13v-2zm0.14351 6.0001-0.14351 2h13v-2zm-12.143 7.9999v1.9999h19.999l5.07e-4 -1.9999z" color="#000000" enable-background="new" fill="#fff" stroke-width="3.7796" style="text-decoration-line:none;text-indent:0;text-transform:none"/>
-</svg>

+ 0 - 13
web/img/application-vnd.oasis.opendocument.spreadsheet-template.a3256fa8.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#396939" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m20 50h24v-20h-24zm2-18h4v4h-4zm6.0001 0h14v4h-14zm-6.0001 6.0001h4v4h-4zm6.0001 0h14v4h-14zm-6.0001 6.0001h4v4h-4zm6.0001 0h14v4h-14z" enable-background="new" fill="#fff" stroke-width="3.7796"/>
-</svg>

+ 0 - 13
web/img/application-vnd.oasis.opendocument.text-template.4e634bfe.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#35677f" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m17 48.999v-2h20v2zm0-6.0001v-2h28v2zm0-6.0001v-2h28v2zm0-6.0001v-2h28v2z" enable-background="new" fill="#fff" stroke-width="3.7796"/>
-</svg>

File diff suppressed because it is too large
+ 0 - 11
web/img/application-vnd.oasis.opendocument.web-template.5d282765.svg


+ 0 - 13
web/img/application-vnd.snap.72d9809b.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#f4f4f4" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m4.4314 4.6853 4.3741 4.3741v-2.7971zm5.0362 1.5966 3.034 1.3638-0.6679-1.3638zm-0.39338 0.09999v2.5419l1.8243-1.7127zm-1.3036 2.0513-2.0213 3.8145 2.9321-2.9322z" enable-background="new" fill="#c8c4b7" stroke-width=".13229"/>
-</svg>

+ 0 - 13
web/img/application-vnd.visio.90d89058.svg

@@ -1,13 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#3d58a5" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m22 21c-0.554 0-1 0.446-1 1v20c0 0.554 0.446 1 1 1h20c0.554 0 1-0.446 1-1v-20c0-0.554-0.446-1-1-1h-20zm15.5 2.5 3 2.9961-2.5 2.5v9h-3v2h-5v-2h-4v-9.0508c-1.1624-0.23728-1.998-1.2589-2-2.4453 0-1.3807 1.1193-2.5 2.5-2.5 1.1879 1.38e-4 2.2116 0.83613 2.4492 2h6.0508l2.5-2.5zm-8.5605 3.5c-0.1999 0.9805-0.96522 1.7474-1.9453 1.9492v8.0508h3v-2h5v2h2v-8l-2-2h-6.0488-0.005859z" fill="#fff" opacity=".75"/>
-</svg>

+ 0 - 16
web/img/application-x-ace.03fa0685.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#415aa2" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -101.04 4.424)" fill="#fff">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
-</svg>

+ 0 - 23
web/img/application-x-addon.4a1bb379.svg

@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#71cd4f" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".1" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <path d="m7.7527 4.4038c-0.48833-0.03224-1.0378 0.31461-1.0183 0.84901-0.05775 0.31806 0.24896 0.55539 0.23561 0.84243-0.18067 0.0792-0.31804 0.0792-0.44525 0.0792h-2.1166c0 0.61015 1e-6 1.4849 1e-6 2.095 0.16525 0.35983 0.50265-0.15404 0.76917-0.09846 0.50926-0.1066 0.96764 0.3398 0.99203 0.83311 0.06771 0.47064-0.11443 1.0824-0.64776 1.1771-0.28767 0.04857-0.59728-0.0047-0.83352-0.18047-0.28447-0.17171-0.30258 0.20506-0.27993 0.38962v2.134h2.4342c0.35983-0.16525-0.15404-0.50265-0.09846-0.76917-0.10654-0.50914 0.33976-0.96791 0.83311-0.99209 0.47065-0.06757 1.0824 0.11445 1.1771 0.64782 0.04857 0.28767-0.0047 0.59728-0.18047 0.83352-0.17171 0.28447 0.20506 0.30258 0.38962 0.27993l1.7948 1e-6v-2.4231c0.16921-0.36295 0.50633 0.16805 0.78146 0.08895 0.44172 0.08689 0.88936-0.2288 0.956-0.67343 0.11271-0.49203-0.02706-1.1447-0.56572-1.3173-0.34122-0.11621-0.68122 0.03221-0.96926 0.20758-0.26514 0.03742-0.19416-0.28348-0.20248-0.4489 0-0.50636-1e-6 -1.2773-1e-6 -1.7837l-1.852-1e-6h-0.23185c-0.36296-0.1692 0.16805-0.50633 0.08895-0.78146 0.08689-0.44172-0.2288-0.88936-0.67342-0.956-0.1106-0.02387-0.22396-0.03314-0.33697-0.03317z" color="#000000" fill="#fff"/>
-</svg>

+ 0 - 16
web/img/application-x-ar.3c76d5a5.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#2bacf2" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -101.04 4.424)" fill="#fff">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
-</svg>

+ 0 - 16
web/img/application-x-arc.c4348636.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#87d07d" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -101.04 4.424)" fill="#fff">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
-</svg>

+ 0 - 26
web/img/application-x-archive.3ecaf965.svg

@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(.26458)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#deaa87" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="translate(-26.734 1.1705)" fill="#fff">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
-</svg>

+ 0 - 16
web/img/application-x-arj.020953b3.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#f38144" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -101.04 4.424)" fill="#fff">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
-</svg>

+ 0 - 23
web/img/application-x-bittorrent.0e44cdf9.svg

@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" viewBox="0 0 16.933 16.933" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(.61734 0 0 .61734 -18.168 -19.05)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="2.1166" y="1.0583" width="12.7" height="14.816" ry="1.3229" fill="#8f76e4" stroke-width=".26458" style="paint-order:stroke fill markers"/>
- <g transform="matrix(.066145 0 0 .066145 -1.0583 -1.852)" enable-background="new" fill="none" stroke="#8f76e4" stroke-width="8">
-  <path transform="matrix(4 0 0 4 16 27.999)" d="m34 17c-5.3575 0-10.312 2.8604-12.99 7.5-2.6786 4.6396-2.6786 10.36 0 15 2.6786 4.6396 7.633 7.5 12.99 7.5h22v-2h-22c-4.6458 0-8.9349-2.4765-11.258-6.5-2.3229-4.0235-2.3229-8.9765 0-13 2.3229-4.0235 6.6117-6.5 11.258-6.5v-2zm-0.58008 4.0156c-2.665 0.14145-5.2478 1.2484-7.209 3.2148-3.138 3.1463-4.0744 7.8801-2.3711 11.984 1.7032 4.1042 5.7165 6.7852 10.16 6.7852h22v-2h-22c-3.6409 0-6.9189-2.1879-8.3145-5.5508-1.3956-3.3628-0.62968-7.2268 1.9414-9.8047 2.5711-2.5779 6.4344-3.3534 9.8008-1.9668l0.76172-1.8496c-1.5407-0.63463-3.1705-0.89737-4.7695-0.8125zm0.36719 3.9902c-1.1298 0.033356-2.2597 0.33851-3.2871 0.93164-2.7398 1.5817-4.0806 4.8194-3.2617 7.875 0.81876 3.0556 3.5984 5.1875 6.7617 5.1875h22v-2h-22c-2.2677 0-4.2431-1.5146-4.8301-3.7051-0.58708-2.1905 0.36586-4.491 2.3301-5.625 1.9643-1.134 4.4315-0.80873 6.0352 0.79492l1.4141-1.4141c-1.398-1.398-3.2791-2.1005-5.1621-2.0449z" color="#000000" color-rendering="auto" dominant-baseline="auto" enable-background="accumulate" fill="#fff" image-rendering="auto" shape-rendering="auto" solid-color="#000000" stroke="none" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
- </g>
- <path d="m14.816 12.171-3.7041 3.7041h2.3812c0.73288 0 1.3229-0.59001 1.3229-1.3229z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="2.3333" style="paint-order:stroke fill markers"/>
-</svg>

+ 0 - 21
web/img/application-x-blender.1a5d4c35.svg

@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<svg width="64" height="64" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <metadata>
-  <rdf:RDF>
-   <cc:Work rdf:about="">
-    <dc:format>image/svg+xml</dc:format>
-    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
-    <dc:title/>
-   </cc:Work>
-  </rdf:RDF>
- </metadata>
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <rect x="8" y="4" width="48" height="56" ry="5" fill="#f37329" style="paint-order:stroke fill markers"/>
- <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- <path d="m32 15.719-15 7.5723v17.225l15 7.7656 15-7.7656v-17.225zm0 2.2402 11.799 5.957-11.797 6.0684-11.781-6.0801zm-13 7.5664 12 6.1934v13.793l-12-6.2129zm26 0.02148v13.752l-12 6.2129v-13.791z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#fff" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
-</svg>

+ 0 - 16
web/img/application-x-bzdvi.ddea8a90.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#8175c0" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -101.04 4.424)" fill="#fff">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
-</svg>

+ 0 - 16
web/img/application-x-bzip-compressed-tar.b40885da.svg

@@ -1,16 +0,0 @@
-<svg width="64" height="64" version="1.1" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">
- <defs>
-  <linearGradient id="a" x1="49.571" x2="51.714" y1="52.714" y2="54.857" gradientTransform="matrix(2.3333,0,0,2.3333,-68.667,-72.001)" gradientUnits="userSpaceOnUse">
-   <stop offset="0"/>
-   <stop stop-opacity="0" offset="1"/>
-  </linearGradient>
- </defs>
- <g transform="scale(1)">
-  <rect x="8" y="4" width="48" height="56" ry="5" fill="#a469d8" style="paint-order:stroke fill markers"/>
-  <path d="m56 46-14 14h9c2.77 0 5-2.23 5-5z" fill="url(#a)" fill-rule="evenodd" opacity=".15" stroke-width="8.8191" style="paint-order:stroke fill markers"/>
- </g>
- <g transform="matrix(3.7796 0 0 3.7796 -101.04 4.424)" fill="#fff">
-  <path d="m34.671 7.0315v1.7198c0 0.07329 0.059 0.13229 0.13229 0.13229h0.79374c0.07329 0 0.13229-0.059 0.13229-0.13229v-1.7198zm0.26458 1.0583h0.52916v0.52916h-0.52916z" color="#000000"/>
-  <path d="m35.2-0.11215v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916zm0 0.52916h-0.52916v0.52916h0.52916zm0 0.52916v0.52916h0.52916v-0.52916z" color="#000000"/>
- </g>
-</svg>

Some files were not shown because too many files changed in this diff