Passed
Push — master ( 031d2e...54d408 )
by Robin
03:05
created

CrawlController::canCrawlerRunAfterPeriodStatus()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
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
    public function setCrawlerId($crawler_id) {
31
        $this->crawler_id = $crawler_id;
32
    }
33
34
    /**
35
     * Setup the crawler so it won't run twice at the same time
36
     *
37
     * @param $crawler_id
38
     */
39
    public function setupCrawler($crawler_id)
40
    {
41
        $this->setCrawlerId($crawler_id);
42
        $times = config('laravel-job-handler.run_times', 10);
43
44
        for ($x = 0; $x <= $times; $x++) {
45
            //fetch the last data
46
            $this->getCrawler();
47
48
            if (!$this->crawler->enabled) {
49
                throw new CrawlerException('Crawler (#' . $this->crawler_id . ') - crawler isnt enabled in database');
50
            }
51
52
53
            $checkIfCrawlerCanBeRunned = $this->canCrawlerRunAfterPeriod();
54
55
            if($checkIfCrawlerCanBeRunned['status']) {
56
                if (is_null($this->crawler->latest_status)) {
57
                    //first time it runs...
58
                    break;
59
                }
60
                if ($this->crawler->latest_status == 2) {
61
                    //Done running...
62
                    break;
63
                }
64
65
66
                if ($this->crawler->latest_status == 3) {
67
                    throw new CrawlerException('Crawler (#' . $this->crawler_id . ') - last run had an error');
68
                }
69
            } else {
70
                throw new CrawlerNotReachedTimeBetweenJobsException('Has to wait '.$checkIfCrawlerCanBeRunned['retry_in'].' more seconds to run');
71
            }
72
73
            if ($x == $times) {
74
                $this->failCrawler('Crawler (#'.$this->crawler_id.') - max execution time');
75
            }
76
77
            if ($this->crawler->status == 1) {
78
                if ($this->crawler->multiple_crawlers) {
79
                    break;
80
                }
81
82
                sleep(config('laravel-job-handler.retry_in_seconds', 3)); //retry in 3 seconds
83
            }
84
        }
85
86
        $this->startCrawler();
87
    }
88
    /**
89
     * Start the crawler and save it to the database
90
     *
91
     * @param string $output
92
     */
93
    public function startCrawler($output = '')
94
    {
95
        return $this->addStatus(1, $output); //start running
96
    }
97
    /**
98
     * set the crawler as done so other scripts can run
99
     *
100
     * @param string $output
101
     */
102
    public function doneCrawler($output = '')
103
    {
104
        return $this->addStatus(2, $output); //done running
105
    }
106
    public function finish($output = '')
107
    {
108
        return $this->doneCrawler($output);
109
    }
110
    /**
111
     * crawler failed...
112
     *
113
     * @param string $output
114
     */
115
    public function failCrawler($output = '')
116
    {
117
        $this->addStatus(3, $output); //failed
118
119
        throw new CrawlerException($output.' - status 3');
120
    }
121
    /**
122
     * save the latest crawler status to the database
123
     *
124
     * @param $status
125
     * @param string $output
126
     * @return bool
127
     */
128
    protected function addStatus($status, $output = '')
129
    {
130
        $crawlerstatus = new CrawlerStatus();
131
132
        $crawlerstatus->crawler_id = $this->crawler_id;
133
        $crawlerstatus->status = $status;
134
135
        if ($crawlerstatus->save()) {
136
            $this->crawler->latest_status = $status;
137
138
            $this->crawler->save();
139
140
            if (!empty($output)) {
141
                $crawlerstatuslog = new CrawlerStatusLogs();
142
143
                $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...
144
                $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...
145
146
                $crawlerstatuslog->save();
147
            }
148
149
            return true;
150
        } else {
151
            throw new CrawlerSaveException('Cannot save crawlerstatus to database...');
152
        }
153
    }
154
155
    /**
156
     * This will define when the job can be runned again
157
     *
158
     * @return array
159
     */
160
    public function canCrawlerRunAfterPeriod() {
161
        $this->getCrawler();
162
163
        if(is_null($this->crawler->time_between)) {
164
            return $this->canCrawlerRunAfterPeriodStatus(true);
165
        } else {
166
            $seconds = $this->crawler->time_between;
167
        }
168
169
        if(!is_null($this->crawler->last_runned_at)) {
170
            if ($this->crawler->last_runned_at <= Carbon::now()->subSeconds($seconds)) {
171
                return $this->canCrawlerRunAfterPeriodStatus(true);
172
            }
173
174
            return $this->canCrawlerRunAfterPeriodStatus(false, Carbon::parse($this->crawler->last_runned_at)->diffInSeconds(Carbon::now()->subSeconds($seconds)));
175
        } else {
176
            //crawler never runned, so it can run now
177
            return $this->canCrawlerRunAfterPeriodStatus(true);
178
        }
179
    }
180
    public function canCrawlerRunAfterPeriodStatus($status, $retry_in = 0) {
181
        return [
182
            'status' => $status,
183
            'retry_in' => $retry_in
184
        ];
185
    }
186
}
187