Add URL rewrites/replacements
[phinde.git] / src / phinde / Crawler.php
1 <?php
2 namespace phinde;
3
4 class Crawler
5 {
6     protected $es;
7     protected $queue;
8
9     /**
10      * If the links only should be shown, not queued
11      */
12     protected $showLinksOnly = false;
13
14     static $supportedTypes = array(
15         'application/atom+xml'  => '\\phinde\\LinkExtractor\\Atom',
16         'application/xhtml+xml' => '\\phinde\\LinkExtractor\\Html',
17         'text/html'             => '\\phinde\\LinkExtractor\\Html',
18     );
19
20     public function __construct()
21     {
22         $this->es = new Elasticsearch($GLOBALS['phinde']['elasticsearch']);
23         $this->queue = new Queue();
24     }
25
26     public function run(Retrieved $retrieved)
27     {
28         $linkInfos = $this->extractLinks($retrieved->httpRes);
29         $linkInfos = $this->filterLinks($linkInfos);
30         if ($this->showLinksOnly) {
31             $this->showLinks($linkInfos);
32             return false;
33         } else {
34             $this->enqueue($linkInfos);
35             return true;
36         }
37     }
38
39     protected function extractLinks(\HTTP_Request2_Response $res)
40     {
41         $mimetype = explode(';', $res->getHeader('content-type'))[0];
42         if (!isset(static::$supportedTypes[$mimetype])) {
43             Log::info("MIME type not supported for crawling: $mimetype");
44             return array();
45         }
46
47         $class = static::$supportedTypes[$mimetype];
48         $extractor = new $class();
49         return $extractor->extract($res);
50     }
51
52     protected function filterLinks($linkInfos)
53     {
54         $filteredLinkInfos = array();
55         foreach ($linkInfos as $linkInfo) {
56             $linkInfo->url = Helper::rewriteUrl($linkInfo->url);
57             $allowed = Helper::isUrlAllowed($linkInfo->url);
58             $crawl   = $allowed;
59             $index   = $GLOBALS['phinde']['indexNonAllowed'] || $allowed;
60
61             if ($crawl && count($GLOBALS['phinde']['crawlBlacklist'])) {
62                 foreach ($GLOBALS['phinde']['crawlBlacklist'] as $bl) {
63                     if (preg_match('#' . $bl . '#', $linkInfo->url)) {
64                         $crawl = false;
65                     }
66                 }
67             }
68
69             $linkInfo->known = $this->es->isKnown($linkInfo->url);
70             $linkInfo->crawl = $crawl;
71             $linkInfo->index = $index;
72             $filteredLinkInfos[] = $linkInfo;
73         }
74         return $filteredLinkInfos;
75     }
76
77     protected function enqueue($linkInfos)
78     {
79         foreach ($linkInfos as $linkInfo) {
80             if ($linkInfo->known) {
81                 continue;
82             }
83             if ($linkInfo->crawl || $linkInfo->index) {
84                 $this->es->markQueued($linkInfo->url);
85                 $actions = array();
86                 if ($linkInfo->index) {
87                     $actions[] = 'index';
88                 }
89                 if ($linkInfo->crawl) {
90                     $actions[] = 'crawl';
91                 }
92                 $this->queue->addToProcessList(
93                     $linkInfo->url, $actions
94                 );
95             }
96         }
97     }
98
99     protected function showLinks($linkInfos)
100     {
101         foreach ($linkInfos as $linkInfo) {
102             Log::msg($linkInfo->url);
103             if ($linkInfo->title) {
104                 Log::msg('   title: ' . $linkInfo->title);
105                 Log::msg('  source: ' . $linkInfo->source);
106                 Log::msg(
107                     '   known: ' . intval($linkInfo->known)
108                     . ', crawl: ' . intval($linkInfo->crawl)
109                     . ', index: ' . intval($linkInfo->index)
110                 );
111             }
112         }
113     }
114
115     public function setShowLinksOnly($showLinksOnly)
116     {
117         $this->showLinksOnly = $showLinksOnly;
118     }
119 }
120 ?>