@@ -1,70 +1,70 @@ discard block |
||
1 | 1 | <?php |
2 | 2 | class Af_Psql_Trgm extends Plugin { |
3 | 3 | |
4 | - /* @var PluginHost $host */ |
|
5 | - private $host; |
|
4 | + /* @var PluginHost $host */ |
|
5 | + private $host; |
|
6 | 6 | |
7 | - public function about() { |
|
8 | - return array(1.0, |
|
9 | - "Marks similar articles as read (requires pg_trgm)", |
|
10 | - "fox"); |
|
11 | - } |
|
7 | + public function about() { |
|
8 | + return array(1.0, |
|
9 | + "Marks similar articles as read (requires pg_trgm)", |
|
10 | + "fox"); |
|
11 | + } |
|
12 | 12 | |
13 | - public function save() { |
|
14 | - $similarity = (float) $_POST["similarity"]; |
|
15 | - $min_title_length = (int) $_POST["min_title_length"]; |
|
16 | - $enable_globally = checkbox_to_sql_bool($_POST["enable_globally"]); |
|
13 | + public function save() { |
|
14 | + $similarity = (float) $_POST["similarity"]; |
|
15 | + $min_title_length = (int) $_POST["min_title_length"]; |
|
16 | + $enable_globally = checkbox_to_sql_bool($_POST["enable_globally"]); |
|
17 | 17 | |
18 | - if ($similarity < 0) { |
|
19 | - $similarity = 0; |
|
20 | - } |
|
21 | - if ($similarity > 1) { |
|
22 | - $similarity = 1; |
|
23 | - } |
|
18 | + if ($similarity < 0) { |
|
19 | + $similarity = 0; |
|
20 | + } |
|
21 | + if ($similarity > 1) { |
|
22 | + $similarity = 1; |
|
23 | + } |
|
24 | 24 | |
25 | - if ($min_title_length < 0) { |
|
26 | - $min_title_length = 0; |
|
27 | - } |
|
25 | + if ($min_title_length < 0) { |
|
26 | + $min_title_length = 0; |
|
27 | + } |
|
28 | 28 | |
29 | - $similarity = sprintf("%.2f", $similarity); |
|
29 | + $similarity = sprintf("%.2f", $similarity); |
|
30 | 30 | |
31 | - $this->host->set($this, "similarity", $similarity); |
|
32 | - $this->host->set($this, "min_title_length", $min_title_length); |
|
33 | - $this->host->set($this, "enable_globally", $enable_globally); |
|
31 | + $this->host->set($this, "similarity", $similarity); |
|
32 | + $this->host->set($this, "min_title_length", $min_title_length); |
|
33 | + $this->host->set($this, "enable_globally", $enable_globally); |
|
34 | 34 | |
35 | - echo T_sprintf("Data saved (%s, %d)", $similarity, $enable_globally); |
|
36 | - } |
|
35 | + echo T_sprintf("Data saved (%s, %d)", $similarity, $enable_globally); |
|
36 | + } |
|
37 | 37 | |
38 | - public function init($host) { |
|
39 | - $this->host = $host; |
|
38 | + public function init($host) { |
|
39 | + $this->host = $host; |
|
40 | 40 | |
41 | - $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
42 | - $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
43 | - $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this); |
|
44 | - $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this); |
|
45 | - $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); |
|
41 | + $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
42 | + $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
43 | + $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this); |
|
44 | + $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this); |
|
45 | + $host->add_hook($host::HOOK_ARTICLE_BUTTON, $this); |
|
46 | 46 | |
47 | - } |
|
47 | + } |
|
48 | 48 | |
49 | - public function get_js() { |
|
50 | - return file_get_contents(__DIR__."/init.js"); |
|
51 | - } |
|
49 | + public function get_js() { |
|
50 | + return file_get_contents(__DIR__."/init.js"); |
|
51 | + } |
|
52 | 52 | |
53 | - public function showrelated() { |
|
54 | - $id = (int) $_REQUEST['param']; |
|
55 | - $owner_uid = $_SESSION["uid"]; |
|
53 | + public function showrelated() { |
|
54 | + $id = (int) $_REQUEST['param']; |
|
55 | + $owner_uid = $_SESSION["uid"]; |
|
56 | 56 | |
57 | - $sth = $this->pdo->prepare("SELECT title FROM ttrss_entries, ttrss_user_entries |
|
57 | + $sth = $this->pdo->prepare("SELECT title FROM ttrss_entries, ttrss_user_entries |
|
58 | 58 | WHERE ref_id = id AND id = ? AND owner_uid = ?"); |
59 | - $sth->execute([$id, $owner_uid]); |
|
59 | + $sth->execute([$id, $owner_uid]); |
|
60 | 60 | |
61 | - if ($row = $sth->fetch()) { |
|
61 | + if ($row = $sth->fetch()) { |
|
62 | 62 | |
63 | - $title = $row['title']; |
|
63 | + $title = $row['title']; |
|
64 | 64 | |
65 | - print "<p>$title</p>"; |
|
65 | + print "<p>$title</p>"; |
|
66 | 66 | |
67 | - $sth = $this->pdo->prepare("SELECT ttrss_entries.id AS id, |
|
67 | + $sth = $this->pdo->prepare("SELECT ttrss_entries.id AS id, |
|
68 | 68 | feed_id, |
69 | 69 | ttrss_entries.title AS title, |
70 | 70 | updated, link, |
@@ -81,83 +81,83 @@ discard block |
||
81 | 81 | sm DESC, date_entered DESC |
82 | 82 | LIMIT 10"); |
83 | 83 | |
84 | - $sth->execute([$title, $owner_uid, $id]); |
|
84 | + $sth->execute([$title, $owner_uid, $id]); |
|
85 | 85 | |
86 | - print "<ul class='panel panel-scrollable'>"; |
|
86 | + print "<ul class='panel panel-scrollable'>"; |
|
87 | 87 | |
88 | - while ($line = $sth->fetch()) { |
|
89 | - print "<li style='display : flex'>"; |
|
90 | - print "<i class='material-icons'>bookmark_outline</i>"; |
|
88 | + while ($line = $sth->fetch()) { |
|
89 | + print "<li style='display : flex'>"; |
|
90 | + print "<i class='material-icons'>bookmark_outline</i>"; |
|
91 | 91 | |
92 | - $sm = sprintf("%.2f", $line['sm']); |
|
93 | - $article_link = htmlspecialchars($line["link"]); |
|
92 | + $sm = sprintf("%.2f", $line['sm']); |
|
93 | + $article_link = htmlspecialchars($line["link"]); |
|
94 | 94 | |
95 | - print "<div style='flex-grow : 2'>"; |
|
95 | + print "<div style='flex-grow : 2'>"; |
|
96 | 96 | |
97 | - print " <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"$article_link\">". |
|
98 | - $line["title"]."</a>"; |
|
97 | + print " <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"$article_link\">". |
|
98 | + $line["title"]."</a>"; |
|
99 | 99 | |
100 | - print " (<a href=\"#\" onclick=\"Feeds.open({feed:".$line["feed_id"]."})\">". |
|
101 | - htmlspecialchars($line["feed_title"])."</a>)"; |
|
100 | + print " (<a href=\"#\" onclick=\"Feeds.open({feed:".$line["feed_id"]."})\">". |
|
101 | + htmlspecialchars($line["feed_title"])."</a>)"; |
|
102 | 102 | |
103 | - print " — $sm"; |
|
103 | + print " — $sm"; |
|
104 | 104 | |
105 | - print "</div>"; |
|
105 | + print "</div>"; |
|
106 | 106 | |
107 | - print "<div style='text-align : right' class='text-muted'>".smart_date_time(strtotime($line["updated"]))."</div>"; |
|
107 | + print "<div style='text-align : right' class='text-muted'>".smart_date_time(strtotime($line["updated"]))."</div>"; |
|
108 | 108 | |
109 | - print "</li>"; |
|
110 | - } |
|
109 | + print "</li>"; |
|
110 | + } |
|
111 | 111 | |
112 | - print "</ul>"; |
|
112 | + print "</ul>"; |
|
113 | 113 | |
114 | - } |
|
114 | + } |
|
115 | 115 | |
116 | - print "<footer class='text-center'>"; |
|
117 | - print "<button dojoType='dijit.form.Button' onclick=\"dijit.byId('trgmRelatedDlg').hide()\">".__('Close this window')."</button>"; |
|
118 | - print "</footer>"; |
|
116 | + print "<footer class='text-center'>"; |
|
117 | + print "<button dojoType='dijit.form.Button' onclick=\"dijit.byId('trgmRelatedDlg').hide()\">".__('Close this window')."</button>"; |
|
118 | + print "</footer>"; |
|
119 | 119 | |
120 | 120 | |
121 | - } |
|
121 | + } |
|
122 | 122 | |
123 | - public function hook_article_button($line) { |
|
124 | - return "<i style=\"cursor : pointer\" class='material-icons' |
|
123 | + public function hook_article_button($line) { |
|
124 | + return "<i style=\"cursor : pointer\" class='material-icons' |
|
125 | 125 | onclick=\"Plugins.Psql_Trgm.showRelated(".$line["id"].")\" |
126 | 126 | title='".__('Show related articles')."'>bookmark_outline</i>"; |
127 | - } |
|
127 | + } |
|
128 | 128 | |
129 | - public function hook_prefs_tab($args) { |
|
130 | - if ($args != "prefFeeds") { |
|
131 | - return; |
|
132 | - } |
|
129 | + public function hook_prefs_tab($args) { |
|
130 | + if ($args != "prefFeeds") { |
|
131 | + return; |
|
132 | + } |
|
133 | 133 | |
134 | - print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
134 | + print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
135 | 135 | title=\"<i class='material-icons'>extension</i> ".__('Mark similar articles as read')."\">"; |
136 | 136 | |
137 | - if (DB_TYPE != "pgsql") { |
|
138 | - print_error("Database type not supported."); |
|
139 | - } else { |
|
137 | + if (DB_TYPE != "pgsql") { |
|
138 | + print_error("Database type not supported."); |
|
139 | + } else { |
|
140 | 140 | |
141 | - $res = $this->pdo->query("select 'similarity'::regproc"); |
|
141 | + $res = $this->pdo->query("select 'similarity'::regproc"); |
|
142 | 142 | |
143 | - if (!$res->fetch()) { |
|
144 | - print_error("pg_trgm extension not found."); |
|
145 | - } |
|
143 | + if (!$res->fetch()) { |
|
144 | + print_error("pg_trgm extension not found."); |
|
145 | + } |
|
146 | 146 | |
147 | - $similarity = $this->host->get($this, "similarity"); |
|
148 | - $min_title_length = $this->host->get($this, "min_title_length"); |
|
149 | - $enable_globally = $this->host->get($this, "enable_globally"); |
|
147 | + $similarity = $this->host->get($this, "similarity"); |
|
148 | + $min_title_length = $this->host->get($this, "min_title_length"); |
|
149 | + $enable_globally = $this->host->get($this, "enable_globally"); |
|
150 | 150 | |
151 | - if (!$similarity) { |
|
152 | - $similarity = '0.75'; |
|
153 | - } |
|
154 | - if (!$min_title_length) { |
|
155 | - $min_title_length = '32'; |
|
156 | - } |
|
151 | + if (!$similarity) { |
|
152 | + $similarity = '0.75'; |
|
153 | + } |
|
154 | + if (!$min_title_length) { |
|
155 | + $min_title_length = '32'; |
|
156 | + } |
|
157 | 157 | |
158 | - print "<form dojoType=\"dijit.form.Form\">"; |
|
158 | + print "<form dojoType=\"dijit.form.Form\">"; |
|
159 | 159 | |
160 | - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> |
|
160 | + print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> |
|
161 | 161 | evt.preventDefault(); |
162 | 162 | if (this.validate()) { |
163 | 163 | console.log(dojo.objectToQuery(this.getValues())); |
@@ -171,206 +171,206 @@ discard block |
||
171 | 171 | } |
172 | 172 | </script>"; |
173 | 173 | |
174 | - print_hidden("op", "pluginhandler"); |
|
175 | - print_hidden("method", "save"); |
|
176 | - print_hidden("plugin", "af_psql_trgm"); |
|
174 | + print_hidden("op", "pluginhandler"); |
|
175 | + print_hidden("method", "save"); |
|
176 | + print_hidden("plugin", "af_psql_trgm"); |
|
177 | 177 | |
178 | - print "<h2>".__("Global settings")."</h2>"; |
|
178 | + print "<h2>".__("Global settings")."</h2>"; |
|
179 | 179 | |
180 | - print_notice("Enable for specific feeds in the feed editor."); |
|
180 | + print_notice("Enable for specific feeds in the feed editor."); |
|
181 | 181 | |
182 | - print "<fieldset>"; |
|
182 | + print "<fieldset>"; |
|
183 | 183 | |
184 | - print "<label>".__("Minimum similarity:")."</label> "; |
|
185 | - print "<input dojoType=\"dijit.form.NumberSpinner\" |
|
184 | + print "<label>".__("Minimum similarity:")."</label> "; |
|
185 | + print "<input dojoType=\"dijit.form.NumberSpinner\" |
|
186 | 186 | placeholder=\"0.75\" id='psql_trgm_similarity' |
187 | 187 | required=\"1\" name=\"similarity\" value=\"$similarity\">"; |
188 | 188 | |
189 | - print "<div dojoType='dijit.Tooltip' connectId='psql_trgm_similarity' position='below'>". |
|
190 | - __("PostgreSQL trigram extension returns string similarity as a floating point number (0-1). Setting it too low might produce false positives, zero disables checking."). |
|
191 | - "</div>"; |
|
189 | + print "<div dojoType='dijit.Tooltip' connectId='psql_trgm_similarity' position='below'>". |
|
190 | + __("PostgreSQL trigram extension returns string similarity as a floating point number (0-1). Setting it too low might produce false positives, zero disables checking."). |
|
191 | + "</div>"; |
|
192 | 192 | |
193 | - print "</fieldset><fieldset>"; |
|
193 | + print "</fieldset><fieldset>"; |
|
194 | 194 | |
195 | - print "<label>".__("Minimum title length:")."</label> "; |
|
196 | - print "<input dojoType=\"dijit.form.NumberSpinner\" |
|
195 | + print "<label>".__("Minimum title length:")."</label> "; |
|
196 | + print "<input dojoType=\"dijit.form.NumberSpinner\" |
|
197 | 197 | placeholder=\"32\" |
198 | 198 | required=\"1\" name=\"min_title_length\" value=\"$min_title_length\">"; |
199 | 199 | |
200 | - print "</fieldset><fieldset>"; |
|
200 | + print "</fieldset><fieldset>"; |
|
201 | 201 | |
202 | - print "<label class='checkbox'>"; |
|
203 | - print_checkbox("enable_globally", $enable_globally); |
|
204 | - print " ".__("Enable for all feeds:"); |
|
205 | - print "</label>"; |
|
202 | + print "<label class='checkbox'>"; |
|
203 | + print_checkbox("enable_globally", $enable_globally); |
|
204 | + print " ".__("Enable for all feeds:"); |
|
205 | + print "</label>"; |
|
206 | 206 | |
207 | - print "</fieldset>"; |
|
207 | + print "</fieldset>"; |
|
208 | 208 | |
209 | - print_button("submit", __("Save"), "class='alt-primary'"); |
|
210 | - print "</form>"; |
|
209 | + print_button("submit", __("Save"), "class='alt-primary'"); |
|
210 | + print "</form>"; |
|
211 | 211 | |
212 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
213 | - if (!array($enabled_feeds)) { |
|
214 | - $enabled_feeds = array(); |
|
215 | - } |
|
212 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
213 | + if (!array($enabled_feeds)) { |
|
214 | + $enabled_feeds = array(); |
|
215 | + } |
|
216 | 216 | |
217 | - $enabled_feeds = $this->filter_unknown_feeds($enabled_feeds); |
|
218 | - $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
217 | + $enabled_feeds = $this->filter_unknown_feeds($enabled_feeds); |
|
218 | + $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
219 | 219 | |
220 | - if (count($enabled_feeds) > 0) { |
|
221 | - print "<h3>".__("Currently enabled for (click to edit):")."</h3>"; |
|
220 | + if (count($enabled_feeds) > 0) { |
|
221 | + print "<h3>".__("Currently enabled for (click to edit):")."</h3>"; |
|
222 | 222 | |
223 | - print "<ul class=\"panel panel-scrollable list list-unstyled\">"; |
|
224 | - foreach ($enabled_feeds as $f) { |
|
225 | - print "<li>". |
|
226 | - "<i class='material-icons'>rss_feed</i> <a href='#' |
|
223 | + print "<ul class=\"panel panel-scrollable list list-unstyled\">"; |
|
224 | + foreach ($enabled_feeds as $f) { |
|
225 | + print "<li>". |
|
226 | + "<i class='material-icons'>rss_feed</i> <a href='#' |
|
227 | 227 | onclick='CommonDialogs.editFeed($f)'>". |
228 | - Feeds::getFeedTitle($f)."</a></li>"; |
|
229 | - } |
|
230 | - print "</ul>"; |
|
231 | - } |
|
232 | - } |
|
228 | + Feeds::getFeedTitle($f)."</a></li>"; |
|
229 | + } |
|
230 | + print "</ul>"; |
|
231 | + } |
|
232 | + } |
|
233 | 233 | |
234 | - print "</div>"; |
|
235 | - } |
|
234 | + print "</div>"; |
|
235 | + } |
|
236 | 236 | |
237 | - public function hook_prefs_edit_feed($feed_id) { |
|
238 | - print "<header>".__("Similarity (pg_trgm)")."</header>"; |
|
239 | - print "<section>"; |
|
237 | + public function hook_prefs_edit_feed($feed_id) { |
|
238 | + print "<header>".__("Similarity (pg_trgm)")."</header>"; |
|
239 | + print "<section>"; |
|
240 | 240 | |
241 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
242 | - if (!array($enabled_feeds)) { |
|
243 | - $enabled_feeds = array(); |
|
244 | - } |
|
241 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
242 | + if (!array($enabled_feeds)) { |
|
243 | + $enabled_feeds = array(); |
|
244 | + } |
|
245 | 245 | |
246 | - $key = array_search($feed_id, $enabled_feeds); |
|
247 | - $checked = $key !== false ? "checked" : ""; |
|
246 | + $key = array_search($feed_id, $enabled_feeds); |
|
247 | + $checked = $key !== false ? "checked" : ""; |
|
248 | 248 | |
249 | - print "<fieldset>"; |
|
249 | + print "<fieldset>"; |
|
250 | 250 | |
251 | - print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='trgm_similarity_enabled' |
|
251 | + print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='trgm_similarity_enabled' |
|
252 | 252 | name='trgm_similarity_enabled' $checked> ".__('Mark similar articles as read')."</label>"; |
253 | 253 | |
254 | - print "</fieldset>"; |
|
254 | + print "</fieldset>"; |
|
255 | 255 | |
256 | - print "</section>"; |
|
257 | - } |
|
256 | + print "</section>"; |
|
257 | + } |
|
258 | 258 | |
259 | - public function hook_prefs_save_feed($feed_id) { |
|
260 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
261 | - if (!is_array($enabled_feeds)) { |
|
262 | - $enabled_feeds = array(); |
|
263 | - } |
|
259 | + public function hook_prefs_save_feed($feed_id) { |
|
260 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
261 | + if (!is_array($enabled_feeds)) { |
|
262 | + $enabled_feeds = array(); |
|
263 | + } |
|
264 | 264 | |
265 | - $enable = checkbox_to_sql_bool($_POST["trgm_similarity_enabled"]); |
|
266 | - $key = array_search($feed_id, $enabled_feeds); |
|
265 | + $enable = checkbox_to_sql_bool($_POST["trgm_similarity_enabled"]); |
|
266 | + $key = array_search($feed_id, $enabled_feeds); |
|
267 | 267 | |
268 | - if ($enable) { |
|
269 | - if ($key === false) { |
|
270 | - array_push($enabled_feeds, $feed_id); |
|
271 | - } |
|
272 | - } else { |
|
273 | - if ($key !== false) { |
|
274 | - unset($enabled_feeds[$key]); |
|
275 | - } |
|
276 | - } |
|
268 | + if ($enable) { |
|
269 | + if ($key === false) { |
|
270 | + array_push($enabled_feeds, $feed_id); |
|
271 | + } |
|
272 | + } else { |
|
273 | + if ($key !== false) { |
|
274 | + unset($enabled_feeds[$key]); |
|
275 | + } |
|
276 | + } |
|
277 | 277 | |
278 | - $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
279 | - } |
|
278 | + $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
279 | + } |
|
280 | 280 | |
281 | - public function hook_article_filter($article) { |
|
281 | + public function hook_article_filter($article) { |
|
282 | 282 | |
283 | - if (DB_TYPE != "pgsql") { |
|
284 | - return $article; |
|
285 | - } |
|
283 | + if (DB_TYPE != "pgsql") { |
|
284 | + return $article; |
|
285 | + } |
|
286 | 286 | |
287 | - $res = $this->pdo->query("select 'similarity'::regproc"); |
|
288 | - if (!$res->fetch()) { |
|
289 | - return $article; |
|
290 | - } |
|
287 | + $res = $this->pdo->query("select 'similarity'::regproc"); |
|
288 | + if (!$res->fetch()) { |
|
289 | + return $article; |
|
290 | + } |
|
291 | 291 | |
292 | - $enable_globally = $this->host->get($this, "enable_globally"); |
|
292 | + $enable_globally = $this->host->get($this, "enable_globally"); |
|
293 | 293 | |
294 | - if (!$enable_globally) { |
|
295 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
296 | - $key = array_search($article["feed"]["id"], $enabled_feeds); |
|
297 | - if ($key === false) { |
|
298 | - return $article; |
|
299 | - } |
|
300 | - } |
|
294 | + if (!$enable_globally) { |
|
295 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
296 | + $key = array_search($article["feed"]["id"], $enabled_feeds); |
|
297 | + if ($key === false) { |
|
298 | + return $article; |
|
299 | + } |
|
300 | + } |
|
301 | 301 | |
302 | - $similarity = (float) $this->host->get($this, "similarity"); |
|
303 | - if ($similarity < 0.01) { |
|
304 | - return $article; |
|
305 | - } |
|
302 | + $similarity = (float) $this->host->get($this, "similarity"); |
|
303 | + if ($similarity < 0.01) { |
|
304 | + return $article; |
|
305 | + } |
|
306 | 306 | |
307 | - $min_title_length = (int) $this->host->get($this, "min_title_length"); |
|
308 | - if (mb_strlen($article["title"]) < $min_title_length) { |
|
309 | - return $article; |
|
310 | - } |
|
307 | + $min_title_length = (int) $this->host->get($this, "min_title_length"); |
|
308 | + if (mb_strlen($article["title"]) < $min_title_length) { |
|
309 | + return $article; |
|
310 | + } |
|
311 | 311 | |
312 | - $owner_uid = $article["owner_uid"]; |
|
313 | - $entry_guid = $article["guid_hashed"]; |
|
314 | - $title_escaped = $article["title"]; |
|
312 | + $owner_uid = $article["owner_uid"]; |
|
313 | + $entry_guid = $article["guid_hashed"]; |
|
314 | + $title_escaped = $article["title"]; |
|
315 | 315 | |
316 | - // trgm does not return similarity=1 for completely equal strings |
|
316 | + // trgm does not return similarity=1 for completely equal strings |
|
317 | 317 | |
318 | - $sth = $this->pdo->prepare("SELECT COUNT(id) AS nequal |
|
318 | + $sth = $this->pdo->prepare("SELECT COUNT(id) AS nequal |
|
319 | 319 | FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id AND |
320 | 320 | date_entered >= NOW() - interval '3 days' AND |
321 | 321 | title = ? AND |
322 | 322 | guid != ? AND |
323 | 323 | owner_uid = ?"); |
324 | - $sth->execute([$title_escaped, $entry_guid, $owner_uid]); |
|
324 | + $sth->execute([$title_escaped, $entry_guid, $owner_uid]); |
|
325 | 325 | |
326 | - $row = $sth->fetch(); |
|
327 | - $nequal = $row['nequal']; |
|
326 | + $row = $sth->fetch(); |
|
327 | + $nequal = $row['nequal']; |
|
328 | 328 | |
329 | - Debug::log("af_psql_trgm: num equals: $nequal", Debug::$LOG_EXTENDED); |
|
329 | + Debug::log("af_psql_trgm: num equals: $nequal", Debug::$LOG_EXTENDED); |
|
330 | 330 | |
331 | - if ($nequal != 0) { |
|
332 | - $article["force_catchup"] = true; |
|
333 | - return $article; |
|
334 | - } |
|
331 | + if ($nequal != 0) { |
|
332 | + $article["force_catchup"] = true; |
|
333 | + return $article; |
|
334 | + } |
|
335 | 335 | |
336 | - $sth = $this->pdo->prepare("SELECT MAX(SIMILARITY(title, ?)) AS ms |
|
336 | + $sth = $this->pdo->prepare("SELECT MAX(SIMILARITY(title, ?)) AS ms |
|
337 | 337 | FROM ttrss_entries, ttrss_user_entries WHERE ref_id = id AND |
338 | 338 | date_entered >= NOW() - interval '1 day' AND |
339 | 339 | guid != ? AND |
340 | 340 | owner_uid = ?"); |
341 | - $sth->execute([$title_escaped, $entry_guid, $owner_uid]); |
|
341 | + $sth->execute([$title_escaped, $entry_guid, $owner_uid]); |
|
342 | 342 | |
343 | - $row = $sth->fetch(); |
|
344 | - $similarity_result = $row['ms']; |
|
343 | + $row = $sth->fetch(); |
|
344 | + $similarity_result = $row['ms']; |
|
345 | 345 | |
346 | - Debug::log("af_psql_trgm: similarity result: $similarity_result", Debug::$LOG_EXTENDED); |
|
346 | + Debug::log("af_psql_trgm: similarity result: $similarity_result", Debug::$LOG_EXTENDED); |
|
347 | 347 | |
348 | - if ($similarity_result >= $similarity) { |
|
349 | - $article["force_catchup"] = true; |
|
350 | - } |
|
348 | + if ($similarity_result >= $similarity) { |
|
349 | + $article["force_catchup"] = true; |
|
350 | + } |
|
351 | 351 | |
352 | - return $article; |
|
352 | + return $article; |
|
353 | 353 | |
354 | - } |
|
354 | + } |
|
355 | 355 | |
356 | - public function api_version() { |
|
357 | - return 2; |
|
358 | - } |
|
356 | + public function api_version() { |
|
357 | + return 2; |
|
358 | + } |
|
359 | 359 | |
360 | - private function filter_unknown_feeds($enabled_feeds) { |
|
361 | - $tmp = array(); |
|
360 | + private function filter_unknown_feeds($enabled_feeds) { |
|
361 | + $tmp = array(); |
|
362 | 362 | |
363 | - foreach ($enabled_feeds as $feed) { |
|
363 | + foreach ($enabled_feeds as $feed) { |
|
364 | 364 | |
365 | - $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?"); |
|
366 | - $sth->execute([$feed, $_SESSION['uid']]); |
|
365 | + $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?"); |
|
366 | + $sth->execute([$feed, $_SESSION['uid']]); |
|
367 | 367 | |
368 | - if ($row = $sth->fetch()) { |
|
369 | - array_push($tmp, $feed); |
|
370 | - } |
|
371 | - } |
|
368 | + if ($row = $sth->fetch()) { |
|
369 | + array_push($tmp, $feed); |
|
370 | + } |
|
371 | + } |
|
372 | 372 | |
373 | - return $tmp; |
|
374 | - } |
|
373 | + return $tmp; |
|
374 | + } |
|
375 | 375 | |
376 | 376 | } |
@@ -4,67 +4,67 @@ discard block |
||
4 | 4 | |
5 | 5 | class Af_Readability extends Plugin { |
6 | 6 | |
7 | - /* @var PluginHost $host */ |
|
8 | - private $host; |
|
7 | + /* @var PluginHost $host */ |
|
8 | + private $host; |
|
9 | 9 | |
10 | - public function about() { |
|
11 | - return array(1.0, |
|
12 | - "Try to inline article content using Readability", |
|
13 | - "fox"); |
|
14 | - } |
|
10 | + public function about() { |
|
11 | + return array(1.0, |
|
12 | + "Try to inline article content using Readability", |
|
13 | + "fox"); |
|
14 | + } |
|
15 | 15 | |
16 | - public function flags() { |
|
17 | - return array("needs_curl" => true); |
|
18 | - } |
|
16 | + public function flags() { |
|
17 | + return array("needs_curl" => true); |
|
18 | + } |
|
19 | 19 | |
20 | - public function save() { |
|
21 | - $enable_share_anything = checkbox_to_sql_bool($_POST["enable_share_anything"]); |
|
20 | + public function save() { |
|
21 | + $enable_share_anything = checkbox_to_sql_bool($_POST["enable_share_anything"]); |
|
22 | 22 | |
23 | - $this->host->set($this, "enable_share_anything", $enable_share_anything); |
|
23 | + $this->host->set($this, "enable_share_anything", $enable_share_anything); |
|
24 | 24 | |
25 | - echo __("Data saved."); |
|
26 | - } |
|
25 | + echo __("Data saved."); |
|
26 | + } |
|
27 | 27 | |
28 | - public function init($host) |
|
29 | - { |
|
30 | - $this->host = $host; |
|
28 | + public function init($host) |
|
29 | + { |
|
30 | + $this->host = $host; |
|
31 | 31 | |
32 | - if (version_compare(PHP_VERSION, '7.0.0', '<')) { |
|
33 | - user_error("af_readability requires PHP 7.0", E_USER_WARNING); |
|
34 | - return; |
|
35 | - } |
|
32 | + if (version_compare(PHP_VERSION, '7.0.0', '<')) { |
|
33 | + user_error("af_readability requires PHP 7.0", E_USER_WARNING); |
|
34 | + return; |
|
35 | + } |
|
36 | 36 | |
37 | - $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
38 | - $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
39 | - $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this); |
|
40 | - $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this); |
|
37 | + $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
38 | + $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
39 | + $host->add_hook($host::HOOK_PREFS_EDIT_FEED, $this); |
|
40 | + $host->add_hook($host::HOOK_PREFS_SAVE_FEED, $this); |
|
41 | 41 | |
42 | - // Note: we have to install the hook even if disabled because init() is being run before plugin data has loaded |
|
43 | - // so we can't check for our storage-set options here |
|
44 | - $host->add_hook($host::HOOK_GET_FULL_TEXT, $this); |
|
42 | + // Note: we have to install the hook even if disabled because init() is being run before plugin data has loaded |
|
43 | + // so we can't check for our storage-set options here |
|
44 | + $host->add_hook($host::HOOK_GET_FULL_TEXT, $this); |
|
45 | 45 | |
46 | - $host->add_filter_action($this, "action_inline", __("Inline content")); |
|
47 | - } |
|
46 | + $host->add_filter_action($this, "action_inline", __("Inline content")); |
|
47 | + } |
|
48 | 48 | |
49 | - public function hook_prefs_tab($args) { |
|
50 | - if ($args != "prefFeeds") { |
|
51 | - return; |
|
52 | - } |
|
49 | + public function hook_prefs_tab($args) { |
|
50 | + if ($args != "prefFeeds") { |
|
51 | + return; |
|
52 | + } |
|
53 | 53 | |
54 | - print "<div dojoType='dijit.layout.AccordionPane' |
|
54 | + print "<div dojoType='dijit.layout.AccordionPane' |
|
55 | 55 | title=\"<i class='material-icons'>extension</i> ".__('Readability settings (af_readability)')."\">"; |
56 | 56 | |
57 | - if (version_compare(PHP_VERSION, '7.0.0', '<')) { |
|
58 | - print_error("This plugin requires PHP 7.0."); |
|
59 | - } else { |
|
57 | + if (version_compare(PHP_VERSION, '7.0.0', '<')) { |
|
58 | + print_error("This plugin requires PHP 7.0."); |
|
59 | + } else { |
|
60 | 60 | |
61 | - print "<h2>".__("Global settings")."</h2>"; |
|
61 | + print "<h2>".__("Global settings")."</h2>"; |
|
62 | 62 | |
63 | - print_notice("Enable for specific feeds in the feed editor."); |
|
63 | + print_notice("Enable for specific feeds in the feed editor."); |
|
64 | 64 | |
65 | - print "<form dojoType='dijit.form.Form'>"; |
|
65 | + print "<form dojoType='dijit.form.Form'>"; |
|
66 | 66 | |
67 | - print "<script type='dojo/method' event='onSubmit' args='evt'> |
|
67 | + print "<script type='dojo/method' event='onSubmit' args='evt'> |
|
68 | 68 | evt.preventDefault(); |
69 | 69 | if (this.validate()) { |
70 | 70 | console.log(dojo.objectToQuery(this.getValues())); |
@@ -78,223 +78,223 @@ discard block |
||
78 | 78 | } |
79 | 79 | </script>"; |
80 | 80 | |
81 | - print_hidden("op", "pluginhandler"); |
|
82 | - print_hidden("method", "save"); |
|
83 | - print_hidden("plugin", "af_readability"); |
|
81 | + print_hidden("op", "pluginhandler"); |
|
82 | + print_hidden("method", "save"); |
|
83 | + print_hidden("plugin", "af_readability"); |
|
84 | 84 | |
85 | - $enable_share_anything = $this->host->get($this, "enable_share_anything"); |
|
85 | + $enable_share_anything = $this->host->get($this, "enable_share_anything"); |
|
86 | 86 | |
87 | - print "<fieldset>"; |
|
88 | - print "<label class='checkbox'> "; |
|
89 | - print_checkbox("enable_share_anything", $enable_share_anything); |
|
90 | - print " ".__("Provide full-text services to core code (bookmarklets) and other plugins"); |
|
91 | - print "</label>"; |
|
92 | - print "</fieldset>"; |
|
87 | + print "<fieldset>"; |
|
88 | + print "<label class='checkbox'> "; |
|
89 | + print_checkbox("enable_share_anything", $enable_share_anything); |
|
90 | + print " ".__("Provide full-text services to core code (bookmarklets) and other plugins"); |
|
91 | + print "</label>"; |
|
92 | + print "</fieldset>"; |
|
93 | 93 | |
94 | - print_button("submit", __("Save"), "class='alt-primary'"); |
|
95 | - print "</form>"; |
|
94 | + print_button("submit", __("Save"), "class='alt-primary'"); |
|
95 | + print "</form>"; |
|
96 | 96 | |
97 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
98 | - if (!is_array($enabled_feeds)) { |
|
99 | - $enabled_feeds = array(); |
|
100 | - } |
|
97 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
98 | + if (!is_array($enabled_feeds)) { |
|
99 | + $enabled_feeds = array(); |
|
100 | + } |
|
101 | 101 | |
102 | - $enabled_feeds = $this->filter_unknown_feeds($enabled_feeds); |
|
103 | - $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
102 | + $enabled_feeds = $this->filter_unknown_feeds($enabled_feeds); |
|
103 | + $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
104 | 104 | |
105 | - if (count($enabled_feeds) > 0) { |
|
106 | - print "<h3>".__("Currently enabled for (click to edit):")."</h3>"; |
|
105 | + if (count($enabled_feeds) > 0) { |
|
106 | + print "<h3>".__("Currently enabled for (click to edit):")."</h3>"; |
|
107 | 107 | |
108 | - print "<ul class='panel panel-scrollable list list-unstyled'>"; |
|
109 | - foreach ($enabled_feeds as $f) { |
|
110 | - print "<li><i class='material-icons'>rss_feed</i> <a href='#' |
|
108 | + print "<ul class='panel panel-scrollable list list-unstyled'>"; |
|
109 | + foreach ($enabled_feeds as $f) { |
|
110 | + print "<li><i class='material-icons'>rss_feed</i> <a href='#' |
|
111 | 111 | onclick='CommonDialogs.editFeed($f)'>". |
112 | - Feeds::getFeedTitle($f)."</a></li>"; |
|
113 | - } |
|
114 | - print "</ul>"; |
|
115 | - } |
|
112 | + Feeds::getFeedTitle($f)."</a></li>"; |
|
113 | + } |
|
114 | + print "</ul>"; |
|
115 | + } |
|
116 | 116 | |
117 | - } |
|
117 | + } |
|
118 | 118 | |
119 | - print "</div>"; |
|
120 | - } |
|
119 | + print "</div>"; |
|
120 | + } |
|
121 | 121 | |
122 | - public function hook_prefs_edit_feed($feed_id) { |
|
123 | - print "<header>".__("Readability")."</header>"; |
|
124 | - print "<section>"; |
|
122 | + public function hook_prefs_edit_feed($feed_id) { |
|
123 | + print "<header>".__("Readability")."</header>"; |
|
124 | + print "<section>"; |
|
125 | 125 | |
126 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
127 | - if (!is_array($enabled_feeds)) { |
|
128 | - $enabled_feeds = array(); |
|
129 | - } |
|
126 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
127 | + if (!is_array($enabled_feeds)) { |
|
128 | + $enabled_feeds = array(); |
|
129 | + } |
|
130 | 130 | |
131 | - $key = array_search($feed_id, $enabled_feeds); |
|
132 | - $checked = $key !== false ? "checked" : ""; |
|
131 | + $key = array_search($feed_id, $enabled_feeds); |
|
132 | + $checked = $key !== false ? "checked" : ""; |
|
133 | 133 | |
134 | - print "<fieldset>"; |
|
134 | + print "<fieldset>"; |
|
135 | 135 | |
136 | - print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='af_readability_enabled' |
|
136 | + print "<label class='checkbox'><input dojoType='dijit.form.CheckBox' type='checkbox' id='af_readability_enabled' |
|
137 | 137 | name='af_readability_enabled' $checked> ".__('Inline article content')."</label>"; |
138 | 138 | |
139 | - print "</fieldset>"; |
|
139 | + print "</fieldset>"; |
|
140 | 140 | |
141 | - print "</section>"; |
|
142 | - } |
|
141 | + print "</section>"; |
|
142 | + } |
|
143 | 143 | |
144 | - public function hook_prefs_save_feed($feed_id) { |
|
145 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
146 | - if (!is_array($enabled_feeds)) { |
|
147 | - $enabled_feeds = array(); |
|
148 | - } |
|
144 | + public function hook_prefs_save_feed($feed_id) { |
|
145 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
146 | + if (!is_array($enabled_feeds)) { |
|
147 | + $enabled_feeds = array(); |
|
148 | + } |
|
149 | 149 | |
150 | - $enable = checkbox_to_sql_bool($_POST["af_readability_enabled"]); |
|
151 | - $key = array_search($feed_id, $enabled_feeds); |
|
150 | + $enable = checkbox_to_sql_bool($_POST["af_readability_enabled"]); |
|
151 | + $key = array_search($feed_id, $enabled_feeds); |
|
152 | 152 | |
153 | - if ($enable) { |
|
154 | - if ($key === false) { |
|
155 | - array_push($enabled_feeds, $feed_id); |
|
156 | - } |
|
157 | - } else { |
|
158 | - if ($key !== false) { |
|
159 | - unset($enabled_feeds[$key]); |
|
160 | - } |
|
161 | - } |
|
153 | + if ($enable) { |
|
154 | + if ($key === false) { |
|
155 | + array_push($enabled_feeds, $feed_id); |
|
156 | + } |
|
157 | + } else { |
|
158 | + if ($key !== false) { |
|
159 | + unset($enabled_feeds[$key]); |
|
160 | + } |
|
161 | + } |
|
162 | 162 | |
163 | - $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
164 | - } |
|
163 | + $this->host->set($this, "enabled_feeds", $enabled_feeds); |
|
164 | + } |
|
165 | 165 | |
166 | - /** |
|
167 | - * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
168 | - */ |
|
169 | - public function hook_article_filter_action($article, $action) { |
|
170 | - return $this->process_article($article); |
|
171 | - } |
|
166 | + /** |
|
167 | + * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
168 | + */ |
|
169 | + public function hook_article_filter_action($article, $action) { |
|
170 | + return $this->process_article($article); |
|
171 | + } |
|
172 | 172 | |
173 | - public function extract_content($url) { |
|
173 | + public function extract_content($url) { |
|
174 | 174 | |
175 | - global $fetch_effective_url; |
|
175 | + global $fetch_effective_url; |
|
176 | 176 | |
177 | - $tmp = fetch_file_contents([ |
|
178 | - "url" => $url, |
|
179 | - "http_accept" => "text/*", |
|
180 | - "type" => "text/html"]); |
|
177 | + $tmp = fetch_file_contents([ |
|
178 | + "url" => $url, |
|
179 | + "http_accept" => "text/*", |
|
180 | + "type" => "text/html"]); |
|
181 | 181 | |
182 | - if ($tmp && mb_strlen($tmp) < 1024 * 500) { |
|
183 | - $tmpdoc = new DOMDocument("1.0", "UTF-8"); |
|
182 | + if ($tmp && mb_strlen($tmp) < 1024 * 500) { |
|
183 | + $tmpdoc = new DOMDocument("1.0", "UTF-8"); |
|
184 | 184 | |
185 | - if (!@$tmpdoc->loadHTML($tmp)) { |
|
186 | - return false; |
|
187 | - } |
|
185 | + if (!@$tmpdoc->loadHTML($tmp)) { |
|
186 | + return false; |
|
187 | + } |
|
188 | 188 | |
189 | - // this is the worst hack yet :( |
|
190 | - if (strtolower($tmpdoc->encoding) != 'utf-8') { |
|
191 | - $tmp = preg_replace("/<meta.*?charset.*?\/?>/i", "", $tmp); |
|
192 | - if (empty($tmpdoc->encoding)) { |
|
193 | - $tmp = mb_convert_encoding($tmp, 'utf-8'); |
|
194 | - } else { |
|
195 | - $tmp = mb_convert_encoding($tmp, 'utf-8', $tmpdoc->encoding); |
|
196 | - } |
|
197 | - } |
|
189 | + // this is the worst hack yet :( |
|
190 | + if (strtolower($tmpdoc->encoding) != 'utf-8') { |
|
191 | + $tmp = preg_replace("/<meta.*?charset.*?\/?>/i", "", $tmp); |
|
192 | + if (empty($tmpdoc->encoding)) { |
|
193 | + $tmp = mb_convert_encoding($tmp, 'utf-8'); |
|
194 | + } else { |
|
195 | + $tmp = mb_convert_encoding($tmp, 'utf-8', $tmpdoc->encoding); |
|
196 | + } |
|
197 | + } |
|
198 | 198 | |
199 | - try { |
|
200 | - $r = new Readability(new Configuration()); |
|
199 | + try { |
|
200 | + $r = new Readability(new Configuration()); |
|
201 | 201 | |
202 | - if ($r->parse($tmp)) { |
|
202 | + if ($r->parse($tmp)) { |
|
203 | 203 | |
204 | - $tmpxpath = new DOMXPath($r->getDOMDOcument()); |
|
205 | - $entries = $tmpxpath->query('(//a[@href]|//img[@src])'); |
|
204 | + $tmpxpath = new DOMXPath($r->getDOMDOcument()); |
|
205 | + $entries = $tmpxpath->query('(//a[@href]|//img[@src])'); |
|
206 | 206 | |
207 | - foreach ($entries as $entry) { |
|
208 | - if ($entry->hasAttribute("href")) { |
|
209 | - $entry->setAttribute("href", |
|
210 | - rewrite_relative_url($fetch_effective_url, $entry->getAttribute("href"))); |
|
207 | + foreach ($entries as $entry) { |
|
208 | + if ($entry->hasAttribute("href")) { |
|
209 | + $entry->setAttribute("href", |
|
210 | + rewrite_relative_url($fetch_effective_url, $entry->getAttribute("href"))); |
|
211 | 211 | |
212 | - } |
|
212 | + } |
|
213 | 213 | |
214 | - if ($entry->hasAttribute("src")) { |
|
215 | - $entry->setAttribute("src", |
|
216 | - rewrite_relative_url($fetch_effective_url, $entry->getAttribute("src"))); |
|
214 | + if ($entry->hasAttribute("src")) { |
|
215 | + $entry->setAttribute("src", |
|
216 | + rewrite_relative_url($fetch_effective_url, $entry->getAttribute("src"))); |
|
217 | 217 | |
218 | - } |
|
219 | - } |
|
218 | + } |
|
219 | + } |
|
220 | 220 | |
221 | - return $r->getContent(); |
|
222 | - } |
|
221 | + return $r->getContent(); |
|
222 | + } |
|
223 | 223 | |
224 | - } catch (Exception $e) { |
|
225 | - return false; |
|
226 | - } |
|
227 | - } |
|
224 | + } catch (Exception $e) { |
|
225 | + return false; |
|
226 | + } |
|
227 | + } |
|
228 | 228 | |
229 | - return false; |
|
230 | - } |
|
229 | + return false; |
|
230 | + } |
|
231 | 231 | |
232 | - public function process_article($article) { |
|
232 | + public function process_article($article) { |
|
233 | 233 | |
234 | - $extracted_content = $this->extract_content($article["link"]); |
|
234 | + $extracted_content = $this->extract_content($article["link"]); |
|
235 | 235 | |
236 | - # let's see if there's anything of value in there |
|
237 | - $content_test = trim(strip_tags(sanitize($extracted_content))); |
|
236 | + # let's see if there's anything of value in there |
|
237 | + $content_test = trim(strip_tags(sanitize($extracted_content))); |
|
238 | 238 | |
239 | - if ($content_test) { |
|
240 | - $article["content"] = $extracted_content; |
|
241 | - } |
|
239 | + if ($content_test) { |
|
240 | + $article["content"] = $extracted_content; |
|
241 | + } |
|
242 | 242 | |
243 | - return $article; |
|
244 | - } |
|
243 | + return $article; |
|
244 | + } |
|
245 | 245 | |
246 | - public function hook_article_filter($article) { |
|
246 | + public function hook_article_filter($article) { |
|
247 | 247 | |
248 | - $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
249 | - if (!is_array($enabled_feeds)) { |
|
250 | - return $article; |
|
251 | - } |
|
248 | + $enabled_feeds = $this->host->get($this, "enabled_feeds"); |
|
249 | + if (!is_array($enabled_feeds)) { |
|
250 | + return $article; |
|
251 | + } |
|
252 | 252 | |
253 | - $key = array_search($article["feed"]["id"], $enabled_feeds); |
|
254 | - if ($key === false) { |
|
255 | - return $article; |
|
256 | - } |
|
253 | + $key = array_search($article["feed"]["id"], $enabled_feeds); |
|
254 | + if ($key === false) { |
|
255 | + return $article; |
|
256 | + } |
|
257 | 257 | |
258 | - return $this->process_article($article); |
|
258 | + return $this->process_article($article); |
|
259 | 259 | |
260 | - } |
|
260 | + } |
|
261 | 261 | |
262 | - public function hook_get_full_text($link) |
|
263 | - { |
|
264 | - $enable_share_anything = $this->host->get($this, "enable_share_anything"); |
|
262 | + public function hook_get_full_text($link) |
|
263 | + { |
|
264 | + $enable_share_anything = $this->host->get($this, "enable_share_anything"); |
|
265 | 265 | |
266 | - if ($enable_share_anything) { |
|
267 | - $extracted_content = $this->extract_content($link); |
|
266 | + if ($enable_share_anything) { |
|
267 | + $extracted_content = $this->extract_content($link); |
|
268 | 268 | |
269 | - # let's see if there's anything of value in there |
|
270 | - $content_test = trim(strip_tags(sanitize($extracted_content))); |
|
269 | + # let's see if there's anything of value in there |
|
270 | + $content_test = trim(strip_tags(sanitize($extracted_content))); |
|
271 | 271 | |
272 | - if ($content_test) { |
|
273 | - return $extracted_content; |
|
274 | - } |
|
275 | - } |
|
272 | + if ($content_test) { |
|
273 | + return $extracted_content; |
|
274 | + } |
|
275 | + } |
|
276 | 276 | |
277 | - return false; |
|
278 | - } |
|
277 | + return false; |
|
278 | + } |
|
279 | 279 | |
280 | - public function api_version() { |
|
281 | - return 2; |
|
282 | - } |
|
280 | + public function api_version() { |
|
281 | + return 2; |
|
282 | + } |
|
283 | 283 | |
284 | - private function filter_unknown_feeds($enabled_feeds) { |
|
285 | - $tmp = array(); |
|
284 | + private function filter_unknown_feeds($enabled_feeds) { |
|
285 | + $tmp = array(); |
|
286 | 286 | |
287 | - foreach ($enabled_feeds as $feed) { |
|
287 | + foreach ($enabled_feeds as $feed) { |
|
288 | 288 | |
289 | - $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?"); |
|
290 | - $sth->execute([$feed, $_SESSION['uid']]); |
|
289 | + $sth = $this->pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ? AND owner_uid = ?"); |
|
290 | + $sth->execute([$feed, $_SESSION['uid']]); |
|
291 | 291 | |
292 | - if ($row = $sth->fetch()) { |
|
293 | - array_push($tmp, $feed); |
|
294 | - } |
|
295 | - } |
|
292 | + if ($row = $sth->fetch()) { |
|
293 | + array_push($tmp, $feed); |
|
294 | + } |
|
295 | + } |
|
296 | 296 | |
297 | - return $tmp; |
|
298 | - } |
|
297 | + return $tmp; |
|
298 | + } |
|
299 | 299 | |
300 | 300 | } |
@@ -1,44 +1,44 @@ discard block |
||
1 | 1 | <?php |
2 | 2 | class Af_RedditImgur extends Plugin { |
3 | 3 | |
4 | - /* @var PluginHost $host */ |
|
5 | - private $host; |
|
4 | + /* @var PluginHost $host */ |
|
5 | + private $host; |
|
6 | 6 | |
7 | - public function about() { |
|
8 | - return array(1.0, |
|
9 | - "Inline images (and other content) in Reddit RSS feeds", |
|
10 | - "fox"); |
|
11 | - } |
|
7 | + public function about() { |
|
8 | + return array(1.0, |
|
9 | + "Inline images (and other content) in Reddit RSS feeds", |
|
10 | + "fox"); |
|
11 | + } |
|
12 | 12 | |
13 | - public function flags() { |
|
14 | - return array("needs_curl" => true); |
|
15 | - } |
|
13 | + public function flags() { |
|
14 | + return array("needs_curl" => true); |
|
15 | + } |
|
16 | 16 | |
17 | - public function init($host) { |
|
18 | - $this->host = $host; |
|
17 | + public function init($host) { |
|
18 | + $this->host = $host; |
|
19 | 19 | |
20 | - $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
21 | - $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
22 | - } |
|
20 | + $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
21 | + $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
22 | + } |
|
23 | 23 | |
24 | - public function hook_prefs_tab($args) { |
|
25 | - if ($args != "prefFeeds") { |
|
26 | - return; |
|
27 | - } |
|
24 | + public function hook_prefs_tab($args) { |
|
25 | + if ($args != "prefFeeds") { |
|
26 | + return; |
|
27 | + } |
|
28 | 28 | |
29 | - print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
29 | + print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
30 | 30 | title=\"<i class='material-icons'>extension</i> ".__('Reddit content settings (af_redditimgur)')."\">"; |
31 | 31 | |
32 | - $enable_readability = $this->host->get($this, "enable_readability"); |
|
33 | - $enable_content_dupcheck = $this->host->get($this, "enable_content_dupcheck"); |
|
32 | + $enable_readability = $this->host->get($this, "enable_readability"); |
|
33 | + $enable_content_dupcheck = $this->host->get($this, "enable_content_dupcheck"); |
|
34 | 34 | |
35 | - if (version_compare(PHP_VERSION, '5.6.0', '<')) { |
|
36 | - print_error("Readability requires PHP version 5.6."); |
|
37 | - } |
|
35 | + if (version_compare(PHP_VERSION, '5.6.0', '<')) { |
|
36 | + print_error("Readability requires PHP version 5.6."); |
|
37 | + } |
|
38 | 38 | |
39 | - print "<form dojoType='dijit.form.Form'>"; |
|
39 | + print "<form dojoType='dijit.form.Form'>"; |
|
40 | 40 | |
41 | - print "<script type='dojo/method' event='onSubmit' args='evt'> |
|
41 | + print "<script type='dojo/method' event='onSubmit' args='evt'> |
|
42 | 42 | evt.preventDefault(); |
43 | 43 | if (this.validate()) { |
44 | 44 | console.log(dojo.objectToQuery(this.getValues())); |
@@ -52,235 +52,235 @@ discard block |
||
52 | 52 | } |
53 | 53 | </script>"; |
54 | 54 | |
55 | - print_hidden("op", "pluginhandler"); |
|
56 | - print_hidden("method", "save"); |
|
57 | - print_hidden("plugin", "af_redditimgur"); |
|
55 | + print_hidden("op", "pluginhandler"); |
|
56 | + print_hidden("method", "save"); |
|
57 | + print_hidden("plugin", "af_redditimgur"); |
|
58 | 58 | |
59 | - print "<fieldset class='narrow'>"; |
|
60 | - print "<label class='checkbox'>"; |
|
61 | - print_checkbox("enable_readability", $enable_readability); |
|
62 | - print " ".__("Extract missing content using Readability (requires af_readability)")."</label>"; |
|
63 | - print "</fieldset>"; |
|
59 | + print "<fieldset class='narrow'>"; |
|
60 | + print "<label class='checkbox'>"; |
|
61 | + print_checkbox("enable_readability", $enable_readability); |
|
62 | + print " ".__("Extract missing content using Readability (requires af_readability)")."</label>"; |
|
63 | + print "</fieldset>"; |
|
64 | 64 | |
65 | - print "<fieldset class='narrow'>"; |
|
66 | - print "<label class='checkbox'>"; |
|
67 | - print_checkbox("enable_content_dupcheck", $enable_content_dupcheck); |
|
68 | - print " ".__("Enable additional duplicate checking")."</label>"; |
|
69 | - print "</fieldset>"; |
|
65 | + print "<fieldset class='narrow'>"; |
|
66 | + print "<label class='checkbox'>"; |
|
67 | + print_checkbox("enable_content_dupcheck", $enable_content_dupcheck); |
|
68 | + print " ".__("Enable additional duplicate checking")."</label>"; |
|
69 | + print "</fieldset>"; |
|
70 | 70 | |
71 | - print_button("submit", __("Save"), 'class="alt-primary"'); |
|
72 | - print "</form>"; |
|
71 | + print_button("submit", __("Save"), 'class="alt-primary"'); |
|
72 | + print "</form>"; |
|
73 | 73 | |
74 | - print "</div>"; |
|
75 | - } |
|
74 | + print "</div>"; |
|
75 | + } |
|
76 | 76 | |
77 | - public function save() { |
|
78 | - $enable_readability = checkbox_to_sql_bool($_POST["enable_readability"]); |
|
79 | - $enable_content_dupcheck = checkbox_to_sql_bool($_POST["enable_content_dupcheck"]); |
|
77 | + public function save() { |
|
78 | + $enable_readability = checkbox_to_sql_bool($_POST["enable_readability"]); |
|
79 | + $enable_content_dupcheck = checkbox_to_sql_bool($_POST["enable_content_dupcheck"]); |
|
80 | 80 | |
81 | - $this->host->set($this, "enable_readability", $enable_readability, false); |
|
82 | - $this->host->set($this, "enable_content_dupcheck", $enable_content_dupcheck); |
|
81 | + $this->host->set($this, "enable_readability", $enable_readability, false); |
|
82 | + $this->host->set($this, "enable_content_dupcheck", $enable_content_dupcheck); |
|
83 | 83 | |
84 | - echo __("Configuration saved"); |
|
85 | - } |
|
84 | + echo __("Configuration saved"); |
|
85 | + } |
|
86 | 86 | |
87 | - /** |
|
88 | - * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
89 | - */ |
|
90 | - private function inline_stuff($article, &$doc, $xpath) { |
|
87 | + /** |
|
88 | + * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
89 | + */ |
|
90 | + private function inline_stuff($article, &$doc, $xpath) { |
|
91 | 91 | |
92 | - $entries = $xpath->query('(//a[@href]|//img[@src])'); |
|
93 | - $img_entries = $xpath->query("(//img[@src])"); |
|
92 | + $entries = $xpath->query('(//a[@href]|//img[@src])'); |
|
93 | + $img_entries = $xpath->query("(//img[@src])"); |
|
94 | 94 | |
95 | - $found = false; |
|
96 | - //$debug = 1; |
|
95 | + $found = false; |
|
96 | + //$debug = 1; |
|
97 | 97 | |
98 | - foreach ($entries as $entry) { |
|
99 | - if ($entry->hasAttribute("href") && strpos($entry->getAttribute("href"), "reddit.com") === false) { |
|
98 | + foreach ($entries as $entry) { |
|
99 | + if ($entry->hasAttribute("href") && strpos($entry->getAttribute("href"), "reddit.com") === false) { |
|
100 | 100 | |
101 | - Debug::log("processing href: ".$entry->getAttribute("href"), Debug::$LOG_VERBOSE); |
|
101 | + Debug::log("processing href: ".$entry->getAttribute("href"), Debug::$LOG_VERBOSE); |
|
102 | 102 | |
103 | - $matches = array(); |
|
103 | + $matches = array(); |
|
104 | 104 | |
105 | - if (!$found && preg_match("/^https?:\/\/twitter.com\/(.*?)\/status\/(.*)/", $entry->getAttribute("href"), $matches)) { |
|
106 | - Debug::log("handling as twitter: ".$matches[1]." ".$matches[2], Debug::$LOG_VERBOSE); |
|
105 | + if (!$found && preg_match("/^https?:\/\/twitter.com\/(.*?)\/status\/(.*)/", $entry->getAttribute("href"), $matches)) { |
|
106 | + Debug::log("handling as twitter: ".$matches[1]." ".$matches[2], Debug::$LOG_VERBOSE); |
|
107 | 107 | |
108 | - $oembed_result = fetch_file_contents("https://publish.twitter.com/oembed?url=".urlencode($entry->getAttribute("href"))); |
|
108 | + $oembed_result = fetch_file_contents("https://publish.twitter.com/oembed?url=".urlencode($entry->getAttribute("href"))); |
|
109 | 109 | |
110 | - if ($oembed_result) { |
|
111 | - $oembed_result = json_decode($oembed_result, true); |
|
110 | + if ($oembed_result) { |
|
111 | + $oembed_result = json_decode($oembed_result, true); |
|
112 | 112 | |
113 | - if ($oembed_result && isset($oembed_result["html"])) { |
|
113 | + if ($oembed_result && isset($oembed_result["html"])) { |
|
114 | 114 | |
115 | - $tmp = new DOMDocument(); |
|
116 | - if ($tmp->loadHTML('<?xml encoding="utf-8" ?>'.$oembed_result["html"])) { |
|
117 | - $p = $doc->createElement("p"); |
|
115 | + $tmp = new DOMDocument(); |
|
116 | + if ($tmp->loadHTML('<?xml encoding="utf-8" ?>'.$oembed_result["html"])) { |
|
117 | + $p = $doc->createElement("p"); |
|
118 | 118 | |
119 | - $p->appendChild($doc->importNode( |
|
120 | - $tmp->getElementsByTagName("blockquote")->item(0), true)); |
|
119 | + $p->appendChild($doc->importNode( |
|
120 | + $tmp->getElementsByTagName("blockquote")->item(0), true)); |
|
121 | 121 | |
122 | - $br = $doc->createElement('br'); |
|
123 | - $entry->parentNode->insertBefore($p, $entry); |
|
124 | - $entry->parentNode->insertBefore($br, $entry); |
|
122 | + $br = $doc->createElement('br'); |
|
123 | + $entry->parentNode->insertBefore($p, $entry); |
|
124 | + $entry->parentNode->insertBefore($br, $entry); |
|
125 | 125 | |
126 | - $found = 1; |
|
127 | - } |
|
128 | - } |
|
129 | - } |
|
130 | - } |
|
126 | + $found = 1; |
|
127 | + } |
|
128 | + } |
|
129 | + } |
|
130 | + } |
|
131 | 131 | |
132 | - if (!$found && preg_match("/\.gfycat.com\/([a-z]+)?(\.[a-z]+)$/i", $entry->getAttribute("href"), $matches)) { |
|
133 | - $entry->setAttribute("href", "http://www.gfycat.com/".$matches[1]); |
|
134 | - } |
|
132 | + if (!$found && preg_match("/\.gfycat.com\/([a-z]+)?(\.[a-z]+)$/i", $entry->getAttribute("href"), $matches)) { |
|
133 | + $entry->setAttribute("href", "http://www.gfycat.com/".$matches[1]); |
|
134 | + } |
|
135 | 135 | |
136 | - if (!$found && preg_match("/https?:\/\/(www\.)?gfycat.com\/([a-z]+)$/i", $entry->getAttribute("href"), $matches)) { |
|
136 | + if (!$found && preg_match("/https?:\/\/(www\.)?gfycat.com\/([a-z]+)$/i", $entry->getAttribute("href"), $matches)) { |
|
137 | 137 | |
138 | - Debug::log("Handling as Gfycat", Debug::$LOG_VERBOSE); |
|
138 | + Debug::log("Handling as Gfycat", Debug::$LOG_VERBOSE); |
|
139 | 139 | |
140 | - $source_stream = 'https://giant.gfycat.com/'.$matches[2].'.mp4'; |
|
141 | - $poster_url = 'https://thumbs.gfycat.com/'.$matches[2].'-mobile.jpg'; |
|
140 | + $source_stream = 'https://giant.gfycat.com/'.$matches[2].'.mp4'; |
|
141 | + $poster_url = 'https://thumbs.gfycat.com/'.$matches[2].'-mobile.jpg'; |
|
142 | 142 | |
143 | - $content_type = $this->get_content_type($source_stream); |
|
143 | + $content_type = $this->get_content_type($source_stream); |
|
144 | 144 | |
145 | - if (strpos($content_type, "video/") !== false) { |
|
146 | - $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
147 | - $found = 1; |
|
148 | - } |
|
149 | - } |
|
145 | + if (strpos($content_type, "video/") !== false) { |
|
146 | + $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
147 | + $found = 1; |
|
148 | + } |
|
149 | + } |
|
150 | 150 | |
151 | - if (!$found && preg_match("/https?:\/\/v\.redd\.it\/(.*)$/i", $entry->getAttribute("href"), $matches)) { |
|
151 | + if (!$found && preg_match("/https?:\/\/v\.redd\.it\/(.*)$/i", $entry->getAttribute("href"), $matches)) { |
|
152 | 152 | |
153 | - Debug::log("Handling as reddit inline video", Debug::$LOG_VERBOSE); |
|
153 | + Debug::log("Handling as reddit inline video", Debug::$LOG_VERBOSE); |
|
154 | 154 | |
155 | - $img = $img_entries->item(0); |
|
155 | + $img = $img_entries->item(0); |
|
156 | 156 | |
157 | - if ($img) { |
|
158 | - $poster_url = $img->getAttribute("src"); |
|
159 | - } else { |
|
160 | - $poster_url = false; |
|
161 | - } |
|
157 | + if ($img) { |
|
158 | + $poster_url = $img->getAttribute("src"); |
|
159 | + } else { |
|
160 | + $poster_url = false; |
|
161 | + } |
|
162 | 162 | |
163 | - // Get original article URL from v.redd.it redirects |
|
164 | - $source_article_url = $this->get_location($matches[0]); |
|
165 | - Debug::log("Resolved ".$matches[0]." to ".$source_article_url, Debug::$LOG_VERBOSE); |
|
166 | - |
|
167 | - $source_stream = false; |
|
168 | - |
|
169 | - if ($source_article_url) { |
|
170 | - $j = json_decode(fetch_file_contents($source_article_url.".json"), true); |
|
171 | - |
|
172 | - if ($j) { |
|
173 | - foreach ($j as $listing) { |
|
174 | - foreach ($listing["data"]["children"] as $child) { |
|
175 | - if ($child["data"]["url"] == $matches[0]) { |
|
176 | - try { |
|
177 | - $source_stream = $child["data"]["media"]["reddit_video"]["fallback_url"]; |
|
178 | - } catch (Exception $e) { |
|
179 | - } |
|
180 | - break 2; |
|
181 | - } |
|
182 | - } |
|
183 | - } |
|
184 | - } |
|
185 | - } |
|
163 | + // Get original article URL from v.redd.it redirects |
|
164 | + $source_article_url = $this->get_location($matches[0]); |
|
165 | + Debug::log("Resolved ".$matches[0]." to ".$source_article_url, Debug::$LOG_VERBOSE); |
|
166 | + |
|
167 | + $source_stream = false; |
|
168 | + |
|
169 | + if ($source_article_url) { |
|
170 | + $j = json_decode(fetch_file_contents($source_article_url.".json"), true); |
|
171 | + |
|
172 | + if ($j) { |
|
173 | + foreach ($j as $listing) { |
|
174 | + foreach ($listing["data"]["children"] as $child) { |
|
175 | + if ($child["data"]["url"] == $matches[0]) { |
|
176 | + try { |
|
177 | + $source_stream = $child["data"]["media"]["reddit_video"]["fallback_url"]; |
|
178 | + } catch (Exception $e) { |
|
179 | + } |
|
180 | + break 2; |
|
181 | + } |
|
182 | + } |
|
183 | + } |
|
184 | + } |
|
185 | + } |
|
186 | 186 | |
187 | - if (!$source_stream) { |
|
188 | - $source_stream = "https://v.redd.it/".$matches[1]."/DASH_600_K"; |
|
189 | - } |
|
187 | + if (!$source_stream) { |
|
188 | + $source_stream = "https://v.redd.it/".$matches[1]."/DASH_600_K"; |
|
189 | + } |
|
190 | 190 | |
191 | - $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
192 | - $found = 1; |
|
193 | - } |
|
191 | + $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
192 | + $found = 1; |
|
193 | + } |
|
194 | 194 | |
195 | - if (!$found && preg_match("/https?:\/\/(www\.)?streamable.com\//i", $entry->getAttribute("href"))) { |
|
195 | + if (!$found && preg_match("/https?:\/\/(www\.)?streamable.com\//i", $entry->getAttribute("href"))) { |
|
196 | 196 | |
197 | - Debug::log("Handling as Streamable", Debug::$LOG_VERBOSE); |
|
197 | + Debug::log("Handling as Streamable", Debug::$LOG_VERBOSE); |
|
198 | 198 | |
199 | - $tmp = fetch_file_contents($entry->getAttribute("href")); |
|
199 | + $tmp = fetch_file_contents($entry->getAttribute("href")); |
|
200 | 200 | |
201 | - if ($tmp) { |
|
202 | - $tmpdoc = new DOMDocument(); |
|
201 | + if ($tmp) { |
|
202 | + $tmpdoc = new DOMDocument(); |
|
203 | 203 | |
204 | - if (@$tmpdoc->loadHTML($tmp)) { |
|
205 | - $tmpxpath = new DOMXPath($tmpdoc); |
|
204 | + if (@$tmpdoc->loadHTML($tmp)) { |
|
205 | + $tmpxpath = new DOMXPath($tmpdoc); |
|
206 | 206 | |
207 | - $source_node = $tmpxpath->query("//video[contains(@class,'video-player-tag')]//source[contains(@src, '.mp4')]")->item(0); |
|
208 | - $poster_node = $tmpxpath->query("//video[contains(@class,'video-player-tag') and @poster]")->item(0); |
|
207 | + $source_node = $tmpxpath->query("//video[contains(@class,'video-player-tag')]//source[contains(@src, '.mp4')]")->item(0); |
|
208 | + $poster_node = $tmpxpath->query("//video[contains(@class,'video-player-tag') and @poster]")->item(0); |
|
209 | 209 | |
210 | - if ($source_node && $poster_node) { |
|
211 | - $source_stream = $source_node->getAttribute("src"); |
|
212 | - $poster_url = $poster_node->getAttribute("poster"); |
|
210 | + if ($source_node && $poster_node) { |
|
211 | + $source_stream = $source_node->getAttribute("src"); |
|
212 | + $poster_url = $poster_node->getAttribute("poster"); |
|
213 | 213 | |
214 | - $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
215 | - $found = 1; |
|
216 | - } |
|
217 | - } |
|
218 | - } |
|
219 | - } |
|
214 | + $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
215 | + $found = 1; |
|
216 | + } |
|
217 | + } |
|
218 | + } |
|
219 | + } |
|
220 | 220 | |
221 | - // imgur .gif -> .gifv |
|
222 | - if (!$found && preg_match("/i\.imgur\.com\/(.*?)\.gif$/i", $entry->getAttribute("href"))) { |
|
223 | - Debug::log("Handling as imgur gif (->gifv)", Debug::$LOG_VERBOSE); |
|
221 | + // imgur .gif -> .gifv |
|
222 | + if (!$found && preg_match("/i\.imgur\.com\/(.*?)\.gif$/i", $entry->getAttribute("href"))) { |
|
223 | + Debug::log("Handling as imgur gif (->gifv)", Debug::$LOG_VERBOSE); |
|
224 | 224 | |
225 | - $entry->setAttribute("href", |
|
226 | - str_replace(".gif", ".gifv", $entry->getAttribute("href"))); |
|
227 | - } |
|
225 | + $entry->setAttribute("href", |
|
226 | + str_replace(".gif", ".gifv", $entry->getAttribute("href"))); |
|
227 | + } |
|
228 | 228 | |
229 | - if (!$found && preg_match("/\.(gifv|mp4)$/i", $entry->getAttribute("href"))) { |
|
230 | - Debug::log("Handling as imgur gifv", Debug::$LOG_VERBOSE); |
|
229 | + if (!$found && preg_match("/\.(gifv|mp4)$/i", $entry->getAttribute("href"))) { |
|
230 | + Debug::log("Handling as imgur gifv", Debug::$LOG_VERBOSE); |
|
231 | 231 | |
232 | - $source_stream = str_replace(".gifv", ".mp4", $entry->getAttribute("href")); |
|
232 | + $source_stream = str_replace(".gifv", ".mp4", $entry->getAttribute("href")); |
|
233 | 233 | |
234 | - if (strpos($source_stream, "imgur.com") !== false) { |
|
235 | - $poster_url = str_replace(".mp4", "h.jpg", $source_stream); |
|
236 | - } |
|
234 | + if (strpos($source_stream, "imgur.com") !== false) { |
|
235 | + $poster_url = str_replace(".mp4", "h.jpg", $source_stream); |
|
236 | + } |
|
237 | 237 | |
238 | - $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
238 | + $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
239 | 239 | |
240 | - $found = true; |
|
241 | - } |
|
240 | + $found = true; |
|
241 | + } |
|
242 | 242 | |
243 | - $matches = array(); |
|
244 | - if (!$found && preg_match("/youtube\.com\/v\/([\w-]+)/", $entry->getAttribute("href"), $matches) || |
|
245 | - preg_match("/youtube\.com\/.*?[\&\?]v=([\w-]+)/", $entry->getAttribute("href"), $matches) || |
|
246 | - preg_match("/youtube\.com\/watch\?v=([\w-]+)/", $entry->getAttribute("href"), $matches) || |
|
247 | - preg_match("/\/\/youtu.be\/([\w-]+)/", $entry->getAttribute("href"), $matches)) { |
|
243 | + $matches = array(); |
|
244 | + if (!$found && preg_match("/youtube\.com\/v\/([\w-]+)/", $entry->getAttribute("href"), $matches) || |
|
245 | + preg_match("/youtube\.com\/.*?[\&\?]v=([\w-]+)/", $entry->getAttribute("href"), $matches) || |
|
246 | + preg_match("/youtube\.com\/watch\?v=([\w-]+)/", $entry->getAttribute("href"), $matches) || |
|
247 | + preg_match("/\/\/youtu.be\/([\w-]+)/", $entry->getAttribute("href"), $matches)) { |
|
248 | 248 | |
249 | - $vid_id = $matches[1]; |
|
249 | + $vid_id = $matches[1]; |
|
250 | 250 | |
251 | - Debug::log("Handling as youtube: $vid_id", Debug::$LOG_VERBOSE); |
|
251 | + Debug::log("Handling as youtube: $vid_id", Debug::$LOG_VERBOSE); |
|
252 | 252 | |
253 | - $iframe = $doc->createElement("iframe"); |
|
254 | - $iframe->setAttribute("class", "youtube-player"); |
|
255 | - $iframe->setAttribute("type", "text/html"); |
|
256 | - $iframe->setAttribute("width", "640"); |
|
257 | - $iframe->setAttribute("height", "385"); |
|
258 | - $iframe->setAttribute("src", "https://www.youtube.com/embed/$vid_id"); |
|
259 | - $iframe->setAttribute("allowfullscreen", "1"); |
|
260 | - $iframe->setAttribute("frameborder", "0"); |
|
253 | + $iframe = $doc->createElement("iframe"); |
|
254 | + $iframe->setAttribute("class", "youtube-player"); |
|
255 | + $iframe->setAttribute("type", "text/html"); |
|
256 | + $iframe->setAttribute("width", "640"); |
|
257 | + $iframe->setAttribute("height", "385"); |
|
258 | + $iframe->setAttribute("src", "https://www.youtube.com/embed/$vid_id"); |
|
259 | + $iframe->setAttribute("allowfullscreen", "1"); |
|
260 | + $iframe->setAttribute("frameborder", "0"); |
|
261 | 261 | |
262 | - $br = $doc->createElement('br'); |
|
263 | - $entry->parentNode->insertBefore($iframe, $entry); |
|
264 | - $entry->parentNode->insertBefore($br, $entry); |
|
262 | + $br = $doc->createElement('br'); |
|
263 | + $entry->parentNode->insertBefore($iframe, $entry); |
|
264 | + $entry->parentNode->insertBefore($br, $entry); |
|
265 | 265 | |
266 | - $found = true; |
|
267 | - } |
|
266 | + $found = true; |
|
267 | + } |
|
268 | 268 | |
269 | - if (!$found && preg_match("/\.(jpg|jpeg|gif|png)(\?[0-9][0-9]*)?$/i", $entry->getAttribute("href")) || |
|
270 | - mb_strpos($entry->getAttribute("href"), "i.reddituploads.com") !== false || |
|
271 | - mb_strpos($this->get_content_type($entry->getAttribute("href")), "image/") !== false) { |
|
269 | + if (!$found && preg_match("/\.(jpg|jpeg|gif|png)(\?[0-9][0-9]*)?$/i", $entry->getAttribute("href")) || |
|
270 | + mb_strpos($entry->getAttribute("href"), "i.reddituploads.com") !== false || |
|
271 | + mb_strpos($this->get_content_type($entry->getAttribute("href")), "image/") !== false) { |
|
272 | 272 | |
273 | - Debug::log("Handling as a picture", Debug::$LOG_VERBOSE); |
|
273 | + Debug::log("Handling as a picture", Debug::$LOG_VERBOSE); |
|
274 | 274 | |
275 | - $img = $doc->createElement('img'); |
|
276 | - $img->setAttribute("src", $entry->getAttribute("href")); |
|
275 | + $img = $doc->createElement('img'); |
|
276 | + $img->setAttribute("src", $entry->getAttribute("href")); |
|
277 | 277 | |
278 | - $br = $doc->createElement('br'); |
|
279 | - $entry->parentNode->insertBefore($img, $entry); |
|
280 | - $entry->parentNode->insertBefore($br, $entry); |
|
278 | + $br = $doc->createElement('br'); |
|
279 | + $entry->parentNode->insertBefore($img, $entry); |
|
280 | + $entry->parentNode->insertBefore($br, $entry); |
|
281 | 281 | |
282 | - $found = true; |
|
283 | - } |
|
282 | + $found = true; |
|
283 | + } |
|
284 | 284 | |
285 | 285 | // imgur via link rel="image_src" href="..." |
286 | 286 | if (!$found && preg_match("/imgur/", $entry->getAttribute("href"))) { |
@@ -313,109 +313,109 @@ discard block |
||
313 | 313 | } |
314 | 314 | } |
315 | 315 | |
316 | - // wtf is this even |
|
317 | - if (!$found && preg_match("/^https?:\/\/gyazo\.com\/([^\.\/]+$)/", $entry->getAttribute("href"), $matches)) { |
|
318 | - $img_id = $matches[1]; |
|
316 | + // wtf is this even |
|
317 | + if (!$found && preg_match("/^https?:\/\/gyazo\.com\/([^\.\/]+$)/", $entry->getAttribute("href"), $matches)) { |
|
318 | + $img_id = $matches[1]; |
|
319 | 319 | |
320 | - Debug::log("handling as gyazo: $img_id", Debug::$LOG_VERBOSE); |
|
320 | + Debug::log("handling as gyazo: $img_id", Debug::$LOG_VERBOSE); |
|
321 | 321 | |
322 | - $img = $doc->createElement('img'); |
|
323 | - $img->setAttribute("src", "https://i.gyazo.com/$img_id.jpg"); |
|
322 | + $img = $doc->createElement('img'); |
|
323 | + $img->setAttribute("src", "https://i.gyazo.com/$img_id.jpg"); |
|
324 | 324 | |
325 | - $br = $doc->createElement('br'); |
|
326 | - $entry->parentNode->insertBefore($img, $entry); |
|
327 | - $entry->parentNode->insertBefore($br, $entry); |
|
325 | + $br = $doc->createElement('br'); |
|
326 | + $entry->parentNode->insertBefore($img, $entry); |
|
327 | + $entry->parentNode->insertBefore($br, $entry); |
|
328 | 328 | |
329 | - $found = true; |
|
330 | - } |
|
329 | + $found = true; |
|
330 | + } |
|
331 | 331 | |
332 | - // let's try meta properties |
|
333 | - if (!$found) { |
|
334 | - Debug::log("looking for meta og:image", Debug::$LOG_VERBOSE); |
|
332 | + // let's try meta properties |
|
333 | + if (!$found) { |
|
334 | + Debug::log("looking for meta og:image", Debug::$LOG_VERBOSE); |
|
335 | 335 | |
336 | - $content = fetch_file_contents(["url" => $entry->getAttribute("href"), |
|
337 | - "http_accept" => "text/*"]); |
|
336 | + $content = fetch_file_contents(["url" => $entry->getAttribute("href"), |
|
337 | + "http_accept" => "text/*"]); |
|
338 | 338 | |
339 | - if ($content) { |
|
340 | - $cdoc = new DOMDocument(); |
|
339 | + if ($content) { |
|
340 | + $cdoc = new DOMDocument(); |
|
341 | 341 | |
342 | - if (@$cdoc->loadHTML($content)) { |
|
343 | - $cxpath = new DOMXPath($cdoc); |
|
342 | + if (@$cdoc->loadHTML($content)) { |
|
343 | + $cxpath = new DOMXPath($cdoc); |
|
344 | 344 | |
345 | - $og_image = $cxpath->query("//meta[@property='og:image']")->item(0); |
|
346 | - $og_video = $cxpath->query("//meta[@property='og:video']")->item(0); |
|
345 | + $og_image = $cxpath->query("//meta[@property='og:image']")->item(0); |
|
346 | + $og_video = $cxpath->query("//meta[@property='og:video']")->item(0); |
|
347 | 347 | |
348 | - if ($og_video) { |
|
348 | + if ($og_video) { |
|
349 | 349 | |
350 | - $source_stream = $og_video->getAttribute("content"); |
|
350 | + $source_stream = $og_video->getAttribute("content"); |
|
351 | 351 | |
352 | - if ($source_stream) { |
|
352 | + if ($source_stream) { |
|
353 | 353 | |
354 | - if ($og_image) { |
|
355 | - $poster_url = $og_image->getAttribute("content"); |
|
356 | - } else { |
|
357 | - $poster_url = false; |
|
358 | - } |
|
354 | + if ($og_image) { |
|
355 | + $poster_url = $og_image->getAttribute("content"); |
|
356 | + } else { |
|
357 | + $poster_url = false; |
|
358 | + } |
|
359 | 359 | |
360 | - $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
361 | - $found = true; |
|
362 | - } |
|
360 | + $this->handle_as_video($doc, $entry, $source_stream, $poster_url); |
|
361 | + $found = true; |
|
362 | + } |
|
363 | 363 | |
364 | - } else if ($og_image) { |
|
364 | + } else if ($og_image) { |
|
365 | 365 | |
366 | - $og_src = $og_image->getAttribute("content"); |
|
366 | + $og_src = $og_image->getAttribute("content"); |
|
367 | 367 | |
368 | - if ($og_src) { |
|
369 | - $img = $doc->createElement('img'); |
|
370 | - $img->setAttribute("src", $og_src); |
|
368 | + if ($og_src) { |
|
369 | + $img = $doc->createElement('img'); |
|
370 | + $img->setAttribute("src", $og_src); |
|
371 | 371 | |
372 | - $br = $doc->createElement('br'); |
|
373 | - $entry->parentNode->insertBefore($img, $entry); |
|
374 | - $entry->parentNode->insertBefore($br, $entry); |
|
372 | + $br = $doc->createElement('br'); |
|
373 | + $entry->parentNode->insertBefore($img, $entry); |
|
374 | + $entry->parentNode->insertBefore($br, $entry); |
|
375 | 375 | |
376 | - $found = true; |
|
377 | - } |
|
378 | - } |
|
379 | - } |
|
380 | - } |
|
381 | - } |
|
376 | + $found = true; |
|
377 | + } |
|
378 | + } |
|
379 | + } |
|
380 | + } |
|
381 | + } |
|
382 | 382 | |
383 | - } |
|
383 | + } |
|
384 | 384 | |
385 | - // remove tiny thumbnails |
|
386 | - if ($entry->hasAttribute("src")) { |
|
387 | - if ($entry->parentNode && $entry->parentNode->parentNode) { |
|
388 | - $entry->parentNode->parentNode->removeChild($entry->parentNode); |
|
389 | - } |
|
390 | - } |
|
391 | - } |
|
385 | + // remove tiny thumbnails |
|
386 | + if ($entry->hasAttribute("src")) { |
|
387 | + if ($entry->parentNode && $entry->parentNode->parentNode) { |
|
388 | + $entry->parentNode->parentNode->removeChild($entry->parentNode); |
|
389 | + } |
|
390 | + } |
|
391 | + } |
|
392 | 392 | |
393 | - return $found; |
|
394 | - } |
|
393 | + return $found; |
|
394 | + } |
|
395 | 395 | |
396 | - public function hook_article_filter($article) { |
|
396 | + public function hook_article_filter($article) { |
|
397 | 397 | |
398 | - if (strpos($article["link"], "reddit.com/r/") !== false) { |
|
399 | - $doc = new DOMDocument(); |
|
400 | - @$doc->loadHTML($article["content"]); |
|
401 | - $xpath = new DOMXPath($doc); |
|
398 | + if (strpos($article["link"], "reddit.com/r/") !== false) { |
|
399 | + $doc = new DOMDocument(); |
|
400 | + @$doc->loadHTML($article["content"]); |
|
401 | + $xpath = new DOMXPath($doc); |
|
402 | 402 | |
403 | - $content_link = $xpath->query("(//a[contains(., '[link]')])")->item(0); |
|
403 | + $content_link = $xpath->query("(//a[contains(., '[link]')])")->item(0); |
|
404 | 404 | |
405 | - if ($this->host->get($this, "enable_content_dupcheck")) { |
|
405 | + if ($this->host->get($this, "enable_content_dupcheck")) { |
|
406 | 406 | |
407 | - if ($content_link) { |
|
408 | - $content_href = $content_link->getAttribute("href"); |
|
409 | - $entry_guid = $article["guid_hashed"]; |
|
410 | - $owner_uid = $article["owner_uid"]; |
|
407 | + if ($content_link) { |
|
408 | + $content_href = $content_link->getAttribute("href"); |
|
409 | + $entry_guid = $article["guid_hashed"]; |
|
410 | + $owner_uid = $article["owner_uid"]; |
|
411 | 411 | |
412 | - if (DB_TYPE == "pgsql") { |
|
413 | - $interval_qpart = "date_entered < NOW() - INTERVAL '1 day'"; |
|
414 | - } else { |
|
415 | - $interval_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 DAY)"; |
|
416 | - } |
|
412 | + if (DB_TYPE == "pgsql") { |
|
413 | + $interval_qpart = "date_entered < NOW() - INTERVAL '1 day'"; |
|
414 | + } else { |
|
415 | + $interval_qpart = "date_entered < DATE_SUB(NOW(), INTERVAL 1 DAY)"; |
|
416 | + } |
|
417 | 417 | |
418 | - $sth = $this->pdo->prepare("SELECT COUNT(id) AS cid |
|
418 | + $sth = $this->pdo->prepare("SELECT COUNT(id) AS cid |
|
419 | 419 | FROM ttrss_entries, ttrss_user_entries WHERE |
420 | 420 | ref_id = id AND |
421 | 421 | $interval_qpart AND |
@@ -423,153 +423,153 @@ discard block |
||
423 | 423 | owner_uid = ? AND |
424 | 424 | content LIKE ?"); |
425 | 425 | |
426 | - $sth->execute([$entry_guid, $owner_uid, "%href=\"$content_href\">[link]%"]); |
|
426 | + $sth->execute([$entry_guid, $owner_uid, "%href=\"$content_href\">[link]%"]); |
|
427 | 427 | |
428 | - if ($row = $sth->fetch()) { |
|
429 | - $num_found = $row['cid']; |
|
428 | + if ($row = $sth->fetch()) { |
|
429 | + $num_found = $row['cid']; |
|
430 | 430 | |
431 | - if ($num_found > 0) { |
|
432 | - $article["force_catchup"] = true; |
|
433 | - } |
|
434 | - } |
|
435 | - } |
|
436 | - } |
|
431 | + if ($num_found > 0) { |
|
432 | + $article["force_catchup"] = true; |
|
433 | + } |
|
434 | + } |
|
435 | + } |
|
436 | + } |
|
437 | 437 | |
438 | - $found = $this->inline_stuff($article, $doc, $xpath); |
|
438 | + $found = $this->inline_stuff($article, $doc, $xpath); |
|
439 | 439 | |
440 | - $node = $doc->getElementsByTagName('body')->item(0); |
|
440 | + $node = $doc->getElementsByTagName('body')->item(0); |
|
441 | 441 | |
442 | - if ($node && $found) { |
|
443 | - $article["content"] = $doc->saveHTML($node); |
|
444 | - } else if ($content_link) { |
|
445 | - $article = $this->readability($article, $content_link->getAttribute("href"), $doc, $xpath); |
|
446 | - } |
|
447 | - } |
|
442 | + if ($node && $found) { |
|
443 | + $article["content"] = $doc->saveHTML($node); |
|
444 | + } else if ($content_link) { |
|
445 | + $article = $this->readability($article, $content_link->getAttribute("href"), $doc, $xpath); |
|
446 | + } |
|
447 | + } |
|
448 | 448 | |
449 | - return $article; |
|
450 | - } |
|
449 | + return $article; |
|
450 | + } |
|
451 | 451 | |
452 | - public function api_version() { |
|
453 | - return 2; |
|
454 | - } |
|
452 | + public function api_version() { |
|
453 | + return 2; |
|
454 | + } |
|
455 | 455 | |
456 | - private function handle_as_video($doc, $entry, $source_stream, $poster_url = false) { |
|
456 | + private function handle_as_video($doc, $entry, $source_stream, $poster_url = false) { |
|
457 | 457 | |
458 | - Debug::log("handle_as_video: $source_stream", Debug::$LOG_VERBOSE); |
|
458 | + Debug::log("handle_as_video: $source_stream", Debug::$LOG_VERBOSE); |
|
459 | 459 | |
460 | - $video = $doc->createElement('video'); |
|
461 | - $video->setAttribute("autoplay", "1"); |
|
462 | - $video->setAttribute("controls", "1"); |
|
463 | - $video->setAttribute("loop", "1"); |
|
460 | + $video = $doc->createElement('video'); |
|
461 | + $video->setAttribute("autoplay", "1"); |
|
462 | + $video->setAttribute("controls", "1"); |
|
463 | + $video->setAttribute("loop", "1"); |
|
464 | 464 | |
465 | - if ($poster_url) { |
|
466 | - $video->setAttribute("poster", $poster_url); |
|
467 | - } |
|
465 | + if ($poster_url) { |
|
466 | + $video->setAttribute("poster", $poster_url); |
|
467 | + } |
|
468 | 468 | |
469 | - $source = $doc->createElement('source'); |
|
470 | - $source->setAttribute("src", $source_stream); |
|
471 | - $source->setAttribute("type", "video/mp4"); |
|
469 | + $source = $doc->createElement('source'); |
|
470 | + $source->setAttribute("src", $source_stream); |
|
471 | + $source->setAttribute("type", "video/mp4"); |
|
472 | 472 | |
473 | - $video->appendChild($source); |
|
473 | + $video->appendChild($source); |
|
474 | 474 | |
475 | - $br = $doc->createElement('br'); |
|
476 | - $entry->parentNode->insertBefore($video, $entry); |
|
477 | - $entry->parentNode->insertBefore($br, $entry); |
|
475 | + $br = $doc->createElement('br'); |
|
476 | + $entry->parentNode->insertBefore($video, $entry); |
|
477 | + $entry->parentNode->insertBefore($br, $entry); |
|
478 | 478 | |
479 | - $img = $doc->createElement('img'); |
|
480 | - $img->setAttribute("src", |
|
481 | - "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D"); |
|
479 | + $img = $doc->createElement('img'); |
|
480 | + $img->setAttribute("src", |
|
481 | + "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D"); |
|
482 | 482 | |
483 | - $entry->parentNode->insertBefore($img, $entry); |
|
484 | - } |
|
483 | + $entry->parentNode->insertBefore($img, $entry); |
|
484 | + } |
|
485 | 485 | |
486 | - public function testurl() { |
|
487 | - $url = htmlspecialchars($_REQUEST["url"]); |
|
486 | + public function testurl() { |
|
487 | + $url = htmlspecialchars($_REQUEST["url"]); |
|
488 | 488 | |
489 | - header("Content-type: text/plain"); |
|
489 | + header("Content-type: text/plain"); |
|
490 | 490 | |
491 | - print "URL: $url\n"; |
|
491 | + print "URL: $url\n"; |
|
492 | 492 | |
493 | - $doc = new DOMDocument(); |
|
494 | - @$doc->loadHTML("<html><body><a href=\"$url\">[link]</a></body>"); |
|
495 | - $xpath = new DOMXPath($doc); |
|
493 | + $doc = new DOMDocument(); |
|
494 | + @$doc->loadHTML("<html><body><a href=\"$url\">[link]</a></body>"); |
|
495 | + $xpath = new DOMXPath($doc); |
|
496 | 496 | |
497 | - $found = $this->inline_stuff([], $doc, $xpath); |
|
497 | + $found = $this->inline_stuff([], $doc, $xpath); |
|
498 | 498 | |
499 | - print "Inline result: $found\n"; |
|
499 | + print "Inline result: $found\n"; |
|
500 | 500 | |
501 | - if (!$found) { |
|
502 | - print "\nReadability result:\n"; |
|
501 | + if (!$found) { |
|
502 | + print "\nReadability result:\n"; |
|
503 | 503 | |
504 | - $article = $this->readability([], $url, $doc, $xpath); |
|
504 | + $article = $this->readability([], $url, $doc, $xpath); |
|
505 | 505 | |
506 | - print_r($article); |
|
507 | - } else { |
|
508 | - print "\nResulting HTML:\n"; |
|
506 | + print_r($article); |
|
507 | + } else { |
|
508 | + print "\nResulting HTML:\n"; |
|
509 | 509 | |
510 | - print $doc->saveHTML(); |
|
511 | - } |
|
512 | - } |
|
510 | + print $doc->saveHTML(); |
|
511 | + } |
|
512 | + } |
|
513 | 513 | |
514 | - private function get_header($url, $useragent = SELF_USER_AGENT, $header) { |
|
515 | - $ret = false; |
|
514 | + private function get_header($url, $useragent = SELF_USER_AGENT, $header) { |
|
515 | + $ret = false; |
|
516 | 516 | |
517 | - if (function_exists("curl_init") && !defined("NO_CURL")) { |
|
518 | - $ch = curl_init($url); |
|
519 | - curl_setopt($ch, CURLOPT_TIMEOUT, 5); |
|
520 | - curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
|
521 | - curl_setopt($ch, CURLOPT_HEADER, true); |
|
522 | - curl_setopt($ch, CURLOPT_NOBODY, true); |
|
523 | - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, !ini_get("open_basedir")); |
|
524 | - curl_setopt($ch, CURLOPT_USERAGENT, $useragent); |
|
517 | + if (function_exists("curl_init") && !defined("NO_CURL")) { |
|
518 | + $ch = curl_init($url); |
|
519 | + curl_setopt($ch, CURLOPT_TIMEOUT, 5); |
|
520 | + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
|
521 | + curl_setopt($ch, CURLOPT_HEADER, true); |
|
522 | + curl_setopt($ch, CURLOPT_NOBODY, true); |
|
523 | + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, !ini_get("open_basedir")); |
|
524 | + curl_setopt($ch, CURLOPT_USERAGENT, $useragent); |
|
525 | 525 | |
526 | - @curl_exec($ch); |
|
527 | - $ret = curl_getinfo($ch, $header); |
|
528 | - } |
|
526 | + @curl_exec($ch); |
|
527 | + $ret = curl_getinfo($ch, $header); |
|
528 | + } |
|
529 | 529 | |
530 | - return $ret; |
|
531 | - } |
|
530 | + return $ret; |
|
531 | + } |
|
532 | 532 | |
533 | - private function get_content_type($url, $useragent = SELF_USER_AGENT) { |
|
534 | - return $this->get_header($url, $useragent, CURLINFO_CONTENT_TYPE); |
|
535 | - } |
|
533 | + private function get_content_type($url, $useragent = SELF_USER_AGENT) { |
|
534 | + return $this->get_header($url, $useragent, CURLINFO_CONTENT_TYPE); |
|
535 | + } |
|
536 | 536 | |
537 | - private function get_location($url, $useragent = SELF_USER_AGENT) { |
|
538 | - return $this->get_header($url, $useragent, CURLINFO_EFFECTIVE_URL); |
|
539 | - } |
|
537 | + private function get_location($url, $useragent = SELF_USER_AGENT) { |
|
538 | + return $this->get_header($url, $useragent, CURLINFO_EFFECTIVE_URL); |
|
539 | + } |
|
540 | 540 | |
541 | - /** |
|
542 | - * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
543 | - */ |
|
544 | - private function readability($article, $url, $doc, $xpath, $debug = false) { |
|
541 | + /** |
|
542 | + * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
543 | + */ |
|
544 | + private function readability($article, $url, $doc, $xpath, $debug = false) { |
|
545 | 545 | |
546 | - if (!defined('NO_CURL') && function_exists("curl_init") && $this->host->get($this, "enable_readability") && |
|
547 | - mb_strlen(strip_tags($article["content"])) <= 150) { |
|
546 | + if (!defined('NO_CURL') && function_exists("curl_init") && $this->host->get($this, "enable_readability") && |
|
547 | + mb_strlen(strip_tags($article["content"])) <= 150) { |
|
548 | 548 | |
549 | - // do not try to embed posts linking back to other reddit posts |
|
550 | - // readability.php requires PHP 5.6 |
|
551 | - if ($url && strpos($url, "reddit.com") === false && version_compare(PHP_VERSION, '5.6.0', '>=')) { |
|
549 | + // do not try to embed posts linking back to other reddit posts |
|
550 | + // readability.php requires PHP 5.6 |
|
551 | + if ($url && strpos($url, "reddit.com") === false && version_compare(PHP_VERSION, '5.6.0', '>=')) { |
|
552 | 552 | |
553 | - /* link may lead to a huge video file or whatever, we need to check content type before trying to |
|
553 | + /* link may lead to a huge video file or whatever, we need to check content type before trying to |
|
554 | 554 | parse it which p much requires curl */ |
555 | 555 | |
556 | - $useragent_compat = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"; |
|
557 | - $content_type = $this->get_content_type($url, $useragent_compat); |
|
556 | + $useragent_compat = "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)"; |
|
557 | + $content_type = $this->get_content_type($url, $useragent_compat); |
|
558 | 558 | |
559 | - if ($content_type && strpos($content_type, "text/html") !== false) { |
|
559 | + if ($content_type && strpos($content_type, "text/html") !== false) { |
|
560 | 560 | |
561 | - foreach ($this->host->get_hooks(PluginHost::HOOK_GET_FULL_TEXT) as $p) { |
|
562 | - $extracted_content = $p->hook_get_full_text($url); |
|
561 | + foreach ($this->host->get_hooks(PluginHost::HOOK_GET_FULL_TEXT) as $p) { |
|
562 | + $extracted_content = $p->hook_get_full_text($url); |
|
563 | 563 | |
564 | - if ($extracted_content) { |
|
565 | - $article["content"] = $extracted_content; |
|
566 | - break; |
|
567 | - } |
|
568 | - } |
|
569 | - } |
|
570 | - } |
|
571 | - } |
|
564 | + if ($extracted_content) { |
|
565 | + $article["content"] = $extracted_content; |
|
566 | + break; |
|
567 | + } |
|
568 | + } |
|
569 | + } |
|
570 | + } |
|
571 | + } |
|
572 | 572 | |
573 | - return $article; |
|
574 | - } |
|
573 | + return $article; |
|
574 | + } |
|
575 | 575 | } |
@@ -1,56 +1,56 @@ |
||
1 | 1 | <?php |
2 | 2 | class Bookmarklets extends Plugin { |
3 | - private $host; |
|
3 | + private $host; |
|
4 | 4 | |
5 | - function about() { |
|
5 | + function about() { |
|
6 | 6 | return array(1.0, |
7 | - "Easy feed subscription and web page sharing using bookmarklets", |
|
8 | - "fox", |
|
9 | - false, |
|
10 | - "https://git.tt-rss.org/fox/tt-rss/wiki/ShareAnything"); |
|
11 | - } |
|
7 | + "Easy feed subscription and web page sharing using bookmarklets", |
|
8 | + "fox", |
|
9 | + false, |
|
10 | + "https://git.tt-rss.org/fox/tt-rss/wiki/ShareAnything"); |
|
11 | + } |
|
12 | 12 | |
13 | - function init($host) { |
|
13 | + function init($host) { |
|
14 | 14 | $this->host = $host; |
15 | 15 | |
16 | 16 | $host->add_hook($host::HOOK_PREFS_TAB, $this); |
17 | - } |
|
17 | + } |
|
18 | 18 | |
19 | - function hook_prefs_tab($args) { |
|
19 | + function hook_prefs_tab($args) { |
|
20 | 20 | if ($args == "prefFeeds") { |
21 | 21 | |
22 | - print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
22 | + print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
23 | 23 | title=\"<i class='material-icons'>bookmark</i> ".__('Bookmarklets')."\">"; |
24 | 24 | |
25 | - print "<h3>".__("Drag the link below to your browser toolbar, open the feed you're interested in in your browser and click on the link to subscribe to it.")."</h3>"; |
|
25 | + print "<h3>".__("Drag the link below to your browser toolbar, open the feed you're interested in in your browser and click on the link to subscribe to it.")."</h3>"; |
|
26 | 26 | |
27 | - $bm_subscribe_url = str_replace('%s', '', Pref_Feeds::subscribe_to_feed_url()); |
|
27 | + $bm_subscribe_url = str_replace('%s', '', Pref_Feeds::subscribe_to_feed_url()); |
|
28 | 28 | |
29 | - $confirm_str = str_replace("'", "\'", __('Subscribe to %s in Tiny Tiny RSS?')); |
|
29 | + $confirm_str = str_replace("'", "\'", __('Subscribe to %s in Tiny Tiny RSS?')); |
|
30 | 30 | |
31 | - $bm_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url'+window.location.href}"); |
|
31 | + $bm_url = htmlspecialchars("javascript:{if(confirm('$confirm_str'.replace('%s',window.location.href)))window.location.href='$bm_subscribe_url'+window.location.href}"); |
|
32 | 32 | |
33 | - print "<p><label class='dijitButton'>"; |
|
34 | - print "<a href=\"$bm_url\">".__('Subscribe in Tiny Tiny RSS')."</a>"; |
|
35 | - print "</label></p>"; |
|
33 | + print "<p><label class='dijitButton'>"; |
|
34 | + print "<a href=\"$bm_url\">".__('Subscribe in Tiny Tiny RSS')."</a>"; |
|
35 | + print "</label></p>"; |
|
36 | 36 | |
37 | - print "<h3>".__("Use this bookmarklet to publish arbitrary pages using Tiny Tiny RSS")."</h3>"; |
|
37 | + print "<h3>".__("Use this bookmarklet to publish arbitrary pages using Tiny Tiny RSS")."</h3>"; |
|
38 | 38 | |
39 | - print "<label class='dijitButton'>"; |
|
40 | - $bm_url = htmlspecialchars("javascript:(function(){var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='".get_self_url_prefix()."/public.php?op=sharepopup',l=d.location,e=encodeURIComponent,g=f+'&title='+((e(s))?e(s):e(document.title))+'&url='+e(l.href);function a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=500,height=250')){l.href=g;}}a();})()"); |
|
41 | - print "<a href=\"$bm_url\">".__('Share with Tiny Tiny RSS')."</a>"; |
|
42 | - print "</label>"; |
|
39 | + print "<label class='dijitButton'>"; |
|
40 | + $bm_url = htmlspecialchars("javascript:(function(){var d=document,w=window,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),f='".get_self_url_prefix()."/public.php?op=sharepopup',l=d.location,e=encodeURIComponent,g=f+'&title='+((e(s))?e(s):e(document.title))+'&url='+e(l.href);function a(){if(!w.open(g,'t','toolbar=0,resizable=0,scrollbars=1,status=1,width=500,height=250')){l.href=g;}}a();})()"); |
|
41 | + print "<a href=\"$bm_url\">".__('Share with Tiny Tiny RSS')."</a>"; |
|
42 | + print "</label>"; |
|
43 | 43 | |
44 | - print "<button dojoType='dijit.form.Button' class='alt-info' onclick='window.open(\"https://tt-rss.org/wiki/ShareAnything\")'> |
|
44 | + print "<button dojoType='dijit.form.Button' class='alt-info' onclick='window.open(\"https://tt-rss.org/wiki/ShareAnything\")'> |
|
45 | 45 | <i class='material-icons'>help</i> ".__("More info...")."</button>"; |
46 | 46 | |
47 | - print "</div>"; #pane |
|
47 | + print "</div>"; #pane |
|
48 | 48 | |
49 | - } |
|
50 | - } |
|
49 | + } |
|
50 | + } |
|
51 | 51 | |
52 | - public function api_version() { |
|
53 | - return 2; |
|
54 | - } |
|
52 | + public function api_version() { |
|
53 | + return 2; |
|
54 | + } |
|
55 | 55 | |
56 | 56 | } |
@@ -1,23 +1,23 @@ |
||
1 | 1 | <?php |
2 | 2 | class Af_Zz_VidMute extends Plugin { |
3 | - private $host; |
|
3 | + private $host; |
|
4 | 4 | |
5 | - public function about() { |
|
6 | - return array(1.0, |
|
7 | - "Mute audio in HTML5 videos", |
|
8 | - "fox"); |
|
9 | - } |
|
5 | + public function about() { |
|
6 | + return array(1.0, |
|
7 | + "Mute audio in HTML5 videos", |
|
8 | + "fox"); |
|
9 | + } |
|
10 | 10 | |
11 | - public function init($host) { |
|
12 | - $this->host = $host; |
|
13 | - } |
|
11 | + public function init($host) { |
|
12 | + $this->host = $host; |
|
13 | + } |
|
14 | 14 | |
15 | - public function get_js() { |
|
16 | - return file_get_contents(__DIR__."/init.js"); |
|
17 | - } |
|
15 | + public function get_js() { |
|
16 | + return file_get_contents(__DIR__."/init.js"); |
|
17 | + } |
|
18 | 18 | |
19 | - public function api_version() { |
|
20 | - return 2; |
|
21 | - } |
|
19 | + public function api_version() { |
|
20 | + return 2; |
|
21 | + } |
|
22 | 22 | |
23 | 23 | } |
@@ -1,45 +1,45 @@ discard block |
||
1 | 1 | <?php |
2 | 2 | class Cache_Starred_Images extends Plugin { |
3 | 3 | |
4 | - /* @var PluginHost $host */ |
|
5 | - private $host; |
|
6 | - /* @var DiskCache $cache */ |
|
7 | - private $cache; |
|
4 | + /* @var PluginHost $host */ |
|
5 | + private $host; |
|
6 | + /* @var DiskCache $cache */ |
|
7 | + private $cache; |
|
8 | 8 | private $max_cache_attempts = 5; // per-article |
9 | 9 | |
10 | - public function about() { |
|
11 | - return array(1.0, |
|
12 | - "Automatically cache media files in Starred articles", |
|
13 | - "fox"); |
|
14 | - } |
|
10 | + public function about() { |
|
11 | + return array(1.0, |
|
12 | + "Automatically cache media files in Starred articles", |
|
13 | + "fox"); |
|
14 | + } |
|
15 | 15 | |
16 | - public function init($host) { |
|
17 | - $this->host = $host; |
|
18 | - $this->cache = new DiskCache("starred-images"); |
|
16 | + public function init($host) { |
|
17 | + $this->host = $host; |
|
18 | + $this->cache = new DiskCache("starred-images"); |
|
19 | 19 | |
20 | - if ($this->cache->makeDir()) { |
|
21 | - chmod($this->cache->getDir(), 0777); |
|
22 | - } |
|
20 | + if ($this->cache->makeDir()) { |
|
21 | + chmod($this->cache->getDir(), 0777); |
|
22 | + } |
|
23 | 23 | |
24 | - if (!$this->cache->exists(".no-auto-expiry")) { |
|
25 | - $this->cache->touch(".no-auto-expiry"); |
|
26 | - } |
|
24 | + if (!$this->cache->exists(".no-auto-expiry")) { |
|
25 | + $this->cache->touch(".no-auto-expiry"); |
|
26 | + } |
|
27 | 27 | |
28 | - if ($this->cache->isWritable()) { |
|
29 | - $host->add_hook($host::HOOK_HOUSE_KEEPING, $this); |
|
30 | - $host->add_hook($host::HOOK_ENCLOSURE_ENTRY, $this); |
|
31 | - $host->add_hook($host::HOOK_SANITIZE, $this); |
|
32 | - } else { |
|
33 | - user_error("Starred cache directory ".$this->cache->getDir()." is not writable.", E_USER_WARNING); |
|
34 | - } |
|
35 | - } |
|
28 | + if ($this->cache->isWritable()) { |
|
29 | + $host->add_hook($host::HOOK_HOUSE_KEEPING, $this); |
|
30 | + $host->add_hook($host::HOOK_ENCLOSURE_ENTRY, $this); |
|
31 | + $host->add_hook($host::HOOK_SANITIZE, $this); |
|
32 | + } else { |
|
33 | + user_error("Starred cache directory ".$this->cache->getDir()." is not writable.", E_USER_WARNING); |
|
34 | + } |
|
35 | + } |
|
36 | 36 | |
37 | - public function hook_house_keeping() { |
|
38 | - /* since HOOK_UPDATE_TASK is not available to user plugins, this hook is a next best thing */ |
|
37 | + public function hook_house_keeping() { |
|
38 | + /* since HOOK_UPDATE_TASK is not available to user plugins, this hook is a next best thing */ |
|
39 | 39 | |
40 | - Debug::log("caching media of starred articles for user ".$this->host->get_owner_uid()."..."); |
|
40 | + Debug::log("caching media of starred articles for user ".$this->host->get_owner_uid()."..."); |
|
41 | 41 | |
42 | - $sth = $this->pdo->prepare("SELECT content, ttrss_entries.title, |
|
42 | + $sth = $this->pdo->prepare("SELECT content, ttrss_entries.title, |
|
43 | 43 | ttrss_user_entries.owner_uid, link, site_url, ttrss_entries.id, plugin_data |
44 | 44 | FROM ttrss_entries, ttrss_user_entries LEFT JOIN ttrss_feeds ON |
45 | 45 | (ttrss_user_entries.feed_id = ttrss_feeds.id) |
@@ -50,117 +50,117 @@ discard block |
||
50 | 50 | plugin_data NOT LIKE '%starred_cache_images%' |
51 | 51 | ORDER BY ".sql_random_function()." LIMIT 100"); |
52 | 52 | |
53 | - if ($sth->execute([$this->host->get_owner_uid()])) { |
|
53 | + if ($sth->execute([$this->host->get_owner_uid()])) { |
|
54 | 54 | |
55 | - $usth = $this->pdo->prepare("UPDATE ttrss_entries SET plugin_data = ? WHERE id = ?"); |
|
55 | + $usth = $this->pdo->prepare("UPDATE ttrss_entries SET plugin_data = ? WHERE id = ?"); |
|
56 | 56 | |
57 | - while ($line = $sth->fetch()) { |
|
58 | - Debug::log("processing article ".$line["title"], Debug::$LOG_VERBOSE); |
|
57 | + while ($line = $sth->fetch()) { |
|
58 | + Debug::log("processing article ".$line["title"], Debug::$LOG_VERBOSE); |
|
59 | 59 | |
60 | - if ($line["site_url"]) { |
|
61 | - $success = $this->cache_article_images($line["content"], $line["site_url"], $line["owner_uid"], $line["id"]); |
|
60 | + if ($line["site_url"]) { |
|
61 | + $success = $this->cache_article_images($line["content"], $line["site_url"], $line["owner_uid"], $line["id"]); |
|
62 | 62 | |
63 | - if ($success) { |
|
64 | - $plugin_data = "starred_cache_images,${line['owner_uid']}:".$line["plugin_data"]; |
|
63 | + if ($success) { |
|
64 | + $plugin_data = "starred_cache_images,${line['owner_uid']}:".$line["plugin_data"]; |
|
65 | 65 | |
66 | - $usth->execute([$plugin_data, $line['id']]); |
|
67 | - } |
|
68 | - } |
|
69 | - } |
|
70 | - } |
|
66 | + $usth->execute([$plugin_data, $line['id']]); |
|
67 | + } |
|
68 | + } |
|
69 | + } |
|
70 | + } |
|
71 | 71 | |
72 | - /* actual housekeeping */ |
|
72 | + /* actual housekeeping */ |
|
73 | 73 | |
74 | - Debug::log("expiring ".$this->cache->getDir()."..."); |
|
74 | + Debug::log("expiring ".$this->cache->getDir()."..."); |
|
75 | 75 | |
76 | - $files = glob($this->cache->getDir()."/*.{png,mp4,status}", GLOB_BRACE); |
|
76 | + $files = glob($this->cache->getDir()."/*.{png,mp4,status}", GLOB_BRACE); |
|
77 | 77 | |
78 | - $last_article_id = 0; |
|
79 | - $article_exists = 1; |
|
78 | + $last_article_id = 0; |
|
79 | + $article_exists = 1; |
|
80 | 80 | |
81 | - foreach ($files as $file) { |
|
82 | - list ($article_id, $hash) = explode("-", basename($file)); |
|
81 | + foreach ($files as $file) { |
|
82 | + list ($article_id, $hash) = explode("-", basename($file)); |
|
83 | 83 | |
84 | - if ($article_id != $last_article_id) { |
|
85 | - $last_article_id = $article_id; |
|
84 | + if ($article_id != $last_article_id) { |
|
85 | + $last_article_id = $article_id; |
|
86 | 86 | |
87 | - $sth = $this->pdo->prepare("SELECT id FROM ttrss_entries WHERE id = ?"); |
|
88 | - $sth->execute([$article_id]); |
|
87 | + $sth = $this->pdo->prepare("SELECT id FROM ttrss_entries WHERE id = ?"); |
|
88 | + $sth->execute([$article_id]); |
|
89 | 89 | |
90 | - $article_exists = $sth->fetch(); |
|
91 | - } |
|
90 | + $article_exists = $sth->fetch(); |
|
91 | + } |
|
92 | 92 | |
93 | - if (!$article_exists) { |
|
94 | - unlink($file); |
|
95 | - } |
|
96 | - } |
|
97 | - } |
|
93 | + if (!$article_exists) { |
|
94 | + unlink($file); |
|
95 | + } |
|
96 | + } |
|
97 | + } |
|
98 | 98 | |
99 | - public function hook_enclosure_entry($enc, $article_id) { |
|
100 | - $local_filename = $article_id."-".sha1($enc["content_url"]); |
|
99 | + public function hook_enclosure_entry($enc, $article_id) { |
|
100 | + $local_filename = $article_id."-".sha1($enc["content_url"]); |
|
101 | 101 | |
102 | - if ($this->cache->exists($local_filename)) { |
|
103 | - $enc["content_url"] = $this->cache->getUrl($local_filename); |
|
104 | - } |
|
102 | + if ($this->cache->exists($local_filename)) { |
|
103 | + $enc["content_url"] = $this->cache->getUrl($local_filename); |
|
104 | + } |
|
105 | 105 | |
106 | - return $enc; |
|
107 | - } |
|
106 | + return $enc; |
|
107 | + } |
|
108 | 108 | |
109 | - public function hook_sanitize($doc, $site_url, $allowed_elements, $disallowed_attributes, $article_id) { |
|
110 | - $xpath = new DOMXpath($doc); |
|
109 | + public function hook_sanitize($doc, $site_url, $allowed_elements, $disallowed_attributes, $article_id) { |
|
110 | + $xpath = new DOMXpath($doc); |
|
111 | 111 | |
112 | - if ($article_id) { |
|
113 | - $entries = $xpath->query('(//img[@src])|(//video/source[@src])'); |
|
112 | + if ($article_id) { |
|
113 | + $entries = $xpath->query('(//img[@src])|(//video/source[@src])'); |
|
114 | 114 | |
115 | - foreach ($entries as $entry) { |
|
116 | - if ($entry->hasAttribute('src')) { |
|
117 | - $src = rewrite_relative_url($site_url, $entry->getAttribute('src')); |
|
115 | + foreach ($entries as $entry) { |
|
116 | + if ($entry->hasAttribute('src')) { |
|
117 | + $src = rewrite_relative_url($site_url, $entry->getAttribute('src')); |
|
118 | 118 | |
119 | - $local_filename = $article_id."-".sha1($src); |
|
119 | + $local_filename = $article_id."-".sha1($src); |
|
120 | 120 | |
121 | - if ($this->cache->exists($local_filename)) { |
|
122 | - $entry->setAttribute("src", $this->cache->getUrl($local_filename)); |
|
123 | - $entry->removeAttribute("srcset"); |
|
124 | - } |
|
125 | - } |
|
126 | - } |
|
127 | - } |
|
121 | + if ($this->cache->exists($local_filename)) { |
|
122 | + $entry->setAttribute("src", $this->cache->getUrl($local_filename)); |
|
123 | + $entry->removeAttribute("srcset"); |
|
124 | + } |
|
125 | + } |
|
126 | + } |
|
127 | + } |
|
128 | 128 | |
129 | - return $doc; |
|
130 | - } |
|
129 | + return $doc; |
|
130 | + } |
|
131 | 131 | |
132 | - private function cache_url($article_id, $url) { |
|
133 | - $local_filename = $article_id."-".sha1($url); |
|
132 | + private function cache_url($article_id, $url) { |
|
133 | + $local_filename = $article_id."-".sha1($url); |
|
134 | 134 | |
135 | - if (!$this->cache->exists($local_filename)) { |
|
136 | - Debug::log("cache_images: downloading: $url to $local_filename", Debug::$LOG_VERBOSE); |
|
135 | + if (!$this->cache->exists($local_filename)) { |
|
136 | + Debug::log("cache_images: downloading: $url to $local_filename", Debug::$LOG_VERBOSE); |
|
137 | 137 | |
138 | - $data = fetch_file_contents(["url" => $url, "max_size" => MAX_CACHE_FILE_SIZE]); |
|
138 | + $data = fetch_file_contents(["url" => $url, "max_size" => MAX_CACHE_FILE_SIZE]); |
|
139 | 139 | |
140 | - if ($data) { |
|
141 | - return $this->cache->put($local_filename, $data); |
|
142 | - } |
|
143 | - ; |
|
140 | + if ($data) { |
|
141 | + return $this->cache->put($local_filename, $data); |
|
142 | + } |
|
143 | + ; |
|
144 | 144 | |
145 | - } else { |
|
146 | - //Debug::log("cache_images: local file exists for $url", Debug::$LOG_VERBOSE); |
|
145 | + } else { |
|
146 | + //Debug::log("cache_images: local file exists for $url", Debug::$LOG_VERBOSE); |
|
147 | 147 | |
148 | - return true; |
|
149 | - } |
|
148 | + return true; |
|
149 | + } |
|
150 | 150 | |
151 | - return false; |
|
152 | - } |
|
151 | + return false; |
|
152 | + } |
|
153 | 153 | |
154 | - private function cache_article_images($content, $site_url, $owner_uid, $article_id) { |
|
155 | - $status_filename = $article_id."-".sha1($site_url).".status"; |
|
154 | + private function cache_article_images($content, $site_url, $owner_uid, $article_id) { |
|
155 | + $status_filename = $article_id."-".sha1($site_url).".status"; |
|
156 | 156 | |
157 | - /* housekeeping might run as a separate user, in this case status/media might not be writable */ |
|
158 | - if (!$this->cache->isWritable($status_filename)) { |
|
159 | - Debug::log("status not writable: $status_filename", Debug::$LOG_VERBOSE); |
|
160 | - return false; |
|
161 | - } |
|
157 | + /* housekeeping might run as a separate user, in this case status/media might not be writable */ |
|
158 | + if (!$this->cache->isWritable($status_filename)) { |
|
159 | + Debug::log("status not writable: $status_filename", Debug::$LOG_VERBOSE); |
|
160 | + return false; |
|
161 | + } |
|
162 | 162 | |
163 | - Debug::log("status: $status_filename", Debug::$LOG_VERBOSE); |
|
163 | + Debug::log("status: $status_filename", Debug::$LOG_VERBOSE); |
|
164 | 164 | |
165 | 165 | if ($this->cache->exists($status_filename)) { |
166 | 166 | $status = json_decode($this->cache->get($status_filename), true); |
@@ -181,49 +181,49 @@ discard block |
||
181 | 181 | return false; |
182 | 182 | } |
183 | 183 | |
184 | - $doc = new DOMDocument(); |
|
184 | + $doc = new DOMDocument(); |
|
185 | 185 | |
186 | - $has_images = false; |
|
187 | - $success = false; |
|
186 | + $has_images = false; |
|
187 | + $success = false; |
|
188 | 188 | |
189 | 189 | if ($doc->loadHTML('<?xml encoding="UTF-8">'.$content)) { |
190 | - $xpath = new DOMXPath($doc); |
|
191 | - $entries = $xpath->query('(//img[@src])|(//video/source[@src])'); |
|
190 | + $xpath = new DOMXPath($doc); |
|
191 | + $entries = $xpath->query('(//img[@src])|(//video/source[@src])'); |
|
192 | 192 | |
193 | - foreach ($entries as $entry) { |
|
193 | + foreach ($entries as $entry) { |
|
194 | 194 | |
195 | - if ($entry->hasAttribute('src') && strpos($entry->getAttribute('src'), "data:") !== 0) { |
|
195 | + if ($entry->hasAttribute('src') && strpos($entry->getAttribute('src'), "data:") !== 0) { |
|
196 | 196 | |
197 | - $has_images = true; |
|
197 | + $has_images = true; |
|
198 | 198 | |
199 | - $src = rewrite_relative_url($site_url, $entry->getAttribute('src')); |
|
199 | + $src = rewrite_relative_url($site_url, $entry->getAttribute('src')); |
|
200 | 200 | |
201 | - if ($this->cache_url($article_id, $src)) { |
|
202 | - $success = true; |
|
203 | - } |
|
204 | - } |
|
205 | - } |
|
206 | - } |
|
201 | + if ($this->cache_url($article_id, $src)) { |
|
202 | + $success = true; |
|
203 | + } |
|
204 | + } |
|
205 | + } |
|
206 | + } |
|
207 | 207 | |
208 | - $esth = $this->pdo->prepare("SELECT content_url FROM ttrss_enclosures WHERE post_id = ? AND |
|
208 | + $esth = $this->pdo->prepare("SELECT content_url FROM ttrss_enclosures WHERE post_id = ? AND |
|
209 | 209 | (content_type LIKE '%image%' OR content_type LIKE '%video%')"); |
210 | 210 | |
211 | 211 | if ($esth->execute([$article_id])) { |
212 | - while ($enc = $esth->fetch()) { |
|
212 | + while ($enc = $esth->fetch()) { |
|
213 | 213 | |
214 | - $has_images = true; |
|
215 | - $url = rewrite_relative_url($site_url, $enc["content_url"]); |
|
214 | + $has_images = true; |
|
215 | + $url = rewrite_relative_url($site_url, $enc["content_url"]); |
|
216 | 216 | |
217 | - if ($this->cache_url($article_id, $url)) { |
|
218 | - $success = true; |
|
219 | - } |
|
220 | - } |
|
221 | - } |
|
217 | + if ($this->cache_url($article_id, $url)) { |
|
218 | + $success = true; |
|
219 | + } |
|
220 | + } |
|
221 | + } |
|
222 | 222 | |
223 | - return $success || !$has_images; |
|
224 | - } |
|
223 | + return $success || !$has_images; |
|
224 | + } |
|
225 | 225 | |
226 | - public function api_version() { |
|
227 | - return 2; |
|
228 | - } |
|
226 | + public function api_version() { |
|
227 | + return 2; |
|
228 | + } |
|
229 | 229 | } |
@@ -1,94 +1,94 @@ |
||
1 | 1 | <?php |
2 | 2 | class Auth_Remote extends Plugin implements IAuthModule { |
3 | 3 | |
4 | - private $host; |
|
5 | - /* @var Auth_Base $base */ |
|
6 | - private $base; |
|
7 | - |
|
8 | - public function about() { |
|
9 | - return array(1.0, |
|
10 | - "Authenticates against remote password (e.g. supplied by Apache)", |
|
11 | - "fox", |
|
12 | - true); |
|
13 | - } |
|
14 | - |
|
15 | - /* @var PluginHost $host */ |
|
16 | - public function init($host) { |
|
17 | - $this->host = $host; |
|
18 | - $this->base = new Auth_Base(); |
|
19 | - |
|
20 | - $host->add_hook($host::HOOK_AUTH_USER, $this); |
|
21 | - } |
|
22 | - |
|
23 | - public function get_login_by_ssl_certificate() { |
|
24 | - $cert_serial = get_ssl_certificate_id(); |
|
25 | - |
|
26 | - if ($cert_serial) { |
|
27 | - $sth = $this->pdo->prepare("SELECT login FROM ttrss_user_prefs, ttrss_users |
|
4 | + private $host; |
|
5 | + /* @var Auth_Base $base */ |
|
6 | + private $base; |
|
7 | + |
|
8 | + public function about() { |
|
9 | + return array(1.0, |
|
10 | + "Authenticates against remote password (e.g. supplied by Apache)", |
|
11 | + "fox", |
|
12 | + true); |
|
13 | + } |
|
14 | + |
|
15 | + /* @var PluginHost $host */ |
|
16 | + public function init($host) { |
|
17 | + $this->host = $host; |
|
18 | + $this->base = new Auth_Base(); |
|
19 | + |
|
20 | + $host->add_hook($host::HOOK_AUTH_USER, $this); |
|
21 | + } |
|
22 | + |
|
23 | + public function get_login_by_ssl_certificate() { |
|
24 | + $cert_serial = get_ssl_certificate_id(); |
|
25 | + |
|
26 | + if ($cert_serial) { |
|
27 | + $sth = $this->pdo->prepare("SELECT login FROM ttrss_user_prefs, ttrss_users |
|
28 | 28 | WHERE pref_name = 'SSL_CERT_SERIAL' AND value = ? AND |
29 | 29 | owner_uid = ttrss_users.id"); |
30 | - $sth->execute([$cert_serial]); |
|
31 | - |
|
32 | - if ($row = $sth->fetch()) { |
|
33 | - return $row['login']; |
|
34 | - } |
|
35 | - } |
|
36 | - |
|
37 | - return ""; |
|
38 | - } |
|
39 | - |
|
40 | - /** |
|
41 | - * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
42 | - */ |
|
43 | - public function authenticate($login, $password) { |
|
44 | - $try_login = $_SERVER["REMOTE_USER"]; |
|
45 | - |
|
46 | - // php-cgi |
|
47 | - if (!$try_login) { |
|
48 | - $try_login = $_SERVER["REDIRECT_REMOTE_USER"]; |
|
49 | - } |
|
50 | - if (!$try_login) { |
|
51 | - $try_login = $_SERVER["PHP_AUTH_USER"]; |
|
52 | - } |
|
53 | - |
|
54 | - if (!$try_login) { |
|
55 | - $try_login = $this->get_login_by_ssl_certificate(); |
|
56 | - } |
|
57 | - |
|
58 | - if ($try_login) { |
|
59 | - $user_id = $this->base->auto_create_user($try_login, $password); |
|
60 | - |
|
61 | - if ($user_id) { |
|
62 | - $_SESSION["fake_login"] = $try_login; |
|
63 | - $_SESSION["fake_password"] = "******"; |
|
64 | - $_SESSION["hide_hello"] = true; |
|
65 | - $_SESSION["hide_logout"] = true; |
|
66 | - |
|
67 | - // LemonLDAP can send user informations via HTTP HEADER |
|
68 | - if (defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE) { |
|
69 | - // update user name |
|
70 | - $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN']; |
|
71 | - if ($fullname) { |
|
72 | - $sth = $this->pdo->prepare("UPDATE ttrss_users SET full_name = ? WHERE id = ?"); |
|
73 | - $sth->execute([$fullname, $user_id]); |
|
74 | - } |
|
75 | - // update user mail |
|
76 | - $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL']; |
|
77 | - if ($email) { |
|
78 | - $sth = $this->pdo->prepare("UPDATE ttrss_users SET email = ? WHERE id = ?"); |
|
79 | - $sth->execute([$email, $user_id]); |
|
80 | - } |
|
81 | - } |
|
82 | - |
|
83 | - return $user_id; |
|
84 | - } |
|
85 | - } |
|
86 | - |
|
87 | - return false; |
|
88 | - } |
|
89 | - |
|
90 | - public function api_version() { |
|
91 | - return 2; |
|
92 | - } |
|
30 | + $sth->execute([$cert_serial]); |
|
31 | + |
|
32 | + if ($row = $sth->fetch()) { |
|
33 | + return $row['login']; |
|
34 | + } |
|
35 | + } |
|
36 | + |
|
37 | + return ""; |
|
38 | + } |
|
39 | + |
|
40 | + /** |
|
41 | + * @SuppressWarnings(PHPMD.UnusedFormalParameter) |
|
42 | + */ |
|
43 | + public function authenticate($login, $password) { |
|
44 | + $try_login = $_SERVER["REMOTE_USER"]; |
|
45 | + |
|
46 | + // php-cgi |
|
47 | + if (!$try_login) { |
|
48 | + $try_login = $_SERVER["REDIRECT_REMOTE_USER"]; |
|
49 | + } |
|
50 | + if (!$try_login) { |
|
51 | + $try_login = $_SERVER["PHP_AUTH_USER"]; |
|
52 | + } |
|
53 | + |
|
54 | + if (!$try_login) { |
|
55 | + $try_login = $this->get_login_by_ssl_certificate(); |
|
56 | + } |
|
57 | + |
|
58 | + if ($try_login) { |
|
59 | + $user_id = $this->base->auto_create_user($try_login, $password); |
|
60 | + |
|
61 | + if ($user_id) { |
|
62 | + $_SESSION["fake_login"] = $try_login; |
|
63 | + $_SESSION["fake_password"] = "******"; |
|
64 | + $_SESSION["hide_hello"] = true; |
|
65 | + $_SESSION["hide_logout"] = true; |
|
66 | + |
|
67 | + // LemonLDAP can send user informations via HTTP HEADER |
|
68 | + if (defined('AUTH_AUTO_CREATE') && AUTH_AUTO_CREATE) { |
|
69 | + // update user name |
|
70 | + $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN']; |
|
71 | + if ($fullname) { |
|
72 | + $sth = $this->pdo->prepare("UPDATE ttrss_users SET full_name = ? WHERE id = ?"); |
|
73 | + $sth->execute([$fullname, $user_id]); |
|
74 | + } |
|
75 | + // update user mail |
|
76 | + $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL']; |
|
77 | + if ($email) { |
|
78 | + $sth = $this->pdo->prepare("UPDATE ttrss_users SET email = ? WHERE id = ?"); |
|
79 | + $sth->execute([$email, $user_id]); |
|
80 | + } |
|
81 | + } |
|
82 | + |
|
83 | + return $user_id; |
|
84 | + } |
|
85 | + } |
|
86 | + |
|
87 | + return false; |
|
88 | + } |
|
89 | + |
|
90 | + public function api_version() { |
|
91 | + return 2; |
|
92 | + } |
|
93 | 93 | |
94 | 94 | } |
@@ -1,66 +1,66 @@ discard block |
||
1 | 1 | <?php |
2 | 2 | class NSFW extends Plugin { |
3 | - private $host; |
|
3 | + private $host; |
|
4 | 4 | |
5 | - public function about() { |
|
6 | - return array(1.0, |
|
7 | - "Hide article content based on tags", |
|
8 | - "fox", |
|
9 | - false); |
|
10 | - } |
|
5 | + public function about() { |
|
6 | + return array(1.0, |
|
7 | + "Hide article content based on tags", |
|
8 | + "fox", |
|
9 | + false); |
|
10 | + } |
|
11 | 11 | |
12 | - public function init($host) { |
|
13 | - $this->host = $host; |
|
12 | + public function init($host) { |
|
13 | + $this->host = $host; |
|
14 | 14 | |
15 | - $host->add_hook($host::HOOK_RENDER_ARTICLE, $this); |
|
16 | - $host->add_hook($host::HOOK_RENDER_ARTICLE_CDM, $this); |
|
17 | - $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
15 | + $host->add_hook($host::HOOK_RENDER_ARTICLE, $this); |
|
16 | + $host->add_hook($host::HOOK_RENDER_ARTICLE_CDM, $this); |
|
17 | + $host->add_hook($host::HOOK_PREFS_TAB, $this); |
|
18 | 18 | |
19 | - } |
|
19 | + } |
|
20 | 20 | |
21 | - public function get_js() { |
|
22 | - return file_get_contents(dirname(__FILE__)."/init.js"); |
|
23 | - } |
|
21 | + public function get_js() { |
|
22 | + return file_get_contents(dirname(__FILE__)."/init.js"); |
|
23 | + } |
|
24 | 24 | |
25 | - public function hook_render_article($article) { |
|
26 | - $tags = array_map("trim", explode(",", $this->host->get($this, "tags"))); |
|
27 | - $a_tags = array_map("trim", explode(",", $article["tag_cache"])); |
|
25 | + public function hook_render_article($article) { |
|
26 | + $tags = array_map("trim", explode(",", $this->host->get($this, "tags"))); |
|
27 | + $a_tags = array_map("trim", explode(",", $article["tag_cache"])); |
|
28 | 28 | |
29 | - if (count(array_intersect($tags, $a_tags)) > 0) { |
|
30 | - $article["content"] = "<div class='nswf wrapper'><button onclick=\"nsfwShow(this)\">".__("Not work safe (click to toggle)")."</button> |
|
29 | + if (count(array_intersect($tags, $a_tags)) > 0) { |
|
30 | + $article["content"] = "<div class='nswf wrapper'><button onclick=\"nsfwShow(this)\">".__("Not work safe (click to toggle)")."</button> |
|
31 | 31 | <div class='nswf content' style='display : none'>".$article["content"]."</div></div>"; |
32 | - } |
|
32 | + } |
|
33 | 33 | |
34 | - return $article; |
|
35 | - } |
|
34 | + return $article; |
|
35 | + } |
|
36 | 36 | |
37 | - public function hook_render_article_cdm($article) { |
|
38 | - $tags = array_map("trim", explode(",", $this->host->get($this, "tags"))); |
|
39 | - $a_tags = array_map("trim", explode(",", $article["tag_cache"])); |
|
37 | + public function hook_render_article_cdm($article) { |
|
38 | + $tags = array_map("trim", explode(",", $this->host->get($this, "tags"))); |
|
39 | + $a_tags = array_map("trim", explode(",", $article["tag_cache"])); |
|
40 | 40 | |
41 | - if (count(array_intersect($tags, $a_tags)) > 0) { |
|
42 | - $article["content"] = "<div class='nswf wrapper'><button onclick=\"nsfwShow(this)\">".__("Not work safe (click to toggle)")."</button> |
|
41 | + if (count(array_intersect($tags, $a_tags)) > 0) { |
|
42 | + $article["content"] = "<div class='nswf wrapper'><button onclick=\"nsfwShow(this)\">".__("Not work safe (click to toggle)")."</button> |
|
43 | 43 | <div class='nswf content' style='display : none'>".$article["content"]."</div></div>"; |
44 | - } |
|
44 | + } |
|
45 | 45 | |
46 | - return $article; |
|
47 | - } |
|
46 | + return $article; |
|
47 | + } |
|
48 | 48 | |
49 | - public function hook_prefs_tab($args) { |
|
50 | - if ($args != "prefPrefs") { |
|
51 | - return; |
|
52 | - } |
|
49 | + public function hook_prefs_tab($args) { |
|
50 | + if ($args != "prefPrefs") { |
|
51 | + return; |
|
52 | + } |
|
53 | 53 | |
54 | - print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
54 | + print "<div dojoType=\"dijit.layout.AccordionPane\" |
|
55 | 55 | title=\"<i class='material-icons'>extension</i> ".__("NSFW Plugin")."\">"; |
56 | 56 | |
57 | - print "<br/>"; |
|
57 | + print "<br/>"; |
|
58 | 58 | |
59 | - $tags = $this->host->get($this, "tags"); |
|
59 | + $tags = $this->host->get($this, "tags"); |
|
60 | 60 | |
61 | - print "<form dojoType=\"dijit.form.Form\">"; |
|
61 | + print "<form dojoType=\"dijit.form.Form\">"; |
|
62 | 62 | |
63 | - print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> |
|
63 | + print "<script type=\"dojo/method\" event=\"onSubmit\" args=\"evt\"> |
|
64 | 64 | evt.preventDefault(); |
65 | 65 | if (this.validate()) { |
66 | 66 | new Ajax.Request('backend.php', { |
@@ -73,38 +73,38 @@ discard block |
||
73 | 73 | } |
74 | 74 | </script>"; |
75 | 75 | |
76 | - print_hidden("op", "pluginhandler"); |
|
77 | - print_hidden("method", "save"); |
|
78 | - print_hidden("plugin", "nsfw"); |
|
76 | + print_hidden("op", "pluginhandler"); |
|
77 | + print_hidden("method", "save"); |
|
78 | + print_hidden("plugin", "nsfw"); |
|
79 | 79 | |
80 | - print "<table width=\"100%\" class=\"prefPrefsList\">"; |
|
80 | + print "<table width=\"100%\" class=\"prefPrefsList\">"; |
|
81 | 81 | |
82 | - print "<tr><td width=\"40%\">".__("Tags to consider NSFW (comma-separated)")."</td>"; |
|
83 | - print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"tags\" value=\"$tags\"></td></tr>"; |
|
82 | + print "<tr><td width=\"40%\">".__("Tags to consider NSFW (comma-separated)")."</td>"; |
|
83 | + print "<td class=\"prefValue\"><input dojoType=\"dijit.form.ValidationTextBox\" required=\"1\" name=\"tags\" value=\"$tags\"></td></tr>"; |
|
84 | 84 | |
85 | - print "</table>"; |
|
85 | + print "</table>"; |
|
86 | 86 | |
87 | - print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">". |
|
88 | - __("Save")."</button>"; |
|
87 | + print "<p><button dojoType=\"dijit.form.Button\" type=\"submit\">". |
|
88 | + __("Save")."</button>"; |
|
89 | 89 | |
90 | - print "</form>"; |
|
90 | + print "</form>"; |
|
91 | 91 | |
92 | - print "</div>"; #pane |
|
93 | - } |
|
92 | + print "</div>"; #pane |
|
93 | + } |
|
94 | 94 | |
95 | - public function save() { |
|
96 | - $tags = explode(",", $_POST["tags"]); |
|
97 | - $tags = array_map("trim", $tags); |
|
98 | - $tags = array_map("mb_strtolower", $tags); |
|
99 | - $tags = join(", ", $tags); |
|
95 | + public function save() { |
|
96 | + $tags = explode(",", $_POST["tags"]); |
|
97 | + $tags = array_map("trim", $tags); |
|
98 | + $tags = array_map("mb_strtolower", $tags); |
|
99 | + $tags = join(", ", $tags); |
|
100 | 100 | |
101 | - $this->host->set($this, "tags", $tags); |
|
101 | + $this->host->set($this, "tags", $tags); |
|
102 | 102 | |
103 | - echo __("Configuration saved."); |
|
104 | - } |
|
103 | + echo __("Configuration saved."); |
|
104 | + } |
|
105 | 105 | |
106 | - public function api_version() { |
|
107 | - return 2; |
|
108 | - } |
|
106 | + public function api_version() { |
|
107 | + return 2; |
|
108 | + } |
|
109 | 109 | |
110 | 110 | } |
@@ -1,47 +1,47 @@ |
||
1 | 1 | <?php |
2 | 2 | class Af_Fsckportal extends Plugin { |
3 | 3 | |
4 | - private $host; |
|
4 | + private $host; |
|
5 | 5 | |
6 | - public function about() { |
|
7 | - return array(1.0, |
|
8 | - "Remove feedsportal spamlinks from article content", |
|
9 | - "fox"); |
|
10 | - } |
|
6 | + public function about() { |
|
7 | + return array(1.0, |
|
8 | + "Remove feedsportal spamlinks from article content", |
|
9 | + "fox"); |
|
10 | + } |
|
11 | 11 | |
12 | - public function init($host) { |
|
13 | - $this->host = $host; |
|
12 | + public function init($host) { |
|
13 | + $this->host = $host; |
|
14 | 14 | |
15 | - $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
16 | - } |
|
15 | + $host->add_hook($host::HOOK_ARTICLE_FILTER, $this); |
|
16 | + } |
|
17 | 17 | |
18 | - public function hook_article_filter($article) { |
|
18 | + public function hook_article_filter($article) { |
|
19 | 19 | |
20 | - $doc = new DOMDocument(); |
|
20 | + $doc = new DOMDocument(); |
|
21 | 21 | |
22 | - @$doc->loadHTML('<?xml encoding="UTF-8">'.$article["content"]); |
|
22 | + @$doc->loadHTML('<?xml encoding="UTF-8">'.$article["content"]); |
|
23 | 23 | |
24 | - if ($doc) { |
|
25 | - $xpath = new DOMXPath($doc); |
|
26 | - $entries = $xpath->query('(//img[@src]|//a[@href])'); |
|
24 | + if ($doc) { |
|
25 | + $xpath = new DOMXPath($doc); |
|
26 | + $entries = $xpath->query('(//img[@src]|//a[@href])'); |
|
27 | 27 | |
28 | - foreach ($entries as $entry) { |
|
29 | - if (preg_match("/feedsportal.com/", $entry->getAttribute("src"))) { |
|
30 | - $entry->parentNode->removeChild($entry); |
|
31 | - } else if (preg_match("/feedsportal.com/", $entry->getAttribute("href"))) { |
|
32 | - $entry->parentNode->removeChild($entry); |
|
33 | - } |
|
34 | - } |
|
28 | + foreach ($entries as $entry) { |
|
29 | + if (preg_match("/feedsportal.com/", $entry->getAttribute("src"))) { |
|
30 | + $entry->parentNode->removeChild($entry); |
|
31 | + } else if (preg_match("/feedsportal.com/", $entry->getAttribute("href"))) { |
|
32 | + $entry->parentNode->removeChild($entry); |
|
33 | + } |
|
34 | + } |
|
35 | 35 | |
36 | - $article["content"] = $doc->saveHTML(); |
|
36 | + $article["content"] = $doc->saveHTML(); |
|
37 | 37 | |
38 | - } |
|
38 | + } |
|
39 | 39 | |
40 | - return $article; |
|
41 | - } |
|
40 | + return $article; |
|
41 | + } |
|
42 | 42 | |
43 | - public function api_version() { |
|
44 | - return 2; |
|
45 | - } |
|
43 | + public function api_version() { |
|
44 | + return 2; |
|
45 | + } |
|
46 | 46 | |
47 | 47 | } |