diff --git a/src/Console/ClearAvatarCache.php b/src/Console/ClearAvatarCache.php new file mode 100644 index 0000000000..3d50db511c --- /dev/null +++ b/src/Console/ClearAvatarCache.php @@ -0,0 +1,119 @@ +. + * + */ + +namespace Friendica\Console; + +use Friendica\App\BaseURL; +use Friendica\Contact\Avatar; +use Friendica\Core\L10n; +use Friendica\Model\Contact; +use Friendica\Core\Config\Capability\IManageConfigValues; + +/** + * tool to clear the avatar file cache. + */ +class ClearAvatarCache extends \Asika\SimpleConsole\Console +{ + protected $helpOptions = ['h', 'help', '?']; + + /** + * @var $dba Friendica\Database\Database + */ + private $dba; + + /** + * @var $baseurl Friendica\App\BaseURL + */ + private $baseUrl; + + /** + * @var L10n + */ + private $l10n; + + /** + * @var IManageConfigValues + */ + private $config; + + protected function getHelp() + { + $help = <<dba = $dba; + $this->baseUrl = $baseUrl; + $this->l10n = $l10n; + $this->config = $config; + } + + protected function doExecute(): int + { + if ($this->config->get('system', 'avatar_cache')) { + $this->err($this->l10n->t('The avatar cache needs to be disabled in local.config.php to use this command.')); + return 2; + } + + // Contacts (but not self contacts) with cached avatars. + $condition = ["NOT `self` AND (`photo` != ? OR `thumb` != ? OR `micro` != ?)", '', '', '']; + $total = $this->dba->count('contact', $condition); + $count = 0; + $contacts = $this->dba->select('contact', ['id', 'uri-id', 'url', 'uid', 'photo', 'thumb', 'micro'], $condition); + while ($contact = $this->dba->fetch($contacts)) { + if (Avatar::deleteCache($contact) || $this->isAvatarCache($contact)) { + Contact::update(['photo' => '', 'thumb' => '', 'micro' => ''], ['id' => $contact['id']]); + } + $this->out(++$count . '/' . $total . "\t" . $contact['id'] . "\t" . $contact['url'] . "\t" . $contact['photo']); + } + $this->dba->close($contacts); + return 0; + } + + private function isAvatarCache(array $contact): bool + { + if (!empty($contact['photo']) && strpos($contact['photo'], Avatar::baseUrl()) === 0) { + return true; + } + if (!empty($contact['thumb']) && strpos($contact['thumb'], Avatar::baseUrl()) === 0) { + return true; + } + if (!empty($contact['micro']) && strpos($contact['micro'], Avatar::baseUrl()) === 0) { + return true; + } + return false; + } +} diff --git a/src/Contact/Avatar.php b/src/Contact/Avatar.php index deef2dcc74..12efe19c35 100644 --- a/src/Contact/Avatar.php +++ b/src/Contact/Avatar.php @@ -23,14 +23,11 @@ namespace Friendica\Contact; use Friendica\Core\Logger; use Friendica\DI; -use Friendica\Model\Item; use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Object\Image; use Friendica\Util\DateTimeFormat; use Friendica\Util\HTTPSignature; -use Friendica\Util\Images; -use Friendica\Util\Network; use Friendica\Util\Proxy; /** @@ -97,7 +94,7 @@ class Avatar return $fields; } - $filename = self::getFilename($contact['url'], $avatar); + $filename = self::getFilename($contact['url']); $timestamp = time(); $fields['blurhash'] = $image->getBlurHash(); @@ -125,7 +122,7 @@ class Avatar return $fields; } - $filename = self::getFilename($contact['url'], $contact['avatar']); + $filename = self::getFilename($contact['url']); $timestamp = time(); $fields['photo'] = self::storeAvatarCache($image, $filename, Proxy::PIXEL_SMALL, $timestamp); @@ -135,12 +132,10 @@ class Avatar return $fields; } - private static function getFilename(string $url, string $host): string + private static function getFilename(string $url): string { - $guid = Item::guidFromUri($url, $host); - - return substr($guid, 0, 2) . '/' . substr($guid, 3, 2) . '/' . substr($guid, 5, 3) . '/' . - substr($guid, 9, 2) .'/' . substr($guid, 11, 2) . '/' . substr($guid, 13, 4). '/' . substr($guid, 18) . '-'; + $guid = hash('ripemd128', $url); + return substr($guid, 0, 3) . '/' . substr($guid, 4) . '-'; } private static function storeAvatarCache(Image $image, string $filename, int $size, int $timestamp): string @@ -279,7 +274,7 @@ class Avatar $localFile = self::getCacheFile($avatar); if (!empty($localFile)) { @unlink($localFile); - Logger::debug('Unlink avatar', ['avatar' => $avatar]); + Logger::debug('Unlink avatar', ['avatar' => $avatar, 'local' => $localFile]); } } @@ -316,7 +311,7 @@ class Avatar * * @return string */ - private static function baseUrl(): string + public static function baseUrl(): string { $baseurl = DI::config()->get('system', 'avatar_cache_url'); if (!empty($baseurl)) { diff --git a/src/Core/Console.php b/src/Core/Console.php index ee10558091..b1e89d749f 100644 --- a/src/Core/Console.php +++ b/src/Core/Console.php @@ -47,6 +47,7 @@ Usage: bin/console [--version] [-h|--help|-?] [] [-v] Commands: addon Addon management cache Manage node cache + clearavatarcache Clear the file based avatar cache config Edit site config contact Contact management createdoxygen Generate Doxygen headers @@ -84,6 +85,7 @@ HELP; 'archivecontact' => Friendica\Console\ArchiveContact::class, 'autoinstall' => Friendica\Console\AutomaticInstallation::class, 'cache' => Friendica\Console\Cache::class, + 'clearavatarcache' => Friendica\Console\ClearAvatarCache::class, 'config' => Friendica\Console\Config::class, 'contact' => Friendica\Console\Contact::class, 'createdoxygen' => Friendica\Console\CreateDoxygen::class, diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 5fbee4e4fe..9452211f2f 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2024.06-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-07-11 15:55+0000\n" +"POT-Creation-Date: 2024-07-16 20:38+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -812,6 +812,10 @@ msgstr "" msgid "The contact entries have been archived" msgstr "" +#: src/Console/ClearAvatarCache.php:87 +msgid "The avatar cache needs to be disabled in local.config.php to use this command." +msgstr "" + #: src/Console/GlobalCommunityBlock.php:96 #: src/Module/Moderation/Blocklist/Contact.php:65 #, php-format @@ -8884,15 +8888,15 @@ msgstr "" msgid "Items tagged with: %s" msgstr "" -#: src/Module/Search/Saved.php:59 +#: src/Module/Search/Saved.php:63 msgid "Search term was not saved." msgstr "" -#: src/Module/Search/Saved.php:62 +#: src/Module/Search/Saved.php:66 msgid "Search term already saved." msgstr "" -#: src/Module/Search/Saved.php:68 +#: src/Module/Search/Saved.php:72 msgid "Search term was not removed." msgstr ""