38e3c3f907a84b40c9c25c8b85f4eb120ab48eea
[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             echo "MIME type not supported for indexing: $mimetype\n";
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             $allowed = Helper::isUrlAllowed($linkInfo->url);
57             $crawl   = $allowed;
58             $index   = $GLOBALS['phinde']['indexNonAllowed'] || $allowed;
59
60             if ($crawl && count($GLOBALS['phinde']['crawlBlacklist'])) {
61                 foreach ($GLOBALS['phinde']['crawlBlacklist'] as $bl) {
62                     if (preg_match('#' . $bl . '#', $linkInfo->url)) {
63                         $crawl = false;
64                     }
65                 }
66             }
67
68             $linkInfo->known = $this->es->isKnown($linkInfo->url);
69             $linkInfo->crawl = $crawl;
70             $linkInfo->index = $index;
71             $filteredLinkInfos[] = $linkInfo;
72         }
73         return $filteredLinkInfos;
74     }
75
76     protected function enqueue($linkInfos)
77     {
78         foreach ($linkInfos as $linkInfo) {
79             if ($linkInfo->known) {
80                 continue;
81             }
82             if ($linkInfo->crawl || $linkInfo->index) {
83                 $this->es->markQueued($linkInfo->url);
84                 $actions = array();
85                 if ($linkInfo->index) {
86                     $actions[] = 'index';
87                 }
88                 if ($linkInfo->crawl) {
89                     $actions[] = 'crawl';
90                 }
91                 $this->queue->addToProcessList(
92                     $linkInfo->url, $actions
93                 );
94             }
95         }
96     }
97
98     protected function showLinks($linkInfos)
99     {
100         foreach ($linkInfos as $linkInfo) {
101             echo $linkInfo->url . "\n";
102             if ($linkInfo->title) {
103                 echo '   title: ' . $linkInfo->title . "\n";
104                 echo '  source: ' . $linkInfo->source . "\n";
105                 echo '   known: ' . intval($linkInfo->known)
106                     . ', crawl: ' . intval($linkInfo->crawl)
107                     . ', index: ' . intval($linkInfo->index) . "\n";
108             }
109         }
110     }
111
112     public function setShowLinksOnly($showLinksOnly)
113     {
114         $this->showLinksOnly = $showLinksOnly;
115     }
116 }
117 ?>