mirror of
https://github.com/linuxserver/Heimdall.git
synced 2026-02-24 21:50:32 +09:00
Compare commits
494 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
effafe7b2d | ||
|
|
a2aac1f33c | ||
|
|
7c30f0c236 | ||
|
|
39c71b6f26 | ||
|
|
bc5c1ebb1e | ||
|
|
800470f7fa | ||
|
|
a0195e2e08 | ||
|
|
f60aee8072 | ||
|
|
92b54d18a9 | ||
|
|
aeae6a6ebe | ||
|
|
cf674629cb | ||
|
|
650ba498e1 | ||
|
|
8cbd6b7001 | ||
|
|
096ceb47ea | ||
|
|
d0708ea8fb | ||
|
|
d299e1dbb9 | ||
|
|
ee96a2c625 | ||
|
|
4c8477c4a9 | ||
|
|
aa97c8fd3a | ||
|
|
995eb6b557 | ||
|
|
7f0a33e36a | ||
|
|
2100075972 | ||
|
|
6735401302 | ||
|
|
443e18e84f | ||
|
|
679313e58c | ||
|
|
3b817c20fa | ||
|
|
5baedc39bc | ||
|
|
11177b73a5 | ||
|
|
83263c0b1b | ||
|
|
076d51c6eb | ||
|
|
18e1d962b8 | ||
|
|
989989bda7 | ||
|
|
5c5f204545 | ||
|
|
40e7431b98 | ||
|
|
6a933ffc1d | ||
|
|
a79d47f161 | ||
|
|
887e5c9d49 | ||
|
|
309eb4ac33 | ||
|
|
67f4590942 | ||
|
|
fcadb2443e | ||
|
|
9776825506 | ||
|
|
ee089d0761 | ||
|
|
19e739196c | ||
|
|
a6484b801c | ||
|
|
095c4f5181 | ||
|
|
0c7842a3d6 | ||
|
|
01ac523e60 | ||
|
|
6feff6441e | ||
|
|
7229d32e8b | ||
|
|
bbd85d2516 | ||
|
|
803ab459b1 | ||
|
|
256648e682 | ||
|
|
758599804c | ||
|
|
b2dd3f803e | ||
|
|
912c6512fb | ||
|
|
fff44f4681 | ||
|
|
79f4a6cc07 | ||
|
|
b910a933fb | ||
|
|
e0d08c60d0 | ||
|
|
33394c2f07 | ||
|
|
4fc2bbd1af | ||
|
|
e4e815dc40 | ||
|
|
482831b9f9 | ||
|
|
30aea8e361 | ||
|
|
dfc3c2194c | ||
|
|
7376aef136 | ||
|
|
18a45863bd | ||
|
|
9c5cf150e7 | ||
|
|
c08dcab1d8 | ||
|
|
c9d9d50fa0 | ||
|
|
9bb0304620 | ||
|
|
528b317552 | ||
|
|
3d8483f9bb | ||
|
|
6d1d723df2 | ||
|
|
3a93b4f0e1 | ||
|
|
f7286bb38f | ||
|
|
9e93ac10f4 |
2
.env
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
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
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/*
|
||||
|
||||
49
CHANGELOG.md
49
CHANGELOG.md
@@ -1,10 +1,57 @@
|
||||
# Release Notes
|
||||
|
||||
## v1.1.2 (2018-02-05)
|
||||
## 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
|
||||
- guzzlehttp/guzzle as a dependency
|
||||
- Variable polling, so interval is increased when an app is idle and decreased when it's active
|
||||
- Turkish language translation
|
||||
- Added Sabnzbd enhanced application
|
||||
|
||||
### Changed
|
||||
- Updated composer dependencies
|
||||
- Added live stats to Nzbget supported application
|
||||
- Changed Pihole to an enhanced application
|
||||
- Changed NZBGet to an enhanced application
|
||||
|
||||
### Fixed
|
||||
- Fixed autocomplete being hard to see
|
||||
- Fixed checkboxes not working on edge
|
||||
|
||||
|
||||
## v1.2.0 (2018-02-07)
|
||||
|
||||
### Added
|
||||
- Translation support
|
||||
- Initial "Supported" application support
|
||||
- Finnish translation
|
||||
- Swedish translation
|
||||
- German translation
|
||||
- French translation
|
||||
- Spanish translation
|
||||
- Duplicati supported application
|
||||
- Emby supported application
|
||||
- Nzbget supported application
|
||||
- Pfsense supported application
|
||||
- Pihole supported application
|
||||
- Plex supported application
|
||||
- Portainer supported application
|
||||
- Unifi supported application
|
||||
|
||||
### Changed
|
||||
- button layout and behaviour
|
||||
|
||||
36
app/Helper.php
Normal file
36
app/Helper.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
function format_bytes($bytes, $is_drive_size = true, $beforeunit = '', $afterunit = '')
|
||||
{
|
||||
$btype = ($is_drive_size === true) ? 1000 : 1024;
|
||||
$labels = array('B','KB','MB','GB','TB');
|
||||
for($x = 0; $bytes >= $btype && $x < (count($labels) - 1); $bytes /= $btype, $x++); // use 1000 rather than 1024 to simulate HD size not real size
|
||||
if($labels[$x] == "TB") return(round($bytes, 3).$beforeunit.$labels[$x].$afterunit);
|
||||
elseif($labels[$x] == "GB") return(round($bytes, 2).$beforeunit.$labels[$x].$afterunit);
|
||||
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';
|
||||
}
|
||||
}
|
||||
@@ -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
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');
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,16 @@ namespace App\Http\Controllers;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Item;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
use App\SupportedApps\Nzbget;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ItemController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource on the dashboard.
|
||||
*
|
||||
@@ -18,8 +22,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);
|
||||
}
|
||||
|
||||
@@ -49,7 +53,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 +67,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 +87,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 +102,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 +120,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 +137,7 @@ class ItemController extends Controller
|
||||
//
|
||||
$validatedData = $request->validate([
|
||||
'title' => 'required|max:255',
|
||||
'url' => 'required',
|
||||
'url' => 'required|url',
|
||||
]);
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
@@ -139,19 +147,23 @@ class ItemController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$config = json_encode($request->input('config'));
|
||||
if($config) {
|
||||
$request->merge([
|
||||
'description' => $config
|
||||
]);
|
||||
}
|
||||
$config = Item::checkConfig($request->input('config'));
|
||||
$current_user = User::currentUser();
|
||||
$request->merge([
|
||||
'description' => $config,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
|
||||
|
||||
//die(print_r($request->input('config')));
|
||||
|
||||
Item::create($request->all());
|
||||
$item = Item::create($request->all());
|
||||
|
||||
return redirect()->route('dash')
|
||||
->with('success', __('alert.success.item_created'));
|
||||
$item->parents()->sync($request->tags);
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success', __('app.alert.success.item_created'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,11 +186,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,9 +205,9 @@ 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')) {
|
||||
$path = $request->file('file')->store('icons');
|
||||
$request->merge([
|
||||
@@ -202,11 +215,21 @@ class ItemController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$config = Item::checkConfig($request->input('config'));
|
||||
$current_user = User::currentUser();
|
||||
$request->merge([
|
||||
'description' => $config,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
|
||||
Item::find($id)->update($request->all());
|
||||
$item = Item::find($id);
|
||||
$item->update($request->all());
|
||||
|
||||
return redirect()->route('dash')
|
||||
->with('success',__('alert.success.item_updated'));
|
||||
$item->parents()->sync($request->tags);
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.item_updated'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,9 +249,10 @@ class ItemController extends Controller
|
||||
} else {
|
||||
Item::find($id)->delete();
|
||||
}
|
||||
|
||||
return redirect()->route('items.index')
|
||||
->with('success',__('alert.success.item_deleted'));
|
||||
|
||||
$route = route('items.index', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.item_deleted'));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,9 +266,21 @@ class ItemController extends Controller
|
||||
//
|
||||
Item::withTrashed()
|
||||
->where('id', $id)
|
||||
->restore();
|
||||
return redirect()->route('items.index')
|
||||
->with('success',__('alert.success.item_restored'));
|
||||
->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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -254,16 +290,53 @@ class ItemController extends Controller
|
||||
*/
|
||||
public function appload(Request $request)
|
||||
{
|
||||
$output = [];
|
||||
$app = $request->input('app');
|
||||
if($app) {
|
||||
$all_supported = Item::supportedList();
|
||||
$app_details = new $all_supported[$app];
|
||||
|
||||
if(($app_details = $this->isSupportedAppByKey($app)) !== false) {
|
||||
// basic details
|
||||
$output['icon'] = $app_details->icon();
|
||||
$output['colour'] = $app_details->defaultColour();
|
||||
|
||||
// live details
|
||||
if($app_details instanceof \App\SupportedApps\Contracts\Livestats) {
|
||||
$output['config'] = $app_details->configDetails();
|
||||
} else {
|
||||
$output['config'] = null;
|
||||
}
|
||||
}
|
||||
$output['icon'] = $app_details->icon();
|
||||
$output['colour'] = $app_details->defaultColour();
|
||||
$output['config'] = $app_details->configDetails();
|
||||
|
||||
return json_encode($output);
|
||||
}
|
||||
|
||||
public function testConfig(Request $request)
|
||||
{
|
||||
$data = $request->input('data');
|
||||
//$url = $data[array_search('url', array_column($data, 'name'))]['value'];
|
||||
|
||||
$app = $data['type'];
|
||||
|
||||
$app_details = new $app();
|
||||
$app_details->config = (object)$data;
|
||||
$app_details->testConfig();
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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,6 +63,7 @@ class SettingsController extends Controller
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$setting = Setting::find($id);
|
||||
$user = $this->user();
|
||||
|
||||
if (!is_null($setting)) {
|
||||
$data = Setting::getInput();
|
||||
@@ -62,22 +73,25 @@ class SettingsController extends Controller
|
||||
|
||||
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 +103,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'),
|
||||
]);
|
||||
|
||||
|
||||
197
app/Http/Controllers/TagController.php
Normal file
197
app/Http/Controllers/TagController.php
Normal file
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Item;
|
||||
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, '-');
|
||||
|
||||
// set item type to tag
|
||||
$request->merge([
|
||||
'type' => '1',
|
||||
'url' => $slug
|
||||
]);
|
||||
//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
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
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;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ class VerifyCsrfToken extends Middleware
|
||||
protected $except = [
|
||||
//
|
||||
'order',
|
||||
'appload'
|
||||
'appload',
|
||||
'test_config',
|
||||
//'get_stats'
|
||||
];
|
||||
}
|
||||
|
||||
184
app/Item.php
184
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', 'user_id'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -26,14 +37,72 @@ class Item extends Model
|
||||
public static function supportedList()
|
||||
{
|
||||
return [
|
||||
'AirSonic' => \App\SupportedApps\AirSonic::class,
|
||||
'Cardigann' => \App\SupportedApps\Cardigann::class,
|
||||
'CouchPotato' => \App\SupportedApps\CouchPotato::class,
|
||||
'Bazarr' => \App\SupportedApps\Bazarr::class,
|
||||
'Bitwarden' => \App\SupportedApps\Bitwarden::class,
|
||||
'Booksonic' => \App\SupportedApps\Booksonic::class,
|
||||
'BookStack' => \App\SupportedApps\BookStack::class,
|
||||
'Deluge' => \App\SupportedApps\Deluge::class,
|
||||
'Dokuwiki' => \App\SupportedApps\Dokuwiki::class,
|
||||
'Duplicati' => \App\SupportedApps\Duplicati::class,
|
||||
'Emby' => \App\SupportedApps\Emby::class,
|
||||
'Flood' => \App\SupportedApps\Flood::class,
|
||||
'FreshRSS' => \App\SupportedApps\FreshRSS::class,
|
||||
'Gitea' => \App\SupportedApps\Gitea::class,
|
||||
'Glances' => \App\SupportedApps\Glances::class,
|
||||
'Grafana' => \App\SupportedApps\Grafana::class,
|
||||
'Graylog' => \App\SupportedApps\Graylog::class,
|
||||
'Headphones' => \App\SupportedApps\Headphones::class,
|
||||
'Home Assistant' => \App\SupportedApps\HomeAssistant::class,
|
||||
'Jackett' => \App\SupportedApps\Jackett::class,
|
||||
'Jdownloader' => \App\SupportedApps\Jdownloader::class,
|
||||
'Krusader' => \App\SupportedApps\Krusader::class,
|
||||
'LibreNMS' => \App\SupportedApps\LibreNMS::class,
|
||||
'Lidarr' => \App\SupportedApps\Lidarr::class,
|
||||
'Mailcow' => \App\SupportedApps\Mailcow::class,
|
||||
'Mcmyadmin' => \App\SupportedApps\Mcmyadmin::class,
|
||||
'Medusa' => \App\SupportedApps\Medusa::class,
|
||||
'Monica' => \App\SupportedApps\Monica::class,
|
||||
'MusicBrainz' => \App\SupportedApps\MusicBrainz::class,
|
||||
'Mylar' => \App\SupportedApps\Mylar::class,
|
||||
'NZBGet' => \App\SupportedApps\Nzbget::class,
|
||||
'pFsense' => \App\SupportedApps\Pfsense::class,
|
||||
'Netdata' => \App\SupportedApps\Netdata::class,
|
||||
'Nextcloud' => \App\SupportedApps\Nextcloud::class,
|
||||
'Now Showing' => \App\SupportedApps\NowShowing::class,
|
||||
'Nzbhydra' => \App\SupportedApps\Nzbhydra::class,
|
||||
'OPNSense' => \App\SupportedApps\Opnsense::class,
|
||||
'Ombi' => \App\SupportedApps\Ombi::class,
|
||||
'Openhab' => \App\SupportedApps\Openhab::class,
|
||||
'OpenMediaVault' => \App\SupportedApps\OpenMediaVault::class,
|
||||
'Pihole' => \App\SupportedApps\Pihole::class,
|
||||
'Plex' => \App\SupportedApps\Plex::class,
|
||||
'UniFi' => \App\SupportedApps\Unifi::class,
|
||||
'Plexpy' => \App\SupportedApps\Plexpy::class,
|
||||
'Plexrequests' => \App\SupportedApps\Plexrequests::class,
|
||||
'Portainer' => \App\SupportedApps\Portainer::class,
|
||||
'Proxmox' => \App\SupportedApps\Proxmox::class,
|
||||
'Radarr' => \App\SupportedApps\Radarr::class,
|
||||
'Rancher' => \App\SupportedApps\Rancher::class,
|
||||
'Runeaudio' => \App\SupportedApps\Runeaudio::class,
|
||||
'Sabnzbd' => \App\SupportedApps\Sabnzbd::class,
|
||||
'Sickrage' => \App\SupportedApps\Sickrage::class,
|
||||
'Sonarr' => \App\SupportedApps\Sonarr::class,
|
||||
'Syncthing' => \App\SupportedApps\Syncthing::class,
|
||||
'Tautulli' => \App\SupportedApps\Tautulli::class,
|
||||
'Transmission' => \App\SupportedApps\Transmission::class,
|
||||
'Traefik' => \App\SupportedApps\Traefik::class,
|
||||
'tt-rss' => \App\SupportedApps\Ttrss::class,
|
||||
'TVheadend' => \App\SupportedApps\TVheadend::class,
|
||||
'UniFi' => \App\SupportedApps\Unifi::class,
|
||||
'unRAID' => \App\SupportedApps\Unraid::class,
|
||||
'pfSense' => \App\SupportedApps\Pfsense::class,
|
||||
'pyLoad' => \App\SupportedApps\pyLoad::class,
|
||||
'ruTorrent' => \App\SupportedApps\ruTorrent::class,
|
||||
'Virtualmin' => \App\SupportedApps\Virtualmin::class,
|
||||
'Watcher3' => \App\SupportedApps\Watcher3::class,
|
||||
'Webmin' => \App\SupportedApps\Webmin::class,
|
||||
'WebTools' => \App\SupportedApps\WebTools::class,
|
||||
];
|
||||
}
|
||||
public static function supportedOptions()
|
||||
@@ -58,13 +127,118 @@ class Item extends Model
|
||||
$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;
|
||||
}
|
||||
$output->view = $view;
|
||||
if(!isset($output->dataonly)) $output->dataonly = '0';
|
||||
|
||||
}
|
||||
return (object)$output;
|
||||
}
|
||||
public static function checkConfig($config)
|
||||
{
|
||||
if(empty($config)) {
|
||||
$config = null;
|
||||
} else {
|
||||
$store = false;
|
||||
//die(var_dump($config));
|
||||
foreach($config as $key => $check) {
|
||||
if($key == 'type') continue;
|
||||
if($key == 'dataonly') continue;
|
||||
if(!empty($check) && $check != '0') {
|
||||
$store = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//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 function scopeOfType($query, $type)
|
||||
{
|
||||
switch($type) {
|
||||
case 'item':
|
||||
$typeid = 0;
|
||||
break;
|
||||
case 'tag':
|
||||
$typeid = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return $query->where('type', $typeid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user that owns the item.
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\User');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use Illuminate\Support\ServiceProvider;
|
||||
use Artisan;
|
||||
use Schema;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -16,7 +17,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$alt_bg = '';
|
||||
|
||||
|
||||
if(!is_file(base_path('.env'))) {
|
||||
touch(base_path('.env'));
|
||||
@@ -26,19 +27,15 @@ class AppServiceProvider extends ServiceProvider
|
||||
// first time setup
|
||||
touch(database_path('app.sqlite'));
|
||||
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
|
||||
Artisan::call('storage:link');
|
||||
//Cache
|
||||
//Artisan::call('config:cache');
|
||||
//Artisan::call('route:cache');
|
||||
}
|
||||
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));
|
||||
@@ -46,11 +43,62 @@ class AppServiceProvider extends ServiceProvider
|
||||
} 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);
|
||||
}
|
||||
|
||||
// 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 );
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
if (env('FORCE_HTTPS') === true) {
|
||||
\URL::forceScheme('https');
|
||||
}
|
||||
|
||||
if(env('APP_URL') != 'http://localhost') {
|
||||
\URL::forceRootUrl(env('APP_URL'));
|
||||
}
|
||||
view()->share('alt_bg', $alt_bg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
101
app/Setting.php
101
app/Setting.php
@@ -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 = '';
|
||||
@@ -97,8 +111,8 @@ class Setting extends Model
|
||||
if(isset($this->value) && (bool)$this->value === true) $checked = true;
|
||||
$set_checked = ($checked) ? ' checked="checked"' : '';
|
||||
$value = '
|
||||
<input type="hidden" name="value" value="0" />
|
||||
<label class="switch">
|
||||
<input type="hidden" name="value" value="0" />
|
||||
<input type="checkbox" name="value" value="1"'.$set_checked.' />
|
||||
<span class="slider round"></span>
|
||||
</label>';
|
||||
@@ -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
10
app/SettingUser.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
class SettingUser extends Pivot
|
||||
{
|
||||
//
|
||||
}
|
||||
11
app/SupportedApps/AirSonic.php
Normal file
11
app/SupportedApps/AirSonic.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class AirSonic implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#08F';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/airsonic.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/Bazarr.php
Normal file
14
app/SupportedApps/Bazarr.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Bazarr implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/bazarr.png';
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Bitwarden.php
Normal file
12
app/SupportedApps/Bitwarden.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Bitwarden implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3c8dbc';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/bitwarden.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/BookStack.php
Normal file
14
app/SupportedApps/BookStack.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class BookStack implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#02679E';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/bookstack.png';
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Booksonic.php
Normal file
12
app/SupportedApps/Booksonic.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Booksonic implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#58a';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/booksonic.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Cardigann.php
Normal file
11
app/SupportedApps/Cardigann.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Cardigann implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#753';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/cardigann.png';
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,5 @@ interface Applications {
|
||||
public function defaultColour();
|
||||
|
||||
public function icon();
|
||||
|
||||
public function configDetails();
|
||||
|
||||
}
|
||||
11
app/SupportedApps/Contracts/Livestats.php
Normal file
11
app/SupportedApps/Contracts/Livestats.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps\Contracts;
|
||||
|
||||
interface Livestats {
|
||||
|
||||
public function configDetails();
|
||||
|
||||
public function testConfig();
|
||||
|
||||
public function executeConfig();
|
||||
|
||||
}
|
||||
122
app/SupportedApps/CouchPotato.php
Normal file
122
app/SupportedApps/CouchPotato.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CouchPotato implements Contracts\Applications, Contracts\Livestats
|
||||
{
|
||||
|
||||
private $_client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->_client = new Client(
|
||||
['http_errors' => false,
|
||||
'timeout' => 10]
|
||||
);
|
||||
}
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#363840';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/couchpotato.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'couchpotato';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
echo 'CouchPotato connection failed';
|
||||
return;
|
||||
}
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo "Successfully connected to CouchPotato";
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and includes the port';
|
||||
break;
|
||||
case 409:
|
||||
echo 'Failed: Incorrect session id';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
Log::debug('CouchPotato connection failed');
|
||||
return '';
|
||||
}
|
||||
$data = json_decode($res->getBody());
|
||||
if (! isset($data->movies)) {
|
||||
Log::debug('Failed to fetch data from CouchPotato');
|
||||
return '';
|
||||
}
|
||||
$movies = $data->movies;
|
||||
$wantedMovies = $availableMovies = 0;
|
||||
foreach ($movies as $v) {
|
||||
switch ($v->status) {
|
||||
case 'active':
|
||||
$wantedMovies++;
|
||||
break;
|
||||
case 'done':
|
||||
$availableMovies++;
|
||||
break;
|
||||
default:
|
||||
Log::warning('Unexpected CouchPotato status received: '.$v['status']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Wanted</span><sub>'.$wantedMovies.'</sub></li>
|
||||
<li><span class="title">Available</span><sub>'.$availableMovies.'</sub></li>
|
||||
</ul>
|
||||
';
|
||||
return json_encode(['status' => 'inactive', 'html' => $html]);
|
||||
}
|
||||
|
||||
private function sendRequest()
|
||||
{
|
||||
$res = null;
|
||||
try{
|
||||
$res = $this->_client->request(
|
||||
'GET',
|
||||
$this->getApiUrl()
|
||||
);
|
||||
}catch(\GuzzleHttp\Exception\BadResponseException $e){
|
||||
Log::error("Connection to {$e->getRequest()->getUrl()} failed");
|
||||
Log::debug($e->getMessage());
|
||||
$res = $e->getRequest();
|
||||
}catch(\GuzzleHttp\Exception\ConnectException $e) {
|
||||
Log::error("CouchPotato connection refused");
|
||||
Log::debug($e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function getApiUrl()
|
||||
{
|
||||
$url = $this->config->url;
|
||||
$url = rtrim($url, '/');
|
||||
$apiUrl = $url.'/api/'.$this->config->apikey.'/movie.list';
|
||||
return $apiUrl;
|
||||
}
|
||||
}
|
||||
109
app/SupportedApps/Deluge.php
Normal file
109
app/SupportedApps/Deluge.php
Normal file
@@ -0,0 +1,109 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
class Deluge implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#357';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/deluge.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return 'deluge';
|
||||
}
|
||||
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->login()[0];
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
if(!isset($data->result) || is_null($data->result) || $data->result == false) {
|
||||
echo 'Failed: Invalid Credentials';
|
||||
} 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()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$jar = $this->login()[1];
|
||||
$res = $this->getDetails($jar);
|
||||
$data = json_decode($res->getBody());
|
||||
$download_rate = $data->result->stats->download_rate;
|
||||
$upload_rate = $data->result->stats->upload_rate;
|
||||
$seed_count = $data->result->filters->state[2];
|
||||
$leech_count = $data->result->filters->state[1];
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title"><i class="fas fa-arrow-down"></i> '.$this->formatBytes($download_rate).'</span></li>
|
||||
<li><span class="title"><i class="fas fa-arrow-up"></i> '.$this->formatBytes($upload_rate).'</span></li>
|
||||
</ul>
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Leech: '.$leech_count[1].'</span></li>
|
||||
<li><span class="title">Seed: '.$seed_count[1].'</span></li>
|
||||
</ul>
|
||||
';
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function getDetails($jar)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$url = rtrim($url, '/');
|
||||
$api_url = $url.'/json';
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('POST', $api_url, [
|
||||
'body' => '{"method": "web.update_ui", "params": [["none"], {}], "id": 1}',
|
||||
'cookies' => $jar,
|
||||
'headers' => ['content-type' => 'application/json', 'Accept' => 'application/json']
|
||||
]);
|
||||
return $res;
|
||||
}
|
||||
public function login()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$password = $config->password;
|
||||
$url = rtrim($url, '/');
|
||||
$api_url = $url.'/json';
|
||||
$jar = new \GuzzleHttp\Cookie\CookieJar();
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('POST', $api_url, [
|
||||
'body' => '{"method": "auth.login", "params": ["'.$password.'"], "id": 1}',
|
||||
'cookies' => $jar,
|
||||
'headers' => ['content-type' => 'application/json', 'Accept' => 'application/json']
|
||||
]);
|
||||
return array($res,$jar);
|
||||
}
|
||||
|
||||
function formatBytes($bytes, $precision = 2) {
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
|
||||
// Uncomment one of the following alternatives
|
||||
$bytes /= pow(1024, $pow);
|
||||
// $bytes /= (1 << (10 * $pow));
|
||||
|
||||
return round($bytes, $precision) . ' ' . $units[$pow] . 'ps';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Dokuwiki.php
Normal file
12
app/SupportedApps/Dokuwiki.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Dokuwiki implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#9d7056';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/dokuwiki.png';
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,10 @@
|
||||
class Duplicati implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
return '#2c3744';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/duplicati.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,4 @@ class Emby implements Contracts\Applications {
|
||||
{
|
||||
return 'supportedapps/emby.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Flood.php
Normal file
12
app/SupportedApps/Flood.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Flood implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '##00D091';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/Flood.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/FreshRSS.php
Normal file
11
app/SupportedApps/FreshRSS.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class FreshRSS implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#003B73';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/freshrss.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Gitea.php
Normal file
12
app/SupportedApps/Gitea.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Gitea implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#585e52';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/gitea.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/Glances.php
Normal file
14
app/SupportedApps/Glances.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Glances implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2c363f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/glances.png';
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Grafana.php
Normal file
12
app/SupportedApps/Grafana.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Grafana implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#a56e4d';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/grafana.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Graylog.php
Normal file
12
app/SupportedApps/Graylog.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Graylog implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#158';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/graylog.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Headphones.php
Normal file
12
app/SupportedApps/Headphones.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Headphones implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#185';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/headphones.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/HomeAssistant.php
Normal file
12
app/SupportedApps/HomeAssistant.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class HomeAssistant implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#073c52';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/homeassistant.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Jackett.php
Normal file
12
app/SupportedApps/Jackett.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Jackett implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#484814';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/jackett.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Jdownloader.php
Normal file
12
app/SupportedApps/Jdownloader.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Jdownloader implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2b494f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/jdownloader.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Krusader.php
Normal file
11
app/SupportedApps/Krusader.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Krusader implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#5A5';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/krusader.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Lidarr.php
Normal file
12
app/SupportedApps/Lidarr.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Lidarr implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#183c18';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/lidarr.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Mailcow.php
Normal file
12
app/SupportedApps/Mailcow.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Mailcow implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#161b1f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/mailcow.svg';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Mcmyadmin.php
Normal file
12
app/SupportedApps/Mcmyadmin.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Mcmyadmin implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#30404b';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/mcmyadmin.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Medusa.php
Normal file
12
app/SupportedApps/Medusa.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Medusa implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#4b5e55';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/medusa.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Monica.php
Normal file
12
app/SupportedApps/Monica.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Monica implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#fafbfc';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/monica.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/MusicBrainz.php
Normal file
12
app/SupportedApps/MusicBrainz.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class MusicBrainz implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#a0a';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/musicbrainz.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Mylar.php
Normal file
12
app/SupportedApps/Mylar.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Mylar implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#aa0';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/mylar.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Netdata.php
Normal file
12
app/SupportedApps/Netdata.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Netdata implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#543737';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/netdata.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Nextcloud.php
Normal file
12
app/SupportedApps/Nextcloud.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Nextcloud implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#0e2c3e';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nextcloud.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/NowShowing.php
Normal file
11
app/SupportedApps/NowShowing.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class NowShowing implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#690000';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nowshowing.png';
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,15 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Nzbget implements Contracts\Applications {
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Nzbget implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#124019';
|
||||
return '#253827';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
@@ -12,8 +17,68 @@ class Nzbget implements Contracts\Applications {
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
//return 'nzbget';
|
||||
return null;
|
||||
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()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'inactive';
|
||||
$res = $this->buildRequest('status');
|
||||
$data = json_decode($res->getBody());
|
||||
//$data->result->RemainingSizeMB = '10000000';
|
||||
//$data->result->DownloadRate = '100000000';
|
||||
if($data) {
|
||||
$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>');
|
||||
|
||||
$active = ($size > 0 || $rate > 0) ? 'active' : 'inactive';
|
||||
$html = '
|
||||
<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 json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
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);
|
||||
$rebuild_url = rtrim($rebuild_url, '/');
|
||||
|
||||
|
||||
$api_url = $rebuild_url.'/jsonrpc/'.$endpoint;
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Nzbhydra.php
Normal file
12
app/SupportedApps/Nzbhydra.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Nzbhydra implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#53644d';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nzbhydra.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Ombi.php
Normal file
12
app/SupportedApps/Ombi.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Ombi implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#150f09';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/ombi.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/OpenMediaVault.php
Normal file
11
app/SupportedApps/OpenMediaVault.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class OpenMediaVault implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#5AF';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/openmediavault.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Openhab.php
Normal file
12
app/SupportedApps/Openhab.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Openhab implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2b2525';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/openhab.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Opnsense.php
Normal file
12
app/SupportedApps/Opnsense.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Opnsense implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#211914';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/opnsense.png';
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,10 @@
|
||||
class Pfsense implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
return '#243699';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pfsense.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,73 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Pihole implements Contracts\Applications {
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Pihole implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
return '#352222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pihole.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return null;
|
||||
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()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->buildRequest();
|
||||
$data = json_decode($res->getBody());
|
||||
|
||||
$html = '
|
||||
<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 json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
|
||||
public function buildRequest()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api.php';
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -9,8 +9,4 @@ class Plex implements Contracts\Applications {
|
||||
{
|
||||
return 'supportedapps/plex.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
77
app/SupportedApps/Plexpy.php
Normal file
77
app/SupportedApps/Plexpy.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Plexpy implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2d2208';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plexpy.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'plexpy';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('arnold');
|
||||
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()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->buildRequest('get_activity');
|
||||
$data = json_decode($res->getBody());
|
||||
$stream_count = $data->response->data->stream_count;
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Stream Count</span><strong>'.$stream_count.'</strong></li>
|
||||
</ul>
|
||||
';
|
||||
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$apikey = $config->apikey;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api/v2?apikey='.$apikey.'&cmd='.$endpoint;
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Plexrequests.php
Normal file
12
app/SupportedApps/Plexrequests.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Plexrequests implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3c2d1c';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plexrequests.png';
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,10 @@
|
||||
class Portainer implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
return '#283f44';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/portainer.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
80
app/SupportedApps/Proxmox.php
Normal file
80
app/SupportedApps/Proxmox.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Proxmox implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#542e0a';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/proxmox.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
//return 'proxmox';
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
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;
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
public function buildRequest($endpoint='')
|
||||
{
|
||||
$config = $this->config;
|
||||
|
||||
$username = $config->username;
|
||||
$password = $config->password;
|
||||
|
||||
$url = $config->url;
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api2/json/'.$endpoint.'?username='.$username.'&password='.$password;
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'verify' => false ]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Radarr.php
Normal file
12
app/SupportedApps/Radarr.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Radarr implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3e3726';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/radarr.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Rancher.php
Normal file
12
app/SupportedApps/Rancher.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Rancher implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#78c9cf';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/rancher.png';
|
||||
}
|
||||
}
|
||||
95
app/SupportedApps/Runeaudio.php
Normal file
95
app/SupportedApps/Runeaudio.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Runeaudio implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#05A';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/runeaudio.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return 'runeaudio';
|
||||
}
|
||||
|
||||
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 = '';
|
||||
$active = 'active';
|
||||
$artist = '';
|
||||
$song_title = '';
|
||||
$res = $this->buildRequest('currentsong');
|
||||
$array = explode("\n", $res->getBody());
|
||||
foreach($array as $item) {
|
||||
$item_array = explode(": ", $item);
|
||||
if ($item_array[0] == 'Artist') {
|
||||
$artist = $item_array[1];
|
||||
} elseif ($item_array[0] == 'Title') {
|
||||
$song_title = $item_array[1];
|
||||
}
|
||||
}
|
||||
|
||||
$output = '<ul class="livestats">';
|
||||
|
||||
if (strlen($artist) > 12) {
|
||||
$output = $output.'<li><span class="title-marquee"><span>'.$artist.'</span></span></li>';
|
||||
} else {
|
||||
$output = $output.'<li><span class="title">'.$artist.'</span></li>';
|
||||
}
|
||||
|
||||
$output = $output.'</ul><ul class="livestats">';
|
||||
|
||||
if (strlen($song_title) > 12) {
|
||||
$output = $output.'<li><span class="title-marquee"><span>'.$song_title.'</span></span></li>';
|
||||
} else {
|
||||
$output = $output.'<li><span class="title">'.$song_title.'</span></li>';
|
||||
}
|
||||
|
||||
$output = $output.'</ul>';
|
||||
|
||||
return json_encode(['status' => $active, 'html' => $output]);
|
||||
}
|
||||
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/command/?cmd='.$endpoint;
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
89
app/SupportedApps/Sabnzbd.php
Normal file
89
app/SupportedApps/Sabnzbd.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?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()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'inactive';
|
||||
$res = $this->buildRequest('queue');
|
||||
$data = json_decode($res->getBody());
|
||||
//$data->result->RemainingSizeMB = '10000000';
|
||||
//$data->result->DownloadRate = '100000000';
|
||||
if($data) {
|
||||
$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>');
|
||||
|
||||
$active = ($size > 0 || $rate > 0) ? 'active' : 'inactive';
|
||||
$html = '
|
||||
<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 json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$apikey = $config->apikey;
|
||||
|
||||
//print_r($config);
|
||||
//die();
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api?output=json&apikey='.$apikey.'&mode='.$endpoint;
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Sickrage.php
Normal file
12
app/SupportedApps/Sickrage.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Sickrage implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#6185a6';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/sickrage.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Sonarr.php
Normal file
12
app/SupportedApps/Sonarr.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Sonarr implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#163740';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/sonarr.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Syncthing.php
Normal file
11
app/SupportedApps/Syncthing.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Syncthing implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#888';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/syncthing.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/TVheadend.php
Normal file
14
app/SupportedApps/TVheadend.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class TVheadend implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#006080';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/tvheadend.png';
|
||||
}
|
||||
|
||||
}
|
||||
77
app/SupportedApps/Tautulli.php
Normal file
77
app/SupportedApps/Tautulli.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Tautulli implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2d2208';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/tautulli.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'tautulli';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('arnold');
|
||||
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()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->buildRequest('get_activity');
|
||||
$data = json_decode($res->getBody());
|
||||
$stream_count = $data->response->data->stream_count;
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Stream Count</span><strong>'.$stream_count.'</strong></li>
|
||||
</ul>
|
||||
';
|
||||
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$apikey = $config->apikey;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api/v2?apikey='.$apikey.'&cmd='.$endpoint;
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
78
app/SupportedApps/Traefik.php
Normal file
78
app/SupportedApps/Traefik.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
|
||||
class Traefik implements Contracts\Applications, Contracts\Livestats
|
||||
{
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#28434a';
|
||||
}
|
||||
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/traefik.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return 'traefik';
|
||||
}
|
||||
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
echo 'Traefik connection failed';
|
||||
return;
|
||||
}
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
echo "Successfully connected with status: ".$data->result."\n";
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and includes the port';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'inactive';
|
||||
$res = $this->sendRequest();
|
||||
$data = json_decode($res->getBody());
|
||||
if ($data) {
|
||||
$avg_response_time = $data->average_response_time_sec;
|
||||
$time = $avg_response_time*1000;
|
||||
$time_output = number_format($time, 2);
|
||||
$active = ($time > 0) ? 'active' : 'inactive';
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Avg. Response Time</span><sub><i class="fas fa-heartbeat"></i> '.$time_output.' ms</sub></li>
|
||||
</ul>
|
||||
';
|
||||
}
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
|
||||
public function sendRequest()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
$api_url = $url.'/health';
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
169
app/SupportedApps/Transmission.php
Normal file
169
app/SupportedApps/Transmission.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Transmission implements Contracts\Applications, Contracts\Livestats
|
||||
{
|
||||
|
||||
private $_client;
|
||||
private $_clientOptions = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$body = array();
|
||||
$body["method"] = "torrent-get";
|
||||
$body["arguments"] = array("fields" => ["percentDone","status","rateDownload","rateUpload"]);
|
||||
$this->_client = new Client(
|
||||
['http_errors' => false,
|
||||
'timeout' => 10,
|
||||
'body' => json_encode($body)]
|
||||
);
|
||||
}
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#950003';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/transmission.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'transmission';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
echo 'Transmission connection failed';
|
||||
return;
|
||||
}
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
echo "Successfully connected with status: ".$data->result."\n";
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and includes the port';
|
||||
break;
|
||||
case 409:
|
||||
echo 'Failed: Incorrect session id';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
Log::debug('Transmission connection failed');
|
||||
return '';
|
||||
}
|
||||
$data = json_decode($res->getBody());
|
||||
if (! isset($data->arguments)) {
|
||||
Log::debug('Failed to fetch data from Transmission');
|
||||
return '';
|
||||
}
|
||||
$torrents = $data->arguments->torrents;
|
||||
$torrentCount = count($torrents);
|
||||
$rateDownload = $rateUpload = $completedTorrents = 0;
|
||||
foreach ($torrents as $thisTorrent) {
|
||||
$rateDownload += $thisTorrent->rateDownload;
|
||||
$rateUpload += $thisTorrent->rateUpload;
|
||||
if ($thisTorrent->percentDone == 1) {
|
||||
$completedTorrents += 1;
|
||||
}
|
||||
}
|
||||
if ($torrentCount - $completedTorrents == 0) {
|
||||
// Don't poll as frequently if we don't have any active torrents
|
||||
$active = 'inactive';
|
||||
}
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Done</span><sub>'.$completedTorrents.' / '.$torrentCount.'</sub></li>
|
||||
<li><span class="title">Down</span><sub>'.format_bytes($rateDownload).'</sub></li>
|
||||
<li><span class="title">Up</span><sub>'.format_bytes($rateUpload).'</sub></li>
|
||||
</ul>
|
||||
';
|
||||
return json_encode(['status' => $active, 'html' => $html]);;
|
||||
}
|
||||
|
||||
private function sendRequest()
|
||||
{
|
||||
$optionsSet = $this->setClientOptions();
|
||||
if (! $optionsSet) {
|
||||
// Pass the failed response back up the chain
|
||||
return null;
|
||||
}
|
||||
$res = $this->torrentGet();
|
||||
if ($res->getStatusCode() == 409) {
|
||||
$this->setClientOptions();
|
||||
$res = $this->torrentGet();
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function torrentGet()
|
||||
{
|
||||
$res = null;
|
||||
try{
|
||||
$res = $this->_client->request(
|
||||
'POST',
|
||||
$this->getApiUrl(),
|
||||
$this->_clientOptions
|
||||
);
|
||||
}catch(\GuzzleHttp\Exception\BadResponseException $e){
|
||||
Log::error("Connection to {$e->getRequest()->getUrl()} failed");
|
||||
Log::debug($e->getMessage());
|
||||
$res = $e->getRequest();
|
||||
}catch(\GuzzleHttp\Exception\ConnectException $e) {
|
||||
Log::error("Transmission connection refused");
|
||||
Log::debug($e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function setClientOptions()
|
||||
{
|
||||
if ($this->config->username != '' || $this->config->password != '') {
|
||||
$this->_clientOptions = ['auth'=> [$this->config->username, $this->config->password, 'Basic']];
|
||||
}
|
||||
try{
|
||||
$res = $this->_client->request('HEAD', $this->getApiUrl(), $this->_clientOptions);
|
||||
$xtId = $res->getHeaderLine('X-Transmission-Session-Id');
|
||||
if ($xtId != null) {
|
||||
$this->_clientOptions['headers'] = ['X-Transmission-Session-Id' => $xtId];
|
||||
} else {
|
||||
Log::error("Unable to get Transmission session information");
|
||||
Log::debug("Status Code: ".$res->getStatusCode());
|
||||
}
|
||||
}catch(\GuzzleHttp\Exception\ConnectException $e){
|
||||
Log::error("Failed connection to Transmission");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getApiUrl()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
$api_url = $url.'/transmission/rpc';
|
||||
|
||||
return $api_url;
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Ttrss.php
Normal file
12
app/SupportedApps/Ttrss.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Ttrss implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#9d704c';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/tt-rss.png';
|
||||
}
|
||||
}
|
||||
@@ -3,14 +3,10 @@
|
||||
class Unifi implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
return '#363840';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/unifi.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Unraid.php
Normal file
12
app/SupportedApps/Unraid.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Unraid implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#A12624';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/unraid.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Virtualmin.php
Normal file
12
app/SupportedApps/Virtualmin.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Virtualmin implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#161b1f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/virtualmin.svg';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Watcher3.php
Normal file
11
app/SupportedApps/Watcher3.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Watcher3 implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#500';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/watcher3.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/WebTools.php
Normal file
11
app/SupportedApps/WebTools.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class WebTools implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#555';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/webtools.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Webmin.php
Normal file
12
app/SupportedApps/Webmin.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Webmin implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#161b1f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/webmin.svg';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/pyLoad.php
Normal file
11
app/SupportedApps/pyLoad.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class pyLoad implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#881';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pyload.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/ruTorrent.php
Normal file
12
app/SupportedApps/ruTorrent.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class ruTorrent implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#004';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/rutorrent.png';
|
||||
}
|
||||
}
|
||||
33
app/User.php
33
app/User.php
@@ -15,7 +15,7 @@ class User extends Authenticatable
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name', 'email', 'password',
|
||||
'username', 'email', 'password',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -26,4 +26,35 @@ 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::first();
|
||||
session(['current_user' => $user]);
|
||||
return $user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"fideloper/proxy": "~3.3",
|
||||
"laravel/framework": "5.5.*",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"laravel/framework": "5.7.*",
|
||||
"laravel/tinker": "~1.0",
|
||||
"laravelcollective/html": "^5.5"
|
||||
},
|
||||
@@ -23,6 +24,9 @@
|
||||
"database/seeds",
|
||||
"database/factories"
|
||||
],
|
||||
"files": [
|
||||
"app/Helper.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"App\\": "app/"
|
||||
}
|
||||
|
||||
1273
composer.lock
generated
1273
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ return [
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Heimdall'),
|
||||
'version' => '1.2.0',
|
||||
'version' => '2.0.2',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
3698
css/app.css
vendored
Normal file
3698
css/app.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
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
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']);
|
||||
});
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user