* 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
This commit is contained in:
link 2022-06-08 18:19:45 +08:00 committed by GitHub
parent fcb2b3f5a5
commit d4bed3e5c7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
293 changed files with 7546 additions and 24347 deletions

1
.gitignore vendored
View file

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

View file

@ -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

2
UI

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

8
go.mod
View file

@ -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

40
go.sum
View file

@ -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=

41
main.go
View file

@ -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)
// }
}

View file

@ -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")
//}

View file

@ -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
model/file.go Normal file
View file

@ -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"`
}

View file

@ -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"`
}

View file

@ -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
model/notify/file.go Normal file
View file

@ -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
model/notify/message.go Normal file
View file

@ -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
model/notify/person.go Normal file
View file

@ -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
model/notify/result.go Normal file
View file

@ -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"`
}

View file

@ -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
}
//服务配置

View file

@ -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
}

View file

@ -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
var loggers *zap.Logger
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 LogSetup() {
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)
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,
}
logger = log.New(F, DefaultPrefix, log.LstdFlags)
return zapcore.AddSync(lumberJackLogger)
}
func (o *oLog) Path() string {
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),
)
return filePath + fileName
}
func (o *oLog) Debug(v ...interface{}) {
setPrefix(DEBUG)
logger.Println(v)
loggers = zap.New(core)
}
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) {
pc, file, line, ok := runtime.Caller(2) // 回溯两层,拿到写日志的调用方的函数信息
if !ok {
return
}
funcName := runtime.FuncForPC(pc).Name()
funcName = path.Base(funcName) //Base函数返回路径的最后一个元素只保留函数名
logger.SetPrefix(logPrefix)
}
func NewOLoger() OLog {
return &oLog{}
callerFields = append(callerFields, zap.String("func", funcName), zap.String("file", file), zap.Int("line", line))
return
}

109
pkg/utils/loger/log_old.go Normal file
View file

@ -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{}
}

View file

@ -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

View file

@ -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
route/periodical.go Normal file
View file

@ -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)
}

View file

@ -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
route/socket.go Normal file
View file

@ -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})
}

View file

@ -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})
}

View file

@ -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)
// stepremove 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})
}

View file

@ -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)
defer ar.Close()
commonDir := file.CommonPrefix(filepath.Separator, list...)
//c.Header("Content-Disposition", "attachment; filename*=utf-8''"+url2.PathEscape(fileName))
//在线
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()
fileName := path.Base(filePath)
//c.Header("Content-Disposition", "inline")
// extraHeaders := map[string]string{
// "Content-Disposition": `attachment; filename="` + url2.PathEscape(fileName) + `"`,
// }
//c.Header("Cache-Control", "private")
//c.Header("Content-Type", "application/octet-stream")
http.ServeContent(c.Writer, c.Request, fileStat.Name(), fileStat.ModTime(), fileT)
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)
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 if t == "copy" {
err := file.CopyDir(from, to)
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 {
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
}

View file

@ -1,62 +1,5 @@
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)
}
func aaa() {
}
// @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
route/v1/notify_old.go Normal file
View file

@ -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)
}

View file

@ -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,
})
}

View file

@ -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))

View file

@ -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}
}

View file

@ -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)

View file

@ -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}
}

View file

@ -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------------------------------------

View file

@ -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
// }
var FileQueue sync.Map
// 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 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)
}
}

View file

@ -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"`
}

View file

@ -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}

View file

@ -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}
}

View file

@ -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),

View file

@ -1,13 +1,15 @@
package service
import (
"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/service/model"
"gorm.io/gorm"
"os"
"strconv"
"github.com/IceWhaleTech/CasaOS/pkg/config"
"github.com/IceWhaleTech/CasaOS/pkg/utils/command"
"github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
"github.com/IceWhaleTech/CasaOS/service/model"
"go.uber.org/zap"
"gorm.io/gorm"
)
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}
}

View file

@ -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{}
}

View file

@ -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}
}

View file

@ -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)

View file

@ -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
// }
// }
}
}
// }
// }

View file

