wip: flavor icon caching

This commit is contained in:
Andrew Dolgov 2021-03-15 22:29:03 +03:00
parent 1870fe172b
commit 77924a6286
12 changed files with 108 additions and 32 deletions

View File

@ -749,16 +749,16 @@ class API extends Handler {
"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;
}
if ($show_excerpt)
$headline_row["excerpt"] = $line["content_preview"];
if ($show_content) {
if ($sanitize_content) {
$headline_row["content"] = Sanitizer::sanitize(
$line["content"],
@ -790,7 +790,7 @@ class API extends Handler {
if ($show_content) {
$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["site_url"] ?? "", // could be null if archived article
$headline_row);

View File

@ -1,5 +1,7 @@
<?php
class Article extends Handler_Protected {
const ARTICLE_KIND_UNKNOWN = -1;
const ARTICLE_KIND_IMAGE = 0; // default
const ARTICLE_KIND_ALBUM = 1;
const ARTICLE_KIND_VIDEO = 2;
const ARTICLE_KIND_YOUTUBE = 3;
@ -543,22 +545,42 @@ class Article extends Handler_Protected {
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_stream = "";
$article_kind = 0;
$article_kind = Article::ARTICLE_KIND_UNKNOWN;
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_ARTICLE_IMAGE,
function ($result, $plugin) use (&$article_image, &$article_stream, &$content) {
list ($article_image, $article_stream, $content) = $result;
if ($article_id) {
PluginHost::getInstance()->chain_hooks_callback(PluginHost::HOOK_ARTICLE_IMAGE,
function ($result, $plugin) use (&$article_image, &$article_stream, &$content) {
list ($article_image, $article_stream, $content) = $result;
// run until first hard match
return !empty($article_image);
},
$enclosures, $content, $site_url, $headline);
// run until first hard match
return !empty($article_image);
},
$enclosures, $content, $site_url, $headline);
}
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();
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) {
if (strpos($enc["content_type"], "image/") !== false) {
$article_image = $enc["content_url"];
break;
}
}
}
if ($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;
}
if ($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");

View File

@ -6,7 +6,7 @@ class Config {
const T_STRING = 2;
const T_INT = 3;
const SCHEMA_VERSION = 145;
const SCHEMA_VERSION = 146;
/* override defaults, defined below in _DEFAULTS[], prefixing with _ENVVAR_PREFIX:

View File

@ -14,6 +14,11 @@ class Db
ORM::configure('username', Config::get(Config::DB_USER));
ORM::configure('password', Config::get(Config::DB_PASS));
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)) {
ORM::configure('driver_options', array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . Config::get(Config::MYSQL_CHARSET)));
}

View File

@ -228,6 +228,17 @@ class Feeds extends Handler_Protected {
$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["buttons_left"] = "";
@ -282,17 +293,6 @@ class Feeds extends Handler_Protected {
$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);
//setting feed headline background color, needs to change text color based on dark/light

View File

@ -152,7 +152,7 @@ class Handler_Public extends Handler {
$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);

View File

@ -1101,10 +1101,27 @@ class RSSUtils {
$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
$sth = $pdo->prepare("UPDATE ttrss_user_entries
SET score = ? WHERE ref_id = ?");
$sth->execute([$score, $ref_id]);
$sth = $pdo->prepare("UPDATE
ttrss_user_entries
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 &&
!$entry_force_catchup &&

View File

@ -142,7 +142,7 @@ class Share extends Plugin {
$line);
$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);
$parsed_updated = TimeHelper::make_local_datetime($line["updated"], true, $owner_uid, true);

View File

@ -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;

View File

@ -188,6 +188,9 @@ create table ttrss_user_entries (
note longtext,
last_marked 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,
foreign key (ref_id) references ttrss_entries(id) ON DELETE CASCADE,
foreign key (feed_id) references ttrss_feeds(id) ON DELETE CASCADE,

View File

@ -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;

View File

@ -185,6 +185,9 @@ create table ttrss_user_entries (
last_marked timestamp,
last_published timestamp,
note text,
flavor_image text default null,
flavor_stream text default null,
flavor_kind int default null,
unread boolean not null default true);
-- create index ttrss_user_entries_feed_id_index on ttrss_user_entries(feed_id);