mirror of
https://github.com/unraid/webgui.git
synced 2026-01-06 17:49:58 -06:00
@@ -19,6 +19,8 @@ Tag="trophy"
|
||||
|
||||
**Community Applications** Copyright © 2015-2023, Andrew Zawadzki
|
||||
|
||||
**GUI Search** Copyright © 2021-2023, Andrew Zawadzki
|
||||
|
||||
The Software comprising the Unraid webGui, which is all files within this repository **except** for
|
||||
files listed below, is licensed under GPL version 2.
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -266,3 +266,24 @@ div.icon-zip{background:url('../images/file-types.png') -32px -80px;width:16px;h
|
||||
.tooltipster-sidetip.tooltipster-left .tooltipster-box{border-right:3px solid #ff8c2f}
|
||||
.tooltipster-sidetip.tooltipster-right .tooltipster-box{border-left:3px solid #ff8c2f}
|
||||
.fileTree{background-color:#f2f2f2}
|
||||
#guiSearchBox:placeholder-shown {caret-color:transparent;}
|
||||
#guiSearchBox {position:fixed;top:55px;left:250px;}
|
||||
.guiSearchBoxResults {position:fixed !important;top:90px !important; left:250px !important;}
|
||||
.awesomplete [hidden] {display: none;}
|
||||
.awesomplete .visually-hidden {position: absolute;clip: rect(0, 0, 0, 0);}
|
||||
.awesomplete {display: inline-block;position: relative;color: red;}
|
||||
.awesomplete > input {display: block;}
|
||||
.awesomplete > ul {position: absolute;left: 0;z-index: 1;min-width: 100%;box-sizing: border-box;list-style: none;padding: 0;margin: 0;background: #fff;}
|
||||
.awesomplete > ul:empty {display: none;}
|
||||
.awesomplete > ul {border-radius: .3em;margin: .2em 0 0;background: hsla(0,0%,100%,.9);background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));border: 1px solid rgba(0,0,0,.3);box-shadow: .05em .2em .6em rgba(0,0,0,.2);text-shadow: none;}
|
||||
@supports (transform: scale(0)) {.awesomplete > ul {transition: .3s cubic-bezier(.4,.2,.5,1.4);transform-origin: 1.43em -.43em;}
|
||||
.awesomplete > ul[hidden],.awesomplete > ul:empty {opacity: 0;transform: scale(0);display: block;transition-timing-function: ease;}
|
||||
}
|
||||
/* Pointer */
|
||||
.awesomplete > ul:before {content: "";position: absolute;top: -.43em;left: 1em;width: 0; height: 0;padding: .4em;background: white;border: inherit;border-right: 0;border-bottom: 0;-webkit-transform: rotate(45deg);transform: rotate(45deg);}
|
||||
.awesomplete > ul > li {position: relative;padding: .2em .5em;cursor: pointer;}
|
||||
.awesomplete > ul > li:hover {background: hsl(200, 40%, 80%);color: black;}
|
||||
.awesomplete > ul > li[aria-selected="true"] {background: hsl(205, 40%, 40%);color: white;}
|
||||
.awesomplete mark {background: hsl(65, 100%, 50%);}
|
||||
.awesomplete li:hover mark {background: hsl(68, 100%, 41%);}
|
||||
.awesomplete li[aria-selected="true"] mark {background: hsl(86, 100%, 21%);color: inherit;}
|
||||
@@ -266,3 +266,23 @@ div.icon-zip{background:url('../images/file-types.png') -32px -80px;width:16px;h
|
||||
.tooltipster-sidetip.tooltipster-left .tooltipster-box{border-right:3px solid #ff8c2f}
|
||||
.tooltipster-sidetip.tooltipster-right .tooltipster-box{border-left:3px solid #ff8c2f}
|
||||
.fileTree{background-color:#f2f2f2}
|
||||
#guiSearchBox:placeholder-shown {caret-color:transparent;}
|
||||
.guiSearchBoxResults {width:450px;}
|
||||
.awesomplete [hidden] {display: none;}
|
||||
.awesomplete .visually-hidden {position: absolute;clip: rect(0, 0, 0, 0);}
|
||||
.awesomplete {display: inline-block;position: relative;color: red;}
|
||||
.awesomplete > input {display: block;}
|
||||
.awesomplete > ul {position: absolute;left: 0;z-index: 1;min-width: 100%;box-sizing: border-box;list-style: none;padding: 0;margin: 0;background: #fff;}
|
||||
.awesomplete > ul:empty {display: none;}
|
||||
.awesomplete > ul {border-radius: .3em;margin: .2em 0 0;background: hsla(0,0%,100%,.9);background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));border: 1px solid rgba(0,0,0,.3);box-shadow: .05em .2em .6em rgba(0,0,0,.2);text-shadow: none;}
|
||||
@supports (transform: scale(0)) {.awesomplete > ul {transition: .3s cubic-bezier(.4,.2,.5,1.4);transform-origin: 1.43em -.43em;}
|
||||
.awesomplete > ul[hidden],.awesomplete > ul:empty {opacity: 0;transform: scale(0);display: block;transition-timing-function: ease;}
|
||||
}
|
||||
/* Pointer */
|
||||
.awesomplete > ul:before {content: "";position: absolute;top: -.43em;left: 1em;width: 0; height: 0;padding: .4em;background: white;border: inherit;border-right: 0;border-bottom: 0;-webkit-transform: rotate(45deg);transform: rotate(45deg);}
|
||||
.awesomplete > ul > li {position: relative;padding: .2em .5em;cursor: pointer;}
|
||||
.awesomplete > ul > li:hover {background: hsl(200, 40%, 80%);color: black;}
|
||||
.awesomplete > ul > li[aria-selected="true"] {background: hsl(205, 40%, 40%);color: white;}
|
||||
.awesomplete mark {background: hsl(65, 100%, 50%);}
|
||||
.awesomplete li:hover mark {background: hsl(68, 100%, 41%);}
|
||||
.awesomplete li[aria-selected="true"] mark {background: hsl(86, 100%, 21%);color: inherit;}
|
||||
@@ -266,3 +266,24 @@ div.icon-zip{background:url('../images/file-types.png') -32px -80px;width:16px;h
|
||||
.tooltipster-sidetip.tooltipster-left .tooltipster-box{border-right:3px solid #ff8c2f}
|
||||
.tooltipster-sidetip.tooltipster-right .tooltipster-box{border-left:3px solid #ff8c2f}
|
||||
.fileTree{background-color:#f2f2f2}
|
||||
#guiSearchBox:placeholder-shown {caret-color:transparent;}
|
||||
#guiSearchBox {position:fixed;top:55px;left:250px;}
|
||||
.guiSearchBoxResults {position:fixed !important;top:90px !important; left:250px !important;}
|
||||
.awesomplete [hidden] {display: none;}
|
||||
.awesomplete .visually-hidden {position: absolute;clip: rect(0, 0, 0, 0);}
|
||||
.awesomplete {display: inline-block;position: relative;color: red;}
|
||||
.awesomplete > input {display: block;}
|
||||
.awesomplete > ul {position: absolute;left: 0;z-index: 1;min-width: 100%;box-sizing: border-box;list-style: none;padding: 0;margin: 0;background: #fff;}
|
||||
.awesomplete > ul:empty {display: none;}
|
||||
.awesomplete > ul {border-radius: .3em;margin: .2em 0 0;background: hsla(0,0%,100%,.9);background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));border: 1px solid rgba(0,0,0,.3);box-shadow: .05em .2em .6em rgba(0,0,0,.2);text-shadow: none;}
|
||||
@supports (transform: scale(0)) {.awesomplete > ul {transition: .3s cubic-bezier(.4,.2,.5,1.4);transform-origin: 1.43em -.43em;}
|
||||
.awesomplete > ul[hidden],.awesomplete > ul:empty {opacity: 0;transform: scale(0);display: block;transition-timing-function: ease;}
|
||||
}
|
||||
/* Pointer */
|
||||
.awesomplete > ul:before {content: "";position: absolute;top: -.43em;left: 1em;width: 0; height: 0;padding: .4em;background: white;border: inherit;border-right: 0;border-bottom: 0;-webkit-transform: rotate(45deg);transform: rotate(45deg);}
|
||||
.awesomplete > ul > li {position: relative;padding: .2em .5em;cursor: pointer;}
|
||||
.awesomplete > ul > li:hover {background: hsl(200, 40%, 80%);color: black;}
|
||||
.awesomplete > ul > li[aria-selected="true"] {background: hsl(205, 40%, 40%);color: white;}
|
||||
.awesomplete mark {background: hsl(65, 100%, 50%);}
|
||||
.awesomplete li:hover mark {background: hsl(68, 100%, 41%);}
|
||||
.awesomplete li[aria-selected="true"] mark {background: hsl(86, 100%, 21%);color: inherit;}
|
||||
@@ -266,3 +266,23 @@ div.icon-zip{background:url('../images/file-types.png') -32px -80px;width:16px;h
|
||||
.tooltipster-sidetip.tooltipster-left .tooltipster-box{border-right:3px solid #ff8c2f}
|
||||
.tooltipster-sidetip.tooltipster-right .tooltipster-box{border-left:3px solid #ff8c2f}
|
||||
.fileTree{background-color:#f2f2f2}
|
||||
#guiSearchBox:placeholder-shown {caret-color:transparent;}
|
||||
.guiSearchBoxResults {width:450px;}
|
||||
.awesomplete [hidden] {display: none;}
|
||||
.awesomplete .visually-hidden {position: absolute;clip: rect(0, 0, 0, 0);}
|
||||
.awesomplete {display: inline-block;position: relative;color: red;}
|
||||
.awesomplete > input {display: block;}
|
||||
.awesomplete > ul {position: absolute;left: 0;z-index: 1;min-width: 100%;box-sizing: border-box;list-style: none;padding: 0;margin: 0;background: #fff;}
|
||||
.awesomplete > ul:empty {display: none;}
|
||||
.awesomplete > ul {border-radius: .3em;margin: .2em 0 0;background: hsla(0,0%,100%,.9);background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8));border: 1px solid rgba(0,0,0,.3);box-shadow: .05em .2em .6em rgba(0,0,0,.2);text-shadow: none;}
|
||||
@supports (transform: scale(0)) {.awesomplete > ul {transition: .3s cubic-bezier(.4,.2,.5,1.4);transform-origin: 1.43em -.43em;}
|
||||
.awesomplete > ul[hidden],.awesomplete > ul:empty {opacity: 0;transform: scale(0);display: block;transition-timing-function: ease;}
|
||||
}
|
||||
/* Pointer */
|
||||
.awesomplete > ul:before {content: "";position: absolute;top: -.43em;left: 1em;width: 0; height: 0;padding: .4em;background: white;border: inherit;border-right: 0;border-bottom: 0;-webkit-transform: rotate(45deg);transform: rotate(45deg);}
|
||||
.awesomplete > ul > li {position: relative;padding: .2em .5em;cursor: pointer;}
|
||||
.awesomplete > ul > li:hover {background: hsl(200, 40%, 80%);color: black;}
|
||||
.awesomplete > ul > li[aria-selected="true"] {background: hsl(205, 40%, 40%);color: white;}
|
||||
.awesomplete mark {background: hsl(65, 100%, 50%);}
|
||||
.awesomplete li:hover mark {background: hsl(68, 100%, 41%);}
|
||||
.awesomplete li[aria-selected="true"] mark {background: hsl(86, 100%, 21%);color: inherit;}
|
||||
147
emhttp/plugins/gui.search/exec.php
Executable file
147
emhttp/plugins/gui.search/exec.php
Executable file
@@ -0,0 +1,147 @@
|
||||
<?
|
||||
###################################################
|
||||
# #
|
||||
# GUI Search copyright 2021-2023, Andrew Zawadzki #
|
||||
# Licenced under GPLv2 #
|
||||
# #
|
||||
###################################################
|
||||
@mkdir("/tmp/gui.search");
|
||||
|
||||
extract(@parse_ini_file("/boot/config/plugins/dynamix/dynamix.cfg") ?: []);
|
||||
$locale = $locale ?? "";
|
||||
if ( $locale == "en_US")
|
||||
$locale = "";
|
||||
|
||||
if ( $locale != @file_get_contents("/tmp/gui.search/locale") ) {
|
||||
@unlink("/tmp/gui.search/searchResults.json");
|
||||
}
|
||||
|
||||
file_put_contents("/tmp/gui.search/locale",$locale);
|
||||
|
||||
$uri = "";
|
||||
if ( $locale ) {
|
||||
if ( is_dir("/usr/local/emhttp/languages/$locale") ) {
|
||||
$dotFiles = glob("/usr/local/emhttp/languages/$locale/*.txt");
|
||||
foreach ($dotFiles as $dot) {
|
||||
$uri .= basename($dot,".txt")."/";
|
||||
}
|
||||
$uri = rtrim($uri,"/");
|
||||
}
|
||||
}
|
||||
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: "/usr/local/emhttp";
|
||||
|
||||
$_SERVER['REQUEST_URI'] = $uri;
|
||||
$_SESSION['locale'] = $locale;
|
||||
require_once "$docroot/plugins/dynamix/include/Translations.php";
|
||||
|
||||
$searchPages = array();
|
||||
$pageFiles = glob("/usr/local/emhttp/plugins/*/*.page");
|
||||
if ( is_file("/tmp/gui.search/searchResults.json") ) {
|
||||
$searchPages = unserialize(file_get_contents("/tmp/gui.search/searchResults.json"));
|
||||
}
|
||||
if ( ! $searchPages ) {
|
||||
$MainPages = array("About","WebGui","UNRAID-OS","SystemInformation","OtherSettings","Settings","NetworkServices","Utilities","DiskUtilities","UserPreferences","WGX");
|
||||
// pass 1 - get all the "main" pages
|
||||
foreach ($pageFiles as $page) {
|
||||
if ( $page == "/usr/local/emhttp/plugins/dynamix/WGX.page") continue;
|
||||
$file = explode("---",file_get_contents($page));
|
||||
$pageInfo = parse_ini_string($file[0],true);
|
||||
|
||||
if ( isset($pageInfo['Menu']) && $pageInfo['Menu'] && in_array(explode(":",$pageInfo['Menu'])[0],$MainPages) && ! in_array(basename($page,".page"),$MainPages) ) {
|
||||
$newPage[basename($page,".page")] = array(sanitizeQuote(_($pageInfo['Title'])),basename($page));
|
||||
if ( $locale )
|
||||
$newPage[basename($page,".page")] = array(sanitizeQuote($pageInfo['Title']),basename($page));
|
||||
}
|
||||
}
|
||||
|
||||
//pass 2 - link back any sub-pages
|
||||
foreach ($pageFiles as $page) {
|
||||
$file = explode("---",file_get_contents($page));
|
||||
if ( ! isset($file[1]) ) continue;
|
||||
$pageInfo = parse_ini_string($file[0],true);
|
||||
|
||||
if (isset($pageInfo['Menu']) && $pageInfo['Menu']) {
|
||||
$pageLinked = explode(":",$pageInfo['Menu'])[0];
|
||||
if (isset($newPage[$pageLinked]) && ! in_array($pageLinked,$MainPages) ) {
|
||||
$newPage[] = array(sanitizeQuote(_($pageInfo['Title']))." ("._($newPage[$pageLinked][0]).")",$pageLinked);
|
||||
if ( $locale )
|
||||
$newPage[] = array(sanitizeQuote(($pageInfo['Title']))." (".($newPage[$pageLinked][0]).")",$pageLinked);
|
||||
|
||||
}
|
||||
getSettings();
|
||||
}
|
||||
}
|
||||
//pass 3 - cleanup
|
||||
foreach ($newPage as $page) {
|
||||
if ( ! in_array(array("label"=>sanitizeQuote(_($page[0])),"value"=>basename($page[1],".page")),$searchPages) )
|
||||
$searchPages[] = array("label"=>sanitizeQuote(_($page[0])),"value"=>basename($page[1],".page"));
|
||||
}
|
||||
file_put_contents("/tmp/gui.search/searchResults.json",serialize($searchPages));
|
||||
}
|
||||
echo json_encode($searchPages);
|
||||
|
||||
function getSettings() {
|
||||
global $searchPages, $pageInfo, $page,$file,$locale;
|
||||
|
||||
$bannedPages = array("ShareEdit","UserEdit","Device","community.applications","Selftest","DeviceInfo","EthX","CA_Notices","SecuritySMB","SecurityNFS");
|
||||
if (in_array(basename($page,".page"),$bannedPages) ) return;
|
||||
foreach (explode("\n",$file[1]) as $line) {
|
||||
$line = trim($line);
|
||||
if ( startsWith($line,"_(") && (endsWith($line,")_:") || endsWith($line,")_):") ) ) {
|
||||
preg_match("/<!--search:.*-->/i",$line,$extra,PREG_OFFSET_CAPTURE);
|
||||
$string = str_replace(["_(",")_:",")_?",")_"],["","","",""],$line);
|
||||
|
||||
$extraEng = "";
|
||||
$extraTra = "";
|
||||
if ( $extra ) {
|
||||
$extrasearch = trim(str_replace(["<!--search:","-->"],["",""],$extra[0][0]));
|
||||
$string = str_replace($extra[0][0],"",$string);
|
||||
foreach ( explode("|",$extrasearch) as $term ) {
|
||||
$extraEng .= $term."|";
|
||||
$extraTra .= _($term)."|";
|
||||
}
|
||||
$extraEng = " [".rtrim($extraEng,"|")."]";
|
||||
$extraTra = " [".rtrim($extraTra,"|")."]";
|
||||
}
|
||||
$string = sanitizeQuote($string);
|
||||
|
||||
$linkPage = basename($page,".page");
|
||||
if (strpos($linkPage,"WG") === 0) {
|
||||
$linkPage = "VPNmanager";
|
||||
}
|
||||
if ( stripos(str_replace(" ","",$line),"<!--donotindex-->") )
|
||||
continue;
|
||||
if ( ! in_array(array("label"=>"$string $extraTra (".sanitizeQuote($pageInfo['Title']).")","value"=>"$linkPage**"._($string)),$searchPages) ) {
|
||||
$searchPages[] = array("label"=>_($string)." $extraTra (".sanitizeQuote(_($pageInfo['Title'])).")","value"=>"$linkPage**"._($string));
|
||||
if ( $locale ) {
|
||||
if ( _($string) !== $string )
|
||||
$searchPages[] = array("label"=>($string)." $extraEng (".sanitizeQuote($pageInfo['Title']).")","value"=>"$linkPage**"._($string));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeQuote($string) {
|
||||
return str_replace("'","",str_replace('"',"",$string));
|
||||
}
|
||||
|
||||
##############################################
|
||||
# Determine if $haystack begins with $needle #
|
||||
##############################################
|
||||
function startsWith($haystack, $needle) {
|
||||
if ( !is_string($haystack) || ! is_string($needle) ) return false;
|
||||
return $needle === "" || strripos($haystack, $needle, -strlen($haystack)) !== FALSE;
|
||||
}
|
||||
#############################################
|
||||
# Determine if $string ends with $endstring #
|
||||
#############################################
|
||||
function endsWith($string, $endString) {
|
||||
$len = strlen($endString);
|
||||
if ($len == 0) {
|
||||
return true;
|
||||
}
|
||||
return (substr($string, -$len) === $endString);
|
||||
}
|
||||
?>
|
||||
180
emhttp/plugins/gui.search/gui_search.page
Executable file
180
emhttp/plugins/gui.search/gui_search.page
Executable file
File diff suppressed because one or more lines are too long
2
emhttp/plugins/gui.search/gui_search_post_hook.sh
Executable file
2
emhttp/plugins/gui.search/gui_search_post_hook.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
rm -rf /tmp/gui.search
|
||||
@@ -67,7 +67,7 @@ rm -f /boot/plugins/unRAIDServer.plg
|
||||
rm -f $CONFIG/plugins/unRAIDServer.plg
|
||||
|
||||
# These plugins are now integrated in the OS or obsolete and may interfere
|
||||
Obsolete="vfio.pci dynamix.wireguard dynamix.ssd.trim"
|
||||
Obsolete="vfio.pci dynamix.wireguard dynamix.ssd.trim gui.search"
|
||||
for Plugin in $Obsolete ; do
|
||||
if [[ -e $CONFIG/plugins/$Plugin.plg ]]; then
|
||||
logger "moving obsolete plugin $Plugin.plg to $CONFIG/plugins-error"
|
||||
|
||||
Reference in New Issue
Block a user