mirror of
https://github.com/linuxserver/Heimdall.git
synced 2026-02-24 21:50:32 +09:00
Compare commits
257 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b07efaa7d0 | ||
|
|
7ba8ea6dd4 | ||
|
|
479461821f | ||
|
|
d25aea38fb | ||
|
|
0067502b37 | ||
|
|
d321af6085 | ||
|
|
b30f1730e4 | ||
|
|
7a02986982 | ||
|
|
a4107cba25 | ||
|
|
ba187aa345 | ||
|
|
b400cef734 | ||
|
|
03b72b8d2e | ||
|
|
0c7e20dee0 | ||
|
|
aa42c71a06 | ||
|
|
041c0b81a3 | ||
|
|
fe6776ee9d | ||
|
|
125b9f4160 | ||
|
|
488fee7b4b | ||
|
|
4fba596909 | ||
|
|
af04781830 | ||
|
|
2507cda94c | ||
|
|
21c1401859 | ||
|
|
4351f55225 | ||
|
|
d1956c4e88 | ||
|
|
d76d056ed1 | ||
|
|
e081cc31a2 | ||
|
|
88153b0e32 | ||
|
|
2b2d51cb6f | ||
|
|
abd8c7227d | ||
|
|
50d6dc7b71 | ||
|
|
b4a1ecc305 | ||
|
|
540bead0db | ||
|
|
6e9f25d680 | ||
|
|
268afe7006 | ||
|
|
7b9d3f0ec6 | ||
|
|
de116030bc | ||
|
|
4fb59385b7 | ||
|
|
40d6808067 | ||
|
|
3572bd8068 | ||
|
|
380a0e8623 | ||
|
|
4f6a0cb7c6 | ||
|
|
56cce8233b | ||
|
|
af8afcf931 | ||
|
|
7f997d60cd | ||
|
|
d45f5a805e | ||
|
|
fc9c624509 | ||
|
|
33372509eb | ||
|
|
bca0b02925 | ||
|
|
24995135e6 | ||
|
|
c1e4103edd | ||
|
|
6eda423156 | ||
|
|
7dc72d3519 | ||
|
|
907c22179b | ||
|
|
cdafbab7b1 | ||
|
|
e0064504e7 | ||
|
|
b22117dd01 | ||
|
|
c88efa8dbc | ||
|
|
7d060ff803 | ||
|
|
d5f8b6aae0 | ||
|
|
2416993c5e | ||
|
|
494165a03a | ||
|
|
88e607533c | ||
|
|
035d2f9209 | ||
|
|
53903daa87 | ||
|
|
567994be1a | ||
|
|
32fa27337a | ||
|
|
e1bb7646ac | ||
|
|
108b636def | ||
|
|
4abb14bf54 | ||
|
|
f8f96593c1 | ||
|
|
cb21b0f8f1 | ||
|
|
4c8c5fa27f | ||
|
|
6093119dde | ||
|
|
15755a3fd1 | ||
|
|
0213c81e0d | ||
|
|
c47f296f17 | ||
|
|
75133474f7 | ||
|
|
ddbe171f3a | ||
|
|
12e109f82c | ||
|
|
e095589172 | ||
|
|
d0293c785b | ||
|
|
aa351e31bf | ||
|
|
aceed3d13b | ||
|
|
10b70d4a09 | ||
|
|
cb9e014cf3 | ||
|
|
99017d834e | ||
|
|
fb73f5ca24 | ||
|
|
4369f1aeda | ||
|
|
6501aacb1b | ||
|
|
c3da17befc | ||
|
|
46bb073001 | ||
|
|
e8b47776ce | ||
|
|
6941fd3e2d | ||
|
|
f5937879df | ||
|
|
93877b7025 | ||
|
|
6612631cc3 | ||
|
|
30c3079a90 | ||
|
|
e86e681c53 | ||
|
|
48f72652da | ||
|
|
a3f7bafedb | ||
|
|
d30d610042 | ||
|
|
882e406266 | ||
|
|
45d421256c | ||
|
|
a2f20fc18f | ||
|
|
988364cb7c | ||
|
|
a3816ed8a1 | ||
|
|
d48805ee2c | ||
|
|
e820b81259 | ||
|
|
8b1046ce17 | ||
|
|
a138b65842 | ||
|
|
c344de3f04 | ||
|
|
427659a897 | ||
|
|
a6543970e7 | ||
|
|
399ea088dc | ||
|
|
3f87833e52 | ||
|
|
6dcb77023c | ||
|
|
4d37135bdf | ||
|
|
d109047fa5 | ||
|
|
b6112501e2 | ||
|
|
0663e236b4 | ||
|
|
f25cea1749 | ||
|
|
03e16415aa | ||
|
|
9a55e05943 | ||
|
|
c06fa4eab6 | ||
|
|
5575b082ea | ||
|
|
1c6da858bc | ||
|
|
f0a14641c1 | ||
|
|
c6d07cd8a4 | ||
|
|
df9f07faf4 | ||
|
|
a3dcc278d7 | ||
|
|
5de473fa44 | ||
|
|
763c1545a6 | ||
|
|
ecde7a0f32 | ||
|
|
7fc5e0abb5 | ||
|
|
06a655ac0c | ||
|
|
875ddaa834 | ||
|
|
030fccbb50 | ||
|
|
908f70d90a | ||
|
|
8724ced531 | ||
|
|
aa1a3a95ca | ||
|
|
0767dc075e | ||
|
|
c8a6c89036 | ||
|
|
cafe386cc4 | ||
|
|
0184c9695b | ||
|
|
19536edf28 | ||
|
|
045e4a20fa | ||
|
|
6cb8487a52 | ||
|
|
c39e9aa13f | ||
|
|
0203440b06 | ||
|
|
7f7bf60456 | ||
|
|
e8673634bc | ||
|
|
53e52c93ee | ||
|
|
c239c0ea5a | ||
|
|
7142f755f5 | ||
|
|
9fbc8dc1f9 | ||
|
|
d3819a6a88 | ||
|
|
6e93ed8e5f | ||
|
|
98543d49a9 | ||
|
|
9195eead27 | ||
|
|
e5b384736d | ||
|
|
4def720d1a | ||
|
|
2a0404ea17 | ||
|
|
6d22c4f02e | ||
|
|
24ac12da65 | ||
|
|
3f19882df8 | ||
|
|
dd54c16c1f | ||
|
|
223e9289dc | ||
|
|
2e301bdd51 | ||
|
|
e3ec7de23a | ||
|
|
18ec208381 | ||
|
|
8666daa07d | ||
|
|
926a9bdb03 | ||
|
|
fc2d837a2c | ||
|
|
3f69ccab99 | ||
|
|
b6ee82ee52 | ||
|
|
da1eb859a9 | ||
|
|
2b5269b823 | ||
|
|
6c8eeb0ced | ||
|
|
c5e0f3abc8 | ||
|
|
c6dbe22c57 | ||
|
|
51776e2aa3 | ||
|
|
c9d24607f6 | ||
|
|
46f7a3d4f3 | ||
|
|
56cf450c89 | ||
|
|
38c350b020 | ||
|
|
1f46040f1b | ||
|
|
63b95319cd | ||
|
|
a25d92be9e | ||
|
|
a161210a4a | ||
|
|
24469eb2fa | ||
|
|
a93fb49875 | ||
|
|
08d7cdf95b | ||
|
|
a9334bc247 | ||
|
|
2357d0c466 | ||
|
|
b003d51276 | ||
|
|
503cbf9830 | ||
|
|
2466058c5a | ||
|
|
6b1f422456 | ||
|
|
1d16d67733 | ||
|
|
6f9d15aed8 | ||
|
|
8725f974da | ||
|
|
2551c949ae | ||
|
|
30c6020ce7 | ||
|
|
d00b1ce1a1 | ||
|
|
2c43d79585 | ||
|
|
3e4aacb2b0 | ||
|
|
67cd22371b | ||
|
|
586941ece7 | ||
|
|
32a57cbfa6 | ||
|
|
1837a69b3e | ||
|
|
aa8bfcfd92 | ||
|
|
9e0c658470 | ||
|
|
66aefff4f3 | ||
|
|
bd0fdeecee | ||
|
|
1055eeb01b | ||
|
|
263a4578d4 | ||
|
|
c446b8a5af | ||
|
|
847b34cdcb | ||
|
|
5a57f90b8f | ||
|
|
f8eb9f5bd0 | ||
|
|
c8c336b574 | ||
|
|
43f1410974 | ||
|
|
1df110b3fb | ||
|
|
9bedce0df5 | ||
|
|
ae1d879e5a | ||
|
|
caab2e0952 | ||
|
|
a29d6517d3 | ||
|
|
dae2781818 | ||
|
|
c1de609b1a | ||
|
|
4e84807950 | ||
|
|
41c9cb45d6 | ||
|
|
2d72772f86 | ||
|
|
1cf1f0e04d | ||
|
|
324b88ec2b | ||
|
|
ec64c7ba0b | ||
|
|
67e0f8570e | ||
|
|
1745100705 | ||
|
|
28501944c5 | ||
|
|
c5c1a68f5c | ||
|
|
e2ed7fbd28 | ||
|
|
ab0675055c | ||
|
|
2b65559f36 | ||
|
|
b8beb07df5 | ||
|
|
01748fec49 | ||
|
|
42a50b1a02 | ||
|
|
d81595f43f | ||
|
|
71fa2d867f | ||
|
|
f55dbb0002 | ||
|
|
3e4d623786 | ||
|
|
1b109aac3a | ||
|
|
8558975d55 | ||
|
|
0e895089c7 | ||
|
|
5dd44f66c1 | ||
|
|
a1cfea46c6 | ||
|
|
42c492c85a | ||
|
|
9e8794a39f | ||
|
|
66c3604b2a |
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/*
|
||||
|
||||
55
app/Application.php
Normal file
55
app/Application.php
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Application extends Model
|
||||
{
|
||||
public $incrementing = false;
|
||||
|
||||
protected $primaryKey = 'appid';
|
||||
|
||||
//
|
||||
public function icon()
|
||||
{
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
public function iconView()
|
||||
{
|
||||
return asset('storage/'.$this->icon);
|
||||
}
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
// check if light or dark
|
||||
if($this->tile_background == 'light') return '#fafbfc';
|
||||
return '#161b1f';
|
||||
}
|
||||
|
||||
public function class()
|
||||
{
|
||||
$name = $this->name;
|
||||
$name = preg_replace('/\PL/u', '', $name);
|
||||
|
||||
$class = '\App\SupportedApps\\'.$name.'\\'.$name;
|
||||
return $class;
|
||||
}
|
||||
|
||||
public static function applist()
|
||||
{
|
||||
$list = [];
|
||||
$all = self::orderBy('name')->get();
|
||||
$list['null'] = 'None';
|
||||
foreach($all as $app) {
|
||||
$name = $app->name;
|
||||
$name = preg_replace('/\PL/u', '', $name);
|
||||
|
||||
$list['\App\SupportedApps\\'.$name.'\\'.$name] = $app->name;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
61
app/Console/Commands/RegisterApp.php
Normal file
61
app/Console/Commands/RegisterApp.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Application;
|
||||
use App\SupportedApps;
|
||||
|
||||
class RegisterApp extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'register:app {folder}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Add a local app to the registry';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$folder = $this->argument('folder');
|
||||
$json = app_path('SupportedApps/'.$folder.'/app.json');
|
||||
if(file_exists($json)) {
|
||||
$app = json_decode(file_get_contents($json));
|
||||
$exists = Application::find($app->appid);
|
||||
if($exists) {
|
||||
$this->error('This app is already registered');
|
||||
exit;
|
||||
}
|
||||
// Doesn't exist so add it
|
||||
SupportedApps::saveApp($app, new Application);
|
||||
$this->info("Application Added - ".$app->name." - ".$app->appid);
|
||||
|
||||
} else {
|
||||
$this->error('Could not find '.$json);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
12
app/EnhancedApps.php
Normal file
12
app/EnhancedApps.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php namespace App;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
interface EnhancedApps
|
||||
{
|
||||
public function test();
|
||||
public function livestats();
|
||||
public function url($endpoint);
|
||||
|
||||
}
|
||||
@@ -10,3 +10,35 @@ function format_bytes($bytes, $is_drive_size = true, $beforeunit = '', $afteruni
|
||||
elseif($labels[$x] == "MB") return(round($bytes, 2).$beforeunit.$labels[$x].$afterunit);
|
||||
else return(round($bytes, 0).$beforeunit.$labels[$x].$afterunit);
|
||||
}
|
||||
|
||||
function get_brightness($hex) {
|
||||
// returns brightness value from 0 to 255
|
||||
// strip off any leading #
|
||||
$hex = str_replace('#', '', $hex);
|
||||
if(strlen($hex) == 3) {
|
||||
$hex = $hex[0].$hex[0].$hex[1].$hex[1].$hex[2].$hex[2];
|
||||
}
|
||||
|
||||
$c_r = hexdec(substr($hex, 0, 2));
|
||||
$c_g = hexdec(substr($hex, 2, 2));
|
||||
$c_b = hexdec(substr($hex, 4, 2));
|
||||
|
||||
return (($c_r * 299) + ($c_g * 587) + ($c_b * 114)) / 1000;
|
||||
}
|
||||
|
||||
function title_color($hex)
|
||||
{
|
||||
if(get_brightness($hex) > 130) {
|
||||
return ' black';
|
||||
} else {
|
||||
return ' white';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function className($name)
|
||||
{
|
||||
$name = preg_replace('/\PL/u', '', $name);
|
||||
return $name;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@ namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use App\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@@ -25,7 +30,7 @@ class LoginController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
@@ -34,6 +39,88 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
Session::put('backUrl', URL::previous());
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
public function username()
|
||||
{
|
||||
return 'username';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a login request to the application.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function login(Request $request)
|
||||
{
|
||||
$current_user = User::currentUser();
|
||||
$request->merge(['username' => $current_user->username]);
|
||||
//die(print_r($request->all()));
|
||||
$this->validateLogin($request);
|
||||
|
||||
// If the class is using the ThrottlesLogins trait, we can automatically throttle
|
||||
// the login attempts for this application. We'll key this by the username and
|
||||
// the IP address of the client making these requests into this application.
|
||||
if ($this->hasTooManyLoginAttempts($request)) {
|
||||
$this->fireLockoutEvent($request);
|
||||
|
||||
return $this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
if ($this->attemptLogin($request)) {
|
||||
return $this->sendLoginResponse($request);
|
||||
}
|
||||
|
||||
// If the login attempt was unsuccessful we will increment the number of attempts
|
||||
// to login and redirect the user back to the login form. Of course, when this
|
||||
// user surpasses their maximum number of attempts they will get locked out.
|
||||
$this->incrementLoginAttempts($request);
|
||||
|
||||
return $this->sendFailedLoginResponse($request);
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
}
|
||||
|
||||
public function setUser(User $user)
|
||||
{
|
||||
Auth::logout();
|
||||
session(['current_user' => $user]);
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
public function autologin($uuid)
|
||||
{
|
||||
$user = User::where('autologin', $uuid)->first();
|
||||
Auth::login($user);
|
||||
session(['current_user' => $user]);
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
protected function authenticated(Request $request, $user)
|
||||
{
|
||||
return back();
|
||||
}
|
||||
|
||||
public function redirectTo()
|
||||
{
|
||||
return Session::get('url.intended') ? Session::get('url.intended') : $this->redirectTo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class RegisterController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
||||
@@ -25,7 +25,7 @@ class ResetPasswordController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = '/home';
|
||||
protected $redirectTo = '/';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
|
||||
@@ -6,8 +6,27 @@ use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
protected $user;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware(function ($request, $next) {
|
||||
$this->user = $this->user();
|
||||
//print_r($this->user);
|
||||
return $next($request);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return User::currentUser();
|
||||
}
|
||||
}
|
||||
|
||||
28
app/Http/Controllers/HomeController.php
Normal file
28
app/Http/Controllers/HomeController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class HomeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return redirect()->route('dash');
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,23 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Artisan;
|
||||
use App\Application;
|
||||
use App\Item;
|
||||
use App\Setting;
|
||||
use App\SupportedApps\Nzbget;
|
||||
use App\User;
|
||||
use GrahamCampbell\GitHub\Facades\GitHub;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\SupportedApps;
|
||||
use App\Jobs\ProcessApps;
|
||||
|
||||
class ItemController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource on the dashboard.
|
||||
*
|
||||
@@ -37,9 +45,8 @@ class ItemController extends Controller
|
||||
$item->save();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* Pin item on the dashboard.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
@@ -144,10 +151,19 @@ class ItemController extends Controller
|
||||
}
|
||||
|
||||
$config = Item::checkConfig($request->input('config'));
|
||||
$current_user = User::currentUser();
|
||||
$request->merge([
|
||||
'description' => $config
|
||||
'description' => $config,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
|
||||
if($request->input('class') === 'null') {
|
||||
$request->merge([
|
||||
'class' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
//die(print_r($request->input('config')));
|
||||
|
||||
$item = Item::create($request->all());
|
||||
@@ -209,10 +225,19 @@ class ItemController extends Controller
|
||||
}
|
||||
|
||||
$config = Item::checkConfig($request->input('config'));
|
||||
$current_user = User::currentUser();
|
||||
$request->merge([
|
||||
'description' => $config
|
||||
'description' => $config,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
|
||||
if($request->input('class') === 'null') {
|
||||
$request->merge([
|
||||
'class' => null,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$item = Item::find($id);
|
||||
$item->update($request->all());
|
||||
|
||||
@@ -264,16 +289,6 @@ class ItemController extends Controller
|
||||
->with('success',__('app.alert.success.item_restored'));
|
||||
}
|
||||
|
||||
public function isSupportedAppByKey($app)
|
||||
{
|
||||
$output = false;
|
||||
$all_supported = Item::supportedList();
|
||||
if(array_key_exists($app, $all_supported)) {
|
||||
$output = new $all_supported[$app];
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return details for supported apps
|
||||
*
|
||||
@@ -282,19 +297,25 @@ class ItemController extends Controller
|
||||
public function appload(Request $request)
|
||||
{
|
||||
$output = [];
|
||||
$app = $request->input('app');
|
||||
$appname = $request->input('app');
|
||||
//die($appname);
|
||||
|
||||
if(($app_details = $this->isSupportedAppByKey($app)) !== false) {
|
||||
// basic details
|
||||
$output['icon'] = $app_details->icon();
|
||||
$output['colour'] = $app_details->defaultColour();
|
||||
$app_details = Application::where('name', $appname)->firstOrFail();
|
||||
$appclass = $app_details->class();
|
||||
$app = new $appclass;
|
||||
|
||||
// live details
|
||||
if($app_details instanceof \App\SupportedApps\Contracts\Livestats) {
|
||||
$output['config'] = $app_details->configDetails();
|
||||
} else {
|
||||
$output['config'] = null;
|
||||
}
|
||||
// basic details
|
||||
$output['icon'] = $app_details->icon();
|
||||
$output['name'] = $app_details->name;
|
||||
$output['iconview'] = $app_details->iconView();
|
||||
$output['colour'] = $app_details->defaultColour();
|
||||
$output['class'] = $appclass;
|
||||
|
||||
// live details
|
||||
if($app instanceof \App\EnhancedApps) {
|
||||
$output['config'] = className($app_details->name).'.config';
|
||||
} else {
|
||||
$output['config'] = null;
|
||||
}
|
||||
|
||||
return json_encode($output);
|
||||
@@ -309,25 +330,34 @@ class ItemController extends Controller
|
||||
|
||||
$app_details = new $app();
|
||||
$app_details->config = (object)$data;
|
||||
$app_details->testConfig();
|
||||
$app_details->test();
|
||||
}
|
||||
|
||||
public function getStats($id)
|
||||
{
|
||||
$item = Item::find($id);
|
||||
|
||||
$config = json_decode($item->description);
|
||||
if(isset($config->type)) {
|
||||
$config->url = $item->url;
|
||||
if(isset($config->override_url) && !empty($config->override_url)) {
|
||||
$config->url = $config->override_url;
|
||||
}
|
||||
$app_details = new $config->type;
|
||||
$app_details->config = $config;
|
||||
echo $app_details->executeConfig();
|
||||
$config = $item->getconfig();
|
||||
if(isset($item->class)) {
|
||||
$application = new $item->class;
|
||||
$application->config = $config;
|
||||
echo $application->livestats();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function checkAppList()
|
||||
{
|
||||
ProcessApps::dispatch();
|
||||
$route = route('items.index');
|
||||
return redirect($route)
|
||||
->with('success', __('app.alert.success.updating'));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,10 +5,17 @@ namespace App\Http\Controllers;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Setting;
|
||||
use App\SettingGroup;
|
||||
use App\User;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class SettingsController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
@@ -31,6 +38,7 @@ class SettingsController extends Controller
|
||||
public function edit($id)
|
||||
{
|
||||
$setting = Setting::find($id);
|
||||
//die("s: ".$setting->label);
|
||||
|
||||
if((bool)$setting->system === true) return abort(404);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -4,10 +4,15 @@ namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Item;
|
||||
use App\User;
|
||||
use DB;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('allowed');
|
||||
}
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
@@ -58,10 +63,13 @@ class TagController extends Controller
|
||||
|
||||
$slug = str_slug($request->title, '-');
|
||||
|
||||
$current_user = User::currentUser();
|
||||
|
||||
// set item type to tag
|
||||
$request->merge([
|
||||
'type' => '1',
|
||||
'url' => $slug
|
||||
'url' => $slug,
|
||||
'user_id' => $current_user->id
|
||||
]);
|
||||
//die(print_r($request->all()));
|
||||
Item::create($request->all());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
156
app/Item.php
156
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', 'class', 'user_id'
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -23,63 +34,6 @@ class Item extends Model
|
||||
*/
|
||||
protected $dates = ['deleted_at'];
|
||||
|
||||
public static function supportedList()
|
||||
{
|
||||
return [
|
||||
'AirSonic' => \App\SupportedApps\AirSonic::class,
|
||||
'Cardigann' => \App\SupportedApps\Cardigann::class,
|
||||
'CouchPotato' => \App\SupportedApps\CouchPotato::class,
|
||||
'Deluge' => \App\SupportedApps\Deluge::class,
|
||||
'Dokuwiki' => \App\SupportedApps\Dokuwiki::class,
|
||||
'Duplicati' => \App\SupportedApps\Duplicati::class,
|
||||
'Emby' => \App\SupportedApps\Emby::class,
|
||||
'Gitea' => \App\SupportedApps\Gitea::class,
|
||||
'Glances' => \App\SupportedApps\Glances::class,
|
||||
'Grafana' => \App\SupportedApps\Grafana::class,
|
||||
'Graylog' => \App\SupportedApps\Graylog::class,
|
||||
'Home Assistant' => \App\SupportedApps\HomeAssistant::class,
|
||||
'Jackett' => \App\SupportedApps\Jackett::class,
|
||||
'Jdownloader' => \App\SupportedApps\Jdownloader::class,
|
||||
'Krusader' => \App\SupportedApps\Krusader::class,
|
||||
'Lidarr' => \App\SupportedApps\Lidarr::class,
|
||||
'Mcmyadmin' => \App\SupportedApps\Mcmyadmin::class,
|
||||
'Medusa' => \App\SupportedApps\Medusa::class,
|
||||
'NZBGet' => \App\SupportedApps\Nzbget::class,
|
||||
'Netdata' => \App\SupportedApps\Netdata::class,
|
||||
'Nextcloud' => \App\SupportedApps\Nextcloud::class,
|
||||
'Nzbhydra' => \App\SupportedApps\Nzbhydra::class,
|
||||
'OPNSense' => \App\SupportedApps\Opnsense::class,
|
||||
'Ombi' => \App\SupportedApps\Ombi::class,
|
||||
'Openhab' => \App\SupportedApps\Openhab::class,
|
||||
'OpenMediaVault' => \App\SupportedApps\OpenMediaVault::class,
|
||||
'Pihole' => \App\SupportedApps\Pihole::class,
|
||||
'Plex' => \App\SupportedApps\Plex::class,
|
||||
'Plexpy' => \App\SupportedApps\Plexpy::class,
|
||||
'Plexrequests' => \App\SupportedApps\Plexrequests::class,
|
||||
'Portainer' => \App\SupportedApps\Portainer::class,
|
||||
'Proxmox' => \App\SupportedApps\Proxmox::class,
|
||||
'Radarr' => \App\SupportedApps\Radarr::class,
|
||||
'Runeaudio' => \App\SupportedApps\Runeaudio::class,
|
||||
'Sabnzbd' => \App\SupportedApps\Sabnzbd::class,
|
||||
'Sickrage' => \App\SupportedApps\Sickrage::class,
|
||||
'Sonarr' => \App\SupportedApps\Sonarr::class,
|
||||
'Tautulli' => \App\SupportedApps\Tautulli::class,
|
||||
'Transmission' => \App\SupportedApps\Transmission::class,
|
||||
'Traefik' => \App\SupportedApps\Traefik::class,
|
||||
'tt-rss' => \App\SupportedApps\Ttrss::class,
|
||||
'UniFi' => \App\SupportedApps\Unifi::class,
|
||||
'pfSense' => \App\SupportedApps\Pfsense::class,
|
||||
'pyLoad' => \App\SupportedApps\pyLoad::class,
|
||||
'ruTorrent' => \App\SupportedApps\ruTorrent::class,
|
||||
'Watcher3' => \App\SupportedApps\Watcher3::class,
|
||||
'WebTools' => \App\SupportedApps\WebTools::class,
|
||||
];
|
||||
}
|
||||
public static function supportedOptions()
|
||||
{
|
||||
return array_keys(self::supportedList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope a query to only include pinned items.
|
||||
*
|
||||
@@ -91,24 +45,6 @@ class Item extends Model
|
||||
return $query->where('pinned', 1);
|
||||
}
|
||||
|
||||
public function getConfigAttribute()
|
||||
{
|
||||
$output = null;
|
||||
$view = null;
|
||||
if(isset($this->description) && !empty($this->description)){
|
||||
$output = json_decode($this->description);
|
||||
$output = is_object($output) ? $output : new \stdClass();
|
||||
if(isset($output->type) && !empty($output->type)) {
|
||||
$class = $output->type;
|
||||
$sap = new $class();
|
||||
$view = $sap->configDetails();
|
||||
$output->view = $view;
|
||||
}
|
||||
if(!isset($output->dataonly)) $output->dataonly = '0';
|
||||
|
||||
}
|
||||
return (object)$output;
|
||||
}
|
||||
public static function checkConfig($config)
|
||||
{
|
||||
if(empty($config)) {
|
||||
@@ -125,7 +61,7 @@ class Item extends Model
|
||||
}
|
||||
}
|
||||
//die(var_dump($store))
|
||||
|
||||
|
||||
$config['enabled'] = ($store) ? true : false;
|
||||
$config = json_encode($config);
|
||||
}
|
||||
@@ -162,10 +98,12 @@ class Item extends Model
|
||||
|
||||
public function getLinkTargetAttribute()
|
||||
{
|
||||
if((int)$this->type === 1) {
|
||||
$target = Setting::fetch('window_target');
|
||||
|
||||
if((int)$this->type === 1 || $target === 'current') {
|
||||
return '';
|
||||
} else {
|
||||
return ' target="heimdallapp"';
|
||||
return ' target="' . $target . '"';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,5 +138,63 @@ class Item extends Model
|
||||
return $query->where('type', $typeid);
|
||||
}
|
||||
|
||||
public function enhanced()
|
||||
{
|
||||
if(isset($this->class) && !empty($this->class)) {
|
||||
$app = new $this->class;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return (bool)($app instanceof \App\EnhancedApps);
|
||||
}
|
||||
|
||||
public function enabled()
|
||||
{
|
||||
if($this->enhanced()) {
|
||||
$config = $this->getconfig();
|
||||
if($config) {
|
||||
return (bool) $config->enabled;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getconfig()
|
||||
{
|
||||
$explode = explode('\\', $this->class);
|
||||
|
||||
|
||||
if(!isset($this->description) || empty($this->description)) {
|
||||
$config = new \stdClass;
|
||||
$config->name = end($explode);
|
||||
$config->enabled = false;
|
||||
return $config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$config = json_decode($this->description);
|
||||
|
||||
$config->name = end($explode);
|
||||
|
||||
|
||||
$config->url = $this->url;
|
||||
if(isset($config->override_url) && !empty($config->override_url)) {
|
||||
$config->url = $config->override_url;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the user that owns the item.
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo('App\User');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
63
app/Jobs/ProcessApps.php
Normal file
63
app/Jobs/ProcessApps.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use App\Application;
|
||||
use App\SupportedApps;
|
||||
|
||||
class ProcessApps implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$localapps = Application::all();
|
||||
$list = json_decode(SupportedApps::getList()->getBody());
|
||||
$validapps = [];
|
||||
foreach($list->apps as $app) {
|
||||
$validapps[] = $app->appid;
|
||||
if(!file_exists(app_path('SupportedApps/'.className($app->name)))) {
|
||||
SupportedApps::getFiles($app);
|
||||
$application = new Application;
|
||||
SupportedApps::saveApp($app, $application);
|
||||
} else {
|
||||
// check if there has been an update for this app
|
||||
$localapp = $localapps->where('appid', $app->appid)->first();
|
||||
if($localapp) {
|
||||
if($localapp->sha !== $app->sha) {
|
||||
SupportedApps::getFiles($app);
|
||||
SupportedApps::saveApp($app, $localapp);
|
||||
}
|
||||
} else {
|
||||
SupportedApps::getFiles($app);
|
||||
$application = new Application;
|
||||
SupportedApps::saveApp($app, $application);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//$delete = Application::whereNotIn('appid', $validapps)->delete(); // delete any apps not in list
|
||||
// removed the delete so local apps can be added
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,9 @@ use Illuminate\Support\ServiceProvider;
|
||||
use Artisan;
|
||||
use Schema;
|
||||
use App\Setting;
|
||||
use App\User;
|
||||
use App\Application;
|
||||
use App\Jobs\ProcessApps;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -16,7 +19,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$alt_bg = '';
|
||||
|
||||
if(!is_file(base_path('.env'))) {
|
||||
touch(base_path('.env'));
|
||||
@@ -32,27 +34,86 @@ class AppServiceProvider extends ServiceProvider
|
||||
}
|
||||
if(is_file(database_path('app.sqlite'))) {
|
||||
if(Schema::hasTable('settings')) {
|
||||
if($bg_image = Setting::fetch('background_image')) {
|
||||
$alt_bg = ' style="background-image: url(/storage/'.$bg_image.')"';
|
||||
}
|
||||
|
||||
// check version to see if an upgrade is needed
|
||||
$db_version = Setting::fetch('version');
|
||||
$db_version = Setting::_fetch('version');
|
||||
$app_version = config('app.version');
|
||||
if(version_compare($app_version, $db_version) == 1) { // app is higher than db, so need to run migrations etc
|
||||
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
|
||||
}
|
||||
|
||||
} else {
|
||||
Artisan::call('migrate', array('--path' => 'database/migrations', '--force' => true, '--seed' => true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$applications = Application::all();
|
||||
if($applications->count() <= 0) {
|
||||
if (class_exists('ZipArchive')) {
|
||||
ProcessApps::dispatch();
|
||||
} else {
|
||||
die("You are missing php-zip");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
$this->app['view']->addNamespace('SupportedApps', app_path('SupportedApps'));
|
||||
|
||||
|
||||
if (env('FORCE_HTTPS') === true) {
|
||||
\URL::forceScheme('https');
|
||||
}
|
||||
if(!is_file(public_path('storage'))) {
|
||||
Artisan::call('storage:link');
|
||||
|
||||
if(env('APP_URL') != 'http://localhost') {
|
||||
\URL::forceRootUrl(env('APP_URL'));
|
||||
}
|
||||
view()->share('alt_bg', $alt_bg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace App;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Input;
|
||||
use Form;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use App\User;
|
||||
|
||||
class Setting extends Model
|
||||
{
|
||||
@@ -46,6 +48,12 @@ class Setting extends Model
|
||||
|
||||
public function getListValueAttribute()
|
||||
{
|
||||
if((bool)$this->system === true) {
|
||||
$value = self::_fetch($this->key);
|
||||
} else {
|
||||
$value = self::fetch($this->key);
|
||||
}
|
||||
$this->value = $value;
|
||||
switch($this->type) {
|
||||
case 'image':
|
||||
if(!empty($this->value)) {
|
||||
@@ -80,6 +88,12 @@ class Setting extends Model
|
||||
|
||||
public function getEditValueAttribute()
|
||||
{
|
||||
if((bool)$this->system === true) {
|
||||
$value = self::_fetch($this->key);
|
||||
} else {
|
||||
$value = self::fetch($this->key);
|
||||
}
|
||||
$this->value = $value;
|
||||
switch($this->type) {
|
||||
case 'image':
|
||||
$value = '';
|
||||
@@ -125,6 +139,7 @@ class Setting extends Model
|
||||
return $this->belongsTo('App\SettingGroup', 'group_id');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
@@ -132,20 +147,54 @@ class Setting extends Model
|
||||
*/
|
||||
public static function fetch($key)
|
||||
{
|
||||
if (Setting::cached($key)) {
|
||||
return Setting::$cache[$key];
|
||||
} else {
|
||||
$user = self::user();
|
||||
return self::_fetch($key, $user);
|
||||
}
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function _fetch($key, $user=null)
|
||||
{
|
||||
#$cachekey = ($user === null) ? $key : $key.'-'.$user->id;
|
||||
#if (Setting::cached($cachekey)) {
|
||||
# return Setting::$cache[$cachekey];
|
||||
#} else {
|
||||
$find = self::where('key', '=', $key)->first();
|
||||
|
||||
if (!is_null($find)) {
|
||||
$value = $find->value;
|
||||
Setting::add($key, $value);
|
||||
if((bool)$find->system === true) { // if system variable use global value
|
||||
$value = $find->value;
|
||||
} else { // not system variable so use user specific value
|
||||
// check if user specified value has been set
|
||||
//print_r($user);
|
||||
$usersetting = $user->settings()->where('id', $find->id)->first();
|
||||
//print_r($user->settings);
|
||||
//die(var_dump($usersetting));
|
||||
//->pivot->value;
|
||||
//echo "user: ".$user->id." --- ".$usersettings;
|
||||
if(isset($usersetting) && !empty($usersetting)) {
|
||||
$value = $usersetting->pivot->uservalue;
|
||||
} else { // if not get default from base setting
|
||||
//$user->settings()->save($find, ['value' => $find->value]);
|
||||
#$has_setting = $user->settings()->where('id', $find->id)->exists();
|
||||
#if($has_setting) {
|
||||
# $user->settings()->updateExistingPivot($find->id, ['uservalue' => (string)$find->value]);
|
||||
#} else {
|
||||
# $user->settings()->save($find, ['uservalue' => (string)$find->value]);
|
||||
#}
|
||||
$value = $find->value;
|
||||
}
|
||||
|
||||
}
|
||||
#Setting::add($cachekey, $value);
|
||||
|
||||
return $value;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,21 +224,23 @@ class Setting extends Model
|
||||
$output = '';
|
||||
$homepage_search = self::fetch('homepage_search');
|
||||
$search_provider = self::where('key', '=', 'search_provider')->first();
|
||||
|
||||
//die(var_dump($search_provider->value));
|
||||
$user_search_provider = self::fetch('search_provider');
|
||||
//die(print_r($search_provider));
|
||||
|
||||
//die(var_dump($user_search_provider));
|
||||
// return early if search isn't applicable
|
||||
if((bool)$homepage_search !== true) return $output;
|
||||
if($search_provider->value === 'none') return $output;
|
||||
if(empty($search_provider->value)) return $output;
|
||||
if(is_null($search_provider->value)) return $output;
|
||||
if($user_search_provider === 'none') return $output;
|
||||
if(empty($user_search_provider)) return $output;
|
||||
if(is_null($user_search_provider)) return $output;
|
||||
|
||||
|
||||
if((bool)$homepage_search && (bool)$search_provider) {
|
||||
|
||||
$options = (array)json_decode($search_provider->options);
|
||||
$name = $options[$search_provider->value];
|
||||
if((bool)$search_provider->value) {
|
||||
switch($search_provider->value) {
|
||||
$name = $options[$user_search_provider];
|
||||
if((bool)$user_search_provider) {
|
||||
switch($user_search_provider) {
|
||||
case 'google':
|
||||
$url = 'https://www.google.com/search';
|
||||
$var = 'q';
|
||||
@@ -202,11 +253,14 @@ class Setting extends Model
|
||||
$url = 'https://www.bing.com/search';
|
||||
$var = 'q';
|
||||
break;
|
||||
case 'startpage':
|
||||
$url = 'https://www.startpage.com/';
|
||||
$var = 'q';
|
||||
}
|
||||
$output .= '<div class="searchform">';
|
||||
$output .= Form::open(['url' => $url, 'method' => 'get']);
|
||||
$output .= '<div class="input-container">';
|
||||
$output .= Form::text($var, null, ['class' => 'homesearch', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
|
||||
$output .= Form::text($var, null, ['class' => 'homesearch', 'autofocus' => 'autofocus', 'placeholder' => __($name).' '.__('app.settings.search').'...']);
|
||||
$output .= '<button type="submit">'.ucwords(__('app.settings.search')).'</button>';
|
||||
$output .= '</div>';
|
||||
$output .= Form::close();
|
||||
@@ -215,4 +269,19 @@ class Setting extends Model
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* The users that belong to the setting.
|
||||
*/
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany('App\User')->using('App\SettingUser')->withPivot('uservalue');
|
||||
}
|
||||
|
||||
public static function user()
|
||||
{
|
||||
return User::currentUser();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
10
app/SettingUser.php
Normal file
10
app/SettingUser.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
class SettingUser extends Pivot
|
||||
{
|
||||
//
|
||||
}
|
||||
154
app/SupportedApps.php
Normal file
154
app/SupportedApps.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php namespace App;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
abstract class SupportedApps
|
||||
{
|
||||
|
||||
protected $jar = false;
|
||||
protected $method = 'GET';
|
||||
protected $error;
|
||||
|
||||
public function appTest($url, $attrs = [], $overridevars=false)
|
||||
{
|
||||
$res = $this->execute($url, $attrs);
|
||||
if($res == null) {
|
||||
return (object)[
|
||||
'code' => null,
|
||||
'status' => $this->error,
|
||||
'response' => 'Connection failed',
|
||||
];
|
||||
}
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$status = 'Successfully communicated with the API';
|
||||
break;
|
||||
case 401:
|
||||
$status = 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
$status = 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
$status = 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
return (object)[
|
||||
'code' => $res->getStatusCode(),
|
||||
'status' => $status,
|
||||
'response' => $res->getBody(),
|
||||
];
|
||||
}
|
||||
|
||||
public function execute($url, $attrs = [], $overridevars=false, $overridemethod=false)
|
||||
{
|
||||
$res = null;
|
||||
|
||||
$vars = ($overridevars !== false) ?
|
||||
$overridevars : [
|
||||
'http_errors' => false,
|
||||
'timeout' => 15,
|
||||
'connect_timeout' => 15,
|
||||
];
|
||||
|
||||
$client = new Client($vars);
|
||||
|
||||
$method = ($overridemethod !== false) ? $overridemethod : $this->method;
|
||||
|
||||
try {
|
||||
return $client->request($method, $url, $attrs);
|
||||
} catch (\GuzzleHttp\Exception\ConnectException $e) {
|
||||
Log::error("Connection refused");
|
||||
Log::debug($e->getMessage());
|
||||
$this->error = "Connection refused - ".(string) $e->getMessage();
|
||||
} catch (\GuzzleHttp\Exception\ServerException $e) {
|
||||
Log::debug($e->getMessage());
|
||||
$this->error = (string) $e->getResponse()->getBody();
|
||||
}
|
||||
$this->error = 'General error connecting with API';
|
||||
return $res;
|
||||
}
|
||||
|
||||
public function login()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function normaliseurl($url, $addslash=true)
|
||||
{
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
if($addslash) $url .= '/';
|
||||
|
||||
return $url;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getLiveStats($status, $data)
|
||||
{
|
||||
$className = get_class($this);
|
||||
$explode = explode('\\', $className);
|
||||
$name = end($explode);
|
||||
|
||||
$html = view('SupportedApps::'.$name.'.livestats', $data)->with('data', $data)->render();
|
||||
return json_encode(['status' => $status, 'html' => $html]);
|
||||
//return
|
||||
}
|
||||
|
||||
public static function getList()
|
||||
{
|
||||
$list_url = 'https://apps.heimdall.site/list';
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
return $client->request('GET', $list_url);
|
||||
}
|
||||
|
||||
public static function getFiles($app)
|
||||
{
|
||||
$zipurl = $app->files;
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 60, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $zipurl);
|
||||
|
||||
if(!file_exists(app_path('SupportedApps'))) {
|
||||
mkdir(app_path('SupportedApps'), 0777, true);
|
||||
}
|
||||
|
||||
$src = app_path('SupportedApps/'.className($app->name).'.zip');
|
||||
file_put_contents($src, $res->getBody());
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
$x = $zip->open($src); // open the zip file to extract
|
||||
if ($x === true) {
|
||||
$zip->extractTo(app_path('SupportedApps')); // place in the directory with same name
|
||||
$zip->close();
|
||||
unlink($src); //Deleting the Zipped file
|
||||
}
|
||||
}
|
||||
|
||||
public static function saveApp($details, $app)
|
||||
{
|
||||
$img_src = app_path('SupportedApps/'.className($details->name).'/'.$details->icon);
|
||||
$img_dest = public_path('storage/supportedapps/'.$details->icon);
|
||||
//die("i: ".$img_src);
|
||||
copy($img_src, $img_dest);
|
||||
|
||||
$app->appid = $details->appid;
|
||||
$app->name = $details->name;
|
||||
$app->sha = $details->sha ?? null;
|
||||
$app->icon = 'supportedapps/'.$details->icon;
|
||||
$app->website = $details->website;
|
||||
$app->license = $details->license;
|
||||
$app->description = $details->description;
|
||||
|
||||
$appclass = $app->class();
|
||||
$application = new $appclass;
|
||||
$enhanced = (bool)($application instanceof \App\EnhancedApps);
|
||||
|
||||
$app->enhanced = $enhanced;
|
||||
$app->tile_background = $details->tile_background;
|
||||
$app->save();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class AirSonic implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#08F';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/airsonic.png';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Cardigann implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#753';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/cardigann.png';
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
<?php namespace App\SupportedApps\Contracts;
|
||||
|
||||
interface Applications {
|
||||
|
||||
public function defaultColour();
|
||||
|
||||
public function icon();
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps\Contracts;
|
||||
|
||||
interface Livestats {
|
||||
|
||||
public function configDetails();
|
||||
|
||||
public function testConfig();
|
||||
|
||||
public function executeConfig();
|
||||
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
<?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,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Deluge implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#357';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/deluge.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Dokuwiki implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#9d7056';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/dokuwiki.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Duplicati implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2c3744';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/duplicati.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Emby implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/emby.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Gitea implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#585e52';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/gitea.png';
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Glances implements Contracts\Applications {
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2c363f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/glances.png';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Grafana implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#a56e4d';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/grafana.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Graylog implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#158';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/graylog.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class HomeAssistant implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#073c52';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/homeassistant.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Jackett implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#484814';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/jackett.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Jdownloader implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2b494f';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/jdownloader.png';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Krusader implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#5A5';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/krusader.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Lidarr implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#183c18';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/lidarr.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Mcmyadmin implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#30404b';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/mcmyadmin.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Medusa implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#4b5e55';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/medusa.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Netdata implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#543737';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/netdata.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Nextcloud implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#0e2c3e';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nextcloud.png';
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Nzbget implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#253827';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nzbget.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'nzbget';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('status');
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo 'Successfully connected to the API';
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'inactive';
|
||||
$res = $this->buildRequest('status');
|
||||
$data = json_decode($res->getBody());
|
||||
//$data->result->RemainingSizeMB = '10000000';
|
||||
//$data->result->DownloadRate = '100000000';
|
||||
if($data) {
|
||||
$size = $data->result->RemainingSizeMB;
|
||||
$rate = $data->result->DownloadRate;
|
||||
$queue_size = format_bytes($size*1000*1000, false, ' <span>', '</span>');
|
||||
$current_speed = format_bytes($rate, false, ' <span>');
|
||||
|
||||
$active = ($size > 0 || $rate > 0) ? 'active' : 'inactive';
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Queue</span><strong>'.$queue_size.'</strong></li>
|
||||
<li><span class="title">Speed</span><strong>'.$current_speed.'/s</span></strong></li>
|
||||
</ul>
|
||||
';
|
||||
}
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$username = $config->username;
|
||||
$password = $config->password;
|
||||
|
||||
$rebuild_url = str_replace('http://', 'http://'.$username.':'.$password.'@', $url);
|
||||
$rebuild_url = str_replace('https://', 'https://'.$username.':'.$password.'@', $rebuild_url);
|
||||
$rebuild_url = rtrim($rebuild_url, '/');
|
||||
|
||||
|
||||
$api_url = $rebuild_url.'/jsonrpc/'.$endpoint;
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Nzbhydra implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#53644d';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/nzbhydra.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Ombi implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#150f09';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/ombi.png';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class OpenMediaVault implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#5AF';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/openmediavault.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Openhab implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2b2525';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/openhab.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Opnsense implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#211914';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/opnsense.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Pfsense implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#4e4742';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pfsense.png';
|
||||
}
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Pihole implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#352222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pihole.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
return 'pihole';
|
||||
}
|
||||
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest();
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo 'Successfully connected to the API';
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->buildRequest();
|
||||
$data = json_decode($res->getBody());
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Domains<br />Blocked</span><strong>'.$data->domains_being_blocked.'</strong></li>
|
||||
<li><span class="title">Blocked<br />Today</span><strong>'.$data->ads_blocked_today.'</span></strong></li>
|
||||
</ul>
|
||||
';
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
|
||||
public function buildRequest()
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api.php';
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Plex implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#222';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plex.png';
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Plexpy implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#2d2208';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plexpy.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'plexpy';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('arnold');
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
if(isset($data->error) && !empty($data->error)) {
|
||||
echo 'Failed: '.$data->error;
|
||||
} else {
|
||||
echo 'Successfully connected to the API';
|
||||
}
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'active';
|
||||
$res = $this->buildRequest('get_activity');
|
||||
$data = json_decode($res->getBody());
|
||||
$stream_count = $data->response->data->stream_count;
|
||||
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Stream Count</span><strong>'.$stream_count.'</strong></li>
|
||||
</ul>
|
||||
';
|
||||
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$apikey = $config->apikey;
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api/v2?apikey='.$apikey.'&cmd='.$endpoint;
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Plexrequests implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3c2d1c';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/plexrequests.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Portainer implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#283f44';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/portainer.png';
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Proxmox implements Contracts\Applications, Contracts\Livestats {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#542e0a';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/proxmox.png';
|
||||
}
|
||||
|
||||
public function configDetails()
|
||||
{
|
||||
//return 'proxmox';
|
||||
return null;
|
||||
}
|
||||
|
||||
public function testConfig()
|
||||
{
|
||||
/*$res = $this->buildRequest();
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
echo 'Successfully connected to the API';
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}*/
|
||||
return null;
|
||||
}
|
||||
|
||||
public function executeConfig()
|
||||
{
|
||||
/*
|
||||
$output = '';
|
||||
$res = $this->buildRequest();
|
||||
$data = json_decode($res->getBody());
|
||||
|
||||
$output = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Domains<br />Blocked</span><strong>'.$data->domains_being_blocked.'</strong></li>
|
||||
<li><span class="title">Blocked<br />Today</span><strong>'.$data->ads_blocked_today.'</span></strong></li>
|
||||
</ul>
|
||||
';
|
||||
return $output;
|
||||
*/
|
||||
return null;
|
||||
}
|
||||
|
||||
public function buildRequest($endpoint='')
|
||||
{
|
||||
$config = $this->config;
|
||||
|
||||
$username = $config->username;
|
||||
$password = $config->password;
|
||||
|
||||
$url = $config->url;
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api2/json/'.$endpoint.'?username='.$username.'&password='.$password;
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'verify' => false ]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Radarr implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3e3726';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/radarr.png';
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
<?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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class Sabnzbd implements Contracts\Applications, Contracts\Livestats {
|
||||
|
||||
public $config;
|
||||
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#3e3924';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/sabnzbd.png';
|
||||
}
|
||||
public function configDetails()
|
||||
{
|
||||
return 'sabnzbd';
|
||||
}
|
||||
public function testConfig()
|
||||
{
|
||||
$res = $this->buildRequest('queue');
|
||||
switch($res->getStatusCode()) {
|
||||
case 200:
|
||||
$data = json_decode($res->getBody());
|
||||
if(isset($data->error) && !empty($data->error)) {
|
||||
echo 'Failed: '.$data->error;
|
||||
} else {
|
||||
echo 'Successfully connected to the API';
|
||||
}
|
||||
break;
|
||||
case 401:
|
||||
echo 'Failed: Invalid credentials';
|
||||
break;
|
||||
case 404:
|
||||
echo 'Failed: Please make sure your URL is correct and that there is a trailing slash';
|
||||
break;
|
||||
default:
|
||||
echo 'Something went wrong... Code: '.$res->getStatusCode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
public function executeConfig()
|
||||
{
|
||||
$html = '';
|
||||
$active = 'inactive';
|
||||
$res = $this->buildRequest('queue');
|
||||
$data = json_decode($res->getBody());
|
||||
//$data->result->RemainingSizeMB = '10000000';
|
||||
//$data->result->DownloadRate = '100000000';
|
||||
if($data) {
|
||||
$size = $data->queue->mbleft;
|
||||
$rate = $data->queue->kbpersec;
|
||||
$queue_size = format_bytes($size*1000*1000, false, ' <span>', '</span>');
|
||||
$current_speed = format_bytes($rate*1000, false, ' <span>');
|
||||
|
||||
$active = ($size > 0 || $rate > 0) ? 'active' : 'inactive';
|
||||
$html = '
|
||||
<ul class="livestats">
|
||||
<li><span class="title">Queue</span><strong>'.$queue_size.'</strong></li>
|
||||
<li><span class="title">Speed</span><strong>'.$current_speed.'/s</span></strong></li>
|
||||
</ul>
|
||||
';
|
||||
}
|
||||
return json_encode(['status' => $active, 'html' => $html]);
|
||||
}
|
||||
public function buildRequest($endpoint)
|
||||
{
|
||||
$config = $this->config;
|
||||
$url = $config->url;
|
||||
$apikey = $config->apikey;
|
||||
|
||||
//print_r($config);
|
||||
//die();
|
||||
|
||||
$url = rtrim($url, '/');
|
||||
|
||||
$api_url = $url.'/api?output=json&apikey='.$apikey.'&mode='.$endpoint;
|
||||
//die( $api_url.' --- ');
|
||||
|
||||
$client = new Client(['http_errors' => false, 'timeout' => 15, 'connect_timeout' => 15]);
|
||||
$res = $client->request('GET', $api_url);
|
||||
return $res;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Sickrage implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#6185a6';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/sickrage.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Sonarr implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#163740';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/sonarr.png';
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
<?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 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Traefik implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#28434a';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/traefik.png';
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
<?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()
|
||||
{
|
||||
$url = $this->config->url;
|
||||
$url = rtrim($url, '/');
|
||||
$apiUrl = $url.'/transmission/rpc';
|
||||
return $apiUrl;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Ttrss implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#9d704c';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/tt-rss.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class Unifi implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#363840';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/unifi.png';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class Watcher3 implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#500';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/watcher3.png';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class WebTools implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#555';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/webtools.png';
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
class pyLoad implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#881';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/pyload.png';
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
<?php namespace App\SupportedApps;
|
||||
|
||||
class ruTorrent implements Contracts\Applications {
|
||||
public function defaultColour()
|
||||
{
|
||||
return '#004';
|
||||
}
|
||||
public function icon()
|
||||
{
|
||||
return 'supportedapps/rutorrent.png';
|
||||
}
|
||||
}
|
||||
36
app/User.php
36
app/User.php
@@ -15,7 +15,7 @@ class User extends Authenticatable
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name', 'email', 'password',
|
||||
'username', 'email', 'password',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -26,4 +26,38 @@ class User extends Authenticatable
|
||||
protected $hidden = [
|
||||
'password', 'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the items for the user.
|
||||
*/
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany('App\Item');
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings that belong to the user.
|
||||
*/
|
||||
public function settings()
|
||||
{
|
||||
return $this->belongsToMany('App\Setting')->withPivot('uservalue');
|
||||
}
|
||||
|
||||
public static function currentUser()
|
||||
{
|
||||
$current_user = session('current_user');
|
||||
if ($current_user) { // if logged in, set this user
|
||||
return $current_user;
|
||||
} else { // not logged in, get first user
|
||||
$user = User::where('public_front',true)->first();
|
||||
if(!$user) {
|
||||
$user = User::first();
|
||||
}
|
||||
session(['current_user' => $user]);
|
||||
return $user;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"fideloper/proxy": "~3.3",
|
||||
"fideloper/proxy": "^4.0",
|
||||
"graham-campbell/github": "^7.5",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"laravel/framework": "5.5.*",
|
||||
"laravel/framework": "5.7.*",
|
||||
"laravel/tinker": "~1.0",
|
||||
"laravelcollective/html": "^5.5"
|
||||
"laravelcollective/html": "^5.5",
|
||||
"php-http/guzzle6-adapter": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"filp/whoops": "~2.0",
|
||||
|
||||
2049
composer.lock
generated
2049
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.9',
|
||||
'version' => '2.1.0',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -229,6 +229,9 @@ return [
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
|
||||
'SupportedApps' => App\SupportedApps::class,
|
||||
'EnhancedApps' => App\EnhancedApps::class,
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
91
config/github.php
Normal file
91
config/github.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/*
|
||||
* This file is part of Laravel GitHub.
|
||||
*
|
||||
* (c) Graham Campbell <graham@alt-three.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Connection Name
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify which of the connections below you wish to use as
|
||||
| your default connection for all work. Of course, you may use many
|
||||
| connections at once using the manager class.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => 'main',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| GitHub Connections
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here are each of the connections setup for your application. Example
|
||||
| configuration has been included, but you may add as many connections as
|
||||
| you would like. Note that the 5 supported authentication methods are:
|
||||
| "application", "jwt", "none", "password", and "token".
|
||||
|
|
||||
*/
|
||||
|
||||
'connections' => [
|
||||
|
||||
'main' => [
|
||||
'token' => 'your-token',
|
||||
'method' => 'token',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'app' => [
|
||||
'clientId' => 'your-client-id',
|
||||
'clientSecret' => 'your-client-secret',
|
||||
'method' => 'application',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'jwt' => [
|
||||
'token' => 'your-jwt-token',
|
||||
'method' => 'jwt',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'other' => [
|
||||
'username' => 'your-username',
|
||||
'password' => 'your-password',
|
||||
'method' => 'password',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
'none' => [
|
||||
'method' => 'none',
|
||||
// 'backoff' => false,
|
||||
// 'cache' => false,
|
||||
// 'version' => 'v3',
|
||||
// 'enterprise' => false,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
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');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateApplicationsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('applications', function (Blueprint $table) {
|
||||
|
||||
$table->string('appid')->unique();
|
||||
$table->string('name')->unique();
|
||||
$table->string('sha')->unique()->nullable();
|
||||
$table->string('icon')->nullable();
|
||||
$table->string('website')->nullable();
|
||||
$table->string('license')->nullable();
|
||||
$table->mediumText('description')->nullable();
|
||||
$table->boolean('enhanced')->default(false);
|
||||
$table->string('tile_background')->default('dark');
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('applications');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddClassToItemsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->string('class')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('items', function (Blueprint $table) {
|
||||
$table->dropColumn(['class']);
|
||||
});
|
||||
}
|
||||
}
|
||||
36
database/migrations/2018_10_31_191604_create_jobs_table.php
Normal file
36
database/migrations/2018_10_31_191604_create_jobs_table.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateJobsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('jobs', function (Blueprint $table) {
|
||||
$table->bigIncrements('id');
|
||||
$table->string('queue')->index();
|
||||
$table->longText('payload');
|
||||
$table->unsignedTinyInteger('attempts');
|
||||
$table->unsignedInteger('reserved_at')->nullable();
|
||||
$table->unsignedInteger('available_at');
|
||||
$table->unsignedInteger('created_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('jobs');
|
||||
}
|
||||
}
|
||||
@@ -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)) {
|
||||
@@ -137,6 +138,60 @@ class SettingsSeeder extends Seeder
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
|
||||
$window_target_options = json_encode([
|
||||
'current' => 'app.settings.window_target.current',
|
||||
'heimdall' => 'app.settings.window_target.one',
|
||||
'_blank' => 'app.settings.window_target.new',
|
||||
]);
|
||||
|
||||
if(!$setting = Setting::find(7)) {
|
||||
|
||||
$setting = new Setting;
|
||||
$setting->id = 7;
|
||||
$setting->group_id = 3;
|
||||
$setting->key = 'window_target';
|
||||
$setting->type = 'select';
|
||||
$setting->options = $window_target_options;
|
||||
$setting->label = 'app.settings.window_target';
|
||||
$setting->value = 'heimdall';
|
||||
$setting->save();
|
||||
} else {
|
||||
$setting->options = $window_target_options;
|
||||
$setting->label = 'app.settings.window_target';
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
if($support = Setting::find(8)) {
|
||||
$support->label = 'app.settings.support';
|
||||
$support->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$support->save();
|
||||
} else {
|
||||
$setting = new Setting;
|
||||
$setting->id = 8;
|
||||
$setting->group_id = 1;
|
||||
$setting->key = 'support';
|
||||
$setting->type = 'text';
|
||||
$setting->label = 'app.settings.support';
|
||||
$setting->value = '<a rel="noopener" target="_blank" href="https://discord.gg/CCjHKn4">Discord</a> | <a rel="noopener" target="_blank" href="https://github.com/linuxserver/Heimdall">Github</a> | <a rel="noopener" target="_blank" href="https://blog.heimdall.site/">Blog</a>';
|
||||
$setting->system = true;
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
if($donate = Setting::find(9)) {
|
||||
$donate->label = 'app.settings.donate';
|
||||
$donate->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
|
||||
$donate->save();
|
||||
} else {
|
||||
$setting = new Setting;
|
||||
$setting->id = 9;
|
||||
$setting->group_id = 1;
|
||||
$setting->key = 'donate';
|
||||
$setting->type = 'text';
|
||||
$setting->label = 'app.settings.donate';
|
||||
$setting->value = '<a rel="noopener" target="_blank" href="https://www.paypal.me/heimdall">Paypal</a>';
|
||||
$setting->system = true;
|
||||
$setting->save();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
27
database/seeds/UsersSeeder.php
Normal file
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
10454
package-lock.json
generated
10454
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.1.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-sass": "^4.7.2",
|
||||
"select2": "^4.0.6-rc.1"
|
||||
}
|
||||
}
|
||||
|
||||
278
public/css/app.css
vendored
278
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;
|
||||
@@ -585,10 +703,11 @@ body {
|
||||
max-width: 1000px;
|
||||
width: 100%;
|
||||
margin: 10px 40px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.module-container header,
|
||||
.module-container footer {
|
||||
.module-container header, .module-container footer {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
@@ -606,8 +725,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;
|
||||
@@ -671,6 +789,26 @@ body {
|
||||
height: 51px;
|
||||
}
|
||||
|
||||
.toggleinput {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: reverse;
|
||||
-ms-flex-direction: column-reverse;
|
||||
flex-direction: column-reverse;
|
||||
line-height: 1;
|
||||
font-size: 9px;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
color: #ababab;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.toggleinput label.name {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
.module-actions {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
@@ -756,8 +894,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 +962,11 @@ div.create .input select {
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
|
||||
.switch input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* The slider */
|
||||
|
||||
.slider {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
@@ -871,7 +1006,6 @@ input:checked + .slider:before {
|
||||
}
|
||||
|
||||
/* Rounded sliders */
|
||||
|
||||
.slider.round {
|
||||
border-radius: 20px;
|
||||
}
|
||||
@@ -1025,23 +1159,23 @@ a.settinglink {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.ui-state-hover,
|
||||
.ui-state-active {
|
||||
.ui-state-hover, .ui-state-active {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
#appimage img {
|
||||
max-width: 150px;
|
||||
max-width: 95px;
|
||||
}
|
||||
|
||||
#sapconfig {
|
||||
#sapconfig, .newblock {
|
||||
display: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#sapconfig h2 {
|
||||
#sapconfig h2, .newblock h2 {
|
||||
background: #f2f3f6;
|
||||
padding: 18px 25px;
|
||||
padding: 2px 25px;
|
||||
height: 60px;
|
||||
margin-left: -15px;
|
||||
width: calc(100% + 30px);
|
||||
/* margin-right: -30px; */
|
||||
@@ -1050,9 +1184,18 @@ a.settinglink {
|
||||
font-size: 18px;
|
||||
color: #5b5b5b;
|
||||
font-weight: 500;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-pack: justify;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#sapconfig .items {
|
||||
#sapconfig .items, .newblock .items {
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
@@ -1119,7 +1262,7 @@ hr {
|
||||
}
|
||||
|
||||
.livestats-container .livestats {
|
||||
margin: 5px 0px -5px;
|
||||
margin: 5px 0px 0px;
|
||||
padding: 0;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
@@ -1144,11 +1287,35 @@ hr {
|
||||
font-weight: 500;
|
||||
opacity: 0.5;
|
||||
line-height: 1;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.livestats-container .livestats strong {
|
||||
display: block;
|
||||
line-height: 1;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
color: white;
|
||||
font-size: 12px;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.livestats-container .livestats strong span {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.livestats-container .livestats.flexcolumn {
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-box-direction: normal;
|
||||
-ms-flex-direction: column;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
input:-webkit-autofill,
|
||||
@@ -1172,9 +1339,16 @@ select:-webkit-autofill:focus {
|
||||
.title-marquee {
|
||||
width: 125px;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-box-align: start;
|
||||
-ms-flex-align: start;
|
||||
align-items: flex-start;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.title-marquee span {
|
||||
.title-marquee > span, .title-marquee > strong {
|
||||
white-space: nowrap;
|
||||
-webkit-transform: translate(0, 0);
|
||||
transform: translate(0, 0);
|
||||
@@ -1182,22 +1356,27 @@ select:-webkit-autofill:focus {
|
||||
animation: marquee 8s linear;
|
||||
}
|
||||
|
||||
.title-marquee .title {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.no-marquee .title {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
@-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);
|
||||
@@ -1209,17 +1388,14 @@ select:-webkit-autofill:focus {
|
||||
-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);
|
||||
@@ -1229,7 +1405,6 @@ select:-webkit-autofill:focus {
|
||||
/*! Huebee v2.0.0
|
||||
http://huebee.buzz
|
||||
---------------------------------------------- */
|
||||
|
||||
.huebee {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
@@ -1324,7 +1499,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,
|
||||
@@ -1461,7 +1635,6 @@ http://huebee.buzz
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
@@ -1473,7 +1646,6 @@ http://huebee.buzz
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
@@ -1556,7 +1728,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";
|
||||
}
|
||||
@@ -5340,8 +5511,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;
|
||||
@@ -5354,13 +5524,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,
|
||||
@@ -5671,9 +5840,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;
|
||||
}
|
||||
|
||||
@@ -5701,14 +5868,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;
|
||||
}
|
||||
@@ -6019,4 +6184,3 @@ readers do not read off random characters that represent icons */
|
||||
.select2-container--classic.select2-container--open .select2-dropdown {
|
||||
border-color: #5897fb;
|
||||
}
|
||||
|
||||
|
||||
14
public/img/heimdall-logo-bloated.svg
Normal file
14
public/img/heimdall-logo-bloated.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="780" height="619" viewBox="0 0 780 619">
|
||||
<metadata><?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c138 79.159824, 2016/09/14-01:09:01 ">
|
||||
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<rdf:Description rdf:about=""/>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
|
||||
|
||||
<?xpacket end="w"?></metadata>
|
||||
<path class="cls-1" d="M440.227,415.119V390.2l8.552-26.577C508.647,304.3,555.686,248.776,564,231.691l-10.215,3.56s9.5-11.864,8.552-18.51c-7.6-116.273-73.17-176.862-91.226-191.732,26.607,31.955,19.326,42.4,19.326,42.4C478.714,45.576,454.64,24.377,449.888,19l-5.7,33.853c22.806,13.289,16.79,20.882,16.79,20.882C455.591,66.141,441.021,59.5,441.021,59.5l-1.586,9.491c6.973,3.165,38.327,22.149,38.565,70.872,0,59.323-33.735,74.985-39.674,77.357-19.718-11.865-41.1-11.627-46.326-12.1-5.226.474-26.608,0.236-46.324,12.1C339.735,214.844,306,199.182,306,139.859c0.238-48.723,31.6-67.707,38.564-70.872L342.983,59.5s-14.574,6.644-19.955,14.238c0,0-6.022-7.593,16.786-20.882L334.112,19c-4.752,5.378-28.824,26.577-40.543,48.407,0,0-7.288-10.443,19.32-42.4-18.054,14.87-83.625,75.459-91.226,191.732-0.95,6.646,8.554,18.51,8.554,18.51L220,231.691c8.316,17.085,55.355,72.612,115.221,131.935l8.554,26.577v24.916l-7.6-26.577L318.83,360.067v28.95C325.957,409.186,353.751,450,353.751,450V365.525L247.32,249.488s66.52,54.1,85.526,73.56l9.978-10.2c-12.355-8.78-66.045-62.646-70.8-110.1,40.388,85.426,79.111,96.1,107.62,129.325V340.2h24.707v-8.131c28.508-33.221,67.233-43.9,107.619-129.325-4.75,47.459-58.442,101.325-70.8,110.1l9.976,10.2c19.006-19.458,85.526-73.56,85.526-73.56L430.249,365.525V450s27.8-40.815,34.923-60.984v-28.95l-17.343,28.475ZM392,313.083c-17.818-11.865-63.668-39.629-82.672-83.053a314.117,314.117,0,0,0,34.447,34.882s-1.189-30.61,1.186-37.255c4.276,36.781,13.068,52.442,47.039,71.9,33.973-19.458,42.763-35.119,47.039-71.9,2.375,6.645,1.188,37.255,1.188,37.255a314.117,314.117,0,0,0,34.447-34.882C455.668,273.454,409.818,301.218,392,313.083Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
6
public/img/heimdall-logo-small.svg
Normal file
6
public/img/heimdall-logo-small.svg
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16pt" height="16pt" viewBox="0 0 16 16" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 9.777344 14.660156 L 9.777344 13.738281 L 10.09375 12.761719 C 12.300781 10.574219 14.035156 8.527344 14.339844 7.894531 L 13.964844 8.027344 C 13.964844 8.027344 14.316406 7.589844 14.28125 7.34375 C 14 3.058594 11.582031 0.824219 10.917969 0.277344 C 11.898438 1.453125 11.628906 1.839844 11.628906 1.839844 C 11.195312 1.035156 10.308594 0.253906 10.132812 0.0546875 L 9.925781 1.304688 C 10.765625 1.792969 10.542969 2.074219 10.542969 2.074219 C 10.34375 1.792969 9.808594 1.546875 9.808594 1.546875 L 9.75 1.898438 C 10.003906 2.015625 11.160156 2.714844 11.171875 4.511719 C 11.171875 6.699219 9.925781 7.277344 9.707031 7.363281 C 8.980469 6.925781 8.191406 6.933594 8 6.917969 C 7.808594 6.933594 7.019531 6.925781 6.292969 7.363281 C 6.074219 7.273438 4.828125 6.699219 4.828125 4.511719 C 4.839844 2.714844 5.996094 2.015625 6.25 1.898438 L 6.191406 1.546875 C 6.191406 1.546875 5.65625 1.792969 5.457031 2.074219 C 5.457031 2.074219 5.234375 1.792969 6.074219 1.304688 L 5.867188 0.0546875 C 5.691406 0.253906 4.804688 1.035156 4.371094 1.839844 C 4.371094 1.839844 4.101562 1.453125 5.082031 0.277344 C 4.417969 0.824219 2 3.058594 1.71875 7.34375 C 1.683594 7.589844 2.035156 8.027344 2.035156 8.027344 L 1.660156 7.894531 C 1.964844 8.527344 3.699219 10.574219 5.90625 12.761719 L 6.222656 13.738281 L 6.222656 14.660156 L 5.941406 13.679688 L 5.300781 12.628906 L 5.300781 13.695312 C 5.566406 14.441406 6.589844 15.945312 6.589844 15.945312 L 6.589844 12.832031 L 2.667969 8.550781 C 2.667969 8.550781 5.117188 10.546875 5.820312 11.265625 L 6.1875 10.886719 C 5.730469 10.566406 3.753906 8.578125 3.578125 6.828125 C 5.066406 9.980469 6.492188 10.371094 7.542969 11.597656 L 7.542969 11.898438 L 8.457031 11.898438 L 8.457031 11.597656 C 9.507812 10.371094 10.933594 9.980469 12.421875 6.828125 C 12.246094 8.578125 10.269531 10.566406 9.8125 10.886719 L 10.179688 11.265625 C 10.882812 10.546875 13.332031 8.550781 13.332031 8.550781 L 9.410156 12.832031 L 9.410156 15.945312 C 9.410156 15.945312 10.433594 14.441406 10.699219 13.695312 L 10.699219 12.628906 L 10.058594 13.679688 Z M 8 10.898438 C 7.34375 10.460938 5.652344 9.4375 4.953125 7.835938 C 5.339844 8.296875 5.765625 8.726562 6.222656 9.121094 C 6.222656 9.121094 6.179688 7.992188 6.265625 7.746094 C 6.421875 9.105469 6.746094 9.679688 8 10.398438 C 9.253906 9.679688 9.578125 9.105469 9.734375 7.746094 C 9.820312 7.992188 9.777344 9.121094 9.777344 9.121094 C 10.234375 8.726562 10.660156 8.296875 11.046875 7.835938 C 10.347656 9.4375 8.65625 10.460938 8 10.898438 Z M 8 10.898438 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
11
public/img/heimdall-logo-square.svg
Normal file
11
public/img/heimdall-logo-square.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="434" height="434" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g>
|
||||
<title>background</title>
|
||||
<rect fill="none" id="canvas_background" height="436" width="436" y="-1" x="-1"/>
|
||||
</g>
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<path id="svg_1" d="m265.227,397.619l0,-24.919l8.552,-26.577c59.868,-59.323 106.907,-114.847 115.221,-131.932l-10.215,3.56s9.5,-11.864 8.552,-18.51c-7.6,-116.273 -73.17,-176.862 -91.226,-191.732c26.607,31.955 19.326,42.4 19.326,42.4c-11.723,-21.833 -35.797,-43.032 -40.549,-48.409l-5.7,33.853c22.806,13.289 16.79,20.882 16.79,20.882c-5.387,-7.594 -19.957,-14.235 -19.957,-14.235l-1.586,9.491c6.973,3.165 38.327,22.149 38.565,70.872c0,59.323 -33.735,74.985 -39.674,77.357c-19.718,-11.865 -41.1,-11.627 -46.326,-12.1c-5.226,0.474 -26.608,0.236 -46.324,12.1c-5.941,-2.376 -39.676,-18.038 -39.676,-77.361c0.238,-48.723 31.6,-67.707 38.564,-70.872l-1.581,-9.487s-14.574,6.644 -19.955,14.238c0,0 -6.022,-7.593 16.786,-20.882l-5.702,-33.856c-4.752,5.378 -28.824,26.577 -40.543,48.407c0,0 -7.288,-10.443 19.32,-42.4c-18.054,14.87 -83.625,75.459 -91.226,191.732c-0.95,6.646 8.554,18.51 8.554,18.51l-10.217,-3.558c8.316,17.085 55.355,72.612 115.221,131.935l8.554,26.577l0,24.916l-7.6,-26.577l-17.345,-28.475l0,28.95c7.127,20.169 34.921,60.983 34.921,60.983l0,-84.475l-106.431,-116.037s66.52,54.1 85.526,73.56l9.978,-10.2c-12.355,-8.78 -66.045,-62.646 -70.8,-110.1c40.388,85.426 79.111,96.1 107.62,129.325l0,8.127l24.707,0l0,-8.131c28.508,-33.221 67.233,-43.9 107.619,-129.325c-4.75,47.459 -58.442,101.325 -70.8,110.1l9.976,10.2c19.006,-19.458 85.526,-73.56 85.526,-73.56l-106.423,116.041l0,84.475s27.8,-40.815 34.923,-60.984l0,-28.95l-17.343,28.475l-7.602,26.578zm-48.227,-102.036c-17.818,-11.865 -63.668,-39.629 -82.672,-83.053a314.117,314.117 0 0 0 34.447,34.882s-1.189,-30.61 1.186,-37.255c4.276,36.781 13.068,52.442 47.039,71.9c33.973,-19.458 42.763,-35.119 47.039,-71.9c2.375,6.645 1.188,37.255 1.188,37.255a314.117,314.117 0 0 0 34.447,-34.882c-19.006,43.424 -64.856,71.188 -82.674,83.053z" class="cls-1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
11
public/img/heimdall-logo.svg
Normal file
11
public/img/heimdall-logo.svg
Normal file
@@ -0,0 +1,11 @@
|
||||
<svg width="346" height="434" xmlns="http://www.w3.org/2000/svg">
|
||||
|
||||
<g>
|
||||
<title>background</title>
|
||||
<rect fill="none" id="canvas_background" height="436" width="348" y="-1" x="-1"/>
|
||||
</g>
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<path id="svg_1" d="m221.227,397.119l0,-24.919l8.552,-26.577c59.868,-59.323 106.907,-114.847 115.221,-131.932l-10.215,3.56s9.5,-11.864 8.552,-18.51c-7.6,-116.273 -73.17,-176.862 -91.226,-191.732c26.607,31.955 19.326,42.4 19.326,42.4c-11.723,-21.833 -35.797,-43.032 -40.549,-48.409l-5.7,33.853c22.806,13.289 16.79,20.882 16.79,20.882c-5.387,-7.594 -19.957,-14.235 -19.957,-14.235l-1.586,9.491c6.973,3.165 38.327,22.149 38.565,70.872c0,59.323 -33.735,74.985 -39.674,77.357c-19.718,-11.865 -41.1,-11.627 -46.326,-12.1c-5.226,0.474 -26.608,0.236 -46.324,12.1c-5.941,-2.376 -39.676,-18.038 -39.676,-77.361c0.238,-48.723 31.6,-67.707 38.564,-70.872l-1.581,-9.487s-14.574,6.644 -19.955,14.238c0,0 -6.022,-7.593 16.786,-20.882l-5.702,-33.856c-4.752,5.378 -28.824,26.577 -40.543,48.407c0,0 -7.288,-10.443 19.32,-42.4c-18.054,14.87 -83.625,75.459 -91.226,191.732c-0.95,6.646 8.554,18.51 8.554,18.51l-10.217,-3.558c8.316,17.085 55.355,72.612 115.221,131.935l8.554,26.577l0,24.916l-7.6,-26.577l-17.345,-28.475l0,28.95c7.127,20.169 34.921,60.983 34.921,60.983l0,-84.475l-106.431,-116.037s66.52,54.1 85.526,73.56l9.978,-10.2c-12.355,-8.78 -66.045,-62.646 -70.8,-110.1c40.388,85.426 79.111,96.1 107.62,129.325l0,8.127l24.707,0l0,-8.131c28.508,-33.221 67.233,-43.9 107.619,-129.325c-4.75,47.459 -58.442,101.325 -70.8,110.1l9.976,10.2c19.006,-19.458 85.526,-73.56 85.526,-73.56l-106.423,116.041l0,84.475s27.8,-40.815 34.923,-60.984l0,-28.95l-17.343,28.475l-7.602,26.578zm-48.227,-102.036c-17.818,-11.865 -63.668,-39.629 -82.672,-83.053a314.117,314.117 0 0 0 34.447,34.882s-1.189,-30.61 1.186,-37.255c4.276,36.781 13.068,52.442 47.039,71.9c33.973,-19.458 42.763,-35.119 47.039,-71.9c2.375,6.645 1.188,37.255 1.188,37.255a314.117,314.117 0 0 0 34.447,-34.882c-19.006,43.424 -64.856,71.188 -82.674,83.053z" class="cls-1"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1,171 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 712 712"
|
||||
height="712"
|
||||
width="712"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path16"
|
||||
d="M 0,534 H 534 V 0 H 0 Z" /></clipPath></defs><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,0,712)"
|
||||
id="g10"><g
|
||||
id="g12"><g
|
||||
clip-path="url(#clipPath18)"
|
||||
id="g14"><g
|
||||
transform="translate(393.811,345.8316)"
|
||||
id="g20"><path
|
||||
id="path22"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 24.538,-48.679 35.693,-96.638 39.077,-128.853 3.409,2.889 6.518,5.987 9.318,9.295 C 44.008,-86.276 33.201,-45.41 13.482,-2.216 9.21,-1.054 4.714,-0.293 0,0" /></g><g
|
||||
transform="translate(474.0073,283.56)"
|
||||
id="g24"><path
|
||||
id="path26"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -2.746,20.364 -15.533,43.515 -36.693,60.311 0.831,-5.932 1.399,-11.795 1.735,-17.511 13.776,-14.605 22.245,-33.379 24.23,-48.275 4.005,-30.045 0.821,-64.541 -16.17,-93.955 -0.57,-8.119 -1.935,-15.947 -4.08,-23.411 C 0.994,-86.018 5.717,-42.414 0,0" /></g><g
|
||||
transform="translate(385.5994,134.225)"
|
||||
id="g28"><path
|
||||
id="path30"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 4.978,2.231 10.126,4.9 15.408,8.084 0.431,0.963 0.862,1.934 1.291,2.917 13.266,30.416 21.331,57.602 26.214,83.512 -1.261,8.494 -3.199,19.129 -6.164,31.354 C 33.096,92.579 25.043,59.43 8.133,18.154 5.496,11.715 2.793,5.672 0,0" /></g><g
|
||||
transform="translate(425.0383,307.4895)"
|
||||
id="g32"><path
|
||||
id="path34"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 3.757,-10.543 6.88,-20.55 9.476,-29.923 0.875,13.491 1.202,26.977 1.298,40.761 0.113,16.457 -1.829,35.048 -6.805,53.19 -4.505,3.565 -9.316,6.328 -14.259,8.445 C -2.33,50.589 0.215,26.875 0.073,6.612 0.058,4.391 0.033,2.189 0,0" /></g><g
|
||||
transform="translate(386.608,388.9227)"
|
||||
id="g36"><path
|
||||
id="path38"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 28.927,-1.359 56.121,-14.859 67.722,-50.801 1.163,-3.607 2.212,-7.125 3.152,-10.559 8.947,-11.458 15.298,-24.325 18.197,-37.212 -0.856,16.01 -4.261,34.252 -10.972,55.045 C 63.415,1.968 23.976,16.608 -13.505,19.408 -8.758,13.225 -4.247,6.745 0,0" /></g><g
|
||||
transform="translate(458.4243,221.6535)"
|
||||
id="g40"><path
|
||||
id="path42"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 3.127,14.302 3.772,27.883 3.416,39.047 -1.905,14.006 -15.995,-2.15 -31.262,-12.59 -32.789,-18.805 -34.49,-25.02 -36.37,-31.246 -23.389,-24.415 -10.119,-14.479 0,0" /></g><g
|
||||
transform="translate(444.3687,202.0113)"
|
||||
id="g44"><path
|
||||
id="path46"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -3.23,-2.766 -6.676,-5.371 -10.334,-7.809 -0.733,-41.782 -19.658,-69.771 -47.398,-84.823 -3.677,-5.665 -7.502,-10.841 -11.493,-15.546 41.029,14.834 69.423,50.013 69.423,99.046 C 0.198,-6.198 0.132,-3.151 0,0" /></g><g
|
||||
transform="translate(380.6335,369.7762)"
|
||||
id="g48"><path
|
||||
id="path50"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 5.226,-0.534 10.259,-1.404 15.092,-2.571 -0.889,1.692 -1.785,3.386 -2.702,5.082 -16.462,30.478 -37.594,55.26 -59.872,72.957 -3.747,0.455 -7.437,0.691 -11.034,0.691 -3.084,0 -6.086,-0.173 -9.012,-0.499 C -43.567,59.067 -19.689,32.831 0,0" /></g><g
|
||||
transform="translate(277.8203,439.6349)"
|
||||
id="g52"><path
|
||||
id="path54"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0.965,-0.781 1.902,-1.539 2.823,-2.285 16.915,10.338 37.922,14.465 62.771,9.042 28.083,-6.127 45.11,-20.81 57.944,-39.781 5.759,-1.525 11.199,-3.389 16.31,-5.591 C 126.46,-12.621 104.529,8.859 70.436,16.304 39.851,22.984 13.775,18.552 -7.75,5.74 -5.097,3.943 -2.508,2.031 0,0" /></g><g
|
||||
transform="translate(196.3198,437.5024)"
|
||||
id="g56"><path
|
||||
id="path58"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 4.283,-1.538 8.723,-3.338 13.331,-5.409 3.968,10.138 11.867,19.559 25.463,27.044 16.093,8.861 35.757,7.742 56.297,-1.356 5.767,1.684 11.725,2.851 17.868,3.497 C 85.335,39.045 57.854,43.048 36.898,33.259 18.38,24.608 6.825,12.856 0,0" /></g><g
|
||||
transform="translate(247.7137,105.3549)"
|
||||
id="g60"><path
|
||||
id="path62"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 6.127,1.673 11.893,3.458 17.327,5.333 4.444,12.581 -1.899,21.662 -3.581,31.408 c -0.604,3.504 -1.017,6.799 -0.093,10.712 0.924,3.914 6.739,8.375 9.302,5.407 2.8,-3.245 6.252,-6.183 9.475,-9.292 5.605,1.941 10.678,4.036 15.212,6.206 -3.849,6.266 -7.404,14.138 -6.947,20.42 0.458,6.281 3.075,10.52 8.603,12.187 11.415,3.442 21.999,2.374 25.566,-2.256 2.274,-2.952 2.84,-5.099 0.929,-12.432 C 56.556,55.027 28.877,37.837 -0.53,30.686 0.296,26.898 1.9,23.354 4.268,20.071 31.3,26.585 52.436,37.346 62.531,45.233 c 0,0 3.625,2.818 6.895,4.926 3.271,2.108 6.909,2.389 10.183,1.996 2.641,-0.469 5.128,-1.09 5.926,-3.136 0.424,-1.081 0.58,-2.506 0.793,-3.786 3.81,3.469 7.224,6.844 10.35,10.045 -0.094,0.709 -0.301,1.34 -0.592,3.327 -0.29,1.986 0.873,7.627 4.257,8.472 5.232,1.305 5.352,-2.019 4.758,-4.156 -0.324,-1.158 -2.535,-4.692 -4.491,-7.683 C 96.402,50.874 91.665,46.12 86.1,41.202 79.368,35.304 71.4,29.176 61.657,23.216 67.141,21.2 73.061,19.772 79.275,18.989 c 6.527,4.161 12.301,8.341 17.47,12.437 -0.006,0.015 -0.01,0.029 -0.015,0.045 15.64,12.39 32.343,29.791 34.477,31.837 2.133,2.048 4.192,3.572 9.673,6.772 5.481,3.198 8.032,3.11 12.757,5.157 2.108,6.12 4.032,12.142 5.782,18.099 -13.375,-4.56 -29.007,-6.117 -37.442,-2.982 -8.435,3.137 -9.809,6.612 -13.31,13.049 -6.778,12.464 -6.896,19.112 -13.912,22.317 -7.016,3.205 -22.831,5.462 -27.349,26.236 -4.519,20.774 -1.427,42.142 4.4,49.621 5.826,7.479 7.853,9.191 14.506,12.228 20.81,9.496 20.869,17.035 27.052,22.139 0.95,0.785 1.723,1.526 2.445,2.235 3.051,2.423 6.572,4.287 11.289,5.066 17.824,2.947 33.125,-0.539 45.766,-7.644 -0.524,4.921 -1.222,9.904 -2.118,14.903 -20.171,10.031 -45.318,14.571 -74.683,9.124 -8.344,-1.548 -13.881,-4.571 -21.833,-7.494 -7.954,-2.923 -17.15,1.224 -10.273,9.394 1.746,2.073 3.381,4.053 6.551,5.841 3.17,1.786 5.376,2.748 8.251,4.031 11.585,5.172 25.064,9.265 38.919,11.15 -5.214,7.342 -10.657,14.284 -16.279,20.766 -9.394,-0.39 -20.213,-1.851 -26.032,-2.44 -5.82,-0.589 -9.06,1.857 -12.536,3.822 -7.924,5.899 -18.154,14.12 -34.522,27.37 -11.615,9.402 -24.85,16.142 -38.12,19.963 -0.474,-0.24 -0.945,-0.486 -1.41,-0.743 -5.039,-2.774 -9.226,-5.808 -12.69,-9.025 14.703,-2.765 30.868,-9.573 44.139,-20.356 13.952,-11.337 18.206,-24.704 19.888,-36.34 0.168,-1.155 0.266,-1.815 0.311,-3.475 0.047,-1.659 -0.815,-3.004 -1.678,-3.707 -2.718,-2.211 -8.249,3.916 -13.274,6.929 -2.904,2.223 -5.982,4.456 -9.319,6.723 -3.764,2.558 -7.468,5.013 -11.113,7.371 -3.931,-6.369 -7.327,-13.324 -10.143,-20.75 3.692,-5.018 7.901,-11.893 9.644,-16.1 1.743,-4.206 1.807,-7.837 0.673,-10.29 -1.401,-3.03 -5.825,-9.296 -13.094,-7.378 -7.269,1.917 -6.375,9.465 -5.584,15.816 5.308,23.027 15.847,44.264 31.304,59.454 -3.615,2.885 -7.555,5.533 -11.704,7.903 -14.439,-12.917 -26.266,-30.211 -35.458,-50.71 -0.19,-0.422 -0.226,-0.513 -0.565,-1.268 -0.803,-1.788 -2.853,-1.544 -3.596,0.022 -0.282,0.594 -0.385,0.847 -0.574,1.275 -4.022,9.093 -6.995,19.365 -7.268,29.685 -5.63,3.508 -11.066,6.374 -16.297,8.602 -2.454,-10.066 -2.772,-20.285 -1.894,-29.82 0.158,-1.716 0.303,-2.252 0.534,-3.917 0.028,-0.267 0.402,-1.515 -0.223,-1.559 -0.349,-0.025 -1.27,1.562 -1.427,1.781 -1.017,1.66 -1.304,2.068 -2.525,3.581 -5.657,7.005 -13.679,12.164 -25.732,13.032 -10.722,0.773 -22.284,-0.972 -33.613,-5.296 -2.457,-4.819 -4.631,-10.233 -6.51,-16.211 10.888,5.567 22.052,7.726 31.726,6.586 25.225,-2.974 25.025,-18.049 24.213,-22.17 -0.49,-2.493 -2.607,-2.523 -4.95,-2.523 -2.478,0 -5.264,0.014 -7.874,0.032 -7.606,0.617 -15.399,0.53 -23.172,-0.401 -1.869,-4.868 -3.708,-9.939 -5.517,-15.209 16.143,1.05 29.297,-4.241 36.802,-6.503 21.998,-6.629 31.101,-15.861 39.409,-27.368 5.162,-12.231 7.725,-25.405 9.58,-34.362 2.854,-13.771 1.696,-21.754 -2.14,-27.304 -6.633,-9.598 -13.332,-27.17 -18.702,-30.879 -8.576,-5.921 -26.334,-7.643 -31.417,-12.986 -5.308,-5.578 -7.448,-9.838 -11.965,-11.274 -2.401,-0.765 -4.292,-1.24 -7.298,-1.902 -12.923,-2.85 -28.529,1.171 -42.374,11.419 0.076,-5.029 0.323,-9.919 0.744,-14.666 17.101,-12.923 35.852,-19.863 50.79,-19.313 1.187,0.044 1.919,0.102 3.485,0.275 2.069,0.226 3.367,-1.034 3.862,-2.492 0.496,-1.459 1.041,-2.852 1.607,-4.341 3.641,-9.571 8.553,-20.824 14.704,-32.399 6.483,-0.835 13.109,-1.292 19.835,-1.367 -6.27,17.703 -7.737,34.454 -3.319,43.508 1.211,2.483 3.294,4.888 4.982,5.574 1.69,0.684 3.057,1.633 7.932,1.99 4.875,0.356 10.428,-0.861 10.357,-3.487 -0.072,-2.627 -1.118,-4.924 -1.498,-6.722 C -35.786,37.896 -28.37,15.753 0,0" /></g><g
|
||||
transform="translate(345.0594,86.9108)"
|
||||
id="g64"><path
|
||||
id="path66"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 4.957,3.508 9.604,7.594 13.989,12.282 -4.084,8.229 -24.025,8.156 -44.19,11.921 c -4.428,0.826 -8.556,1.754 -12.399,2.773 -5.437,-2.183 -11.057,-4.241 -16.871,-6.18 8.45,-2.639 17.983,-4.917 28.679,-6.836 C -29.302,-1.096 -14.22,-1.59 0,0" /></g><g
|
||||
transform="translate(424.0582,155.6551)"
|
||||
id="g68"><path
|
||||
id="path70"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -3.333,-3.006 -6.899,-5.889 -10.721,-8.629 -23.418,-16.791 -47.229,-24.75 -68.498,-26.057 -0.971,-3.554 -2.151,-7.019 -3.538,-10.38 21.907,0.434 46.121,6.788 69.041,21.707 C -7.959,-16.431 -3.382,-8.632 0,0" /></g><g
|
||||
transform="translate(332.0492,98.9441)"
|
||||
id="g72"><path
|
||||
id="path74"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 6.576,10.274 10.671,21.912 12.373,34.232 8.62,31.327 4.554,28.382 0.121,25.429 -2.374,16.757 -6.639,8.164 -12.496,0.352 -9.009,0.108 -5.545,-0.017 -2.119,-0.017 -1.411,-0.017 -0.705,-0.011 0,0" /></g><g
|
||||
transform="translate(293.4784,133.4932)"
|
||||
id="g76"><path
|
||||
id="path78"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -1.02,0.698 -2.019,1.44 -2.995,2.217 -3.934,-1.832 -8.175,-3.623 -12.68,-5.326 2.128,-1.663 4.345,-3.298 6.683,-4.897 10.13,-6.931 23.823,-11.988 39.452,-13.986 1.715,3.24 3.152,6.525 4.318,9.818 C 21.313,-10.722 9.406,-6.434 0,0" /></g><g
|
||||
transform="translate(373.0792,112.3586)"
|
||||
id="g80"><path
|
||||
id="path82"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -17.337,-25.704 -38.736,-39.907 -68.98,-43.872 -7.734,-4.602 -16.59,-8.148 -27.68,-10.426 52.785,-1.992 86.015,15.599 111.917,59.48 C 10.021,3.046 4.915,1.346 0,0" /></g><g
|
||||
transform="translate(207.2643,116.8778)"
|
||||
id="g84"><path
|
||||
id="path86"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -0.838,-0.011 -1.675,-0.017 -2.51,-0.017 h -0.006 c -4.847,0 -9.642,0.188 -14.384,0.548 11.348,-17.77 25.585,-34.706 42.6,-45.874 6.415,-1.663 12.827,-2.52 19.16,-2.52 2.66,0 5.293,0.122 7.891,0.354 C 29.652,-42.081 11.377,-21.927 0,0" /></g><g
|
||||
transform="translate(225.2887,402.3531)"
|
||||
id="g88"><path
|
||||
id="path90"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C 2.856,4.852 5.877,9.429 9.057,13.724 -9.122,24.262 -25.618,31.778 -40.359,35.77 -43.291,33.619 -46.769,30.646 -50.677,26.393 -37.61,24.056 -22.788,17.057 -6.339,4.976 -4.139,3.36 -2.028,1.701 0,0" /></g><g
|
||||
transform="translate(153.844,407.1487)"
|
||||
id="g92"><path
|
||||
id="path94"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 0.586,0 1.172,-0.01 1.757,-0.024 15.837,27.113 28.961,34.536 34.736,37.816 2.637,1.498 5.828,2.582 9.427,3.257 0.096,0.128 0.189,0.257 0.285,0.384 3.462,4.529 7.526,8.693 12.156,12.478 -7.686,-0.075 -15,-1.294 -21.582,-3.718 C 27.323,46.71 9.311,35.291 -10.369,-0.704 -6.903,-0.239 -3.442,0 0,0" /></g><g
|
||||
transform="translate(110.5027,359.7524)"
|
||||
id="g96"><path
|
||||
id="path98"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 6.233,38.52 20.951,62.47 43.115,68.417 3.7,5.186 7.278,9.552 10.669,13.232 C 19.274,82.625 -2.578,56.901 -10.403,-5.079 -7.057,-3.186 -3.586,-1.493 0,0" /></g><g
|
||||
transform="translate(142.7769,130.788)"
|
||||
id="g100"><path
|
||||
id="path102"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c 6.02,-9.512 12.474,-18.353 19.267,-26.357 5.732,-2.097 11.846,-3.64 18.317,-4.625 -7.65,7.45 -15.05,16.112 -22.015,25.948 23.025,-6.224 45.696,-7.137 66.372,-5.01 C 79.408,-6.74 77.314,-3.221 75.652,0.533 53.659,-1.389 29.867,0.362 7.016,8.019 c -6.702,11.042 -12.871,23.29 -18.309,36.72 -4.76,1.763 -9.576,4.013 -14.349,6.705 5.008,-13.053 10.815,-25.558 17.267,-37.269 -4.59,2.155 -9.114,4.579 -13.548,7.298 -30.386,18.628 -45.7,47.92 -50.912,77.884 -4.917,8.92 -9.269,19.492 -11.863,31.644 C -86.618,88.432 -72.512,40.94 -28.732,14.102 -19.237,8.28 -9.621,3.637 0,0" /></g><g
|
||||
transform="translate(88.5718,224.2917)"
|
||||
id="g104"><path
|
||||
id="path106"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -11.332,15.213 -19.117,36.192 -19.117,62.341 0,37.856 12.897,64.906 29.809,81.738 1.148,6.561 2.496,12.714 4.041,18.436 -25.112,-18.504 -44.885,-51.876 -44.885,-101.002 0,-30.917 12.513,-57.099 29.663,-76.362 C -0.476,-10.007 -0.313,-5.056 0,0" /></g><g
|
||||
transform="translate(132.9481,385.021)"
|
||||
id="g108"><path
|
||||
id="path110"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -7.698,-17.341 -15.463,-38.736 -22.904,-65.126 -0.223,-11.817 0.107,-24.437 0.996,-37.732 0.021,-0.315 0.045,-0.626 0.066,-0.942 11.167,47.936 22.9,81.62 33.897,105.42 C 8.138,1.593 4.085,1.045 0,0" /></g><g
|
||||
transform="translate(80.9783,335.1565)"
|
||||
id="g112"><path
|
||||
id="path114"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -5.227,-12.952 -8.107,-27.538 -8.593,-43.587 5.086,19.742 14.002,35.727 24.537,43.499 6.063,4.47 12.004,7.641 17.74,9.824 1.715,5.241 3.468,10.334 5.256,15.261 C 28.354,21.684 18.126,16.53 8.81,9.171 5.747,6.751 2.792,3.66 0,0" /></g><g
|
||||
transform="translate(107.5541,165.6139)"
|
||||
id="g116"><path
|
||||
id="path118"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C -4.269,15.889 -6.1,34.231 -5.276,54.798 -8.364,67.6 -10.59,80.395 -11.941,93.107 -17.06,64.013 -17.85,38.438 -14.934,16.468 -10.781,10.732 -5.851,5.174 0,0" /></g><g
|
||||
transform="translate(305.6711,84.8346)"
|
||||
id="g120"><path
|
||||
id="path122"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -13.748,-11.22 -33.729,-18.651 -55.357,-18.651 -14.953,0 -31.093,5.166 -46.959,15.248 -1.537,-0.047 -3.066,-0.073 -4.581,-0.073 h -0.005 c -4.859,0 -9.596,0.238 -14.205,0.709 18.555,-15.209 38.58,-24.093 58.523,-24.093 39.332,0 53.602,7.14 75.98,25.488 C 8.953,-1.1 4.479,-0.641 0,0" /></g><g
|
||||
transform="translate(212.4133,84.8215)"
|
||||
id="g124"><path
|
||||
id="path126"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -3.35,3.361 -6.644,6.999 -9.876,10.909 -20.874,-0.646 -38.945,3.341 -53.773,11.661 -12.673,7.46 -22.973,18.151 -30.64,31.794 -1.872,1.057 -3.73,2.147 -5.572,3.277 -4.478,2.744 -8.708,5.733 -12.69,8.958 3.258,-9.117 7.365,-17.325 12.241,-24.613 h -0.046 C -79.294,10.472 -43.813,-3.836 0,0" /></g><g
|
||||
transform="translate(304.2728,112.9123)"
|
||||
id="g128"><path
|
||||
id="path130"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -0.277,0.089 -0.554,0.177 -0.829,0.269 -0.536,0.175 -1.068,0.354 -1.597,0.54 -0.153,0.053 -0.303,0.109 -0.456,0.163 -0.495,0.177 -0.991,0.354 -1.481,0.538 -0.132,0.049 -0.262,0.102 -0.395,0.152 -0.507,0.193 -1.013,0.387 -1.513,0.588 -0.111,0.045 -0.221,0.092 -0.331,0.136 -0.519,0.21 -1.035,0.423 -1.544,0.641 -0.097,0.041 -0.19,0.082 -0.285,0.125 -0.522,0.225 -1.041,0.454 -1.554,0.686 -0.087,0.04 -0.173,0.081 -0.26,0.122 -0.517,0.238 -1.029,0.477 -1.537,0.725 -0.088,0.042 -0.175,0.087 -0.264,0.13 -0.526,0.258 -1.048,0.518 -1.565,0.785 -14.874,-7.004 -32.975,-13.4 -55.354,-18.43 -4.137,-0.93 -8.191,-1.706 -12.166,-2.341 0.2,-0.244 0.401,-0.481 0.602,-0.722 -0.004,-10e-4 -0.006,-0.002 -0.01,-0.003 2.814,-3.38 5.746,-6.459 8.773,-9.22 0.008,0.001 0.016,0.003 0.024,0.005 0.016,-0.015 0.032,-0.03 0.047,-0.043 2.277,0.457 4.569,0.955 6.882,1.502 27.268,6.448 48.885,14.524 66.35,23.169 C 1.02,-0.327 0.51,-0.164 0,0" /></g><g
|
||||
transform="translate(98.6179,332.7756)"
|
||||
id="g132"><path
|
||||
id="path134"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -0.211,-0.155 -0.42,-0.322 -0.63,-0.484 -0.959,-14.52 -1.313,-30.63 -1.05,-48.42 0.373,-25.232 4.421,-50.661 11.294,-74.894 4.558,-3.189 9.331,-5.712 14.138,-7.502 C 16.559,-107.411 11.56,-80.535 9.573,-50.802 8.177,-29.897 8.153,-10.905 9.438,5.971 6.236,4.268 3.087,2.276 0,0" /></g></g></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 18 KiB |
115
public/js/app.js
vendored
115
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,21 +27,21 @@ $.when( $.ready ).then(function() {
|
||||
var timer = 5000;
|
||||
(function worker() {
|
||||
$.ajax({
|
||||
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() {
|
||||
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);
|
||||
}
|
||||
});
|
||||
})();
|
||||
})();
|
||||
});
|
||||
|
||||
}
|
||||
@@ -49,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');
|
||||
@@ -75,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(
|
||||
@@ -89,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');
|
||||
@@ -104,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 = $('#override_url');
|
||||
if(override_url.length && override_url.val() != '') {
|
||||
|
||||
var override_url = $('#create input[name="config[override_url]"]').val();
|
||||
if(override_url.length && override_url != '') {
|
||||
apiurl = override_url;
|
||||
}
|
||||
|
||||
var data = {};
|
||||
data['url'] = apiurl;
|
||||
$('input.config-item').each(function(index){
|
||||
$('.config-item').each(function(index){
|
||||
var config = $(this).data('config');
|
||||
data[config] = $(this).val();
|
||||
})
|
||||
});
|
||||
|
||||
$.post(
|
||||
'/test_config',
|
||||
{ data }, function(data) {
|
||||
alert(data);
|
||||
}
|
||||
);
|
||||
$.post('/test_config', { data: data }, function(data) {
|
||||
alert(data);
|
||||
});
|
||||
|
||||
});
|
||||
$('#pinlist').on('click', 'a', function(e) {
|
||||
@@ -160,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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user