Compare commits

...

383 Commits

Author SHA1 Message Date
Kode 7f997d60cd Update version 2018-10-17 22:17:27 +01:00
Kode d45f5a805e wrap asset() round root assets 2018-10-17 22:16:23 +01:00
Kode fc9c624509 update donate link 2018-10-17 19:53:27 +01:00
KodeStar 33372509eb Merge pull request #266 from linuxserver/Multi-user
v2.0.0
2018-10-17 18:41:51 +01:00
Kode bca0b02925 update version number to 2.0.0 2018-10-17 18:37:22 +01:00
Kode 24995135e6 update dependency 2018-10-17 18:35:09 +01:00
Chris c1e4103edd Add support for pinned tabs in safari (potentially) 2018-10-17 11:31:42 +01:00
Chris 6eda423156 Added mailcow, webmin and virtualmin 2018-10-17 10:27:05 +01:00
Chris 7dc72d3519 style switch user icon same as user list page 2018-10-17 09:59:39 +01:00
Chris 907c22179b rearrange order 2018-10-17 09:49:23 +01:00
Chris cdafbab7b1 possible fix for basic auth 2018-10-17 09:41:20 +01:00
Chris e0064504e7 Merge branch 'master' into Multi-user 2018-10-17 08:39:10 +01:00
KodeStar b22117dd01 Add missing override url 2018-10-17 08:36:06 +01:00
KodeStar c88efa8dbc Fix broken config 2018-10-17 08:33:42 +01:00
Kode 7d060ff803 Merge branch 'master' into Multi-user 2018-10-16 19:05:04 +01:00
KodeStar d5f8b6aae0 Merge pull request #257 from ABOTlegacy/Monica
Monica
2018-10-16 19:01:52 +01:00
KodeStar 2416993c5e Merge pull request #258 from ABOTlegacy/Bitwarden
Added Bitwarden to foundation apps.
2018-10-16 19:01:10 +01:00
KodeStar 494165a03a Merge pull request #259 from dgw/readme-polishing
readme: formatting, typo fixes, spit & polish
2018-10-16 19:00:20 +01:00
KodeStar 88e607533c Change to multiarch docker 2018-10-16 18:58:33 +01:00
KodeStar 035d2f9209 Merge pull request #265 from alxlaxv/master
Updating french translations
2018-10-16 18:53:05 +01:00
alxlaxv 53903daa87 Update app.php 2018-10-16 19:32:37 +02:00
alxlaxv 567994be1a Merge pull request #1 from alxlaxv/patch-1
Update app.php
2018-10-16 19:21:03 +02:00
alxlaxv 32fa27337a Update app.php
French translations improved
2018-10-16 17:27:53 +02:00
Chris e1bb7646ac small fixes 2018-10-16 15:44:23 +01:00
KodeStar 108b636def Merge pull request #260 from keranoz/patch-1
Update app.php
2018-10-16 15:20:03 +01:00
keranoz 4abb14bf54 Update app.php
Improved some translations that seemed machine translated and added missing entries.
2018-10-16 14:08:19 +00:00
Chris f8f96593c1 Update userseeder 2018-10-16 15:04:53 +01:00
Chris cb21b0f8f1 add basic auth support and put username in switch user section 2018-10-16 14:57:21 +01:00
Chris 4c8c5fa27f Replace name for username in list view 2018-10-16 14:28:12 +01:00
Chris 6093119dde Change name to username 2018-10-16 14:14:14 +01:00
Chris 15755a3fd1 move all assets locally 2018-10-16 12:58:56 +01:00
Chris 0213c81e0d muted the switch user button until it's hovered over 2018-10-16 11:24:21 +01:00
Chris c47f296f17 Change location of switch user 2018-10-16 10:59:35 +01:00
Chris 75133474f7 Added support and br translation 2018-10-16 09:33:24 +01:00
Kode ddbe171f3a minor change to user avatar size to cut down whitespace a bit 2018-10-15 20:43:27 +01:00
Kode 12e109f82c add unique validation for name and don't fail validation when already the owner of data 2018-10-15 20:34:21 +01:00
Kode e095589172 fix validation on email 2018-10-15 20:25:21 +01:00
Kode d0293c785b Get settings working and autologin 2018-10-15 19:56:45 +01:00
Chris aa351e31bf trying to get session settings to work 2018-10-15 16:00:20 +01:00
Chris aceed3d13b fix settings edit not working 2018-10-15 14:35:14 +01:00
Chris 10b70d4a09 changes 2018-10-15 13:02:16 +01:00
Chris cb9e014cf3 Autologin togles working 2018-10-15 09:52:36 +01:00
Chris 99017d834e Merge branch 'master' into Multi-user 2018-10-15 09:08:42 +01:00
Chris fb73f5ca24 Attempt to allow changing root URL 2018-10-15 09:03:54 +01:00
dgw 4369f1aeda readme: formatting, typo fixes, spit & polish
Includes making inter-sentence spaces consistent, `pre-formatting`
values where it seemed appropriate, correcting typos, and other
miscellaneous niceties to help the readme make a good first impression.
2018-10-14 17:38:05 -05:00
Kode 6501aacb1b update to laravel 5.7 and try getting autologin saved 2018-10-14 20:50:32 +01:00
Kode c3da17befc User specific items 2018-10-14 17:27:28 +01:00
Kode 46bb073001 Working on multi user 2018-10-14 16:17:55 +01:00
Kode e8b47776ce Merge branch 'master' into Multi-user 2018-10-13 15:52:42 +01:00
Kode 6941fd3e2d Fixes for folder installs 2018-10-13 15:32:15 +01:00
Andy Bottom f5937879df Added Bitwarden to foundation apps. 2018-10-12 14:59:19 -05:00
Andy Bottom 93877b7025 Fixed spaces vs tabs. 2018-10-12 14:35:59 -05:00
Andy Bottom 6612631cc3 Added Monica to foundation apps. 2018-10-12 14:32:34 -05:00
Chris 30c3079a90 added setting user many to many relationship 2018-10-12 15:10:40 +01:00
Chris e86e681c53 Initial commit of multi user 2018-10-12 14:57:46 +01:00
Chris 48f72652da Merge branch 'master' of https://github.com/linuxserver/Heimdall 2018-10-12 11:33:43 +01:00
Chris a3f7bafedb change css and js links to asset links 2018-10-12 11:33:39 +01:00
KodeStar d30d610042 Update readme.md 2018-10-12 11:13:51 +01:00
Kode 882e406266 remove var dump 2018-09-30 15:47:44 +01:00
Kode 45d421256c Update readme and remove addition to .env as not necessary for everyone 2018-09-30 11:52:54 +01:00
Kode a2f20fc18f allow forcing https for reverse proxy use 2018-09-30 11:45:08 +01:00
KodeStar 988364cb7c Merge pull request #246 from CHBMB/Bazarr
Bazarr
2018-09-13 13:40:12 +01:00
chbmb a3816ed8a1 Update readme.md 2018-09-13 08:44:05 +01:00
chbmb d48805ee2c Update Item.php 2018-09-13 08:43:21 +01:00
chbmb e820b81259 Add files via upload 2018-09-13 08:42:26 +01:00
chbmb 8b1046ce17 Create Bazarr.php 2018-09-13 08:41:57 +01:00
chbmb a138b65842 Merge pull request #1 from linuxserver/master
Rebase
2018-09-13 08:36:04 +01:00
KodeStar c344de3f04 Merge pull request #244 from CHBMB/patch-3
Better logo and colour scheme for Unraid
2018-09-03 12:55:25 +01:00
chbmb 427659a897 Add files via upload 2018-08-30 11:42:02 +01:00
chbmb a6543970e7 Update Unraid.php 2018-08-30 11:40:55 +01:00
KodeStar 399ea088dc Merge pull request #243 from CHBMB/patch-2
Update Unraid Icon & Colour Scheme
2018-08-29 17:37:18 +01:00
chbmb 3f87833e52 Add files via upload 2018-08-29 15:56:02 +01:00
chbmb 6dcb77023c Update Unraid colour in line with new logo 2018-08-29 15:54:19 +01:00
KodeStar 4d37135bdf Merge pull request #233 from CHBMB/freshrss
Freshrss
2018-07-19 21:49:13 +01:00
KodeStar d109047fa5 Merge pull request #232 from CHBMB/bookstack
BookStack
2018-07-19 21:48:51 +01:00
KodeStar b6112501e2 Merge pull request #231 from CHBMB/tvheadend
Add TVheadend to foundation apps
2018-07-19 21:47:16 +01:00
KodeStar 0663e236b4 Merge pull request #230 from CHBMB/patch-1
PfSense update
2018-07-19 21:46:30 +01:00
chbmb f25cea1749 Add FreshRSS logo 2018-07-19 19:57:26 +01:00
chbmb 03e16415aa Create FreshRSS.php 2018-07-19 19:56:39 +01:00
chbmb 9a55e05943 Add FreshRSS 2018-07-19 19:55:21 +01:00
chbmb c06fa4eab6 Update readme.md 2018-07-19 19:54:24 +01:00
chbmb 5575b082ea Update and rename Bookstack.php to BookStack.php 2018-07-18 21:18:19 +01:00
chbmb 1c6da858bc Update Item.php 2018-07-18 21:17:33 +01:00
chbmb f0a14641c1 Update readme.md 2018-07-18 21:17:03 +01:00
chbmb c6d07cd8a4 Update readme.md 2018-07-18 21:15:48 +01:00
chbmb df9f07faf4 Add files via upload 2018-07-18 21:15:14 +01:00
chbmb a3dcc278d7 Create Bookstack.php 2018-07-18 21:13:53 +01:00
chbmb 5de473fa44 Add bookstack 2018-07-18 21:00:36 +01:00
chbmb 763c1545a6 Update readme.md 2018-07-18 20:47:25 +01:00
chbmb ecde7a0f32 Update readme.md 2018-07-18 20:46:27 +01:00
chbmb 7fc5e0abb5 Add TVheadend 2018-07-18 20:45:40 +01:00
chbmb 06a655ac0c Create TVheadend.php 2018-07-18 20:43:36 +01:00
chbmb 875ddaa834 Add TVheadend logo 2018-07-18 20:30:30 +01:00
chbmb 030fccbb50 Change pfSense logo to 250 x 250 2018-07-18 16:06:47 +01:00
chbmb 908f70d90a Update pfsense logo to new version 2018-07-18 16:02:11 +01:00
chbmb 8724ced531 pfSense New Logo/Colour 2018-07-18 16:00:30 +01:00
KodeStar aa1a3a95ca Merge pull request #227 from MindTooth/update_package_json
Cleaned up package.json
2018-07-09 12:54:35 +01:00
Birger J. Nordølum 0767dc075e Cleaned up package.json
And updated some dependencies.
2018-07-09 13:08:02 +02:00
KodeStar c8a6c89036 Merge pull request #225 from linuxserver/revert-217-fix_reported_errors
Revert "Changed from variable assignment to comparison"
2018-06-22 11:37:34 +01:00
KodeStar cafe386cc4 Revert "Changed from variable assignment to comparison" 2018-06-22 11:36:58 +01:00
KodeStar 0184c9695b Merge pull request #218 from MindTooth/new_view
Cleaned of variable population in scripts.blade.php
2018-06-22 11:15:26 +01:00
KodeStar 19536edf28 Merge pull request #222 from MindTooth/add_info_to_files
Clarified _rune.scss file
2018-06-22 11:09:37 +01:00
KodeStar 045e4a20fa Merge pull request #213 from MindTooth/tweak_readme
Readme style tweaks
2018-06-22 11:09:13 +01:00
Birger J. Nordølum 6cb8487a52 Clarified _rune.scss file 2018-06-21 17:41:04 +02:00
Birger J. Nordølum c39e9aa13f Trim variable in script view for create/edit.blade
Removed the large logic to populate the varible in page specific view.
2018-06-20 23:42:31 +02:00
KodeStar 0203440b06 Merge pull request #217 from MindTooth/fix_reported_errors
Changed from variable assignment to comparison
2018-06-20 21:20:12 +01:00
Birger J. Nordølum 7f7bf60456 Changed from variable assignment to comparison
Issue reported by CodeFactor:
https://www.codefactor.io/repository/github/mindtooth/heimdall/file/master/database/seeds/SettingsSeeder.php
2018-06-18 00:34:05 +02:00
KodeStar e8673634bc Merge pull request #216 from MindTooth/fix_error
Fixes compile error with webpack.mix.js and app.js
2018-06-17 22:33:33 +01:00
KodeStar 53e52c93ee Merge pull request #214 from MindTooth/up_node_packages
Up packages.json to reflect upstream Laravel 5.5
2018-06-17 22:32:17 +01:00
Birger J. Nordølum c239c0ea5a Compiled new source for fix 2018-06-17 23:19:45 +02:00
Birger J. Nordølum 7142f755f5 Fixes error thrown by UglifyJS 2018-06-17 23:17:35 +02:00
Birger J. Nordølum 9fbc8dc1f9 Fix missing bracket in app.js 2018-06-17 23:17:35 +02:00
Birger J. Nordølum d3819a6a88 Last fix for Huebee issue.
After some major debugging once again, I've concluded that the previous
webpack.mix.js worked fine, but threw an error when minifying the app.js
file.  The culprit is because the current app.js contains some newer
ECMAScript code that needs to be translated.  However, with the current
inclusion of huebee.js into the samme command, it seems to mess things
up.

