mirror of https://tt-rss.org/git/tt-rss.git
wip: flavor icon caching
This commit is contained in:
parent
1870fe172b
commit
77924a6286
|
@ -749,16 +749,16 @@ class API extends Handler {
|
||||||
"tags" => $tags,
|
"tags" => $tags,
|
||||||
);
|
);
|
||||||
|
|
||||||
$enclosures = Article::_get_enclosures($line['id']);
|
if ($line["num_enclosures"] > 0 && $include_attachments) {
|
||||||
|
$enclosures = Article::_get_enclosures($line['id']);
|
||||||
|
|
||||||
if ($include_attachments)
|
|
||||||
$headline_row['attachments'] = $enclosures;
|
$headline_row['attachments'] = $enclosures;
|
||||||
|
}
|
||||||
|
|
||||||
if ($show_excerpt)
|
if ($show_excerpt)
|
||||||
$headline_row["excerpt"] = $line["content_preview"];
|
$headline_row["excerpt"] = $line["content_preview"];
|
||||||
|
|
||||||
if ($show_content) {
|
if ($show_content) {
|
||||||
|
|
||||||
if ($sanitize_content) {
|
if ($sanitize_content) {
|
||||||
$headline_row["content"] = Sanitizer::sanitize(
|
$headline_row["content"] = Sanitizer::sanitize(
|
||||||
$line["content"],
|
$line["content"],
|
||||||
|
@ -790,7 +790,7 @@ class API extends Handler {
|
||||||
if ($show_content) {
|
if ($show_content) {
|
||||||
$hook_object = ["headline" => &$headline_row];
|
$hook_object = ["headline" => &$headline_row];
|
||||||
|
|
||||||
list ($flavor_image, $flavor_stream, $flavor_kind) = Article::_get_image($enclosures,
|
list ($flavor_image, $flavor_stream, $flavor_kind) = Article::_get_image($line["id"], $enclosures ?? [],
|
||||||
$line["content"], // unsanitized
|
$line["content"], // unsanitized
|
||||||
$line["site_url"] ?? "", // could be null if archived article
|
$line["site_url"] ?? "", // could be null if archived article
|
||||||
$headline_row);
|
$headline_row);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
class Article extends Handler_Protected {
|
class Article extends Handler_Protected {
|
||||||
|
const ARTICLE_KIND_UNKNOWN = -1;
|
||||||
|
const ARTICLE_KIND_IMAGE = 0; // default
|
||||||
const ARTICLE_KIND_ALBUM = 1;
|
const ARTICLE_KIND_ALBUM = 1;
|
||||||
const ARTICLE_KIND_VIDEO = 2;
|
const ARTICLE_KIND_VIDEO = 2;
|
||||||
const ARTICLE_KIND_YOUTUBE = 3;
|
const ARTICLE_KIND_YOUTUBE = 3;
|
||||||
|
@ -543,22 +545,42 @@ class Article extends Handler_Protected {
|
||||||
return $rv;
|
return $rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static function _get_image(array $enclosures, string $content, string $site_url, array $headline) {
|
// TODO: when invoked without article_id (i.e. by rssutils) we can implement additional checks
|
||||||
|
// i.e. check for returned content-type and/or http status for checked images
|
||||||
|
static function _get_image(int $article_id, array $enclosures, string $content, string $site_url, array $headline) {
|
||||||
|
|
||||||
$article_image = "";
|
$article_image = "";
|
||||||
$article_stream = "";
|
$article_stream = "";
|
||||||
$article_kind = 0;
|
$article_kind = Article::ARTICLE_KIND_UNKNOWN;
|
||||||
|
|
||||||
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_ARTICLE_IMAGE,
|
if ($article_id) {
|
||||||
function ($result, $plugin) use (&$article_image, &$article_stream, &$content) {
|
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_ARTICLE_IMAGE,
|
||||||
list ($article_image, $article_stream, $content) = $result;
|
function ($result, $plugin) use (&$article_image, &$article_stream, &$content) {
|
||||||
|
list ($article_image, $article_stream, $content) = $result;
|
||||||
|
|
||||||
// run until first hard match
|
// run until first hard match
|
||||||
return !empty($article_image);
|
return !empty($article_image);
|
||||||
},
|
},
|
||||||
$enclosures, $content, $site_url, $headline);
|
$enclosures, $content, $site_url, $headline);
|
||||||
|
}
|
||||||
|
|
||||||
if (!$article_image && !$article_stream) {
|
if (!$article_image && !$article_stream) {
|
||||||
|
|
||||||
|
if ($article_id) {
|
||||||
|
$user_entry = ORM::for_table('ttrss_user_entries')
|
||||||
|
->where('ref_id', $article_id)
|
||||||
|
->find_one();
|
||||||
|
|
||||||
|
if (!$user_entry)
|
||||||
|
return [Article::ARTICLE_KIND_UNKNOWN, "", ""];
|
||||||
|
|
||||||
|
if ($user_entry->flavor_kind !== null) {
|
||||||
|
return [$user_entry->flavor_image, $user_entry->flavor_stream, $user_entry->flavor_kind];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$user_entry = null;
|
||||||
|
}
|
||||||
|
|
||||||
$tmpdoc = new DOMDocument();
|
$tmpdoc = new DOMDocument();
|
||||||
|
|
||||||
if (@$tmpdoc->loadHTML('<?xml encoding="UTF-8">' . mb_substr($content, 0, 131070))) {
|
if (@$tmpdoc->loadHTML('<?xml encoding="UTF-8">' . mb_substr($content, 0, 131070))) {
|
||||||
|
@ -594,23 +616,35 @@ class Article extends Handler_Protected {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$article_image)
|
if (!$article_image) {
|
||||||
foreach ($enclosures as $enc) {
|
foreach ($enclosures as $enc) {
|
||||||
if (strpos($enc["content_type"], "image/") !== false) {
|
if (strpos($enc["content_type"], "image/") !== false) {
|
||||||
$article_image = $enc["content_url"];
|
$article_image = $enc["content_url"];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ($article_image) {
|
if ($article_image) {
|
||||||
$article_image = rewrite_relative_url($site_url, $article_image);
|
$article_image = rewrite_relative_url($site_url, $article_image);
|
||||||
|
|
||||||
if (!$article_kind && (count($enclosures) > 1 || (isset($elems) && $elems->length > 1)))
|
if ($article_kind == Article::ARTICLE_KIND_UNKNOWN && (count($enclosures) > 1 || (isset($elems) && $elems->length > 1)))
|
||||||
$article_kind = Article::ARTICLE_KIND_ALBUM;
|
$article_kind = Article::ARTICLE_KIND_ALBUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($article_stream)
|
if ($article_stream)
|
||||||
$article_stream = rewrite_relative_url($site_url, $article_stream);
|
$article_stream = rewrite_relative_url($site_url, $article_stream);
|
||||||
|
|
||||||
|
if ($article_image && $article_kind == Article::ARTICLE_KIND_UNKNOWN)
|
||||||
|
$article_kind = Article::ARTICLE_KIND_IMAGE;
|
||||||
|
|
||||||
|
// use original URLs here, only save if invoked for article_id
|
||||||
|
if ($user_entry) {
|
||||||
|
$user_entry->flavor_image = $article_image ?? "";
|
||||||
|
$user_entry->flavor_stream = $article_stream ?? "";
|
||||||
|
$user_entry->flavor_kind = $article_kind;
|
||||||
|
$user_entry->save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$cache = new DiskCache("images");
|
$cache = new DiskCache("images");
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Config {
|
||||||
const T_STRING = 2;
|
const T_STRING = 2;
|
||||||
const T_INT = 3;
|
const T_INT = 3;
|
||||||
|
|
||||||
const SCHEMA_VERSION = 145;
|
const SCHEMA_VERSION = 146;
|
||||||
|
|
||||||
/* override defaults, defined below in _DEFAULTS[], prefixing with _ENVVAR_PREFIX:
|
/* override defaults, defined below in _DEFAULTS[], prefixing with _ENVVAR_PREFIX:
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,11 @@ class Db
|
||||||
ORM::configure('username', Config::get(Config::DB_USER));
|
ORM::configure('username', Config::get(Config::DB_USER));
|
||||||
ORM::configure('password', Config::get(Config::DB_PASS));
|
ORM::configure('password', Config::get(Config::DB_PASS));
|
||||||
ORM::configure('return_result_sets', true);
|
ORM::configure('return_result_sets', true);
|
||||||
|
|
||||||
|
ORM::configure('id_column_overrides', array(
|
||||||
|
'ttrss_user_entries' => 'int_id'
|
||||||
|
));
|
||||||
|
|
||||||
if (Config::get(Config::DB_TYPE) == "mysql" && Config::get(Config::MYSQL_CHARSET)) {
|
if (Config::get(Config::DB_TYPE) == "mysql" && Config::get(Config::MYSQL_CHARSET)) {
|
||||||
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . Config::get(Config::MYSQL_CHARSET)));
|
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . Config::get(Config::MYSQL_CHARSET)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,6 +228,17 @@ class Feeds extends Handler_Protected {
|
||||||
|
|
||||||
$this->_mark_timestamp(" labels");
|
$this->_mark_timestamp(" labels");
|
||||||
|
|
||||||
|
if ($line["tag_cache"])
|
||||||
|
$tags = explode(",", $line["tag_cache"]);
|
||||||
|
else
|
||||||
|
$tags = [];
|
||||||
|
|
||||||
|
$line["tags"] = $tags;
|
||||||
|
|
||||||
|
//$line["tags"] = Article::_get_tags($line["id"], false, $line["tag_cache"]);
|
||||||
|
|
||||||
|
$this->_mark_timestamp(" tags");
|
||||||
|
|
||||||
$line["feed_title"] = $line["feed_title"] ?? "";
|
$line["feed_title"] = $line["feed_title"] ?? "";
|
||||||
|
|
||||||
$line["buttons_left"] = "";
|
$line["buttons_left"] = "";
|
||||||
|
@ -282,17 +293,6 @@ class Feeds extends Handler_Protected {
|
||||||
|
|
||||||
$this->_mark_timestamp(" local-datetime");
|
$this->_mark_timestamp(" local-datetime");
|
||||||
|
|
||||||
if ($line["tag_cache"])
|
|
||||||
$tags = explode(",", $line["tag_cache"]);
|
|
||||||
else
|
|
||||||
$tags = [];
|
|
||||||
|
|
||||||
$line["tags"] = $tags;
|
|
||||||
|
|
||||||
//$line["tags"] = Article::_get_tags($line["id"], false, $line["tag_cache"]);
|
|
||||||
|
|
||||||
$this->_mark_timestamp(" tags");
|
|
||||||
|
|
||||||
$line['has_icon'] = self::_has_icon($feed_id);
|
$line['has_icon'] = self::_has_icon($feed_id);
|
||||||
|
|
||||||
//setting feed headline background color, needs to change text color based on dark/light
|
//setting feed headline background color, needs to change text color based on dark/light
|
||||||
|
|
|
@ -152,7 +152,7 @@ class Handler_Public extends Handler {
|
||||||
$tpl->setVariable('ARTICLE_ENCLOSURE_LENGTH', "", true);
|
$tpl->setVariable('ARTICLE_ENCLOSURE_LENGTH', "", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
list ($og_image, $og_stream) = Article::_get_image($enclosures, $line['content'], $feed_site_url, $line);
|
list ($og_image, $og_stream) = Article::_get_image($line["id"], $enclosures, $line['content'], $feed_site_url, $line);
|
||||||
|
|
||||||
$tpl->setVariable('ARTICLE_OG_IMAGE', $og_image, true);
|
$tpl->setVariable('ARTICLE_OG_IMAGE', $og_image, true);
|
||||||
|
|
||||||
|
|
|
@ -1101,10 +1101,27 @@ class RSSUtils {
|
||||||
|
|
||||||
$sth->execute($params);
|
$sth->execute($params);
|
||||||
|
|
||||||
|
list ($entry_flavor_image, $entry_flavor_stream, $entry_flavor_kind) = Article::_get_image(0, $enclosures,
|
||||||
|
$entry_content, $feed_obj->site_url, $article);
|
||||||
|
|
||||||
|
Debug::log("article flavor image: $entry_flavor_image stream: $entry_flavor_stream kind: $entry_flavor_kind");
|
||||||
|
|
||||||
// update aux data
|
// update aux data
|
||||||
$sth = $pdo->prepare("UPDATE ttrss_user_entries
|
$sth = $pdo->prepare("UPDATE
|
||||||
SET score = ? WHERE ref_id = ?");
|
ttrss_user_entries
|
||||||
$sth->execute([$score, $ref_id]);
|
SET
|
||||||
|
score = :score,
|
||||||
|
flavor_image = :flavor_image,
|
||||||
|
flavor_stream = :flavor_stream,
|
||||||
|
flavor_kind = :flavor_kind
|
||||||
|
WHERE ref_id = :ref_id");
|
||||||
|
|
||||||
|
$sth->execute([
|
||||||
|
":score" => $score,
|
||||||
|
":flavor_image" => $entry_flavor_image,
|
||||||
|
":flavor_stream" => $entry_flavor_stream,
|
||||||
|
":flavor_kind" => $entry_flavor_kind,
|
||||||
|
":ref_id" => $ref_id]);
|
||||||
|
|
||||||
if ($feed_obj->mark_unread_on_update &&
|
if ($feed_obj->mark_unread_on_update &&
|
||||||
!$entry_force_catchup &&
|
!$entry_force_catchup &&
|
||||||
|
|
|
@ -142,7 +142,7 @@ class Share extends Plugin {
|
||||||
$line);
|
$line);
|
||||||
|
|
||||||
$enclosures = Article::_get_enclosures($line["id"]);
|
$enclosures = Article::_get_enclosures($line["id"]);
|
||||||
list ($og_image, $og_stream) = Article::_get_image($enclosures, $line['content'], $line["site_url"], $line);
|
list ($og_image, $og_stream) = Article::_get_image($line["id"], $enclosures, $line["content"], $line["site_url"], $line);
|
||||||
|
|
||||||
$content_decoded = html_entity_decode($line["title"], ENT_NOQUOTES | ENT_HTML401);
|
$content_decoded = html_entity_decode($line["title"], ENT_NOQUOTES | ENT_HTML401);
|
||||||
$parsed_updated = TimeHelper::make_local_datetime($line["updated"], true, $owner_uid, true);
|
$parsed_updated = TimeHelper::make_local_datetime($line["updated"], true, $owner_uid, true);
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
alter table ttrss_user_entries add column flavor_image text;
|
||||||
|
alter table ttrss_user_entries add column flavor_stream text;
|
||||||
|
alter table ttrss_user_entries add column flavor_kind int;
|
||||||
|
|
||||||
|
alter table ttrss_user_entries alter column flavor_image set default null;
|
||||||
|
alter table ttrss_user_entries alter column flavor_stream set default null;
|
||||||
|
alter table ttrss_user_entries alter column flavor_kind set default null;
|
|
@ -188,6 +188,9 @@ create table ttrss_user_entries (
|
||||||
note longtext,
|
note longtext,
|
||||||
last_marked datetime,
|
last_marked datetime,
|
||||||
last_published datetime,
|
last_published datetime,
|
||||||
|
flavor_image text default null,
|
||||||
|
flavor_stream text default null,
|
||||||
|
flavor_kind int default null,
|
||||||
unread bool not null default 1,
|
unread bool not null default 1,
|
||||||
foreign key (ref_id) references ttrss_entries(id) ON DELETE CASCADE,
|
foreign key (ref_id) references ttrss_entries(id) ON DELETE CASCADE,
|
||||||
foreign key (feed_id) references ttrss_feeds(id) ON DELETE CASCADE,
|
foreign key (feed_id) references ttrss_feeds(id) ON DELETE CASCADE,
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
alter table ttrss_user_entries add column flavor_image text;
|
||||||
|
alter table ttrss_user_entries add column flavor_stream text;
|
||||||
|
alter table ttrss_user_entries add column flavor_kind int;
|
||||||
|
|
||||||
|
alter table ttrss_user_entries alter column flavor_image set default null;
|
||||||
|
alter table ttrss_user_entries alter column flavor_stream set default null;
|
||||||
|
alter table ttrss_user_entries alter column flavor_kind set default null;
|
|
@ -185,6 +185,9 @@ create table ttrss_user_entries (
|
||||||
last_marked timestamp,
|
last_marked timestamp,
|
||||||
last_published timestamp,
|
last_published timestamp,
|
||||||
note text,
|
note text,
|
||||||
|
flavor_image text default null,
|
||||||
|
flavor_stream text default null,
|
||||||
|
flavor_kind int default null,
|
||||||
unread boolean not null default true);
|
unread boolean not null default true);
|
||||||
|
|
||||||
-- create index ttrss_user_entries_feed_id_index on ttrss_user_entries(feed_id);
|
-- create index ttrss_user_entries_feed_id_index on ttrss_user_entries(feed_id);
|
||||||
|
|
Loading…
Reference in New Issue