Passed
Push — master ( 615432...534ea0 )
by Robin
03:11
created

CrawlController::setCrawlerId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Famdirksen\LaravelJobHandler\Http\Controllers;
4
5
use Carbon\Carbon;
6
use Famdirksen\LaravelJobHandler\Exceptions\CrawlerException;
7
use Famdirksen\LaravelJobHandler\Exceptions\CrawlerNotReachedTimeBetweenJobsException;
8
use Famdirksen\LaravelJobHandler\Exceptions\CrawlerSaveException;
9
use Famdirksen\LaravelJobHandler\Models\Crawlers;
10
use Famdirksen\LaravelJobHandler\Models\CrawlerStatus;
11
use Famdirksen\LaravelJobHandler\Models\CrawlerStatusLogs;
12
13
class CrawlController
14
{
15
    protected $crawler;
16
    protected $crawler_id;
17
18
19
    /**
20
     * Get the latest crawler data from the database
21
     */
22
    protected function getCrawler()
23
    {
24
        if (empty($this->crawler) || $this->crawler->id != $this->crawler_id) {
25
            $this->crawler = Crawlers::findOrFail($this->crawler_id);
26
        } else {
27
            $this->crawler = $this->crawler->fresh();
28
        }
29
    }
30
31
    /**
32
     * Set the crawler id
33
     *
34
     * @param $crawler_id
35
     */
36
    public function setCrawlerId($crawler_id)
37
    {
38
        $this->crawler_id = $crawler_id;
39
    }
40
41
    /**
42
     * Return the crawler id
43
     *
44
     * @return mixed
45
     */
46
    public function getCrawlerId()
47
    {
48
        return $this->crawler_id;
49
    }
50
51
    /**
52
     * Check if the controller is setup correctly
53
     *
54
     * @return bool
55
     */
56
    protected function controllerIsSetup()
57
    {
58
        if (!is_null($this->crawler_id)) {
59
            return true;
60
        }
61
62
        return false;
63
    }
64
65
    /**
66
     * Setup the crawler so it won't run twice at the same time
67
     *
68
     * @param $crawler_id
69
     */
70
    public function setupCrawler($crawler_id = null)
71
    {
72
        if (!is_null($crawler_id)) {
73
            $this->setCrawlerId($crawler_id);
74
        }
75
76
        if ($this->controllerIsSetup()) {
77
            $times = config('laravel-job-handler.run_times', 10);
78
79
            for ($x = 0; $x <= $times; $x++) {
80
                //fetch the last data
81
                $this->getCrawler();
82
83
                if (!$this->crawler->enabled) {
84
                    throw new CrawlerException('Crawler (#' . $this->crawler_id . ') - crawler isnt enabled in database');
85
                }
86
87
                $checkIfCrawlerCanBeRunned = $this->canCrawlerRunAfterPeriod();
88
89
                if ($checkIfCrawlerCanBeRunned['status']) {
90
                    if (is_null($this->crawler->latest_status)) {
91
                        //first time it runs...
92
                        break;
93
                    }
94
                    if ($this->crawler->latest_status == 2) {
95
                        //Done running...
96
                        break;
97
                    }
98
99
100
                    if ($this->crawler->latest_status == 3) {
101
                        throw new CrawlerException('Crawler (#' . $this->crawler_id . ') - last run had an error');
102
                    }
103
                } else {
104
                    throw new CrawlerNotReachedTimeBetweenJobsException('Has to wait ' . $checkIfCrawlerCanBeRunned['retry_in'] . ' more seconds to run');
105
                }
106
107
                if ($x == $times) {
108
                    $this->failCrawler('Crawler (#' . $this->crawler_id . ') - max execution time');
109
                }
110
111
                if ($this->crawler->status == 1) {
112
                    if ($this->crawler->multiple_crawlers) {
113
                        break;
114
                    }
115
116
                    sleep(config('laravel-job-handler.retry_in_seconds', 3)); //retry in 3 seconds
117
                }
118
            }
119
120
            $this->startCrawler();
121
        } else {
122
            throw new CrawlerException('CrawlController is not setup correctly.');
123
        }
124
    }
125
    /**
126
     * Start the crawler and save it to the database
127
     *
128
     * @param string $output
129
     */
130
    public function startCrawler($output = '')
131
    {
132
        return $this->addStatus(1, $output); //start running
133
    }
134
    /**
135
     * set the crawler as done so other scripts can run
136
     *
137
     * @param string $output
138
     */
139
    public function doneCrawler($output = '')
140
    {
141
        return $this->addStatus(2, $output); //done running
142
    }
143
144
    /**
145
     * Finishing the crawler
146
     *
147
     * @param string $output
148
     * @return bool
149
     */
150
    public function finish($output = '')
151
    {
152
        return $this->doneCrawler($output);
153
    }
154
    /**
155
     * crawler failed...
156
     *
157
     * @param string $output
158
     */
159
    public function failCrawler($output = '')
160
    {
161
        $this->addStatus(3, $output); //failed
162
163
        throw new CrawlerException($output.' - status 3');
164
    }
165
    /**
166
     * Save the latest crawler status to the database
167
     *
168
     * @param $status
169
     * @param string $output
170
     * @return bool
171
     */
172
    protected function addStatus($status, $output = '')
173
    {
174
        $crawlerstatus = new CrawlerStatus();
175
176
        $crawlerstatus->crawler_id = $this->crawler_id;
177
        $crawlerstatus->status = $status;
178
179
        if ($crawlerstatus->save()) {
180
            $this->crawler->latest_status = $status;
181
182
            $this->crawler->save();
183
184
            if (!empty($output)) {
185
                $crawlerstatuslog = new CrawlerStatusLogs();
186
187
                $crawlerstatuslog->status_id = $crawlerstatus->id;
0 ignored issues
show
Bug introduced by
The property status_id does not seem to exist on Famdirksen\LaravelJobHan...odels\CrawlerStatusLogs. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
188
                $crawlerstatuslog->output = $output;
0 ignored issues
show
Bug introduced by
The property output does not seem to exist on Famdirksen\LaravelJobHan...odels\CrawlerStatusLogs. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
189
190
                $crawlerstatuslog->save();
191
            }
192
193
            return true;
194
        } else {
195
            throw new CrawlerSaveException('Cannot save crawlerstatus to database...');
196
        }
197
    }
198
199
    /**
200
     * This will define when the job can be runned again
201
     *
202
     * @return array
203
     */
204
    public function canCrawlerRunAfterPeriod()
205
    {
206
        $this->getCrawler();
207
208
        if (is_null($this->crawler->time_between)) {
209
            return $this->canCrawlerRunAfterPeriodStatus(true);
210
        } else {
211
            $seconds = $this->crawler->time_between;
212
        }
213
214
        if (!is_null($this->crawler->last_runned_at)) {
215
            if ($this->crawler->last_runned_at <= Carbon::now()->subSeconds($seconds)) {
216
                return $this->canCrawlerRunAfterPeriodStatus(true);
217
            }
218
219
            return $this->canCrawlerRunAfterPeriodStatus(false, Carbon::parse($this->crawler->last_runned_at)->diffInSeconds(Carbon::now()->subSeconds($seconds)));
220
        } else {
221
            //crawler never runned, so it can run now
222
            return $this->canCrawlerRunAfterPeriodStatus(true);
223
        }
224
    }
225
226
    /**
227
     * Return the status for canCrawlerRunAfterPeriod method
228
     *
229
     * @param $status
230
     * @param int $retry_in
231
     * @return array
232
     */
233
    public function canCrawlerRunAfterPeriodStatus($status, $retry_in = 0)
234
    {
235
        return [
236
            'status' => $status,
237
            'retry_in' => $retry_in
238
        ];
239
    }
240
}
241