|
|
@ -34,9 +34,9 @@ class RSSUtils {
|
|
|
|
$pdo = Db::pdo();
|
|
|
|
$pdo = Db::pdo();
|
|
|
|
$sth = $pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ?");
|
|
|
|
$sth = $pdo->prepare("SELECT id FROM ttrss_feeds WHERE id = ?");
|
|
|
|
|
|
|
|
|
|
|
|
// check icon files once every CACHE_MAX_DAYS days
|
|
|
|
// check icon files once every Config::get(Config::CACHE_MAX_DAYS) days
|
|
|
|
$icon_files = array_filter(glob(ICONS_DIR . "/*.ico"),
|
|
|
|
$icon_files = array_filter(glob(Config::get(Config::ICONS_DIR) . "/*.ico"),
|
|
|
|
function($f) { return filemtime($f) < time() - 86400*CACHE_MAX_DAYS; });
|
|
|
|
function($f) { return filemtime($f) < time() - 86400 * Config::get(Config::CACHE_MAX_DAYS); });
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($icon_files as $icon) {
|
|
|
|
foreach ($icon_files as $icon) {
|
|
|
|
$feed_id = basename($icon, ".ico");
|
|
|
|
$feed_id = basename($icon, ".ico");
|
|
|
@ -52,20 +52,22 @@ class RSSUtils {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static function update_daemon_common($limit = DAEMON_FEED_LIMIT, $options = []) {
|
|
|
|
static function update_daemon_common($limit = null, $options = []) {
|
|
|
|
$schema_version = get_schema_version();
|
|
|
|
$schema_version = get_schema_version();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!$limit) $limit = Config::get(Config::DAEMON_FEED_LIMIT);
|
|
|
|
|
|
|
|
|
|
|
|
if ($schema_version != SCHEMA_VERSION) {
|
|
|
|
if ($schema_version != SCHEMA_VERSION) {
|
|
|
|
die("Schema version is wrong, please upgrade the database.\n");
|
|
|
|
die("Schema version is wrong, please upgrade the database.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$pdo = Db::pdo();
|
|
|
|
$pdo = Db::pdo();
|
|
|
|
|
|
|
|
|
|
|
|
if (!Config::get(Config::SINGLE_USER_MODE) && DAEMON_UPDATE_LOGIN_LIMIT > 0) {
|
|
|
|
if (!Config::get(Config::SINGLE_USER_MODE) && Config::get(Config::DAEMON_UPDATE_LOGIN_LIMIT) > 0) {
|
|
|
|
if (Config::get(Config::DB_TYPE) == "pgsql") {
|
|
|
|
if (Config::get(Config::DB_TYPE) == "pgsql") {
|
|
|
|
$login_thresh_qpart = "AND ttrss_users.last_login >= NOW() - INTERVAL '".DAEMON_UPDATE_LOGIN_LIMIT." days'";
|
|
|
|
$login_thresh_qpart = "AND ttrss_users.last_login >= NOW() - INTERVAL '".Config::get(Config::DAEMON_UPDATE_LOGIN_LIMIT)." days'";
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
$login_thresh_qpart = "AND ttrss_users.last_login >= DATE_SUB(NOW(), INTERVAL ".DAEMON_UPDATE_LOGIN_LIMIT." DAY)";
|
|
|
|
$login_thresh_qpart = "AND ttrss_users.last_login >= DATE_SUB(NOW(), INTERVAL ".Config::get(Config::DAEMON_UPDATE_LOGIN_LIMIT)." DAY)";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
$login_thresh_qpart = "";
|
|
|
|
$login_thresh_qpart = "";
|
|
|
@ -288,7 +290,7 @@ class RSSUtils {
|
|
|
|
if (!$basic_info) {
|
|
|
|
if (!$basic_info) {
|
|
|
|
$feed_data = UrlHelper::fetch($fetch_url, false,
|
|
|
|
$feed_data = UrlHelper::fetch($fetch_url, false,
|
|
|
|
$auth_login, $auth_pass, false,
|
|
|
|
$auth_login, $auth_pass, false,
|
|
|
|
FEED_FETCH_TIMEOUT,
|
|
|
|
Config::get(Config::FEED_FETCH_TIMEOUT),
|
|
|
|
0);
|
|
|
|
0);
|
|
|
|
|
|
|
|
|
|
|
|
$feed_data = trim($feed_data);
|
|
|
|
$feed_data = trim($feed_data);
|
|
|
@ -455,7 +457,7 @@ class RSSUtils {
|
|
|
|
Debug::log("not using CURL due to open_basedir restrictions", Debug::$LOG_VERBOSE);
|
|
|
|
Debug::log("not using CURL due to open_basedir restrictions", Debug::$LOG_VERBOSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (time() - strtotime($last_unconditional) > MAX_CONDITIONAL_INTERVAL) {
|
|
|
|
if (time() - strtotime($last_unconditional) > Config::get(Config::MAX_CONDITIONAL_INTERVAL)) {
|
|
|
|
Debug::log("maximum allowed interval for conditional requests exceeded, forcing refetch", Debug::$LOG_VERBOSE);
|
|
|
|
Debug::log("maximum allowed interval for conditional requests exceeded, forcing refetch", Debug::$LOG_VERBOSE);
|
|
|
|
|
|
|
|
|
|
|
|
$force_refetch = true;
|
|
|
|
$force_refetch = true;
|
|
|
@ -469,7 +471,7 @@ class RSSUtils {
|
|
|
|
"url" => $fetch_url,
|
|
|
|
"url" => $fetch_url,
|
|
|
|
"login" => $auth_login,
|
|
|
|
"login" => $auth_login,
|
|
|
|
"pass" => $auth_pass,
|
|
|
|
"pass" => $auth_pass,
|
|
|
|
"timeout" => $no_cache ? FEED_FETCH_NO_CACHE_TIMEOUT : FEED_FETCH_TIMEOUT,
|
|
|
|
"timeout" => $no_cache ? Config::get(Config::FEED_FETCH_NO_CACHE_TIMEOUT) : Config::get(Config::FEED_FETCH_TIMEOUT),
|
|
|
|
"last_modified" => $force_refetch ? "" : $stored_last_modified
|
|
|
|
"last_modified" => $force_refetch ? "" : $stored_last_modified
|
|
|
|
]);
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
|
@ -591,7 +593,7 @@ class RSSUtils {
|
|
|
|
/* terrible hack: if we crash on floicon shit here, we won't check
|
|
|
|
/* terrible hack: if we crash on floicon shit here, we won't check
|
|
|
|
* the icon avgcolor again (unless the icon got updated) */
|
|
|
|
* the icon avgcolor again (unless the icon got updated) */
|
|
|
|
|
|
|
|
|
|
|
|
$favicon_file = ICONS_DIR . "/$feed.ico";
|
|
|
|
$favicon_file = Config::get(Config::ICONS_DIR) . "/$feed.ico";
|
|
|
|
$favicon_modified = file_exists($favicon_file) ? filemtime($favicon_file) : -1;
|
|
|
|
$favicon_modified = file_exists($favicon_file) ? filemtime($favicon_file) : -1;
|
|
|
|
|
|
|
|
|
|
|
|
Debug::log("checking favicon for feed $feed...", Debug::$LOG_VERBOSE);
|
|
|
|
Debug::log("checking favicon for feed $feed...", Debug::$LOG_VERBOSE);
|
|
|
@ -755,7 +757,7 @@ class RSSUtils {
|
|
|
|
$e->type, $e->length, $e->title, $e->width, $e->height);
|
|
|
|
$e->type, $e->length, $e->title, $e->width, $e->height);
|
|
|
|
|
|
|
|
|
|
|
|
// Yet another episode of "mysql utf8_general_ci is gimped"
|
|
|
|
// Yet another episode of "mysql utf8_general_ci is gimped"
|
|
|
|
if (Config::get(Config::DB_TYPE) == "mysql" && MYSQL_CHARSET != "UTF8MB4") {
|
|
|
|
if (Config::get(Config::DB_TYPE) == "mysql" && Config::get(Config::MYSQL_CHARSET) != "UTF8MB4") {
|
|
|
|
for ($i = 0; $i < count($e_item); $i++) {
|
|
|
|
for ($i = 0; $i < count($e_item); $i++) {
|
|
|
|
if (is_string($e_item[$i])) {
|
|
|
|
if (is_string($e_item[$i])) {
|
|
|
|
$e_item[$i] = self::strip_utf8mb4($e_item[$i]);
|
|
|
|
$e_item[$i] = self::strip_utf8mb4($e_item[$i]);
|
|
|
@ -833,7 +835,7 @@ class RSSUtils {
|
|
|
|
Debug::log("plugin data: $entry_plugin_data", Debug::$LOG_VERBOSE);
|
|
|
|
Debug::log("plugin data: $entry_plugin_data", Debug::$LOG_VERBOSE);
|
|
|
|
|
|
|
|
|
|
|
|
// Workaround: 4-byte unicode requires utf8mb4 in MySQL. See https://tt-rss.org/forum/viewtopic.php?f=1&t=3377&p=20077#p20077
|
|
|
|
// Workaround: 4-byte unicode requires utf8mb4 in MySQL. See https://tt-rss.org/forum/viewtopic.php?f=1&t=3377&p=20077#p20077
|
|
|
|
if (Config::get(Config::DB_TYPE) == "mysql" && MYSQL_CHARSET != "UTF8MB4") {
|
|
|
|
if (Config::get(Config::DB_TYPE) == "mysql" && Config::get(Config::MYSQL_CHARSET) != "UTF8MB4") {
|
|
|
|
foreach ($article as $k => $v) {
|
|
|
|
foreach ($article as $k => $v) {
|
|
|
|
// i guess we'll have to take the risk of 4byte unicode labels & tags here
|
|
|
|
// i guess we'll have to take the risk of 4byte unicode labels & tags here
|
|
|
|
if (is_string($article[$k])) {
|
|
|
|
if (is_string($article[$k])) {
|
|
|
@ -1298,7 +1300,7 @@ class RSSUtils {
|
|
|
|
|
|
|
|
|
|
|
|
$file_content = UrlHelper::fetch(array("url" => $src,
|
|
|
|
$file_content = UrlHelper::fetch(array("url" => $src,
|
|
|
|
"http_referrer" => $src,
|
|
|
|
"http_referrer" => $src,
|
|
|
|
"max_size" => MAX_CACHE_FILE_SIZE));
|
|
|
|
"max_size" => Config::get(Config::MAX_CACHE_FILE_SIZE)));
|
|
|
|
|
|
|
|
|
|
|
|
if ($file_content) {
|
|
|
|
if ($file_content) {
|
|
|
|
$cache->put($local_filename, $file_content);
|
|
|
|
$cache->put($local_filename, $file_content);
|
|
|
@ -1328,7 +1330,7 @@ class RSSUtils {
|
|
|
|
|
|
|
|
|
|
|
|
$file_content = UrlHelper::fetch(array("url" => $url,
|
|
|
|
$file_content = UrlHelper::fetch(array("url" => $url,
|
|
|
|
"http_referrer" => $url,
|
|
|
|
"http_referrer" => $url,
|
|
|
|
"max_size" => MAX_CACHE_FILE_SIZE));
|
|
|
|
"max_size" => Config::get(Config::MAX_CACHE_FILE_SIZE)));
|
|
|
|
|
|
|
|
|
|
|
|
if ($file_content) {
|
|
|
|
if ($file_content) {
|
|
|
|
$cache->put($local_filename, $file_content);
|
|
|
|
$cache->put($local_filename, $file_content);
|
|
|
@ -1643,7 +1645,7 @@ class RSSUtils {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static function check_feed_favicon($site_url, $feed) {
|
|
|
|
static function check_feed_favicon($site_url, $feed) {
|
|
|
|
$icon_file = ICONS_DIR . "/$feed.ico";
|
|
|
|
$icon_file = Config::get(Config::ICONS_DIR) . "/$feed.ico";
|
|
|
|
|
|
|
|
|
|
|
|
$favicon_url = self::get_favicon_url($site_url);
|
|
|
|
$favicon_url = self::get_favicon_url($site_url);
|
|
|
|
if (!$favicon_url) {
|
|
|
|
if (!$favicon_url) {
|
|
|
@ -1654,7 +1656,7 @@ class RSSUtils {
|
|
|
|
// Limiting to "image" type misses those served with text/plain
|
|
|
|
// Limiting to "image" type misses those served with text/plain
|
|
|
|
$contents = UrlHelper::fetch([
|
|
|
|
$contents = UrlHelper::fetch([
|
|
|
|
'url' => $favicon_url,
|
|
|
|
'url' => $favicon_url,
|
|
|
|
'max_size' => MAX_FAVICON_FILE_SIZE,
|
|
|
|
'max_size' => Config::get(Config::MAX_FAVICON_FILE_SIZE),
|
|
|
|
//'type' => 'image',
|
|
|
|
//'type' => 'image',
|
|
|
|
]);
|
|
|
|
]);
|
|
|
|
if (!$contents) {
|
|
|
|
if (!$contents) {
|
|
|
|