MetaGerSearch.php 7.39 KB
Newer Older
Dominik Hebeler's avatar
Dominik Hebeler committed
1
2
3
4
<?php

namespace App\Http\Controllers;

5
use App;
6
use App\MetaGer;
7
use Cache;
8
use Illuminate\Http\Request;
9
use LaravelLocalization;
10
use View;
Dominik Hebeler's avatar
Dominik Hebeler committed
11
12
13

class MetaGerSearch extends Controller
{
14
    public function search(Request $request, MetaGer $metager)
15
    {
Dominik Hebeler's avatar
Dominik Hebeler committed
16
        $time = microtime(true);
17
18
19
20
21
        $spamEntries = [];
        if (file_exists(config_path('spam.txt'))) {
            $spamEntries = file(config_path('spam.txt'));
        }

22
        $focus = $request->input("focus", "web");
23

24
25
26
27
28
        if ($focus === "maps") {
            $searchinput = $request->input('eingabe', '');
            return redirect()->to('https://maps.metager.de/map/' . $searchinput . '/1240908.5493525574,6638783.2192695495,6');
        }

29
30
31
32
33
34
        # If there is no query parameter we redirect to the startpage
        $eingabe = $request->input('eingabe', '');
        if (empty(trim($eingabe))) {
            return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), '/'));
        }

35
36
        # Mit gelieferte Formulardaten parsen und abspeichern:
        $metager->parseFormData($request);
37

38
39
        # Nach Spezialsuchen überprüfen:
        $metager->checkSpecialSearches($request);
40

41
        if (Cache::has('spam.' . $metager->getFokus() . "." . md5($metager->getQ()))) {
Dominik Hebeler's avatar
Dominik Hebeler committed
42
            return response(Cache::get('spam.' . $metager->getFokus() . "." . md5($metager->getEingabe())));
43
44
        }

45
46
47
        # Die Quicktips als Job erstellen
        $quicktips = $metager->createQuicktips();

48
        # Suche für alle zu verwendenden Suchmaschinen als Job erstellen,
49
        # auf Ergebnisse warten und die Ergebnisse laden
50
        $metager->createSearchEngines($request);
51

52
53
54
55
56
57
        $metager->startSearch();

        $metager->waitForMainResults();

        $metager->retrieveResults();

58
59
        # Versuchen die Ergebnisse der Quicktips zu laden
        $quicktipResults = $quicktips->loadResults();
60
61
62
        # Alle Ergebnisse vor der Zusammenführung ranken:
        $metager->rankAll();

63
        # Ergebnisse der Suchmaschinen kombinieren:
Phil Höfer's avatar
Phil Höfer committed
64
        $metager->prepareResults();
65

Dominik Hebeler's avatar
Dominik Hebeler committed
66
67
68
69
70
71
72
73
74
        $finished = true;
        foreach ($metager->getEngines() as $engine) {
            if ($engine->loaded) {
                $engine->setNew(false);
                $engine->markNew();
            }
        }

        \App\CacheHelper::put("loader_" . $metager->getSearchUid(), $metager->getEngines(), 60 * 60);
75

76
        # Die Ausgabe erstellen:
77
78
79
        $resultpage = $metager->createView($quicktipResults);
        foreach ($spamEntries as $index => $entry) {
            $entry = trim($entry);
Dominik Hebeler's avatar
Dominik Hebeler committed
80
81
82
            if (empty($entry)) {
                continue;
            }
83
            if (preg_match("/" . $entry . "/si", $metager->getEingabe())) {
Dominik Hebeler's avatar
Dominik Hebeler committed
84
                Cache::put('spam.' . $metager->getFokus() . "." . md5($metager->getEingabe()), $resultpage->render(), 604800);
85
86
87
            }
        }
        return $resultpage;
Dominik Hebeler's avatar
Dominik Hebeler committed
88
89
    }

90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    public function loadMore(Request $request)
    {
        /**
         * There are three forms of requests to the resultpage
         * 1. Initial Request: Loads the fastest searchengines and sends them to the user
         * 2. Load more results (with JS): Loads new search engines that answered after the initial request was send
         * 3. Load more results (without JS): Loads new search engines that answered within 1s timeout
         */
        if ($request->filled('loadMore') && $request->filled('script') && $request->input('script') === "yes") {
            return $this->loadMoreJS($request);
        }

    }

    private function loadMoreJS(Request $request)
    {
        # Create a MetaGer Instance with the supplied hash
        $hash = $request->input('loadMore', '');

109
110
111
112
113
114
        # Parser Skripte einhängen
        $dir = app_path() . "/Models/parserSkripte/";
        foreach (scandir($dir) as $filename) {
            $path = $dir . $filename;
            if (is_file($path)) {
                require_once $path;
115
            }
116
        }
117

118
119
120
121
        $engines = Cache::get($hash);
        if ($engines === null) {
            return response()->json(['finished' => true]);
        }
122

Dominik Hebeler's avatar
Dominik Hebeler committed
123
        $metager = new MetaGer(substr($hash, strpos($hash, "loader_") + 7));
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

        $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;
152
153
154
                }
            }
        }
155

Dominik Hebeler's avatar
Dominik Hebeler committed
156
157
158
159
160
161
162
163
164
165
166
167
        $finished = true;
        foreach ($engines as $engine) {
            if (!$engine->loaded) {
                $finished = false;
            } else {
                $engine->setNew(false);
                $engine->markNew();
            }
        }

        $result["finished"] = $finished;

168
        // Update new Engines
Dominik Hebeler's avatar
Dominik Hebeler committed
169
        \App\CacheHelper::put("loader_" . $metager->getSearchUid(), $metager->getEngines(), 1 * 60);
170
171
172
        return response()->json($result);
    }

173
174
175
176
177
178
179
180
    public function botProtection($redirect)
    {
        $hash = md5(date('YmdHi'));
        return view('botProtection')
            ->with('hash', $hash)
            ->with('r', $redirect);
    }

181
182
    public function get($url)
    {
183
        $ctx = stream_context_create(array('http' => array('timeout' => 2)));
184
        return file_get_contents($url, false, $ctx);
185
    }
186
187
188
189
190
191

    private function startsWith($haystack, $needle)
    {
        $length = strlen($needle);
        return (substr($haystack, 0, $length) === $needle);
    }
192
193
194

    public function tips(Request $request)
    {
195
196
197
198
199
200
        $tipserver = '';
        if (env('APP_ENV') === "development") {
            $tipserver = "https://dev.quicktips.metager.de/1.1/tips.xml";
        } else {
            $tipserver = "https://quicktips.metager.de/1.1/tips.xml";
        }
201
202
203
        if (LaravelLocalization::getCurrentLocale() == "en") {
            $tipserver .= "?locale=en";
        }
204
        $tips_text = file_get_contents($tipserver);
205
        $tips = [];
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
        try {
            $tips_xml = simplexml_load_string($tips_text);

            $tips_xml->registerXPathNamespace('mg', 'http://metager.de/tips/');
            $tips_xml = $tips_xml->xpath('mg:tip');
            foreach ($tips_xml as $tip_xml) {
                $tips[] = $tip_xml->__toString();
            }
        } catch (\Exception $e) {
            Log::error("A problem occurred loading tips from the tip server.");
            Log::error($e->getMessage());
            abort(500);
        }
        return view('tips')
            ->with('title', trans('tips.title'))
            ->with('tips', $tips);
    }
223
}