]> git.wh0rd.org Git - tt-rss.git/blob - plugins/af_readability/init.php
6216d510a58cd59abe609a88012a7c3107808d90
[tt-rss.git] / plugins / af_readability / init.php
1 <?php
2 class Af_Readability extends Plugin {
3
4         private $host;
5
6         function about() {
7                 return array(1.0,
8                         "Try to inline article content using Readability",
9                         "fox");
10         }
11
12         function save() {
13                 //
14         }
15
16         function init($host)
17         {
18                 $this->host = $host;
19
20                 $host->add_hook($host::HOOK_ARTICLE_FILTER, $this);
21                 $host->add_hook($host::HOOK_PREFS_TAB, $this);
22                 $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this);
23                 $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this);
24
25                 $host->add_filter_action($this, "action_inline", __("Inline content"));
26         }
27
28         function hook_prefs_tab($args) {
29                 if ($args != "prefFeeds") return;
30
31                 print "<div dojoType=\"dijit.layout.AccordionPane\" title=\"".__('af_readability settings')."\">";
32
33                 print_notice("Enable the plugin for specific feeds in the feed editor.");
34
35                 $enabled_feeds = $this->host->get($this, "enabled_feeds");
36                 if (!array($enabled_feeds)) $enabled_feeds = array();
37
38                 $enabled_feeds = $this->filter_unknown_feeds($enabled_feeds);
39                 $this->host->set($this, "enabled_feeds", $enabled_feeds);
40
41                 if (count($enabled_feeds) > 0) {
42                         print "<h3>" . __("Currently enabled for (click to edit):") . "</h3>";
43
44                         print "<ul class=\"browseFeedList\" style=\"border-width : 1px\">";
45                         foreach ($enabled_feeds as $f) {
46                                 print "<li>" .
47                                         "<img src='images/pub_set.png'
48                                                 style='vertical-align : middle'> <a href='#'
49                                                 onclick='editFeed($f)'>".
50                                         getFeedTitle($f) . "</a></li>";
51                         }
52                         print "</ul>";
53                 }
54
55                 print "</div>";
56         }
57
58         function hook_prefs_edit_feed($feed_id) {
59                 print "<div class=\"dlgSec\">".__("Readability")."</div>";
60                 print "<div class=\"dlgSecCont\">";
61
62                 $enabled_feeds = $this->host->get($this, "enabled_feeds");
63                 if (!array($enabled_feeds)) $enabled_feeds = array();
64
65                 $key = array_search($feed_id, $enabled_feeds);
66                 $checked = $key !== FALSE ? "checked" : "";
67
68                 print "<hr/><input dojoType=\"dijit.form.CheckBox\" type=\"checkbox\" id=\"af_readability_enabled\"
69                         name=\"af_readability_enabled\"
70                         $checked>&nbsp;<label for=\"af_readability_enabled\">".__('Inline article content')."</label>";
71
72                 print "</div>";
73         }
74
75         function hook_prefs_save_feed($feed_id) {
76                 $enabled_feeds = $this->host->get($this, "enabled_feeds");
77                 if (!is_array($enabled_feeds)) $enabled_feeds = array();
78
79                 $enable = checkbox_to_sql_bool($_POST["af_readability_enabled"]) == 'true';
80                 $key = array_search($feed_id, $enabled_feeds);
81
82                 if ($enable) {
83                         if ($key === FALSE) {
84                                 array_push($enabled_feeds, $feed_id);
85                         }
86                 } else {
87                         if ($key !== FALSE) {
88                                 unset($enabled_feeds[$key]);
89                         }
90                 }
91
92                 $this->host->set($this, "enabled_feeds", $enabled_feeds);
93         }
94
95         function hook_article_filter_action($article, $action) {
96                 return $this->process_article($article);
97         }
98
99         function process_article($article) {
100
101                 if (!class_exists("Readability")) require_once(dirname(dirname(__DIR__)). "/lib/readability/Readability.php");
102
103                 if (function_exists("curl_init")) {
104                         $ch = curl_init($article["link"]);
105                         curl_setopt($ch, CURLOPT_TIMEOUT, 5);
106                         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
107                         curl_setopt($ch, CURLOPT_HEADER, true);
108                         curl_setopt($ch, CURLOPT_NOBODY, true);
109                         curl_setopt($ch, CURLOPT_FOLLOWLOCATION, !ini_get("open_basedir"));
110                         curl_setopt($ch, CURLOPT_USERAGENT, SELF_USER_AGENT);
111
112                         @$result = curl_exec($ch);
113                         $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
114
115                         if (strpos($content_type, "text/html") === FALSE)
116                                 return $article;
117                 }
118
119                 $tmp = fetch_file_contents($article["link"]);
120
121                 if ($tmp && mb_strlen($tmp) < 65535 * 4) {
122                         $tmpdoc = new DOMDocument("1.0", "UTF-8");
123
124                         if (!$tmpdoc->loadHTML($tmp))
125                                 return $article;
126
127                         if (strtolower($tmpdoc->encoding) != 'utf-8') {
128                                 $tmpxpath = new DOMXPath($tmpdoc);
129
130                                 foreach ($tmpxpath->query("//meta") as $elem) {
131                                         $elem->parentNode->removeChild($elem);
132                                 }
133
134                                 $tmp = $tmpdoc->saveHTML();
135                         }
136
137                         $r = new Readability($tmp, $article["link"]);
138
139                         if ($r->init()) {
140
141                                 $tmpxpath = new DOMXPath($r->dom);
142
143                                 $entries = $tmpxpath->query('(//a[@href]|//img[@src])');
144
145                                 foreach ($entries as $entry) {
146                                         if ($entry->hasAttribute("href")) {
147                                                 $entry->setAttribute("href",
148                                                         rewrite_relative_url($article["link"], $entry->getAttribute("href")));
149
150                                         }
151
152                                         if ($entry->hasAttribute("src")) {
153                                                 $entry->setAttribute("src",
154                                                         rewrite_relative_url($article["link"], $entry->getAttribute("src")));
155
156                                         }
157
158                                 }
159
160                                 $article["content"] = $r->articleContent->innerHTML;
161                         }
162                 }
163
164                 return $article;
165         }
166
167         function hook_article_filter($article) {
168
169                 $enabled_feeds = $this->host->get($this, "enabled_feeds");
170                 $key = array_search($article["feed"]["id"], $enabled_feeds);
171                 if ($key === FALSE) return $article;
172
173                 return $this->process_article($article);
174
175         }
176
177         function api_version() {
178                 return 2;
179         }
180
181         private function filter_unknown_feeds($enabled_feeds) {
182                 $tmp = array();
183
184                 foreach ($enabled_feeds as $feed) {
185
186                         $result = db_query("SELECT id FROM ttrss_feeds WHERE id = '$feed' AND owner_uid = " . $_SESSION["uid"]);
187
188                         if (db_num_rows($result) != 0) {
189                                 array_push($tmp, $feed);
190                         }
191                 }
192
193                 return $tmp;
194         }
195
196 }
197 ?>