diff --git a/Dockerfile b/Dockerfile index e6b4514e5741feb787aab13d4ab3123fb67ef58a..73ac6bec7b5074140235efb00de64fb3d489524e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,9 @@ COPY config/nginx-default.conf /etc/nginx/conf.d/default.conf COPY --chown=root:nginx . /html RUN chmod -R g+w storage bootstrap/cache -CMD /etc/init.d/cron start && \ +CMD chown -R root:nginx storage/logs/metager bootstrap/cache && \ + chmod -R g+w storage/logs/metager bootstrap/cache && \ + /etc/init.d/cron start && \ /etc/init.d/php7.3-fpm start && \ /etc/init.d/nginx start && \ /etc/init.d/redis-server start && \ diff --git a/app/CacheHelper.php b/app/CacheHelper.php index 81b7ee56a42b2fe11de752cddb1da5ff01baa780..3a4aeaae55015b4c26f40d5ae2ebd0ed927a4d05 100644 --- a/app/CacheHelper.php +++ b/app/CacheHelper.php @@ -18,7 +18,7 @@ class CacheHelper 'key' => $key, 'value' => $value, ]; - Redis::rpush(\App\Console\Commands\RequestCacher::CACHER_QUEUE, json_encode($cacherItem)); + Redis::rpush(\App\Console\Commands\RequestCacher::CACHER_QUEUE, base64_encode(serialize($cacherItem))); } } diff --git a/app/Console/Commands/RequestCacher.php b/app/Console/Commands/RequestCacher.php index 39a88827d6d3894cffc16b660e94945ecc502f81..bf52f428edd9f6474fb1c89b79a43f1b584ce5b4 100644 --- a/app/Console/Commands/RequestCacher.php +++ b/app/Console/Commands/RequestCacher.php @@ -50,11 +50,11 @@ class RequestCacher extends Command while ($this->shouldRun) { $cacheItem = Redis::blpop(self::CACHER_QUEUE, 1); if (!empty($cacheItem)) { - $cacheItem = json_decode($cacheItem[1], true); - if (empty($cacheItem["body"])) { - $cacheItem["body"] = "no-result"; + $cacheItem = unserialize(base64_decode($cacheItem[1])); + if (empty($cacheItem["value"])) { + $cacheItem["value"] = "no-result"; } - Cache::put($cacheItem["hash"], $cacheItem["body"], now()->addMinutes($cacheItem["cacheDuration"])); + Cache::put($cacheItem["key"], $cacheItem["value"], now()->addSeconds($cacheItem["timeSeconds"])); } } } diff --git a/app/Console/Commands/RequestFetcher.php b/app/Console/Commands/RequestFetcher.php index c96a6d9bbd460debfe632e809dd62eb594f2dc6b..e6e92671822c3eeef8383ad63c6b9e54d1db7a3f 100644 --- a/app/Console/Commands/RequestFetcher.php +++ b/app/Console/Commands/RequestFetcher.php @@ -120,7 +120,7 @@ class RequestFetcher extends Command 'key' => $resulthash, 'value' => $body, ]; - $pipe->rpush(\App\Console\Commands\RequestCacher::CACHER_QUEUE, json_encode($cacherItem)); + $pipe->rpush(\App\Console\Commands\RequestCacher::CACHER_QUEUE, base64_encode(serialize($cacherItem))); }); \curl_multi_remove_handle($this->multicurl, $info["handle"]); } diff --git a/app/Http/Controllers/MetaGerSearch.php b/app/Http/Controllers/MetaGerSearch.php index 4eaba9979831d0f885f5aa09af29e40a1e64ab0a..134b92beda984904081629189b197779d9318470 100644 --- a/app/Http/Controllers/MetaGerSearch.php +++ b/app/Http/Controllers/MetaGerSearch.php @@ -6,7 +6,6 @@ use App; use App\MetaGer; use Cache; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Redis; use LaravelLocalization; use View; @@ -64,14 +63,15 @@ class MetaGerSearch extends Controller # Ergebnisse der Suchmaschinen kombinieren: $metager->prepareResults(); - # Save the results in Redis - $redis = Redis::connection(env('REDIS_RESULT_CONNECTION')); - $pipeline = $redis->pipeline(); - foreach ($metager->getResults() as $result) { - $pipeline->rpush($metager->getRedisCurrentResultList(), base64_encode(serialize($result))); + $finished = true; + foreach ($metager->getEngines() as $engine) { + if ($engine->loaded) { + $engine->setNew(false); + $engine->markNew(); + } } - $pipeline->expire($metager->getRedisCurrentResultList(), env('REDIS_RESULT_CACHE_DURATION')); - $pipeline->execute(); + + \App\CacheHelper::put("loader_" . $metager->getSearchUid(), $metager->getEngines(), 60 * 60); # Die Ausgabe erstellen: $resultpage = $metager->createView($quicktipResults); @@ -106,83 +106,67 @@ class MetaGerSearch extends Controller # Create a MetaGer Instance with the supplied hash $hash = $request->input('loadMore', ''); - $metager = new MetaGer($hash); - $redis = Redis::connection(env('REDIS_RESULT_CONNECTION')); - - $result = []; - # Check if there should be more results - $stats = $redis->hgetall($metager->getRedisEngineResult() . "status"); - $stats["startTime"] = floatval($stats["startTime"]); - $stats["engineCount"] = intval($stats["engineCount"]); - $stats["engineAnswered"] = intval($stats["engineAnswered"]); - $stats["engineDelivered"] = intval($stats["engineDelivered"]); - - $result["finished"] = true; - $result["engineCount"] = $stats["engineCount"]; - $result["engineAnswered"] = $stats["engineAnswered"]; - $result["engineDelivered"] = $stats["engineDelivered"]; - $result["timeWaiting"] = microtime(true) - $stats["startTime"]; - - # Check if we can abort - if ($stats["engineAnswered"] > $stats["engineDelivered"]/*&& $result["timeWaiting"] <= 10 */) { - $metager->parseFormData($request); - # Nach Spezialsuchen überprüfen: - $metager->checkSpecialSearches($request); - - # Read which search engines are new - $newEngines = []; - - while (($engine = $redis->lpop($metager->getRedisResultWaitingKey())) != null) { - $result["engineDelivered"]++; - $newEngines[$engine] = $metager->getSumaFile()->sumas->{$engine}; - } - $cache = Cache::get($hash); - if ($cache != null) { - $metager->setNext(unserialize($cache)["engines"]); + # Parser Skripte einhängen + $dir = app_path() . "/Models/parserSkripte/"; + foreach (scandir($dir) as $filename) { + $path = $dir . $filename; + if (is_file($path)) { + require_once $path; } + } + + $engines = Cache::get($hash); + if ($engines === null) { + return response()->json(['finished' => true]); + } - # Check if this request is not for page one - $metager->setEngines($request, $newEngines); + $metager = new MetaGer(substr($hash, strpos($hash, "loader_") + 7)); - # Add the results already delivered to the user - $results = $redis->lrange($metager->getRedisCurrentResultList(), 0, -1); - foreach ($results as $index => $oldResult) { - $results[$index] = unserialize(base64_decode($oldResult)); - $results[$index]->new = false; - } - $metager->setResults($results); - $metager->retrieveResults(); - $metager->rankAll(); - $metager->prepareResults(); - $result["nextSearchLink"] = $metager->nextSearchLink(); - $results = $metager->getResults(); - foreach ($results as $index => $resultTmp) { - if ($resultTmp->new) { - if ($metager->getFokus() !== "bilder") { - $view = View::make('layouts.result', ['index' => $index, 'result' => $resultTmp, 'metager' => $metager]); - $html = $view->render(); - $result['newResults'][$index] = $html; - $result["imagesearch"] = false; - } else { - $view = View::make('layouts.image_result', ['index' => $index, 'result' => $resultTmp, 'metager' => $metager]); - $html = $view->render(); - $result['newResults'][$index] = $html; - $result["imagesearch"] = true; - } + $metager->parseFormData($request); + # Nach Spezialsuchen überprüfen: + $metager->checkSpecialSearches($request); + $metager->restoreEngines($engines); + + $metager->retrieveResults(); + $metager->rankAll(); + $metager->prepareResults(); + + $result = [ + 'finished' => true, + 'newResults' => [], + ]; + $result["nextSearchLink"] = $metager->nextSearchLink(); + + foreach ($metager->getResults() as $index => $resultTmp) { + if ($resultTmp->new) { + if ($metager->getFokus() !== "bilder") { + $view = View::make('layouts.result', ['index' => $index, 'result' => $resultTmp, 'metager' => $metager]); + $html = $view->render(); + $result['newResults'][$index] = $html; + $result["imagesearch"] = false; + } else { + $view = View::make('layouts.image_result', ['index' => $index, 'result' => $resultTmp, 'metager' => $metager]); + $html = $view->render(); + $result['newResults'][$index] = $html; + $result["imagesearch"] = true; } } - # Save the results in Redis - $pipeline = $redis->pipeline(); - $pipeline->hincrby($metager->getRedisEngineResult() . "status", "engineDelivered", sizeof($newEngines)); - $pipeline->hset($metager->getRedisEngineResult() . "status", "nextSearchLink", $result["nextSearchLink"]); - foreach ($metager->getResults() as $resultTmp) { - $resultTmp->new = false; - $pipeline->rpush($metager->getRedisCurrentResultList(), base64_encode(serialize($resultTmp))); - } - $pipeline->expire($metager->getRedisCurrentResultList(), env('REDIS_RESULT_CACHE_DURATION')); - $pipeline->execute(); + } + $finished = true; + foreach ($engines as $engine) { + if (!$engine->loaded) { + $finished = false; + } else { + $engine->setNew(false); + $engine->markNew(); + } } + + $result["finished"] = $finished; + + // Update new Engines + \App\CacheHelper::put("loader_" . $metager->getSearchUid(), $metager->getEngines(), 1 * 60); return response()->json($result); } diff --git a/app/MetaGer.php b/app/MetaGer.php index 63c9f5e6871b88075feb406d6509c9cffa315b6f..01b358aaee0f10a256711d5e774e12074a05360f 100644 --- a/app/MetaGer.php +++ b/app/MetaGer.php @@ -71,6 +71,7 @@ class MetaGer protected $verificationCount; protected $searchUid; protected $redisResultWaitingKey, $redisResultEngineList, $redisEngineResult, $redisCurrentResultList; + public $starttime; public function __construct($hash = "") { @@ -804,7 +805,6 @@ class MetaGer } while (sizeof($enginesToWaitFor) > 0 || ($forceTimeout !== null && (microtime(true) - $timeStart) < $forceTimeout)) { - Log::info(sizeof($enginesToWaitFor) . " " . sizeof($answered) . " " . $enginesToWaitFor[0]->hash); foreach ($enginesToWaitFor as $index => $engine) { if (Redis::get($engine->hash) !== null) { $answered[] = $engine; @@ -1734,4 +1734,16 @@ class MetaGer { return $this->redisCurrentResultList; } + + public function getEngines() + { + return $this->engines; + } + /** + * Used by JS result loader to restore MetaGer Object of previous request + */ + public function restoreEngines($engines) + { + $this->engines = $engines; + } } diff --git a/app/Models/Searchengine.php b/app/Models/Searchengine.php index 0604f5eac0d824904a2c8fbb1dbedd9c93e0dbe1..e8a7a4817455c55ce9a1b954a2e2468ea1efdf04 100644 --- a/app/Models/Searchengine.php +++ b/app/Models/Searchengine.php @@ -37,6 +37,7 @@ abstract class Searchengine public $write_time = 0; # Wird eventuell für Artefakte benötigt public $connection_time = 0; # Wird eventuell für Artefakte benötigt public $cacheDuration = 60; # Wie lange soll das Ergebnis im Cache bleiben (Minuten) + public $new = true; # Important for loading results by JS public function __construct($name, \stdClass $engine, MetaGer $metager) { @@ -50,7 +51,7 @@ abstract class Searchengine $this->useragent = $metager->getUserAgent(); $this->ip = $metager->getIp(); - $this->startTime = microtime(); + $this->startTime = microtime(true); # check for http Auth if (!empty($this->engine->{"http-auth-credentials"}->username) && !empty($this->engine->{"http-auth-credentials"}->password)) { $this->username = $this->engine->{"http-auth-credentials"}->username; @@ -183,6 +184,7 @@ abstract class Searchengine if ($body !== null) { $this->loadResults($body); $this->getNext($metager, $body); + $this->markNew(); $this->loaded = true; return true; } else { @@ -190,6 +192,13 @@ abstract class Searchengine } } + public function markNew() + { + foreach ($this->results as $result) { + $result->new = $this->new; + } + } + # Erstellt den für die Get-Anfrage genutzten String protected function generateGetString($query) { @@ -243,4 +252,9 @@ abstract class Searchengine { return []; } + + public function setNew($new) + { + $this->new = $new; + } } diff --git a/chart/templates/deployment.yaml b/chart/templates/deployment.yaml index 892d2979f6f8dade3e9d86e4aef865d0bcc4da86..0940498c1fbb03087901827449603c36c39b83fd 100644 --- a/chart/templates/deployment.yaml +++ b/chart/templates/deployment.yaml @@ -104,8 +104,10 @@ spec: volumeMounts: - name: mglogs-persistent-storage mountPath: /html/storage/logs/metager + readOnly: false - name: mgcache-persistent-storage mountPath: /html/storage/framework/cache + readOnly: false resources: {{ toYaml .Values.resources | indent 12 }} {{- end -}} diff --git a/resources/js/scriptResultPage.js b/resources/js/scriptResultPage.js index dd140c82180bdc03f0a6f9d5009f3b5e614432f7..9e899d7da05263988bdb29685097afb1cc3d2eb1 100644 --- a/resources/js/scriptResultPage.js +++ b/resources/js/scriptResultPage.js @@ -55,13 +55,10 @@ function enableFormResetter() { function loadMoreResults() { var searchKey = $("meta[name=searchkey]").attr("content"); var updateUrl = document.location.href; - updateUrl += "&loadMore=" + searchKey + "&script=yes"; + updateUrl += "&loadMore=loader_" + searchKey + "&script=yes"; updateUrl = updateUrl.replace("/meta.ger3", "/loadMore"); - var expectedEngines = -1; - var deliveredEngines = -1; - var currentlyLoading = false; // Regularily check for not yet delivered Results @@ -70,7 +67,7 @@ function loadMoreResults() { currentlyLoading = true; $.getJSON(updateUrl, function (data) { // Check if we can clear the interval (once every searchengine has answered) - if (data.engineDelivered == data.engineCount || data.timeWaiting > 15) { + if (!data || data.finished) { clearInterval(resultLoader); } // If there are new results we can add them @@ -109,13 +106,9 @@ function loadMoreResults() { $(".alert.alert-danger").remove(); } } - console.log(data); } currentlyLoading = false; }); } }, 1000); - //clearInterval(resultLoader); - console.log(updateUrl); - } \ No newline at end of file