@ -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 one or more lines are too long

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 5.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -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="#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(-.35818 .95866)" fill="#57688e" fill-opacity=".471" stroke-width=".427">
<path d="m10.692 4.262a1.73 1.73 0 0 0-0.162 0.194l-0.132 0.174-0.047-0.032c-0.066-0.044-0.129-0.054-0.189-0.027-0.04 0.018-0.138 0.142-0.774 0.979a42.55 42.55 0 0 0-0.728 0.97c0 6e-3 0.162 0.133 0.357 0.281l0.357 0.271 0.475-0.625c0.26-0.344 0.478-0.622 0.483-0.618 0.017 0.012 0.046 0.283 0.04 0.37a0.904 0.904 0 0 1-0.04 0.19c-0.033 0.101-0.037 0.108-0.626 0.885-0.325 0.43-0.596 0.795-0.6 0.81-0.015 0.04 0 0.114 0.03 0.157 0.05 0.073 0.175 0.096 0.246 0.045 0.05-0.036 1.215-1.587 1.253-1.668 0.108-0.231 0.132-0.528 0.066-0.82a1.896 1.896 0 0 0-0.095-0.307c-0.01-0.022 7e-3 -0.05 0.116-0.194 0.103-0.138 0.126-0.177 0.128-0.213 5e-3 -0.077-0.018-0.12-0.093-0.178l-0.07-0.055 0.14-0.186c0.115-0.154 0.14-0.194 0.142-0.23 7e-3 -0.153-0.151-0.252-0.277-0.173"/>
<path d="m7.483 8.058c-0.837 1.104-0.956 1.267-1.033 1.408-0.154 0.28-0.322 0.707-0.435 1.097-0.072 0.25-0.075 0.228 0.024 0.175 0.308-0.164 0.71-0.43 0.944-0.627 0.23-0.193 0.268-0.242 1.241-1.523l0.936-1.233-0.36-0.273c-0.198-0.15-0.362-0.273-0.365-0.272-3e-3 0-0.431 0.562-0.952 1.248m0.935 1.612a0.631 0.631 0 0 0-0.384 0.3 1.301 1.301 0 0 0-0.075 0.186 1.9 1.9 0 0 1-0.039 0.122c-0.01 0.014-0.288 0.08-0.45 0.108-0.384 0.067-0.488 0.092-0.525 0.127-0.074 0.068-0.017 0.136 0.087 0.106 0.028-9e-3 0.146-0.032 0.26-0.052s0.288-0.055 0.387-0.078a0.971 0.971 0 0 1 0.187-0.034 0.813 0.813 0 0 1-0.04 0.176l-0.046 0.168-0.105 0.045a1.34 1.34 0 0 0-0.182 0.098c-0.13 0.086-0.156 0.194-0.064 0.264 0.05 0.038 0.189 0.037 0.276 0 0.077-0.035 0.12-0.083 0.18-0.21 0.032-0.066 0.056-0.1 0.076-0.105 0.016-6e-3 0.153-0.032 0.306-0.063l0.31-0.064c0.03-7e-3 0.033-6e-3 0.024 0.022a0.735 0.735 0 0 1-0.057 0.109 0.315 0.315 0 0 0-0.047 0.115c0 0.043 0.036 0.086 0.066 0.075a0.08 0.08 0 0 1 0.033-9e-3 0.255 0.255 0 0 0 0.068-0.05c0.057-0.052 0.196-0.304 0.196-0.356 0-0.027 0.02-0.034 0.033-0.013 4e-3 7e-3 0.037 0.02 0.071 0.028 0.05 0.013 0.063 0.022 0.063 0.045 0 0.043 0.071 0.106 0.134 0.118a0.32 0.32 0 0 0 0.178-0.029c0.024-0.01 0.025-7e-3 0.017 0.03a0.897 0.897 0 0 1-0.09 0.158 2.288 2.288 0 0 0-0.232 0.45c-0.023 0.082-0.013 0.143 0.03 0.172 0.038 0.025 0.102 0.014 0.136-0.022a4.34 4.34 0 0 0 0.246-0.52 0.563 0.563 0 0 1 0.156-0.237c0.078-0.082 0.103-0.102 0.086-0.07-0.027 0.06-0.026 0.106 5e-3 0.134 0.065 0.06 0.16 0 0.242-0.148 0.049-0.09 0.085-0.116 0.266-0.201l0.095-0.043-0.01 0.051a1.081 1.081 0 0 1-0.072 0.175c-0.065 0.138-0.078 0.226-0.039 0.3 0.027 0.052 0.055 0.053 0.183 0.01 0.178-0.06 0.41-0.198 0.47-0.277 0.082-0.112 0.107-0.22 0.057-0.255-0.052-0.038-0.08-0.022-0.146 0.074a0.837 0.837 0 0 1-0.3 0.283c-0.05 0.026-0.093 0.043-0.097 0.038a5.018 5.018 0 0 1 0.165-0.445 0.281 0.281 0 0 0 0.023-0.08c0-0.04-0.05-0.084-0.09-0.084a0.958 0.958 0 0 0-0.204 0.084c-0.19 0.095-0.178 0.103-0.13-0.075 0.03-0.11 0.02-0.139-0.046-0.146-0.064-7e-3 -0.09 0.015-0.148 0.119a0.822 0.822 0 0 1-0.183 0.218c-0.127 0.117-0.132 0.121-0.162 0.1-0.045-0.032-0.07-0.027-0.178 0.027-0.106 0.053-0.141 0.06-0.168 0.028-0.022-0.026 0.013-0.04 0.207-0.078 0.187-0.036 0.21-0.046 0.21-0.085 0-0.062-0.05-0.122-0.142-0.163-0.159-0.07-0.177-0.075-0.247-0.057-0.075 0.02-0.186 0.127-0.202 0.194-0.015 0.069-0.062 0.049-0.062-0.028a0.243 0.243 0 0 0-0.062-0.127c-0.047-0.032-0.124 0.038-0.182 0.165l-0.046 0.099-0.102 0.022c-0.134 0.03-0.522 0.107-0.574 0.117-0.034 6e-3 -0.04 6e-3 -0.032-0.017l0.039-0.137c0.043-0.172 0.055-0.195 0.118-0.217a6.14 6.14 0 0 0 0.394-0.169 0.86 0.86 0 0 0 0.14-0.104c0.14-0.131 0.162-0.252 0.062-0.341a0.424 0.424 0 0 0-0.08-0.056 0.59 0.59 0 0 0-0.24-0.014zm0.179 0.191c0.028 0.028 0.028 0.03 3e-3 0.083a0.323 0.323 0 0 1-0.105 0.106c-0.085 0.058-0.35 0.165-0.36 0.146-0.01-0.032 0.075-0.223 0.13-0.284 0.072-0.082 0.093-0.09 0.208-0.084 0.074 7e-3 0.103 0.012 0.124 0.034m-0.908 1.158c-0.018 0.034-0.065 0.06-0.091 0.05-0.03-0.013-0.023-0.03 0.026-0.055 0.064-0.032 0.084-0.03 0.066 7e-3z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 982 B

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 834 B

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 874 B

View file

@ -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>

Before

Width:  |  Height:  |  Size: 813 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 14 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 917 B

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -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>

Before

Width:  |  Height:  |  Size: 1.4 KiB

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