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 477c3993a4873044bdc9a239dd5c0d52b17421f6..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,7 +577,6 @@ class MetaGer foreach ($engines as $engine) { $engine->startSearch($this); } - $quicktips = new \App\Models\Quicktips($this->q, $this->lang, $this->getTime(), $this->getHashCode()); /* 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/Quicktip.php b/app/Models/Quicktip.php deleted file mode 100644 index 95d4a1d853ec36d3c9ba5f30b82565dcd0d3a2a7..0000000000000000000000000000000000000000 --- a/app/Models/Quicktip.php +++ /dev/null @@ -1,36 +0,0 @@ -<?php - -namespace App\Models; - -class Quicktip -{ - private $type; - private $title; - private $link; - private $descr; - private $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; - } -} - -class Quicktip_Detail -{ - private $title; - private $link; - private $descr; - - public function __construct($title, $link, $descr) - { - $this->title = $title; - $this->link = $link; - $this->descr = $descr; - } -} diff --git a/app/Models/Quicktips.php b/app/Models/Quicktips.php deleted file mode 100644 index 0caa8ecf4df0770b42d1786b68eb87ef17fd65e0..0000000000000000000000000000000000000000 --- a/app/Models/Quicktips.php +++ /dev/null @@ -1,117 +0,0 @@ -<?php - -namespace App\Models; - -class Quicktips -{ - use DispatchesJobs; - - const QUICKTIP_URL = "https://quicktips.metager3.de/quicktips.xml"; - const QUICKTIP_NAME = "quicktips"; - - public function __construct($search, $locale, $max_time, $resultHash) - { - $this->startSearch($search, $locale, $max_time, $resultHash); - } - - public function startSearch($search, $locale, $max_time, $resultHash) - { - $full_url = QUICKTIP_URL . "?search=" . $search . "&locale=" . $locale; - - $hash = md5($full_url); - - if (Cache::has($hash)) { - $cached = true; - $this->retrieveResults(); - } else { - // ??? - Redis::hset("search." . $resultHash, QUICKTIP_NAME, "waiting"); - - // Queue this search - $mission = $resultHash . ";" . $url . ";" . $max_time; - Redis::rpush(QUICKTIP_NAME . ".queue", $mission); - - // Check the current status of Searchers for QUICKTIP_NAME - $needSearcher = false; - $searcherData = Redis::hgetall(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(QUICKTIP_NAME) !== "locked") { - Redis::set(QUICKTIP_NAME, "locked"); - $this->dispatch(new Searcher(QUICKTIP_NAME)); - } - } - } - - public function retrieveResults($hash, $resultHash) - { - $body = ""; - if (Cache::has($hash)) { - $body = Cache::get($hash); - } elseif (Redis::hexists('search.' . $resultHash, QUICKTIP_NAME)) { - $body = Redis::hget('search.' . $resultHash, QUICKTIP_NAME); - Redis::hdel('search.' . $resultHash, QUICKTIP_NAME); - Cache::put($hash, $body, $cacheDuration); - } - if ($body !== "") { - return $this->loadResults($body); - } else { - return false; - } - } - - public function loadResults($quicktips_raw) { - $quicktips_raw = preg_replace("/\r\n/si", "", $quicktips_raw); - try { - $content = simplexml_load_string($quicktips_raw); - if (!$content) { - return; - } - - $quicktips = []; - - $quicktips_xpath = $content->xpath('feed/entry'); - foreach ($quicktips_xpath as $quicktip_xml) { - $type = $quicktip_xml->{"mg:type"}->__toString(); - $title = $quicktip_xml->{"title"}->__toString(); - $link = $quicktip_xml->{"link"}->__toString(); - $descr = $quicktip_xml->{"content"}->__toString(); - $details = []; - foreach ($quicktip_xml->{"mg:details"}->{"entry"} 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\Detail( - $details_title, - $details_link, - $details_descr - ); - } - $quicktips[] = new \App\Models\Quicktip( - $type, - $title, - $link, - $descr, - $details - ); - } - return $quicktips; - } catch (\Exception $e) { - Log::error("A problem occurred parsing quicktips"); - return []; - } - } -} 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..86c6534b8550b9f5a6ed4f47410c82afeb093014 --- /dev/null +++ b/app/Models/Quicktips/Quicktips.php @@ -0,0 +1,157 @@ +<?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'); + $content->registerXPathNamespace('opensearch', 'http://a9.com/-/spec/opensearch/1.1/'); + $content->registerXPathNamespace('relevance', 'http://a9.com/-/opensearch/extensions/relevance/1.0/'); + $content->registerXPathNamespace('mg', 'http://metager.de/opensearch/quicktips/'); + + $quicktips = []; + #die(var_dump($content->xpath('//main:entry/mg:type'))); + + $quicktips_xpath = $content->xpath('main:entry'); + foreach ($quicktips_xpath as $quicktip_xml) { + $content->registerXPathNamespace('mg', 'http://metager.de/opensearch/quicktips/'); + $types = $quicktip_xml->xpath('mg:type'); + if (sizeof($types) > 0) { + $type = $types[0]->__toString(); + } + $title = $quicktip_xml->{"title"}->__toString(); + $link_xml = $quicktip_xml->link['href']; + if ($link_xml->count() > 0) { + $link = $link_xml->toString(); + } else { + $link = ""; + } + + $link = $quicktip_xml->{"link"}->__toString(); + $descr = $quicktip_xml->{"content"}->__toString(); + + $details = []; + $details_xpath = $quicktip_xml->xpath('mg:details'); + if (sizeof($details_xpath) > 0) { + foreach ($details_xpath 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 + ); + } + die(var_dump($quicktips)); + return $quicktips; + } catch (\Exception $e) { + die($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/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/layouts/quicktip.blade.php b/resources/views/parts/quicktip.blade.php similarity index 96% rename from resources/views/layouts/quicktip.blade.php rename to resources/views/parts/quicktip.blade.php index 74593b536989f6a371083339a64084b90a305e52..4ac21b233b8068aa20c35d6f608d5f22d5dad043 100644 --- a/resources/views/layouts/quicktip.blade.php +++ b/resources/views/parts/quicktip.blade.php @@ -1,3 +1,4 @@ +{{ die(var_dump($quicktip)) }} @if (sizeof($quicktip->details) > 0) <details> <summary class="quicktip-summary"> @@ -9,7 +10,6 @@ @endif </h1> <p>{{ $quicktip->descr }}</p> - @if </summary> @foreach ($quicktip->details as $detail) <div class="quicktip-detail"> @@ -33,6 +33,5 @@ {{ $quicktip->title }} @endif </h1> - @if </summary> @endif \ No newline at end of file diff --git a/resources/views/quicktips.blade.php b/resources/views/quicktips.blade.php index 4999e2dcc4af967f5da6edf04928491e46c0df12..f354bda8b7ff7dadefffc7704e3bf4325b39b28b 100644 --- a/resources/views/quicktips.blade.php +++ b/resources/views/quicktips.blade.php @@ -1,5 +1,5 @@ @foreach($quicktips as $quicktip) <div class="quicktip" type="{{ $quicktip->type }}"> - @include('layouts.quicktip', ['quicktip' => $quicktip]) + @include('parts.quicktip', ['quicktip' => $quicktip]) </div> @endforeach \ No newline at end of file