Do not use STDOUT and STDERR constants
[phinde.git] / src / phinde / Fetcher.php
1 <?php
2 namespace phinde;
3
4 class Fetcher
5 {
6     protected $es;
7
8     public function __construct()
9     {
10         $this->es = new Elasticsearch($GLOBALS['phinde']['elasticsearch']);
11     }
12
13     /**
14      * @return Retrieved HTTP response and elasticsearch document
15      */
16     public function fetch($url, $actions, $force = false)
17     {
18         $url = Helper::rewriteUrl($url);
19
20         $esDoc  = $this->es->get($url);
21         $locUrl = null;
22         if (isset($esDoc->status->location)
23             && $esDoc->status->location != ''
24         ) {
25             //Location redirect: Use modified time of known target
26             $locUrl = $esDoc->status->location;
27             $locUrl = Helper::rewriteUrl($locUrl);
28             $esDoc = $this->es->get($locUrl);
29         }
30
31         $types = array();
32         foreach ($actions as $action) {
33             $types = array_merge($types, array_keys($action::$supportedTypes));
34         }
35         $types = array_unique($types);
36
37         $req = new HttpRequest($url);
38         $req->setHeader('accept', implode(',', $types));
39         if (!$force && $esDoc
40             && isset($esDoc->status->processed)
41             && $esDoc->status->processed != ''
42         ) {
43             $nCrawlTime = strtotime($esDoc->status->processed);
44             $req->setHeader('If-Modified-Since: ' . gmdate('r', $nCrawlTime));
45         }
46
47         $res = $req->send();
48         $effUrl = Helper::removeAnchor($res->getEffectiveUrl());
49         $effUrl = Helper::rewriteUrl($effUrl);
50
51         if ($res->getStatus() === 304) {
52             //not modified since last time, so don't crawl again
53             if ($locUrl !== null && $effUrl != $locUrl) {
54                 //location URL changed, and we used the wrong crawl timestampx
55                 $this->storeRedirect($url, $effUrl);
56                 return $this->fetch($url, $actions, $force);
57             }
58
59             Log::info("Not modified since last fetch");
60             return false;
61         } else if ($res->getStatus() !== 200) {
62             throw new \Exception(
63                 "Response code is not 200 but "
64                 . $res->getStatus() . ", stopping"
65             );
66         }
67
68         if ($effUrl != $url) {
69             $this->storeRedirect($url, $effUrl);
70             $url = $effUrl;
71             $esDoc = $this->es->get($url);
72         }
73         //FIXME: etag, hash on content
74
75         $retrieved = new Retrieved();
76         $retrieved->httpRes = $res;
77         $retrieved->esDoc   = $esDoc;
78         $retrieved->url     = $url;
79         return $retrieved;
80     }
81
82     protected function storeRedirect($url, $target)
83     {
84         $esDoc = Helper::baseDoc($url);
85         $esDoc->status = (object) array(
86             'location' => $target,
87             'findable' => false,
88         );
89         $this->storeDoc($url, $esDoc);
90     }
91
92     public function storeDoc($url, $esDoc)
93     {
94         Log::info("Store $url");
95         $esDoc->status->processed = gmdate('c');
96         $r = new Elasticsearch_Request(
97             $GLOBALS['phinde']['elasticsearch'] . 'document/'
98             . ElasticSearch::getDocId($url),
99             \HTTP_Request2::METHOD_PUT
100         );
101         $r->setBody(json_encode($esDoc));
102         $r->send();
103     }
104 }
105 ?>