Just as a potensial fix for now is to just ignore the issue, and have a
stab at it at a later date.  This reverts the "fixes" I've made before.
2018-06-16 15:15:00 +02:00
Birger J. Nordølum 6e93ed8e5f Up packages.json to reflect upstream Laravel 5.5
This updates laravel-mix to 2.0.  Removed node-sass,
as it's already pulled by laravel-mix.
2018-06-16 14:56:45 +02:00
Birger J. Nordølum 98543d49a9 Readme style tweaks 2018-06-16 14:11:48 +02:00
KodeStar 9195eead27 Merge pull request #208 from MindTooth/fix_huebee
Fixes bug introduced in #203
2018-06-16 12:06:04 +01:00
KodeStar e5b384736d Merge pull request #209 from dansoaress/master
Brazilian Portuguese translation
2018-06-15 14:14:48 +01:00
Daniel Soares 4def720d1a spell checking 2018-06-14 14:06:59 -03:00
Daniel Soares 2a0404ea17 Brazilian Portuguese translation 2018-06-14 07:02:14 -03:00
Birger J. Nordølum 6d22c4f02e Fixes bug introduced in #203
Needs to import the library when using webpack.mix.js.
Will also be the case for future libraries.
2018-06-14 00:20:42 +02:00
KodeStar 24ac12da65 Merge pull request #207 from MindTooth/fix_app_js
Fix issue with using override_url and running a test
2018-06-13 22:39:44 +01:00
Birger J. Nordølum 3f19882df8 All the other tweaks 2018-06-13 22:35:51 +02:00
Birger J. Nordølum dd54c16c1f Fixed test when using override_url 2018-06-13 22:35:51 +02:00
Kode 223e9289dc include arrow in text color fix 2018-06-13 20:11:28 +01:00
Kode 2e301bdd51 This closes #184, closes #126 2018-06-13 20:03:26 +01:00
Kode e3ec7de23a Dependency updates and update version number 2018-06-13 19:35:28 +01:00
KodeStar 18ec208381 Merge pull request #205 from MindTooth/add_gitattribute
.gitattributes: More settings added
2018-06-13 15:22:04 +01:00
KodeStar 8666daa07d Merge pull request #197 from finish06/master
Add App - Flood
2018-06-13 15:20:24 +01:00
KodeStar 926a9bdb03 Merge pull request #190 from ullbergm/app-Mylar
Foundation App: Mylar
2018-06-13 15:18:41 +01:00
Birger J. Nordølum fc2d837a2c .gitattributes: More settings added 2018-06-13 16:15:38 +02:00
KodeStar 3f69ccab99 Merge pull request #192 from ullbergm/app-Headphones
Foundation App: Headphones
2018-06-13 15:09:58 +01:00
KodeStar b6ee82ee52 Merge pull request #201 from shuaiscott/master
Enhanced App: Deluge
2018-06-13 15:09:25 +01:00
KodeStar da1eb859a9 Merge pull request #202 from MindTooth/enhanced_traefik
Enhanced App: Traefik
2018-06-13 15:08:11 +01:00
KodeStar 2b5269b823 Merge pull request #203 from MindTooth/fix_webpack
Fixes typo in webpack.mix.js
2018-06-13 15:07:19 +01:00
ullbergm 6c8eeb0ced Merge branch 'master' into app-Mylar 2018-06-10 07:39:37 -04:00
Magnus Ullberg c5e0f3abc8 Revert "Merge branch 'master' into app-Mylar"
This reverts commit 586941ece7, reversing
changes made to 263a4578d4.
2018-06-10 07:34:48 -04:00
Birger J. Nordølum c6dbe22c57 Fixes typo in webpack.mix.js 2018-06-10 13:20:46 +02:00
KodeStar 51776e2aa3 Merge pull request #200 from ullbergm/Add-option-to-open-links-in-current-window-or-new-tab
WIP: Add option to open links in current window or new tab
2018-06-10 09:01:25 +01:00
KodeStar c9d24607f6 Merge pull request #199 from MindTooth/tweak_names
lang_en: Reworded some strings, and removed whitespace
2018-06-10 08:53:37 +01:00
KodeStar 46f7a3d4f3 Merge pull request #198 from MindTooth/transmission_url
Transmission: Added custom URL
2018-06-10 08:50:33 +01:00
KodeStar 56cf450c89 Merge pull request #195 from ullbergm/app-MusicBrainz
Foundation App: MusicBrainz
2018-06-10 08:36:33 +01:00
KodeStar 38c350b020 Merge pull request #194 from ullbergm/app-LibreNMS
Foundation App: LibreNMS
2018-06-10 08:30:09 +01:00
KodeStar 1f46040f1b Merge pull request #193 from ullbergm/app-LazyLibrarian
Foundation App: LazyLibrarian
2018-06-10 08:29:03 +01:00
KodeStar 63b95319cd Merge pull request #191 from ullbergm/app-Booksonic
Foundation App: Booksonic
2018-06-10 08:25:17 +01:00
Birger J. Nordølum a25d92be9e Traefik: enhanced conversion 2018-06-09 18:20:36 +02:00
Scott Carlson a161210a4a Moving Deluge to Enhanced List 2018-06-08 15:39:57 -05:00
shuaiscott 24469eb2fa Adding Enhanced Deluge 2018-06-08 13:58:17 -06:00
ullbergm a93fb49875 Update Item.php 2018-06-07 17:35:01 -04:00
ullbergm 08d7cdf95b Update SettingsSeeder.php 2018-06-07 12:34:35 -04:00
ullbergm a9334bc247 Update Item.php 2018-06-07 12:33:40 -04:00
ullbergm 2357d0c466 Update app.php 2018-06-07 12:33:14 -04:00
ullbergm b003d51276 Update SettingsSeeder.php 2018-06-07 12:32:45 -04:00
ullbergm 503cbf9830 Update SettingsSeeder.php 2018-06-07 12:32:08 -04:00
ullbergm 2466058c5a Update Item.php 2018-06-07 12:31:26 -04:00
Magnus Ullberg 6b1f422456 Initial stab at allowing you to select how links open. 2018-06-07 12:17:08 -04:00
Birger J. Nordølum 1d16d67733 lang_en: Reworded some strings, and removed whitespace 2018-06-07 10:49:35 +02:00
Birger J. Nordølum 6f9d15aed8 Transmission: Added custom URL 2018-06-07 10:42:02 +02:00
ullbergm 8725f974da Update readme.md 2018-06-06 19:09:42 -04:00
ullbergm 2551c949ae Update Item.php 2018-06-06 19:08:51 -04:00
ullbergm 30c6020ce7 Delete LazyLibrarian.php 2018-06-06 19:08:32 -04:00
ullbergm d00b1ce1a1 Delete lazylibrarian.png 2018-06-06 19:08:12 -04:00
Caleb Dunn 2c43d79585 Add Flood class 2018-06-05 11:18:49 -05:00
Caleb Dunn 3e4aacb2b0 Add Flood 2018-06-05 11:17:17 -05:00
KodeStar 67cd22371b Merge pull request #189 from ullbergm/app-Rancher
Foundation App: Rancher
2018-06-05 11:59:24 +01:00
ullbergm 586941ece7 Merge branch 'master' into app-Mylar 2018-06-04 21:41:52 -04:00
ullbergm 32a57cbfa6 Merge pull request #5 from ullbergm/app-Headphones
Added Headphones support.
2018-06-04 21:41:04 -04:00
ullbergm 1837a69b3e Merge pull request #4 from ullbergm/app-Booksonic
Added Booksonic support.
2018-06-04 21:40:38 -04:00
ullbergm aa8bfcfd92 Merge pull request #3 from ullbergm/app-MusicBrainz
Added MusicBrainz support.
2018-06-04 21:40:00 -04:00
ullbergm 9e0c658470 Merge pull request #2 from ullbergm/app-LibreNMS
Added LibreNMS support.
2018-06-04 19:20:01 -04:00
ullbergm 66aefff4f3 Merge branch 'master' into app-LibreNMS 2018-06-04 19:19:41 -04:00
ullbergm bd0fdeecee Merge pull request #1 from ullbergm/app-LazyLibrarian
Added LazyLibrarian support.
2018-06-04 19:18:25 -04:00
Magnus Ullberg 1055eeb01b Added Rancher support. 2018-06-04 19:13:30 -04:00
Magnus Ullberg 263a4578d4 Added Mylar support. 2018-06-04 19:13:08 -04:00
Magnus Ullberg c446b8a5af Added MusicBrainz support. 2018-06-04 19:12:24 -04:00
Magnus Ullberg 847b34cdcb Added LibreNMS support. 2018-06-04 19:12:02 -04:00
Magnus Ullberg 5a57f90b8f Added LazyLibrarian support. 2018-06-04 19:11:36 -04:00
Magnus Ullberg f8eb9f5bd0 Added Headphones support. 2018-06-04 19:11:11 -04:00
Magnus Ullberg c8c336b574 Added Booksonic support. 2018-06-04 19:10:22 -04:00
KodeStar 43f1410974 added fileinfo note to installing section 2018-05-25 09:12:32 +01:00
KodeStar 1df110b3fb update app version 2018-05-04 17:57:03 +01:00
KodeStar 9bedce0df5 Merge pull request #177 from CHBMB/patch-1
Add unRAID to readme
2018-05-03 23:19:24 +01:00
chbmb ae1d879e5a Add unRAID to readme 2018-05-03 21:56:24 +01:00
KodeStar caab2e0952 Merge pull request #176 from ninthwalker/master
Add Now Showing to Supported Apps
2018-05-01 21:55:16 +01:00
ninthwalker a29d6517d3 add NowShowing 2018-05-01 11:43:56 -07:00
ninthwalker dae2781818 Add files via upload 2018-05-01 11:34:56 -07:00
ninthwalker c1de609b1a Create NowShowing.php 2018-05-01 11:31:54 -07:00
KodeStar 4e84807950 Merge pull request #173 from CHBMB/patch-5
Add Unraid to supported apps
2018-04-30 18:45:00 +01:00
chbmb 41c9cb45d6 Add files via upload 2018-04-29 01:39:27 +01:00
chbmb 2d72772f86 Delete unraid.png 2018-04-29 01:39:11 +01:00
chbmb 1cf1f0e04d Update Item.php 2018-04-29 01:30:45 +01:00
chbmb 324b88ec2b Add files via upload 2018-04-29 01:29:08 +01:00
chbmb ec64c7ba0b Create Unraid.php 2018-04-29 01:27:48 +01:00
KodeStar 67e0f8570e fix autofocus 2018-04-25 23:03:48 +01:00
KodeStar 1745100705 fix @CHBMB 's fsckup 2018-04-25 22:58:14 +01:00
KodeStar 28501944c5 Merge pull request #172 from CHBMB/master
Add StartPage support
2018-04-25 22:46:50 +01:00
chbmb c5c1a68f5c Merge pull request #3 from CHBMB/patch-4
Update SettingsSeeder.php
2018-04-25 22:41:54 +01:00
chbmb e2ed7fbd28 Merge pull request #2 from CHBMB/patch-3
Update app.php
2018-04-25 22:41:36 +01:00
chbmb ab0675055c Merge pull request #1 from CHBMB/patch-2
Update Setting.php
2018-04-25 22:41:14 +01:00
chbmb 2b65559f36 Update SettingsSeeder.php 2018-04-25 22:40:15 +01:00
chbmb b8beb07df5 Update app.php 2018-04-25 22:39:29 +01:00
chbmb 01748fec49 Update Setting.php 2018-04-25 22:38:30 +01:00
KodeStar 42a50b1a02 Merge pull request #169 from ferrymanders/master
AllowOverride explained for apache .htaccess
2018-04-17 09:03:41 +01:00
Ferry Manders d81595f43f AllowOverride explained for apache .htaccess
added extra example so users have a reference
2018-04-12 10:36:45 +02:00
Ferry Manders 71fa2d867f AllowOverride explained for apache .htaccess
In some apache installations .htaccess is disallowed by default. explained a few fixes/work arounds.
2018-04-12 10:32:32 +02:00
KodeStar f55dbb0002 Merge pull request #165 from kimpenhaus/master
added autofocus to search input #149
2018-04-11 15:02:19 +01:00
KodeStar 3e4d623786 Update readme.md 2018-04-06 09:13:30 +01:00
KodeStar 1b109aac3a Merge pull request #166 from halorrr/patch-1
SupportedApp: Syncthing
2018-04-06 09:02:50 +01:00
KodeStar 8558975d55 Merge pull request #164 from albertsj1/fix_cp_icon
fix couchpotato icon capitalization
2018-04-04 09:45:20 +01:00
halorrr 0e895089c7 Create Syncthing.php 2018-04-04 01:31:43 -04:00
halorrr 5dd44f66c1 Update Item.php 2018-04-04 01:26:08 -04:00
halorrr a1cfea46c6 Add files via upload 2018-04-04 07:25:18 +02:00
halorrr 42c492c85a Update readme.md 2018-04-04 01:24:07 -04:00
Marcus Kimpenhaus 9e8794a39f added autofocus to search input #149 2018-04-02 11:13:49 +02:00
John Alberts 66c3604b2a fix couchpotato icon capitalization 2018-03-31 22:29:59 -07:00
KodeStar c0ee1ee27b Update app.php 2018-03-27 10:57:49 +01:00
KodeStar a3e669e433 Merge pull request #162 from halorrr/master
Bug Fix On Newly Added Apps
2018-03-27 10:52:29 +01:00
halorrr 8a83b4fff5 Capitalized first letter of filename to fix link 2018-03-26 09:29:26 -04:00
halorrr 69c48d3f5d Deleted extra space at beginning of file 2018-03-26 09:28:53 -04:00
halorrr 88504a335e Deleted extra space at beginning of file 2018-03-26 09:28:39 -04:00
halorrr a44a433807 Deleted extra space at beginning of file 2018-03-26 09:28:26 -04:00
halorrr 9c03a8ae28 Deleted extra space at beginning of file 2018-03-26 09:28:12 -04:00
halorrr 767a5f3a94 Deleted extra space at beginning of file 2018-03-26 09:27:57 -04:00
halorrr db1e138d36 Deleted extra space at beginning of file 2018-03-26 09:27:36 -04:00
halorrr 84aa05f9a9 Deleted extra space at beginning of file 2018-03-26 09:27:19 -04:00
KodeStar 1071b85472 Merge pull request #160 from LiamAkkerman/master
SupportedApp: Grafana
2018-03-26 08:34:56 +01:00
KodeStar 479412b190 Merge pull request #157 from halorrr/patch-2
SupportedApp: Cardigann
2018-03-26 08:34:26 +01:00
KodeStar ac4fc5b0ba Merge pull request #156 from halorrr/patch-1
SupportedApp: pyLoad
2018-03-26 08:33:28 +01:00
KodeStar 4a8770232d Merge pull request #158 from rigrassm/mobile-app-compatible
Add html needed to allow the site to load as a mobile app
2018-03-26 08:31:40 +01:00
Liam B. Akkerman 2ea983bdae rename grafana icon file 2018-03-24 21:40:52 -07:00
Liam B. Akkerman ffce8fa505 add grafana to readme 2018-03-24 21:37:07 -07:00
Liam B. Akkerman cb9e529eb7 add grafana to Item.php 2018-03-24 21:35:23 -07:00
Liam B. Akkerman 7f0ee208fa add grafana icon 2018-03-24 21:29:46 -07:00
Liam B. Akkerman 2d38652034 add grafana app php 2018-03-24 21:23:15 -07:00
Ricky Grassmuck 4a2076a550 One more indentation fix
This time I really did fix it I swear!
2018-03-23 18:25:36 -05:00
Ricky Grassmuck 35049b26fe Fix Indentation
Fixed indentation of newly added lines to match existing lines.
2018-03-23 18:24:40 -05:00
Ricky Grassmuck 39648ba372 Add html needed to allow the site to load as a mobile app 2018-03-23 18:11:04 -05:00
KodeStar 44ce0bbffd Merge pull request #155 from imcdona/master
Document adding a supported application
2018-03-22 15:01:44 +00:00
halorrr a634472873 Create Cardigann.php 2018-03-21 11:28:30 -04:00
halorrr a98c30f7fa Update Item.php 2018-03-21 11:25:31 -04:00
halorrr 43d4b80e11 Add files via upload 2018-03-21 16:24:47 +01:00
halorrr 09926fcc53 Update readme.md 2018-03-21 11:24:14 -04:00
halorrr 17eef7a4aa Update pyLoad.php 2018-03-21 11:17:12 -04:00
halorrr 4738d7c951 Create pyLoad.php 2018-03-21 11:07:16 -04:00
halorrr 4be0af5fa3 Update Item.php 2018-03-21 11:06:33 -04:00
halorrr 8aaa0900e5 Add files via upload 2018-03-21 16:05:38 +01:00
halorrr 49b5d9b886 Update readme.md 2018-03-21 11:03:40 -04:00
Isaac McDonald 7a3912767b Document adding a supported application
If you type the name of a supported application quickly enough in the title field, you'll never see the option to select that application from the list. Long term I think this needs to be addressed. In the short term, an explanation will suffice.
2018-03-21 07:52:47 -07:00
KodeStar d1e473aafe Merge pull request #151 from halorrr/patch-3
SupportedApp: Watcher3
2018-03-21 12:59:41 +00:00
KodeStar c91eb7ed47 Merge branch 'master' into patch-3 2018-03-21 12:59:21 +00:00
KodeStar 443f631bac Merge pull request #146 from halorrr/patch-1
SupportedApp: AirSonic
2018-03-21 12:57:53 +00:00
KodeStar 95be8d4698 Merge branch 'master' into patch-1 2018-03-21 12:57:39 +00:00
KodeStar f3926d020f Merge pull request #154 from imcdona/master
Changed pFsense to the proper pfSense. Changed Ttrss to tt-rss
2018-03-21 12:56:13 +00:00
KodeStar b48eb5fdd3 Merge pull request #153 from albertsj1/better_transmission_icon
New Transmission icon with transparent background
2018-03-21 12:55:41 +00:00
KodeStar b0fecdd017 Merge pull request #147 from halorrr/patch-2
SupportedApp: OpenVaultMedia
2018-03-21 12:55:08 +00:00
KodeStar 793483b6e9 Merge pull request #145 from halorrr/master
SupportedApp: WebTools
2018-03-21 12:54:21 +00:00
Isaac McDonald c99c7fa9af Changed pFsense to the proper pfSense. Changed Ttrss to tt-rss 2018-03-20 14:15:01 -07:00
John Alberts 59449a73e1 New Transmission icon with transparent background 2018-03-20 08:31:12 -07:00
halorrr dc86d636ac Create Watcher3.php 2018-03-18 09:20:39 -04:00
halorrr 27dd2dd5f3 Update Item.php 2018-03-18 09:18:27 -04:00
halorrr 494ae1a47f Add files via upload 2018-03-18 14:17:25 +01:00
halorrr 7d1e1e5ff1 Update readme.md 2018-03-18 09:09:10 -04:00
KodeStar bcd1567b7d Merge pull request #133 from albertsj1/couchpotato
Add Couchpotato as an enhanced app
2018-03-17 13:18:03 +00:00
KodeStar ae391b885b added missing dataonly attribute so it polls every 20 seconds 2018-03-17 13:17:45 +00:00
KodeStar 226bc84a4c removed duplicate semi-colon 2018-03-17 13:15:39 +00:00
halorrr e60a0c8f61 Logo for OpenMediaVault 2018-03-17 07:07:50 +01:00
halorrr 218c90a306 Delete openvaultmedia.png 2018-03-17 02:07:29 -04:00
halorrr 2a60c80194 Create OpenMediaVault.php 2018-03-17 02:06:26 -04:00
halorrr 35b1c55564 Update Item.php 2018-03-17 02:05:32 -04:00
halorrr 20476387ff Add files via upload 2018-03-17 07:04:23 +01:00
halorrr a787748a00 Update readme.md 2018-03-17 02:03:43 -04:00
halorrr 34ee540c30 Changed default colour for AirSonic 2018-03-17 02:02:35 -04:00
halorrr 975a5ffc82 Create AirSonic.php 2018-03-17 01:52:17 -04:00
halorrr dee0870bf6 Airsonic added 2018-03-17 01:48:40 -04:00
halorrr 96ec3bd44e Airsonic logo added 2018-03-17 06:47:20 +01:00
halorrr e4cf4096a6 Adding AirSonic to readme 2018-03-17 01:46:12 -04:00
halorrr 3d79694c0a Create WebTools.php 2018-03-17 01:24:14 -04:00
halorrr eab3e4e6f7 Update Item.php 2018-03-17 01:19:30 -04:00
halorrr 462152bab2 Update readme.md 2018-03-17 01:17:33 -04:00
halorrr 766a455db0 Add files via upload 2018-03-17 06:16:06 +01:00
John Alberts 30200ac219 Get rid off aggressive polling option and always use inactive status 2018-03-16 15:08:04 -07:00
KodeStar 90a9113971 Merge pull request #140 from halorrr/master
FoundationApp: Krusader closes #144
2018-03-16 22:00:17 +00:00
KodeStar ad1834568f Merge pull request #141 from halorrr/patch-1
Adding Tautulli to Enhanced Apps
2018-03-16 21:58:19 +00:00
KodeStar 6231500b4a Merge pull request #142 from grOGH/master
Add a readme section about using self-signed certificates with enhanced apps
2018-03-15 13:04:38 +00:00
grOGH b2dbc08ea0 Add a readme section about using self-signed certificates with enhanced
apps
2018-03-15 08:48:56 +01:00
KodeStar 4700f68f4d Update readme.md 2018-03-13 21:09:59 +00:00
halorrr fa73738309 Update readme.md 2018-03-13 16:01:44 -04:00
halorrr 25f92ec438 Create tautulli.blade.php 2018-03-13 16:01:14 -04:00
halorrr 6a59c1dfd6 Update Item.php 2018-03-13 15:58:37 -04:00
halorrr bad6e9d2fe Create Tautulli.php 2018-03-13 15:57:14 -04:00
halorrr e544972c1d Add files via upload 2018-03-13 20:56:12 +01:00
halorrr f1e5de0d58 Update readme.md 2018-03-13 15:52:44 -04:00
halorrr e434e1effb Update readme.md 2018-03-13 15:32:54 -04:00
halorrr ca04b210e6 Update Item.php 2018-03-13 12:38:29 -04:00
halorrr 51275af41d Create Krusader.php 2018-03-13 12:35:26 -04:00
halorrr c2417ac5b3 Add files via upload 2018-03-13 17:32:04 +01:00
John Alberts 72831d413b update couchpotato icon 2018-03-13 08:14:18 -07:00
John Alberts 5cb4bd5819 Icon name should be lower case. 2018-03-13 06:49:05 -07:00
KodeStar 2d9bbca9a9 Merge pull request #135 from albertsj1/fix_transmission_pic
Fix capitalization of tranmission icon name
2018-03-13 09:36:29 +00:00
KodeStar 7b54c4e969 Merge pull request #134 from albertsj1/update_readme
add some apps to the enhanced app section of the readme that were mis…
2018-03-13 09:35:54 +00:00
Chris b50f4ec5ce Merge branch 'master' of https://github.com/linuxserver/Heimdall 2018-03-12 09:59:43 +00:00
Chris 86cc7534c2 fix html error in link, but replaced target _blank to a named window to keep the experience 2018-03-12 09:59:37 +00:00
John Alberts 1ab2565244 Fix capitalization of tranmission icon name 2018-03-11 21:23:01 -07:00
John Alberts d2089a9344 add some apps to the enhanced app section of the readme that were missing. 2018-03-11 21:12:25 -07:00
John Alberts 39153c6936 Add Couchpotato as an enhanced app 2018-03-11 20:48:58 -07:00
KodeStar 1a8e2b92de closes #128 2018-03-11 17:47:05 +00:00
KodeStar cf63e751bf Merge pull request #127 from albertsj1/add_transmission
Add Enhanced App Transmission
2018-03-11 17:41:02 +00:00
KodeStar 0c51bc2771 fix multiple tags 2018-03-11 17:40:08 +00:00
John Alberts 5f278cce3e cleanup a couple symlinks I didn't intend to commit and some errant whitespace 2018-03-09 07:59:01 -08:00
KodeStar f8cf3ac832 Merge pull request #125 from frenos/foundation_glances
Foundation App for Glances
2018-03-09 08:05:07 +00:00
John Alberts 50bdd02a72 Add Enhanced App Transmission 2018-03-08 16:18:39 -08:00
frenos 424155e5cd Foundation App for Glances
Default color is the backgroundcolor of the official site.
2018-03-07 17:39:45 +01:00
Chris c4a4d25f7e change js version to break cache 2018-03-06 09:43:54 +00:00
KodeStar ca2e135cba closes #122, closes #82, 2018-03-05 19:38:23 +00:00
KodeStar 8b4583c59c update version 2018-03-01 19:21:18 +00:00
KodeStar 6a836f9151 Merge pull request #118 from Futos/add-new-foundationApps
Add new foundation apps
2018-03-01 10:16:43 +00:00
Futos c7b92ad945 fix(SupportedApps): fixed class name 2018-02-28 13:04:45 +01:00
Futos a05b7a43bd feat(SupportedApps): Added DokuWiki to Foundation Apps
Closes #104
2018-02-28 13:03:17 +01:00
Futos 929346b2f1 feat(SupportedApps): Added SickRage to Foundation Apps
Closes #102
2018-02-28 12:58:00 +01:00
Futos 23ceed01cb feat(SupportedApps): Added Gitea to Foundation Apps
Closes #101
2018-02-28 12:52:11 +01:00
KodeStar 2ccf9a1110 Merge pull request #115 from mrquatsch/runeaudio
Add Runeaudio to list of foundation apps
2018-02-26 12:02:35 +00:00
mrquatsch 4917d8e47b updated runeaudio scss to bump keyframes outside of the title-marquee 2018-02-25 20:44:24 -06:00
mrquatsch a0963e5d92 add Runeaudio to app/Item list 2018-02-25 20:41:19 -06:00
KodeStar e2731b532a Update readme.md 2018-02-25 20:26:33 +00:00
KodeStar eccd6056bd Merge pull request #112 from mrquatsch/runeaudio
enhanced runeaudio app - displays artist and song
2018-02-25 16:39:20 +00:00
mrquatsch c1273a4b01 new rune scss - imported in app.scss 2018-02-25 08:23:45 -06:00
KodeStar 017752b06e Merge pull request #113 from Ephelyon/master
Add Dutch translation
2018-02-25 11:45:13 +00:00
KodeStar 9abb7a04ac Merge pull request #114 from mrquatsch/patch-1
Rename plexpy.blade.app to plexpy.blade.php
2018-02-25 11:44:37 +00:00
mrquatsch 9533b9d887 Rename plexpy.blade.app to plexpy.blade.php 2018-02-24 13:58:54 -06:00
Ephelyon f1a6feeb8f Add Dutch translation 2018-02-24 18:54:31 +00:00
KodeStar 35930f2ffb Merge pull request #111 from mrquatsch/enhanced_plexpy
Enhanced Plexpy - display stream count via api token
2018-02-23 11:18:56 +00:00
mrquatsch 0a1e8a2f8b enhanced runeaudio app - displays artist and song 2018-02-22 13:41:30 -06:00
mrquatsch 4f9315132b Enhanced Plexpy - display stream count via api token 2018-02-22 13:27:44 -06:00
KodeStar 196a843148 Merge pull request #105 from Attoy/master
Update readme.md
2018-02-20 12:23:21 +00:00
KodeStar 9778875d52 Merge branch 'master' into master 2018-02-20 12:23:10 +00:00
KodeStar fdeb812333 Merge pull request #106 from kehator/master
Add PL translation
2018-02-20 11:51:35 +00:00
KodeStar e21e12e737 Update SettingsSeeder.php 2018-02-20 11:51:18 +00:00
nuc 52d2322955 Rough translation based on EN translation 2018-02-20 05:40:50 +00:00
KodeStar 5ea8f7df33 Fix target link 2018-02-19 23:15:09 +00:00
Attoy 7a9c73df3f Update readme.md 2018-02-19 20:18:46 +01:00
KodeStar 1f38de989b fix routes 2018-02-18 22:36:32 +00:00
KodeStar c4f119de9c Fix routes in controllers for RP support 2018-02-18 22:15:14 +00:00
KodeStar fa2afa856a change release number 2018-02-18 19:23:17 +00:00
KodeStar 4c83680ae9 remove apps from tags 2018-02-18 19:21:42 +00:00
KodeStar 981665e3e3 Update readme.md 2018-02-18 19:04:19 +00:00
KodeStar b3185292b3 Merge pull request #100 from linuxserver/v1.4
fixes to RP
2018-02-18 18:39:35 +00:00
KodeStar 249f437ff5 fixes to RP 2018-02-18 18:38:43 +00:00
KodeStar a7563ab499 Merge pull request #99 from linuxserver/v1.4
V1.4
2018-02-18 17:51:26 +00:00
KodeStar 38f8143fd2 closes #46, #47, #77, #89 2018-02-18 17:48:52 +00:00
KodeStar a051c17010 style the tags + close #47 2018-02-18 17:23:05 +00:00
KodeStar 0b62f8a1c8 change icon for tags 2018-02-18 17:04:18 +00:00
KodeStar b803d4f49d fix mix 2018-02-17 23:18:20 +00:00
KodeStar 78e368f406 Merge branch 'master' into v1.4 2018-02-17 23:17:34 +00:00
KodeStar 90e613ab26 Update readme.md 2018-02-17 23:15:07 +00:00
KodeStar e15914dc2e Update readme.md 2018-02-17 23:09:21 +00:00
KodeStar ebe6c39237 Closes #86 2018-02-17 22:23:30 +00:00
KodeStar 3369de9660 possible fix for RP for forms 2018-02-17 20:37:23 +00:00
KodeStar 98b831bc22 folder support 2018-02-17 00:13:38 +00:00
KodeStar c0f741d914 Merge pull request #95 from cheesemarathon/master
feat: added Deluge to supported Apps - Closes #70
2018-02-16 17:37:35 +00:00
KodeStar 4c27a0cb5c Update Item.php 2018-02-16 17:37:09 +00:00
KodeStar 4ff5f139f7 fix indentation 2018-02-16 17:36:36 +00:00
cheesemarathon 59910ecadc Add Graylog 2018-02-16 16:28:48 +00:00
Chris 4e37176436 changes to allow preview of image first 2018-02-16 15:27:48 +00:00
Chris 35085248b6 some changes to test droppable 2018-02-16 15:15:22 +00:00
nuc 3ad8a366a6 Add Polish Translation 2018-02-16 11:22:11 +00:00
KodeStar b1660c92cc changed opening a link to new tab 2018-02-15 20:52:04 +00:00
KodeStar 6ec1a3d4cb Merge pull request #90 from Futos/adding-new-foundation-apps
Adding new foundation apps
2018-02-15 20:45:57 +00:00
KodeStar 86ffa86800 Merge branch 'master' into adding-new-foundation-apps 2018-02-15 20:45:08 +00:00
KodeStar 22ad29c92f crap image 2018-02-15 20:42:53 +00:00
KodeStar ebc1046ba6 Merge pull request #88 from cheesemarathon/master
feat: added Deluge to supported Apps - Closes #63
2018-02-15 20:41:50 +00:00
KodeStar 43e23b15dc update version 2018-02-15 20:33:36 +00:00
KodeStar c8effe757b fix for nzbget on new apps 2018-02-15 20:33:07 +00:00
Futos 40b5cd3cff feat(SupportedApps): added TT-RSS Application to Foundation Apps
Closes #72
2018-02-15 19:59:53 +01:00
Futos 26435d85e8 feat(SupportedApps): added NZBHydra Application to Foundation Apps
Closes #66
2018-02-15 19:51:38 +01:00
Futos b6d5e73708 feat(SupportedApps): added Deluge Application to Foundation Apps
Closes #63
2018-02-15 19:32:10 +01:00
Futos 2f193e0c83 feat(SupportedApps): added Medusa Application to Foundation Apps
Closes #64
2018-02-15 19:25:37 +01:00
Futos 4897c80646 feat(.gitignore): added MacOS generated files to ignore 2018-02-15 19:23:57 +01:00
cheesemarathon 601a455e08 Add Deluge 2018-02-15 15:03:41 +00:00
KodeStar d37f4fd77b Merge pull request #84 from cheesemarathon/master
feat: added ruTorrent to supported Apps - Closes #35
2018-02-15 14:07:37 +00:00
cheesemarathon c395cb2206 Replace with better logo 2018-02-15 14:01:18 +00:00
cheesemarathon b6f8c612f1 Removes icon background 2018-02-15 08:36:19 +00:00
cheesemarathon 18551528ca Removes icon background 2018-02-15 08:27:34 +00:00
cheesemarathon bbc7782f40 Adds ruTorrent 2018-02-15 08:22:37 +00:00
KodeStar c121341911 Update readme.md 2018-02-15 08:22:14 +00:00
3406 changed files with 135410 additions and 58665 deletions
+1 -1
View File
@@ -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
View File
@@ -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
# }}}
+16 -1
View File
@@ -9,4 +9,19 @@ Homestead.yaml
npm-debug.log
yarn-error.log
storage/app/public/.DS_Store
### macOS ###
*.DS_Store
.AppleDouble
.LSOverride
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
storage/app/public/avatars/*
+15
View File
@@ -1,5 +1,20 @@
# Release Notes
## v1.4.0 (2018-02-18)
### Added
- Tag(folder) support
- Image preview for uploading icons
- A load of supported apps, full list of apps https://github.com/linuxserver/Heimdall/projects/1
### Changed
- Edited vendor/laravelcollective/html/src/FormBuilder.php to allow relative links #3369de9
- Changed links to use relative links for reverse proxy support
- Links open in new tab
### Fixed
- adds all the fixes in the 1.3.x point releases and on master
## v1.3.0 (2018-02-09)
### Added
+24
View File
@@ -10,3 +10,27 @@ function format_bytes($bytes, $is_drive_size = true, $beforeunit = '', $afteruni
elseif($labels[$x] == "MB") return(round($bytes, 2).$beforeunit.$labels[$x].$afterunit);
else return(round($bytes, 0).$beforeunit.$labels[$x].$afterunit);
}
function get_brightness($hex) {
// returns brightness value from 0 to 255
// strip off any leading #
$hex = str_replace('#', '', $hex);
if(strlen($hex) == 3) {
$hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2];
}
$c_r = hexdec(substr($hex, 0, 2));
$c_g = hexdec(substr($hex, 2, 2));
$c_b = hexdec(substr($hex, 4, 2));
return (($c_r * 299) + ($c_g * 587) + ($c_b * 114)) / 1000;
}
function title_color($hex)
{
if(get_brightness($hex) > 130) {
return ' black';
} else {
return ' white';
}
}
+88 -1
View File
@@ -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.
+19
View File
@@ -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
View 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');
}
}
+47 -23
View File
@@ -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);
}
@@ -140,15 +148,21 @@ class ItemController extends Controller
}
$config = Item::checkConfig($request->input('config'));
$current_user = User::currentUser();
$request->merge([
'description' => $config
'description' => $config,
'user_id' => $current_user->id
]);
//die(print_r($request->input('config')));
Item::create($request->all());
$item = Item::create($request->all());
return redirect()->route('dash')
$item->parents()->sync($request->tags);
$route = route('dash', [], false);
return redirect($route)
->with('success', __('app.alert.success.item_created'));
}
@@ -172,11 +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);
}
/**
@@ -201,13 +216,19 @@ class ItemController extends Controller
}
$config = Item::checkConfig($request->input('config'));
$current_user = User::currentUser();
$request->merge([
'description' => $config
'description' => $config,
'user_id' => $current_user->id
]);
Item::find($id)->update($request->all());
$item = Item::find($id);
$item->update($request->all());
return redirect()->route('dash')
$item->parents()->sync($request->tags);
$route = route('dash', [], false);
return redirect($route)
->with('success',__('app.alert.success.item_updated'));
}
@@ -228,8 +249,9 @@ class ItemController extends Controller
} else {
Item::find($id)->delete();
}
return redirect()->route('items.index')
$route = route('items.index', [], false);
return redirect($route)
->with('success',__('app.alert.success.item_deleted'));
}
@@ -244,8 +266,10 @@ class ItemController extends Controller
//
Item::withTrashed()
->where('id', $id)
->restore();
return redirect()->route('items.index')
->restore();
$route = route('items.inded', [], false);
return redirect($route)
->with('success',__('app.alert.success.item_restored'));
}
+29 -12
View File
@@ -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
View 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
View 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'));
}
}
}
+1
View File
@@ -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
View 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);
+1 -7
View File
@@ -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;
}
+139 -7
View File
@@ -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,19 +37,45 @@ 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,
'Nextcloud' => \App\SupportedApps\Nextcloud::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,
'Openhab' => \App\SupportedApps\Openhab::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,
'Plexpy' => \App\SupportedApps\Plexpy::class,
@@ -46,10 +83,26 @@ class Item extends Model
'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()
@@ -82,7 +135,7 @@ class Item extends Model
$output->view = $view;
}
if(!isset($output->dataonly)) $output->dataonly = '0';
}
return (object)$output;
}
@@ -102,11 +155,90 @@ class Item extends Model
}
}
//die(var_dump($store))
$config['enabled'] = ($store) ? true : false;
$config = json_encode($config);
}
return $config;
}
public function parents()
{
return $this->belongsToMany('App\Item', 'item_tag', 'item_id', 'tag_id');
}
public function children()
{
return $this->belongsToMany('App\Item', 'item_tag', 'tag_id', 'item_id');
}
public function getLinkAttribute()
{
if((int)$this->type === 1) {
return '/tag/'.$this->url;
} else {
return $this->url;
}
}
public function getDroppableAttribute()
{
if((int)$this->type === 1) {
return ' droppable';
} else {
return '';
}
}
public function getLinkTargetAttribute()
{
$target = Setting::fetch('window_target');
if((int)$this->type === 1 || $target === 'current') {
return '';
} else {
return ' target="' . $target . '"';
}
}
public function getLinkIconAttribute()
{
if((int)$this->type === 1) {
return 'fa-tag';
} else {
return 'fa-arrow-alt-to-right';
}
}
public function getLinkTypeAttribute()
{
if((int)$this->type === 1) {
return 'tags';
} else {
return 'items';
}
}
public 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');
}
}
+54 -8
View File
@@ -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'));
@@ -32,12 +33,9 @@ class AppServiceProvider extends ServiceProvider
}
if(is_file(database_path('app.sqlite'))) {
if(Schema::hasTable('settings')) {
if($bg_image = Setting::fetch('background_image')) {
$alt_bg = ' style="background-image: url('.asset('storage/'.$bg_image).')"';
}
// check version to see if an upgrade is needed
$db_version = Setting::fetch('version');
$db_version = Setting::_fetch('version');
$app_version = config('app.version');
if(version_compare($app_version, $db_version) == 1) { // app is higher than db, so need to run migrations etc
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
@@ -45,14 +43,62 @@ class AppServiceProvider extends ServiceProvider
} else {
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
}
$lang = Setting::fetch('language');
\App::setLocale($lang);
}
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);
}
+84 -15
View File
@@ -5,6 +5,8 @@ namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Input;
use Form;
use Illuminate\Support\Facades\Auth;
use App\User;
class Setting extends Model
{
@@ -46,6 +48,12 @@ class Setting extends Model
public function getListValueAttribute()
{
if((bool)$this->system === true) {
$value = self::_fetch($this->key);
} else {
$value = self::fetch($this->key);
}
$this->value = $value;
switch($this->type) {
case 'image':
if(!empty($this->value)) {
@@ -80,6 +88,12 @@ class Setting extends Model
public function getEditValueAttribute()
{
if((bool)$this->system === true) {
$value = self::_fetch($this->key);
} else {
$value = self::fetch($this->key);
}
$this->value = $value;
switch($this->type) {
case 'image':
$value = '';
@@ -125,6 +139,7 @@ class Setting extends Model
return $this->belongsTo('App\SettingGroup', 'group_id');
}
/**
* @param string $key
*
@@ -132,20 +147,54 @@ class Setting extends Model
*/
public static function fetch($key)
{
if (Setting::cached($key)) {
return Setting::$cache[$key];
} else {
$user = self::user();
return self::_fetch($key, $user);
}
/**
* @param string $key
*
* @return mixed
*/
public static function _fetch($key, $user=null)
{
#$cachekey = ($user === null) ? $key : $key.'-'.$user->id;
#if (Setting::cached($cachekey)) {
# return Setting::$cache[$cachekey];
#} else {
$find = self::where('key', '=', $key)->first();
if (!is_null($find)) {
$value = $find->value;
Setting::add($key, $value);
if((bool)$find->system === true) { // if system variable use global value
$value = $find->value;
} else { // not system variable so use user specific value
// check if user specified value has been set
//print_r($user);
$usersetting = $user->settings()->where('id', $find->id)->first();
//print_r($user->settings);
//die(var_dump($usersetting));
//->pivot->value;
//echo "user: ".$user->id." --- ".$usersettings;
if(isset($usersetting) && !empty($usersetting)) {
$value = $usersetting->pivot->uservalue;
} else { // if not get default from base setting
//$user->settings()->save($find, ['value' => $find->value]);
#$has_setting = $user->settings()->where('id', $find->id)->exists();
#if($has_setting) {
# $user->settings()->updateExistingPivot($find->id, ['uservalue' => (string)$find->value]);
#} else {
# $user->settings()->save($find, ['uservalue' => (string)$find->value]);
#}
$value = $find->value;
}
}
#Setting::add($cachekey, $value);
return $value;
} else {
return false;
}
}
#}
}
/**
@@ -175,21 +224,23 @@ class Setting extends Model
$output = '';
$homepage_search = self::fetch('homepage_search');
$search_provider = self::where('key', '=', 'search_provider')->first();
//die(var_dump($search_provider->value));
$user_search_provider = self::fetch('search_provider');
//die(print_r($search_provider));
//die(var_dump($user_search_provider));
// return early if search isn't applicable
if((bool)$homepage_search !== true) return $output;
if($search_provider->value === 'none') return $output;
if(empty($search_provider->value)) return $output;
if(is_null($search_provider->value)) return $output;
if($user_search_provider === 'none') return $output;
if(empty($user_search_provider)) return $output;
if(is_null($user_search_provider)) return $output;
if((bool)$homepage_search && (bool)$search_provider) {
$options = (array)json_decode($search_provider->options);
$name = $options[$search_provider->value];
if((bool)$search_provider->value) {
switch($search_provider->value) {
$name = $options[$user_search_provider];
if((bool)$user_search_provider) {
switch($user_search_provider) {
case 'google':
$url = 'https://www.google.com/search';
$var = 'q';
@@ -202,11 +253,14 @@ class Setting extends Model
$url = 'https://www.bing.com/search';
$var = 'q';
break;
case 'startpage':
$url = 'https://www.startpage.com/';
$var = 'q';
}
$output .= '<div class="searchform">';
$output .= Form::open(['url' => $url, 'method' => 'get']);
$output .= '<div class="input-container">';
$output .= Form::text($var, null, ['class' => 'homesearch', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
$output .= Form::text($var, null, ['class' => 'homesearch', 'autofocus' => 'autofocus', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
$output .= '<button type="submit">'.ucwords(__('app.settings.search')).'</button>';
$output .= '</div>';
$output .= Form::close();
@@ -215,4 +269,19 @@ class Setting extends Model
}
return $output;
}
/**
* The users that belong to the setting.
*/
public function users()
{
return $this->belongsToMany('App\User')->using('App\SettingUser')->withPivot('uservalue');
}
public static function user()
{
return User::currentUser();
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Relations\Pivot;
class SettingUser extends Pivot
{
//
}
+11
View 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
View 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
View 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
View 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
View 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
View 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';
}
}
+122
View 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
View 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
View 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';
}
}
+12
View 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
View 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
View 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
View 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
View 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
View 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
View 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';
}
}
+11
View 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
View 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
View 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
View 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
View 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
View 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';
}
}
+11
View 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';
}
}
+11 -9
View File
@@ -39,25 +39,27 @@ class Nzbget implements Contracts\Applications, Contracts\Livestats {
}
public function executeConfig()
{
$output = '';
$html = '';
$active = 'inactive';
$res = $this->buildRequest('status');
$data = json_decode($res->getBody());
//$data->result->RemainingSizeMB = '10000000';
//$data->result->DownloadRate = '100000000';
$size = $data->result->RemainingSizeMB;
$rate = $data->result->DownloadRate;
$queue_size = format_bytes($size*1000*1000, false, ' <span>', '</span>');
$current_speed = format_bytes($rate, false, ' <span>');
if($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>');
if($size > 0 || $rate > 0) {
$output = '
$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 $output;
return json_encode(['status' => $active, 'html' => $html]);
}
public function buildRequest($endpoint)
{
@@ -73,7 +75,7 @@ class Nzbget implements Contracts\Applications, Contracts\Livestats {
$api_url = $rebuild_url.'/jsonrpc/'.$endpoint;
$client = new Client(['http_errors' => false]);
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
$res = $client->request('GET', $api_url);
return $res;
+12
View 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
View 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
View 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';
}
}
+2 -2
View File
@@ -3,10 +3,10 @@
class Pfsense implements Contracts\Applications {
public function defaultColour()
{
return '#4e4742';
return '#243699';
}
public function icon()
{
return 'supportedapps/pfsense.png';
}
}
}
+5 -4
View File
@@ -39,17 +39,18 @@ class Pihole implements Contracts\Applications, Contracts\Livestats {
public function executeConfig()
{
$output = '';
$html = '';
$active = 'active';
$res = $this->buildRequest();
$data = json_decode($res->getBody());
$output = '
$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 $output;
return json_encode(['status' => $active, 'html' => $html]);
}
public function buildRequest()
@@ -62,7 +63,7 @@ class Pihole implements Contracts\Applications, Contracts\Livestats {
$api_url = $url.'/api.php';
//die( $api_url.' --- ');
$client = new Client(['http_errors' => false]);
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
$res = $client->request('GET', $api_url);
return $res;
+67 -2
View File
@@ -1,6 +1,12 @@
<?php namespace App\SupportedApps;
class Plexpy implements Contracts\Applications {
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
class Plexpy implements Contracts\Applications, Contracts\Livestats {
public $config;
public function defaultColour()
{
return '#2d2208';
@@ -9,4 +15,63 @@ class Plexpy implements Contracts\Applications {
{
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
View 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
View 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;
}
}
+18 -13
View File
@@ -44,25 +44,27 @@ class Sabnzbd implements Contracts\Applications, Contracts\Livestats {
}
public function executeConfig()
{
$output = '';
$html = '';
$active = 'inactive';
$res = $this->buildRequest('queue');
$data = json_decode($res->getBody());
//$data->result->RemainingSizeMB = '10000000';
//$data->result->DownloadRate = '100000000';
$size = $data->queue->mbleft;
$rate = $data->queue->kbpersec;
$queue_size = format_bytes($size*1000*1000, false, ' <span>', '</span>');
$current_speed = format_bytes($rate*1000, false, ' <span>');
if($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>');
if($size > 0 || $rate > 0) {
$output = '
<ul class="livestats">
<li><span class="title">Queue</span><strong>'.$queue_size.'</strong></li>
<li><span class="title">Speed</span><strong>'.$current_speed.'/s</span></strong></li>
</ul>
$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 $output;
return json_encode(['status' => $active, 'html' => $html]);
}
public function buildRequest($endpoint)
{
@@ -70,12 +72,15 @@ class Sabnzbd implements Contracts\Applications, Contracts\Livestats {
$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]);
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
$res = $client->request('GET', $api_url);
return $res;
+12
View 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';
}
}
+11
View 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
View 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
View 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;
}
}
+68 -2
View File
@@ -1,12 +1,78 @@
<?php namespace App\SupportedApps;
class Traefik implements Contracts\Applications {
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
View 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
View 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';
}
}
+12
View 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
View 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
View 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
View 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
View 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
View 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
View 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';
}
}
+32 -1
View File
@@ -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;
}
}
}
+2 -2
View File
@@ -6,9 +6,9 @@
"type": "project",
"require": {
"php": ">=7.0.0",
"fideloper/proxy": "~3.3",
"fideloper/proxy": "^4.0",
"guzzlehttp/guzzle": "^6.3",
"laravel/framework": "5.5.*",
"laravel/framework": "5.7.*",
"laravel/tinker": "~1.0",
"laravelcollective/html": "^5.5"
},
Generated
+653 -510
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -14,7 +14,7 @@ return [
*/
'name' => env('APP_NAME', 'Heimdall'),
'version' => '1.3.3',
'version' => '2.0.2',
/*
|--------------------------------------------------------------------------
Vendored
+3698
View 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']);
});
}
}
@@ -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');
}
}
@@ -0,0 +1,38 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username')->unique();
$table->string('email');
$table->string('avatar')->nullable();
$table->string('password')->nullable();
$table->string('autologin')->nullable()->index();
$table->boolean('public_front')->default(false);
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreatePasswordResetsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('password_resets');
}
}
@@ -0,0 +1,32 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddUserIdToItemsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('items', function (Blueprint $table) {
$table->integer('user_id')->default(1)->index(); // 0 = item, 1 = category
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('items', function (Blueprint $table) {
$table->dropColumn(['user_id']);
});
}
}
@@ -0,0 +1,35 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateSettingUserPivotTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('setting_user', function (Blueprint $table) {
$table->integer('setting_id')->unsigned()->index();
$table->foreign('setting_id')->references('id')->on('settings')->onDelete('cascade');
$table->integer('user_id')->unsigned()->index();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->primary(['setting_id', 'user_id']);
$table->string('uservalue')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('setting_user');
}
}
+1
View File
@@ -12,5 +12,6 @@ class DatabaseSeeder extends Seeder
public function run()
{
$this->call(SettingsSeeder::class);
$this->call(UsersSeeder::class);
}
}
+59 -3
View File
@@ -90,7 +90,8 @@ class SettingsSeeder extends Seeder
'none' => 'app.options.none',
'google' => 'app.options.google',
'ddg' => 'app.options.ddg',
'bing' => 'app.options.bing'
'bing' => 'app.options.bing',
'startpage' => 'app.options.startpage',
]);
if(!$setting = Setting::find(4)) {
@@ -116,7 +117,8 @@ class SettingsSeeder extends Seeder
'fi' => 'Suomi (Finnish)',
'fr' => 'Français (French)',
'it' => 'Italiano (Italian)',
'no' => 'Norsk (Norwegian)',
'no' => 'Norsk (Norwegian)',
'pl' => 'Polski (Polish)',
'sv' => 'Svenska (Swedish)',
'es' => 'Español (Spanish)',
'tr' => 'Türkçe (Turkish)',
@@ -136,6 +138,60 @@ class SettingsSeeder extends Seeder
$setting->save();
}
$window_target_options = json_encode([
'current' => 'app.settings.window_target.current',
'heimdall' => 'app.settings.window_target.one',
'_blank' => 'app.settings.window_target.new',
]);
if(!$setting = Setting::find(7)) {
$setting = new Setting;
$setting->id = 7;
$setting->group_id = 3;
$setting->key = 'window_target';
$setting->type = 'select';
$setting->options = $window_target_options;
$setting->label = 'app.settings.window_target';
$setting->value = 'heimdall';
$setting->save();
} else {
$setting->options = $window_target_options;
$setting->label = 'app.settings.window_target';
$setting->save();
}
if($support = Setting::find(8)) {
$support->label = 'app.settings.support';
$support->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
$support->save();
} else {
$setting = new Setting;
$setting->id = 8;
$setting->group_id = 1;
$setting->key = 'support';
$setting->type = 'text';
$setting->label = 'app.settings.support';
$setting->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
$setting->system = true;
$setting->save();
}
if($donate = Setting::find(9)) {
$donate->label = 'app.settings.donate';
$donate->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
$donate->save();
} else {
$setting = new Setting;
$setting->id = 9;
$setting->group_id = 1;
$setting->key = 'donate';
$setting->type = 'text';
$setting->label = 'app.settings.donate';
$setting->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
$setting->system = true;
$setting->save();
}
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Seeder;
use App\User;
class UsersSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
// Groups
if(!$user = User::find(1)) {
$user = new User;
$user->id = 1;
$user->username = 'admin';
$user->email = 'admin@test.com';
$user->password = null;
$user->save();
} else {
//$user->save();
}
}
}
+3
View File
@@ -0,0 +1,3 @@
{
"/css/app.css": "/css/app.css"
}
+5103 -4465
View File
File diff suppressed because it is too large Load Diff
+3 -6
View File
@@ -10,15 +10,12 @@
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"axios": "^0.17",
"bootstrap-sass": "^3.3.7",
"cross-env": "^5.1.3",
"cross-env": "^5.2.0",
"jquery": "^3.2",
"laravel-mix": "^1.0",
"lodash": "^4.17.4",
"vue": "^2.5.7"
"laravel-mix": "^2.0"
},
"dependencies": {
"node-sass": "^4.7.2"
"select2": "^4.0.6-rc.1"
}
}
+837 -36
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="15pt" height="12pt" viewBox="0 0 16 16" version="1.1">
<g id="surface1">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 8.464844 8.046875 L 8.464844 7.566406 L 8.628906 7.050781 C 9.78125 5.898438 10.6875 4.824219 10.847656 4.492188 L 10.648438 4.5625 C 10.648438 4.5625 10.832031 4.332031 10.8125 4.203125 C 10.667969 1.949219 9.40625 0.773438 9.058594 0.484375 C 9.570312 1.105469 9.429688 1.308594 9.429688 1.308594 C 9.207031 0.882812 8.742188 0.472656 8.652344 0.367188 L 8.542969 1.023438 C 8.980469 1.28125 8.863281 1.429688 8.863281 1.429688 C 8.761719 1.28125 8.480469 1.152344 8.480469 1.152344 L 8.449219 1.335938 C 8.585938 1.398438 9.1875 1.765625 9.191406 2.710938 C 9.191406 3.863281 8.542969 4.164062 8.429688 4.210938 C 8.050781 3.980469 7.640625 3.984375 7.539062 3.976562 C 7.4375 3.984375 7.027344 3.980469 6.648438 4.210938 C 6.535156 4.164062 5.882812 3.863281 5.882812 2.710938 C 5.890625 1.765625 6.492188 1.398438 6.625 1.335938 L 6.597656 1.152344 C 6.597656 1.152344 6.316406 1.28125 6.210938 1.429688 C 6.210938 1.429688 6.097656 1.28125 6.535156 1.023438 L 6.425781 0.367188 C 6.332031 0.472656 5.871094 0.882812 5.644531 1.308594 C 5.644531 1.308594 5.503906 1.105469 6.015625 0.484375 C 5.667969 0.773438 4.410156 1.949219 4.261719 4.203125 C 4.246094 4.332031 4.425781 4.5625 4.425781 4.5625 L 4.230469 4.492188 C 4.390625 4.824219 5.296875 5.898438 6.445312 7.050781 L 6.609375 7.566406 L 6.609375 8.046875 L 6.464844 7.53125 L 6.132812 6.980469 L 6.132812 7.542969 C 6.269531 7.933594 6.804688 8.722656 6.804688 8.722656 L 6.804688 7.085938 L 4.757812 4.835938 C 4.757812 4.835938 6.035156 5.886719 6.402344 6.261719 L 6.59375 6.066406 C 6.355469 5.894531 5.324219 4.851562 5.230469 3.929688 C 6.007812 5.585938 6.753906 5.792969 7.300781 6.4375 L 7.300781 6.59375 L 7.777344 6.59375 L 7.777344 6.4375 C 8.324219 5.792969 9.070312 5.585938 9.84375 3.929688 C 9.753906 4.851562 8.722656 5.894531 8.484375 6.066406 L 8.675781 6.261719 C 9.042969 5.886719 10.320312 4.835938 10.320312 4.835938 L 8.273438 7.085938 L 8.273438 8.722656 C 8.273438 8.722656 8.808594 7.933594 8.945312 7.542969 L 8.945312 6.980469 L 8.613281 7.53125 Z M 7.539062 6.070312 C 7.195312 5.839844 6.3125 5.300781 5.949219 4.460938 C 6.152344 4.703125 6.375 4.929688 6.609375 5.136719 C 6.609375 5.136719 6.589844 4.542969 6.632812 4.414062 C 6.714844 5.125 6.886719 5.429688 7.539062 5.808594 C 8.191406 5.429688 8.359375 5.125 8.441406 4.414062 C 8.488281 4.542969 8.464844 5.136719 8.464844 5.136719 C 8.703125 4.929688 8.925781 4.703125 9.128906 4.460938 C 8.761719 5.300781 7.882812 5.839844 7.539062 6.070312 Z M 7.539062 6.070312 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

+14
View File
@@ -0,0 +1,14 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="780" height="619" viewBox="0 0 780 619">
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""/>
</rdf:RDF>
</x:xmpmeta>
<?xpacket end="w"?></metadata>
<path class="cls-1" d="M440.227,415.119V390.2l8.552-26.577C508.647,304.3,555.686,248.776,564,231.691l-10.215,3.56s9.5-11.864,8.552-18.51c-7.6-116.273-73.17-176.862-91.226-191.732,26.607,31.955,19.326,42.4,19.326,42.4C478.714,45.576,454.64,24.377,449.888,19l-5.7,33.853c22.806,13.289,16.79,20.882,16.79,20.882C455.591,66.141,441.021,59.5,441.021,59.5l-1.586,9.491c6.973,3.165,38.327,22.149,38.565,70.872,0,59.323-33.735,74.985-39.674,77.357-19.718-11.865-41.1-11.627-46.326-12.1-5.226.474-26.608,0.236-46.324,12.1C339.735,214.844,306,199.182,306,139.859c0.238-48.723,31.6-67.707,38.564-70.872L342.983,59.5s-14.574,6.644-19.955,14.238c0,0-6.022-7.593,16.786-20.882L334.112,19c-4.752,5.378-28.824,26.577-40.543,48.407,0,0-7.288-10.443,19.32-42.4-18.054,14.87-83.625,75.459-91.226,191.732-0.95,6.646,8.554,18.51,8.554,18.51L220,231.691c8.316,17.085,55.355,72.612,115.221,131.935l8.554,26.577v24.916l-7.6-26.577L318.83,360.067v28.95C325.957,409.186,353.751,450,353.751,450V365.525L247.32,249.488s66.52,54.1,85.526,73.56l9.978-10.2c-12.355-8.78-66.045-62.646-70.8-110.1,40.388,85.426,79.111,96.1,107.62,129.325V340.2h24.707v-8.131c28.508-33.221,67.233-43.9,107.619-129.325-4.75,47.459-58.442,101.325-70.8,110.1l9.976,10.2c19.006-19.458,85.526-73.56,85.526-73.56L430.249,365.525V450s27.8-40.815,34.923-60.984v-28.95l-17.343,28.475ZM392,313.083c-17.818-11.865-63.668-39.629-82.672-83.053a314.117,314.117,0,0,0,34.447,34.882s-1.189-30.61,1.186-37.255c4.276,36.781,13.068,52.442,47.039,71.9,33.973-19.458,42.763-35.119,47.039-71.9,2.375,6.645,1.188,37.255,1.188,37.255a314.117,314.117,0,0,0,34.447-34.882C455.668,273.454,409.818,301.218,392,313.083Z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

+76 -46
View File
@@ -11,10 +11,10 @@ $.when( $.ready ).then(function() {
if($('.message-container').length) {
setTimeout(
function()
{
$('.message-container').fadeOut();
}, 3500);
function()
{
$('.message-container').fadeOut();
}, 3500);
}
if($('.livestats-container').length) {
@@ -27,27 +27,61 @@ $.when( $.ready ).then(function() {
var timer = 5000;
(function worker() {
$.ajax({
url: '/get_stats/'+id,
success: function(data) {
container.html(data);
if(data != '') timer = increaseby;
else {
if(timer < max_timer) timer += 2000;
}
},
complete: function() {
url: '/get_stats/'+id,
dataType: 'json',
success: function(data) {
container.html(data.html);
if(data.status == 'active') timer = increaseby;
else {
if(timer < max_timer) timer += 2000;
}
},
complete: function() {
// Schedule the next request when the current one's complete
setTimeout(worker, timer);
}
setTimeout(worker, timer);
}
});
})();
})();
});
}
$( "#sortable" ).sortable({
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('#appimage img').attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
}
$('#upload').change(function() {
readURL(this);
});
/*$(".droppable").droppable({
tolerance: "intersect",
drop: function( event, ui ) {
var tag = $( this ).data('id');
var item = $( ui.draggable ).data('id');
$.get('tag/add/'+tag+'/'+item, function(data) {
if(data == 1) {
$( ui.draggable ).remove();
} else {
alert('not added');
}
});
}
});*/
$( '#sortable' ).sortable({
stop: function (event, ui) {
var idsInOrder = $("#sortable").sortable('toArray', {
var idsInOrder = $('#sortable').sortable('toArray', {
attribute: 'data-id'
});
$.post(
@@ -55,11 +89,12 @@ $.when( $.ready ).then(function() {
{ order:idsInOrder }
);
}
});
$("#sortable").sortable("disable");
});
$('#sortable').sortable('disable');
$('#app').on('click', '#config-button', function(e) {
e.preventDefault();
var app = $('#app');
@@ -69,50 +104,45 @@ $.when( $.ready ).then(function() {
$('.add-item').hide();
$('.item-edit').hide();
$('#app').removeClass('sidebar');
$("#sortable").sortable("disable")
$('#sortable').sortable('disable');
} else {
$("#sortable").sortable("enable")
setTimeout(
function()
{
$('.add-item').fadeIn();
$('.item-edit').fadeIn();
}, 350);
$('#sortable').sortable('enable');
setTimeout(function() {
$('.add-item').fadeIn();
$('.item-edit').fadeIn();
}, 350);
}
}).on('click', '#add-item, #pin-item', function(e) {
e.preventDefault();
var app = $('#app');
var active = (app.hasClass('sidebar'));
app.toggleClass('sidebar');
}).on('click', '.close-sidenav', function(e) {
e.preventDefault();
var app = $('#app');
app.removeClass('sidebar');
}).on('click', '#test_config', function(e) {
e.preventDefault();
var apiurl = $('#create input[name=url]').val();
var override_url = $('#create input[name=override_url]');
if(override_url.length && override_url.val() != '') {
var override_url = $('#create input[name="config[override_url]"]').val();
if(override_url.length && override_url != '') {
apiurl = override_url;
}
var data = {};
data['url'] = apiurl;
$('input.config-item').each(function(index){
var config = $(this).data('config');
data[config] = $(this).val();
})
});
$.post(
'/test_config',
{ data }, function(data) {
alert(data);
}
);
$.post('/test_config', { data: data }, function(data) {
alert(data);
});
});
$('#pinlist').on('click', 'a', function(e) {
@@ -125,5 +155,5 @@ $.when( $.ready ).then(function() {
current.toggleClass('active');
});
});
});
});
+13
View File
File diff suppressed because one or more lines are too long
+1
View File
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -1,4 +1,4 @@
{
"/css/app.css": "/css/app.css?id=a571eeda02c71a01f251",
"/js/app.js": "/js/app.js?id=b38be2e595ece6fcef81"
}
"/css/app.css": "/css/app.css?id=24e9bb4fa993b66f0572",
"/js/app.js": "/js/app.js?id=f18d23b8fc7a094a2c66"
}
+135 -32
View File
@@ -1,63 +1,126 @@
![alt text](https://i.imgur.com/iuV8w3y.png)
# Heimdall
## About
[![Heimdall_Banner](https://i.imgur.com/iuV8w3y.png)](https://heimdall.site)
[![Discord](https://img.shields.io/discord/354974912613449730.svg)](https://discord.gg/CCjHKn4)
[![Docker Pulls](https://img.shields.io/docker/pulls/linuxserver/heimdall.svg)](https://hub.docker.com/r/linuxserver/heimdall/)
[![firsttimersonly](https://img.shields.io/badge/first--timers--only-friendly-blue.svg)](https://www.firsttimersonly.com/)
[![Paypal](https://heimdall.site/img/paypaldonate.svg)](https://www.paypal.me/heimdall)
___
Visit the website - https://heimdall.site
___
## About
As the name suggests Heimdall Application Dashboard is a dashboard for all your web applications. It doesn't need to be limited to applications though, you can add links to anything you like.
Heimdall is an elegant solution to organise all your web applications. Its dedicated to this purpose so you wont lose your links in a sea of bookmarks.
Why not use it as your browser start page? It even has the ability to include a search bar using either Google, Bing or DuckDuckGo.
Why not use it as your browser start page? It even has the ability to include a search bar using either Google, Bing or DuckDuckGo.
![alt text](https://i.imgur.com/MrC4QpN.gif)
![Heimdall demo animation](https://i.imgur.com/MrC4QpN.gif)
## Video
If you want to see a quick video of it in use, go to https://youtu.be/GXnnMAxPzMc
## Supported applications
You can use the app to link to any site or application, but Foundation apps will auto fill in the icon for the app and supply a default color for the tile. In addition Enhanced apps allow you provide details to an apps API, allowing you to view live stats directly on the dashboad. For example, the NZBGet and Sabnzbd Enhanced apps will display the queue size and download speed while something is downloading.
You can use the app to link to any site or application, but Foundation apps will auto fill in the icon for the app and supply a default color for the tile. In addition Enhanced apps allow you provide details to an apps API, allowing you to view live stats directly on the dashboad. For example, the NZBGet and Sabnzbd Enhanced apps will display the queue size and download speed while something is downloading.
Supported applications are recognized by the title of the application as entered in the title field when adding an application. For example, to add a link to pfSense, begin by typing "p" in the title field and then select "pfSense" from the list of supported applications.
**Enhanced**
- CouchPotato
- Deluge
- NZBGet
- Pihole
- PlexPy
- Proxmox
- Runeaudio
- Sabnzbd
- Tautulli
- Traefik
- Transmission
**Foundation**
- AirSonic
- Bazarr
- Bitwarden
- Booksonic
- BookStack
- Cardigann
- DokuWiki
- Duplicati
- Emby
- FreshRSS
- Gitea
- Grafana
- Graylog
- Headphones
- Jdownloader
- Mcmyadmin
- NZBGet
- Krusader
- LibreNMS
- Lidarr
- Mailcow
- McMyAdmin
- Medusa
- Monica
- MusicBrainz
- Mylar
- NZBhydra & NZBhydra2
- Netdata
- Nextcloud
- Openhab
- Pihole
- Ombi
- OpenHAB
- OpenMediaVault
- Plex
- Plexpy
- Plexrequests
- Portainer
- Sabnzbd
- Traefik
- UniFi
- pFsense
- Radarr
- Rancher
- SickRage
- Sonarr
- TT-RSS
- TVheadend
- UniFI
- unRAID
- pfSense
- pyLoad
- rTorrent/Flood
- rTorrent/ruTorrent
- Syncthing
- Virtualmin
- Watcher3
- Webmin
- WebTools
## Installing
Apart from the Laravel dependencies, namely PHP >= 7.0.0, OpenSSL PHP Extension, PDO PHP Extension, Mbstring PHP Extension, Tokenizer PHP Extension and XML PHP Extension, the only other thing Heimdall needs is sqlite support.
Installation is as simple as cloning the repository somewhere, or downloading and extracting the zip/tar and pointing your httpd document root to it. For simple testing you could just go to the folder and type `php artisan serve`
If you find you can't change the background make sure `php_fileinfo` is enabled in your php.ini. I believe it should be by default, but one user came across the issue on a windows system.
There are also dockers and instructions on how to use them at
Installation is as simple as cloning the repository somewhere, or downloading and extracting the zip/tar and pointing your httpd document root to the `/public` folder. For simple testing you could just go to the folder and type `php artisan serve`
for x86-64: https://hub.docker.com/r/linuxserver/heimdall/
There is also a multi-arch Docker which supports x86-64, armhf and arm64, instructions on how to use them at
for armhf: https://hub.docker.com/r/lsioarmhf/heimdall/
- https://hub.docker.com/r/linuxserver/heimdall/
and for arm64: https://hub.docker.com/r/lsioarmhf/heimdall-aarch64/
## New background image not being set
If you are using the docker image or a default php install you may find images over 2MB wont get set as the background image, you just need to change the `upload_max_filesize` in the php.ini.
If you are using the linuxserver.io docker image simply edit `/path/to/config/php/php-local.ini` and add `upload_max_filesize = 30M` to the end.
## Docker and enhanced apps
If you are running the docker and the EnhancedApps you are using are also in dockers, you may need to use the docker networking addresses to communicate with them.
You can do this by using `http(s)://docker_name:port` in the config section. Instead of the name you can use the internal docker ip, this usually starts with `172.`
## Languages
The app has been translated into several languages, however the quality of the translations could do with work, if you would like to improve them or help with other translations they are stored in /resources/lang/
The app has been translated into several languages; however, the quality of the translations could do with work. If you would like to improve them, or help with other translations, they are stored in `/resources/lang/`.
To create a new one, create a new folder with the ISO 3166-1 alpha-2 code as the name, copy app.php from /resources/lang/en/app.php into your new folder and replace the english strings.
To create a new language translation, make a new folder with the ISO 3166-1 alpha-2 code as the name, copy `app.php` from `/resources/lang/en/app.php` into your new folder and replace the English strings.
When you are finished create a pull request.
When you are finished, create a pull request.
Currently added languages are
@@ -72,8 +135,19 @@ Currently added languages are
## Web Server Configuration
### Apache
A .htaccess file ships with the app, however, if it does not work with your Apache installation, try this alternative:
A `.htaccess` file ships with the app, however, a lot of apache installations disallow `.htaccess` files by default.
You will notice this due to some links not working like `/settings`.
#### Fixes & work around options
##### - Apache global allow .htaccess
Find the `AllowOverride None` line in your apache configuration and change this to `AllowOverride All`
##### - Apache vhost configuration allow .htaccess
In the apache vhost configuration in the `<Directory />` block add `AllowOverride All`
##### - Add .htaccess content in apache configuration
You can add the full `.htaccess` into your apache configuration, this way you do not need to allow `.htaccess` files.
You can even shorten the content of the `.htaccess` when inserting it into the apache configuration to:
```
Options +FollowSymLinks
RewriteEngine On
@@ -82,28 +156,33 @@ RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
```
#### More info
More info about `AllowOverride` can be found here:
https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride
### Nginx
If you are using Nginx, the following directive in your site configuration will direct all requests to the index.php front controller:
If you are using Nginx, the following directive in your site configuration will direct all requests to the `index.php` front controller:
```
location / {
try_files $uri $uri/ /index.php?$query_string;
}
```
Someone was using the same nginx setup to both run this and reverse proxy Plex, Plex is served from /web so their location was interferring with the /webfonts.
Someone was using the same nginx setup to both run this and reverse proxy Plex, Plex is served from `/web` so their location was interfering with the `/webfonts`.
Therefore, if your fonts aren't showing because you have a location for /web add the following
Therefore, if your fonts aren't showing because you have a location for `/web`, add the following
```
location /webfonts {
try_files $uri $uri/;
try_files $uri $uri/;
}
```
If there are any other locations which might interefere with any of the folders in the /public folder, you might have to do the same for those as well, but it's a super fringe case.
If there are any other locations which might interfere with any of the folders in the `/public` folder, you might have to do the same for those as well, but it's a super fringe case.
### Reverse proxy
If you'd like to reverse proxy this app, we recommend using our letsencrypt/nginx docker image: [Letsencrypt/Nginx](https://hub.docker.com/r/linuxserver/letsencrypt/)
You can either reverse proxy from the root location, or from a subdomain (subfolder method is currently not supported). For https proxy, make sure you use the https port of Heimdall webserver, otherwise some links may break. You can add security through `.htpasswd`
If you'd like to reverse proxy this app, we recommend using our letsencrypt/nginx docker image: [Letsencrypt/Nginx](https://hub.docker.com/r/linuxserver/letsencrypt/)
You can either reverse proxy from the root location, or from a subdomain (subfolder method is currently not supported). For HTTPS proxy, make sure you use the HTTPS port of Heimdall webserver, otherwise some links may break. You can add security through `.htpasswd`
```
location / {
@@ -114,10 +193,34 @@ location / {
}
```
If you are using HTTPS and things aren't working try adding `FORCE_HTTPS=true` to the end of your `.env` file
### Self-signed certificates and local CAs
Per default Heimdall uses the standard certificate bundle file (`ca-certificates.crt`) to verify HTTPS sites and will ignore additional certificates placed in `/etc/ssl/certs`. If you wish to use enhanced apps with HTTPS sites that use a self-signed certificate or certs signed with your own local CA, you can override the default bundle:
- Create a unified certificate `.pem` file that contains all CAs and certificates that Heimdall has to verify. For example, if you use both LetsEncrypt and a local CA for your internal apps, concatenate the LetsEncrypt intermediate CA (export via browser) and your local CA `cert.pem` (or any number of self-signed certs) into one `heimdall.pem` file.
- Place the `heimdall.pem` into the container (if you use Docker), for example by placing it in the path that you mapped to `/config`. Make sure that the Heimdall user has read access (`chmod a+r`).
- Set the `openssl.cafile` setting in `/config/php/php-local.ini` to your cert bundle:
```
# /config/php/php-local.ini
openssl.cafile = /config/heimdall.pem
```
Restart the container and the enhanced apps should now be able to access your local HTTP websites. This configuration will survive updating or recreating the Heimdall container.
## Support
https://discord.gg/CCjHKn4 or through GitHub issues
## Donate
If you would like to show your appreciation, feel free to use the link below.
[![PayPal](https://heimdall.site/img/paypaldonate.svg)](https://www.paypal.me/heimdall)
## Credits
- PHP Framework - [Laravel](https://laravel.com/)
- Icons - [FonteAwesome 5](https://fontawesome.com/)
- Javascript - [jQuery](https://jquery.com/)
- Icons - [FontAwesome 5](https://fontawesome.com/)
- JavaScript - [jQuery](https://jquery.com/)
- Colour picker - [Huebee](http://huebee.buzz/)
- Background image - [pexels](https://www.pexels.com)
- Everyone at Linuxserver.io that has helped with the app and let's not forget IronicBadger for the following question that started it all:
+76 -46
View File
@@ -2,10 +2,10 @@ $.when( $.ready ).then(function() {
if($('.message-container').length) {
setTimeout(
function()
{
$('.message-container').fadeOut();
}, 3500);
function()
{
$('.message-container').fadeOut();
}, 3500);
}
if($('.livestats-container').length) {
@@ -18,27 +18,61 @@ $.when( $.ready ).then(function() {
var timer = 5000;
(function worker() {
$.ajax({
url: '/get_stats/'+id,
success: function(data) {
container.html(data);
if(data != '') timer = increaseby;
else {
if(timer < max_timer) timer += 2000;
}
},
complete: function() {
url: '/get_stats/'+id,
dataType: 'json',
success: function(data) {
container.html(data.html);
if(data.status == 'active') timer = increaseby;
else {
if(timer < max_timer) timer += 2000;
}
},
complete: function() {
// Schedule the next request when the current one's complete
setTimeout(worker, timer);
}
setTimeout(worker, timer);
}
});
})();
})();
});
}
$( "#sortable" ).sortable({
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('#appimage img').attr('src', e.target.result);
};
reader.readAsDataURL(input.files[0]);
}
}
$('#upload').change(function() {
readURL(this);
});
/*$(".droppable").droppable({
tolerance: "intersect",
drop: function( event, ui ) {
var tag = $( this ).data('id');
var item = $( ui.draggable ).data('id');
$.get('tag/add/'+tag+'/'+item, function(data) {
if(data == 1) {
$( ui.draggable ).remove();
} else {
alert('not added');
}
});
}
});*/
$( '#sortable' ).sortable({
stop: function (event, ui) {
var idsInOrder = $("#sortable").sortable('toArray', {
var idsInOrder = $('#sortable').sortable('toArray', {
attribute: 'data-id'
});
$.post(
@@ -46,11 +80,12 @@ $.when( $.ready ).then(function() {
{ order:idsInOrder }
);
}
});
$("#sortable").sortable("disable");
});
$('#sortable').sortable('disable');
$('#app').on('click', '#config-button', function(e) {
e.preventDefault();
var app = $('#app');
@@ -60,50 +95,45 @@ $.when( $.ready ).then(function() {
$('.add-item').hide();
$('.item-edit').hide();
$('#app').removeClass('sidebar');
$("#sortable").sortable("disable")
$('#sortable').sortable('disable');
} else {
$("#sortable").sortable("enable")
setTimeout(
function()
{
$('.add-item').fadeIn();
$('.item-edit').fadeIn();
}, 350);
$('#sortable').sortable('enable');
setTimeout(function() {
$('.add-item').fadeIn();
$('.item-edit').fadeIn();
}, 350);
}
}).on('click', '#add-item, #pin-item', function(e) {
e.preventDefault();
var app = $('#app');
var active = (app.hasClass('sidebar'));
app.toggleClass('sidebar');
}).on('click', '.close-sidenav', function(e) {
e.preventDefault();
var app = $('#app');
app.removeClass('sidebar');
}).on('click', '#test_config', function(e) {
e.preventDefault();
var apiurl = $('#create input[name=url]').val();
var override_url = $('#create input[name=override_url]');
if(override_url.length && override_url.val() != '') {
var override_url = $('#create input[name="config[override_url]"]').val();
if(override_url.length && override_url != '') {
apiurl = override_url;
}
var data = {};
data['url'] = apiurl;
$('input.config-item').each(function(index){
var config = $(this).data('config');
data[config] = $(this).val();
})
});
$.post(
'/test_config',
{ data }, function(data) {
alert(data);
}
);
$.post('/test_config', { data: data }, function(data) {
alert(data);
});
});
$('#pinlist').on('click', 'a', function(e) {
@@ -116,5 +146,5 @@ $.when( $.ready ).then(function() {
current.toggleClass('active');
});
});
});
});
+90 -3
View File
@@ -7,12 +7,51 @@ html {
body {
background: $body-bg;
}
#switchuser {
background: rgba(0,0,0,0.5);
position: absolute;
padding: 10px;
color: white;
text-align: center;
bottom:0;
left: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-top: 2px solid rgba(255, 255, 255, 0.15);
border-right: 2px solid rgba(255, 255, 255, 0.15);
box-shadow: 0 0 10px 0px rgba(0, 0, 0, 0.4);
border-radius: 0 9px 0 0;
line-height: 1.5;
font-size: 14px;
img {
width: 50px;
margin-bottom: 5px;
border-radius: 50%;
}
.btn {
font-size: 13px;
color: white;
text-decoration: none;
margin-left: -10px;
margin-right: -10px;
margin-bottom: -10px;
margin-top: 8px;
border-radius: 0;
width: calc(100% + 22px);
background: rgba(255, 255, 255, 0.15);
transition: all .35s ease-in-out;
&:hover {
background: #d64d55;
}
}
}
#app {
display: flex;
min-height: 100vh;
flex-direction: column;
background-image: url('/img/bg1.jpg');
background-image: url('../img/bg1.jpg');
background-repeat: no-repeat;
background-size: cover;
background-position: bottom center;
@@ -70,7 +109,7 @@ body {
flex-direction: column;
}
main, #sortable {
padding: 10px;
padding: 30px 10px;
display: flex;
justify-content: center;
align-items: center;
@@ -104,6 +143,47 @@ body {
}
}
.userlist {
display: flex;
justify-content: center;
align-items: center;
.user {
background: rgba(0,0,0,0.5);
display: flex;
padding: 15px;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 20px;
color: white;
text-decoration: none;
border-radius: 15px;
border: 5px solid rgba(255,255,255, 0.7);
box-shadow: 0 0 10px 0px rgba(0,0,0,0.4);
}
.user-img {
width: 130px;
height: 130px;
margin-bottom: 20px;
border-radius: 50%;
margin: 10px 10px 15px;
}
#password {
color: $app-text;
width: 100%;
padding: 5px 10px;
margin: 15px -5px;
}
.btn {
width: 100%;
}
.forgot {
color: white;
font-size: 12px;
margin-top: 25px;
}
}
.item-container {
//width: 340px;
//transition: width .35s ease-in-out;
@@ -122,6 +202,13 @@ body {
display: none;
}
}
.black {
color: #000!important;
}
.white {
color: #fff!important;
}
.message-container {
width: 100%;
padding: 10px 20px;
+18
View File
@@ -0,0 +1,18 @@
// This file were added as a supplement to RuneAudio application
.title-marquee {
width: 125px;
overflow: hidden;
span {
white-space: nowrap;
transform: translate(0, 0);
animation: marquee 8s linear;
}
}
@keyframes marquee {
0% { transform: translate(0, 0); }
20% { transform: translate(0, 0); }
95% { transform: translate(-200%, 0); }
100% { transform: translate(-200%, 0); }
}
+486
View File
@@ -0,0 +1,486 @@
.select2-container {
box-sizing: border-box;
display: inline-block;
margin: 0;
position: relative;
vertical-align: middle; }
.select2-container .select2-selection--single {
box-sizing: border-box;
cursor: pointer;
display: block;
height: 28px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--single .select2-selection__rendered {
display: block;
padding-left: 8px;
padding-right: 20px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-selection--single .select2-selection__clear {
position: relative; }
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
padding-right: 8px;
padding-left: 20px; }
.select2-container .select2-selection--multiple {
box-sizing: border-box;
cursor: pointer;
display: block;
min-height: 39px;
user-select: none;
-webkit-user-select: none; }
.select2-container .select2-selection--multiple .select2-selection__rendered {
display: inline-block;
overflow: hidden;
padding-left: 8px;
text-overflow: ellipsis;
white-space: nowrap; }
.select2-container .select2-search--inline {
float: left; }
.select2-container .select2-search--inline .select2-search__field {
box-sizing: border-box;
border: none;
font-size: 100%;
margin-top: 5px;
padding: 0; }
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-dropdown {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
box-sizing: border-box;
display: block;
position: absolute;
left: -100000px;
width: 100%;
z-index: 1051; }
.select2-results {
display: block; }
.select2-results__options {
list-style: none;
margin: 0;
padding: 0; }
.select2-results__option {
padding: 6px;
user-select: none;
-webkit-user-select: none; }
.select2-results__option[aria-selected] {
cursor: pointer; }
.select2-container--open .select2-dropdown {
left: 0; }
.select2-container--open .select2-dropdown--above {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--open .select2-dropdown--below {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-search--dropdown {
display: block;
padding: 4px; }
.select2-search--dropdown .select2-search__field {
padding: 4px;
width: 100%;
box-sizing: border-box; }
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
-webkit-appearance: none; }
.select2-search--dropdown.select2-search--hide {
display: none; }
.select2-close-mask {
border: 0;
margin: 0;
padding: 0;
display: block;
position: fixed;
left: 0;
top: 0;
min-height: 100%;
min-width: 100%;
height: auto;
width: auto;
opacity: 0;
z-index: 99;
background-color: #fff;
filter: alpha(opacity=0); }
.select2-hidden-accessible {
border: 0 !important;
clip: rect(0 0 0 0) !important;
-webkit-clip-path: inset(50%) !important;
clip-path: inset(50%) !important;
height: 1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important; }
.select2-container--default .select2-selection--single {
background-color: #fff;
border: 1px solid #aaa;
border-radius: 4px; }
.select2-container--default .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--default .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold; }
.select2-container--default .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--default .select2-selection--single .select2-selection__arrow {
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px; }
.select2-container--default .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
left: 1px;
right: auto; }
.select2-container--default.select2-container--disabled .select2-selection--single {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
display: none; }
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--default .select2-selection--multiple {
background-color: white;
border: 1px solid #dedfe2;
border-radius: 4px;
cursor: text; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
box-sizing: border-box;
list-style: none;
margin: 0;
padding: 0 5px;
width: 100%; }
.select2-container--default .select2-selection--multiple .select2-selection__rendered li {
list-style: none; }
.select2-container--default .select2-selection--multiple .select2-selection__placeholder {
color: #999;
margin-top: 5px;
float: left; }
.select2-container--default .select2-selection--multiple .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-top: 5px;
margin-right: 10px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice {
background-color: #f2f3f6;
border: 1px solid #dedfe2;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
font-size: 13px;
font-weight: 300;
margin-top: 5px;
padding: 5px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
color: #999;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #333; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
float: right; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
margin-left: 5px;
margin-right: auto; }
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--default.select2-container--focus .select2-selection--multiple {
border: solid #dedfe2 1px;
outline: 0; }
.select2-container--default.select2-container--disabled .select2-selection--multiple {
background-color: #eee;
cursor: default; }
.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
display: none; }
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--default .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa; }
.select2-container--default .select2-search--inline .select2-search__field {
background: transparent;
border: none;
outline: 0;
box-shadow: none;
-webkit-appearance: textfield; }
.select2-container--default .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--default .select2-results__option[role=group] {
padding: 0; }
.select2-container--default .select2-results__option[aria-disabled=true] {
color: #999; }
.select2-container--default .select2-results__option[aria-selected=true] {
background-color: #ddd; }
.select2-container--default .select2-results__option .select2-results__option {
padding-left: 1em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__group {
padding-left: 0; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option {
margin-left: -1em;
padding-left: 2em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -2em;
padding-left: 3em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -3em;
padding-left: 4em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -4em;
padding-left: 5em; }
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
margin-left: -5em;
padding-left: 6em; }
.select2-container--default .select2-results__option--highlighted[aria-selected] {
background-color: #5897fb;
color: white; }
.select2-container--default .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic .select2-selection--single {
background-color: #f7f7f7;
border: 1px solid #aaa;
border-radius: 4px;
outline: 0;
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic .select2-selection--single:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--single .select2-selection__rendered {
color: #444;
line-height: 28px; }
.select2-container--classic .select2-selection--single .select2-selection__clear {
cursor: pointer;
float: right;
font-weight: bold;
margin-right: 10px; }
.select2-container--classic .select2-selection--single .select2-selection__placeholder {
color: #999; }
.select2-container--classic .select2-selection--single .select2-selection__arrow {
background-color: #ddd;
border: none;
border-left: 1px solid #aaa;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
height: 26px;
position: absolute;
top: 1px;
right: 1px;
width: 20px;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
.select2-container--classic .select2-selection--single .select2-selection__arrow b {
border-color: #888 transparent transparent transparent;
border-style: solid;
border-width: 5px 4px 0 4px;
height: 0;
left: 50%;
margin-left: -4px;
margin-top: -2px;
position: absolute;
top: 50%;
width: 0; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
float: left; }
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
border: none;
border-right: 1px solid #aaa;
border-radius: 0;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
left: 1px;
right: auto; }
.select2-container--classic.select2-container--open .select2-selection--single {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
background: transparent;
border: none; }
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
border-color: transparent transparent #888 transparent;
border-width: 0 4px 5px 4px; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0;
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
.select2-container--classic .select2-selection--multiple {
background-color: white;
border: 1px solid #aaa;
border-radius: 4px;
cursor: text;
outline: 0; }
.select2-container--classic .select2-selection--multiple:focus {
border: 1px solid #5897fb; }
.select2-container--classic .select2-selection--multiple .select2-selection__rendered {
list-style: none;
margin: 0;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__clear {
display: none; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice {
background-color: #e4e4e4;
border: 1px solid #aaa;
border-radius: 4px;
cursor: default;
float: left;
margin-right: 5px;
margin-top: 5px;
padding: 0 5px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
color: #888;
cursor: pointer;
display: inline-block;
font-weight: bold;
margin-right: 2px; }
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
color: #555; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
float: right;
margin-left: 5px;
margin-right: auto; }
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
margin-left: 2px;
margin-right: auto; }
.select2-container--classic.select2-container--open .select2-selection--multiple {
border: 1px solid #5897fb; }
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
border-top: none;
border-top-left-radius: 0;
border-top-right-radius: 0; }
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
border-bottom: none;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0; }
.select2-container--classic .select2-search--dropdown .select2-search__field {
border: 1px solid #aaa;
outline: 0; }
.select2-container--classic .select2-search--inline .select2-search__field {
outline: 0;
box-shadow: none; }
.select2-container--classic .select2-dropdown {
background-color: white;
border: 1px solid transparent; }
.select2-container--classic .select2-dropdown--above {
border-bottom: none; }
.select2-container--classic .select2-dropdown--below {
border-top: none; }
.select2-container--classic .select2-results > .select2-results__options {
max-height: 200px;
overflow-y: auto; }
.select2-container--classic .select2-results__option[role=group] {
padding: 0; }
.select2-container--classic .select2-results__option[aria-disabled=true] {
color: grey; }
.select2-container--classic .select2-results__option--highlighted[aria-selected] {
background-color: #3875d7;
color: white; }
.select2-container--classic .select2-results__group {
cursor: default;
display: block;
padding: 6px; }
.select2-container--classic.select2-container--open .select2-dropdown {
border-color: #5897fb; }
+6 -2
View File
@@ -1,6 +1,6 @@
// Fonts
@import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600");
//@import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600");
// Variables
@import "variables";
@@ -10,10 +10,14 @@
// Bootstrap
@import "app";
@import "rune";
// Huebee
@import "huebee";
// fontawesome
@import "fontawesome/fontawesome";
@import "fontawesome/fa-solid";
@import "fontawesome/fa-solid";
@import "select2";
+1 -1
View File
@@ -1,7 +1,7 @@
// Variables
// --------------------------
$fa-font-path: "/webfonts" !default;
$fa-font-path: "../webfonts" !default;
$fa-font-size-base: 16px !default;
$fa-css-prefix: fa !default;
$fa-version: "5.0.2" !default;

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