diff --git a/.gitlab/development-values.yaml b/.gitlab/development-values.yaml index 669089a9d4ff19faf09cb8267369fbc0ab194d52..4082c9baf9c2227ba61bfe27b76c8ad042a6afad 100644 --- a/.gitlab/development-values.yaml +++ b/.gitlab/development-values.yaml @@ -33,8 +33,8 @@ resources: memory: 500M podDisruptionBudget: enabled: true - minAvailable: - maxUnavailable: 0 + minAvailable: 1 + maxUnavailable: podAnnotations: prometheus.io/scrape: "true" prometheus.io/path: /metrics diff --git a/.gitlab/production-values.yaml b/.gitlab/production-values.yaml index d9b41ed8d20b5fe0d1f589cbf3f752bde493e1fa..c2ab6cb44de47ad1d503faef53eb0b18367a8f4e 100644 --- a/.gitlab/production-values.yaml +++ b/.gitlab/production-values.yaml @@ -9,8 +9,8 @@ hpa: maxReplicas: 100 podDisruptionBudget: enabled: true - minAvailable: - maxUnavailable: 0 + minAvailable: 3 + maxUnavailable: podAnnotations: prometheus.io/scrape: "true" prometheus.io/path: /metrics diff --git a/.gitlab/review-apps-values.yaml b/.gitlab/review-apps-values.yaml index a8a7331ba3b28d881b56dc6845c2124779a058b2..39675d18a11ea100f328d62b50fe08e84869cff3 100644 --- a/.gitlab/review-apps-values.yaml +++ b/.gitlab/review-apps-values.yaml @@ -36,4 +36,4 @@ resourcesRedis: limits: resourcesFetcher: requests: - limits: \ No newline at end of file + limits: diff --git a/app/Console/Commands/AppendLogs.php b/app/Console/Commands/AppendLogs.php index 7049e06a6777901d7272abf7090394744667a413..5042aca3d9e3bb255c301e849ade2a8cb179c75b 100644 --- a/app/Console/Commands/AppendLogs.php +++ b/app/Console/Commands/AppendLogs.php @@ -16,6 +16,7 @@ class AppendLogs extends Command */ protected $signature = 'logs:gather'; const LOGKEY = "metager.logs"; + const LOGKEYTAZ = "metager.tazlogs"; /** * The console command description. @@ -41,8 +42,14 @@ class AppendLogs extends Command */ public function handle() { - $redis = null; + $this->handleMGLogs(); + $this->handleTazLogs(); + } + private function handleMGLogs() + { + $redis = null; + if (env("REDIS_CACHE_DRIVER", "redis") === "redis") { $redis = Redis::connection('cache'); } elseif (env("REDIS_CACHE_DRIVER", "redis") === "redis-sentinel") { @@ -64,9 +71,50 @@ class AppendLogs extends Command } if (file_put_contents(\App\MetaGer::getMGLogFile(), implode(PHP_EOL, $elements) . PHP_EOL, FILE_APPEND) === false) { Log::error("Konnte Log Zeile(n) nicht schreiben"); - $redis->lpush(array_reverse($elements)); + $redis->lpush(\App\Console\Commands\AppendLogs::LOGKEY, array_reverse($elements)); } else { Log::info("Added " . sizeof($elements) . " lines to todays log!"); } } + + private function handleTazLogs() + { + $redis = null; + + if (env("REDIS_CACHE_DRIVER", "redis") === "redis") { + $redis = Redis::connection('cache'); + } elseif (env("REDIS_CACHE_DRIVER", "redis") === "redis-sentinel") { + $redis = RedisSentinel::connection('cache'); + } + if ($redis === null) { + Log::error("No valid Redis Connection specified"); + return; + } + + $elements = []; + $reply = $redis->pipeline(function ($pipe) use ($elements) { + $pipe->lrange(\App\Console\Commands\AppendLogs::LOGKEYTAZ, 0, -1); + $pipe->del(\App\Console\Commands\AppendLogs::LOGKEYTAZ); + }); + $elements = $reply[0]; + if (!is_array($elements) || sizeof($elements) <= 0) { + return; + } + if (file_put_contents(\App\Console\Commands\AppendLogs::getTazLogFile(), implode(PHP_EOL, $elements) . PHP_EOL, FILE_APPEND) === false) { + Log::error("Konnte Log Zeile(n) nicht schreiben"); + $redis->lpush(\App\Console\Commands\AppendLogs::LOGKEYTAZ, array_reverse($elements)); + } else { + Log::info("Added " . sizeof($elements) . " lines to todays TAZ log!"); + } + } + + public static function getTazLogFile() + { + $logpath = storage_path("logs/metager/taz/" . date("Y") . "/" . date("m") . "/"); + if (!file_exists($logpath)) { + mkdir($logpath, 0777, true); + } + $logpath .= date("d") . ".log"; + return $logpath; + } } diff --git a/app/Http/Controllers/AdminInterface.php b/app/Http/Controllers/AdminInterface.php index 19efccc428cd5eba19e096f1b4e1ee06ec9f6afd..dd14d95d868424f9e6e04fdcff6f14011cec79bc 100644 --- a/app/Http/Controllers/AdminInterface.php +++ b/app/Http/Controllers/AdminInterface.php @@ -142,11 +142,19 @@ class AdminInterface extends Controller $rekordTagDate = ""; $size = 0; $count = 0; + $logToday = 0; foreach ($logs as $key => $stats) { if ($key === 0) { // Log for today - $logToday = empty($stats->insgesamt->{$interface}) ? 0 : $stats->insgesamt->{$interface}; + $now = Carbon::now(); + $now->hour = 0; + $now->minute = 0; + $now->second = 0; + while ($now->lessThanOrEqualTo(Carbon::now()->subMinutes(5))) { + $logToday += empty($stats->time->{$now->format('H:i')}->{$interface}) ? 0 : $stats->time->{$now->format('H:i')}->{$interface}; + $now->addMinutes(5); + } continue; } $insgesamt = empty($stats->insgesamt->{$interface}) ? 0 : $stats->insgesamt->{$interface}; @@ -156,7 +164,7 @@ class AdminInterface extends Controller $now->minute = 0; $now->second = 0; - while ($now->lessThanOrEqualTo(Carbon::now())) { + while ($now->lessThanOrEqualTo(Carbon::now()->subMinutes(5))) { $sameTime += empty($stats->time->{$now->format('H:i')}->{$interface}) ? 0 : $stats->time->{$now->format('H:i')}->{$interface}; $now->addMinutes(5); } @@ -190,7 +198,7 @@ class AdminInterface extends Controller $sum += ($logToday - $sameTime); } } - + $averageIncrease = 0; if (sizeof($sameTimes) > 0) { $averageIncrease = $sum / sizeof($sameTimes); diff --git a/app/Http/Controllers/MetaGerSearch.php b/app/Http/Controllers/MetaGerSearch.php index e1aaf1ba5001a500bc4f717b233dd2f3d96e925d..032d739bdd2a8d0c2fcdd33a8fa08e10008eb1bd 100644 --- a/app/Http/Controllers/MetaGerSearch.php +++ b/app/Http/Controllers/MetaGerSearch.php @@ -88,9 +88,13 @@ class MetaGerSearch extends Controller $metager->startSearch($timings); # Versuchen die Ergebnisse der Quicktips zu laden - $quicktipResults = $quicktips->loadResults(); - if (!empty($timings)) { - $timings["Loaded Quicktip Results"] = microtime(true) - $time; + if($quicktips !== null) { + $quicktipResults = $quicktips->loadResults(); + if (!empty($timings)) { + $timings["Loaded Quicktip Results"] = microtime(true) - $time; + } + } else { + $quicktipResults = []; } $metager->waitForMainResults(); @@ -119,7 +123,6 @@ class MetaGerSearch extends Controller $engine->markNew(); } } - try { Cache::put("loader_" . $metager->getSearchUid(), [ "metager" => [ diff --git a/app/Http/Controllers/StartpageController.php b/app/Http/Controllers/StartpageController.php index 05d8c6120e139e432a2ebe96a79d33051fe0588f..28701194d0053d42d01d151f7388d01d41ef747e 100644 --- a/app/Http/Controllers/StartpageController.php +++ b/app/Http/Controllers/StartpageController.php @@ -7,6 +7,7 @@ use Cookie; use Illuminate\Http\Request; use Jenssegers\Agent\Agent; use LaravelLocalization; +use Illuminate\Support\Facades\Redis; use Response; class StartpageController extends Controller @@ -43,6 +44,21 @@ class StartpageController extends Controller $lang = 'all'; } + /** + * Logging Requests from Taz advertisement + */ + if ($request->filled("key") && $request->input("key", "") === "taz") { + $logEntry = date("H:i:s"); + $referer = request()->headers->get('referer'); + $logEntry .= " ref=$referer"; + + if (env("REDIS_CACHE_DRIVER", "redis") === "redis") { + Redis::connection('cache')->rpush(\App\Console\Commands\AppendLogs::LOGKEYTAZ, $logEntry); + } elseif (env("REDIS_CACHE_DRIVER", "redis") === "redis-sentinel") { + RedisSentinel::connection('cache')->rpush(\App\Console\Commands\AppendLogs::LOGKEYTAZ, $logEntry); + } + } + return view('index') ->with('title', trans('titles.index')) ->with('homeIcon') diff --git a/app/Http/Controllers/Stresstest.php b/app/Http/Controllers/Stresstest.php new file mode 100644 index 0000000000000000000000000000000000000000..a4114a8c6c4c9f7766c78c55a406ead2d65aa7f0 --- /dev/null +++ b/app/Http/Controllers/Stresstest.php @@ -0,0 +1,31 @@ +<?php + +namespace App\Http\Controllers; + +use App; +use App\MetaGer; +use Cache; +use Illuminate\Http\Request; +use LaravelLocalization; +use Log; +use View; + +/* The controller uses the MetaGers dummy engine ( documentation: https:\/\/gitlab.metager.de\/open-source\/dummy-engine ) +* to generate a list of test results for stress testing purposes at "/admin/stress". +* For local testing go to config/stress.json and change sumas->dummy->host to "dummy-nginx". +* To activate browser and human verfication use the following route: "/admin/stress/verify". +*/ +class Stresstest extends MetaGerSearch +{ + public function index(Request $request, MetaGer $metager, $timing = false) + { + # adds / replaces query input with a random string to avoid cached results + $request->merge(["eingabe" => "test" . rand()]); + + # deactivates adgoal + $metager->setDummy(true); + $metager->setAdgoalHash(true); + + parent::search($request, $metager, $timing); + } +} \ No newline at end of file diff --git a/app/MetaGer.php b/app/MetaGer.php index 2767f0272aa51b2207a7116eca924007ea8454a2..51a7546f6a3f8d3e8e85ba07b2106f4317506f25 100644 --- a/app/MetaGer.php +++ b/app/MetaGer.php @@ -78,6 +78,7 @@ class MetaGer protected $redisEngineResult; protected $redisCurrentResultList; public $starttime; + protected $dummy = false; public function __construct($hash = "") { @@ -300,7 +301,7 @@ class MetaGer if (empty($this->adgoalLoaded)) { $this->adgoalLoaded = false; } - if (!$this->apiAuthorized && !$this->adgoalLoaded) { + if (!$this->apiAuthorized && !$this->adgoalLoaded && !$this->dummy) { if (empty($this->adgoalHash)) { if (!empty($this->jskey)) { $js = Redis::connection('cache')->lpop("js" . $this->jskey); @@ -308,19 +309,19 @@ class MetaGer $this->javascript = true; } } - $this->adgoalHash = $this->startAdgoal($this->results); + $this->adgoalHash = \App\Models\Adgoal::startAdgoal($this->results); if (!empty($timings)) { $timings["prepareResults"]["started adgoal"] = microtime(true) - $timings["starttime"]; } } if (!$this->javascript) { - $this->adgoalLoaded = $this->parseAdgoal($this->results, $this->adgoalHash, true); + $this->adgoalLoaded = \App\Models\Adgoal::parseAdgoal($this->results, $this->adgoalHash, true); if (!empty($timings)) { $timings["prepareResults"]["parsed adgoal"] = microtime(true) - $timings["starttime"]; } } else { - $this->adgoalLoaded = $this->parseAdgoal($this->results, $this->adgoalHash, false); + $this->adgoalLoaded = \App\Models\Adgoal::parseAdgoal($this->results, $this->adgoalHash, false); if (!empty($timings)) { $timings["prepareResults"]["parsed adgoal"] = microtime(true) - $timings["starttime"]; } @@ -418,132 +419,7 @@ class MetaGer } } - public function startAdgoal(&$results) - { - $publicKey = getenv('adgoal_public'); - $privateKey = getenv('adgoal_private'); - if ($publicKey === false) { - return true; - } - $linkList = ""; - foreach ($results as $result) { - if (!$result->new) { - continue; - } - $link = $result->link; - if (strpos($link, "http") !== 0) { - $link = "http://" . $link; - } - $linkList .= $link . ","; - $result->tld = parse_url($link, PHP_URL_HOST); - } - - $linkList = rtrim($linkList, ","); - - # Hashwert - $hash = md5($linkList . $privateKey); - - # Query - $query = $this->q; - - $link = "https://xf.gdprvalidate.de/v4/check"; - - $postfields = [ - "key" => $publicKey, - "panel" => "ZMkW9eSKJS", - "member" => "338b9Bnm", - "signature" => $hash, - "links" => $linkList - ]; - - // Submit fetch job to worker - $mission = [ - "resulthash" => $hash, - "url" => $link, - "useragent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0", - "username" => null, - "password" => null, - "headers" => [ - "Content-Type" => "application/x-www-form-urlencoded" - ], - "cacheDuration" => 60, - "name" => "Adgoal", - "curlopts" => [ - CURLOPT_POST => true, - CURLOPT_POSTFIELDS => \http_build_query($postfields) - ] - ]; - $mission = json_encode($mission); - Redis::rpush(\App\MetaGer::FETCHQUEUE_KEY, $mission); - - return $hash; - } - - public function parseAdgoal(&$results, $hash, $waitForResult) - { - # Wait for result - $startTime = microtime(true); - $answer = null; - - # Hash is true if Adgoal request wasn't started in the first place - if ($hash === true) { - return true; - } - - if ($waitForResult) { - while (microtime(true) - $startTime < 5) { - $answer = Cache::get($hash); - if ($answer === null) { - usleep(50 * 1000); - } else { - break; - } - } - } else { - $answer = Cache::get($hash); - } - if ($answer === null) { - return false; - } - - try { - $answer = json_decode($answer, true); - - # Nun müssen wir nur noch die Links für die Advertiser ändern: - foreach ($results as $result) { - $link = $result->link; - $result->tld = parse_url($link, PHP_URL_HOST); - } - - foreach ($answer as $partnershop) { - $targetUrl = parse_url($partnershop["click_url"], PHP_URL_QUERY); - parse_str($targetUrl, $params); - $targetUrl = $params["url"]; - - foreach ($results as $result) { - if ($result->link === $targetUrl && !$result->partnershop) { - # Ein Advertiser gefunden - if ($result->image !== "") { - $result->logo = $partnershop["logo"]; - } else { - $result->image = $partnershop["logo"]; - } - - # Den Link hinzufügen: - $result->link = $partnershop["click_url"]; - $result->partnershop = true; - $result->changed = true; - } - } - } - } catch (\ErrorException $e) { - Log::error($e->getMessage()); - } finally { - $requestTime = microtime(true) - $startTime; - \App\PrometheusExporter::Duration($requestTime, "adgoal"); - } - return true; - } + public function humanVerification(&$results) { @@ -671,7 +547,7 @@ class MetaGer # Special case if search engines are disabled # Since bing is normally only active if a filter is set but it should be active, too if yahoo is disabled - if ($this->getFokus() === "web" && empty($this->enabledSearchengines["yahoo"]) && \Cookie::get("web_engine_bing") !== "off") { + if ($this->getFokus() === "web" && empty($this->enabledSearchengines["yahoo"]) && \Cookie::get("web_engine_bing") !== "off" && isset($this->sumaFile->sumas->{"bing"})) { $this->enabledSearchengines["bing"] = $this->sumaFile->sumas->{"bing"}; } @@ -758,6 +634,10 @@ class MetaGer foreach ($this->engines as $engine) { $keys[] = $engine->hash; } + # Noch searchengines enabled + if (empty($keys)) { + return; + } $cacheValues = Cache::many($keys); foreach ($this->engines as $engine) { if ($cacheValues[$engine->hash] !== null) { @@ -1050,9 +930,9 @@ class MetaGer $this->fokus = $request->input('focus', 'web'); # Suma-File if (App::isLocale("en")) { - $this->sumaFile = config_path() . "/sumasEn.json"; + $this->sumaFile = config_path() . ($this->dummy ? "/stress.json" : "/sumasEn.json"); } else { - $this->sumaFile = config_path() . "/sumas.json"; + $this->sumaFile = config_path() . ($this->dummy ? "/stress.json" : "/sumas.json"); } if (!file_exists($this->sumaFile)) { die(trans('metaGer.formdata.cantLoad')); @@ -1231,8 +1111,12 @@ class MetaGer public function createQuicktips() { # Die quicktips werden als job erstellt und zur Abarbeitung freigegeben - $quicktips = new \App\Models\Quicktips\Quicktips($this->q, LaravelLocalization::getCurrentLocale(), $this->getTime(), $this->sprueche); - return $quicktips; + if (!$this->dummy) { + $quicktips = new \App\Models\Quicktips\Quicktips($this->q, LaravelLocalization::getCurrentLocale(), $this->getTime(), $this->sprueche); + return $quicktips; + } else { + return null; + } } @@ -2032,4 +1916,9 @@ class MetaGer { $this->engines = $engines; } + + public function setDummy($dummy) + { + $this->dummy = $dummy; + } } diff --git a/app/Models/Adgoal.php b/app/Models/Adgoal.php new file mode 100644 index 0000000000000000000000000000000000000000..94d16c375aaa28bd9f182262fcc0f7be58a7015d --- /dev/null +++ b/app/Models/Adgoal.php @@ -0,0 +1,161 @@ +<?php + +namespace App\Models; + +use Cache; +use Illuminate\Support\Facades\Redis; +use Log; +use Request; +use LaravelLocalization; + +class Adgoal +{ + const COUNTRIES = ["af","al","dz","um","as","vi","ad","ao","ai","ag","ar","am","aw","az","au","eg","gq","et","bs", + "bh","bd","bb","be","bz","bj","bm","bt","bo","ba","bw","bv","br","vg","io","bn","bg","bf","bi","cl","cn","ck", + "cr","ci","dk","de","dm","do","dj","ec","sv","er","ee","eu","fk","fo","fj","fi","fr","gf","pf","tf","ga","gm", + "ge","gh","gi","gd","gr","gb","uk","gl","gp","gu","gt","gn","gw","gy","ht","hm","hn","hk","in","id","iq","ir", + "ie","is","il","it","jm","sj","jp","ye","jo","yu","ky","kh","cm","ca","cv","kz","qa","ke","kg","ki","cc","co", + "km","cg","cd","hr","cu","kw","la","ls","lv","lb","lr","ly","li","lt","lu","mo","mg","mw","my","mv","ml","mt", + "mp","ma","mh","mq","mr","mu","yt","mk","mx","fm","md","mc","mn","ms","mz","mm","na","nr","np","nc","nz","ni", + "nl","an","ne","ng","nu","kp","nf","no","om","tp","at","pk","pw","ps","pa","pg","py","pe","ph","pn","pl","pt", + "pr","re","rw","ro","ru","st","sb","zm","ws","sm","sa","se","ch","sn","sc","sl","zw","sg","sk","si","so","es", + "lk","sh","kn","lc","pm","vc","sd","sr","za","kr","sz","sy","tj","tw","tz","th","tg","to","tt","td","cz","tn", + "tm","tc","tv","tr","us","ug","ua","xx","hu","uy","uz","vu","va","ve","ae","vn","wf","cx","by","eh","ww","zr","cf","cy",]; + + public static function startAdgoal(&$results) + { + $publicKey = getenv('adgoal_public'); + $privateKey = getenv('adgoal_private'); + if ($publicKey === false) { + return true; + } + $linkList = ""; + foreach ($results as $result) { + if (!$result->new) { + continue; + } + $link = $result->link; + if (strpos($link, "http") !== 0) { + $link = "http://" . $link; + } + $linkList .= $link . ","; + } + + $linkList = rtrim($linkList, ","); + + # Hashwert + $hash = md5($linkList . $privateKey); + + $link = "https://xf.gdprvalidate.de/v4/check"; + + # Which country to use + # Will be de for metager.de and en for metager.org + $country = "de"; + if (LaravelLocalization::getCurrentLocale() === "en") { + $country = "us"; + } + $preferredLanguage = Request::getPreferredLanguage(); + if (!empty($preferredLanguage)) { + if (str_contains($preferredLanguage, "_")) { + $preferredLanguage = substr($preferredLanguage, stripos($preferredLanguage, "_")+1); + } elseif (str_contains($preferredLanguage, "-")) { + $preferredLanguage = substr($preferredLanguage, stripos($preferredLanguage, "-")+1); + } + + $preferredLanguage = strtolower($preferredLanguage); + + if (in_array($preferredLanguage, self::COUNTRIES)) { + $country = $preferredLanguage; + } + } + + $postfields = [ + "key" => $publicKey, + "panel" => "ZMkW9eSKJS", + "member" => "338b9Bnm", + "signature" => $hash, + "links" => $linkList, + "country" => $country, + ]; + + // Submit fetch job to worker + $mission = [ + "resulthash" => $hash, + "url" => $link, + "useragent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0", + "username" => null, + "password" => null, + "headers" => [ + "Content-Type" => "application/x-www-form-urlencoded" + ], + "cacheDuration" => 60, + "name" => "Adgoal", + "curlopts" => [ + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => \http_build_query($postfields) + ] + ]; + $mission = json_encode($mission); + Redis::rpush(\App\MetaGer::FETCHQUEUE_KEY, $mission); + + return $hash; + } + + public static function parseAdgoal(&$results, $hash, $waitForResult) + { + # Wait for result + $startTime = microtime(true); + $answer = null; + + # Hash is true if Adgoal request wasn't started in the first place + if ($hash === true) { + return true; + } + + if ($waitForResult) { + while (microtime(true) - $startTime < 5) { + $answer = Cache::get($hash); + if ($answer === null) { + usleep(50 * 1000); + } else { + break; + } + } + } else { + $answer = Cache::get($hash); + } + if ($answer === null) { + return false; + } + + try { + $answer = json_decode($answer, true); + + foreach ($answer as $partnershop) { + $targetUrl = $partnershop["url"]; + + foreach ($results as $result) { + if ($result->link === $targetUrl && !$result->partnershop) { + # Ein Advertiser gefunden + if ($result->image !== "") { + $result->logo = $partnershop["logo"]; + } else { + $result->image = $partnershop["logo"]; + } + + # Den Link hinzufügen: + $result->link = $partnershop["click_url"]; + $result->partnershop = true; + $result->changed = true; + } + } + } + } catch (\ErrorException $e) { + Log::error($e->getMessage()); + } finally { + $requestTime = microtime(true) - $startTime; + \App\PrometheusExporter::Duration($requestTime, "adgoal"); + } + return true; + } +} diff --git a/app/Models/parserSkripte/Dummy.php b/app/Models/parserSkripte/Dummy.php new file mode 100644 index 0000000000000000000000000000000000000000..8dc7af0b74865eb2457f936918d38e90ce98337a --- /dev/null +++ b/app/Models/parserSkripte/Dummy.php @@ -0,0 +1,85 @@ +<?php + +namespace app\Models\parserSkripte; + +use App\Models\Searchengine; +use Log; +use LaravelLocalization; + +class Dummy extends Searchengine +{ + public $results = []; + + public function __construct($name, \stdClass $engine, \App\MetaGer $metager) + { + parent::__construct($name, $engine, $metager); + } + + public function loadResults($result) + { + try { + $content = json_decode($result); + if (!$content) { + return; + } + + foreach ($content as $result) { + $title = $result->title; + $link = $result->link; + $anzeigeLink = $link; + $descr = $result->descr; + $this->counter++; + $this->results[] = new \App\Models\Result( + $this->engine, + $title, + $link, + $anzeigeLink, + $descr, + $this->engine->{"display-name"},$this->engine->homepage, + $this->counter + ); + } + } catch (\Exception $e) { + Log::error("A problem occurred parsing results from $this->name:"); + Log::error($e->getMessage()); + return; + } + } + public function getNext(\App\MetaGer $metager, $result) + { + try { + $results = json_decode($result); + + $newEngine = unserialize(serialize($this->engine)); + + $perPage = 0; + if(isset($newEngine->{"get-parameter"}->count)){ + $perPage = $newEngine->{"get-parameter"}->count; + } else { + $perPage = 10; + } + + $offset = 0; + if(empty($newEngine->{"get-parameter"}->skip)){ + $offset = $perPage; + } else { + $offset = $newEngine->{"get-parameter"}->skip + $perPage; + } + + if (PHP_INT_MAX - $perPage < ($offset + $perPage)) { + return; + } else { + $newEngine->{"get-parameter"}->skip = strval($offset); + } + + $next = new Dummy($this->name, $newEngine, $metager); + $this->next = $next; + + } catch (\Exception $e) { + Log::error("A problem occurred parsing results from $this->name:"); + Log::error($e->getMessage()); + return; + } + + } +} \ No newline at end of file diff --git a/config/stress.json b/config/stress.json new file mode 100644 index 0000000000000000000000000000000000000000..181de977f56660ea1cd120b9eccc317df7d7c0f7 --- /dev/null +++ b/config/stress.json @@ -0,0 +1,115 @@ +{ + "sumas": { + "dummy": { + "host": "production-auto-deploy.dummy-engine-87.svc.cluster.local", + "path": "\/", + "port": 80, + "query-parameter": "q", + "input-encoding": "utf8", + "output-encoding": "utf8", + "parser-class": "Dummy", + "get-parameter": {}, + "request-header": {}, + "display-name": "dummy", + "engine-boost": 1, + "cache-duration": 0, + "disabled": false, + "filter-opt-in": false, + "homepage": "https:\/\/gitlab.metager.de\/open-source\/dummy-engine" + } + }, + "foki": { + "web": { + "display-name": "index.foki.web", + "sumas": [ + "dummy" + ], + "main": [ + "dummy" + ] + } + }, + "filter": { + "query-filter": {}, + "parameter-filter": { + "count": { + "name": "metaGer.filter.count", + "desc": "", + "get-parameter": "count", + "values": { + "10": "10", + "20": "20", + "30": "30", + "40": "40", + "50": "50", + "100": "100" + }, + "sumas": { + "dummy": { + "get-parameter": "count", + "values": { + "10": "10", + "20": "20", + "30": "30", + "40": "40", + "50": "50", + "100": "100" + } + } + } + }, + "min": { + "name": "metaGer.filter.min", + "desc": "", + "get-parameter": "min", + "values": { + "nofilter" : "0", + "2": "2", + "4": "4", + "6": "6", + "8": "8", + "10": "10" + }, + "sumas": { + "dummy": { + "get-parameter": "min", + "values": { + "nofilter" : "0", + "2": "2000", + "4": "4000", + "6": "6000", + "8": "8000", + "10": "10000" + } + } + } + }, + "max": { + "name": "metaGer.filter.max", + "desc": "", + "get-parameter": "max", + "values": { + "nofilter" : "0", + "2": "2", + "4": "4", + "6": "6", + "8": "8", + "10": "10" + }, + "sumas": { + "dummy": { + "get-parameter": "max", + "values": { + "nofilter" : "0", + "2": "2000", + "4": "4000", + "6": "6000", + "8": "8000", + "10": "10000" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/config/sumas.json.example b/config/sumas.json.example new file mode 100644 index 0000000000000000000000000000000000000000..d9962295300d34cd9e18f60f20a883b3c251d36c --- /dev/null +++ b/config/sumas.json.example @@ -0,0 +1,115 @@ +{ + "sumas": { + "dummy": { + "host": "dummy-nginx", + "path": "\/", + "port": 80, + "query-parameter": "q", + "input-encoding": "utf8", + "output-encoding": "utf8", + "parser-class": "Dummy", + "get-parameter": {}, + "request-header": {}, + "display-name": "dummy", + "engine-boost": 1, + "cache-duration": -1, + "disabled": false, + "filter-opt-in": false, + "homepage": "https:\/\/gitlab.metager.de\/open-source\/dummy-engine" + } + }, + "foki": { + "web": { + "display-name": "index.foki.web", + "sumas": [ + "dummy" + ], + "main": [ + "dummy" + ] + } + }, + "filter": { + "query-filter": {}, + "parameter-filter": { + "count": { + "name": "metaGer.filter.count", + "desc": "", + "get-parameter": "count", + "values": { + "10": "10", + "20": "20", + "30": "30", + "40": "40", + "50": "50", + "100": "100" + }, + "sumas": { + "dummy": { + "get-parameter": "count", + "values": { + "10": "10", + "20": "20", + "30": "30", + "40": "40", + "50": "50", + "100": "100" + } + } + } + }, + "min": { + "name": "metaGer.filter.min", + "desc": "", + "get-parameter": "min", + "values": { + "nofilter" : "0", + "2": "2", + "4": "4", + "6": "6", + "8": "8", + "10": "10" + }, + "sumas": { + "dummy": { + "get-parameter": "min", + "values": { + "nofilter" : "0", + "2": "2000", + "4": "4000", + "6": "6000", + "8": "8000", + "10": "10000" + } + } + } + }, + "max": { + "name": "metaGer.filter.max", + "desc": "", + "get-parameter": "max", + "values": { + "nofilter" : "0", + "2": "2", + "4": "4", + "6": "6", + "8": "8", + "10": "10" + }, + "sumas": { + "dummy": { + "get-parameter": "max", + "values": { + "nofilter" : "0", + "2": "2000", + "4": "4000", + "6": "6000", + "8": "8000", + "10": "10000" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/config/sumas.xml.example b/config/sumas.xml.example deleted file mode 100644 index c9de862dea063a45488e74ab7e220afcc89c7600..0000000000000000000000000000000000000000 --- a/config/sumas.xml.example +++ /dev/null @@ -1,6 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<sumas> - <suma name="mnogosearch" host="mg3.suma-ev.de" skript="/cgi-bin/search.cgi" formData="q=<<QUERY>>&cs=utf-8&ps=20" package="mnogosearch" type="web" port="80" userSelectable="1" displayName="Wikis" outputEncoding="Latin1"/> - <suma name="BASE" host="baseapi.ub.uni-bielefeld.de" skript="/cgi-bin/BaseHttpSearchInterface.fcgi" formData="func=PerformSearch&query=<<QUERY>>" package="BASE" port="80" formDataEn="func=PerformSearch&query=<<QUERY>>" displayName="BASE" userSelectable="1" type="wissenschaft" homepage="http://www.base-search.net/"/> - <suma name="blogsearch" host="blogsuche.suma-ev.de" skript="/blogsearch/xmlout.php" formData="search=<<QUERY>>&length=400&rows=50&category=<<CATEGORY>>" package="blogsearch" port="80" inputEncoding="utf8" displayName="Blogsuche" userSelectable="1" type="andere" engineBoost="0.2" homepage="http://blogsuche.suma-ev.de/blogsearch/index.php"/> -</sumas> diff --git a/docker-compose.yml b/docker-compose.yml index 04bc08d050d1ed9ec8e1df7d5c76164c03c9c9e9..1b05b4f8884f4735a4cd1110436c4b5504b4dac3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -76,3 +76,14 @@ services: volumes: - .:/html command: "php artisan dusk" + dummy-phpfpm: + restart: on-failure + image: registry.metager.de/open-source/dummy-engine/master + working_dir: /html + dummy-nginx: + depends_on: + - "dummy-phpfpm" + restart: on-failure + image: registry.metager.de/open-source/dummy-engine/master + working_dir: /html + command: sh -c "sed -i 's/fastcgi_pass localhost:9000;/fastcgi_pass dummy-phpfpm:9000;/g' /etc/nginx/conf.d/default.conf && nginx" \ No newline at end of file diff --git a/init.sh b/init.sh index 42af2efa729c488cf1e2ab9d83222a6d67111426..63305b0bdc1795424cbf2d708620b31977d1e2a0 100755 --- a/init.sh +++ b/init.sh @@ -7,6 +7,14 @@ if [ ! -f "/data/.env" ]; then cp /data/.env.example /data/.env fi +if [ ! -f "/data/config/sumas.json" ]; then + cp /data/config/sumas.json.example /data/config/sumas.json +fi + +if [ ! -f "/data/config/sumasEn.json" ]; then + cp /data/config/sumas.json.example /data/config/sumasEn.json +fi + if [ -f "/data/database/useragents.sqlite" ]; then rm /data/database/useragents.sqlite fi diff --git a/resources/lang/de/metaGer.php b/resources/lang/de/metaGer.php index 549fb420085adf703ddbed7a66adc4c1f25f43a6..220c08c0755427224e29241decb8321098258818 100644 --- a/resources/lang/de/metaGer.php +++ b/resources/lang/de/metaGer.php @@ -133,5 +133,10 @@ return [ "filter.rabate" => "Min. Rabatt", + "filter.count" => "Anzahl", + "filter.skip" => "Ãœberspringen", + "filter.min" => "Minimum Sleep (in s)", + "filter.max" => "Maximum Sleep (in s)", + "settings" => "Einstellungen", ]; diff --git a/resources/lang/en/kontakt.php b/resources/lang/en/kontakt.php index 0bd4f8d6561485ceffb3e2eb59fe50c699101f7e..df70727c6a9c9a57d49622c2470b8ceb9df37630 100644 --- a/resources/lang/en/kontakt.php +++ b/resources/lang/en/kontakt.php @@ -6,7 +6,7 @@ return [ 'form.1' => 'Secure Contact Form', 'form.2' => 'Via this form you can contact us by e-mail.', 'form.name' => 'Forename, Surname', - 'form.5' => 'Your e-mail-adress (optional)', + 'form.5' => 'Your e-mail-adress', 'form.6' => 'Your message', 'form.7' => 'Subject', 'form.8' => 'Send', diff --git a/resources/lang/en/metaGer.php b/resources/lang/en/metaGer.php index 2af697cc3d9539792a3bef180ec1224a309084c8..66f0557cbba5b8f561f2c9a68a7f51206f04e2da 100644 --- a/resources/lang/en/metaGer.php +++ b/resources/lang/en/metaGer.php @@ -133,5 +133,10 @@ return [ "filter.rabate" => "Min. Rabate", + "filter.count" => "Count", + "filter.skip" => "Skip", + "filter.min" => "Minimum sleep (in s)", + "filter.max" => "Maximum sleep (in s)", + "settings" => "Settings", ]; diff --git a/resources/lang/es/plugin-desktop/desktop-ie.php b/resources/lang/es/plugin-desktop/desktop-ie.php new file mode 100644 index 0000000000000000000000000000000000000000..2491de5b0d7fd854e1e1418447b3b7571ae29f46 --- /dev/null +++ b/resources/lang/es/plugin-desktop/desktop-ie.php @@ -0,0 +1,14 @@ +<?php + +return [ + "default-search-v9.1" => "Haga clic en <a href=\"javascript:window.external.addSearchProvider($('link[rel=search]').attr('href'));\">aquÃ</a>, para agregar MetaGer como motor de búsqueda.", + "default-search-v9.2" => "Seleccione \"Establecer este buscador como predeterminado\" y haga clic en \"Agregar\".", + "default-search-v11.1" => "Haga clic en <a href=\"javascript:window.external.addSearchProvider($('link[rel=search]').attr('href'));\">aquÃ</a>, para agregar MetaGer como motor de búsqueda.", + "default-search-v11.2" => "En la parte superior derecha de su navegador haga clic en \"<i class=\"fa fa-cog\" aria-hidden=\"true\"></i>\".", + "default-search-v11.3" => "Seleccione el elemento del menú \"Administrar complementos\".", + "default-search-v11.4" => "En la sección \"Tipos de complementos\", haga clic en \"Proveedores de búsqueda\", luego en el panel derecho pulse MetaGer.", + "default-search-v11.5" => "Confirmar pulsando en el botón \"Como predeterminado\" que tiene abajo.", + "default-page-v9.1" => "Haga clic en <a href=\"/\" target=\"_blank\" rel=\"noopener\">aquà </a> para abrir MetaGer en una nueva pestaña.", + "default-page-v9.2" => "En la nueva pestaña arriba a la izquierda, haga clic en la flecha junto a la <i class=\"fas fa-home\" aria-hidden=\"true\"> </i> y luego en \"Cambiar o agregar página de inicio\".", + "default-page-v9.3" => "En la ventana emergente que aparece, seleccione \"Usar esta página como única página principal\" y luego haga clic en \"SÃ\"." +]; diff --git a/resources/lang/es/plugin-desktop/desktop-opera.php b/resources/lang/es/plugin-desktop/desktop-opera.php new file mode 100644 index 0000000000000000000000000000000000000000..677fe71500ddfafdfc3fd7a989482f27a9c42103 --- /dev/null +++ b/resources/lang/es/plugin-desktop/desktop-opera.php @@ -0,0 +1,11 @@ +<?php + +return [ + "default-search-v36.1" => "Haga un clic derecho del ratón en el campo de entrada de búsqueda al final de estas instrucciones.", + "default-search-v36.2" => "Seleccione la opción \"Crear motor de búsqueda ...\" en el menú contextual.", + "default-search-v36.3" => "En la ventana emergente, haga clic en \"Crear\".", + "default-page-v36.1" => "En la parte superior izquierda del navegador haga clic en el sÃmbolo de Opera o \"Menú\" y pulse en la opción \"Configuración\".", + "default-page-v36.2" => "En la sección \"En inicio\", seleccione la opción \"Abrir una página especifica o conjunto de páginas\" y luego haga clic en \"Agregar nueva página\" o \"Establecer página\".", + "default-page-v36.3" => "Escriba \":link\" como URL de la página web en \"Agregar nueva página\".", + "default-page-v36.4" => "NOTA: \r\nTodos los sitios web que aparecen ahora en la lista se abrirán cuando se inicie el navegador. Puede borrar las entradas de la lista haciendo clic en \"<i class =\" fas fa-ellipsis-h \"></i>\" junto a la entrada que desea eliminar." +]; diff --git a/resources/lang/es/plugin-desktop/desktop-vivaldi.php b/resources/lang/es/plugin-desktop/desktop-vivaldi.php new file mode 100644 index 0000000000000000000000000000000000000000..94ce622de994a974bbc963fe23ff4d4f75eed857 --- /dev/null +++ b/resources/lang/es/plugin-desktop/desktop-vivaldi.php @@ -0,0 +1,9 @@ +<?php + +return [ + "default-search-v3-3.1" => "Haga un clic derecho del ratón en el campo de entrada de búsqueda que tiene debajo de la instrucción.", + "default-search-v3-3.2" => "En el menú contextual seleccione la opción \"Crear búsqueda...\"", + "default-search-v3-3.3" => "En la ventana emergente, haga clic en \"Establecer como búsqueda predeterminada\" y a continuación en \"Agregar\".", + "default-page-v3-3.1" => "En la esquina superior izquierda haga clic en el sÃmbolo de Vivaldi y en \"Extras\" seleccione el elemento del menú \"<i class=\" fa fa-cog\" aria-hidden=\" true \"></i> Configuración\"", + "default-page-v3-3.2" => "En la ventana que aparece debajo de \"Página de inicio\", seleccione \"Personalizado:\" e ingrese :link." +]; diff --git a/resources/lang/es/widget.php b/resources/lang/es/widget.php index dfa5f706dbe06f450db927e23504843cf50e03f3..59e80441949fd7c7b11f0909f873d8d32091b72f 100644 --- a/resources/lang/es/widget.php +++ b/resources/lang/es/widget.php @@ -1,8 +1,9 @@ <?php return [ - "head" => "MetaGer Widget", - "body.1" => "MetaGer: un motor de búsqueda for suyo sitio web. Selecciona por favor:", + "head" => "Widget de MetaGer", + "body.1" => "MetaGer para la integración en su sitio web. Para hacer esto, seleccione dónde buscar:", "body.2" => "Búsqueda en el web", - "body.3" => "Búsqueda en el dominio solo (sitesearch)" -]; \ No newline at end of file + "body.3" => "Búsqueda en un solo dominio (sitesearch)", + "body.4" => "Nota: \r\nNo debe usar el widget si está tratando de dar la impresión en su sitio web de que MetaGer es su propio servicio o si se da la impresión de que sus páginas son las páginas reales de MetaGer (todo esto ya ha sucedido). Por este motivo, en particular, no está permitido eliminar nuestro logotipo." +]; diff --git a/resources/less/metager/startpage-only.less b/resources/less/metager/startpage-only.less index cdc2bd48824d6e36095dee6c062486bc37fbf999..3b276a451495149458f50082dae5a56be803a37e 100644 --- a/resources/less/metager/startpage-only.less +++ b/resources/less/metager/startpage-only.less @@ -158,9 +158,11 @@ footer { align-items:center; min-height: 70vh; &:not(:nth-child(1)){ - padding-bottom: @clippathHeight; - padding-top: @clippathHeight; - margin-top: -@clippathHeight; + @supports(clip-path: polygon(0 0, 30% 0, 50% 30px, 70% 0, 100% 0, 100% 100%, 0 100%)) or (-webkit-clip-path: polygon(0 0, 40% 0, 50% 30px, 60% 0, 100% 0, 100% 100%, 0 100%)){ + padding-bottom: @clippathHeight; + padding-top: @clippathHeight; + margin-top: -@clippathHeight; + } } } diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index f2733dc752e09ae9a5dfd4aa34a6e9648af757f5..4322e133126ce052067ab62196f28ff44e26b722 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -32,57 +32,53 @@ <div id="story-container"> <section id="story-privacy"> <h1>{{ trans('mg-story.privacy.title') }}</h1> - <ul class="story-links"> - <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "about") }}">{{ trans('mg-story.btn-about-us') }}</a></li> - <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "datenschutz") }}">{{ trans('mg-story.btn-data-protection') }}</a></li> - </ul> <figure class="story-icon"> <img src="/img/lock.svg" alt="{{ trans('mg-story.privacy.image.alt') }}"> </figure> <p>{!! trans('mg-story.privacy.p') !!}</p> + <ul class="story-links"> + <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "about") }}">{{ trans('mg-story.btn-about-us') }}</a></li> + <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "datenschutz") }}">{{ trans('mg-story.btn-data-protection') }}</a></li> + </ul> </section> <section id="story-ngo"> <h1>{{ trans('mg-story.ngo.title') }}</h1> - - <ul class="story-links"> - <li><a class="story-button" href="https://suma-ev.de/" target="_blank">{{ trans('mg-story.btn-SUMA-EV') }}</a></li> - <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "spende") }}">{{ trans('mg-story.btn-donate') }}</a></li> - <li><a class="story-button" href="https://metager.de/beitritt" target="_blank">{{ trans('mg-story.btn-member') }}</a></li> - <li><a class="story-button" href="https://suma-ev.de/mitglieder/" target="_blank"> {{ trans('mg-story.btn-member-advantage') }}</a></li> </ul> <figure class="story-icon"> - <img src="/img/heart.svg" alt="{{ trans('mg-story.ngo.image.alt') }}"> + <img src="/img/heart.svg" alt="{{ trans('mg-story.ngo.image.alt') }}"> </figure> <p>{!!trans('mg-story.ngo.p') !!}</p> + <ul class="story-links"> + <li><a class="story-button" href="https://suma-ev.de/" target="_blank">{{ trans('mg-story.btn-SUMA-EV') }}</a></li> + <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "spende") }}">{{ trans('mg-story.btn-donate') }}</a></li> + <li><a class="story-button" href="https://metager.de/beitritt" target="_blank">{{ trans('mg-story.btn-member') }}</a></li> + <li><a class="story-button" href="https://suma-ev.de/mitglieder/" target="_blank"> {{ trans('mg-story.btn-member-advantage') }}</a></li> + </ul> </section> <section id="story-diversity"> <h1>{{ trans('mg-story.diversity.title') }}</h1> + <figure class="story-icon"> + <img src="/img/rainbow.svg" alt="{{ trans('mg-story.diversity.image.alt') }}"> + </figure> + <p>{!! trans('mg-story.diversity.p') !!}</p> <ul class="story-links"> <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "about") }}">{{ trans('mg-story.btn-about-us') }}</a></li> <li><a class="story-button" href="https://gitlab.metager.de/open-source/MetaGer" target="_blank"><nobr>{{ trans('mg-story.btn-mg-code') }}</nobr></a></li> <!--<li><a class="story-button" href="https://metager.de/about">{{ trans('mg-story.btn-mg-algorithm') }}</a></li>--> </ul> - <figure class="story-icon"> - <img src="/img/rainbow.svg" alt="{{ trans('mg-story.diversity.image.alt') }}"> - </figure> - <p>{!! trans('mg-story.diversity.p') !!}</p> </section> <section id="story-eco"> <h1>{{ trans('mg-story.eco.title') }}</h1> - <ul class="story-links"> - <li><a class="story-button" href="https://www.hetzner.de/unternehmen/umweltschutz/" target="_blank">{{ trans('mg-story.btn-more') }}</a></li> - </ul> <figure class="story-icon"> <img src="/img/leaf.svg" alt="{{ trans('mg-story.eco.image.alt') }}"> </figure> <p>{!! trans('mg-story.eco.p')!!}</p> + <ul class="story-links"> + <li><a class="story-button" href="https://www.hetzner.de/unternehmen/umweltschutz/" target="_blank">{{ trans('mg-story.btn-more') }}</a></li> + </ul> </section> <section id="story-plugin"> <h1>{{ trans('mg-story.plugin.title') }}</h1> - <ul class="story-links"> - <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "/plugin") }}">{{ trans('mg-story.plugin.btn-add') }}</a></li> - <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "/app") }}">{{ trans('mg-story.plugin.btn-app') }}</a></li> - </ul> <figure class="story-icon"> <picture> <source media="(max-width: 760px)" srcset="/img/App.svg"> @@ -91,6 +87,10 @@ </figure> <p>{{ trans('mg-story.plugin.p') }}</p> + <ul class="story-links"> + <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "/plugin") }}">{{ trans('mg-story.plugin.btn-add') }}</a></li> + <li><a class="story-button" href="{{ LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), "/app") }}">{{ trans('mg-story.plugin.btn-app') }}</a></li> + </ul> </section> </div> @endsection diff --git a/resources/views/kontakt/kontakt.blade.php b/resources/views/kontakt/kontakt.blade.php index f7aed2ec917620a875a274a37973c3ae0946dc86..305b1b25466d9459e5e65e92984f603bc72dcafc 100644 --- a/resources/views/kontakt/kontakt.blade.php +++ b/resources/views/kontakt/kontakt.blade.php @@ -40,11 +40,12 @@ <h2>{!! trans('kontakt.mail.1') !!}</h2> @if(LaravelLocalization::getCurrentLocale() === "de") <p>{!! trans('kontakt.mail.2', ["mail" => "support@suma-ev.de"]) !!}</p> + <p>{!! trans('kontakt.mail.3') !!}</p> + <textarea id="pubkey" style="width:50%" rows="8" readonly>@include('kontakt/pgp')</textarea> @else <p>{!! trans('kontakt.mail.2', ["mail" => "support@metager.org"]) !!}</p> @endif - <p>{!! trans('kontakt.mail.3') !!}</p> - <textarea id="pubkey" style="width:50%" rows="8" readonly>@include('kontakt/pgp')</textarea> + </div> <div class="card-heavy"> <h2>{!! trans('kontakt.letter.1') !!}</h2> diff --git a/routes/web.php b/routes/web.php index 6ce056c1fcbf6dbb0f3f86e9357732411096832a..da5dae281108282da61ea83896f0d34393a1172e 100644 --- a/routes/web.php +++ b/routes/web.php @@ -192,6 +192,8 @@ Route::group( Route::post('deleteRegexp', 'AdminSpamController@deleteRegexp'); }); Route::post('service-desk', 'ServiceDesk@webhook'); + Route::get('stress', 'Stresstest@index'); + Route::get('stress/verify', 'Stresstest@index')->middleware('browserverification', 'humanverification'); }); Route::get('settings', function () { diff --git a/tests/Browser/Pages/Widget.php b/tests/Browser/Pages/Widget.php index 4a3d927a0f53b3c1288eb37c2a64d58e75ce197f..f76e540e3defd5c3964a01cf829d0b5637246301 100644 --- a/tests/Browser/Pages/Widget.php +++ b/tests/Browser/Pages/Widget.php @@ -31,7 +31,7 @@ class Widget extends Page ->waitForText("MetaGer for usage on your website. Please choose the scope of your widget:") ->assertTitle("MetaGer Widget") ->switchLanguage("Español") - ->waitForText("MetaGer: un motor de búsqueda for suyo sitio web. Selecciona por favor:") + ->waitForText("MetaGer para la integración en su sitio web. Para hacer esto, seleccione dónde buscar:") ->assertTitle("MetaGer Widget") ->switchLanguage("Deutsch");