mirror of
https://github.com/linuxserver/Heimdall.git
synced 2026-02-23 21:20:32 +09:00
Compare commits
337 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33372509eb | ||
|
|
bca0b02925 | ||
|
|
24995135e6 | ||
|
|
c1e4103edd | ||
|
|
6eda423156 | ||
|
|
7dc72d3519 | ||
|
|
907c22179b | ||
|
|
cdafbab7b1 | ||
|
|
e0064504e7 | ||
|
|
b22117dd01 | ||
|
|
c88efa8dbc | ||
|
|
7d060ff803 | ||
|
|
d5f8b6aae0 | ||
|
|
2416993c5e | ||
|
|
494165a03a | ||
|
|
88e607533c | ||
|
|
035d2f9209 | ||
|
|
53903daa87 | ||
|
|
567994be1a | ||
|
|
32fa27337a | ||
|
|
e1bb7646ac | ||
|
|
108b636def | ||
|
|
4abb14bf54 | ||
|
|
f8f96593c1 | ||
|
|
cb21b0f8f1 | ||
|
|
4c8c5fa27f | ||
|
|
6093119dde | ||
|
|
15755a3fd1 | ||
|
|
0213c81e0d | ||
|
|
c47f296f17 | ||
|
|
75133474f7 | ||
|
|
ddbe171f3a | ||
|
|
12e109f82c | ||
|
|
e095589172 | ||
|
|
d0293c785b | ||
|
|
aa351e31bf | ||
|
|
aceed3d13b | ||
|
|
10b70d4a09 | ||
|
|
cb9e014cf3 | ||
|
|
99017d834e | ||
|
|
fb73f5ca24 | ||
|
|
4369f1aeda | ||
|
|
6501aacb1b | ||
|
|
c3da17befc | ||
|
|
46bb073001 | ||
|
|
e8b47776ce | ||
|
|
6941fd3e2d | ||
|
|
f5937879df | ||
|
|
93877b7025 | ||
|
|
6612631cc3 | ||
|
|
30c3079a90 | ||
|
|
e86e681c53 | ||
|
|
48f72652da | ||
|
|
a3f7bafedb | ||
|
|
d30d610042 | ||
|
|
882e406266 | ||
|
|
45d421256c | ||
|
|
a2f20fc18f | ||
|
|
988364cb7c | ||
|
|
a3816ed8a1 | ||
|
|
d48805ee2c | ||
|
|
e820b81259 | ||
|
|
8b1046ce17 | ||
|
|
a138b65842 | ||
|
|
c344de3f04 | ||
|
|
427659a897 | ||
|
|
a6543970e7 | ||
|
|
399ea088dc | ||
|
|
3f87833e52 | ||
|
|
6dcb77023c | ||
|
|
4d37135bdf | ||
|
|
d109047fa5 | ||
|
|
b6112501e2 | ||
|
|
0663e236b4 | ||
|
|
f25cea1749 | ||
|
|
03e16415aa | ||
|
|
9a55e05943 | ||
|
|
c06fa4eab6 | ||
|
|
5575b082ea | ||
|
|
1c6da858bc | ||
|
|
f0a14641c1 | ||
|
|
c6d07cd8a4 | ||
|
|
df9f07faf4 | ||
|
|
a3dcc278d7 | ||
|
|
5de473fa44 | ||
|
|
763c1545a6 | ||
|
|
ecde7a0f32 | ||
|
|
7fc5e0abb5 | ||
|
|
06a655ac0c | ||
|
|
875ddaa834 | ||
|
|
030fccbb50 | ||
|
|
908f70d90a | ||
|
|
8724ced531 | ||
|
|
aa1a3a95ca | ||
|
|
0767dc075e | ||
|
|
c8a6c89036 | ||
|
|
cafe386cc4 | ||
|
|
0184c9695b | ||
|
|
19536edf28 | ||
|
|
045e4a20fa | ||
|
|
6cb8487a52 | ||
|
|
c39e9aa13f | ||
|
|
0203440b06 | ||
|
|
7f7bf60456 | ||
|
|
e8673634bc | ||
|
|
53e52c93ee | ||
|
|
c239c0ea5a | ||
|
|
7142f755f5 | ||
|
|
9fbc8dc1f9 | ||
|
|
d3819a6a88 | ||
|
|
6e93ed8e5f | ||
|
|
98543d49a9 | ||
|
|
9195eead27 | ||
|
|
e5b384736d | ||
|
|
4def720d1a | ||
|
|
2a0404ea17 | ||
|
|
6d22c4f02e | ||
|
|
24ac12da65 | ||
|
|
3f19882df8 | ||
|
|
dd54c16c1f | ||
|
|
223e9289dc | ||
|
|
2e301bdd51 | ||
|
|
e3ec7de23a | ||
|
|
18ec208381 | ||
|
|
8666daa07d | ||
|
|
926a9bdb03 | ||
|
|
fc2d837a2c | ||
|
|
3f69ccab99 | ||
|
|
b6ee82ee52 | ||
|
|
da1eb859a9 | ||
|
|
2b5269b823 | ||
|
|
6c8eeb0ced | ||
|
|
c5e0f3abc8 | ||
|
|
c6dbe22c57 | ||
|
|
51776e2aa3 | ||
|
|
c9d24607f6 | ||
|
|
46f7a3d4f3 | ||
|
|
56cf450c89 | ||
|
|
38c350b020 | ||
|
|
1f46040f1b | ||
|
|
63b95319cd | ||
|
|
a25d92be9e | ||
|
|
a161210a4a | ||
|
|
24469eb2fa | ||
|
|
a93fb49875 | ||
|
|
08d7cdf95b | ||
|
|
a9334bc247 | ||
|
|
2357d0c466 | ||
|
|
b003d51276 | ||
|
|
503cbf9830 | ||
|
|
2466058c5a | ||
|
|
6b1f422456 | ||
|
|
1d16d67733 | ||
|
|
6f9d15aed8 | ||
|
|
8725f974da | ||
|
|
2551c949ae | ||
|
|
30c6020ce7 | ||
|
|
d00b1ce1a1 | ||
|
|
2c43d79585 | ||
|
|
3e4aacb2b0 | ||
|
|
67cd22371b | ||
|
|
586941ece7 | ||
|
|
32a57cbfa6 | ||
|
|
1837a69b3e | ||
|
|
aa8bfcfd92 | ||
|
|
9e0c658470 | ||
|
|
66aefff4f3 | ||
|
|
bd0fdeecee | ||
|
|
1055eeb01b | ||
|
|
263a4578d4 | ||
|
|
c446b8a5af | ||
|
|
847b34cdcb | ||
|
|
5a57f90b8f | ||
|
|
f8eb9f5bd0 | ||
|
|
c8c336b574 | ||
|
|
43f1410974 | ||
|
|
1df110b3fb | ||
|
|
9bedce0df5 | ||
|
|
ae1d879e5a | ||
|
|
caab2e0952 | ||
|
|
a29d6517d3 | ||
|
|
dae2781818 | ||
|
|
c1de609b1a | ||
|
|
4e84807950 | ||
|
|
41c9cb45d6 | ||
|
|
2d72772f86 | ||
|
|
1cf1f0e04d | ||
|
|
324b88ec2b | ||
|
|
ec64c7ba0b | ||
|
|
67e0f8570e | ||
|
|
1745100705 | ||
|
|
28501944c5 | ||
|
|
c5c1a68f5c | ||
|
|
e2ed7fbd28 | ||
|
|
ab0675055c | ||
|
|
2b65559f36 | ||
|
|
b8beb07df5 | ||
|
|
01748fec49 | ||
|
|
42a50b1a02 | ||
|
|
d81595f43f | ||
|
|
71fa2d867f | ||
|
|
f55dbb0002 | ||
|
|
3e4d623786 | ||
|
|
1b109aac3a | ||
|
|
8558975d55 | ||
|
|
0e895089c7 | ||
|
|
5dd44f66c1 | ||
|
|
a1cfea46c6 | ||
|
|
42c492c85a | ||
|
|
9e8794a39f | ||
|
|
66c3604b2a | ||
|
|
c0ee1ee27b | ||
|
|
a3e669e433 | ||
|
|
8a83b4fff5 | ||
|
|
69c48d3f5d | ||
|
|
88504a335e | ||
|
|
a44a433807 | ||
|
|
9c03a8ae28 | ||
|
|
767a5f3a94 | ||
|
|
db1e138d36 | ||
|
|
84aa05f9a9 | ||
|
|
1071b85472 | ||
|
|
479412b190 | ||
|
|
ac4fc5b0ba | ||
|
|
4a8770232d | ||
|
|
2ea983bdae | ||
|
|
ffce8fa505 | ||
|
|
cb9e529eb7 | ||
|
|
7f0ee208fa | ||
|
|
2d38652034 | ||
|
|
4a2076a550 | ||
|
|
35049b26fe | ||
|
|
39648ba372 | ||
|
|
44ce0bbffd | ||
|
|
a634472873 | ||
|
|
a98c30f7fa | ||
|
|
43d4b80e11 | ||
|
|
09926fcc53 | ||
|
|
17eef7a4aa | ||
|
|
4738d7c951 | ||
|
|
4be0af5fa3 | ||
|
|
8aaa0900e5 | ||
|
|
49b5d9b886 | ||
|
|
7a3912767b | ||
|
|
d1e473aafe | ||
|
|
c91eb7ed47 | ||
|
|
443f631bac | ||
|
|
95be8d4698 | ||
|
|
f3926d020f | ||
|
|
b48eb5fdd3 | ||
|
|
b0fecdd017 | ||
|
|
793483b6e9 | ||
|
|
c99c7fa9af | ||
|
|
59449a73e1 | ||
|
|
dc86d636ac | ||
|
|
27dd2dd5f3 | ||
|
|
494ae1a47f | ||
|
|
7d1e1e5ff1 | ||
|
|
bcd1567b7d | ||
|
|
ae391b885b | ||
|
|
226bc84a4c | ||
|
|
e60a0c8f61 | ||
|
|
218c90a306 | ||
|
|
2a60c80194 | ||
|
|
35b1c55564 | ||
|
|
20476387ff | ||
|
|
a787748a00 | ||
|
|
34ee540c30 | ||
|
|
975a5ffc82 | ||
|
|
dee0870bf6 | ||
|
|
96ec3bd44e | ||
|
|
e4cf4096a6 | ||
|
|
3d79694c0a | ||
|
|
eab3e4e6f7 | ||
|
|
462152bab2 | ||
|
|
766a455db0 | ||
|
|
30200ac219 | ||
|
|
90a9113971 | ||
|
|
ad1834568f | ||
|
|
6231500b4a | ||
|
|
b2dbc08ea0 | ||
|
|
4700f68f4d | ||
|
|
fa73738309 | ||
|
|
25f92ec438 | ||
|
|
6a59c1dfd6 | ||
|
|
bad6e9d2fe | ||
|
|
e544972c1d | ||
|
|
f1e5de0d58 | ||
|
|
e434e1effb | ||
|
|
ca04b210e6 | ||
|
|
51275af41d | ||
|
|
c2417ac5b3 | ||
|
|
72831d413b | ||
|
|
5cb4bd5819 | ||
|
|
2d9bbca9a9 | ||
|
|
7b54c4e969 | ||
|
|
b50f4ec5ce | ||
|
|
86cc7534c2 | ||
|
|
1ab2565244 | ||
|
|
d2089a9344 | ||
|
|
39153c6936 | ||
|
|
1a8e2b92de | ||
|
|
cf63e751bf | ||
|
|
0c51bc2771 | ||
|
|
5f278cce3e | ||
|
|
f8cf3ac832 | ||
|
|
50bdd02a72 | ||
|
|
424155e5cd | ||
|
|
c4a4d25f7e | ||
|
|
ca2e135cba | ||
|
|
8b4583c59c | ||
|
|
6a836f9151 | ||
|
|
c7b92ad945 | ||
|
|
a05b7a43bd | ||
|
|
929346b2f1 | ||
|
|
23ceed01cb | ||
|
|
2ccf9a1110 | ||
|
|
4917d8e47b | ||
|
|
a0963e5d92 | ||
|
|
e2731b532a | ||
|
|
eccd6056bd | ||
|
|
c1273a4b01 | ||
|
|
017752b06e | ||
|
|
9abb7a04ac | ||
|
|
9533b9d887 | ||
|
|
f1a6feeb8f | ||
|
|
35930f2ffb | ||
|
|
0a1e8a2f8b | ||
|
|
4f9315132b | ||
|
|
196a843148 | ||
|
|
9778875d52 | ||
|
|
fdeb812333 | ||
|
|
e21e12e737 | ||
|
|
52d2322955 | ||
|
|
5ea8f7df33 | ||
|
|
7a9c73df3f | ||
|
|
3ad8a366a6 |
2
.env
2
.env
@@ -28,4 +28,4 @@ MAIL_ENCRYPTION=null
|
||||
PUSHER_APP_ID=
|
||||
PUSHER_APP_KEY=
|
||||
PUSHER_APP_SECRET=
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
PUSHER_APP_CLUSTER=mt1
|
||||
44
.gitattributes
vendored
44
.gitattributes
vendored
@@ -1,5 +1,49 @@
|
||||
# Configuration file for Git attributes
|
||||
|
||||
# Core Settings {{{
|
||||
# .gitattributes
|
||||
.gitattributes !filter !diff
|
||||
|
||||
# Line Endings
|
||||
* text=auto
|
||||
|
||||
# Set binary to none-text files
|
||||
*.png -text
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
# GitHub Linguist {{{
|
||||
|
||||
# Exclude files/folder from being detected by the GitHub linguist
|
||||
# statistic.
|
||||
node_modules/* linguist-vendored
|
||||
public/* linguist-generated=true
|
||||
vendor/* linguist-vendored
|
||||
|
||||
# Remove Vue as it's currently not used in the project.
|
||||
resources/assets/js/components/ExampleComponent.vue linguist-vendored
|
||||
|
||||
# System Wide
|
||||
*.css linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
*.js linguist-vendored
|
||||
|
||||
# Include user generated files that's removed bu the setting above.
|
||||
resources/assets/js/app.js linguist-vendored=false
|
||||
resources/assets/sass/_app.scss linguist-vendored=false
|
||||
resources/assets/sass/_rune.scss linguist-vendored=false
|
||||
resources/assets/sass/_variables.scss linguist-vendored=false
|
||||
|
||||
# }}}
|
||||
|
||||
|
||||
# Archive Exlude {{{
|
||||
# Exclude files/folders from being exported when creating an archive.
|
||||
|
||||
.gitattributes export-ignore
|
||||
.gitignore export-ignore
|
||||
.travis.yml export-ignore
|
||||
CHANGELOG.md export-ignore
|
||||
|
||||
# }}}
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,4 +23,5 @@ yarn-error.log
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.VolumeIcon.icns
|
||||
storage/app/public/avatars/*
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,11 @@ namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@@ -25,7 +30,7 @@ class LoginController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
@@ -34,6 +39,88 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
Session::put('backUrl', URL::previous());
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
public function username()
|
||||
{
|
||||
return 'username';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a login request to the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
$current_user = User::currentUser();
|
||||
$request->merge(['username' => $current_user->username]);
|
||||
//die(print_r($request->all()));
|
||||
$this->validateLogin($request);
|
||||
|
||||
// If the class is using the ThrottlesLogins trait, we can automatically throttle
|
||||
// the login attempts for this application. We'll key this by the username and
|
||||
// the IP address of the client making these requests into this application.
|
||||
if ($this->hasTooManyLoginAttempts($request)) {
|
||||
$this->fireLockoutEvent($request);
|
||||
|
||||
return $this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
if ($this->attemptLogin($request)) {
|
||||
return $this->sendLoginResponse($request);
|
||||
}
|
||||
|
||||
// If the login attempt was unsuccessful we will increment the number of attempts
|
||||
// to login and redirect the user back to the login form. Of course, when this
|
||||
// user surpasses their maximum number of attempts they will get locked out.
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
return $this->sendFailedLoginResponse($request);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
}
|
||||
|
||||
public function setUser(User $user)
|
||||
{
|
||||
Auth::logout();
|
||||
session(['current_user' => $user]);
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
public function autologin($uuid)
|
||||
{
|
||||
$user = User::where('autologin', $uuid)->first();
|
||||
Auth::login($user);
|
||||
session(['current_user' => $user]);
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
protected function authenticated(Request $request, $user)
|
||||
{
|
||||
return back();
|
||||
}
|
||||
|
||||
public function redirectTo()
|
||||
{
|
||||
return Session::get('url.intended') ? Session::get('url.intended') : $this->redirectTo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class RegisterController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
||||
@@ -25,7 +25,7 @@ class ResetPasswordController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
||||
@@ -6,8 +6,27 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
protected $user;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(function ($request, $next) {
|
||||
$this->user = $this->user();
|
||||
//print_r($this->user);
|
||||
return $next($request);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return User::currentUser();
|
||||
}
|
||||
}
|
||||
|
||||
28
app/Http/Controllers/HomeController.php
Normal file
28
app/Http/Controllers/HomeController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,16 @@ namespace App\Http\Controllers;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Item;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
use App\SupportedApps\Nzbget;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ItemController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource on the dashboard.
|
||||
*
|
||||
@@ -144,10 +148,13 @@ 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 = Item::create($request->all());
|
||||
@@ -209,8 +216,10 @@ 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 = Item::find($id);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -55,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();
|
||||
@@ -64,17 +73,16 @@ 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();
|
||||
|
||||
$user->settings()->detach($setting->id);
|
||||
$user->settings()->save($setting, ['uservalue' => $setting_value]);
|
||||
|
||||
$route = route('settings.index', [], false);
|
||||
return redirect($route)
|
||||
->with([
|
||||
@@ -95,10 +103,11 @@ 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' => '']);
|
||||
}
|
||||
$route = route('settings.index', [], false);
|
||||
return redirect($route)
|
||||
|
||||
@@ -8,6 +8,10 @@ use DB;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
|
||||
175
app/Http/Controllers/UserController.php
Normal file
175
app/Http/Controllers/UserController.php
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\User;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed')->except(['selectUser']);
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$data['users'] = User::all();
|
||||
return view('users.index', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$data = [];
|
||||
return view('users.create', $data);
|
||||
}
|
||||
|
||||
public function selectUser()
|
||||
{
|
||||
Auth::logout();
|
||||
$data['users'] = User::all();
|
||||
return view('userselect', $data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'username' => 'required|max:255|unique:users',
|
||||
'email' => 'required|email',
|
||||
'password' => 'nullable|confirmed',
|
||||
'password_confirmation' => 'nullable'
|
||||
|
||||
]);
|
||||
$user = new User;
|
||||
$user->username = $request->input('username');
|
||||
$user->email = $request->input('email');
|
||||
$user->public_front = $request->input('public_front');
|
||||
|
||||
$password = $request->input('password');
|
||||
if(!empty($password)) {
|
||||
$user->password = bcrypt($password);
|
||||
}
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
$path = $request->file('file')->store('avatars');
|
||||
$user->avatar = $path;
|
||||
}
|
||||
|
||||
if ((bool)$request->input('autologin_allow') === true) {
|
||||
$user->autologin = (string)Str::uuid();
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.user_updated'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit(User $user)
|
||||
{
|
||||
$data['user'] = $user;
|
||||
return view('users.edit', $data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, User $user)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'username' => 'required|max:255|unique:users,username,'.$user->id,
|
||||
'email' => 'required|email',
|
||||
'password' => 'nullable|confirmed',
|
||||
'password_confirmation' => 'nullable'
|
||||
]);
|
||||
//die(print_r($request->all()));
|
||||
|
||||
$user->username = $request->input('username');
|
||||
$user->email = $request->input('email');
|
||||
$user->public_front = $request->input('public_front');
|
||||
|
||||
$password = $request->input('password');
|
||||
if(!empty($password)) {
|
||||
$user->password = bcrypt($password);
|
||||
} elseif($password == 'null') {
|
||||
$user->password = null;
|
||||
}
|
||||
|
||||
if($request->hasFile('file')) {
|
||||
$path = $request->file('file')->store('avatars');
|
||||
$user->avatar = $path;
|
||||
}
|
||||
|
||||
if ((bool)$request->input('autologin_allow') === true) {
|
||||
$user->autologin = (is_null($user->autologin)) ? (string)Str::uuid() : $user->autologin;
|
||||
} else {
|
||||
$user->autologin = null;
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.user_updated'));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy(User $user)
|
||||
{
|
||||
if($user->id !== 1) {
|
||||
$user->delete();
|
||||
$route = route('dash', [], false);
|
||||
return redirect($route)
|
||||
->with('success',__('app.alert.success.user_deleted'));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,7 @@ class Kernel extends HttpKernel
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'allowed' => \App\Http\Middleware\CheckAllowed::class,
|
||||
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
|
||||
48
app/Http/Middleware/CheckAllowed.php
Normal file
48
app/Http/Middleware/CheckAllowed.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Session;
|
||||
|
||||
class CheckAllowed
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$route = Route::currentRouteName();
|
||||
$current_user = User::currentUser();
|
||||
|
||||
if(str_is('users*', $route)) {
|
||||
if($current_user->id !== 1) {
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
}
|
||||
|
||||
if($route == 'dash') {
|
||||
//print_r(User::all());
|
||||
//die("here".var_dump($current_user->password));
|
||||
if((bool)$current_user->public_front === true) return $next($request);
|
||||
}
|
||||
|
||||
if(empty($current_user->password)) return $next($request);
|
||||
|
||||
// Check if user is logged in as $current_user
|
||||
if (Auth::check()) {
|
||||
$loggedin_user = Auth::user();
|
||||
if($loggedin_user->id === $current_user->id) return $next($request);
|
||||
}
|
||||
|
||||
return Auth::authenticate();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ class RedirectIfAuthenticated
|
||||
public function handle($request, Closure $next, $guard = null)
|
||||
{
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect('/home');
|
||||
return redirect()->intended();
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
@@ -19,11 +19,5 @@ class TrustProxies extends Middleware
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $headers = [
|
||||
Request::HEADER_FORWARDED => 'FORWARDED',
|
||||
Request::HEADER_X_FORWARDED_FOR => 'X_FORWARDED_FOR',
|
||||
Request::HEADER_X_FORWARDED_HOST => 'X_FORWARDED_HOST',
|
||||
Request::HEADER_X_FORWARDED_PORT => 'X_FORWARDED_PORT',
|
||||
Request::HEADER_X_FORWARDED_PROTO => 'X_FORWARDED_PROTO',
|
||||
];
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
}
|
||||
|
||||
76
app/Item.php
76
app/Item.php
@@ -5,15 +5,26 @@ namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Symfony\Component\ClassLoader\ClassMapGenerator;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\User;
|
||||
|
||||
class Item extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::addGlobalScope('user_id', function (Builder $builder) {
|
||||
$current_user = User::currentUser();
|
||||
$builder->where('user_id', $current_user->id);
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
protected $fillable = [
|
||||
'title', 'url', 'colour', 'icon', 'description', 'pinned', 'order', 'type'
|
||||
'title', 'url', 'colour', 'icon', 'description', 'pinned', 'order', 'type', 'user_id'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -26,24 +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,
|
||||
'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,
|
||||
'Netdata' => \App\SupportedApps\Netdata::class,
|
||||
'Nextcloud' => \App\SupportedApps\Nextcloud::class,
|
||||
'Now Showing' => \App\SupportedApps\NowShowing::class,
|
||||
'Nzbhydra' => \App\SupportedApps\Nzbhydra::class,
|
||||
'Ttrss' => \App\SupportedApps\Ttrss::class,
|
||||
'Ombi' => \App\SupportedApps\Ombi::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,
|
||||
@@ -51,12 +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,
|
||||
'pFsense' => \App\SupportedApps\Pfsense::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()
|
||||
@@ -89,7 +135,7 @@ class Item extends Model
|
||||
$output->view = $view;
|
||||
}
|
||||
if(!isset($output->dataonly)) $output->dataonly = '0';
|
||||
|
||||
|
||||
}
|
||||
return (object)$output;
|
||||
}
|
||||
@@ -109,7 +155,7 @@ class Item extends Model
|
||||
}
|
||||
}
|
||||
//die(var_dump($store))
|
||||
|
||||
|
||||
$config['enabled'] = ($store) ? true : false;
|
||||
$config = json_encode($config);
|
||||
}
|
||||
@@ -144,12 +190,14 @@ class Item extends Model
|
||||
}
|
||||
}
|
||||
|
||||
public function getTargetAttribute()
|
||||
public function getLinkTargetAttribute()
|
||||
{
|
||||
if((int)$this->type === 1) {
|
||||
$target = Setting::fetch('window_target');
|
||||
|
||||
if((int)$this->type === 1 || $target === 'current') {
|
||||
return '';
|
||||
} else {
|
||||
return ' target="_blank"';
|
||||
return ' target="' . $target . '"';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,5 +232,13 @@ class Item extends Model
|
||||
return $query->where('type', $typeid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the user that owns the item.
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\User');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ use Illuminate\Support\ServiceProvider;
|
||||
use Artisan;
|
||||
use Schema;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -16,7 +17,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$alt_bg = '';
|
||||
|
||||
|
||||
if(!is_file(base_path('.env'))) {
|
||||
touch(base_path('.env'));
|
||||
@@ -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(/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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Form;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class Setting extends Model
|
||||
{
|
||||
@@ -46,6 +48,12 @@ class Setting extends Model
|
||||
|
||||
public function getListValueAttribute()
|
||||
{
|
||||
if((bool)$this->system === true) {
|
||||
$value = self::_fetch($this->key);
|
||||
} else {
|
||||
$value = self::fetch($this->key);
|
||||
}
|
||||
$this->value = $value;
|
||||
switch($this->type) {
|
||||
case 'image':
|
||||
if(!empty($this->value)) {
|
||||
@@ -80,6 +88,12 @@ class Setting extends Model
|
||||
|
||||
public function getEditValueAttribute()
|
||||
{
|
||||
if((bool)$this->system === true) {
|
||||
$value = self::_fetch($this->key);
|
||||
} else {
|
||||
$value = self::fetch($this->key);
|
||||
}
|
||||
$this->value = $value;
|
||||
switch($this->type) {
|
||||
case 'image':
|
||||
$value = '';
|
||||
@@ -125,6 +139,7 @@ class Setting extends Model
|
||||
return $this->belongsTo('App\SettingGroup', 'group_id');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
@@ -132,20 +147,54 @@ class Setting extends Model
|
||||
*/
|
||||
public static function fetch($key)
|
||||
{
|
||||
if (Setting::cached($key)) {
|
||||
return Setting::$cache[$key];
|
||||
} else {
|
||||
$user = self::user();
|
||||
return self::_fetch($key, $user);
|
||||
}
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function _fetch($key, $user=null)
|
||||
{
|
||||
#$cachekey = ($user === null) ? $key : $key.'-'.$user->id;
|
||||
#if (Setting::cached($cachekey)) {
|
||||
# return Setting::$cache[$cachekey];
|
||||
#} else {
|
||||
$find = self::where('key', '=', $key)->first();
|
||||
|
||||
if (!is_null($find)) {
|
||||
$value = $find->value;
|
||||
Setting::add($key, $value);
|
||||
if((bool)$find->system === true) { // if system variable use global value
|
||||
$value = $find->value;
|
||||
} else { // not system variable so use user specific value
|
||||
// check if user specified value has been set
|
||||
//print_r($user);
|
||||
$usersetting = $user->settings()->where('id', $find->id)->first();
|
||||
//print_r($user->settings);
|
||||
//die(var_dump($usersetting));
|
||||
//->pivot->value;
|
||||
//echo "user: ".$user->id." --- ".$usersettings;
|
||||
if(isset($usersetting) && !empty($usersetting)) {
|
||||
$value = $usersetting->pivot->uservalue;
|
||||
} else { // if not get default from base setting
|
||||
//$user->settings()->save($find, ['value' => $find->value]);
|
||||
#$has_setting = $user->settings()->where('id', $find->id)->exists();
|
||||
#if($has_setting) {
|
||||
# $user->settings()->updateExistingPivot($find->id, ['uservalue' => (string)$find->value]);
|
||||
#} else {
|
||||
# $user->settings()->save($find, ['uservalue' => (string)$find->value]);
|
||||
#}
|
||||
$value = $find->value;
|
||||
}
|
||||
|
||||
}
|
||||
#Setting::add($cachekey, $value);
|
||||
|
||||
return $value;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,21 +224,23 @@ class Setting extends Model
|
||||
$output = '';
|
||||
$homepage_search = self::fetch('homepage_search');
|
||||
$search_provider = self::where('key', '=', 'search_provider')->first();
|
||||
|
||||
//die(var_dump($search_provider->value));
|
||||
$user_search_provider = self::fetch('search_provider');
|
||||
//die(print_r($search_provider));
|
||||
|
||||
//die(var_dump($user_search_provider));
|
||||
// return early if search isn't applicable
|
||||
if((bool)$homepage_search !== true) return $output;
|
||||
if($search_provider->value === 'none') return $output;
|
||||
if(empty($search_provider->value)) return $output;
|
||||
if(is_null($search_provider->value)) return $output;
|
||||
if($user_search_provider === 'none') return $output;
|
||||
if(empty($user_search_provider)) return $output;
|
||||
if(is_null($user_search_provider)) return $output;
|
||||
|
||||
|
||||
if((bool)$homepage_search && (bool)$search_provider) {
|
||||
|
||||
$options = (array)json_decode($search_provider->options);
|
||||
$name = $options[$search_provider->value];
|
||||
if((bool)$search_provider->value) {
|
||||
switch($search_provider->value) {
|
||||
$name = $options[$user_search_provider];
|
||||
if((bool)$user_search_provider) {
|
||||
switch($user_search_provider) {
|
||||
case 'google':
|
||||
$url = 'https://www.google.com/search';
|
||||
$var = 'q';
|
||||
@@ -202,11 +253,14 @@ class Setting extends Model
|
||||
$url = 'https://www.bing.com/search';
|
||||
$var = 'q';
|
||||
break;
|
||||
case 'startpage':
|
||||
$url = 'https://www.startpage.com/';
|
||||
$var = 'q';
|
||||
}
|
||||
$output .= '<div class="searchform">';
|
||||
$output .= Form::open(['url' => $url, 'method' => 'get']);
|
||||
$output .= '<div class="input-container">';
|
||||
$output .= Form::text($var, null, ['class' => 'homesearch', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
|
||||
$output .= Form::text($var, null, ['class' => 'homesearch', 'autofocus' => 'autofocus', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
|
||||
$output .= '<button type="submit">'.ucwords(__('app.settings.search')).'</button>';
|
||||
$output .= '</div>';
|
||||
$output .= Form::close();
|
||||
@@ -215,4 +269,19 @@ class Setting extends Model
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* The users that belong to the setting.
|
||||
*/
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany('App\User')->using('App\SettingUser')->withPivot('uservalue');
|
||||
}
|
||||
|
||||
public static function user()
|
||||
{
|
||||
return User::currentUser();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
10
app/SettingUser.php
Normal file
10
app/SettingUser.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
class SettingUser extends Pivot
|
||||
{
|
||||
//
|
||||
}
|
||||
11
app/SupportedApps/AirSonic.php
Normal file
11
app/SupportedApps/AirSonic.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class AirSonic implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#08F';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/airsonic.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/Bazarr.php
Normal file
14
app/SupportedApps/Bazarr.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Bazarr implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/bazarr.png';
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Bitwarden.php
Normal file
12
app/SupportedApps/Bitwarden.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Bitwarden implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3c8dbc';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/bitwarden.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/BookStack.php
Normal file
14
app/SupportedApps/BookStack.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class BookStack implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#02679E';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/bookstack.png';
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Booksonic.php
Normal file
12
app/SupportedApps/Booksonic.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Booksonic implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#58a';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/booksonic.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Cardigann.php
Normal file
11
app/SupportedApps/Cardigann.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Cardigann implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#753';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/cardigann.png';
|
||||
}
|
||||
}
|
||||
122
app/SupportedApps/CouchPotato.php
Normal file
122
app/SupportedApps/CouchPotato.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class CouchPotato implements Contracts\Applications, Contracts\Livestats
|
||||
{
|
||||
|
||||
private $_client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->_client = new Client(
|
||||
['http_errors' => false,
|
||||
'timeout' => 10]
|
||||
);
|
||||
}
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#363840';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/couchpotato.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'couchpotato';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
echo 'CouchPotato connection failed';
|
||||
return;
|
||||
}
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo "Successfully connected to CouchPotato";
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and includes the port';
|
||||
break;
|
||||
case 409:
|
||||
echo 'Failed: Incorrect session id';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
Log::debug('CouchPotato connection failed');
|
||||
return '';
|
||||
}
|
||||
$data = json_decode($res->getBody());
|
||||
if (! isset($data->movies)) {
|
||||
Log::debug('Failed to fetch data from CouchPotato');
|
||||
return '';
|
||||
}
|
||||
$movies = $data->movies;
|
||||
$wantedMovies = $availableMovies = 0;
|
||||
foreach ($movies as $v) {
|
||||
switch ($v->status) {
|
||||
case 'active':
|
||||
$wantedMovies++;
|
||||
break;
|
||||
case 'done':
|
||||
$availableMovies++;
|
||||
break;
|
||||
default:
|
||||
Log::warning('Unexpected CouchPotato status received: '.$v['status']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Wanted</span><sub>'.$wantedMovies.'</sub></li>
|
||||
<li><span class="title">Available</span><sub>'.$availableMovies.'</sub></li>
|
||||
</ul>
|
||||
';
|
||||
return json_encode(['status' => 'inactive', 'html' => $html]);
|
||||
}
|
||||
|
||||
private function sendRequest()
|
||||
{
|
||||
$res = null;
|
||||
try{
|
||||
$res = $this->_client->request(
|
||||
'GET',
|
||||
$this->getApiUrl()
|
||||
);
|
||||
}catch(\GuzzleHttp\Exception\BadResponseException $e){
|
||||
Log::error("Connection to {$e->getRequest()->getUrl()} failed");
|
||||
Log::debug($e->getMessage());
|
||||
$res = $e->getRequest();
|
||||
}catch(\GuzzleHttp\Exception\ConnectException $e) {
|
||||
Log::error("CouchPotato connection refused");
|
||||
Log::debug($e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function getApiUrl()
|
||||
{
|
||||
$url = $this->config->url;
|
||||
$url = rtrim($url, '/');
|
||||
$apiUrl = $url.'/api/'.$this->config->apikey.'/movie.list';
|
||||
return $apiUrl;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Deluge implements Contracts\Applications {
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
class Deluge implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#357';
|
||||
@@ -9,4 +10,100 @@ class Deluge implements Contracts\Applications {
|
||||
{
|
||||
return 'supportedapps/deluge.png';
|
||||
}
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return 'deluge';
|
||||
}
|
||||
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->login()[0];
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
if(!isset($data->result) || is_null($data->result) || $data->result == false) {
|
||||
echo 'Failed: Invalid Credentials';
|
||||
} else {
|
||||
echo 'Successfully connected to the API';
|
||||
}
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$jar = $this->login()[1];
|
||||
$res = $this->getDetails($jar);
|
||||
$data = json_decode($res->getBody());
|
||||
$download_rate = $data->result->stats->download_rate;
|
||||
$upload_rate = $data->result->stats->upload_rate;
|
||||
$seed_count = $data->result->filters->state[2];
|
||||
$leech_count = $data->result->filters->state[1];
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title"><i class="fas fa-arrow-down"></i> '.$this->formatBytes($download_rate).'</span></li>
|
||||
<li><span class="title"><i class="fas fa-arrow-up"></i> '.$this->formatBytes($upload_rate).'</span></li>
|
||||
</ul>
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Leech: '.$leech_count[1].'</span></li>
|
||||
<li><span class="title">Seed: '.$seed_count[1].'</span></li>
|
||||
</ul>
|
||||
';
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function getDetails($jar)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$url = rtrim($url, '/');
|
||||
$api_url = $url.'/json';
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('POST', $api_url, [
|
||||
'body' => '{"method": "web.update_ui", "params": [["none"], {}], "id": 1}',
|
||||
'cookies' => $jar,
|
||||
'headers' => ['content-type' => 'application/json', 'Accept' => 'application/json']
|
||||
]);
|
||||
return $res;
|
||||
}
|
||||
public function login()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$password = $config->password;
|
||||
$url = rtrim($url, '/');
|
||||
$api_url = $url.'/json';
|
||||
$jar = new \GuzzleHttp\Cookie\CookieJar();
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('POST', $api_url, [
|
||||
'body' => '{"method": "auth.login", "params": ["'.$password.'"], "id": 1}',
|
||||
'cookies' => $jar,
|
||||
'headers' => ['content-type' => 'application/json', 'Accept' => 'application/json']
|
||||
]);
|
||||
return array($res,$jar);
|
||||
}
|
||||
|
||||
function formatBytes($bytes, $precision = 2) {
|
||||
$units = array('B', 'KB', 'MB', 'GB', 'TB');
|
||||
|
||||
$bytes = max($bytes, 0);
|
||||
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
||||
$pow = min($pow, count($units) - 1);
|
||||
|
||||
// Uncomment one of the following alternatives
|
||||
$bytes /= pow(1024, $pow);
|
||||
// $bytes /= (1 << (10 * $pow));
|
||||
|
||||
return round($bytes, $precision) . ' ' . $units[$pow] . 'ps';
|
||||
}
|
||||
}
|
||||
|
||||
12
app/SupportedApps/Dokuwiki.php
Normal file
12
app/SupportedApps/Dokuwiki.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Dokuwiki implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#9d7056';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/dokuwiki.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Flood.php
Normal file
12
app/SupportedApps/Flood.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Flood implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '##00D091';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/Flood.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/FreshRSS.php
Normal file
11
app/SupportedApps/FreshRSS.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class FreshRSS implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#003B73';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/freshrss.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Gitea.php
Normal file
12
app/SupportedApps/Gitea.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Gitea implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#585e52';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/gitea.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/Glances.php
Normal file
14
app/SupportedApps/Glances.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Glances implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2c363f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/glances.png';
|
||||
}
|
||||
|
||||
}
|
||||
12
app/SupportedApps/Grafana.php
Normal file
12
app/SupportedApps/Grafana.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Grafana implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#a56e4d';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/grafana.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Headphones.php
Normal file
12
app/SupportedApps/Headphones.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Headphones implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#185';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/headphones.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Krusader.php
Normal file
11
app/SupportedApps/Krusader.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Krusader implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#5A5';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/krusader.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Mailcow.php
Normal file
12
app/SupportedApps/Mailcow.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Mailcow implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#161b1f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/mailcow.svg';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Monica.php
Normal file
12
app/SupportedApps/Monica.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Monica implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#fafbfc';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/monica.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/MusicBrainz.php
Normal file
12
app/SupportedApps/MusicBrainz.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class MusicBrainz implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#a0a';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/musicbrainz.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Mylar.php
Normal file
12
app/SupportedApps/Mylar.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Mylar implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#aa0';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/mylar.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/NowShowing.php
Normal file
11
app/SupportedApps/NowShowing.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class NowShowing implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#690000';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nowshowing.png';
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
11
app/SupportedApps/OpenMediaVault.php
Normal file
11
app/SupportedApps/OpenMediaVault.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class OpenMediaVault implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#5AF';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/openmediavault.png';
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
class Pfsense implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#4e4742';
|
||||
return '#243699';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pfsense.png';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
app/SupportedApps/Rancher.php
Normal file
12
app/SupportedApps/Rancher.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Rancher implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#78c9cf';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/rancher.png';
|
||||
}
|
||||
}
|
||||
95
app/SupportedApps/Runeaudio.php
Normal file
95
app/SupportedApps/Runeaudio.php
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Runeaudio implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#05A';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/runeaudio.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return 'runeaudio';
|
||||
}
|
||||
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('status');
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo 'Successfully connected to the API';
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$output = '';
|
||||
$active = 'active';
|
||||
$artist = '';
|
||||
$song_title = '';
|
||||
$res = $this->buildRequest('currentsong');
|
||||
$array = explode("\n", $res->getBody());
|
||||
foreach($array as $item) {
|
||||
$item_array = explode(": ", $item);
|
||||
if ($item_array[0] == 'Artist') {
|
||||
$artist = $item_array[1];
|
||||
} elseif ($item_array[0] == 'Title') {
|
||||
$song_title = $item_array[1];
|
||||
}
|
||||
}
|
||||
|
||||
$output = '<ul class="livestats">';
|
||||
|
||||
if (strlen($artist) > 12) {
|
||||
$output = $output.'<li><span class="title-marquee"><span>'.$artist.'</span></span></li>';
|
||||
} else {
|
||||
$output = $output.'<li><span class="title">'.$artist.'</span></li>';
|
||||
}
|
||||
|
||||
$output = $output.'</ul><ul class="livestats">';
|
||||
|
||||
if (strlen($song_title) > 12) {
|
||||
$output = $output.'<li><span class="title-marquee"><span>'.$song_title.'</span></span></li>';
|
||||
} else {
|
||||
$output = $output.'<li><span class="title">'.$song_title.'</span></li>';
|
||||
}
|
||||
|
||||
$output = $output.'</ul>';
|
||||
|
||||
return json_encode(['status' => $active, 'html' => $output]);
|
||||
}
|
||||
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/command/?cmd='.$endpoint;
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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
app/SupportedApps/Sickrage.php
Normal file
12
app/SupportedApps/Sickrage.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Sickrage implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#6185a6';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/sickrage.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Syncthing.php
Normal file
11
app/SupportedApps/Syncthing.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Syncthing implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#888';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/syncthing.png';
|
||||
}
|
||||
}
|
||||
14
app/SupportedApps/TVheadend.php
Normal file
14
app/SupportedApps/TVheadend.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class TVheadend implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#006080';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/tvheadend.png';
|
||||
}
|
||||
|
||||
}
|
||||
77
app/SupportedApps/Tautulli.php
Normal file
77
app/SupportedApps/Tautulli.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Tautulli implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2d2208';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/tautulli.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'tautulli';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('arnold');
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
if(isset($data->error) && !empty($data->error)) {
|
||||
echo 'Failed: '.$data->error;
|
||||
} else {
|
||||
echo 'Successfully connected to the API';
|
||||
}
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->buildRequest('get_activity');
|
||||
$data = json_decode($res->getBody());
|
||||
$stream_count = $data->response->data->stream_count;
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Stream Count</span><strong>'.$stream_count.'</strong></li>
|
||||
</ul>
|
||||
';
|
||||
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$apikey = $config->apikey;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api/v2?apikey='.$apikey.'&cmd='.$endpoint;
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
app/SupportedApps/Transmission.php
Normal file
169
app/SupportedApps/Transmission.php
Normal file
@@ -0,0 +1,169 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Transmission implements Contracts\Applications, Contracts\Livestats
|
||||
{
|
||||
|
||||
private $_client;
|
||||
private $_clientOptions = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$body = array();
|
||||
$body["method"] = "torrent-get";
|
||||
$body["arguments"] = array("fields" => ["percentDone","status","rateDownload","rateUpload"]);
|
||||
$this->_client = new Client(
|
||||
['http_errors' => false,
|
||||
'timeout' => 10,
|
||||
'body' => json_encode($body)]
|
||||
);
|
||||
}
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#950003';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/transmission.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'transmission';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
echo 'Transmission connection failed';
|
||||
return;
|
||||
}
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
echo "Successfully connected with status: ".$data->result."\n";
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and includes the port';
|
||||
break;
|
||||
case 409:
|
||||
echo 'Failed: Incorrect session id';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->sendRequest();
|
||||
if ($res == null) {
|
||||
Log::debug('Transmission connection failed');
|
||||
return '';
|
||||
}
|
||||
$data = json_decode($res->getBody());
|
||||
if (! isset($data->arguments)) {
|
||||
Log::debug('Failed to fetch data from Transmission');
|
||||
return '';
|
||||
}
|
||||
$torrents = $data->arguments->torrents;
|
||||
$torrentCount = count($torrents);
|
||||
$rateDownload = $rateUpload = $completedTorrents = 0;
|
||||
foreach ($torrents as $thisTorrent) {
|
||||
$rateDownload += $thisTorrent->rateDownload;
|
||||
$rateUpload += $thisTorrent->rateUpload;
|
||||
if ($thisTorrent->percentDone == 1) {
|
||||
$completedTorrents += 1;
|
||||
}
|
||||
}
|
||||
if ($torrentCount - $completedTorrents == 0) {
|
||||
// Don't poll as frequently if we don't have any active torrents
|
||||
$active = 'inactive';
|
||||
}
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Done</span><sub>'.$completedTorrents.' / '.$torrentCount.'</sub></li>
|
||||
<li><span class="title">Down</span><sub>'.format_bytes($rateDownload).'</sub></li>
|
||||
<li><span class="title">Up</span><sub>'.format_bytes($rateUpload).'</sub></li>
|
||||
</ul>
|
||||
';
|
||||
return json_encode(['status' => $active, 'html' => $html]);;
|
||||
}
|
||||
|
||||
private function sendRequest()
|
||||
{
|
||||
$optionsSet = $this->setClientOptions();
|
||||
if (! $optionsSet) {
|
||||
// Pass the failed response back up the chain
|
||||
return null;
|
||||
}
|
||||
$res = $this->torrentGet();
|
||||
if ($res->getStatusCode() == 409) {
|
||||
$this->setClientOptions();
|
||||
$res = $this->torrentGet();
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function torrentGet()
|
||||
{
|
||||
$res = null;
|
||||
try{
|
||||
$res = $this->_client->request(
|
||||
'POST',
|
||||
$this->getApiUrl(),
|
||||
$this->_clientOptions
|
||||
);
|
||||
}catch(\GuzzleHttp\Exception\BadResponseException $e){
|
||||
Log::error("Connection to {$e->getRequest()->getUrl()} failed");
|
||||
Log::debug($e->getMessage());
|
||||
$res = $e->getRequest();
|
||||
}catch(\GuzzleHttp\Exception\ConnectException $e) {
|
||||
Log::error("Transmission connection refused");
|
||||
Log::debug($e->getMessage());
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
private function setClientOptions()
|
||||
{
|
||||
if ($this->config->username != '' || $this->config->password != '') {
|
||||
$this->_clientOptions = ['auth'=> [$this->config->username, $this->config->password, 'Basic']];
|
||||
}
|
||||
try{
|
||||
$res = $this->_client->request('HEAD', $this->getApiUrl(), $this->_clientOptions);
|
||||
$xtId = $res->getHeaderLine('X-Transmission-Session-Id');
|
||||
if ($xtId != null) {
|
||||
$this->_clientOptions['headers'] = ['X-Transmission-Session-Id' => $xtId];
|
||||
} else {
|
||||
Log::error("Unable to get Transmission session information");
|
||||
Log::debug("Status Code: ".$res->getStatusCode());
|
||||
}
|
||||
}catch(\GuzzleHttp\Exception\ConnectException $e){
|
||||
Log::error("Failed connection to Transmission");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private function getApiUrl()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
$api_url = $url.'/transmission/rpc';
|
||||
|
||||
return $api_url;
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Unraid.php
Normal file
12
app/SupportedApps/Unraid.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Unraid implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#A12624';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/unraid.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Virtualmin.php
Normal file
12
app/SupportedApps/Virtualmin.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Virtualmin implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#161b1f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/virtualmin.svg';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/Watcher3.php
Normal file
11
app/SupportedApps/Watcher3.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Watcher3 implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#500';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/watcher3.png';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/WebTools.php
Normal file
11
app/SupportedApps/WebTools.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class WebTools implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#555';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/webtools.png';
|
||||
}
|
||||
}
|
||||
12
app/SupportedApps/Webmin.php
Normal file
12
app/SupportedApps/Webmin.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Webmin implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#161b1f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/webmin.svg';
|
||||
}
|
||||
}
|
||||
11
app/SupportedApps/pyLoad.php
Normal file
11
app/SupportedApps/pyLoad.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class pyLoad implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#881';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pyload.png';
|
||||
}
|
||||
}
|
||||
33
app/User.php
33
app/User.php
@@ -15,7 +15,7 @@ class User extends Authenticatable
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name', 'email', 'password',
|
||||
'username', 'email', 'password',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -26,4 +26,35 @@ class User extends Authenticatable
|
||||
protected $hidden = [
|
||||
'password', 'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the items for the user.
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany('App\Item');
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings that belong to the user.
|
||||
*/
|
||||
public function settings()
|
||||
{
|
||||
return $this->belongsToMany('App\Setting')->withPivot('uservalue');
|
||||
}
|
||||
|
||||
public static function currentUser()
|
||||
{
|
||||
$current_user = session('current_user');
|
||||
if ($current_user) { // if logged in, set this user
|
||||
return $current_user;
|
||||
} else { // not logged in, get first user
|
||||
$user = User::first();
|
||||
session(['current_user' => $user]);
|
||||
return $user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,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"
|
||||
},
|
||||
|
||||
1163
composer.lock
generated
1163
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ return [
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Heimdall'),
|
||||
'version' => '1.4.3',
|
||||
'version' => '2.0.0',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
38
database/migrations/2018_10_12_122907_create_users_table.php
Normal file
38
database/migrations/2018_10_12_122907_create_users_table.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateUsersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('username')->unique();
|
||||
$table->string('email');
|
||||
$table->string('avatar')->nullable();
|
||||
$table->string('password')->nullable();
|
||||
$table->string('autologin')->nullable()->index();
|
||||
$table->boolean('public_front')->default(false);
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreatePasswordResetsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('password_resets', function (Blueprint $table) {
|
||||
$table->string('email')->index();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('password_resets');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddUserIdToItemsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->integer('user_id')->default(1)->index(); // 0 = item, 1 = category
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->dropColumn(['user_id']);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -12,5 +12,6 @@ class DatabaseSeeder extends Seeder
|
||||
public function run()
|
||||
{
|
||||
$this->call(SettingsSeeder::class);
|
||||
$this->call(UsersSeeder::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,8 @@ class SettingsSeeder extends Seeder
|
||||
'none' => 'app.options.none',
|
||||
'google' => 'app.options.google',
|
||||
'ddg' => 'app.options.ddg',
|
||||
'bing' => 'app.options.bing'
|
||||
'bing' => 'app.options.bing',
|
||||
'startpage' => 'app.options.startpage',
|
||||
]);
|
||||
|
||||
if(!$setting = Setting::find(4)) {
|
||||
@@ -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://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>';
|
||||
$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://paypal.me/pools/c/81ZR4dfBGo">Paypal</a>';
|
||||
$setting->system = true;
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
27
database/seeds/UsersSeeder.php
Normal file
27
database/seeds/UsersSeeder.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use App\User;
|
||||
|
||||
class UsersSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
// Groups
|
||||
if(!$user = User::find(1)) {
|
||||
$user = new User;
|
||||
$user->id = 1;
|
||||
$user->username = 'admin';
|
||||
$user->email = 'admin@test.com';
|
||||
$user->password = null;
|
||||
$user->save();
|
||||
} else {
|
||||
//$user->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
9553
package-lock.json
generated
9553
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -10,16 +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"
|
||||
}
|
||||
}
|
||||
|
||||
238
public/css/app.css
vendored
238
public/css/app.css
vendored
@@ -1,5 +1,4 @@
|
||||
@import url(https://fonts.googleapis.com/css?family=Raleway:300,400,600);/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
|
||||
|
||||
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
-ms-text-size-adjust: 100%;
|
||||
@@ -225,9 +224,7 @@ html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
*,
|
||||
*:before,
|
||||
*:after {
|
||||
*, *:before, *:after {
|
||||
-webkit-box-sizing: inherit;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
@@ -236,6 +233,61 @@ body {
|
||||
background: #cfd2d4;
|
||||
}
|
||||
|
||||
#switchuser {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
position: absolute;
|
||||
padding: 10px;
|
||||
color: white;
|
||||
text-align: center;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
border-top: 2px solid rgba(255, 255, 255, 0.15);
|
||||
border-right: 2px solid rgba(255, 255, 255, 0.15);
|
||||
-webkit-box-shadow: 0 0 10px 0px rgba(0, 0, 0, 0.4);
|
||||
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;
|
||||
}
|
||||
|
||||
#switchuser img {
|
||||
width: 50px;
|
||||
margin-bottom: 5px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#switchuser .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);
|
||||
-webkit-transition: all .35s ease-in-out;
|
||||
transition: all .35s ease-in-out;
|
||||
}
|
||||
|
||||
#switchuser .btn:hover {
|
||||
background: #d64d55;
|
||||
}
|
||||
|
||||
#app {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
@@ -245,7 +297,7 @@ body {
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
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;
|
||||
@@ -325,9 +377,8 @@ body {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#app main,
|
||||
#app #sortable {
|
||||
padding: 10px;
|
||||
#app main, #app #sortable {
|
||||
padding: 30px 10px;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
@@ -378,6 +429,68 @@ body {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.userlist {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.userlist .user {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
-webkit-box-pack: center;
|
||||
-ms-flex-pack: center;
|
||||
justify-content: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
margin: 20px;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-radius: 15px;
|
||||
border: 5px solid rgba(255, 255, 255, 0.7);
|
||||
-webkit-box-shadow: 0 0 10px 0px rgba(0, 0, 0, 0.4);
|
||||
box-shadow: 0 0 10px 0px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.userlist .user-img {
|
||||
width: 130px;
|
||||
height: 130px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 50%;
|
||||
margin: 10px 10px 15px;
|
||||
}
|
||||
|
||||
.userlist #password {
|
||||
color: #2f313a;
|
||||
width: 100%;
|
||||
padding: 5px 10px;
|
||||
margin: 15px -5px;
|
||||
}
|
||||
|
||||
.userlist .btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.userlist .forgot {
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.item-container {
|
||||
position: relative;
|
||||
}
|
||||
@@ -396,6 +509,14 @@ body {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.black {
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.white {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.message-container {
|
||||
width: 100%;
|
||||
padding: 10px 20px;
|
||||
@@ -423,13 +544,11 @@ body {
|
||||
box-shadow: 0 0 15px 3px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.alert.alert-success,
|
||||
.alert.alert-danger {
|
||||
.alert.alert-success, .alert.alert-danger {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.alert.alert-success:before,
|
||||
.alert.alert-danger:before {
|
||||
.alert.alert-success:before, .alert.alert-danger:before {
|
||||
content: "\F00C";
|
||||
font-family: 'Font Awesome 5 Pro';
|
||||
font-weight: 900;
|
||||
@@ -463,8 +582,7 @@ body {
|
||||
color: #91a1b3;
|
||||
}
|
||||
|
||||
#app.header .item,
|
||||
#app.header .add-item {
|
||||
#app.header .item, #app.header .add-item {
|
||||
-webkit-transform: scale(0.9);
|
||||
transform: scale(0.9);
|
||||
opacity: 0.8;
|
||||
@@ -587,8 +705,7 @@ body {
|
||||
margin: 10px 40px;
|
||||
}
|
||||
|
||||
.module-container header,
|
||||
.module-container footer {
|
||||
.module-container header, .module-container footer {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
@@ -606,8 +723,7 @@ body {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.module-container header .section-title,
|
||||
.module-container footer .section-title {
|
||||
.module-container header .section-title, .module-container footer .section-title {
|
||||
font-size: 18px;
|
||||
color: #5b5b5b;
|
||||
margin-left: 25px;
|
||||
@@ -756,8 +872,7 @@ div.create .input label:not(.switch) {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
div.create .input input,
|
||||
div.create .input select {
|
||||
div.create .input input, div.create .input select {
|
||||
width: 100%;
|
||||
border: 1px solid #dedfe2;
|
||||
padding: 10px;
|
||||
@@ -825,13 +940,11 @@ div.create .input select {
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
|
||||
.switch input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
@@ -871,7 +984,6 @@ input:checked + .slider:before {
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
|
||||
.slider.round {
|
||||
border-radius: 20px;
|
||||
}
|
||||
@@ -1025,8 +1137,7 @@ a.settinglink {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-state-hover,
|
||||
.ui-state-active {
|
||||
.ui-state-hover, .ui-state-active {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -1169,10 +1280,60 @@ select:-webkit-autofill:focus {
|
||||
color: #2f313a !important;
|
||||
}
|
||||
|
||||
.title-marquee {
|
||||
width: 125px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.title-marquee span {
|
||||
white-space: nowrap;
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
-webkit-animation: marquee 8s linear;
|
||||
animation: marquee 8s linear;
|
||||
}
|
||||
|
||||
@-webkit-keyframes marquee {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
20% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
95% {
|
||||
-webkit-transform: translate(-200%, 0);
|
||||
transform: translate(-200%, 0);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translate(-200%, 0);
|
||||
transform: translate(-200%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes marquee {
|
||||
0% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
20% {
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
}
|
||||
95% {
|
||||
-webkit-transform: translate(-200%, 0);
|
||||
transform: translate(-200%, 0);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: translate(-200%, 0);
|
||||
transform: translate(-200%, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*! Huebee v2.0.0
|
||||
http://huebee.buzz
|
||||
---------------------------------------------- */
|
||||
|
||||
.huebee {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
@@ -1267,7 +1428,6 @@ http://huebee.buzz
|
||||
* Font Awesome Pro 5.0.2 by @fontawesome - http://fontawesome.com
|
||||
* License - http://fontawesome.com/license (Commercial License)
|
||||
*/
|
||||
|
||||
.fa,
|
||||
.fas,
|
||||
.far,
|
||||
@@ -1404,7 +1564,6 @@ http://huebee.buzz
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
@@ -1416,7 +1575,6 @@ http://huebee.buzz
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
@@ -1499,7 +1657,6 @@ http://huebee.buzz
|
||||
|
||||
/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
|
||||
readers do not read off random characters that represent icons */
|
||||
|
||||
.fa-500px:before {
|
||||
content: "\F26E";
|
||||
}
|
||||
@@ -5283,8 +5440,7 @@ readers do not read off random characters that represent icons */
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.sr-only-focusable:active,
|
||||
.sr-only-focusable:focus {
|
||||
.sr-only-focusable:active, .sr-only-focusable:focus {
|
||||
clip: auto;
|
||||
height: auto;
|
||||
margin: 0;
|
||||
@@ -5297,13 +5453,12 @@ readers do not read off random characters that represent icons */
|
||||
* Font Awesome Pro 5.0.2 by @fontawesome - http://fontawesome.com
|
||||
* License - http://fontawesome.com/license (Commercial License)
|
||||
*/
|
||||
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 5 Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
src: url("/webfonts/fa-solid-900.eot");
|
||||
src: url("/webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("/webfonts/fa-solid-900.woff2") format("woff2"), url("/webfonts/fa-solid-900.woff") format("woff"), url("/webfonts/fa-solid-900.ttf") format("truetype"), url("/webfonts/fa-solid-900.svg#fontawesome") format("svg");
|
||||
src: url("../webfonts/fa-solid-900.eot");
|
||||
src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg");
|
||||
}
|
||||
|
||||
.fa,
|
||||
@@ -5614,9 +5769,7 @@ readers do not read off random characters that represent icons */
|
||||
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 {
|
||||
.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;
|
||||
}
|
||||
|
||||
@@ -5644,14 +5797,12 @@ readers do not read off random characters that represent icons */
|
||||
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 {
|
||||
.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 {
|
||||
.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;
|
||||
}
|
||||
@@ -5962,4 +6113,3 @@ readers do not read off random characters that represent icons */
|
||||
.select2-container--classic.select2-container--open .select2-dropdown {
|
||||
border-color: #5897fb;
|
||||
}
|
||||
|
||||
|
||||
6
public/img/heimdall-logo-small.svg
Normal file
6
public/img/heimdall-logo-small.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="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
public/img/heimdall-logo.svg
Normal file
14
public/img/heimdall-logo.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="780" height="619" viewBox="0 0 780 619">
|
||||
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about=""/>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
|
||||
|
||||
<?xpacket end="w"?></metadata>
|
||||
<path class="cls-1" d="M440.227,415.119V390.2l8.552-26.577C508.647,304.3,555.686,248.776,564,231.691l-10.215,3.56s9.5-11.864,8.552-18.51c-7.6-116.273-73.17-176.862-91.226-191.732,26.607,31.955,19.326,42.4,19.326,42.4C478.714,45.576,454.64,24.377,449.888,19l-5.7,33.853c22.806,13.289,16.79,20.882,16.79,20.882C455.591,66.141,441.021,59.5,441.021,59.5l-1.586,9.491c6.973,3.165,38.327,22.149,38.565,70.872,0,59.323-33.735,74.985-39.674,77.357-19.718-11.865-41.1-11.627-46.326-12.1-5.226.474-26.608,0.236-46.324,12.1C339.735,214.844,306,199.182,306,139.859c0.238-48.723,31.6-67.707,38.564-70.872L342.983,59.5s-14.574,6.644-19.955,14.238c0,0-6.022-7.593,16.786-20.882L334.112,19c-4.752,5.378-28.824,26.577-40.543,48.407,0,0-7.288-10.443,19.32-42.4-18.054,14.87-83.625,75.459-91.226,191.732-0.95,6.646,8.554,18.51,8.554,18.51L220,231.691c8.316,17.085,55.355,72.612,115.221,131.935l8.554,26.577v24.916l-7.6-26.577L318.83,360.067v28.95C325.957,409.186,353.751,450,353.751,450V365.525L247.32,249.488s66.52,54.1,85.526,73.56l9.978-10.2c-12.355-8.78-66.045-62.646-70.8-110.1,40.388,85.426,79.111,96.1,107.62,129.325V340.2h24.707v-8.131c28.508-33.221,67.233-43.9,107.619-129.325-4.75,47.459-58.442,101.325-70.8,110.1l9.976,10.2c19.006-19.458,85.526-73.56,85.526-73.56L430.249,365.525V450s27.8-40.815,34.923-60.984v-28.95l-17.343,28.475ZM392,313.083c-17.818-11.865-63.668-39.629-82.672-83.053a314.117,314.117,0,0,0,34.447,34.882s-1.189-30.61,1.186-37.255c4.276,36.781,13.068,52.442,47.039,71.9,33.973-19.458,42.763-35.119,47.039-71.9,2.375,6.645,1.188,37.255,1.188,37.255a314.117,314.117,0,0,0,34.447-34.882C455.668,273.454,409.818,301.218,392,313.083Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
112
public/js/app.js
vendored
112
public/js/app.js
vendored
@@ -11,10 +11,10 @@ $.when( $.ready ).then(function() {
|
||||
|
||||
if($('.message-container').length) {
|
||||
setTimeout(
|
||||
function()
|
||||
{
|
||||
$('.message-container').fadeOut();
|
||||
}, 3500);
|
||||
function()
|
||||
{
|
||||
$('.message-container').fadeOut();
|
||||
}, 3500);
|
||||
}
|
||||
|
||||
if($('.livestats-container').length) {
|
||||
@@ -27,20 +27,21 @@ $.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);
|
||||
}
|
||||
});
|
||||
})();
|
||||
})();
|
||||
});
|
||||
|
||||
}
|
||||
@@ -48,20 +49,20 @@ $.when( $.ready ).then(function() {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
var reader = new FileReader();
|
||||
|
||||
$("#upload").change(function() {
|
||||
reader.onload = function(e) {
|
||||
$('#appimage img').attr('src', e.target.result);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
$('#upload').change(function() {
|
||||
readURL(this);
|
||||
});
|
||||
/*$(".droppable").droppable({
|
||||
});
|
||||
/*$(".droppable").droppable({
|
||||
tolerance: "intersect",
|
||||
drop: function( event, ui ) {
|
||||
var tag = $( this ).data('id');
|
||||
@@ -74,13 +75,13 @@ $.when( $.ready ).then(function() {
|
||||
alert('not added');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});*/
|
||||
|
||||
$( "#sortable" ).sortable({
|
||||
$( '#sortable' ).sortable({
|
||||
stop: function (event, ui) {
|
||||
var idsInOrder = $("#sortable").sortable('toArray', {
|
||||
var idsInOrder = $('#sortable').sortable('toArray', {
|
||||
attribute: 'data-id'
|
||||
});
|
||||
$.post(
|
||||
@@ -88,12 +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');
|
||||
@@ -103,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) {
|
||||
@@ -159,5 +155,5 @@ $.when( $.ready ).then(function() {
|
||||
current.toggleClass('active');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
13
public/js/jquery-ui.min.js
vendored
Normal file
13
public/js/jquery-ui.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
public/mix-manifest.json
generated
6
public/mix-manifest.json
generated
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"/css/app.css": "/css/app.css?id=353c513dd97a5fa0607d",
|
||||
"/js/app.js": "/js/app.js?id=24ea5e5c1fbea3461a14"
|
||||
}
|
||||
"/css/app.css": "/css/app.css?id=24e9bb4fa993b66f0572",
|
||||
"/js/app.js": "/js/app.js?id=f18d23b8fc7a094a2c66"
|
||||
}
|
||||
|
||||
160
readme.md
160
readme.md
@@ -1,76 +1,126 @@
|
||||

|
||||
# Heimdall
|
||||
|
||||
[](https://heimdall.site)
|
||||
|
||||
____
|
||||
[](https://discord.gg/CCjHKn4)
|
||||
[](https://hub.docker.com/r/linuxserver/heimdall/)
|
||||
[](http://www.firsttimersonly.com/)
|
||||
|
||||
[](https://www.firsttimersonly.com/)
|
||||
[](https://paypal.me/pools/c/81ZR4dfBGo)
|
||||
|
||||
___
|
||||
|
||||
## About
|
||||
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. It’s dedicated to this purpose so you won’t 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.
|
||||
|
||||

|
||||

|
||||
|
||||
## 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**
|
||||
- Deluge
|
||||
- AirSonic
|
||||
- Bazarr
|
||||
- Bitwarden
|
||||
- Booksonic
|
||||
- BookStack
|
||||
- Cardigann
|
||||
- DokuWiki
|
||||
- Duplicati
|
||||
- Emby
|
||||
- FreshRSS
|
||||
- Gitea
|
||||
- Grafana
|
||||
- Graylog
|
||||
- Headphones
|
||||
- Jdownloader
|
||||
- Mcmyadmin
|
||||
- Krusader
|
||||
- LibreNMS
|
||||
- Lidarr
|
||||
- Mailcow
|
||||
- McMyAdmin
|
||||
- Medusa
|
||||
- NZBGet
|
||||
- NZBHydra
|
||||
- Monica
|
||||
- MusicBrainz
|
||||
- Mylar
|
||||
- NZBhydra & NZBhydra2
|
||||
- Netdata
|
||||
- Nextcloud
|
||||
- Openhab
|
||||
- Pihole
|
||||
- Ombi
|
||||
- OpenHAB
|
||||
- OpenMediaVault
|
||||
- Plex
|
||||
- Plexpy
|
||||
- Plexrequests
|
||||
- Portainer
|
||||
- Sabnzbd
|
||||
- Radarr
|
||||
- Rancher
|
||||
- SickRage
|
||||
- Sonarr
|
||||
- TT-RSS
|
||||
- Traefik
|
||||
- UniFi
|
||||
- pFsense
|
||||
- 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
|
||||
|
||||
@@ -85,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
|
||||
@@ -95,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 / {
|
||||
@@ -127,18 +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
|
||||
https://discord.gg/CCjHKn4 or through GitHub issues
|
||||
|
||||
## Donate
|
||||
If you would like to show your appreciation, feel free to use the link below.
|
||||
|
||||
[](https://paypal.me/pools/c/81ZR4dfBGo)
|
||||
[](https://paypal.me/pools/c/81ZR4dfBGo)
|
||||
|
||||
## 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:
|
||||
|
||||
@@ -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,20 +18,21 @@ $.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);
|
||||
}
|
||||
});
|
||||
})();
|
||||
})();
|
||||
});
|
||||
|
||||
}
|
||||
@@ -39,20 +40,20 @@ $.when( $.ready ).then(function() {
|
||||
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]);
|
||||
}
|
||||
}
|
||||
var reader = new FileReader();
|
||||
|
||||
$("#upload").change(function() {
|
||||
reader.onload = function(e) {
|
||||
$('#appimage img').attr('src', e.target.result);
|
||||
};
|
||||
|
||||
reader.readAsDataURL(input.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
$('#upload').change(function() {
|
||||
readURL(this);
|
||||
});
|
||||
/*$(".droppable").droppable({
|
||||
});
|
||||
/*$(".droppable").droppable({
|
||||
tolerance: "intersect",
|
||||
drop: function( event, ui ) {
|
||||
var tag = $( this ).data('id');
|
||||
@@ -65,13 +66,13 @@ $.when( $.ready ).then(function() {
|
||||
alert('not added');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
});*/
|
||||
|
||||
$( "#sortable" ).sortable({
|
||||
$( '#sortable' ).sortable({
|
||||
stop: function (event, ui) {
|
||||
var idsInOrder = $("#sortable").sortable('toArray', {
|
||||
var idsInOrder = $('#sortable').sortable('toArray', {
|
||||
attribute: 'data-id'
|
||||
});
|
||||
$.post(
|
||||
@@ -79,12 +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');
|
||||
@@ -94,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) {
|
||||
@@ -150,5 +146,5 @@ $.when( $.ready ).then(function() {
|
||||
current.toggleClass('active');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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
resources/assets/sass/_rune.scss
Normal file
18
resources/assets/sass/_rune.scss
Normal 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); }
|
||||
}
|
||||
3
resources/assets/sass/app.scss
vendored
3
resources/assets/sass/app.scss
vendored
@@ -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,6 +10,7 @@
|
||||
|
||||
// Bootstrap
|
||||
@import "app";
|
||||
@import "rune";
|
||||
|
||||
// Huebee
|
||||
@import "huebee";
|
||||
|
||||
@@ -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;
|
||||
|
||||
110
resources/lang/br/app.php
Normal file
110
resources/lang/br/app.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| App Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
'settings.system' => 'Sistema',
|
||||
'settings.appearance' => 'Aparência',
|
||||
'settings.miscellaneous' => 'Diversos',
|
||||
'settings.support' => 'Ajuda',
|
||||
'settings.donate' => 'Doar',
|
||||
|
||||
'settings.version' => 'Versão',
|
||||
'settings.background_image' => 'Imagem de fundo',
|
||||
'settings.window_target' => 'Link é aberto em',
|
||||
'settings.window_target.current' => 'Abra nesta aba',
|
||||
'settings.window_target.one' => 'Abra na mesma aba',
|
||||
'settings.window_target.new' => 'Abra em uma nova aba',
|
||||
'settings.homepage_search' => 'Pesquisa na página inicial',
|
||||
'settings.search_provider' => 'Provedor de pesquisa',
|
||||
'settings.language' => 'Idioma',
|
||||
'settings.reset' => 'Redefinir de volta ao padrão',
|
||||
'settings.remove' => 'Remover',
|
||||
'settings.search' => 'busca',
|
||||
'settings.no_items' => 'Nenhum item encontrado',
|
||||
|
||||
|
||||
'settings.label' => 'Rótulo',
|
||||
'settings.value' => 'Valor',
|
||||
'settings.edit' => 'Editar',
|
||||
'settings.view' => 'Ver',
|
||||
|
||||
'options.none' => '- não configurado -',
|
||||
'options.google' => 'Google',
|
||||
'options.ddg' => 'DuckDuckGo',
|
||||
'options.bing' => 'Bing',
|
||||
'options.startpage' => 'Página inicial',
|
||||
'options.yes' => 'Sim',
|
||||
'options.no' => 'Não',
|
||||
|
||||
'buttons.save' => 'Salvar',
|
||||
'buttons.cancel' => 'Cancelar',
|
||||
'buttons.add' => 'Adicionar',
|
||||
'buttons.upload' => 'Carregar um arquivo',
|
||||
|
||||
'dash.pin_item' => 'Fixar o item na dashboard',
|
||||
'dash.no_apps' => 'Atualmente não há aplicativos fixados, :link1 ou :link2',
|
||||
'dash.link1' => 'Adicionar um aplivativo aqui',
|
||||
'dash.link2' => 'Fixar um item na dashboard',
|
||||
'dash.pinned_items' => 'Itens fixados',
|
||||
|
||||
'apps.app_list' => 'Lista de aplicativos',
|
||||
'apps.view_trash' => 'Ver lixo',
|
||||
'apps.add_application' => 'Adicionar aplicativo',
|
||||
'apps.application_name' => 'Nome do aplicativo',
|
||||
'apps.colour' => 'Cor',
|
||||
'apps.icon' => 'Ícone',
|
||||
'apps.pinned' => 'Fixado',
|
||||
'apps.title' => 'Título',
|
||||
'apps.hex' => 'Cor hexadecimal',
|
||||
'apps.username' => 'Nome de usuário',
|
||||
'apps.password' => 'Senha',
|
||||
'apps.config' => 'Configuração',
|
||||
'apps.apikey' => 'API Key',
|
||||
'apps.enable' => 'Habilitar',
|
||||
'apps.tag_list' => 'Lista de tags',
|
||||
'apps.add_tag' => 'Adicionar tag',
|
||||
'apps.tag_name' => 'Nome da tag',
|
||||
'apps.tags' => 'Tags',
|
||||
'apps.override' => 'Se diferente do URL principal',
|
||||
|
||||
'user.user_list' => 'Comercial',
|
||||
'user.add_user' => 'Adicionar usuários',
|
||||
'user.username' => 'Nome de usuário',
|
||||
'user.avatar' => 'Avatar',
|
||||
'user.email' => 'O email',
|
||||
'user.password_confirm' => 'Confirme a Senha',
|
||||
'user.secure_front' => 'Permitir acesso público à frente - Aplicado apenas se uma senha for definida.',
|
||||
'user.autologin' => 'Permitir o login a partir de um URL específico. Qualquer pessoa com o link pode fazer o login.',
|
||||
|
||||
'url' => 'URL',
|
||||
'title' => 'Título',
|
||||
'delete' => 'Apagar',
|
||||
'optional' => 'Opcional',
|
||||
'restore' => 'Restaurar',
|
||||
|
||||
'alert.success.item_created' => 'Item criado com sucesso',
|
||||
'alert.success.item_updated' => 'Item atualizado com sucesso',
|
||||
'alert.success.item_deleted' => 'Item apagado com sucesso',
|
||||
'alert.success.item_restored' => 'Item restaurado com sucesso',
|
||||
|
||||
'alert.success.tag_created' => 'Tag criada com sucesso',
|
||||
'alert.success.tag_updated' => 'Tag atualizada com sucesso',
|
||||
'alert.success.tag_deleted' => 'Tag apagada com sucesso',
|
||||
'alert.success.tag_restored' => 'Tag restaurada com sucesso',
|
||||
|
||||
'alert.success.setting_updated' => 'Você editou com sucesso essa configuração',
|
||||
'alert.error.not_exist' => 'Essa configuração não existe.',
|
||||
|
||||
'alert.success.user_created' => 'Usuário criado com sucesso',
|
||||
'alert.success.user_updated' => 'Usuário atualizado com sucesso',
|
||||
'alert.success.user_deleted' => 'Usuário excluído com sucesso',
|
||||
'alert.success.user_restored' => 'Usuário restaurado com sucesso',
|
||||
|
||||
];
|
||||
@@ -12,9 +12,15 @@ return [
|
||||
'settings.system' => 'System',
|
||||
'settings.appearance' => 'Appearance',
|
||||
'settings.miscellaneous' => 'Miscellaneous',
|
||||
'settings.support' => 'Support',
|
||||
'settings.donate' => 'Donate',
|
||||
|
||||
'settings.version' => 'Version',
|
||||
'settings.background_image' => 'Background Image',
|
||||
'settings.window_target' => 'Link opens in',
|
||||
'settings.window_target.current' => 'Open in this tab',
|
||||
'settings.window_target.one' => 'Open in the same tab',
|
||||
'settings.window_target.new' => 'Open in a new tab',
|
||||
'settings.homepage_search' => 'Homepage Search',
|
||||
'settings.search_provider' => 'Search Provider',
|
||||
'settings.language' => 'Language',
|
||||
@@ -22,17 +28,18 @@ return [
|
||||
'settings.remove' => 'Remove',
|
||||
'settings.search' => 'search',
|
||||
'settings.no_items' => 'No items found',
|
||||
|
||||
|
||||
'settings.label' => 'Label',
|
||||
'settings.value' => 'Value',
|
||||
'settings.edit' => 'Edit',
|
||||
'settings.view' => 'View',
|
||||
|
||||
'settings.label' => 'Label',
|
||||
'settings.value' => 'Value',
|
||||
'settings.edit' => 'Edit',
|
||||
'settings.view' => 'View',
|
||||
|
||||
'options.none' => '- not set -',
|
||||
'options.google' => 'Google',
|
||||
'options.ddg' => 'DuckDuckGo',
|
||||
'options.bing' => 'Bing',
|
||||
'options.startpage' => 'StartPage',
|
||||
'options.yes' => 'Yes',
|
||||
'options.no' => 'No',
|
||||
|
||||
@@ -59,18 +66,28 @@ return [
|
||||
'apps.username' => 'Username',
|
||||
'apps.password' => 'Password',
|
||||
'apps.config' => 'Config',
|
||||
'apps.apikey' => 'Api Key',
|
||||
'apps.apikey' => 'API Key',
|
||||
'apps.enable' => 'Enable',
|
||||
'apps.tag_list' => 'Tags list',
|
||||
'apps.add_tag' => 'Add tag',
|
||||
'apps.tag_name' => 'Tag name',
|
||||
'apps.tags' => 'Tags',
|
||||
'apps.override' => 'If different to main url',
|
||||
|
||||
'url' => 'Url',
|
||||
'user.user_list' => 'Users',
|
||||
'user.add_user' => 'Add user',
|
||||
'user.username' => 'Username',
|
||||
'user.avatar' => 'Avatar',
|
||||
'user.email' => 'Email',
|
||||
'user.password_confirm' => 'Confirm Password',
|
||||
'user.secure_front' => 'Allow public access to front - Only enforced if a password is set.',
|
||||
'user.autologin' => 'Allow logging in from a specific URL. Anyone with the link can login.',
|
||||
|
||||
'url' => 'URL',
|
||||
'title' => 'Title',
|
||||
'delete' => 'Delete',
|
||||
'optional' => 'Optional',
|
||||
'restore' => 'Restore',
|
||||
'delete' => 'Delete',
|
||||
'optional' => 'Optional',
|
||||
'restore' => 'Restore',
|
||||
|
||||
'alert.success.item_created' => 'Item created successfully',
|
||||
'alert.success.item_updated' => 'Item updated successfully',
|
||||
@@ -82,8 +99,13 @@ return [
|
||||
'alert.success.tag_deleted' => 'Tag deleted successfully',
|
||||
'alert.success.tag_restored' => 'Tag restored successfully',
|
||||
|
||||
'alert.success.setting_updated' => 'You have successfully edited this Setting',
|
||||
'alert.error.not_exist' => 'This Setting does not exist.',
|
||||
'alert.success.setting_updated' => 'You have successfully edited this setting',
|
||||
'alert.error.not_exist' => 'This setting does not exist.',
|
||||
|
||||
'alert.success.user_created' => 'User created successfully',
|
||||
'alert.success.user_updated' => 'User updated successfully',
|
||||
'alert.success.user_deleted' => 'User deleted successfully',
|
||||
'alert.success.user_restored' => 'User restored successfully',
|
||||
|
||||
|
||||
];
|
||||
|
||||
@@ -4,55 +4,88 @@ return array (
|
||||
'settings.system' => 'Système',
|
||||
'settings.appearance' => 'Apparence',
|
||||
'settings.miscellaneous' => 'Divers',
|
||||
'settings.support' => 'Support',
|
||||
'settings.donate' => 'Contribuer',
|
||||
|
||||
'settings.version' => 'Version',
|
||||
'settings.background_image' => 'Image D\'Arrière-Plan',
|
||||
'settings.homepage_search' => 'La Page D\'Accueil De Recherche',
|
||||
'settings.search_provider' => 'Fournisseur de recherche',
|
||||
'settings.background_image' => 'Image d\'arrière-plan',
|
||||
'settings.window_target' => 'Ouverture des liens',
|
||||
'settings.window_target.current' => 'Dans l\'onglet courant',
|
||||
'settings.window_target.one' => 'Dans le même nouvel onglet',
|
||||
'settings.window_target.new' => 'Dans un nouvel onglet',
|
||||
'settings.homepage_search' => 'Barre de recherche',
|
||||
'settings.search_provider' => 'Moteur de recherche',
|
||||
'settings.language' => 'Langue',
|
||||
'settings.reset' => 'Réinitialiser aux valeurs par défaut',
|
||||
'settings.reset' => 'Réinitialiser les valeurs par défaut',
|
||||
'settings.remove' => 'Supprimer',
|
||||
'settings.search' => 'chercher',
|
||||
'settings.no_items' => 'Pas d\'articles trouvés',
|
||||
'settings.search' => 'Chercher',
|
||||
'settings.no_items' => 'Aucun élement trouvé',
|
||||
|
||||
'settings.label' => 'Étiquette',
|
||||
'settings.value' => 'Valeur',
|
||||
'settings.edit' => 'Modifier',
|
||||
'settings.view' => 'Vue',
|
||||
|
||||
'options.none' => '- non défini -',
|
||||
'options.google' => 'Google',
|
||||
'options.ddg' => 'DuckDuckGo',
|
||||
'options.bing' => 'Bing',
|
||||
'options.startpage' => 'Page d\'accueil',
|
||||
'options.yes' => 'Oui',
|
||||
'options.no' => 'Non',
|
||||
|
||||
'buttons.save' => 'Enregistrer',
|
||||
'buttons.cancel' => 'Annuler',
|
||||
'buttons.add' => 'Ajouter',
|
||||
'buttons.upload' => 'Télécharger un fichier',
|
||||
'dash.pin_item' => 'Épingler l\'élément au tableau de bord',
|
||||
'dash.no_apps' => 'Il n\'existe actuellement aucun épinglé applications :link1 ou :link2',
|
||||
'dash.link1' => 'Ajouter une application ici',
|
||||
'dash.link2' => 'Pin un élément au tableau de bord',
|
||||
'dash.pinned_items' => 'Éléments épinglés',
|
||||
'buttons.upload' => 'Choisir un fichier',
|
||||
|
||||
'dash.pin_item' => 'Épingler l\'application au tableau de bord',
|
||||
'dash.no_apps' => 'Il n\'existe actuellement aucune application épinglée :link1 ou :link2',
|
||||
'dash.link1' => 'Ajouter une application',
|
||||
'dash.link2' => 'Épingler une application au tableau de bord',
|
||||
'dash.pinned_items' => 'Applications épinglées',
|
||||
|
||||
'apps.app_list' => 'Liste des applications',
|
||||
'apps.view_trash' => 'Voir la corbeille',
|
||||
'apps.add_application' => 'Ajouter une application',
|
||||
'apps.application_name' => 'Nom de l\'application',
|
||||
'apps.colour' => 'Couleur',
|
||||
'apps.icon' => 'Icône',
|
||||
'apps.pinned' => 'Épinglé',
|
||||
'apps.pinned' => 'Épinglée',
|
||||
'apps.title' => 'Titre',
|
||||
'apps.hex' => 'Hexadécimal de la couleur',
|
||||
'apps.username' => 'Nom d\'utilisateur',
|
||||
'apps.password' => 'Mot de passe',
|
||||
'apps.config' => 'Config',
|
||||
'apps.enable' => 'Actif',
|
||||
'apps.tag_list' => 'Liste des labels',
|
||||
'apps.add_tag' => 'Ajouter un label',
|
||||
'apps.tag_name' => 'Nom du label',
|
||||
'apps.tags' => 'Labels',
|
||||
'apps.override' => 'Si différent de l\'url actuelle',
|
||||
|
||||
'url' => 'Url',
|
||||
'title' => 'Titre',
|
||||
'delete' => 'Effacer',
|
||||
'optional' => 'Optionnel',
|
||||
'restore' => 'Restaurer',
|
||||
'alert.success.item_created' => 'Élément créé avec succès',
|
||||
'alert.success.item_updated' => 'Article mis à jour avec succès',
|
||||
'alert.success.item_deleted' => 'Élément supprimé avec succès',
|
||||
'alert.success.item_restored' => 'Élément à restaurer avec succès',
|
||||
'alert.success.setting_updated' => 'Vous avez modifié ce paramètre avec succès',
|
||||
|
||||
'alert.success.item_created' => 'Application créée avec succès',
|
||||
'alert.success.item_updated' => 'Application mise à jour avec succès',
|
||||
'alert.success.item_deleted' => 'Application supprimée avec succès',
|
||||
'alert.success.item_restored' => 'Application restaurée avec succès',
|
||||
|
||||
'alert.success.tag_created' => 'Label crée avec succès',
|
||||
'alert.success.tag_updated' => 'Label mis à jour avec succès',
|
||||
'alert.success.tag_deleted' => 'Label supprimé avec succès',
|
||||
'alert.success.tag_restored' => 'Label restauré avec succès',
|
||||
|
||||
'alert.success.setting_updated' => 'Paramètre mis à jour avec succès',
|
||||
'alert.error.not_exist' => 'Ce paramètre n\'existe pas.',
|
||||
);
|
||||
|
||||
'alert.success.user_created' => 'Utilisateur crée avec succès',
|
||||
'alert.success.user_updated' => 'Utilisateur mis à jour avec succès',
|
||||
'alert.success.user_deleted' => 'Utilisateur supprimé avec succès',
|
||||
'alert.success.user_restored' => 'Utilisateur restoré avec succès',
|
||||
|
||||
);
|
||||
|
||||
104
resources/lang/nl/app.php
Normal file
104
resources/lang/nl/app.php
Normal file
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| App Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
'settings.system' => 'Systeem',
|
||||
'settings.appearance' => 'Uiterlijk',
|
||||
'settings.miscellaneous' => 'Overige',
|
||||
|
||||
'settings.version' => 'Versie',
|
||||
'settings.background_image' => 'Achtergrondafbeelding',
|
||||
'settings.homepage_search' => 'Zoeken op thuispagina',
|
||||
'settings.search_provider' => 'Zoekaanbieder',
|
||||
'settings.language' => 'Taal',
|
||||
'settings.reset' => 'Standaard instellingen herstellen',
|
||||
'settings.remove' => 'Verwijderen',
|
||||
'settings.search' => 'zoeken',
|
||||
'settings.no_items' => 'Geen items gevonden',
|
||||
|
||||
|
||||
'settings.label' => 'Label',
|
||||
'settings.value' => 'Waarde',
|
||||
'settings.edit' => 'Bewerken',
|
||||
'settings.view' => 'Weergeven',
|
||||
|
||||
'options.none' => '- niet ingesteld -',
|
||||
'options.google' => 'Google',
|
||||
'options.ddg' => 'DuckDuckGo',
|
||||
'options.bing' => 'Bing',
|
||||
'options.yes' => 'Ja',
|
||||
'options.no' => 'Nee',
|
||||
|
||||
'buttons.save' => 'Opslaan',
|
||||
'buttons.cancel' => 'Annuleren',
|
||||
'buttons.add' => 'Toevoegen',
|
||||
'buttons.upload' => 'Een bestand uploaden',
|
||||
|
||||
'dash.pin_item' => 'Item aan dashboard vastpinnen',
|
||||
'dash.no_apps' => 'Er zijn momenteel geen vastgepinde toepassingen, :link1 of :link2',
|
||||
'dash.link1' => 'Voeg hier een toepassing toe',
|
||||
'dash.link2' => 'Een item aan het dashboard vastpinnen',
|
||||
'dash.pinned_items' => 'Vastgepinde Items',
|
||||
|
||||
'apps.app_list' => 'Applicatielijst',
|
||||
'apps.view_trash' => 'Prullenbak weergeven',
|
||||
'apps.add_application' => 'Applicatie toevoegen',
|
||||
'apps.application_name' => 'Applicatienaam',
|
||||
'apps.colour' => 'Kleur',
|
||||
'apps.icon' => 'Pictogram',
|
||||
'apps.pinned' => 'Vastgepind',
|
||||
'apps.title' => 'Titel',
|
||||
'apps.hex' => 'Hex-kleur',
|
||||
'apps.username' => 'Gebruikersnaam',
|
||||
'apps.password' => 'Wachtwoord',
|
||||
'apps.config' => 'Configuratie',
|
||||
'apps.apikey' => 'API-sleutel',
|
||||
'apps.enable' => 'Inschakalen',
|
||||
'apps.tag_list' => 'Tags-lijst',
|
||||
'apps.add_tag' => 'Tag toevoegen',
|
||||
'apps.tag_name' => 'Tag naam',
|
||||
'apps.tags' => 'Tags',
|
||||
'apps.override' => 'Indien anders dan hoofd-url',
|
||||
|
||||
'user.user_list' => 'Gebruikers',
|
||||
'user.add_user' => 'Gebruiker toevoegen',
|
||||
'user.username' => 'Gebruikersnaam',
|
||||
'user.avatar' => 'Avatar',
|
||||
'user.email' => 'Email',
|
||||
'user.password_confirm' => 'Bevestig wachtwoord',
|
||||
'user.secure_front' => 'Sta publieke toegang toe tot voorkant - Alleen geforceerd indien een wachtwoord is ingesteld.',
|
||||
'user.autologin' => 'Sta inloggen vanaf een specifieke URL toe. Iedereen met de link kan inloggen.',
|
||||
|
||||
'url' => 'URL',
|
||||
'title' => 'Titel',
|
||||
'delete' => 'Verwijderen',
|
||||
'optional' => 'Optioneel',
|
||||
'restore' => 'Herstellen',
|
||||
|
||||
'alert.success.item_created' => 'Item met succes aangemaakt',
|
||||
'alert.success.item_updated' => 'Item met succes bewerkt',
|
||||
'alert.success.item_deleted' => 'Item met succes verwijderd',
|
||||
'alert.success.item_restored' => 'Item met succes hersteld',
|
||||
|
||||
'alert.success.tag_created' => 'Tag met succes aangemaakt',
|
||||
'alert.success.tag_updated' => 'Tag met succes bewerkt',
|
||||
'alert.success.tag_deleted' => 'Tag met succes verwijderd',
|
||||
'alert.success.tag_restored' => 'Tag met succes hersteld',
|
||||
|
||||
'alert.success.setting_updated' => 'Deze instelling is met succes gewijzigd',
|
||||
'alert.error.not_exist' => 'Deze instelling bestaat niet.',
|
||||
|
||||
'alert.success.user_created' => 'Gebruiker met succes aangemaakt',
|
||||
'alert.success.user_updated' => 'Gebruiker met succes bewerkt',
|
||||
'alert.success.user_deleted' => 'Gebruiker met succes verwijderd',
|
||||
'alert.success.user_restored' => 'Gebruiker met succes hersteld',
|
||||
|
||||
|
||||
];
|
||||
19
resources/lang/nl/auth.php
Normal file
19
resources/lang/nl/auth.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'De door u opgegeven referenties komen niet overeen met onze gegevens.',
|
||||
'throttle' => 'Te veel aanmeldpogingen. Probeer het over :seconds seconden opnieuw.',
|
||||
|
||||
];
|
||||
19
resources/lang/nl/pagination.php
Normal file
19
resources/lang/nl/pagination.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Vorige',
|
||||
'next' => 'Volgende »',
|
||||
|
||||
];
|
||||
22
resources/lang/nl/passwords.php
Normal file
22
resources/lang/nl/passwords.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'Wachtwoorden moeten tenminste zes karakters bevatten en overeenkomen met de bevestiging.',
|
||||
'reset' => 'Uw wachtwoord is opnieuw ingesteld!',
|
||||
'sent' => 'De link voor het opnieuw instellen van uw wachtwoord is naar u gemaild!',
|
||||
'token' => 'Deze token voor het opnieuw instellen van een wachtwoord is ongeldig.',
|
||||
'user' => "Er bestaat geen gebruiker met het opgegeven e-mailadres.",
|
||||
|
||||
];
|
||||
121
resources/lang/nl/validation.php
Normal file
121
resources/lang/nl/validation.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => ':attribute moet geaccepteerd worden.',
|
||||
'active_url' => ':attribute is geen geldige URL.',
|
||||
'after' => ':attribute moet een datum na :date zijn.',
|
||||
'after_or_equal' => ':attribute moet een datum op of na :date zijn.',
|
||||
'alpha' => ':attribute mag alleen letters bevatten.',
|
||||
'alpha_dash' => ':attribute mag alleen letters, cijfers en streepjes bevatten.',
|
||||
'alpha_num' => ':attribute mag alleen letters en cijfers bevatten.',
|
||||
'array' => ':attribute moet een array zijn.',
|
||||
'before' => ':attribute moet een datum voor :date zijn.',
|
||||
'before_or_equal' => ':attribute moet een datum op of voor :date zijn.',
|
||||
'between' => [
|
||||
'numeric' => ':attribute moet tussen :min en :max liggen.',
|
||||
'file' => ':attribute moet tussen :min en :max kilobyte in omvang zijn.',
|
||||
'string' => ':attribute moet tussen :min en :max karakters bevatten.',
|
||||
'array' => ':attribute moet tussen :min en :max items bevatten.',
|
||||
],
|
||||
'boolean' => 'Het veld :attribute moet waar of onwaar zijn.',
|
||||
'confirmed' => 'De bevestiging voor :attribute komt niet overeen.',
|
||||
'date' => ':attribute is geen geldige datum.',
|
||||
'date_format' => ':attribute komt niet overeen met het formaat :format.',
|
||||
'different' => ':attribute en :other moeten verschillen.',
|
||||
'digits' => ':attribute moet :digits getallen bevatten.',
|
||||
'digits_between' => ':attribute moet tussen :min en :max getallen bevatten.',
|
||||
'dimensions' => ':attribute heeft ongeldige afbeeldingsafmetingen.',
|
||||
'distinct' => 'Het veld :attribute heeft een dubbele waarde.',
|
||||
'email' => ':attribute moet een geldig e-mailadres zijn.',
|
||||
'exists' => 'Geselecteerde :attribute is ongeldig.',
|
||||
'file' => ':attribute moet een bestand zijn.',
|
||||
'filled' => 'Het veld :attribute moet een waarde bevatten.',
|
||||
'image' => ':attribute moet een afbeelding zijn.',
|
||||
'in' => 'Geselecteerde :attribute is ongeldig.',
|
||||
'in_array' => 'Het veld :attribute bestaat niet in :other.',
|
||||
'integer' => ':attribute moet een geheel getal zijn.',
|
||||
'ip' => ':attribute moet een geldig IP-adres zijn.',
|
||||
'ipv4' => ':attribute moet een geldig IPv4-adres zijn.',
|
||||
'ipv6' => ':attribute moet een geldig IPv6-adres zijn.',
|
||||
'json' => ':attribute moet een geldige JSON-reeks zijn.',
|
||||
'max' => [
|
||||
'numeric' => ':attribute mag niet groter dan :max zijn.',
|
||||
'file' => ':attribute mag niet groter dan :max kilobyte in omvang zijn.',
|
||||
'string' => ':attribute mag niet meer dan :max karakters bevatten.',
|
||||
'array' => ':attribute mag niet meer dan :max items bevatten.',
|
||||
],
|
||||
'mimes' => ':attribute moet een bestand zijn van type: :values.',
|
||||
'mimetypes' => ':attribute moet een bestand zijn van type: :values.',
|
||||
'min' => [
|
||||
'numeric' => ':attribute moet tenminste :min zijn.',
|
||||
'file' => ':attribute moet tenminste :min kilobyte in omvang zijn.',
|
||||
'string' => ':attribute moet tenminste :min karakters bevatten.',
|
||||
'array' => ':attribute moet tenminste :min items bevatten.',
|
||||
],
|
||||
'not_in' => 'Geselecteerde :attribute is ongeldig.',
|
||||
'numeric' => ':attribute moet een getal zijn.',
|
||||
'present' => 'Het veld :attribute moet aanwezig zijn.',
|
||||
'regex' => 'Het formaat van :attribute is ongeldig.',
|
||||
'required' => 'Het veld :attribute is vereist.',
|
||||
'required_if' => 'Het veld :attribute is vereist wanneer :other :value is.',
|
||||
'required_unless' => 'Het veld :attribute is vereist tenzij :other in :values aanwezig is.',
|
||||
'required_with' => 'Het veld :attribute is vereist wanneer :values aanwezig is.',
|
||||
'required_with_all' => 'Het veld :attribute is vereist wanneer :values aanwezig is.',
|
||||
'required_without' => 'Het veld :attribute is vereist wanneer :values niet aanwezig is.',
|
||||
'required_without_all' => 'Het veld :attribute is vereist wanneer geen van :values aanwezig zijn.',
|
||||
'same' => ':attribute en :other moeten overeenkomen.',
|
||||
'size' => [
|
||||
'numeric' => ':attribute moet :size zijn.',
|
||||
'file' => ':attribute moet :size kilobyte in omvang zijn.',
|
||||
'string' => ':attribute moet :size karakters bevatten.',
|
||||
'array' => ':attribute moet :size items bevatten.',
|
||||
],
|
||||
'string' => ':attribute moet een reekswaarde zijn.',
|
||||
'timezone' => ':attribute moet een geldige zone bevatten.',
|
||||
'unique' => ':attribute is reeds in gebruik.',
|
||||
'uploaded' => 'Het uploaden van :attribute is niet gelukt.',
|
||||
'url' => 'Het formaat van :attribute is ongeldig.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
||||
80
resources/lang/pl/app.php
Normal file
80
resources/lang/pl/app.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| App Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
*/
|
||||
|
||||
'settings.system' => 'System',
|
||||
'settings.appearance' => 'Wygląd',
|
||||
'settings.miscellaneous' => 'Różne',
|
||||
|
||||
'settings.version' => 'Wersja',
|
||||
'settings.background_image' => 'Tapeta Pulpitu',
|
||||
'settings.homepage_search' => 'Strona Domowa Wyszukiwanie',
|
||||
'settings.search_provider' => 'Operator Wyszukiwania',
|
||||
'settings.language' => 'Język',
|
||||
'settings.reset' => 'Przywróć ustawienia domyślne',
|
||||
'settings.remove' => 'Usuń',
|
||||
'settings.search' => 'szukaj',
|
||||
'settings.no_items' => 'Nic nie znaleziono',
|
||||
|
||||
|
||||
'settings.label' => 'Etykieta',
|
||||
'settings.value' => 'Wartość',
|
||||
'settings.edit' => 'Edytuj',
|
||||
'settings.view' => 'Widok',
|
||||
|
||||
'options.none' => '- not set -',
|
||||
'options.google' => 'Google',
|
||||
'options.ddg' => 'DuckDuckGo',
|
||||
'options.bing' => 'Bing',
|
||||
'options.yes' => 'Tak',
|
||||
'options.no' => 'Nie',
|
||||
|
||||
'buttons.save' => 'Zapisz',
|
||||
'buttons.cancel' => 'Anuluj',
|
||||
'buttons.add' => 'Dodaj',
|
||||
'buttons.upload' => 'Prześlij plik',
|
||||
|
||||
'dash.pin_item' => 'Przypnij element do pulpitu',
|
||||
'dash.no_apps' => 'Obecnie nie ma przypiętych aplikacji, :link1 or :link2',
|
||||
'dash.link1' => 'Dodaj aplikację tutaj',
|
||||
'dash.link2' => 'Przypnij element do pulpitu',
|
||||
'dash.pinned_items' => 'Przypięte elementy',
|
||||
|
||||
'apps.app_list' => 'Lista aplikacji',
|
||||
'apps.view_trash' => 'Widok kosza',
|
||||
'apps.add_application' => 'Dodaj Aplikacje',
|
||||
'apps.application_name' => 'Nazwa Aplikacji',
|
||||
'apps.colour' => 'Kolor',
|
||||
'apps.icon' => 'Ikona',
|
||||
'apps.pinned' => 'Przypięty',
|
||||
'apps.title' => 'Tytuł',
|
||||
'apps.hex' => 'Kolor HEX',
|
||||
'apps.username' => 'Nazwa Użytkownika',
|
||||
'apps.password' => 'Hasło',
|
||||
'apps.config' => 'Ustawienia',
|
||||
'apps.apikey' => 'Klucz API',
|
||||
'apps.enable' => 'Włącz',
|
||||
|
||||
'url' => 'URL',
|
||||
'title' => 'Tytuł',
|
||||
'delete' => 'Usuń',
|
||||
'optional' => 'Opcjonalny',
|
||||
'restore' => 'Przywróć',
|
||||
|
||||
'alert.success.item_created' => 'Element utworzony',
|
||||
'alert.success.item_updated' => 'Element zaktualizowany',
|
||||
'alert.success.item_deleted' => 'Element usunięty',
|
||||
'alert.success.item_restored' => 'Przywrócono element',
|
||||
|
||||
'alert.success.setting_updated' => 'Ustawienie zostało zaktualizowane',
|
||||
'alert.error.not_exist' => 'Takie ustawienie nie istnieje',
|
||||
|
||||
|
||||
];
|
||||
19
resources/lang/pl/auth.php
Normal file
19
resources/lang/pl/auth.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'Nieprawidłowe dane uwierzytelnienia',
|
||||
'throttle' => 'Zbyt wiele prób logowania. Spróbuj ponownie za :seconds sekund.',
|
||||
|
||||
];
|
||||
19
resources/lang/pl/pagination.php
Normal file
19
resources/lang/pl/pagination.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Poprzedni',
|
||||
'next' => 'Następny »',
|
||||
|
||||
];
|
||||
22
resources/lang/pl/passwords.php
Normal file
22
resources/lang/pl/passwords.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'Hasła muszą mieć co najmniej sześć znaków i być zgodne z potwierdzeniem.',
|
||||
'reset' => 'Twoje hasło zostało zresetowane!',
|
||||
'sent' => 'Wysłaliśmy e-mailem link do resetowania hasła!',
|
||||
'token' => 'Ten token resetowania hasła jest nieprawidłowy',
|
||||
'user' => 'Nie możemy znaleźć użytkownika z tym adresem e-mail',
|
||||
|
||||
];
|
||||
121
resources/lang/pl/validation.php
Normal file
121
resources/lang/pl/validation.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => ':attribute musi zostać zaakceptowany.',
|
||||
'active_url' => ':attribute nie jest prawidłowym adresem URL.',
|
||||
'after' => ':attribute musi być datą następną po :date.',
|
||||
'after_or_equal' => ':attribute musi być datą następną lub równą dacie :date.',
|
||||
'alpha' => ':attribute może zawierać tylko litery.',
|
||||
'alpha_dash' => ':attribute mogą zawierać tylko litery, cyfry i myślniki.',
|
||||
'alpha_num' => ':attribute może zawierać tylko litery i cyfry.',
|
||||
'array' => ':attribute musi być tablicą.',
|
||||
'before' => ':attribute musi być datą wcześniejszą od daty :date.',
|
||||
'before_or_equal' => ':attribute musi być datą wcześniejszą lub równą dacie :date.',
|
||||
'between' => [
|
||||
'numeric' => 'Numer :attribute musi byc większy niż :min oraz mniejszy niż :max.',
|
||||
'file' => 'Rozmiar pliku :attribute musi byc większy niż :min oraz mniejszy niż :max kilobajtów.',
|
||||
'string' => 'Tekst :attribute musi posiadać więcej niż :min oraz mniej niż :max znaków.',
|
||||
'array' => 'Tablica :attribute musi zawierać więcej niż :min oraz mniej niż :max elementów.',
|
||||
],
|
||||
'boolean' => ':attribute musi zwracac wartość logiczną TRUE lub FALSE.',
|
||||
'confirmed' => ':attribute nie jest zgodny z polem potwierdzenia.',
|
||||
'date' => ':attribute nieprawidłowy format daty.',
|
||||
'date_format' => 'Format daty :attribute musi byc zgodny z formatem :format.',
|
||||
'different' => 'Wartości :attribute oraz :other muszą być różne.',
|
||||
'digits' => 'Wartość :attribute musi być liczbą o długość :digits znaków.',
|
||||
'digits_between' => 'Wartość :attribute musi być liczbą o długość co najmniej :min oraz nie więcej niz :max digits.',
|
||||
'dimensions' => ':attribute ma nieprawidłowe wymiary obrazu.',
|
||||
'distinct' => 'Pole :attribute ma zduplikowaną wartość.',
|
||||
'email' => ':attribute musi być prawidłowym adresem e-mail.',
|
||||
'exists' => 'Wybrnay :attribute nie istnieje.',
|
||||
'file' => ':attribute musi być plikiem.',
|
||||
'filled' => 'Pole :attribute nie może być puste.',
|
||||
'image' => ':attribute musi być obrazem.',
|
||||
'in' => 'Wybrany :attribute jest nieprawidłowy.',
|
||||
'in_array' => 'Pole :attribute nie istnieje w :other.',
|
||||
'integer' => ':attribute musi być liczbą całkowitą.',
|
||||
'ip' => ':attribute musi być prawidłowym adresem IP.',
|
||||
'ipv4' => ':attribute musi być prawidłowym adresem IPv4.',
|
||||
'ipv6' => ':attribute musi być prawidłowym adresem IPv6.',
|
||||
'json' => ':attribute musi być poprawnym łańcuchem JSON.',
|
||||
'max' => [
|
||||
'numeric' => ':attribute nie może być większa niż :max.',
|
||||
'file' => 'Rozmiar :attribute nie może być większy niż :max kilobajtów.',
|
||||
'string' => ':attribute nie może zawierać więcej niż :max znaków.',
|
||||
'array' => ':attribute nie może zawierać więcej niż :max elementów.',
|
||||
],
|
||||
'mimes' => ':attribute musi być plikiem typu: :values.',
|
||||
'mimetypes' => ':attribute musi być plikiem typu: :values.',
|
||||
'min' => [
|
||||
'numeric' => ':attribute musi wynosić conajmniej :min.',
|
||||
'file' => 'Rozmiar :attribute musi być rowny lub większy niż :min kilobajtów.',
|
||||
'string' => ':attribute musi zawierać conajmniej :min znaków.',
|
||||
'array' => ':attribute musi zawierać conajmniej :min elementów.',
|
||||
],
|
||||
'not_in' => ':attribute jest nieprawidłowy.',
|
||||
'numeric' => ':attribute musi być liczbą.',
|
||||
'present' => 'Obecność pola :attribute jest obowiązkowa.',
|
||||
'regex' => 'Format :attribute jest nieprawidłowy.',
|
||||
'required' => ':attribute jest wymagany.',
|
||||
'required_if' => 'Pole :attribute jest wymagane gdy :other wynosi :value.',
|
||||
'required_unless' => 'Pole :attribute jest wymagane, chyba że :other jest zawarte w :values.',
|
||||
'required_with' => 'Pole :attribute jest wymagane gdy pole :values jest obecne.',
|
||||
'required_with_all' => 'Pole :attribute jest wymagane gdy :values jest obecne.',
|
||||
'required_without' => 'Pole :attribute jest wymagane gdy pole :values NIE jest obecne.',
|
||||
'required_without_all' => 'Pole :attribute jest wymagane gdy żadne z pól :values NIE jest obecne.',
|
||||
'same' => 'Pole :attribute oraz :other muszą być takie same.',
|
||||
'size' => [
|
||||
'numeric' => ':attribute musi wynosić dokladnie :size.',
|
||||
'file' => 'Rozmiar :attribute musi być równy :size kilobajtów.',
|
||||
'string' => ':attribute musi składać się dokładnie z :size znaków.',
|
||||
'array' => ':attribute musi składać się dokładnie z :size elementów.',
|
||||
],
|
||||
'string' => ':attribute musi być łańcuchem znaków.',
|
||||
'timezone' => ':attribute musi być prawidłową strefą czasową.',
|
||||
'unique' => ':attribute jest już zajety.',
|
||||
'uploaded' => 'Nie udało się przesłać :attribute.',
|
||||
'url' => ':attribute ma nieprawidłowy format.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'dowlona-wiadomosc',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user