Compare commits
484 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
49b8dc0079 | ||
|
|
ab83c3a551 | ||
|
|
98c6093674 | ||
|
|
e1f51521bf | ||
|
|
e85bc98dcc | ||
|
|
4ba52baa5c | ||
|
|
a82077b4de | ||
|
|
b8f04f3d11 | ||
|
|
e91f65f833 | ||
|
|
575ab9be2d | ||
|
|
64071bb60f | ||
|
|
44621a1a61 | ||
|
|
c56043e1f9 | ||
|
|
e8e4cbfd41 | ||
|
|
4b2bbe0614 | ||
|
|
9adfa14e62 | ||
|
|
067f82b632 | ||
|
|
e24e7979be | ||
|
|
c7c2b6e6f2 | ||
|
|
96798963d6 | ||
|
|
75508a81ef | ||
|
|
f7f4efadb7 | ||
|
|
4cc80b98db | ||
|
|
b07efaa7d0 | ||
|
|
7ba8ea6dd4 | ||
|
|
479461821f | ||
|
|
d25aea38fb | ||
|
|
0067502b37 | ||
|
|
d321af6085 | ||
|
|
b30f1730e4 | ||
|
|
7a02986982 | ||
|
|
a4107cba25 | ||
|
|
ba187aa345 | ||
|
|
b400cef734 | ||
|
|
03b72b8d2e | ||
|
|
0c7e20dee0 | ||
|
|
aa42c71a06 | ||
|
|
041c0b81a3 | ||
|
|
fe6776ee9d | ||
|
|
125b9f4160 | ||
|
|
488fee7b4b | ||
|
|
4fba596909 | ||
|
|
af04781830 | ||
|
|
2507cda94c | ||
|
|
21c1401859 | ||
|
|
4351f55225 | ||
|
|
d1956c4e88 | ||
|
|
d76d056ed1 | ||
|
|
e081cc31a2 | ||
|
|
88153b0e32 | ||
|
|
2b2d51cb6f | ||
|
|
abd8c7227d | ||
|
|
50d6dc7b71 | ||
|
|
b4a1ecc305 | ||
|
|
540bead0db | ||
|
|
6e9f25d680 | ||
|
|
268afe7006 | ||
|
|
7b9d3f0ec6 | ||
|
|
de116030bc | ||
|
|
4fb59385b7 | ||
|
|
40d6808067 | ||
|
|
3572bd8068 | ||
|
|
380a0e8623 | ||
|
|
4f6a0cb7c6 | ||
|
|
56cce8233b | ||
|
|
af8afcf931 | ||
|
|
7f997d60cd | ||
|
|
d45f5a805e | ||
|
|
fc9c624509 | ||
|
|
33372509eb | ||
|
|
bca0b02925 | ||
|
|
24995135e6 | ||
|
|
c1e4103edd | ||
|
|
6eda423156 | ||
|
|
7dc72d3519 | ||
|
|
907c22179b | ||
|
|
cdafbab7b1 | ||
|
|
e0064504e7 | ||
|
|
b22117dd01 | ||
|
|
c88efa8dbc | ||
|
|
7d060ff803 | ||
|
|
d5f8b6aae0 | ||
|
|
2416993c5e | ||
|
|
494165a03a | ||
|
|
88e607533c | ||
|
|
035d2f9209 | ||
|
|
53903daa87 | ||
|
|
567994be1a | ||
|
|
32fa27337a | ||
|
|
e1bb7646ac | ||
|
|
108b636def | ||
|
|
4abb14bf54 | ||
|
|
f8f96593c1 | ||
|
|
cb21b0f8f1 | ||
|
|
4c8c5fa27f | ||
|
|
6093119dde | ||
|
|
15755a3fd1 | ||
|
|
0213c81e0d | ||
|
|
c47f296f17 | ||
|
|
75133474f7 | ||
|
|
ddbe171f3a | ||
|
|
12e109f82c | ||
|
|
e095589172 | ||
|
|
d0293c785b | ||
|
|
aa351e31bf | ||
|
|
aceed3d13b | ||
|
|
10b70d4a09 | ||
|
|
cb9e014cf3 | ||
|
|
99017d834e | ||
|
|
fb73f5ca24 | ||
|
|
4369f1aeda | ||
|
|
6501aacb1b | ||
|
|
c3da17befc | ||
|
|
46bb073001 | ||
|
|
e8b47776ce | ||
|
|
6941fd3e2d | ||
|
|
f5937879df | ||
|
|
93877b7025 | ||
|
|
6612631cc3 | ||
|
|
30c3079a90 | ||
|
|
e86e681c53 | ||
|
|
48f72652da | ||
|
|
a3f7bafedb | ||
|
|
d30d610042 | ||
|
|
882e406266 | ||
|
|
45d421256c | ||
|
|
a2f20fc18f | ||
|
|
988364cb7c | ||
|
|
a3816ed8a1 | ||
|
|
d48805ee2c | ||
|
|
e820b81259 | ||
|
|
8b1046ce17 | ||
|
|
a138b65842 | ||
|
|
c344de3f04 | ||
|
|
427659a897 | ||
|
|
a6543970e7 | ||
|
|
399ea088dc | ||
|
|
3f87833e52 | ||
|
|
6dcb77023c | ||
|
|
4d37135bdf | ||
|
|
d109047fa5 | ||
|
|
b6112501e2 | ||
|
|
0663e236b4 | ||
|
|
f25cea1749 | ||
|
|
03e16415aa | ||
|
|
9a55e05943 | ||
|
|
c06fa4eab6 | ||
|
|
5575b082ea | ||
|
|
1c6da858bc | ||
|
|
f0a14641c1 | ||
|
|
c6d07cd8a4 | ||
|
|
df9f07faf4 | ||
|
|
a3dcc278d7 | ||
|
|
5de473fa44 | ||
|
|
763c1545a6 | ||
|
|
ecde7a0f32 | ||
|
|
7fc5e0abb5 | ||
|
|
06a655ac0c | ||
|
|
875ddaa834 | ||
|
|
030fccbb50 | ||
|
|
908f70d90a | ||
|
|
8724ced531 | ||
|
|
aa1a3a95ca | ||
|
|
0767dc075e | ||
|
|
c8a6c89036 | ||
|
|
cafe386cc4 | ||
|
|
0184c9695b | ||
|
|
19536edf28 | ||
|
|
045e4a20fa | ||
|
|
6cb8487a52 | ||
|
|
c39e9aa13f | ||
|
|
0203440b06 | ||
|
|
7f7bf60456 | ||
|
|
e8673634bc | ||
|
|
53e52c93ee | ||
|
|
c239c0ea5a | ||
|
|
7142f755f5 | ||
|
|
9fbc8dc1f9 | ||
|
|
d3819a6a88 | ||
|
|
6e93ed8e5f | ||
|
|
98543d49a9 | ||
|
|
9195eead27 | ||
|
|
e5b384736d | ||
|
|
4def720d1a | ||
|
|
2a0404ea17 | ||
|
|
6d22c4f02e | ||
|
|
24ac12da65 | ||
|
|
3f19882df8 | ||
|
|
dd54c16c1f | ||
|
|
223e9289dc | ||
|
|
2e301bdd51 | ||
|
|
e3ec7de23a | ||
|
|
18ec208381 | ||
|
|
8666daa07d | ||
|
|
926a9bdb03 | ||
|
|
fc2d837a2c | ||
|
|
3f69ccab99 | ||
|
|
b6ee82ee52 | ||
|
|
da1eb859a9 | ||
|
|
2b5269b823 | ||
|
|
6c8eeb0ced | ||
|
|
c5e0f3abc8 | ||
|
|
c6dbe22c57 | ||
|
|
51776e2aa3 | ||
|
|
c9d24607f6 | ||
|
|
46f7a3d4f3 | ||
|
|
56cf450c89 | ||
|
|
38c350b020 | ||
|
|
1f46040f1b | ||
|
|
63b95319cd | ||
|
|
a25d92be9e | ||
|
|
a161210a4a | ||
|
|
24469eb2fa | ||
|
|
a93fb49875 | ||
|
|
08d7cdf95b | ||
|
|
a9334bc247 | ||
|
|
2357d0c466 | ||
|
|
b003d51276 | ||
|
|
503cbf9830 | ||
|
|
2466058c5a | ||
|
|
6b1f422456 | ||
|
|
1d16d67733 | ||
|
|
6f9d15aed8 | ||
|
|
8725f974da | ||
|
|
2551c949ae | ||
|
|
30c6020ce7 | ||
|
|
d00b1ce1a1 | ||
|
|
2c43d79585 | ||
|
|
3e4aacb2b0 | ||
|
|
67cd22371b | ||
|
|
586941ece7 | ||
|
|
32a57cbfa6 | ||
|
|
1837a69b3e | ||
|
|
aa8bfcfd92 | ||
|
|
9e0c658470 | ||
|
|
66aefff4f3 | ||
|
|
bd0fdeecee | ||
|
|
1055eeb01b | ||
|
|
263a4578d4 | ||
|
|
c446b8a5af | ||
|
|
847b34cdcb | ||
|
|
5a57f90b8f | ||
|
|
f8eb9f5bd0 | ||
|
|
c8c336b574 | ||
|
|
43f1410974 | ||
|
|
1df110b3fb | ||
|
|
9bedce0df5 | ||
|
|
ae1d879e5a | ||
|
|
caab2e0952 | ||
|
|
a29d6517d3 | ||
|
|
dae2781818 | ||
|
|
c1de609b1a | ||
|
|
4e84807950 | ||
|
|
41c9cb45d6 | ||
|
|
2d72772f86 | ||
|
|
1cf1f0e04d | ||
|
|
324b88ec2b | ||
|
|
ec64c7ba0b | ||
|
|
67e0f8570e | ||
|
|
1745100705 | ||
|
|
28501944c5 | ||
|
|
c5c1a68f5c | ||
|
|
e2ed7fbd28 | ||
|
|
ab0675055c | ||
|
|
2b65559f36 | ||
|
|
b8beb07df5 | ||
|
|
01748fec49 | ||
|
|
42a50b1a02 | ||
|
|
d81595f43f | ||
|
|
71fa2d867f | ||
|
|
f55dbb0002 | ||
|
|
3e4d623786 | ||
|
|
1b109aac3a | ||
|
|
8558975d55 | ||
|
|
0e895089c7 | ||
|
|
5dd44f66c1 | ||
|
|
a1cfea46c6 | ||
|
|
42c492c85a | ||
|
|
9e8794a39f | ||
|
|
66c3604b2a | ||
|
|
c0ee1ee27b | ||
|
|
a3e669e433 | ||
|
|
8a83b4fff5 | ||
|
|
69c48d3f5d | ||
|
|
88504a335e | ||
|
|
a44a433807 | ||
|
|
9c03a8ae28 | ||
|
|
767a5f3a94 | ||
|
|
db1e138d36 | ||
|
|
84aa05f9a9 | ||
|
|
1071b85472 | ||
|
|
479412b190 | ||
|
|
ac4fc5b0ba | ||
|
|
4a8770232d | ||
|
|
2ea983bdae | ||
|
|
ffce8fa505 | ||
|
|
cb9e529eb7 | ||
|
|
7f0ee208fa | ||
|
|
2d38652034 | ||
|
|
4a2076a550 | ||
|
|
35049b26fe | ||
|
|
39648ba372 | ||
|
|
44ce0bbffd | ||
|
|
a634472873 | ||
|
|
a98c30f7fa | ||
|
|
43d4b80e11 | ||
|
|
09926fcc53 | ||
|
|
17eef7a4aa | ||
|
|
4738d7c951 | ||
|
|
4be0af5fa3 | ||
|
|
8aaa0900e5 | ||
|
|
49b5d9b886 | ||
|
|
7a3912767b | ||
|
|
d1e473aafe | ||
|
|
c91eb7ed47 | ||
|
|
443f631bac | ||
|
|
95be8d4698 | ||
|
|
f3926d020f | ||
|
|
b48eb5fdd3 | ||
|
|
b0fecdd017 | ||
|
|
793483b6e9 | ||
|
|
c99c7fa9af | ||
|
|
59449a73e1 | ||
|
|
dc86d636ac | ||
|
|
27dd2dd5f3 | ||
|
|
494ae1a47f | ||
|
|
7d1e1e5ff1 | ||
|
|
bcd1567b7d | ||
|
|
ae391b885b | ||
|
|
226bc84a4c | ||
|
|
e60a0c8f61 | ||
|
|
218c90a306 | ||
|
|
2a60c80194 | ||
|
|
35b1c55564 | ||
|
|
20476387ff | ||
|
|
a787748a00 | ||
|
|
34ee540c30 | ||
|
|
975a5ffc82 | ||
|
|
dee0870bf6 | ||
|
|
96ec3bd44e | ||
|
|
e4cf4096a6 | ||
|
|
3d79694c0a | ||
|
|
eab3e4e6f7 | ||
|
|
462152bab2 | ||
|
|
766a455db0 | ||
|
|
30200ac219 | ||
|
|
90a9113971 | ||
|
|
ad1834568f | ||
|
|
6231500b4a | ||
|
|
b2dbc08ea0 | ||
|
|
4700f68f4d | ||
|
|
fa73738309 | ||
|
|
25f92ec438 | ||
|
|
6a59c1dfd6 | ||
|
|
bad6e9d2fe | ||
|
|
e544972c1d | ||
|
|
f1e5de0d58 | ||
|
|
e434e1effb | ||
|
|
ca04b210e6 | ||
|
|
51275af41d | ||
|
|
c2417ac5b3 | ||
|
|
72831d413b | ||
|
|
5cb4bd5819 | ||
|
|
2d9bbca9a9 | ||
|
|
7b54c4e969 | ||
|
|
b50f4ec5ce | ||
|
|
86cc7534c2 | ||
|
|
1ab2565244 | ||
|
|
d2089a9344 | ||
|
|
39153c6936 | ||
|
|
1a8e2b92de | ||
|
|
cf63e751bf | ||
|
|
0c51bc2771 | ||
|
|
5f278cce3e | ||
|
|
f8cf3ac832 | ||
|
|
50bdd02a72 | ||
|
|
424155e5cd | ||
|
|
c4a4d25f7e | ||
|
|
ca2e135cba | ||
|
|
8b4583c59c | ||
|
|
6a836f9151 | ||
|
|
c7b92ad945 | ||
|
|
a05b7a43bd | ||
|
|
929346b2f1 | ||
|
|
23ceed01cb | ||
|
|
2ccf9a1110 | ||
|
|
4917d8e47b | ||
|
|
a0963e5d92 | ||
|
|
e2731b532a | ||
|
|
eccd6056bd | ||
|
|
c1273a4b01 | ||
|
|
017752b06e | ||
|
|
9abb7a04ac | ||
|
|
9533b9d887 | ||
|
|
f1a6feeb8f | ||
|
|
35930f2ffb | ||
|
|
0a1e8a2f8b | ||
|
|
4f9315132b | ||
|
|
196a843148 | ||
|
|
9778875d52 | ||
|
|
fdeb812333 | ||
|
|
e21e12e737 | ||
|
|
52d2322955 | ||
|
|
5ea8f7df33 | ||
|
|
7a9c73df3f | ||
|
|
1f38de989b | ||
|
|
c4f119de9c | ||
|
|
fa2afa856a | ||
|
|
4c83680ae9 | ||
|
|
981665e3e3 | ||
|
|
b3185292b3 | ||
|
|
249f437ff5 | ||
|
|
a7563ab499 | ||
|
|
38f8143fd2 | ||
|
|
a051c17010 | ||
|
|
0b62f8a1c8 | ||
|
|
b803d4f49d | ||
|
|
78e368f406 | ||
|
|
90e613ab26 | ||
|
|
e15914dc2e | ||
|
|
ebe6c39237 | ||
|
|
3369de9660 | ||
|
|
98b831bc22 | ||
|
|
c0f741d914 | ||
|
|
4c27a0cb5c | ||
|
|
4ff5f139f7 | ||
|
|
59910ecadc | ||
|
|
4e37176436 | ||
|
|
35085248b6 | ||
|
|
3ad8a366a6 | ||
|
|
b1660c92cc | ||
|
|
6ec1a3d4cb | ||
|
|
86ffa86800 | ||
|
|
22ad29c92f | ||
|
|
ebc1046ba6 | ||
|
|
43e23b15dc | ||
|
|
c8effe757b | ||
|
|
40b5cd3cff | ||
|
|
26435d85e8 | ||
|
|
b6d5e73708 | ||
|
|
2f193e0c83 | ||
|
|
4897c80646 | ||
|
|
601a455e08 | ||
|
|
d37f4fd77b | ||
|
|
c395cb2206 | ||
|
|
b6f8c612f1 | ||
|
|
18551528ca | ||
|
|
bbc7782f40 | ||
|
|
c121341911 | ||
|
|
990a256e40 | ||
|
|
89e3caf4f2 | ||
|
|
3e4a458fac | ||
|
|
25d2897fb9 | ||
|
|
a2151d0b93 | ||
|
|
5b9dcd829c | ||
|
|
e2e1471dfa | ||
|
|
a664c9abe9 | ||
|
|
0f9b1cdf25 | ||
|
|
7cfd6e7493 | ||
|
|
592f8f0831 | ||
|
|
88c36d2b2d | ||
|
|
dbe5f1dfb2 | ||
|
|
1297ae7bb3 | ||
|
|
ba48a45d39 | ||
|
|
12b5de5cea | ||
|
|
a7b33647ea | ||
|
|
3a7467e6f7 | ||
|
|
8c47ce9b0e | ||
|
|
11f623cc35 | ||
|
|
5365f4b867 | ||
|
|
260a88623e | ||
|
|
2143cab1fa | ||
|
|
5be3662b35 | ||
|
|
c8ab62f9fe | ||
|
|
114c16a36f | ||
|
|
8ac33ceb4c | ||
|
|
9290c20c43 | ||
|
|
c302c26d87 | ||
|
|
f04c6c2032 | ||
|
|
9d35d567ae | ||
|
|
3549ebc5b9 | ||
|
|
68c2dcf67d | ||
|
|
cb4ab20249 | ||
|
|
9e93ac10f4 |
2
.env
@@ -28,4 +28,4 @@ MAIL_ENCRYPTION=null
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
44
.gitattributes
vendored
@@ -1,5 +1,49 @@
|
||||
# Configuration file for Git attributes
|
||||
|
||||
# Core Settings {{{
|
||||
# .gitattributes
|
||||
.gitattributes !filter !diff
|
||||
|
||||
# Line Endings
|
||||
* text=auto
|
||||
|
||||
# Set binary to none-text files
|
||||
*.png -text
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
# GitHub Linguist {{{
|
||||
|
||||
# Exclude files/folder from being detected by the GitHub linguist
|
||||
# statistic.
|
||||
node_modules/* linguist-vendored
|
||||
public/* linguist-generated=true
|
||||
vendor/* linguist-vendored
|
||||
|
||||
# Remove Vue as it's currently not used in the project.
|
||||
resources/assets/js/components/ExampleComponent.vue linguist-vendored
|
||||
|
||||
# System Wide
|
||||
*.css linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
*.js linguist-vendored
|
||||
|
||||
# Include user generated files that's removed bu the setting above.
|
||||
resources/assets/js/app.js linguist-vendored=false
|
||||
resources/assets/sass/_app.scss linguist-vendored=false
|
||||
resources/assets/sass/_rune.scss linguist-vendored=false
|
||||
resources/assets/sass/_variables.scss linguist-vendored=false
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
# Archive Exlude {{{
|
||||
# Exclude files/folders from being exported when creating an archive.
|
||||
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.travis.yml export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
|
||||
# }}}
|
||||
|
||||
17
.gitignore
vendored
@@ -9,4 +9,19 @@ Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
||||
storage/app/public/.DS_Store
|
||||
### macOS ###
|
||||
*.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
storage/app/public/avatars/*
|
||||
|
||||
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
||||
# Release Notes
|
||||
|
||||
## v1.4.0 (2018-02-18)
|
||||
|
||||
### Added
|
||||
- Tag(folder) support
|
||||
- Image preview for uploading icons
|
||||
- A load of supported apps, full list of apps https://github.com/linuxserver/Heimdall/projects/1
|
||||
|
||||
### Changed
|
||||
- Edited vendor/laravelcollective/html/src/FormBuilder.php to allow relative links #3369de9
|
||||
- Changed links to use relative links for reverse proxy support
|
||||
- Links open in new tab
|
||||
|
||||
### Fixed
|
||||
- adds all the fixes in the 1.3.x point releases and on master
|
||||
|
||||
## v1.3.0 (2018-02-09)
|
||||
|
||||
### Added
|
||||
|
||||
63
app/Application.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Application extends Model
|
||||
{
|
||||
public $incrementing = false;
|
||||
|
||||
protected $primaryKey = 'appid';
|
||||
|
||||
//
|
||||
public function icon()
|
||||
{
|
||||
if(!file_exists(storage_path('app/public/'.$this->icon))) {
|
||||
$img_src = app_path('SupportedApps/'.$this->name.'/'.str_replace('icons/', '', $this->icon));
|
||||
$img_dest = storage_path('app/public/'.$this->icon);
|
||||
//die("i: ".$img_src);
|
||||
@copy($img_src, $img_dest);
|
||||
}
|
||||
|
||||
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function iconView()
|
||||
{
|
||||
return asset('storage/'.$this->icon);
|
||||
}
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
// check if light or dark
|
||||
if($this->tile_background == 'light') return '#fafbfc';
|
||||
return '#161b1f';
|
||||
}
|
||||
|
||||
public function class()
|
||||
{
|
||||
$name = $this->name;
|
||||
$name = preg_replace('/\PL/u', '', $name);
|
||||
|
||||
$class = '\App\SupportedApps\\'.$name.'\\'.$name;
|
||||
return $class;
|
||||
}
|
||||
|
||||
public static function applist()
|
||||
{
|
||||
$list = [];
|
||||
$all = self::orderBy('name')->get()->sortBy('name', SORT_NATURAL|SORT_FLAG_CASE);
|
||||
$list['null'] = 'None';
|
||||
foreach($all as $app) {
|
||||
$name = $app->name;
|
||||
$name = preg_replace('/\PL/u', '', $name);
|
||||
|
||||
$list['\App\SupportedApps\\'.$name.'\\'.$name] = $app->name;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
79
app/Console/Commands/RegisterApp.php
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Application;
|
||||
use App\SupportedApps;
|
||||
|
||||
class RegisterApp extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'register:app {folder}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Add a local app to the registry';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$folder = $this->argument('folder');
|
||||
if($folder == 'all') {
|
||||
$apps = scandir(app_path('SupportedApps'));
|
||||
foreach($apps as $folder) {
|
||||
if($folder == '.' || $folder == '..') continue;
|
||||
$this->addApp($folder);
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->addApp($folder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function addApp($folder)
|
||||
{
|
||||
$json = app_path('SupportedApps/'.$folder.'/app.json');
|
||||
if(file_exists($json)) {
|
||||
$app = json_decode(file_get_contents($json));
|
||||
if(isset($app->appid)) {
|
||||
$exists = Application::find($app->appid);
|
||||
if($exists) {
|
||||
$this->error('Application already registered - '.$exists->name." - ".$exists->appid);
|
||||
} else {
|
||||
// Doesn't exist so add it
|
||||
SupportedApps::saveApp($app, new Application);
|
||||
$this->info("Application Added - ".$app->name." - ".$app->appid);
|
||||
}
|
||||
} else {
|
||||
$this->error('No App ID for - '.$folder);
|
||||
}
|
||||
|
||||
} else {
|
||||
$this->error('Could not find '.$json);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
12
app/EnhancedApps.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
interface EnhancedApps
|
||||
{
|
||||
public function test();
|
||||
public function livestats();
|
||||
public function url($endpoint);
|
||||
|
||||
}
|
||||
@@ -10,3 +10,35 @@ function format_bytes($bytes, $is_drive_size = true, $beforeunit = '', $afteruni
|
||||
elseif($labels[$x] == "MB") return(round($bytes, 2).$beforeunit.$labels[$x].$afterunit);
|
||||
else return(round($bytes, 0).$beforeunit.$labels[$x].$afterunit);
|
||||
}
|
||||
|
||||
function get_brightness($hex) {
|
||||
// returns brightness value from 0 to 255
|
||||
// strip off any leading #
|
||||
$hex = str_replace('#', '', $hex);
|
||||
if(strlen($hex) == 3) {
|
||||
$hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2];
|
||||
}
|
||||
|
||||
$c_r = hexdec(substr($hex, 0, 2));
|
||||
$c_g = hexdec(substr($hex, 2, 2));
|
||||
$c_b = hexdec(substr($hex, 4, 2));
|
||||
|
||||
return (($c_r * 299) + ($c_g * 587) + ($c_b * 114)) / 1000;
|
||||
}
|
||||
|
||||
function title_color($hex)
|
||||
{
|
||||
if(get_brightness($hex) > 130) {
|
||||
return ' black';
|
||||
} else {
|
||||
return ' white';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function className($name)
|
||||
{
|
||||
$name = preg_replace('/\PL/u', '', $name);
|
||||
return $name;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@ namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@@ -25,7 +30,7 @@ class LoginController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
@@ -34,6 +39,88 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
Session::put('backUrl', URL::previous());
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
public function username()
|
||||
{
|
||||
return 'username';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a login request to the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
$current_user = User::currentUser();
|
||||
$request->merge(['username' => $current_user->username]);
|
||||
//die(print_r($request->all()));
|
||||
$this->validateLogin($request);
|
||||
|
||||
// If the class is using the ThrottlesLogins trait, we can automatically throttle
|
||||
// the login attempts for this application. We'll key this by the username and
|
||||
// the IP address of the client making these requests into this application.
|
||||
if ($this->hasTooManyLoginAttempts($request)) {
|
||||
$this->fireLockoutEvent($request);
|
||||
|
||||
return $this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
if ($this->attemptLogin($request)) {
|
||||
return $this->sendLoginResponse($request);
|
||||
}
|
||||
|
||||
// If the login attempt was unsuccessful we will increment the number of attempts
|
||||
// to login and redirect the user back to the login form. Of course, when this
|
||||
// user surpasses their maximum number of attempts they will get locked out.
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
return $this->sendFailedLoginResponse($request);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
}
|
||||
|
||||
public function setUser(User $user)
|
||||
{
|
||||
Auth::logout();
|
||||
session(['current_user' => $user]);
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
public function autologin($uuid)
|
||||
{
|
||||
$user = User::where('autologin', $uuid)->first();
|
||||
Auth::login($user);
|
||||
session(['current_user' => $user]);
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
protected function authenticated(Request $request, $user)
|
||||
{
|
||||
return back();
|
||||
}
|
||||
|
||||
public function redirectTo()
|
||||
{
|
||||
return Session::get('url.intended') ? Session::get('url.intended') : $this->redirectTo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class RegisterController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
||||
@@ -25,7 +25,7 @@ class ResetPasswordController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
||||
@@ -6,8 +6,27 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
protected $user;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(function ($request, $next) {
|
||||
$this->user = $this->user();
|
||||
//print_r($this->user);
|
||||
return $next($request);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return User::currentUser();
|
||||
}
|
||||
}
|
||||
|
||||
28
app/Http/Controllers/HomeController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,23 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Artisan;
|
||||
use App\Application;
|
||||
use App\Item;
|
||||
use App\Setting;
|
||||
use App\SupportedApps\Nzbget;
|
||||
use App\User;
|
||||
use GrahamCampbell\GitHub\Facades\GitHub;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\SupportedApps;
|
||||
use App\Jobs\ProcessApps;
|
||||
|
||||
class ItemController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource on the dashboard.
|
||||
*
|
||||
@@ -18,8 +26,8 @@ class ItemController extends Controller
|
||||
*/
|
||||
public function dash()
|
||||
{
|
||||
$data['apps'] = Item::pinned()->orderBy('order', 'asc')->get();
|
||||
$data['all_apps'] = Item::all();
|
||||
$data['apps'] = Item::doesntHave('parents')->pinned()->orderBy('order', 'asc')->get();
|
||||
$data['all_apps'] = Item::doesntHave('parents')->get();
|
||||
return view('welcome', $data);
|
||||
}
|
||||
|
||||
@@ -37,9 +45,8 @@ class ItemController extends Controller
|
||||
$item->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Pin item on the dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
@@ -49,7 +56,8 @@ class ItemController extends Controller
|
||||
$item = Item::findOrFail($id);
|
||||
$item->pinned = true;
|
||||
$item->save();
|
||||
return redirect()->route('dash');
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +70,8 @@ class ItemController extends Controller
|
||||
$item = Item::findOrFail($id);
|
||||
$item->pinned = false;
|
||||
$item->save();
|
||||
return redirect()->route('dash');
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,8 +90,9 @@ class ItemController extends Controller
|
||||
$data['ajax'] = true;
|
||||
return view('sortable', $data);
|
||||
} else {
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,8 +105,8 @@ class ItemController extends Controller
|
||||
{
|
||||
$trash = (bool)$request->input('trash');
|
||||
|
||||
$data['apps'] = Item::orderBy('title', 'asc')->get();
|
||||
$data['trash'] = Item::onlyTrashed()->get();
|
||||
$data['apps'] = Item::ofType('item')->orderBy('title', 'asc')->get();
|
||||
$data['trash'] = Item::ofType('item')->onlyTrashed()->get();
|
||||
if($trash) {
|
||||
return view('items.trash', $data);
|
||||
} else {
|
||||
@@ -113,7 +123,8 @@ class ItemController extends Controller
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
$data = [];
|
||||
$data['tags'] = Item::ofType('tag')->orderBy('title', 'asc')->pluck('title', 'id');
|
||||
$data['current_tags'] = [];
|
||||
return view('items.create', $data);
|
||||
|
||||
}
|
||||
@@ -129,7 +140,7 @@ class ItemController extends Controller
|
||||
//
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
'url' => 'required',
|
||||
'url' => 'required|url',
|
||||
]);
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
@@ -140,15 +151,27 @@ class ItemController extends Controller
|
||||
}
|
||||
|
||||
$config = Item::checkConfig($request->input('config'));
|
||||
$current_user = User::currentUser();
|
||||
$request->merge([
|
||||
'description' => $config
|
||||
'description' => $config,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
|
||||
if($request->input('class') === 'null') {
|
||||
$request->merge([
|
||||
'class' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
//die(print_r($request->input('config')));
|
||||
|
||||
Item::create($request->all());
|
||||
$item = Item::create($request->all());
|
||||
|
||||
return redirect()->route('dash')
|
||||
$item->parents()->sync($request->tags);
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success', __('app.alert.success.item_created'));
|
||||
}
|
||||
|
||||
@@ -172,11 +195,12 @@ class ItemController extends Controller
|
||||
public function edit($id)
|
||||
{
|
||||
// Get the item
|
||||
$item = Item::find($id);
|
||||
$data['item'] = Item::find($id);
|
||||
$data['tags'] = Item::ofType('tag')->orderBy('title', 'asc')->pluck('title', 'id');
|
||||
$data['current_tags'] = $data['item']->parents;
|
||||
|
||||
// show the edit form and pass the nerd
|
||||
return view('items.edit')
|
||||
->with('item', $item);
|
||||
return view('items.edit', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,7 +214,7 @@ class ItemController extends Controller
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
'url' => 'required',
|
||||
'url' => 'required|url',
|
||||
]);
|
||||
//die(print_r($request->all()));
|
||||
if($request->hasFile('file')) {
|
||||
@@ -201,13 +225,26 @@ class ItemController extends Controller
|
||||
}
|
||||
|
||||
$config = Item::checkConfig($request->input('config'));
|
||||
$current_user = User::currentUser();
|
||||
$request->merge([
|
||||
'description' => $config
|
||||
'description' => $config,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
|
||||
Item::find($id)->update($request->all());
|
||||
if($request->input('class') === 'null') {
|
||||
$request->merge([
|
||||
'class' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
return redirect()->route('dash')
|
||||
|
||||
$item = Item::find($id);
|
||||
$item->update($request->all());
|
||||
|
||||
$item->parents()->sync($request->tags);
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.item_updated'));
|
||||
}
|
||||
|
||||
@@ -228,8 +265,9 @@ class ItemController extends Controller
|
||||
} else {
|
||||
Item::find($id)->delete();
|
||||
}
|
||||
|
||||
return redirect()->route('items.index')
|
||||
|
||||
$route = route('items.index', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.item_deleted'));
|
||||
}
|
||||
|
||||
@@ -244,21 +282,13 @@ class ItemController extends Controller
|
||||
//
|
||||
Item::withTrashed()
|
||||
->where('id', $id)
|
||||
->restore();
|
||||
return redirect()->route('items.index')
|
||||
->restore();
|
||||
|
||||
$route = route('items.inded', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.item_restored'));
|
||||
}
|
||||
|
||||
public function isSupportedAppByKey($app)
|
||||
{
|
||||
$output = false;
|
||||
$all_supported = Item::supportedList();
|
||||
if(array_key_exists($app, $all_supported)) {
|
||||
$output = new $all_supported[$app];
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return details for supported apps
|
||||
*
|
||||
@@ -267,19 +297,25 @@ class ItemController extends Controller
|
||||
public function appload(Request $request)
|
||||
{
|
||||
$output = [];
|
||||
$app = $request->input('app');
|
||||
$appname = $request->input('app');
|
||||
//die($appname);
|
||||
|
||||
if(($app_details = $this->isSupportedAppByKey($app)) !== false) {
|
||||
// basic details
|
||||
$output['icon'] = $app_details->icon();
|
||||
$output['colour'] = $app_details->defaultColour();
|
||||
$app_details = Application::where('name', $appname)->firstOrFail();
|
||||
$appclass = $app_details->class();
|
||||
$app = new $appclass;
|
||||
|
||||
// live details
|
||||
if($app_details instanceof \App\SupportedApps\Contracts\Livestats) {
|
||||
$output['config'] = $app_details->configDetails();
|
||||
} else {
|
||||
$output['config'] = null;
|
||||
}
|
||||
// basic details
|
||||
$output['icon'] = $app_details->icon();
|
||||
$output['name'] = $app_details->name;
|
||||
$output['iconview'] = $app_details->iconView();
|
||||
$output['colour'] = $app_details->defaultColour();
|
||||
$output['class'] = $appclass;
|
||||
|
||||
// live details
|
||||
if($app instanceof \App\EnhancedApps) {
|
||||
$output['config'] = className($app_details->name).'.config';
|
||||
} else {
|
||||
$output['config'] = null;
|
||||
}
|
||||
|
||||
return json_encode($output);
|
||||
@@ -294,25 +330,34 @@ class ItemController extends Controller
|
||||
|
||||
$app_details = new $app();
|
||||
$app_details->config = (object)$data;
|
||||
$app_details->testConfig();
|
||||
$app_details->test();
|
||||
}
|
||||
|
||||
public function getStats($id)
|
||||
{
|
||||
$item = Item::find($id);
|
||||
|
||||
$config = json_decode($item->description);
|
||||
if(isset($config->type)) {
|
||||
$config->url = $item->url;
|
||||
if(isset($config->override_url) && !empty($config->override_url)) {
|
||||
$config->url = $config->override_url;
|
||||
}
|
||||
$app_details = new $config->type;
|
||||
$app_details->config = $config;
|
||||
echo $app_details->executeConfig();
|
||||
$config = $item->getconfig();
|
||||
if(isset($item->class)) {
|
||||
$application = new $item->class;
|
||||
$application->config = $config;
|
||||
echo $application->livestats();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function checkAppList()
|
||||
{
|
||||
ProcessApps::dispatch();
|
||||
$route = route('items.index');
|
||||
return redirect($route)
|
||||
->with('success', __('app.alert.success.updating'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,17 @@ namespace App\Http\Controllers;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Setting;
|
||||
use App\SettingGroup;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
@@ -31,6 +38,7 @@ class SettingsController extends Controller
|
||||
public function edit($id)
|
||||
{
|
||||
$setting = Setting::find($id);
|
||||
//die("s: ".$setting->label);
|
||||
|
||||
if((bool)$setting->system === true) return abort(404);
|
||||
|
||||
@@ -39,7 +47,9 @@ class SettingsController extends Controller
|
||||
'setting' => $setting,
|
||||
]);
|
||||
} else {
|
||||
return redirect()->route('settings.list')->with([
|
||||
$route = route('settings.list', [], false);
|
||||
return redirect($route)
|
||||
->with([
|
||||
'error' => __('app.alert.error.not_exist'),
|
||||
]);
|
||||
}
|
||||
@@ -53,31 +63,37 @@ class SettingsController extends Controller
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$setting = Setting::find($id);
|
||||
$user = $this->user();
|
||||
|
||||
if (!is_null($setting)) {
|
||||
$data = Setting::getInput();
|
||||
|
||||
$setting_value = null;
|
||||
|
||||
if ($setting->type == 'image') {
|
||||
|
||||
|
||||
if($request->hasFile('value')) {
|
||||
$path = $request->file('value')->store('backgrounds');
|
||||
$setting->value = $path;
|
||||
$setting_value = $path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} else {
|
||||
$setting->value = $data->value;
|
||||
$setting_value = $data->value;
|
||||
}
|
||||
|
||||
$setting->save();
|
||||
|
||||
return redirect()->route('settings.index')->with([
|
||||
$user->settings()->detach($setting->id);
|
||||
$user->settings()->save($setting, ['uservalue' => $setting_value]);
|
||||
|
||||
$route = route('settings.index', [], false);
|
||||
return redirect($route)
|
||||
->with([
|
||||
'success' => __('app.alert.success.setting_updated'),
|
||||
]);
|
||||
} else {
|
||||
return redirect()->route('settings.index')->with([
|
||||
$route = route('settings.index', [], false);
|
||||
return redirect($route)
|
||||
->with([
|
||||
'error' => __('app.alert.error.not_exist'),
|
||||
]);
|
||||
}
|
||||
@@ -89,12 +105,15 @@ class SettingsController extends Controller
|
||||
*/
|
||||
public function clear($id)
|
||||
{
|
||||
$user = $this->user();
|
||||
$setting = Setting::find($id);
|
||||
if((bool)$setting->system !== true) {
|
||||
$setting->value = '';
|
||||
$setting->save();
|
||||
$user->settings()->detach($setting->id);
|
||||
$user->settings()->save($setting, ['uservalue' => '']);
|
||||
}
|
||||
return redirect()->route('settings.index')->with([
|
||||
$route = route('settings.index', [], false);
|
||||
return redirect($route)
|
||||
->with([
|
||||
'success' => __('app.alert.success.setting_updated'),
|
||||
]);
|
||||
|
||||
|
||||
201
app/Http/Controllers/TagController.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Item;
|
||||
use App\User;
|
||||
use DB;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
$trash = (bool)$request->input('trash');
|
||||
|
||||
$data['apps'] = Item::ofType('tag')->orderBy('title', 'asc')->get();
|
||||
$data['trash'] = Item::ofType('tag')->onlyTrashed()->get();
|
||||
if($trash) {
|
||||
return view('tags.trash', $data);
|
||||
} else {
|
||||
return view('tags.list', $data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$data = [];
|
||||
return view('tags.create', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
]);
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
$path = $request->file('file')->store('icons');
|
||||
$request->merge([
|
||||
'icon' => $path
|
||||
]);
|
||||
}
|
||||
|
||||
$slug = str_slug($request->title, '-');
|
||||
|
||||
$current_user = User::currentUser();
|
||||
|
||||
// set item type to tag
|
||||
$request->merge([
|
||||
'type' => '1',
|
||||
'url' => $slug,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
//die(print_r($request->all()));
|
||||
Item::create($request->all());
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success', __('app.alert.success.tag_created'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($slug)
|
||||
{
|
||||
$item = Item::whereUrl($slug)->first();
|
||||
//print_r($item);
|
||||
$data['apps'] = $item->children()->pinned()->orderBy('order', 'asc')->get();
|
||||
$data['all_apps'] = $item->children;
|
||||
return view('welcome', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
// Get the item
|
||||
$item = Item::find($id);
|
||||
|
||||
// show the edit form and pass the nerd
|
||||
return view('tags.edit')
|
||||
->with('item', $item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
]);
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
$path = $request->file('file')->store('icons');
|
||||
$request->merge([
|
||||
'icon' => $path
|
||||
]);
|
||||
}
|
||||
|
||||
$slug = str_slug($request->title, '-');
|
||||
// set item type to tag
|
||||
$request->merge([
|
||||
'url' => $slug
|
||||
]);
|
||||
|
||||
Item::find($id)->update($request->all());
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.tag_updated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(Request $request, $id)
|
||||
{
|
||||
//
|
||||
$force = (bool)$request->input('force');
|
||||
if($force) {
|
||||
Item::withTrashed()
|
||||
->where('id', $id)
|
||||
->forceDelete();
|
||||
} else {
|
||||
Item::find($id)->delete();
|
||||
}
|
||||
|
||||
$route = route('tags.index', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.item_deleted'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the specified resource from soft deletion.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function restore($id)
|
||||
{
|
||||
//
|
||||
Item::withTrashed()
|
||||
->where('id', $id)
|
||||
->restore();
|
||||
$route = route('tags.index', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.item_restored'));
|
||||
}
|
||||
|
||||
public function add($tag, $item)
|
||||
{
|
||||
$output = 0;
|
||||
$tag = Item::find($tag);
|
||||
$item = Item::find($item);
|
||||
if($tag && $item) {
|
||||
// only add items, not cats
|
||||
if((int)$item->type === 0) {
|
||||
$tag->children()->attach($item);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
175
app/Http/Controllers/UserController.php
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\User;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed')->except(['selectUser']);
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$data['users'] = User::all();
|
||||
return view('users.index', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$data = [];
|
||||
return view('users.create', $data);
|
||||
}
|
||||
|
||||
public function selectUser()
|
||||
{
|
||||
Auth::logout();
|
||||
$data['users'] = User::all();
|
||||
return view('userselect', $data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'username' => 'required|max:255|unique:users',
|
||||
'email' => 'required|email',
|
||||
'password' => 'nullable|confirmed',
|
||||
'password_confirmation' => 'nullable'
|
||||
|
||||
]);
|
||||
$user = new User;
|
||||
$user->username = $request->input('username');
|
||||
$user->email = $request->input('email');
|
||||
$user->public_front = $request->input('public_front');
|
||||
|
||||
$password = $request->input('password');
|
||||
if(!empty($password)) {
|
||||
$user->password = bcrypt($password);
|
||||
}
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
$path = $request->file('file')->store('avatars');
|
||||
$user->avatar = $path;
|
||||
}
|
||||
|
||||
if ((bool)$request->input('autologin_allow') === true) {
|
||||
$user->autologin = (string)Str::uuid();
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.user_updated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(User $user)
|
||||
{
|
||||
$data['user'] = $user;
|
||||
return view('users.edit', $data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, User $user)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'username' => 'required|max:255|unique:users,username,'.$user->id,
|
||||
'email' => 'required|email',
|
||||
'password' => 'nullable|confirmed',
|
||||
'password_confirmation' => 'nullable'
|
||||
]);
|
||||
//die(print_r($request->all()));
|
||||
|
||||
$user->username = $request->input('username');
|
||||
$user->email = $request->input('email');
|
||||
$user->public_front = $request->input('public_front');
|
||||
|
||||
$password = $request->input('password');
|
||||
if(!empty($password)) {
|
||||
$user->password = bcrypt($password);
|
||||
} elseif($password == 'null') {
|
||||
$user->password = null;
|
||||
}
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
$path = $request->file('file')->store('avatars');
|
||||
$user->avatar = $path;
|
||||
}
|
||||
|
||||
if ((bool)$request->input('autologin_allow') === true) {
|
||||
$user->autologin = (is_null($user->autologin)) ? (string)Str::uuid() : $user->autologin;
|
||||
} else {
|
||||
$user->autologin = null;
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.user_updated'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(User $user)
|
||||
{
|
||||
if($user->id !== 1) {
|
||||
$user->delete();
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.user_deleted'));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ class Kernel extends HttpKernel
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'allowed' => \App\Http\Middleware\CheckAllowed::class,
|
||||
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
|
||||
48
app/Http/Middleware/CheckAllowed.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Session;
|
||||
|
||||
class CheckAllowed
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$route = Route::currentRouteName();
|
||||
$current_user = User::currentUser();
|
||||
|
||||
if(str_is('users*', $route)) {
|
||||
if($current_user->id !== 1) {
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
}
|
||||
|
||||
if($route == 'dash') {
|
||||
//print_r(User::all());
|
||||
//die("here".var_dump($current_user->password));
|
||||
if((bool)$current_user->public_front === true) return $next($request);
|
||||
}
|
||||
|
||||
if(empty($current_user->password)) return $next($request);
|
||||
|
||||
// Check if user is logged in as $current_user
|
||||
if (Auth::check()) {
|
||||
$loggedin_user = Auth::user();
|
||||
if($loggedin_user->id === $current_user->id) return $next($request);
|
||||
}
|
||||
|
||||
return Auth::authenticate();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ class RedirectIfAuthenticated
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect('/home');
|
||||
return redirect()->intended();
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
@@ -19,11 +19,5 @@ class TrustProxies extends Middleware
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = [
|
||||
Request::HEADER_FORWARDED => 'FORWARDED',
|
||||
Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
|
||||
Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
|
||||
Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
|
||||
Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
|
||||
];
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
}
|
||||
|
||||
204
app/Item.php
@@ -5,15 +5,26 @@ namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Symfony\Component\ClassLoader\ClassMapGenerator;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\User;
|
||||
|
||||
class Item extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::addGlobalScope('user_id', function (Builder $builder) {
|
||||
$current_user = User::currentUser();
|
||||
$builder->where('user_id', $current_user->id);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
protected $fillable = [
|
||||
'title', 'url', 'colour', 'icon', 'description', 'pinned', 'order'
|
||||
'title', 'url', 'colour', 'icon', 'description', 'pinned', 'order', 'type', 'class', 'user_id'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -23,32 +34,6 @@ class Item extends Model
|
||||
*/
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
public static function supportedList()
|
||||
{
|
||||
return [
|
||||
'Duplicati' => \App\SupportedApps\Duplicati::class,
|
||||
'Emby' => \App\SupportedApps\Emby::class,
|
||||
'Jdownloader' => \App\SupportedApps\Jdownloader::class,
|
||||
'Mcmyadmin' => \App\SupportedApps\Mcmyadmin::class,
|
||||
'NZBGet' => \App\SupportedApps\Nzbget::class,
|
||||
'Nextcloud' => \App\SupportedApps\Nextcloud::class,
|
||||
'Openhab' => \App\SupportedApps\Openhab::class,
|
||||
'Pihole' => \App\SupportedApps\Pihole::class,
|
||||
'Plex' => \App\SupportedApps\Plex::class,
|
||||
'Plexpy' => \App\SupportedApps\Plexpy::class,
|
||||
'Plexrequests' => \App\SupportedApps\Plexrequests::class,
|
||||
'Portainer' => \App\SupportedApps\Portainer::class,
|
||||
'Sabnzbd' => \App\SupportedApps\Sabnzbd::class,
|
||||
'Traefik' => \App\SupportedApps\Traefik::class,
|
||||
'UniFi' => \App\SupportedApps\Unifi::class,
|
||||
'pFsense' => \App\SupportedApps\Pfsense::class,
|
||||
];
|
||||
}
|
||||
public static function supportedOptions()
|
||||
{
|
||||
return array_keys(self::supportedList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include pinned items.
|
||||
*
|
||||
@@ -60,24 +45,6 @@ class Item extends Model
|
||||
return $query->where('pinned', 1);
|
||||
}
|
||||
|
||||
public function getConfigAttribute()
|
||||
{
|
||||
$output = null;
|
||||
$view = null;
|
||||
if(isset($this->description) && !empty($this->description)){
|
||||
$output = json_decode($this->description);
|
||||
$output = is_object($output) ? $output : new \stdClass();
|
||||
if(isset($output->type) && !empty($output->type)) {
|
||||
$class = $output->type;
|
||||
$sap = new $class();
|
||||
$view = $sap->configDetails();
|
||||
$output->view = $view;
|
||||
}
|
||||
if(!isset($output->dataonly)) $output->dataonly = '0';
|
||||
|
||||
}
|
||||
return (object)$output;
|
||||
}
|
||||
public static function checkConfig($config)
|
||||
{
|
||||
if(empty($config)) {
|
||||
@@ -94,11 +61,154 @@ class Item extends Model
|
||||
}
|
||||
}
|
||||
//die(var_dump($store))
|
||||
|
||||
|
||||
$config['enabled'] = ($store) ? true : false;
|
||||
$config = json_encode($config);
|
||||
}
|
||||
return $config;
|
||||
|
||||
}
|
||||
|
||||
public function parents()
|
||||
{
|
||||
return $this->belongsToMany('App\Item', 'item_tag', 'item_id', 'tag_id');
|
||||
}
|
||||
public function children()
|
||||
{
|
||||
return $this->belongsToMany('App\Item', 'item_tag', 'tag_id', 'item_id');
|
||||
}
|
||||
|
||||
public function getLinkAttribute()
|
||||
{
|
||||
if((int)$this->type === 1) {
|
||||
return '/tag/'.$this->url;
|
||||
} else {
|
||||
return $this->url;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDroppableAttribute()
|
||||
{
|
||||
if((int)$this->type === 1) {
|
||||
return ' droppable';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
public function getLinkTargetAttribute()
|
||||
{
|
||||
$target = Setting::fetch('window_target');
|
||||
|
||||
if((int)$this->type === 1 || $target === 'current') {
|
||||
return '';
|
||||
} else {
|
||||
return ' target="' . $target . '"';
|
||||
}
|
||||
}
|
||||
|
||||
public function getLinkIconAttribute()
|
||||
{
|
||||
if((int)$this->type === 1) {
|
||||
return 'fa-tag';
|
||||
} else {
|
||||
return 'fa-arrow-alt-to-right';
|
||||
}
|
||||
}
|
||||
public function getLinkTypeAttribute()
|
||||
{
|
||||
if((int)$this->type === 1) {
|
||||
return 'tags';
|
||||
} else {
|
||||
return 'items';
|
||||
}
|
||||
}
|
||||
|
||||
public static function nameFromClass($class)
|
||||
{
|
||||
$explode = explode('\\', $class);
|
||||
$name = end($explode);
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
public function scopeOfType($query, $type)
|
||||
{
|
||||
switch($type) {
|
||||
case 'item':
|
||||
$typeid = 0;
|
||||
break;
|
||||
case 'tag':
|
||||
$typeid = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return $query->where('type', $typeid);
|
||||
}
|
||||
|
||||
public function enhanced()
|
||||
{
|
||||
if(isset($this->class) && !empty($this->class)) {
|
||||
$app = new $this->class;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (bool)($app instanceof \App\EnhancedApps);
|
||||
}
|
||||
|
||||
public static function isEnhanced($class)
|
||||
{
|
||||
$app = new $class;
|
||||
return (bool)($app instanceof \App\EnhancedApps);
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
if($this->enhanced()) {
|
||||
$config = $this->getconfig();
|
||||
if($config) {
|
||||
return (bool) $config->enabled;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getconfig()
|
||||
{
|
||||
$explode = explode('\\', $this->class);
|
||||
|
||||
|
||||
if(!isset($this->description) || empty($this->description)) {
|
||||
$config = new \stdClass;
|
||||
$config->name = end($explode);
|
||||
$config->enabled = false;
|
||||
return $config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$config = json_decode($this->description);
|
||||
|
||||
$config->name = end($explode);
|
||||
|
||||
|
||||
$config->url = $this->url;
|
||||
if(isset($config->override_url) && !empty($config->override_url)) {
|
||||
$config->url = $config->override_url;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the user that owns the item.
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\User');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
66
app/Jobs/ProcessApps.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Application;
|
||||
use App\SupportedApps;
|
||||
|
||||
class ProcessApps implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$localapps = Application::all();
|
||||
$list = json_decode(SupportedApps::getList()->getBody());
|
||||
$validapps = [];
|
||||
|
||||
foreach($list->apps as $app) {
|
||||
$validapps[] = $app->appid;
|
||||
$localapp = $localapps->where('appid', $app->appid)->first();
|
||||
|
||||
$application = ($localapp) ? $localapp : new Application;
|
||||
|
||||
if(!file_exists(app_path('SupportedApps/'.className($app->name)))) {
|
||||
SupportedApps::getFiles($app);
|
||||
SupportedApps::saveApp($app, $application);
|
||||
} else {
|
||||
// check if there has been an update for this app
|
||||
$localapp = $localapps->where('appid', $app->appid)->first();
|
||||
if($localapp) {
|
||||
if($localapp->sha !== $app->sha) {
|
||||
SupportedApps::getFiles($app);
|
||||
SupportedApps::saveApp($app, $application);
|
||||
}
|
||||
} else {
|
||||
SupportedApps::getFiles($app);
|
||||
SupportedApps::saveApp($app, $application);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//$delete = Application::whereNotIn('appid', $validapps)->delete(); // delete any apps not in list
|
||||
// removed the delete so local apps can be added
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ use Illuminate\Support\ServiceProvider;
|
||||
use Artisan;
|
||||
use Schema;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
use App\Application;
|
||||
use App\Jobs\ProcessApps;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -16,7 +19,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$alt_bg = '';
|
||||
|
||||
if(!is_file(base_path('.env'))) {
|
||||
touch(base_path('.env'));
|
||||
@@ -32,27 +34,86 @@ class AppServiceProvider extends ServiceProvider
|
||||
}
|
||||
if(is_file(database_path('app.sqlite'))) {
|
||||
if(Schema::hasTable('settings')) {
|
||||
if($bg_image = Setting::fetch('background_image')) {
|
||||
$alt_bg = ' style="background-image: url('.asset('storage/'.$bg_image).')"';
|
||||
}
|
||||
|
||||
// check version to see if an upgrade is needed
|
||||
$db_version = Setting::fetch('version');
|
||||
$db_version = Setting::_fetch('version');
|
||||
$app_version = config('app.version');
|
||||
if(version_compare($app_version, $db_version) == 1) { // app is higher than db, so need to run migrations etc
|
||||
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
|
||||
}
|
||||
|
||||
} else {
|
||||
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!is_file(public_path('storage'))) {
|
||||
Artisan::call('storage:link');
|
||||
\Session::put('current_user', null);
|
||||
}
|
||||
|
||||
$applications = Application::all();
|
||||
if($applications->count() <= 0) {
|
||||
if (class_exists('ZipArchive')) {
|
||||
ProcessApps::dispatch();
|
||||
} else {
|
||||
die("You are missing php-zip");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// User specific settings need to go here as session isn't available at this point in the app
|
||||
view()->composer('*', function ($view)
|
||||
{
|
||||
|
||||
if(isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
|
||||
explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
|
||||
}
|
||||
if(!\Auth::check()) {
|
||||
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
|
||||
$credentials = ['username' => $_SERVER['PHP_AUTH_USER'], 'password' => $_SERVER['PHP_AUTH_PW']];
|
||||
|
||||
if (\Auth::attempt($credentials)) {
|
||||
// Authentication passed...
|
||||
$user = \Auth::user();
|
||||
//\Session::put('current_user', $user);
|
||||
session(['current_user' => $user]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$alt_bg = '';
|
||||
if($bg_image = Setting::fetch('background_image')) {
|
||||
$alt_bg = ' style="background-image: url(/storage/'.$bg_image.')"';
|
||||
}
|
||||
$lang = Setting::fetch('language');
|
||||
\App::setLocale($lang);
|
||||
|
||||
$allusers = User::all();
|
||||
$current_user = User::currentUser();
|
||||
|
||||
$view->with('alt_bg', $alt_bg );
|
||||
$view->with('allusers', $allusers );
|
||||
$view->with('current_user', $current_user );
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
$this->app['view']->addNamespace('SupportedApps', app_path('SupportedApps'));
|
||||
|
||||
|
||||
if (env('FORCE_HTTPS') === true) {
|
||||
\URL::forceScheme('https');
|
||||
}
|
||||
if(!is_file(public_path('storage'))) {
|
||||
Artisan::call('storage:link');
|
||||
|
||||
if(env('APP_URL') != 'http://localhost') {
|
||||
\URL::forceRootUrl(env('APP_URL'));
|
||||
}
|
||||
view()->share('alt_bg', $alt_bg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Form;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class Setting extends Model
|
||||
{
|
||||
@@ -46,6 +48,12 @@ class Setting extends Model
|
||||
|
||||
public function getListValueAttribute()
|
||||
{
|
||||
if((bool)$this->system === true) {
|
||||
$value = self::_fetch($this->key);
|
||||
} else {
|
||||
$value = self::fetch($this->key);
|
||||
}
|
||||
$this->value = $value;
|
||||
switch($this->type) {
|
||||
case 'image':
|
||||
if(!empty($this->value)) {
|
||||
@@ -80,6 +88,12 @@ class Setting extends Model
|
||||
|
||||
public function getEditValueAttribute()
|
||||
{
|
||||
if((bool)$this->system === true) {
|
||||
$value = self::_fetch($this->key);
|
||||
} else {
|
||||
$value = self::fetch($this->key);
|
||||
}
|
||||
$this->value = $value;
|
||||
switch($this->type) {
|
||||
case 'image':
|
||||
$value = '';
|
||||
@@ -125,6 +139,7 @@ class Setting extends Model
|
||||
return $this->belongsTo('App\SettingGroup', 'group_id');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
@@ -132,20 +147,54 @@ class Setting extends Model
|
||||
*/
|
||||
public static function fetch($key)
|
||||
{
|
||||
if (Setting::cached($key)) {
|
||||
return Setting::$cache[$key];
|
||||
} else {
|
||||
$user = self::user();
|
||||
return self::_fetch($key, $user);
|
||||
}
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function _fetch($key, $user=null)
|
||||
{
|
||||
#$cachekey = ($user === null) ? $key : $key.'-'.$user->id;
|
||||
#if (Setting::cached($cachekey)) {
|
||||
# return Setting::$cache[$cachekey];
|
||||
#} else {
|
||||
$find = self::where('key', '=', $key)->first();
|
||||
|
||||
if (!is_null($find)) {
|
||||
$value = $find->value;
|
||||
Setting::add($key, $value);
|
||||
if((bool)$find->system === true) { // if system variable use global value
|
||||
$value = $find->value;
|
||||
} else { // not system variable so use user specific value
|
||||
// check if user specified value has been set
|
||||
//print_r($user);
|
||||
$usersetting = $user->settings()->where('id', $find->id)->first();
|
||||
//print_r($user->settings);
|
||||
//die(var_dump($usersetting));
|
||||
//->pivot->value;
|
||||
//echo "user: ".$user->id." --- ".$usersettings;
|
||||
if(isset($usersetting) && !empty($usersetting)) {
|
||||
$value = $usersetting->pivot->uservalue;
|
||||
} else { // if not get default from base setting
|
||||
//$user->settings()->save($find, ['value' => $find->value]);
|
||||
#$has_setting = $user->settings()->where('id', $find->id)->exists();
|
||||
#if($has_setting) {
|
||||
# $user->settings()->updateExistingPivot($find->id, ['uservalue' => (string)$find->value]);
|
||||
#} else {
|
||||
# $user->settings()->save($find, ['uservalue' => (string)$find->value]);
|
||||
#}
|
||||
$value = $find->value;
|
||||
}
|
||||
|
||||
}
|
||||
#Setting::add($cachekey, $value);
|
||||
|
||||
return $value;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,21 +224,23 @@ class Setting extends Model
|
||||
$output = '';
|
||||
$homepage_search = self::fetch('homepage_search');
|
||||
$search_provider = self::where('key', '=', 'search_provider')->first();
|
||||
|
||||
//die(var_dump($search_provider->value));
|
||||
$user_search_provider = self::fetch('search_provider');
|
||||
//die(print_r($search_provider));
|
||||
|
||||
//die(var_dump($user_search_provider));
|
||||
// return early if search isn't applicable
|
||||
if((bool)$homepage_search !== true) return $output;
|
||||
if($search_provider->value === 'none') return $output;
|
||||
if(empty($search_provider->value)) return $output;
|
||||
if(is_null($search_provider->value)) return $output;
|
||||
if($user_search_provider === 'none') return $output;
|
||||
if(empty($user_search_provider)) return $output;
|
||||
if(is_null($user_search_provider)) return $output;
|
||||
|
||||
|
||||
if((bool)$homepage_search && (bool)$search_provider) {
|
||||
|
||||
$options = (array)json_decode($search_provider->options);
|
||||
$name = $options[$search_provider->value];
|
||||
if((bool)$search_provider->value) {
|
||||
switch($search_provider->value) {
|
||||
$name = $options[$user_search_provider];
|
||||
if((bool)$user_search_provider) {
|
||||
switch($user_search_provider) {
|
||||
case 'google':
|
||||
$url = 'https://www.google.com/search';
|
||||
$var = 'q';
|
||||
@@ -202,11 +253,14 @@ class Setting extends Model
|
||||
$url = 'https://www.bing.com/search';
|
||||
$var = 'q';
|
||||
break;
|
||||
case 'startpage':
|
||||
$url = 'https://www.startpage.com/';
|
||||
$var = 'q';
|
||||
}
|
||||
$output .= '<div class="searchform">';
|
||||
$output .= Form::open(['url' => $url, 'method' => 'get']);
|
||||
$output .= '<div class="input-container">';
|
||||
$output .= Form::text($var, null, ['class' => 'homesearch', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
|
||||
$output .= Form::text($var, null, ['class' => 'homesearch', 'autofocus' => 'autofocus', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
|
||||
$output .= '<button type="submit">'.ucwords(__('app.settings.search')).'</button>';
|
||||
$output .= '</div>';
|
||||
$output .= Form::close();
|
||||
@@ -215,4 +269,19 @@ class Setting extends Model
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* The users that belong to the setting.
|
||||
*/
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany('App\User')->using('App\SettingUser')->withPivot('uservalue');
|
||||
}
|
||||
|
||||
public static function user()
|
||||
{
|
||||
return User::currentUser();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
10
app/SettingUser.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
class SettingUser extends Pivot
|
||||
{
|
||||
//
|
||||
}
|
||||
172
app/SupportedApps.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php namespace App;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
abstract class SupportedApps
|
||||
{
|
||||
|
||||
protected $jar = false;
|
||||
protected $method = 'GET';
|
||||
protected $error;
|
||||
|
||||
public function appTest($url, $attrs = [], $overridevars=false)
|
||||
{
|
||||
if(empty($this->config->url)) {
|
||||
return (object)[
|
||||
'code' => 404,
|
||||
'status' => 'No URL has been specified',
|
||||
'response' => 'No URL has been specified',
|
||||
];
|
||||
}
|
||||
$res = $this->execute($url, $attrs);
|
||||
if($res == null) {
|
||||
return (object)[
|
||||
'code' => null,
|
||||
'status' => $this->error,
|
||||
'response' => 'Connection failed',
|
||||
];
|
||||
}
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$status = 'Successfully communicated with the API';
|
||||
break;
|
||||
case 401:
|
||||
$status = 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
$status = 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
$status = 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
return (object)[
|
||||
'code' => $res->getStatusCode(),
|
||||
'status' => $status,
|
||||
'response' => $res->getBody(),
|
||||
];
|
||||
}
|
||||
|
||||
public function execute($url, $attrs = [], $overridevars=false, $overridemethod=false)
|
||||
{
|
||||
$res = null;
|
||||
|
||||
$vars = ($overridevars !== false) ?
|
||||
$overridevars : [
|
||||
'http_errors' => false,
|
||||
'timeout' => 15,
|
||||
'connect_timeout' => 15,
|
||||
];
|
||||
|
||||
$client = new Client($vars);
|
||||
|
||||
$method = ($overridemethod !== false) ? $overridemethod : $this->method;
|
||||
|
||||
try {
|
||||
return $client->request($method, $url, $attrs);
|
||||
} catch (\GuzzleHttp\Exception\ConnectException $e) {
|
||||
Log::error("Connection refused");
|
||||
Log::debug($e->getMessage());
|
||||
$this->error = "Connection refused - ".(string) $e->getMessage();
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
Log::debug($e->getMessage());
|
||||
$this->error = (string) $e->getResponse()->getBody();
|
||||
}
|
||||
$this->error = 'General error connecting with API';
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function login()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function normaliseurl($url, $addslash=true)
|
||||
{
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
if($addslash) $url .= '/';
|
||||
|
||||
return $url;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getLiveStats($status, $data)
|
||||
{
|
||||
$className = get_class($this);
|
||||
$explode = explode('\\', $className);
|
||||
$name = end($explode);
|
||||
|
||||
$html = view('SupportedApps::'.$name.'.livestats', $data)->with('data', $data)->render();
|
||||
return json_encode(['status' => $status, 'html' => $html]);
|
||||
//return
|
||||
}
|
||||
|
||||
public static function getList()
|
||||
{
|
||||
$list_url = 'https://apps.heimdall.site/list';
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
return $client->request('GET', $list_url);
|
||||
}
|
||||
|
||||
public static function configValue($item=null, $key=null)
|
||||
{
|
||||
if(isset($item) && !empty($item)) {
|
||||
return $item->getconfig()->$key;
|
||||
} else return null;
|
||||
}
|
||||
|
||||
public static function getFiles($app)
|
||||
{
|
||||
$zipurl = $app->files;
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 60, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $zipurl);
|
||||
|
||||
if(!file_exists(app_path('SupportedApps'))) {
|
||||
mkdir(app_path('SupportedApps'), 0777, true);
|
||||
}
|
||||
|
||||
$src = app_path('SupportedApps/'.className($app->name).'.zip');
|
||||
file_put_contents($src, $res->getBody());
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
$x = $zip->open($src); // open the zip file to extract
|
||||
if ($x === true) {
|
||||
$zip->extractTo(app_path('SupportedApps')); // place in the directory with same name
|
||||
$zip->close();
|
||||
unlink($src); //Deleting the Zipped file
|
||||
}
|
||||
}
|
||||
|
||||
public static function saveApp($details, $app)
|
||||
{
|
||||
if(!file_exists(storage_path('app/public/icons'))) {
|
||||
mkdir(storage_path('app/public/icons'), 0777, true);
|
||||
}
|
||||
|
||||
$img_src = app_path('SupportedApps/'.className($details->name).'/'.$details->icon);
|
||||
$img_dest = storage_path('app/public/icons/'.$details->icon);
|
||||
//die("i: ".$img_src);
|
||||
@copy($img_src, $img_dest);
|
||||
|
||||
$app->appid = $details->appid;
|
||||
$app->name = $details->name;
|
||||
$app->sha = $details->sha ?? null;
|
||||
$app->icon = 'icons/'.$details->icon;
|
||||
$app->website = $details->website;
|
||||
$app->license = $details->license;
|
||||
$app->description = $details->description;
|
||||
|
||||
$appclass = $app->class();
|
||||
$application = new $appclass;
|
||||
$enhanced = (bool)($application instanceof \App\EnhancedApps);
|
||||
|
||||
$app->enhanced = $enhanced;
|
||||
$app->tile_background = $details->tile_background;
|
||||
$app->save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php namespace App\SupportedApps\Contracts;
|
||||
|
||||
interface Applications {
|
||||
|
||||
public function defaultColour();
|
||||
|
||||
public function icon();
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps\Contracts;
|
||||
|
||||
interface Livestats {
|
||||
|
||||
public function configDetails();
|
||||
|
||||
public function testConfig();
|
||||
|
||||
public function executeConfig();
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Duplicati implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2c3744';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/duplicati.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Emby implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/emby.png';
|
||||
}
|
||||
}
|
||||
5
app/SupportedApps/Ghost/Ghost.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\Ghost;
|
||||
|
||||
class Ghost extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/Ghost/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "c4745785181de931cfd5bd79294cb1687d82aea9",
|
||||
"name": "Ghost",
|
||||
"website": "https://github.com/tryghost/ghost",
|
||||
"license": "MIT License",
|
||||
"description": "Fiercely independent, professional publishing. A fully open source, powerful platform for building and running modern publications, we power serious blogs, magazines and journalism from DuckDuckGo to OpenAI & Sky News.",
|
||||
"enhanced": false,
|
||||
"tile_background": "light",
|
||||
"icon": "ghost.png"
|
||||
}
|
||||
BIN
app/SupportedApps/Ghost/ghost.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Jdownloader implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2b494f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/jdownloader.png';
|
||||
}
|
||||
}
|
||||
5
app/SupportedApps/MailcowSOGo/MailcowSOGo.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\MailcowSOGo;
|
||||
|
||||
class MailcowSOGo extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/MailcowSOGo/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "1ec48781d2c87a9e6dc9ee99e5eff0ab5958df09",
|
||||
"name": "Mailcow - SOGo",
|
||||
"website": "https://sogo.nu/",
|
||||
"license": "GNU GPL/LGPL v2 and above",
|
||||
"description": "SOGo is a fully supported and trusted groupware server with a focus on scalability and open standards.\r\n\r\nPart of the Mailcow stack.",
|
||||
"enhanced": false,
|
||||
"tile_background": "dark",
|
||||
"icon": "mailcowsogo.svg"
|
||||
}
|
||||
3
app/SupportedApps/MailcowSOGo/mailcowsogo.svg
Normal file
|
After Width: | Height: | Size: 10 KiB |
5
app/SupportedApps/Mattermost/Mattermost.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\Mattermost;
|
||||
|
||||
class Mattermost extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/Mattermost/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "b3e1424fb69ca08481b03ad9d81e95488421997f",
|
||||
"name": "Mattermost",
|
||||
"website": "https://mattermost.com/",
|
||||
"license": "MIT License",
|
||||
"description": "Mattermost provides high trust collaboration and messaging solutions through an open source, community-powered approach. Enjoy all the productivity benefits of workplace messaging across web, mobile and PC, with unlimited archiving, search and integrations within IT-controlled private environments in public clouds, including AWS and Azure, as well as on-premise in private clouds and virtual or physical servers.",
|
||||
"enhanced": false,
|
||||
"tile_background": "light",
|
||||
"icon": "mattermost.png"
|
||||
}
|
||||
BIN
app/SupportedApps/Mattermost/mattermost.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
5
app/SupportedApps/MayanEDMS/MayanEDMS.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\MayanEDMS;
|
||||
|
||||
class MayanEDMS extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/MayanEDMS/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "6b9e062ff02ea610df64e9b0eca1c973faf1b51d",
|
||||
"name": "Mayan EDMS",
|
||||
"website": "https://github.com/tryghost/ghost",
|
||||
"license": "Apache License 2.0",
|
||||
"description": "Mayan EDMS is an open-source document management system. Its main purpose is to store, introspect, and categorize files, with a strong emphasis on preserving the contextual and business information of documents. It can also OCR, preview, label, sign, send, and receive thoses files. Other features of interest are its workflow system, role based access control, and REST API.",
|
||||
"enhanced": false,
|
||||
"tile_background": "light",
|
||||
"icon": "mayanedms.png"
|
||||
}
|
||||
BIN
app/SupportedApps/MayanEDMS/mayanedms.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Mcmyadmin implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#30404b';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/mcmyadmin.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Nextcloud implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#0e2c3e';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nextcloud.png';
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Nzbget implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#253827';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nzbget.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'nzbget';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('status');
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo 'Successfully connected to the API';
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function executeConfig()
|
||||
{
|
||||
$output = '';
|
||||
$res = $this->buildRequest('status');
|
||||
$data = json_decode($res->getBody());
|
||||
//$data->result->RemainingSizeMB = '10000000';
|
||||
//$data->result->DownloadRate = '100000000';
|
||||
$size = $data->result->RemainingSizeMB;
|
||||
$rate = $data->result->DownloadRate;
|
||||
$queue_size = format_bytes($size*1000*1000, false, ' <span>', '</span>');
|
||||
$current_speed = format_bytes($rate, false, ' <span>');
|
||||
|
||||
if($size > 0 || $rate > 0) {
|
||||
$output = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Queue</span><strong>'.$queue_size.'</strong></li>
|
||||
<li><span class="title">Speed</span><strong>'.$current_speed.'/s</span></strong></li>
|
||||
</ul>
|
||||
';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$username = $config->username;
|
||||
$password = $config->password;
|
||||
|
||||
$rebuild_url = str_replace('http://', 'http://'.$username.':'.$password.'@', $url);
|
||||
$rebuild_url = str_replace('https://', 'https://'.$username.':'.$password.'@', $rebuild_url);
|
||||
|
||||
$api_url = $rebuild_url.'jsonrpc/'.$endpoint;
|
||||
|
||||
$client = new Client(['http_errors' => false]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
45
app/SupportedApps/Nzbget/Nzbget.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php namespace App\SupportedApps\Nzbget;
|
||||
|
||||
class Nzbget extends \App\SupportedApps implements \App\EnhancedApps {
|
||||
|
||||
public $config;
|
||||
|
||||
public function test()
|
||||
{
|
||||
$test = parent::appTest($this->url('status'));
|
||||
echo $test->status;
|
||||
}
|
||||
|
||||
public function livestats()
|
||||
{
|
||||
$status = 'inactive';
|
||||
$res = parent::execute($this->url('status'));
|
||||
$details = json_decode($res->getBody());
|
||||
|
||||
$data = [];
|
||||
|
||||
if($details) {
|
||||
$size = $details->result->RemainingSizeMB;
|
||||
$rate = $details->result->DownloadRate;
|
||||
$data['queue_size'] = format_bytes($size*1000*1000, false, ' <span>', '</span>');
|
||||
$data['current_speed'] = format_bytes($rate, false, ' <span>');
|
||||
$status = ($size > 0 || $rate > 0) ? 'active' : 'inactive';
|
||||
}
|
||||
|
||||
return parent::getLiveStats($status, $data);
|
||||
|
||||
}
|
||||
|
||||
public function url($endpoint)
|
||||
{
|
||||
$api_url = parent::normaliseurl($this->config->url);
|
||||
$username = $this->config->username;
|
||||
$password = $this->config->password;
|
||||
$rebuild_url = str_replace('http://', 'http://'.$username.':'.$password.'@', $api_url);
|
||||
$rebuild_url = str_replace('https://', 'https://'.$username.':'.$password.'@', $rebuild_url);
|
||||
$rebuild_url = rtrim($rebuild_url, '/');
|
||||
|
||||
$api_url = $rebuild_url.'/jsonrpc/'.$endpoint;
|
||||
return $api_url;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Openhab implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#b7b7b7';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/openhab.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Pfsense implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#4e4742';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pfsense.png';
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Pihole implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#352222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pihole.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return 'pihole';
|
||||
}
|
||||
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest();
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo 'Successfully connected to the API';
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$output = '';
|
||||
$res = $this->buildRequest();
|
||||
$data = json_decode($res->getBody());
|
||||
|
||||
$output = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Domains<br />Blocked</span><strong>'.$data->domains_being_blocked.'</strong></li>
|
||||
<li><span class="title">Blocked<br />Today</span><strong>'.$data->ads_blocked_today.'</span></strong></li>
|
||||
</ul>
|
||||
';
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function buildRequest()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$api_url = $url.'admin/api.php';
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Plex implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plex.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Plexpy implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2d2208';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plexpy.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Plexrequests implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#845c2c';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plexrequests.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Portainer implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#283f44';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/portainer.png';
|
||||
}
|
||||
}
|
||||
5
app/SupportedApps/Privatebin/Privatebin.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\Privatebin;
|
||||
|
||||
class Privatebin extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/Privatebin/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "87ecbead58e42b5ab9e1a92ccc0b42075f4fba91",
|
||||
"name": "Privatebin",
|
||||
"website": "https://privatebin.info/",
|
||||
"license": "zlib/libpng License with Acknowledgement",
|
||||
"description": "PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data.\r\n\r\nData is encrypted and decrypted in the browser using 256bit AES in Galois Counter mode.",
|
||||
"enhanced": false,
|
||||
"tile_background": "light",
|
||||
"icon": "privatebin.png"
|
||||
}
|
||||
BIN
app/SupportedApps/Privatebin/privatebin.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
5
app/SupportedApps/Rspamd/Rspamd.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\Rspamd;
|
||||
|
||||
class Rspamd extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/Rspamd/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "5876529d5d47f91c435d9230576044bc4cad8547",
|
||||
"name": "Rspamd",
|
||||
"website": "https://rspamd.com/",
|
||||
"license": "Apache 2.0",
|
||||
"description": "Fast, free and open-source spam filtering system.",
|
||||
"enhanced": false,
|
||||
"tile_background": "dark",
|
||||
"icon": "rspamd.png"
|
||||
}
|
||||
BIN
app/SupportedApps/Rspamd/rspamd.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
5
app/SupportedApps/SOGo/SOGo.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\SOGo;
|
||||
|
||||
class SOGo extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/SOGo/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "d143b3a76b72591495655c5257c7523456bdd736",
|
||||
"name": "SOGo",
|
||||
"website": "https://sogo.nu/",
|
||||
"license": "GNU GPL/LGPL v2 and above",
|
||||
"description": "SOGo is a fully supported and trusted groupware server with a focus on scalability and open standards.",
|
||||
"enhanced": false,
|
||||
"tile_background": "light",
|
||||
"icon": "sogo.svg"
|
||||
}
|
||||
11
app/SupportedApps/SOGo/sogo.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="792px" height="464px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M643.711,144.938C633.849,144.938 626.847,137.721 626.847,128.035C626.847,118.341 633.849,111.123 643.711,111.123C653.65,111.123 660.652,118.341 660.652,128.035C660.652,137.721 653.65,144.938 643.711,144.938ZM643.681,94.5835C624.154,94.5835 610.288,108.861 610.288,128.035C610.288,147.2 624.154,161.478 643.681,161.478C663.335,161.478 677.202,147.2 677.202,128.035C677.202,108.861 663.335,94.5835 643.681,94.5835ZM643.652,178.811C614.019,178.811 592.965,157.13 592.965,128.035C592.965,98.9315 614.019,77.2602 643.652,77.2602C673.48,77.2602 694.525,98.9315 694.525,128.035C694.525,157.13 673.48,178.811 643.652,178.811ZM643.613,58.4876C603.032,58.4876 574.212,88.1791 574.212,128.035C574.212,167.882 603.032,197.564 643.613,197.564C684.458,197.564 713.288,167.882 713.288,128.035C713.288,88.1791 684.458,58.4876 643.613,58.4876ZM157.492,182.836L136.653,177.871C117.684,173.513 108.048,168.538 108.048,154.858C108.048,139.307 123.903,133.079 138.21,133.079C152.752,133.079 163.377,140.345 169.635,151.656C169.654,151.704 169.684,151.753 169.723,151.812C169.85,152.057 169.997,152.292 170.124,152.537L170.154,152.517C172.122,155.494 175.432,157.482 178.997,157.482C185.068,157.482 189.465,153.095 189.465,147.024C189.465,144.703 188.966,142.245 187.879,140.394C177.205,122.248 159.607,114.424 139.454,114.424C112.093,114.424 85.6524,128.104 85.6524,158.266C85.6524,185.95 113.023,194.038 122.972,196.516L142.871,201.187C158.109,204.918 170.546,209.903 170.546,224.504C170.546,241.298 153.134,248.77 136.34,248.77C119.241,248.77 106.579,240.025 97.8541,227.118L97.8443,227.118C95.9054,224.288 92.899,222.3 89.2169,222.3C83.2826,222.3 78.5037,227.177 78.7191,233.102C78.8171,235.52 79.6201,237.567 80.854,239.32C94.5246,259.777 114.296,267.425 136.34,267.425C164.641,267.425 192.942,254.362 192.942,222.643C192.942,202.127 177.704,187.507 157.492,182.836ZM296.617,248.682C263.038,248.682 241.886,223.495 241.886,190.846C241.886,158.187 263.038,133 296.617,133C330.52,133 351.662,158.187 351.662,190.846C351.662,223.495 330.52,248.682 296.617,248.682ZM296.617,114.345C251.531,114.345 219.499,146.994 219.499,190.846C219.499,234.688 251.531,267.337 296.617,267.337C342.016,267.337 374.048,234.688 374.048,190.846C374.048,146.994 342.016,114.345 296.617,114.345ZM514.985,232.818C514.221,233.552 513.448,234.277 512.606,234.972C511.509,235.981 510.236,237.068 508.786,238.155C500.032,244.491 488.976,248.163 476.049,248.163C442.46,248.163 421.318,222.976 421.318,190.327C421.318,157.668 442.46,132.481 476.049,132.481C509.942,132.481 531.084,157.668 531.084,190.327C531.084,207.376 525.316,222.369 514.985,232.818ZM464.797,315.733C467.304,315.733 469.899,315.566 472.592,315.233C477.567,314.607 482.101,314.332 486.204,314.332C505.281,314.44 514.995,319.983 520.851,326.387C526.697,332.831 528.95,341.566 528.94,348.989C528.95,352.544 528.391,355.726 527.774,357.636C524.856,366.488 518.961,372.511 509.932,377.045C500.972,381.491 489.015,383.763 476.51,383.743C472.034,383.743 467.481,383.459 462.986,382.921C454.486,381.941 443.244,378.289 435.096,371.923C430.993,368.751 427.614,364.99 425.235,360.534C422.875,356.059 421.406,350.869 421.396,344.23L421.396,343.495C421.651,331.254 427.272,323.126 433.431,317.221C436.477,314.342 439.611,312.198 441.892,310.836C442.255,310.621 442.597,310.425 442.911,310.249C448.953,313.823 456.454,315.762 464.797,315.733ZM476.049,113.826C430.964,113.826 398.922,146.475 398.922,190.327C398.922,219.96 413.562,244.461 436.976,257.241C436.663,257.554 436.359,257.877 436.066,258.2C430.014,264.83 426.919,273.32 426.909,281.909C426.9,285.698 427.526,289.586 428.868,293.307C425.832,295.246 422.209,297.9 418.497,301.386C409.547,309.72 399.921,323.733 399.637,343.123C399.627,343.573 399.627,343.946 399.627,344.23C399.617,354.218 401.987,363.227 406.031,370.778C412.113,382.147 421.582,390.059 431.355,395.338C441.187,400.626 451.44,403.436 460.381,404.533C465.708,405.17 471.114,405.512 476.51,405.512C491.532,405.493 506.514,402.957 519.549,396.572C532.524,390.285 543.678,379.464 548.496,364.285C549.926,359.771 550.689,354.649 550.709,348.989C550.689,337.492 547.389,323.449 537.058,311.855C526.727,300.221 509.638,292.455 486.204,292.563C481.112,292.563 475.687,292.916 469.919,293.63C468.058,293.856 466.354,293.963 464.797,293.963C457.619,293.915 454.016,291.927 451.871,289.899C449.756,287.833 448.698,285.101 448.669,281.909C448.659,278.657 449.942,275.24 452.106,272.909C454.319,270.598 457.071,269.031 461.869,268.972C462.3,268.972 462.761,268.982 463.231,269.021C466.306,269.237 469.292,269.345 472.191,269.345C496.173,269.393 514.212,261.961 526.482,251.737C538.791,241.514 545.294,229.077 548.369,219.255L548.329,219.245C551.669,210.422 553.48,200.688 553.48,190.327C553.48,146.475 521.448,113.826 476.049,113.826Z" style="fill:rgb(80,189,55);fill-rule:nonzero;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
@@ -1,82 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Sabnzbd implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3e3924';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/sabnzbd.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'sabnzbd';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('queue');
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
if(isset($data->error) && !empty($data->error)) {
|
||||
echo 'Failed: '.$data->error;
|
||||
} else {
|
||||
echo 'Successfully connected to the API';
|
||||
}
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function executeConfig()
|
||||
{
|
||||
$output = '';
|
||||
$res = $this->buildRequest('queue');
|
||||
$data = json_decode($res->getBody());
|
||||
//$data->result->RemainingSizeMB = '10000000';
|
||||
//$data->result->DownloadRate = '100000000';
|
||||
$size = $data->queue->mbleft;
|
||||
$rate = $data->queue->kbpersec;
|
||||
$queue_size = format_bytes($size*1000*1000, false, ' <span>', '</span>');
|
||||
$current_speed = format_bytes($rate*1000, false, ' <span>');
|
||||
|
||||
if($size > 0 || $rate > 0) {
|
||||
$output = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Queue</span><strong>'.$queue_size.'</strong></li>
|
||||
<li><span class="title">Speed</span><strong>'.$current_speed.'/s</span></strong></li>
|
||||
</ul>
|
||||
';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$apikey = $config->apikey;
|
||||
|
||||
$api_url = $url.'api?output=json&apikey='.$apikey.'&mode='.$endpoint;
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
5
app/SupportedApps/Snibox/Snibox.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php namespace App\SupportedApps\Snibox;
|
||||
|
||||
class Snibox extends \App\SupportedApps {
|
||||
|
||||
}
|
||||
10
app/SupportedApps/Snibox/app.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"appid": "6c050d5bdf522fa20599560ff0f6b74e7dcd97a8",
|
||||
"name": "Snibox",
|
||||
"website": "https://github.com/snibox/snibox",
|
||||
"license": "MIT License",
|
||||
"description": "Snibox is a self-hosted, single-user (for now) snippet manager. Developed to collect and organize code snippets. Supports various programming languages, markdown, plain text.",
|
||||
"enhanced": false,
|
||||
"tile_background": "dark",
|
||||
"icon": "snibox.png"
|
||||
}
|
||||
BIN
app/SupportedApps/Snibox/snibox.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Traefik implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#427d8c';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/traefik.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Unifi implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#363840';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/unifi.png';
|
||||
}
|
||||
}
|
||||
36
app/User.php
@@ -15,7 +15,7 @@ class User extends Authenticatable
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name', 'email', 'password',
|
||||
'username', 'email', 'password',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -26,4 +26,38 @@ class User extends Authenticatable
|
||||
protected $hidden = [
|
||||
'password', 'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the items for the user.
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany('App\Item');
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings that belong to the user.
|
||||
*/
|
||||
public function settings()
|
||||
{
|
||||
return $this->belongsToMany('App\Setting')->withPivot('uservalue');
|
||||
}
|
||||
|
||||
public static function currentUser()
|
||||
{
|
||||
$current_user = session('current_user');
|
||||
if ($current_user) { // if logged in, set this user
|
||||
return $current_user;
|
||||
} else { // not logged in, get first user
|
||||
$user = User::where('public_front',true)->first();
|
||||
if(!$user) {
|
||||
$user = User::first();
|
||||
}
|
||||
session(['current_user' => $user]);
|
||||
return $user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"fideloper/proxy": "~3.3",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"graham-campbell/github": "^7.5",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"laravel/framework": "5.5.*",
|
||||
"laravel/framework": "5.7.*",
|
||||
"laravel/tinker": "~1.0",
|
||||
"laravelcollective/html": "^5.5"
|
||||
"laravelcollective/html": "^5.5",
|
||||
"php-http/guzzle6-adapter": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"filp/whoops": "~2.0",
|
||||
|
||||
2049
composer.lock
generated
@@ -14,7 +14,7 @@ return [
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Heimdall'),
|
||||
'version' => '1.3.2',
|
||||
'version' => '2.1.11',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -229,6 +229,9 @@ return [
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
|
||||
'SupportedApps' => App\SupportedApps::class,
|
||||
'EnhancedApps' => App\EnhancedApps::class,
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
91
config/github.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of Laravel GitHub.
|
||||
*
|
||||
* (c) Graham Campbell <graham@alt-three.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Connection Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify which of the connections below you wish to use as
|
||||
| your default connection for all work. Of course, you may use many
|
||||
| connections at once using the manager class.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => 'main',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| GitHub Connections
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here are each of the connections setup for your application. Example
|
||||
| configuration has been included, but you may add as many connections as
|
||||
| you would like. Note that the 5 supported authentication methods are:
|
||||
| "application", "jwt", "none", "password", and "token".
|
||||
|
|
||||
*/
|
||||
|
||||
'connections' => [
|
||||
|
||||
'main' => [
|
||||
'token' => 'your-token',
|
||||
'method' => 'token',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'app' => [
|
||||
'clientId' => 'your-client-id',
|
||||
'clientSecret' => 'your-client-secret',
|
||||
'method' => 'application',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'jwt' => [
|
||||
'token' => 'your-jwt-token',
|
||||
'method' => 'jwt',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'other' => [
|
||||
'username' => 'your-username',
|
||||
'password' => 'your-password',
|
||||
'method' => 'password',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'none' => [
|
||||
'method' => 'none',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
3698
css/app.css
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddColumnsToItemsForGroups extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->integer('type')->default(0)->index(); // 0 = item, 1 = category
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->dropColumn(['type']);
|
||||
});
|
||||
}
|
||||
}
|
||||
35
database/migrations/2018_02_16_193703_item_tag.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class ItemTag extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('item_tag', function (Blueprint $table) {
|
||||
$table->integer('item_id')->unsigned()->index();
|
||||
$table->foreign('item_id')->references('id')->on('items')->onDelete('cascade');
|
||||
|
||||
$table->integer('tag_id')->unsigned()->index();
|
||||
$table->foreign('tag_id')->references('id')->on('items')->onDelete('cascade');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('item_tag');
|
||||
}
|
||||
}
|
||||
38
database/migrations/2018_10_12_122907_create_users_table.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateUsersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('username')->unique();
|
||||
$table->string('email');
|
||||
$table->string('avatar')->nullable();
|
||||
$table->string('password')->nullable();
|
||||
$table->string('autologin')->nullable()->index();
|
||||
$table->boolean('public_front')->default(false);
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreatePasswordResetsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('password_resets', function (Blueprint $table) {
|
||||
$table->string('email')->index();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('password_resets');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddUserIdToItemsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->integer('user_id')->default(1)->index(); // 0 = item, 1 = category
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->dropColumn(['user_id']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateSettingUserPivotTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('setting_user', function (Blueprint $table) {
|
||||
$table->integer('setting_id')->unsigned()->index();
|
||||
$table->foreign('setting_id')->references('id')->on('settings')->onDelete('cascade');
|
||||
$table->integer('user_id')->unsigned()->index();
|
||||
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
|
||||
$table->primary(['setting_id', 'user_id']);
|
||||
$table->string('uservalue')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('setting_user');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateApplicationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('applications', function (Blueprint $table) {
|
||||
|
||||
$table->string('appid')->unique();
|
||||
$table->string('name')->unique();
|
||||
$table->string('sha')->unique()->nullable();
|
||||
$table->string('icon')->nullable();
|
||||
$table->string('website')->nullable();
|
||||
$table->string('license')->nullable();
|
||||
$table->mediumText('description')->nullable();
|
||||
$table->boolean('enhanced')->default(false);
|
||||
$table->string('tile_background')->default('dark');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('applications');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddClassToItemsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->string('class')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->dropColumn(['class']);
|
||||
});
|
||||
}
|
||||
}
|
||||
36
database/migrations/2018_10_31_191604_create_jobs_table.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateFailedJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
}
|
||||
@@ -12,5 +12,6 @@ class DatabaseSeeder extends Seeder
|
||||
public function run()
|
||||
{
|
||||
$this->call(SettingsSeeder::class);
|
||||
$this->call(UsersSeeder::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,8 @@ class SettingsSeeder extends Seeder
|
||||
'none' => 'app.options.none',
|
||||
'google' => 'app.options.google',
|
||||
'ddg' => 'app.options.ddg',
|
||||
'bing' => 'app.options.bing'
|
||||
'bing' => 'app.options.bing',
|
||||
'startpage' => 'app.options.startpage',
|
||||
]);
|
||||
|
||||
if(!$setting = Setting::find(4)) {
|
||||
@@ -115,6 +116,9 @@ class SettingsSeeder extends Seeder
|
||||
'en' => 'English',
|
||||
'fi' => 'Suomi (Finnish)',
|
||||
'fr' => 'Français (French)',
|
||||
'it' => 'Italiano (Italian)',
|
||||
'no' => 'Norsk (Norwegian)',
|
||||
'pl' => 'Polski (Polish)',
|
||||
'sv' => 'Svenska (Swedish)',
|
||||
'es' => 'Español (Spanish)',
|
||||
'tr' => 'Türkçe (Turkish)',
|
||||
@@ -134,6 +138,60 @@ class SettingsSeeder extends Seeder
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
|
||||
$window_target_options = json_encode([
|
||||
'current' => 'app.settings.window_target.current',
|
||||
'heimdall' => 'app.settings.window_target.one',
|
||||
'_blank' => 'app.settings.window_target.new',
|
||||
]);
|
||||
|
||||
if(!$setting = Setting::find(7)) {
|
||||
|
||||
$setting = new Setting;
|
||||
$setting->id = 7;
|
||||
$setting->group_id = 3;
|
||||
$setting->key = 'window_target';
|
||||
$setting->type = 'select';
|
||||
$setting->options = $window_target_options;
|
||||
$setting->label = 'app.settings.window_target';
|
||||
$setting->value = 'heimdall';
|
||||
$setting->save();
|
||||
} else {
|
||||
$setting->options = $window_target_options;
|
||||
$setting->label = 'app.settings.window_target';
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
if($support = Setting::find(8)) {
|
||||
$support->label = 'app.settings.support';
|
||||
$support->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$support->save();
|
||||
} else {
|
||||
$setting = new Setting;
|
||||
$setting->id = 8;
|
||||
$setting->group_id = 1;
|
||||
$setting->key = 'support';
|
||||
$setting->type = 'text';
|
||||
$setting->label = 'app.settings.support';
|
||||
$setting->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$setting->system = true;
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
if($donate = Setting::find(9)) {
|
||||
$donate->label = 'app.settings.donate';
|
||||
$donate->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
|
||||
$donate->save();
|
||||
} else {
|
||||
$setting = new Setting;
|
||||
$setting->id = 9;
|
||||
$setting->group_id = 1;
|
||||
$setting->key = 'donate';
|
||||
$setting->type = 'text';
|
||||
$setting->label = 'app.settings.donate';
|
||||
$setting->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
|
||||
$setting->system = true;
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
27
database/seeds/UsersSeeder.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\User;
|
||||
|
||||
class UsersSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Groups
|
||||
if(!$user = User::find(1)) {
|
||||
$user = new User;
|
||||
$user->id = 1;
|
||||
$user->username = 'admin';
|
||||
$user->email = 'admin@test.com';
|
||||
$user->password = null;
|
||||
$user->save();
|
||||
} else {
|
||||
//$user->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
mix-manifest.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"/css/app.css": "/css/app.css"
|
||||
}
|
||||
10469
package-lock.json
generated
@@ -10,15 +10,12 @@
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.17",
|
||||
"bootstrap-sass": "^3.3.7",
|
||||
"cross-env": "^5.1.3",
|
||||
"cross-env": "^5.2.0",
|
||||
"jquery": "^3.2",
|
||||
"laravel-mix": "^1.0",
|
||||
"lodash": "^4.17.4",
|
||||
"vue": "^2.5.7"
|
||||
"laravel-mix": "^2.1.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-sass": "^4.7.2"
|
||||
"select2": "^4.0.6-rc.1"
|
||||
}
|
||||
}
|
||||
|
||||
960
public/css/app.css
vendored
14
public/img/heimdall-logo-bloated.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="780" height="619" viewBox="0 0 780 619">
|
||||
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about=""/>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
|
||||
|
||||
<?xpacket end="w"?></metadata>
|
||||
<path class="cls-1" d="M440.227,415.119V390.2l8.552-26.577C508.647,304.3,555.686,248.776,564,231.691l-10.215,3.56s9.5-11.864,8.552-18.51c-7.6-116.273-73.17-176.862-91.226-191.732,26.607,31.955,19.326,42.4,19.326,42.4C478.714,45.576,454.64,24.377,449.888,19l-5.7,33.853c22.806,13.289,16.79,20.882,16.79,20.882C455.591,66.141,441.021,59.5,441.021,59.5l-1.586,9.491c6.973,3.165,38.327,22.149,38.565,70.872,0,59.323-33.735,74.985-39.674,77.357-19.718-11.865-41.1-11.627-46.326-12.1-5.226.474-26.608,0.236-46.324,12.1C339.735,214.844,306,199.182,306,139.859c0.238-48.723,31.6-67.707,38.564-70.872L342.983,59.5s-14.574,6.644-19.955,14.238c0,0-6.022-7.593,16.786-20.882L334.112,19c-4.752,5.378-28.824,26.577-40.543,48.407,0,0-7.288-10.443,19.32-42.4-18.054,14.87-83.625,75.459-91.226,191.732-0.95,6.646,8.554,18.51,8.554,18.51L220,231.691c8.316,17.085,55.355,72.612,115.221,131.935l8.554,26.577v24.916l-7.6-26.577L318.83,360.067v28.95C325.957,409.186,353.751,450,353.751,450V365.525L247.32,249.488s66.52,54.1,85.526,73.56l9.978-10.2c-12.355-8.78-66.045-62.646-70.8-110.1,40.388,85.426,79.111,96.1,107.62,129.325V340.2h24.707v-8.131c28.508-33.221,67.233-43.9,107.619-129.325-4.75,47.459-58.442,101.325-70.8,110.1l9.976,10.2c19.006-19.458,85.526-73.56,85.526-73.56L430.249,365.525V450s27.8-40.815,34.923-60.984v-28.95l-17.343,28.475ZM392,313.083c-17.818-11.865-63.668-39.629-82.672-83.053a314.117,314.117,0,0,0,34.447,34.882s-1.189-30.61,1.186-37.255c4.276,36.781,13.068,52.442,47.039,71.9,33.973-19.458,42.763-35.119,47.039-71.9,2.375,6.645,1.188,37.255,1.188,37.255a314.117,314.117,0,0,0,34.447-34.882C455.668,273.454,409.818,301.218,392,313.083Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
6
public/img/heimdall-logo-small.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16pt" height="16pt" viewBox="0 0 16 16" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 9.777344 14.660156 L 9.777344 13.738281 L 10.09375 12.761719 C 12.300781 10.574219 14.035156 8.527344 14.339844 7.894531 L 13.964844 8.027344 C 13.964844 8.027344 14.316406 7.589844 14.28125 7.34375 C 14 3.058594 11.582031 0.824219 10.917969 0.277344 C 11.898438 1.453125 11.628906 1.839844 11.628906 1.839844 C 11.195312 1.035156 10.308594 0.253906 10.132812 0.0546875 L 9.925781 1.304688 C 10.765625 1.792969 10.542969 2.074219 10.542969 2.074219 C 10.34375 1.792969 9.808594 1.546875 9.808594 1.546875 L 9.75 1.898438 C 10.003906 2.015625 11.160156 2.714844 11.171875 4.511719 C 11.171875 6.699219 9.925781 7.277344 9.707031 7.363281 C 8.980469 6.925781 8.191406 6.933594 8 6.917969 C 7.808594 6.933594 7.019531 6.925781 6.292969 7.363281 C 6.074219 7.273438 4.828125 6.699219 4.828125 4.511719 C 4.839844 2.714844 5.996094 2.015625 6.25 1.898438 L 6.191406 1.546875 C 6.191406 1.546875 5.65625 1.792969 5.457031 2.074219 C 5.457031 2.074219 5.234375 1.792969 6.074219 1.304688 L 5.867188 0.0546875 C 5.691406 0.253906 4.804688 1.035156 4.371094 1.839844 C 4.371094 1.839844 4.101562 1.453125 5.082031 0.277344 C 4.417969 0.824219 2 3.058594 1.71875 7.34375 C 1.683594 7.589844 2.035156 8.027344 2.035156 8.027344 L 1.660156 7.894531 C 1.964844 8.527344 3.699219 10.574219 5.90625 12.761719 L 6.222656 13.738281 L 6.222656 14.660156 L 5.941406 13.679688 L 5.300781 12.628906 L 5.300781 13.695312 C 5.566406 14.441406 6.589844 15.945312 6.589844 15.945312 L 6.589844 12.832031 L 2.667969 8.550781 C 2.667969 8.550781 5.117188 10.546875 5.820312 11.265625 L 6.1875 10.886719 C 5.730469 10.566406 3.753906 8.578125 3.578125 6.828125 C 5.066406 9.980469 6.492188 10.371094 7.542969 11.597656 L 7.542969 11.898438 L 8.457031 11.898438 L 8.457031 11.597656 C 9.507812 10.371094 10.933594 9.980469 12.421875 6.828125 C 12.246094 8.578125 10.269531 10.566406 9.8125 10.886719 L 10.179688 11.265625 C 10.882812 10.546875 13.332031 8.550781 13.332031 8.550781 L 9.410156 12.832031 L 9.410156 15.945312 C 9.410156 15.945312 10.433594 14.441406 10.699219 13.695312 L 10.699219 12.628906 L 10.058594 13.679688 Z M 8 10.898438 C 7.34375 10.460938 5.652344 9.4375 4.953125 7.835938 C 5.339844 8.296875 5.765625 8.726562 6.222656 9.121094 C 6.222656 9.121094 6.179688 7.992188 6.265625 7.746094 C 6.421875 9.105469 6.746094 9.679688 8 10.398438 C 9.253906 9.679688 9.578125 9.105469 9.734375 7.746094 C 9.820312 7.992188 9.777344 9.121094 9.777344 9.121094 C 10.234375 8.726562 10.660156 8.296875 11.046875 7.835938 C 10.347656 9.4375 8.65625 10.460938 8 10.898438 Z M 8 10.898438 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
11
public/img/heimdall-logo-square.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="434" height="434" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g>
|
||||
<title>background</title>
|
||||
<rect fill="none" id="canvas_background" height="436" width="436" y="-1" x="-1"/>
|
||||
</g>
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<path id="svg_1" d="m265.227,397.619l0,-24.919l8.552,-26.577c59.868,-59.323 106.907,-114.847 115.221,-131.932l-10.215,3.56s9.5,-11.864 8.552,-18.51c-7.6,-116.273 -73.17,-176.862 -91.226,-191.732c26.607,31.955 19.326,42.4 19.326,42.4c-11.723,-21.833 -35.797,-43.032 -40.549,-48.409l-5.7,33.853c22.806,13.289 16.79,20.882 16.79,20.882c-5.387,-7.594 -19.957,-14.235 -19.957,-14.235l-1.586,9.491c6.973,3.165 38.327,22.149 38.565,70.872c0,59.323 -33.735,74.985 -39.674,77.357c-19.718,-11.865 -41.1,-11.627 -46.326,-12.1c-5.226,0.474 -26.608,0.236 -46.324,12.1c-5.941,-2.376 -39.676,-18.038 -39.676,-77.361c0.238,-48.723 31.6,-67.707 38.564,-70.872l-1.581,-9.487s-14.574,6.644 -19.955,14.238c0,0 -6.022,-7.593 16.786,-20.882l-5.702,-33.856c-4.752,5.378 -28.824,26.577 -40.543,48.407c0,0 -7.288,-10.443 19.32,-42.4c-18.054,14.87 -83.625,75.459 -91.226,191.732c-0.95,6.646 8.554,18.51 8.554,18.51l-10.217,-3.558c8.316,17.085 55.355,72.612 115.221,131.935l8.554,26.577l0,24.916l-7.6,-26.577l-17.345,-28.475l0,28.95c7.127,20.169 34.921,60.983 34.921,60.983l0,-84.475l-106.431,-116.037s66.52,54.1 85.526,73.56l9.978,-10.2c-12.355,-8.78 -66.045,-62.646 -70.8,-110.1c40.388,85.426 79.111,96.1 107.62,129.325l0,8.127l24.707,0l0,-8.131c28.508,-33.221 67.233,-43.9 107.619,-129.325c-4.75,47.459 -58.442,101.325 -70.8,110.1l9.976,10.2c19.006,-19.458 85.526,-73.56 85.526,-73.56l-106.423,116.041l0,84.475s27.8,-40.815 34.923,-60.984l0,-28.95l-17.343,28.475l-7.602,26.578zm-48.227,-102.036c-17.818,-11.865 -63.668,-39.629 -82.672,-83.053a314.117,314.117 0 0 0 34.447,34.882s-1.189,-30.61 1.186,-37.255c4.276,36.781 13.068,52.442 47.039,71.9c33.973,-19.458 42.763,-35.119 47.039,-71.9c2.375,6.645 1.188,37.255 1.188,37.255a314.117,314.117 0 0 0 34.447,-34.882c-19.006,43.424 -64.856,71.188 -82.674,83.053z" class="cls-1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
11
public/img/heimdall-logo.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="346" height="434" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g>
|
||||
<title>background</title>
|
||||
<rect fill="none" id="canvas_background" height="436" width="348" y="-1" x="-1"/>
|
||||
</g>
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<path id="svg_1" d="m221.227,397.119l0,-24.919l8.552,-26.577c59.868,-59.323 106.907,-114.847 115.221,-131.932l-10.215,3.56s9.5,-11.864 8.552,-18.51c-7.6,-116.273 -73.17,-176.862 -91.226,-191.732c26.607,31.955 19.326,42.4 19.326,42.4c-11.723,-21.833 -35.797,-43.032 -40.549,-48.409l-5.7,33.853c22.806,13.289 16.79,20.882 16.79,20.882c-5.387,-7.594 -19.957,-14.235 -19.957,-14.235l-1.586,9.491c6.973,3.165 38.327,22.149 38.565,70.872c0,59.323 -33.735,74.985 -39.674,77.357c-19.718,-11.865 -41.1,-11.627 -46.326,-12.1c-5.226,0.474 -26.608,0.236 -46.324,12.1c-5.941,-2.376 -39.676,-18.038 -39.676,-77.361c0.238,-48.723 31.6,-67.707 38.564,-70.872l-1.581,-9.487s-14.574,6.644 -19.955,14.238c0,0 -6.022,-7.593 16.786,-20.882l-5.702,-33.856c-4.752,5.378 -28.824,26.577 -40.543,48.407c0,0 -7.288,-10.443 19.32,-42.4c-18.054,14.87 -83.625,75.459 -91.226,191.732c-0.95,6.646 8.554,18.51 8.554,18.51l-10.217,-3.558c8.316,17.085 55.355,72.612 115.221,131.935l8.554,26.577l0,24.916l-7.6,-26.577l-17.345,-28.475l0,28.95c7.127,20.169 34.921,60.983 34.921,60.983l0,-84.475l-106.431,-116.037s66.52,54.1 85.526,73.56l9.978,-10.2c-12.355,-8.78 -66.045,-62.646 -70.8,-110.1c40.388,85.426 79.111,96.1 107.62,129.325l0,8.127l24.707,0l0,-8.131c28.508,-33.221 67.233,-43.9 107.619,-129.325c-4.75,47.459 -58.442,101.325 -70.8,110.1l9.976,10.2c19.006,-19.458 85.526,-73.56 85.526,-73.56l-106.423,116.041l0,84.475s27.8,-40.815 34.923,-60.984l0,-28.95l-17.343,28.475l-7.602,26.578zm-48.227,-102.036c-17.818,-11.865 -63.668,-39.629 -82.672,-83.053a314.117,314.117 0 0 0 34.447,34.882s-1.189,-30.61 1.186,-37.255c4.276,36.781 13.068,52.442 47.039,71.9c33.973,-19.458 42.763,-35.119 47.039,-71.9c2.375,6.645 1.188,37.255 1.188,37.255a314.117,314.117 0 0 0 34.447,-34.882c-19.006,43.424 -64.856,71.188 -82.674,83.053z" class="cls-1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1,171 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 712 712"
|
||||
height="712"
|
||||
width="712"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path16"
|
||||
d="M 0,534 H 534 V 0 H 0 Z" /></clipPath></defs><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,0,712)"
|
||||
id="g10"><g
|
||||
id="g12"><g
|
||||
clip-path="url(#clipPath18)"
|
||||
id="g14"><g
|
||||
transform="translate(393.811,345.8316)"
|
||||
id="g20"><path
|
||||
id="path22"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 24.538,-48.679 35.693,-96.638 39.077,-128.853 3.409,2.889 6.518,5.987 9.318,9.295 C 44.008,-86.276 33.201,-45.41 13.482,-2.216 9.21,-1.054 4.714,-0.293 0,0" /></g><g
|
||||
transform="translate(474.0073,283.56)"
|
||||
id="g24"><path
|
||||
id="path26"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -2.746,20.364 -15.533,43.515 -36.693,60.311 0.831,-5.932 1.399,-11.795 1.735,-17.511 13.776,-14.605 22.245,-33.379 24.23,-48.275 4.005,-30.045 0.821,-64.541 -16.17,-93.955 -0.57,-8.119 -1.935,-15.947 -4.08,-23.411 C 0.994,-86.018 5.717,-42.414 0,0" /></g><g
|
||||
transform="translate(385.5994,134.225)"
|
||||
id="g28"><path
|
||||
id="path30"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 4.978,2.231 10.126,4.9 15.408,8.084 0.431,0.963 0.862,1.934 1.291,2.917 13.266,30.416 21.331,57.602 26.214,83.512 -1.261,8.494 -3.199,19.129 -6.164,31.354 C 33.096,92.579 25.043,59.43 8.133,18.154 5.496,11.715 2.793,5.672 0,0" /></g><g
|
||||
transform="translate(425.0383,307.4895)"
|
||||
id="g32"><path
|
||||
id="path34"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 3.757,-10.543 6.88,-20.55 9.476,-29.923 0.875,13.491 1.202,26.977 1.298,40.761 0.113,16.457 -1.829,35.048 -6.805,53.19 -4.505,3.565 -9.316,6.328 -14.259,8.445 C -2.33,50.589 0.215,26.875 0.073,6.612 0.058,4.391 0.033,2.189 0,0" /></g><g
|
||||
transform="translate(386.608,388.9227)"
|
||||
id="g36"><path
|
||||
id="path38"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 28.927,-1.359 56.121,-14.859 67.722,-50.801 1.163,-3.607 2.212,-7.125 3.152,-10.559 8.947,-11.458 15.298,-24.325 18.197,-37.212 -0.856,16.01 -4.261,34.252 -10.972,55.045 C 63.415,1.968 23.976,16.608 -13.505,19.408 -8.758,13.225 -4.247,6.745 0,0" /></g><g
|
||||
transform="translate(458.4243,221.6535)"
|
||||
id="g40"><path
|
||||
id="path42"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 3.127,14.302 3.772,27.883 3.416,39.047 -1.905,14.006 -15.995,-2.15 -31.262,-12.59 -32.789,-18.805 -34.49,-25.02 -36.37,-31.246 -23.389,-24.415 -10.119,-14.479 0,0" /></g><g
|
||||
transform="translate(444.3687,202.0113)"
|
||||
id="g44"><path
|
||||
id="path46"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -3.23,-2.766 -6.676,-5.371 -10.334,-7.809 -0.733,-41.782 -19.658,-69.771 -47.398,-84.823 -3.677,-5.665 -7.502,-10.841 -11.493,-15.546 41.029,14.834 69.423,50.013 69.423,99.046 C 0.198,-6.198 0.132,-3.151 0,0" /></g><g
|
||||
transform="translate(380.6335,369.7762)"
|
||||
id="g48"><path
|
||||
id="path50"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 5.226,-0.534 10.259,-1.404 15.092,-2.571 -0.889,1.692 -1.785,3.386 -2.702,5.082 -16.462,30.478 -37.594,55.26 -59.872,72.957 -3.747,0.455 -7.437,0.691 -11.034,0.691 -3.084,0 -6.086,-0.173 -9.012,-0.499 C -43.567,59.067 -19.689,32.831 0,0" /></g><g
|
||||
transform="translate(277.8203,439.6349)"
|
||||
id="g52"><path
|
||||
id="path54"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0.965,-0.781 1.902,-1.539 2.823,-2.285 16.915,10.338 37.922,14.465 62.771,9.042 28.083,-6.127 45.11,-20.81 57.944,-39.781 5.759,-1.525 11.199,-3.389 16.31,-5.591 C 126.46,-12.621 104.529,8.859 70.436,16.304 39.851,22.984 13.775,18.552 -7.75,5.74 -5.097,3.943 -2.508,2.031 0,0" /></g><g
|
||||
transform="translate(196.3198,437.5024)"
|
||||
id="g56"><path
|
||||
id="path58"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 4.283,-1.538 8.723,-3.338 13.331,-5.409 3.968,10.138 11.867,19.559 25.463,27.044 16.093,8.861 35.757,7.742 56.297,-1.356 5.767,1.684 11.725,2.851 17.868,3.497 C 85.335,39.045 57.854,43.048 36.898,33.259 18.38,24.608 6.825,12.856 0,0" /></g><g
|
||||
transform="translate(247.7137,105.3549)"
|
||||
id="g60"><path
|
||||
id="path62"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 6.127,1.673 11.893,3.458 17.327,5.333 4.444,12.581 -1.899,21.662 -3.581,31.408 c -0.604,3.504 -1.017,6.799 -0.093,10.712 0.924,3.914 6.739,8.375 9.302,5.407 2.8,-3.245 6.252,-6.183 9.475,-9.292 5.605,1.941 10.678,4.036 15.212,6.206 -3.849,6.266 -7.404,14.138 -6.947,20.42 0.458,6.281 3.075,10.52 8.603,12.187 11.415,3.442 21.999,2.374 25.566,-2.256 2.274,-2.952 2.84,-5.099 0.929,-12.432 C 56.556,55.027 28.877,37.837 -0.53,30.686 0.296,26.898 1.9,23.354 4.268,20.071 31.3,26.585 52.436,37.346 62.531,45.233 c 0,0 3.625,2.818 6.895,4.926 3.271,2.108 6.909,2.389 10.183,1.996 2.641,-0.469 5.128,-1.09 5.926,-3.136 0.424,-1.081 0.58,-2.506 0.793,-3.786 3.81,3.469 7.224,6.844 10.35,10.045 -0.094,0.709 -0.301,1.34 -0.592,3.327 -0.29,1.986 0.873,7.627 4.257,8.472 5.232,1.305 5.352,-2.019 4.758,-4.156 -0.324,-1.158 -2.535,-4.692 -4.491,-7.683 C 96.402,50.874 91.665,46.12 86.1,41.202 79.368,35.304 71.4,29.176 61.657,23.216 67.141,21.2 73.061,19.772 79.275,18.989 c 6.527,4.161 12.301,8.341 17.47,12.437 -0.006,0.015 -0.01,0.029 -0.015,0.045 15.64,12.39 32.343,29.791 34.477,31.837 2.133,2.048 4.192,3.572 9.673,6.772 5.481,3.198 8.032,3.11 12.757,5.157 2.108,6.12 4.032,12.142 5.782,18.099 -13.375,-4.56 -29.007,-6.117 -37.442,-2.982 -8.435,3.137 -9.809,6.612 -13.31,13.049 -6.778,12.464 -6.896,19.112 -13.912,22.317 -7.016,3.205 -22.831,5.462 -27.349,26.236 -4.519,20.774 -1.427,42.142 4.4,49.621 5.826,7.479 7.853,9.191 14.506,12.228 20.81,9.496 20.869,17.035 27.052,22.139 0.95,0.785 1.723,1.526 2.445,2.235 3.051,2.423 6.572,4.287 11.289,5.066 17.824,2.947 33.125,-0.539 45.766,-7.644 -0.524,4.921 -1.222,9.904 -2.118,14.903 -20.171,10.031 -45.318,14.571 -74.683,9.124 -8.344,-1.548 -13.881,-4.571 -21.833,-7.494 -7.954,-2.923 -17.15,1.224 -10.273,9.394 1.746,2.073 3.381,4.053 6.551,5.841 3.17,1.786 5.376,2.748 8.251,4.031 11.585,5.172 25.064,9.265 38.919,11.15 -5.214,7.342 -10.657,14.284 -16.279,20.766 -9.394,-0.39 -20.213,-1.851 -26.032,-2.44 -5.82,-0.589 -9.06,1.857 -12.536,3.822 -7.924,5.899 -18.154,14.12 -34.522,27.37 -11.615,9.402 -24.85,16.142 -38.12,19.963 -0.474,-0.24 -0.945,-0.486 -1.41,-0.743 -5.039,-2.774 -9.226,-5.808 -12.69,-9.025 14.703,-2.765 30.868,-9.573 44.139,-20.356 13.952,-11.337 18.206,-24.704 19.888,-36.34 0.168,-1.155 0.266,-1.815 0.311,-3.475 0.047,-1.659 -0.815,-3.004 -1.678,-3.707 -2.718,-2.211 -8.249,3.916 -13.274,6.929 -2.904,2.223 -5.982,4.456 -9.319,6.723 -3.764,2.558 -7.468,5.013 -11.113,7.371 -3.931,-6.369 -7.327,-13.324 -10.143,-20.75 3.692,-5.018 7.901,-11.893 9.644,-16.1 1.743,-4.206 1.807,-7.837 0.673,-10.29 -1.401,-3.03 -5.825,-9.296 -13.094,-7.378 -7.269,1.917 -6.375,9.465 -5.584,15.816 5.308,23.027 15.847,44.264 31.304,59.454 -3.615,2.885 -7.555,5.533 -11.704,7.903 -14.439,-12.917 -26.266,-30.211 -35.458,-50.71 -0.19,-0.422 -0.226,-0.513 -0.565,-1.268 -0.803,-1.788 -2.853,-1.544 -3.596,0.022 -0.282,0.594 -0.385,0.847 -0.574,1.275 -4.022,9.093 -6.995,19.365 -7.268,29.685 -5.63,3.508 -11.066,6.374 -16.297,8.602 -2.454,-10.066 -2.772,-20.285 -1.894,-29.82 0.158,-1.716 0.303,-2.252 0.534,-3.917 0.028,-0.267 0.402,-1.515 -0.223,-1.559 -0.349,-0.025 -1.27,1.562 -1.427,1.781 -1.017,1.66 -1.304,2.068 -2.525,3.581 -5.657,7.005 -13.679,12.164 -25.732,13.032 -10.722,0.773 -22.284,-0.972 -33.613,-5.296 -2.457,-4.819 -4.631,-10.233 -6.51,-16.211 10.888,5.567 22.052,7.726 31.726,6.586 25.225,-2.974 25.025,-18.049 24.213,-22.17 -0.49,-2.493 -2.607,-2.523 -4.95,-2.523 -2.478,0 -5.264,0.014 -7.874,0.032 -7.606,0.617 -15.399,0.53 -23.172,-0.401 -1.869,-4.868 -3.708,-9.939 -5.517,-15.209 16.143,1.05 29.297,-4.241 36.802,-6.503 21.998,-6.629 31.101,-15.861 39.409,-27.368 5.162,-12.231 7.725,-25.405 9.58,-34.362 2.854,-13.771 1.696,-21.754 -2.14,-27.304 -6.633,-9.598 -13.332,-27.17 -18.702,-30.879 -8.576,-5.921 -26.334,-7.643 -31.417,-12.986 -5.308,-5.578 -7.448,-9.838 -11.965,-11.274 -2.401,-0.765 -4.292,-1.24 -7.298,-1.902 -12.923,-2.85 -28.529,1.171 -42.374,11.419 0.076,-5.029 0.323,-9.919 0.744,-14.666 17.101,-12.923 35.852,-19.863 50.79,-19.313 1.187,0.044 1.919,0.102 3.485,0.275 2.069,0.226 3.367,-1.034 3.862,-2.492 0.496,-1.459 1.041,-2.852 1.607,-4.341 3.641,-9.571 8.553,-20.824 14.704,-32.399 6.483,-0.835 13.109,-1.292 19.835,-1.367 -6.27,17.703 -7.737,34.454 -3.319,43.508 1.211,2.483 3.294,4.888 4.982,5.574 1.69,0.684 3.057,1.633 7.932,1.99 4.875,0.356 10.428,-0.861 10.357,-3.487 -0.072,-2.627 -1.118,-4.924 -1.498,-6.722 C -35.786,37.896 -28.37,15.753 0,0" /></g><g
|
||||
transform="translate(345.0594,86.9108)"
|
||||
id="g64"><path
|
||||
id="path66"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 4.957,3.508 9.604,7.594 13.989,12.282 -4.084,8.229 -24.025,8.156 -44.19,11.921 c -4.428,0.826 -8.556,1.754 -12.399,2.773 -5.437,-2.183 -11.057,-4.241 -16.871,-6.18 8.45,-2.639 17.983,-4.917 28.679,-6.836 C -29.302,-1.096 -14.22,-1.59 0,0" /></g><g
|
||||
transform="translate(424.0582,155.6551)"
|
||||
id="g68"><path
|
||||
id="path70"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -3.333,-3.006 -6.899,-5.889 -10.721,-8.629 -23.418,-16.791 -47.229,-24.75 -68.498,-26.057 -0.971,-3.554 -2.151,-7.019 -3.538,-10.38 21.907,0.434 46.121,6.788 69.041,21.707 C -7.959,-16.431 -3.382,-8.632 0,0" /></g><g
|
||||
transform="translate(332.0492,98.9441)"
|
||||
id="g72"><path
|
||||
id="path74"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 6.576,10.274 10.671,21.912 12.373,34.232 8.62,31.327 4.554,28.382 0.121,25.429 -2.374,16.757 -6.639,8.164 -12.496,0.352 -9.009,0.108 -5.545,-0.017 -2.119,-0.017 -1.411,-0.017 -0.705,-0.011 0,0" /></g><g
|
||||
transform="translate(293.4784,133.4932)"
|
||||
id="g76"><path
|
||||
id="path78"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -1.02,0.698 -2.019,1.44 -2.995,2.217 -3.934,-1.832 -8.175,-3.623 -12.68,-5.326 2.128,-1.663 4.345,-3.298 6.683,-4.897 10.13,-6.931 23.823,-11.988 39.452,-13.986 1.715,3.24 3.152,6.525 4.318,9.818 C 21.313,-10.722 9.406,-6.434 0,0" /></g><g
|
||||
transform="translate(373.0792,112.3586)"
|
||||
id="g80"><path
|
||||
id="path82"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -17.337,-25.704 -38.736,-39.907 -68.98,-43.872 -7.734,-4.602 -16.59,-8.148 -27.68,-10.426 52.785,-1.992 86.015,15.599 111.917,59.48 C 10.021,3.046 4.915,1.346 0,0" /></g><g
|
||||
transform="translate(207.2643,116.8778)"
|
||||
id="g84"><path
|
||||
id="path86"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -0.838,-0.011 -1.675,-0.017 -2.51,-0.017 h -0.006 c -4.847,0 -9.642,0.188 -14.384,0.548 11.348,-17.77 25.585,-34.706 42.6,-45.874 6.415,-1.663 12.827,-2.52 19.16,-2.52 2.66,0 5.293,0.122 7.891,0.354 C 29.652,-42.081 11.377,-21.927 0,0" /></g><g
|
||||
transform="translate(225.2887,402.3531)"
|
||||
id="g88"><path
|
||||
id="path90"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 2.856,4.852 5.877,9.429 9.057,13.724 -9.122,24.262 -25.618,31.778 -40.359,35.77 -43.291,33.619 -46.769,30.646 -50.677,26.393 -37.61,24.056 -22.788,17.057 -6.339,4.976 -4.139,3.36 -2.028,1.701 0,0" /></g><g
|
||||
transform="translate(153.844,407.1487)"
|
||||
id="g92"><path
|
||||
id="path94"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0.586,0 1.172,-0.01 1.757,-0.024 15.837,27.113 28.961,34.536 34.736,37.816 2.637,1.498 5.828,2.582 9.427,3.257 0.096,0.128 0.189,0.257 0.285,0.384 3.462,4.529 7.526,8.693 12.156,12.478 -7.686,-0.075 -15,-1.294 -21.582,-3.718 C 27.323,46.71 9.311,35.291 -10.369,-0.704 -6.903,-0.239 -3.442,0 0,0" /></g><g
|
||||
transform="translate(110.5027,359.7524)"
|
||||
id="g96"><path
|
||||
id="path98"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 6.233,38.52 20.951,62.47 43.115,68.417 3.7,5.186 7.278,9.552 10.669,13.232 C 19.274,82.625 -2.578,56.901 -10.403,-5.079 -7.057,-3.186 -3.586,-1.493 0,0" /></g><g
|
||||
transform="translate(142.7769,130.788)"
|
||||
id="g100"><path
|
||||
id="path102"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 6.02,-9.512 12.474,-18.353 19.267,-26.357 5.732,-2.097 11.846,-3.64 18.317,-4.625 -7.65,7.45 -15.05,16.112 -22.015,25.948 23.025,-6.224 45.696,-7.137 66.372,-5.01 C 79.408,-6.74 77.314,-3.221 75.652,0.533 53.659,-1.389 29.867,0.362 7.016,8.019 c -6.702,11.042 -12.871,23.29 -18.309,36.72 -4.76,1.763 -9.576,4.013 -14.349,6.705 5.008,-13.053 10.815,-25.558 17.267,-37.269 -4.59,2.155 -9.114,4.579 -13.548,7.298 -30.386,18.628 -45.7,47.92 -50.912,77.884 -4.917,8.92 -9.269,19.492 -11.863,31.644 C -86.618,88.432 -72.512,40.94 -28.732,14.102 -19.237,8.28 -9.621,3.637 0,0" /></g><g
|
||||
transform="translate(88.5718,224.2917)"
|
||||
id="g104"><path
|
||||
id="path106"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -11.332,15.213 -19.117,36.192 -19.117,62.341 0,37.856 12.897,64.906 29.809,81.738 1.148,6.561 2.496,12.714 4.041,18.436 -25.112,-18.504 -44.885,-51.876 -44.885,-101.002 0,-30.917 12.513,-57.099 29.663,-76.362 C -0.476,-10.007 -0.313,-5.056 0,0" /></g><g
|
||||
transform="translate(132.9481,385.021)"
|
||||
id="g108"><path
|
||||
id="path110"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -7.698,-17.341 -15.463,-38.736 -22.904,-65.126 -0.223,-11.817 0.107,-24.437 0.996,-37.732 0.021,-0.315 0.045,-0.626 0.066,-0.942 11.167,47.936 22.9,81.62 33.897,105.42 C 8.138,1.593 4.085,1.045 0,0" /></g><g
|
||||
transform="translate(80.9783,335.1565)"
|
||||
id="g112"><path
|
||||
id="path114"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -5.227,-12.952 -8.107,-27.538 -8.593,-43.587 5.086,19.742 14.002,35.727 24.537,43.499 6.063,4.47 12.004,7.641 17.74,9.824 1.715,5.241 3.468,10.334 5.256,15.261 C 28.354,21.684 18.126,16.53 8.81,9.171 5.747,6.751 2.792,3.66 0,0" /></g><g
|
||||
transform="translate(107.5541,165.6139)"
|
||||
id="g116"><path
|
||||
id="path118"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C -4.269,15.889 -6.1,34.231 -5.276,54.798 -8.364,67.6 -10.59,80.395 -11.941,93.107 -17.06,64.013 -17.85,38.438 -14.934,16.468 -10.781,10.732 -5.851,5.174 0,0" /></g><g
|
||||
transform="translate(305.6711,84.8346)"
|
||||
id="g120"><path
|
||||
id="path122"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -13.748,-11.22 -33.729,-18.651 -55.357,-18.651 -14.953,0 -31.093,5.166 -46.959,15.248 -1.537,-0.047 -3.066,-0.073 -4.581,-0.073 h -0.005 c -4.859,0 -9.596,0.238 -14.205,0.709 18.555,-15.209 38.58,-24.093 58.523,-24.093 39.332,0 53.602,7.14 75.98,25.488 C 8.953,-1.1 4.479,-0.641 0,0" /></g><g
|
||||
transform="translate(212.4133,84.8215)"
|
||||
id="g124"><path
|
||||
id="path126"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -3.35,3.361 -6.644,6.999 -9.876,10.909 -20.874,-0.646 -38.945,3.341 -53.773,11.661 -12.673,7.46 -22.973,18.151 -30.64,31.794 -1.872,1.057 -3.73,2.147 -5.572,3.277 -4.478,2.744 -8.708,5.733 -12.69,8.958 3.258,-9.117 7.365,-17.325 12.241,-24.613 h -0.046 C -79.294,10.472 -43.813,-3.836 0,0" /></g><g
|
||||
transform="translate(304.2728,112.9123)"
|
||||
id="g128"><path
|
||||
id="path130"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -0.277,0.089 -0.554,0.177 -0.829,0.269 -0.536,0.175 -1.068,0.354 -1.597,0.54 -0.153,0.053 -0.303,0.109 -0.456,0.163 -0.495,0.177 -0.991,0.354 -1.481,0.538 -0.132,0.049 -0.262,0.102 -0.395,0.152 -0.507,0.193 -1.013,0.387 -1.513,0.588 -0.111,0.045 -0.221,0.092 -0.331,0.136 -0.519,0.21 -1.035,0.423 -1.544,0.641 -0.097,0.041 -0.19,0.082 -0.285,0.125 -0.522,0.225 -1.041,0.454 -1.554,0.686 -0.087,0.04 -0.173,0.081 -0.26,0.122 -0.517,0.238 -1.029,0.477 -1.537,0.725 -0.088,0.042 -0.175,0.087 -0.264,0.13 -0.526,0.258 -1.048,0.518 -1.565,0.785 -14.874,-7.004 -32.975,-13.4 -55.354,-18.43 -4.137,-0.93 -8.191,-1.706 -12.166,-2.341 0.2,-0.244 0.401,-0.481 0.602,-0.722 -0.004,-10e-4 -0.006,-0.002 -0.01,-0.003 2.814,-3.38 5.746,-6.459 8.773,-9.22 0.008,0.001 0.016,0.003 0.024,0.005 0.016,-0.015 0.032,-0.03 0.047,-0.043 2.277,0.457 4.569,0.955 6.882,1.502 27.268,6.448 48.885,14.524 66.35,23.169 C 1.02,-0.327 0.51,-0.164 0,0" /></g><g
|
||||
transform="translate(98.6179,332.7756)"
|
||||
id="g132"><path
|
||||
id="path134"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -0.211,-0.155 -0.42,-0.322 -0.63,-0.484 -0.959,-14.52 -1.313,-30.63 -1.05,-48.42 0.373,-25.232 4.421,-50.661 11.294,-74.894 4.558,-3.189 9.331,-5.712 14.138,-7.502 C 16.559,-107.411 11.56,-80.535 9.573,-50.802 8.177,-29.897 8.153,-10.905 9.438,5.971 6.236,4.268 3.087,2.276 0,0" /></g></g></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 18 KiB |
124
public/js/app.js
vendored
@@ -11,10 +11,10 @@ $.when( $.ready ).then(function() {
|
||||
|
||||
if($('.message-container').length) {
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
$('.message-container').fadeOut();
|
||||
}, 3500);
|
||||
function()
|
||||
{
|
||||
$('.message-container').fadeOut();
|
||||
}, 3500);
|
||||
}
|
||||
|
||||
if($('.livestats-container').length) {
|
||||
@@ -27,27 +27,61 @@ $.when( $.ready ).then(function() {
|
||||
var timer = 5000;
|
||||
(function worker() {
|
||||
$.ajax({
|
||||
url: '/get_stats/'+id,
|
||||
success: function(data) {
|
||||
container.html(data);
|
||||
if(data != '') timer = increaseby;
|
||||
else {
|
||||
if(timer < max_timer) timer += 2000;
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
url: '/get_stats/'+id,
|
||||
dataType: 'json',
|
||||
success: function(data) {
|
||||
container.html(data.html);
|
||||
if(data.status == 'active') timer = increaseby;
|
||||
else {
|
||||
if(timer < max_timer) timer += 2000;
|
||||
}
|
||||
},
|
||||
complete: function() {
|
||||
// Schedule the next request when the current one's complete
|
||||
setTimeout(worker, timer);
|
||||
}
|
||||
setTimeout(worker, timer);
|
||||
}
|
||||
});
|
||||
})();
|
||||
})();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$( "#sortable" ).sortable({
|
||||
function readURL(input) {
|
||||
|
||||
if (input.files && input.files[0]) {
|
||||
var reader = new FileReader();
|
||||
|
||||
reader.onload = function(e) {
|
||||
$('#appimage img').attr('src', e.target.result);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
$('#upload').change(function() {
|
||||
readURL(this);
|
||||
});
|
||||
/*$(".droppable").droppable({
|
||||
tolerance: "intersect",
|
||||
drop: function( event, ui ) {
|
||||
var tag = $( this ).data('id');
|
||||
var item = $( ui.draggable ).data('id');
|
||||
|
||||
$.get('tag/add/'+tag+'/'+item, function(data) {
|
||||
if(data == 1) {
|
||||
$( ui.draggable ).remove();
|
||||
} else {
|
||||
alert('not added');
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});*/
|
||||
|
||||
$( '#sortable' ).sortable({
|
||||
stop: function (event, ui) {
|
||||
var idsInOrder = $("#sortable").sortable('toArray', {
|
||||
var idsInOrder = $('#sortable').sortable('toArray', {
|
||||
attribute: 'data-id'
|
||||
});
|
||||
$.post(
|
||||
@@ -55,11 +89,12 @@ $.when( $.ready ).then(function() {
|
||||
{ order:idsInOrder }
|
||||
);
|
||||
}
|
||||
|
||||
});
|
||||
$("#sortable").sortable("disable");
|
||||
|
||||
|
||||
});
|
||||
$('#sortable').sortable('disable');
|
||||
|
||||
|
||||
|
||||
$('#app').on('click', '#config-button', function(e) {
|
||||
e.preventDefault();
|
||||
var app = $('#app');
|
||||
@@ -69,50 +104,45 @@ $.when( $.ready ).then(function() {
|
||||
$('.add-item').hide();
|
||||
$('.item-edit').hide();
|
||||
$('#app').removeClass('sidebar');
|
||||
$("#sortable").sortable("disable")
|
||||
$('#sortable').sortable('disable');
|
||||
} else {
|
||||
$("#sortable").sortable("enable")
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
$('.add-item').fadeIn();
|
||||
$('.item-edit').fadeIn();
|
||||
}, 350);
|
||||
|
||||
$('#sortable').sortable('enable');
|
||||
setTimeout(function() {
|
||||
$('.add-item').fadeIn();
|
||||
$('.item-edit').fadeIn();
|
||||
}, 350);
|
||||
|
||||
}
|
||||
}).on('click', '#add-item, #pin-item', function(e) {
|
||||
e.preventDefault();
|
||||
var app = $('#app');
|
||||
var active = (app.hasClass('sidebar'));
|
||||
app.toggleClass('sidebar');
|
||||
|
||||
|
||||
}).on('click', '.close-sidenav', function(e) {
|
||||
e.preventDefault();
|
||||
var app = $('#app');
|
||||
app.removeClass('sidebar');
|
||||
|
||||
|
||||
}).on('click', '#test_config', function(e) {
|
||||
e.preventDefault();
|
||||
var apiurl = $('#create input[name=url]').val();
|
||||
|
||||
|
||||
var override_url = $('#create input[name=override_url]');
|
||||
if(override_url.length && override_url.val() != '') {
|
||||
|
||||
var override_url = $('#create input[name="config[override_url]"]').val();
|
||||
if(override_url.length && override_url != '') {
|
||||
apiurl = override_url;
|
||||
}
|
||||
|
||||
var data = {};
|
||||
data['url'] = apiurl;
|
||||
$('input.config-item').each(function(index){
|
||||
$('.config-item').each(function(index){
|
||||
var config = $(this).data('config');
|
||||
data[config] = $(this).val();
|
||||
})
|
||||
});
|
||||
|
||||
$.post(
|
||||
'/test_config',
|
||||
{ data }, function(data) {
|
||||
alert(data);
|
||||
}
|
||||
);
|
||||
$.post('/test_config', { data: data }, function(data) {
|
||||
alert(data);
|
||||
});
|
||||
|
||||
});
|
||||
$('#pinlist').on('click', 'a', function(e) {
|
||||
@@ -125,5 +155,5 @@ $.when( $.ready ).then(function() {
|
||||
current.toggleClass('active');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||