diff --git a/app/Http/Controllers/MetaGerSearch.php b/app/Http/Controllers/MetaGerSearch.php index b3582ba71adf62abdba08d9d3b2891b172fd9ca9..6f853d4a98753b73d60bd887aa71d5f58774c4e6 100644 --- a/app/Http/Controllers/MetaGerSearch.php +++ b/app/Http/Controllers/MetaGerSearch.php @@ -11,6 +11,7 @@ class MetaGerSearch extends Controller { public function search(Request $request, MetaGer $metager) { + $focus = $request->input("focus", "web"); if ($focus === "maps") { @@ -31,9 +32,16 @@ class MetaGerSearch extends Controller # Nach Spezialsuchen überprüfen: $metager->checkSpecialSearches($request); - # Alle Suchmaschinen erstellen + # Die Quicktips als Job erstellen + $quicktips = $metager->createQuicktips(); + + # Suche für alle zu verwendenden Suchmaschinen als Job erstellen, + # auf Ergebnisse warten und die Ergebnisse laden $metager->createSearchEngines($request); + # Versuchen die Ergebnisse der Quicktips zu laden + $quicktipResults = $quicktips->loadResults(); + # Alle Ergebnisse vor der Zusammenführung ranken: $metager->rankAll(); @@ -41,7 +49,7 @@ class MetaGerSearch extends Controller $metager->prepareResults(); # Die Ausgabe erstellen: - return $metager->createView(); + return $metager->createView($quicktipResults); } public function botProtection($redirect) diff --git a/app/Jobs/Searcher.php b/app/Jobs/Searcher.php index 2d7a48b3c8425628cba02c3a0983df0873076e5e..bd33d47bccd5324b94093b5191da4ea8d1ca490e 100644 --- a/app/Jobs/Searcher.php +++ b/app/Jobs/Searcher.php @@ -68,13 +68,14 @@ class Searcher implements ShouldQueue $mission = $mission[1]; $poptime = microtime(true) - $time; - // The mission is a String which can be divided to retrieve two informations: + // The mission is a String which can be divided to retrieve three informations: // 1. The Hash Value where the result should be stored // 2. The Url to Retrieve - // These two informations are divided by a ";" in the mission string + // 3. The maximum time to take + // These three informations are divided by a ";" in the mission string $mission = explode(";", $mission); - $hashValue = $mission[0]; - $url = base64_decode($mission[1]); + $hashValue = $mission[0]; // The hash value for redis to store the results under + $url = base64_decode($mission[1]); // The url to fetch $timeout = $mission[2]; // Timeout from the MetaGer process in ms $medianFetchTime = $this->getFetchTime(); // The median Fetch time of the search engine in ms Redis::hset('search.' . $hashValue, $this->name, "connected"); diff --git a/app/MetaGer.php b/app/MetaGer.php index b860bf7b62872eb9a080f7240b38eeb2c4501cb3..377e87ad95d31094ce1840e396727c865fe3c776 100644 --- a/app/MetaGer.php +++ b/app/MetaGer.php @@ -88,7 +88,7 @@ class MetaGer } # Erstellt aus den gesammelten Ergebnissen den View - public function createView() + public function createView($quicktipResults = NULL) { $viewResults = []; # Wir extrahieren alle notwendigen Variablen und geben Sie an unseren View: @@ -184,7 +184,8 @@ class MetaGer ->with('errors', $this->errors) ->with('apiAuthorized', $this->apiAuthorized) ->with('metager', $this) - ->with('browser', (new Agent())->browser()); + ->with('browser', (new Agent())->browser()) + ->with('quicktips', $quicktipResults); break; } } @@ -468,6 +469,12 @@ class MetaGer } } + public function createQuicktips() { + # Die quicktips werden als job erstellt und zur Abarbeitung freigegeben + $quicktips = new \App\Models\Quicktips\Quicktips($this->q, $this->lang, $this->getTime(), $this->getHashCode()); + return $quicktips; + } + /* * Die Erstellung der Suchmaschinen bis die Ergebnisse da sind mit Unterfunktionen */ @@ -570,8 +577,6 @@ class MetaGer foreach ($engines as $engine) { $engine->startSearch($this); } - // Derzeit deaktiviert, da es die eigene Suche gibt - // $this->adjustFocus($sumas, $enabledSearchengines); /* Wir warten auf die Antwort der Suchmaschinen * Die Verbindung steht zu diesem Zeitpunkt und auch unsere Requests wurden schon gesendet. diff --git a/app/Models/Quicktips/Quicktip.php b/app/Models/Quicktips/Quicktip.php new file mode 100644 index 0000000000000000000000000000000000000000..d2e8160fca84b381a3527333689cee0466b9dd50 --- /dev/null +++ b/app/Models/Quicktips/Quicktip.php @@ -0,0 +1,22 @@ +<?php + +namespace App\Models\Quicktips; + +class Quicktip +{ + public $type; + public $title; + public $link; + public $descr; + public $details; + + # Erstellt ein neues Ergebnis + public function __construct($type, $title, $link, $descr, $details) + { + $this->type = $type; + $this->title = $title; + $this->link = $link; + $this->descr = $descr; + $this->details = $details; + } +} diff --git a/app/Models/Quicktips/Quicktip_detail.php b/app/Models/Quicktips/Quicktip_detail.php new file mode 100644 index 0000000000000000000000000000000000000000..aec1150df3204a1cf978165a45277fb33c8bb4ae --- /dev/null +++ b/app/Models/Quicktips/Quicktip_detail.php @@ -0,0 +1,17 @@ +<?php + +namespace App\Models\Quicktips; + +class Quicktip_detail +{ + public $title; + public $link; + public $descr; + + public function __construct($title, $link, $descr) + { + $this->title = $title; + $this->link = $link; + $this->descr = $descr; + } +} diff --git a/app/Models/Quicktips/Quicktips.php b/app/Models/Quicktips/Quicktips.php new file mode 100644 index 0000000000000000000000000000000000000000..ef06935bc23cb7597d6a1e6f4bed2797656b36d0 --- /dev/null +++ b/app/Models/Quicktips/Quicktips.php @@ -0,0 +1,154 @@ +<?php + +namespace App\Models\Quicktips; + +use App\Jobs\Searcher; +use Cache; +use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Support\Facades\Redis; +use Log; + +class Quicktips +{ + use DispatchesJobs; + + const QUICKTIP_URL = "https://quicktips.metager3.de/quicktips.xml"; + const QUICKTIP_NAME = "quicktips"; + const CACHE_DURATION = 60; + + private $hash; + + public function __construct($search, $locale, $max_time) + { + $this->startSearch($search, $locale, $max_time); + } + + public function startSearch($search, $locale, $max_time) + { + $url = self::QUICKTIP_URL . "?search=" . $search . "&locale=" . $locale; + + $hash = md5($url); + + # TODO anders weitergeben + $this->hash = $hash; + + # TODO cache wieder einbauen (eventuell) + if ( /*!Cache::has($hash)*/true) { + Redis::hset("search." . $hash, self::QUICKTIP_NAME, "waiting"); + + // Queue this search + $mission = $hash . ";" . base64_encode($url) . ";" . $max_time; + Redis::rpush(self::QUICKTIP_NAME . ".queue", $mission); + + // Check the current status of Searchers for QUICKTIP_NAME + $needSearcher = false; + $searcherData = Redis::hgetall(self::QUICKTIP_NAME . ".stats"); + + // Create additional Searchers for QUICKTIP_NAME if necessary + if (sizeof($searcherData) === 0) { + $needSearcher = true; + } else { + $median = 0; + foreach ($searcherData as $pid => $data) { + $data = explode(";", $data); + $median += floatval($data[1]); + } + $median /= sizeof($searcherData); + if ($median < .1) { + $needSearcher = true; + } + } + if ($needSearcher && Redis::get(self::QUICKTIP_NAME) !== "locked") { + Redis::set(self::QUICKTIP_NAME, "locked"); + $this->dispatch(new Searcher(self::QUICKTIP_NAME)); + } + } + } + + public function loadResults() + { + $resultsRaw = $this->retrieveResults($this->hash); + $results = $this->parseResults($resultsRaw); + return $results; + } + + public function retrieveResults($hash) + { + $body = ""; + #if (Cache::has($hash)) { + $body = Cache::get($hash); + #} elseif (Redis::hexists('search.' . $hash, self::QUICKTIP_NAME)) { + $body = Redis::hget('search.' . $hash, self::QUICKTIP_NAME); + Redis::hdel('search.' . $hash, self::QUICKTIP_NAME); + Cache::put($hash, $body, self::CACHE_DURATION); + #} + if ($body !== "") { + return $body; + } else { + return false; + } + } + + public function parseResults($quicktips_raw) + { + $quicktips_raw = preg_replace("/\r\n/si", "", $quicktips_raw); + try { + $content = simplexml_load_string($quicktips_raw); + if (!$content) { + return; + } + + $content->registerXPathNamespace('main', 'http://www.w3.org/2005/Atom'); + + $quicktips = []; + + $quicktips_xpath = $content->xpath('main:entry'); + foreach ($quicktips_xpath as $quicktip_xml) { + // Title + $title = $quicktip_xml->title->__toString(); + + // Link + $link = $quicktip_xml->link['href']->__toString(); + + // Type + $quicktip_xml->registerXPathNamespace('mg', 'http://metager.de/opensearch/quicktips/'); + $types = $quicktip_xml->xpath('mg:type'); + if (sizeof($types) > 0) { + $type = $types[0]->__toString(); + } else { + $type = ""; + } + + // Description + $descr = $quicktip_xml->content->__toString(); + + // Details + $details = []; + $details_xpath = $quicktip_xml->xpath('mg:details'); + if (sizeof($details_xpath) > 0) { + foreach ($details_xpath[0] as $detail_xml) { + $details_title = $detail_xml->title->__toString(); + $details_link = $detail_xml->url->__toString(); + $details_descr = $detail_xml->text->__toString(); + $details[] = new \App\Models\Quicktips\Quicktip_detail( + $details_title, + $details_link, + $details_descr + ); + } + } + $quicktips[] = new \App\Models\Quicktips\Quicktip( + $type, + $title, + $link, + $descr, + $details + ); + } + return $quicktips; + } catch (\Exception $e) { + Log::error("A problem occurred parsing quicktips"); + return []; + } + } +} diff --git a/app/Models/Searchengine.php b/app/Models/Searchengine.php index 0dd3b76bfa7621203aa5e01f3ef3d34629642bfe..c54d53eaa35979edabe8988458a5f0fe0f174a99 100644 --- a/app/Models/Searchengine.php +++ b/app/Models/Searchengine.php @@ -219,7 +219,6 @@ abstract class Searchengine { $number = Redis::hget('search.' . $this->hash, $this->name); if ($number === null) { - die("test"); return null; } else { return pfsockopen($this->getHost() . ":" . $this->port . "/$number", $this->port, $errstr, $errno, 1); diff --git a/gulpfile.js b/gulpfile.js index 4de54a12ea310d12ec51c9967c9ec874e9dd0b20..1679a9b683ed77645d611e2656d403ce9d4d67c0 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -17,7 +17,7 @@ elixir(function (mix) { // js mix.scripts(['lib/jquery.js', 'lib/jquery-ui.min.js', 'lib/bootstrap.js', 'lib/lightslider.js', 'lib/masonry.js', 'lib/imagesloaded.js', 'lib/openpgp.min.js', 'lib/iframeResizer.min.js', 'lib/md5.js'], 'public/js/lib.js') mix.scripts(['scriptStartPage.js', 'result-saver.js'], 'public/js/scriptStartPage.js'); - mix.scripts(['scriptResultPage.js', 'result-saver.js', 'quicktips.js'], 'public/js/scriptResultPage.js'); + mix.scripts(['scriptResultPage.js', 'result-saver.js'], 'public/js/scriptResultPage.js'); mix.scripts(['searchbar.js', 'focus-creator.js'], 'public/js/searchbar.js'); // utility mix.scripts(['utility.js'], 'public/js/utility.js'); diff --git a/resources/assets/js/focus-creator.js b/resources/assets/js/focus-creator.js index b1989859c8e947279bd81d160f9dcdb820b05205..fd1b06725298a30def137f0bb2fa5a0c229b2b04 100644 --- a/resources/assets/js/focus-creator.js +++ b/resources/assets/js/focus-creator.js @@ -322,9 +322,7 @@ function loadFocusForSearch (focus) { var url ="/meta/meta.ger3?eingabe=x&focus="; - console.log(focus, url); - - clearCustomSearch(); + //clearCustomSearch(); for (var key in focus) { if (key.startsWith('engine_') && focus[key] == 'on') { addSumaToCustomSearch(key); diff --git a/resources/assets/js/scriptResultPage.js b/resources/assets/js/scriptResultPage.js index 5e7aabff7d88e087bfc55ced202aacd7225f638b..80259672b05d4cf65e90437f386388f872635e73 100644 --- a/resources/assets/js/scriptResultPage.js +++ b/resources/assets/js/scriptResultPage.js @@ -15,7 +15,7 @@ $(document).ready(function () { } var search = getMetaTag('q') || ''; var locale = getMetaTag('l') || 'de'; - loadQuicktips(search, locale, sprueche); // load the quicktips + //loadQuicktips(search, locale, sprueche); // load the quicktips }); /* diff --git a/resources/assets/less/metager/quicktips.less b/resources/assets/less/metager/quicktips.less index 5fcc75995f0e896404c2c11bc557812bf78c895b..a6fd9bb439399680c8c43f32ac8f632ce693d646 100644 --- a/resources/assets/less/metager/quicktips.less +++ b/resources/assets/less/metager/quicktips.less @@ -57,6 +57,7 @@ font-size: 15px; } &[type=spruch] { + order: 0; border-left: 3px solid #070; p { color: #070; @@ -69,7 +70,35 @@ } } } + &[type=duckDuckGo-bang] { + order: 1; + .bang-btn { + width: 100%; + margin-top: 5px; + color: #fff; + background-color: #286992; + font-size: 16px; + } + } + &[type=wikipedia] { + order: 2; + } + &[type=dictCC] { + order: 3; + .quicktip-summary { + p { + font-weight: bold; + } + } + } + &[type=tip] { + order: 4; + } + &[type=ad] { + order: 5; + } &[type=spendenaufruf] { + order: 6; border: none; color: #ff8000; background-color: inherit; @@ -90,21 +119,5 @@ } } } - &[type=dictCC] { - .quicktip-summary { - p { - font-weight: bold; - } - } - } - &[type=duckDuckGo-bang] { - .bang-btn { - width: 100%; - margin-top: 5px; - color: #fff; - background-color: #286992; - font-size: 16px; - } - } } } \ No newline at end of file diff --git a/resources/views/layouts/researchandtabs.blade.php b/resources/views/layouts/researchandtabs.blade.php index 2ddbec1a7eb59b8cf53d401bf18661cbd784c0d5..a0a888404b19efd330df8fa803bda10267871d16 100644 --- a/resources/views/layouts/researchandtabs.blade.php +++ b/resources/views/layouts/researchandtabs.blade.php @@ -49,7 +49,9 @@ @endforeach </div> @if( $metager->showQuicktips() ) - <div id="quicktips"></div> + <div id="quicktips"> + @include('quicktips', ['quicktips', $quicktips]) + </div> @endif </div> </div> diff --git a/resources/views/parts/quicktip.blade.php b/resources/views/parts/quicktip.blade.php new file mode 100644 index 0000000000000000000000000000000000000000..2841b77128e5b5172071ccd2eeb00e0a914027cf --- /dev/null +++ b/resources/views/parts/quicktip.blade.php @@ -0,0 +1,41 @@ +@if (sizeof($quicktip->details) > 0) + <details> + <summary class="quicktip-summary"> + @if ($quicktip->title != "") + <h1> + @if ($quicktip->link != "") + <a href="{{ $quicktip->link }}">{{ $quicktip->title }}</a> + @else + {{ $quicktip->title }} + @endif + </h1> + @endif + <p>{!! $quicktip->descr !!}</p> + </summary> + @foreach ($quicktip->details as $detail) + <div class="quicktip-detail"> + <h2> + @if (isset($detail->link)) + <a href="{{ $detail->link }}">{{ $detail->title }}</a> + @else + {{ $detail->title }} + @endif + </h2> + <p>{!! $detail->descr !!}</p> + </div> + @endforeach + </details> +@else + <div class="quicktip-summary"> + @if ($quicktip->title != "") + <h1> + @if ($quicktip->link != "") + <a href="{{ $quicktip->link }}">{{ $quicktip->title }}</a> + @else + {{ $quicktip->title }} + @endif + </h1> + @endif + <p>{!! $quicktip->descr !!}</p> + </div> +@endif \ No newline at end of file diff --git a/resources/views/quicktips.blade.php b/resources/views/quicktips.blade.php new file mode 100644 index 0000000000000000000000000000000000000000..f354bda8b7ff7dadefffc7704e3bf4325b39b28b --- /dev/null +++ b/resources/views/quicktips.blade.php @@ -0,0 +1,5 @@ +@foreach($quicktips as $quicktip) + <div class="quicktip" type="{{ $quicktip->type }}"> + @include('parts.quicktip', ['quicktip' => $quicktip]) + </div> +@endforeach \ No newline at end of file