Răsfoiți Sursa

Plex Media Search

causefx 8 ani în urmă
părinte
comite
fd3a1f6575

+ 5 - 1
api/config/default.php

@@ -134,5 +134,9 @@ return array(
     'calendarLimit' => '1000',
 	'customCss' => '',
     'customHTMLone' => '',
-    'customHTMLtwo' => ''
+    'customHTMLtwo' => '',
+	'mediaSearch' => false,
+	'mediaSearchType' => '',
+	'mediaSearchAuth' => '1'
+
 );

+ 9 - 1
api/functions/homepage-connect-functions.php

@@ -11,6 +11,9 @@ function homepageConnect($array){
         case 'getPlexMetadata':
             return plexConnect('metadata',$array['data']['key']);
             break;
+        case 'getPlexSearch':
+            return plexConnect('search',$array['data']['query']);
+            break;
         case 'getPlexPlaylists':
             return getPlexPlaylists();
             break;
@@ -425,6 +428,9 @@ function plexConnect($action,$key=null){
                 break;
 			case 'playlists':
                 $url = $url."/playlists?X-Plex-Token=".$GLOBALS['plexToken'];
+                break;
+			case 'search':
+                $url = $url."/search?query=".rawurlencode($key)."&X-Plex-Token=".$GLOBALS['plexToken'];
                 break;
             default:
                 # code...
@@ -438,7 +444,9 @@ function plexConnect($action,$key=null){
                 $items = array();
                 $plex = simplexml_load_string($response->body);
                 foreach($plex AS $child) {
-                    $items[] = resolvePlexItem($child);
+                    if($child['type'] != "artist" && $child['type'] != "episode" && isset($child['librarySectionID'])){
+                        $items[] = resolvePlexItem($child);
+                    }
                 }
                 $api['content'] = $items;
                 $api['plexID'] = $GLOBALS['plexID'];

+ 36 - 0
api/functions/homepage-functions.php

@@ -209,6 +209,20 @@ function buildHomepageItem($homepageItem){
 }
 function getHomepageList(){
     $groups = groupSelect();
+	$mediaServers = array(
+		array(
+			'name' => 'N/A',
+			'value' => ''
+		),
+		array(
+			'name' => 'Plex',
+			'value' => 'plex'
+		),
+		array(
+			'name' => 'Emby [Not Available]',
+			'value' => 'emby'
+		)
+	);
     $time = array(
         array(
             'name' => '5',
@@ -512,6 +526,28 @@ function getHomepageList(){
 						'value' => $GLOBALS['homepageRecentRefresh'],
 						'options' => $time
 					),
+                ),
+				'Media Search' => array(
+					array(
+            			'type' => 'switch',
+            			'name' => 'mediaSearch',
+            			'label' => 'Enable',
+            			'value' => $GLOBALS['mediaSearch']
+            		),
+                    array(
+    					'type' => 'select',
+    					'name' => 'mediaSearchAuth',
+                        'label' => 'Minimum Authorization',
+    					'value' => $GLOBALS['mediaSearchAuth'],
+    					'options' => $groups
+    				),
+					array(
+    					'type' => 'select',
+    					'name' => 'mediaSearchType',
+                        'label' => 'Media Server',
+    					'value' => $GLOBALS['mediaSearchType'],
+    					'options' => $mediaServers
+    				),
                 ),
 				'Playlists' => array(
 					array(

+ 15 - 1
api/functions/organizr-functions.php

@@ -1,5 +1,17 @@
 <?php
-
+function organizrSpecialSettings(){
+    return array(
+        'homepage' => array(
+            'search' => array(
+                'enabled' => (qualifyRequest($GLOBALS['mediaSearchAuth']) && $GLOBALS['mediaSearch'] == true && $GLOBALS['plexToken']) ? true : false,
+                'type' => $GLOBALS['mediaSearchType'],
+            ),
+            'ombi' => array(
+                'enabled' => (qualifyRequest($GLOBALS['homepageOmbiAuth']) && $GLOBALS['homepageOmbiEnabled'] == true && $GLOBALS['ssoOmbi']) ? true : false,
+            )
+        )
+    );
+}
 function wizardConfig($array){
     foreach ($array['data'] as $items) {
         foreach ($items as $key => $value) {
@@ -116,6 +128,8 @@ function editUser($array){
 }
 function logout(){
     coookie('delete','organizrToken');
+    coookie('delete','mpt');
+    coookie('delete','Auth');
     $GLOBALS['organizrUser'] = false;
     return true;
 }

+ 1 - 0
api/index.php

@@ -799,6 +799,7 @@ switch ($function) {
                     'myPlexAccessToken' => isset($_COOKIE['mpt']) ? $_COOKIE['mpt'] : false,
                     'id_token' => isset($_COOKIE['Auth']) ? $_COOKIE['Auth'] : false
                 );
+                $result['settings'] = organizrSpecialSettings();
                 break;
             default:
                 $result['status'] = 'error';

+ 0 - 2
api/pages/homepage.php

@@ -70,8 +70,6 @@ function($) {
     $.CalendarApp.init()
 }(window.jQuery);
 </script>
-<link href="plugins/bower_components/owl.carousel/owl.carousel.min.css" rel="stylesheet" type="text/css" />
-<link href="plugins/bower_components/owl.carousel/owl.theme.default.css" rel="stylesheet" type="text/css" />
 <div class="container-fluid p-t-10" id="homepage-items">
     '.buildHomepage().'
 </div>

+ 2 - 0
index.php

@@ -27,6 +27,8 @@
 	<link href="plugins/bower_components/custom-select/custom-select.css" rel="stylesheet" type="text/css" />
 	<link href="plugins/bower_components/bootstrap-select/bootstrap-select.min.css" rel="stylesheet" />
 	<link href="plugins/bower_components/multiselect/css/multi-select.css" rel="stylesheet" type="text/css" />
+	<link href="plugins/bower_components/owl.carousel/owl.carousel.min.css" rel="stylesheet" type="text/css" />
+	<link href="plugins/bower_components/owl.carousel/owl.theme.default.css" rel="stylesheet" type="text/css" />
 	<link id="style" href="css/dark.css?v=<?php echo $GLOBALS['installedVersion']; ?>" rel="stylesheet">
 	<link href="css/organizr.css?v=<?php echo $GLOBALS['installedVersion']; ?>" rel="stylesheet">
 	<?php echo pluginFiles('css'); ?>

+ 32 - 0
js/custom.js

@@ -389,6 +389,38 @@ $(document).on("click", ".show-login", function(e) {
 $(document).on("click", ".depenency-item", function(e) {
     alert($(this).attr('data-name'));
 });
+$(document).on("click", ".mediaSearchSubmit", function(e) {
+    var query = $('#mediaSearchQuery').val();
+    var server = $('#mediaSearchQuery').attr('data-server');
+    switch (server) {
+        case 'plex':
+            var action = 'getPlexSearch';
+            break;
+        case 'emby':
+            var action = 'getEmbySearch';
+            break;
+        default:
+    }
+    organizrAPI('POST','api/?v1/homepage/connect',{action:action, query:query}).success(function(data) {
+        var response = JSON.parse(data);
+        console.log(response.data);
+        $('.mediaSearch-div').html('');
+        var results = `
+        <div class="row el-element-overlay">
+
+
+                    `+buildMediaResults(response.data,server,query)+`
+
+
+        </div>
+        <div class="clearfix"></div>
+        `;
+        $('.mediaSearch-div').html(results);
+        $('.openResults').trigger('click');
+    }).fail(function(xhr) {
+        console.error("Organizr Function: API Connection Failed");
+    });
+});
 $(document).on("click", ".login-button", function(e) {
     e.preventDefault;
     $('div.login-box').block({

+ 121 - 9
js/functions.js

@@ -1452,10 +1452,9 @@ function submitTabOrder(){
 		messageBody:window.lang.translate('Tab Order Saved'),
 		error:'Organizr Function: API Connection Failed'
 	};
-	settingsAPI(post);
-	setTimeout(function(){
-		buildTabEditor();
-	}, 1000)
+	var callbacks = $.Callbacks();
+    callbacks.add( buildTabEditor );
+	settingsAPI(post,callbacks);
 }
 function submitCategoryOrder(){
 	var post = {
@@ -1466,10 +1465,9 @@ function submitCategoryOrder(){
 		messageBody:window.lang.translate('Category Order Saved'),
 		error:'Organizr Function: API Connection Failed'
 	};
-	settingsAPI(post);
-	setTimeout(function(){
-		buildCategoryEditor();
-	}, 1000)
+	var callbacks = $.Callbacks();
+    callbacks.add( buildCategoryEditor );
+	settingsAPI(post,callbacks);
 }
 function buildTR(array,type,badge){
 	var listing = '';
@@ -2440,7 +2438,7 @@ function buildRequest(array){
 		<button aria-expanded="false" data-toggle="dropdown" class="btn btn-info dropdown-toggle waves-effect waves-light" type="button">
 			<i class="fa fa-filter m-r-5"></i><span class="caret"></span>
 		</button>
-		<button href="#new-request" class="btn btn-info waves-effect waves-light inline-popups" data-effect="mfp-zoom-out"><i class="fa fa-plus m-l-5"></i></button>
+		<button href="#new-request" id="newRequestButton" class="btn btn-info waves-effect waves-light inline-popups" data-effect="mfp-zoom-out"><i class="fa fa-plus m-l-5"></i></button>
 		<div role="menu" class="dropdown-menu request-filter">
 			<div class="checkbox checkbox-success m-l-20 checkbox-circle">
 				<input id="request-filter-available" data-filter="request-available" class="filter-request-input" type="checkbox" checked="">
@@ -3531,6 +3529,118 @@ function changeAuth(){
     }
     if(type == 'internal') { $('.switchAuth').parent().parent().parent().hide(); }
 }
+function organizrSpecialSettings(array){
+	//media search
+	if(array.settings.homepage.search.enabled == true && typeof array.settings.homepage.search.type !== 'undefined'){
+		var htmlDOM = `
+		<li class="in">
+            <form id="mediaSearch" role="search" class="app-search hidden-sm hidden-xs m-r-10" onsubmit='return false;'>
+                <input id="mediaSearchQuery" data-server="`+array.settings.homepage.search.type+`" type="text" lang="en" placeholder="Search..." class="form-control" autocomplete="off"> <a class="mediaSearchSubmit" href="javascript:void(0);" type="submit"><i class="fa fa-search"></i></a>
+				<button class="btn btn-info btn-lg btn-block text-uppercase waves-effect waves-light mediaSearchSubmit hidden" type="submit">ok</button>
+			</form>
+        </li>
+		`;
+		var searchBoxResults = `
+		<a class="inline-popups hidden openResults" href="#mediaSearch-area" data-effect="mfp-zoom-out"></a>
+		<div id="mediaSearch-area" class="white-popup mfp-with-anim mfp-hide">
+			<div class="col-md-8 col-md-offset-2">
+				<div class="white-box m-b-0 mediaSearch-div"></div>
+			</div>
+		</div>
+		`;
+		$(htmlDOM).prependTo('.navbar-right');
+		$(searchBoxResults).appendTo($('.organizr-area'));
+	}
+}
+function forceSearch(term){
+    $.magnificPopup.close();
+    var tabName = $("li[data-url^='api/?v1/homepage/page']").find('span').html();
+    if($("li[data-url^='api/?v1/homepage/page']").find('i').hasClass('tabLoaded')){
+        console.log('yup');
+        if($("li[data-url^='api/?v1/homepage/page']").find('a').hasClass('active')){
+            setTimeout(
+                function(){
+                    $('#newRequestButton').trigger('click');
+                    $('#request-input').val(term);
+                    doneTyping();
+                },
+            1000);
+        }else{
+            tabActions('click',tabName,0);
+            setTimeout(
+                function(){
+
+
+                    $('#newRequestButton').trigger('click');
+                    $('#request-input').val(term);
+                    doneTyping();
+                },
+            1000);
+        }
+    }else{
+        tabActions('click',tabName,0);
+        setTimeout(
+            function(){
+
+
+                $('#newRequestButton').trigger('click');
+                $('#request-input').val(term);
+                doneTyping();
+            },
+        3000);
+    }
+}
+function buildMediaResults(array,source,term){
+    if(array.content.length == 0){
+		var none = '<h2 class="text-center" lang="en">No Results for:</h2><h3 class="text-center" lang="en">'+term+'</h3>';
+        none += (activeInfo.settings.homepage.ombi.enabled == true) ? `<button onclick="forceSearch('`+term+`')" class="btn btn-block btn-info" lang="en">Would you like to Request it?</button>` : '';
+        return none;
+	}
+    var results = '';
+    var tv = 0;
+    var movie = 0;
+    var music = 0;
+    var total = 0;
+	$.each(array.content, function(i,v) {
+
+        total = total + 1;
+        tv = (v.type == 'tv') ? tv + 1 : tv;
+        movie = (v.type == 'movie') ? movie + 1 : movie;
+        music = (v.type == 'music') ? music + 1 : music;
+        var bg = v.imageURL;
+        var top = v.title;
+        var bottom = v.metadata.originallyAvailableAt;
+        results += `
+        <div id="`+v.uid+`-metadata-div" class="white-popup mfp-with-anim mfp-hide">
+            <div class="col-md-8 col-md-offset-2 `+v.uid+`-metadata-info"></div>
+        </div>
+        <a class="inline-popups `+v.uid+` hidden" href="#`+v.uid+`-metadata-div" data-effect="mfp-zoom-out"></a>
+
+        <div class="col-lg-3 col-md-4 col-sm-6 col-xs-12 m-t-20 request-result-item request-result-`+v.type+` metadata-get mouse" data-source="`+source+`" data-key="`+v.metadataKey+`" data-uid="`+v.uid+`">
+            <div class="white-box m-b-10">
+                <div class="el-card-item p-b-0">
+                    <div class="el-card-avatar el-overlay-1 m-b-5"> <img class="lazyload resultImages" data-src="`+bg+`"></div>
+                    <div class="el-card-content bg-org">
+                        <h3 class="box-title elip">`+top+`</h3> <small>`+bottom+`</small>
+                        <br>
+                    </div>
+                </div>
+            </div>
+        </div>
+        `;
+
+    });
+
+    var buttons = `
+    <div class="button-box p-20 text-center p-b-0">
+        <button class="btn btn-inverse waves-effect waves-light filter-request-result" data-filter="request-result-all"><span>`+total+`</span> <i class="fa fa-th-large m-l-5 fa-fw"></i></button>
+        <button class="btn btn-primary waves-effect waves-light filter-request-result" data-filter="request-result-movie"><span>`+movie+`</span> <i class="fa fa-film m-l-5 fa-fw"></i></button>
+        <button class="btn btn-info waves-effect waves-light filter-request-result" data-filter="request-result-tv"><span>`+tv+`</span> <i class="fa fa-tv m-l-5 fa-fw"></i></button>
+        <button class="btn btn-info waves-effect waves-light filter-request-result" data-filter="request-result-music"><span>`+music+`</span> <i class="fa fa-music m-l-5 fa-fw"></i></button>
+    </div>
+    `;
+    return buttons+results;
+}
 function launch(){
 	organizrConnect('api/?v1/launch_organizr').success(function (data) {
 		var json = JSON.parse(data);
@@ -3553,6 +3663,7 @@ function launch(){
 			plugins:json.data.plugins,
 			branch:json.branch,
 			sso:json.sso,
+			settings:json.settings,
 			theme:json.theme,
 			style:json.style,
 			version:json.version
@@ -3579,6 +3690,7 @@ function launch(){
 				categoryProcess(json);
 				tabProcess(json);
 				accountManager(json);
+				organizrSpecialSettings(json);
 				break;
 			default:
 				console.error('Organizr Function: Action not set or defined');