diff --git a/.env.dist b/.env.dist index f741802..1f4ddbb 100644 --- a/.env.dist +++ b/.env.dist @@ -43,10 +43,6 @@ MERCURE_PUBLIC_URL=https://${SERVER_NAME}/.well-known/mercure # The secret used to sign the JWTs MERCURE_JWT_SECRET="!NotSoSecretMercureHubJWTSecretKey!" ###< symfony/mercure-bundle ### -###> redis ### -REDIS_HOST=localhost -REDIS_PASSWORD=r_password -###< redis ### ###> LNBits ### LNBITS_URL=https://legend.lnbits.com LNBITS_API_KEY= diff --git a/Dockerfile b/Dockerfile index 107ba02..83d7da2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,6 @@ RUN set -eux; \ zip \ gmp \ gd \ - redis \ ; # https://getcomposer.org/doc/03-cli.md#composer-allow-superuser diff --git a/composer.json b/composer.json index e1158a2..f91d346 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,6 @@ "ext-ctype": "*", "ext-iconv": "*", "ext-openssl": "*", - "ext-redis": "*", "doctrine/dbal": "^4.2", "doctrine/doctrine-bundle": "^2.13", "doctrine/doctrine-migrations-bundle": "^3.3", diff --git a/config/packages/cache.yaml b/config/packages/cache.yaml index 86c2e75..b7e41f0 100644 --- a/config/packages/cache.yaml +++ b/config/packages/cache.yaml @@ -3,14 +3,9 @@ framework: # Unique name of your app: used to compute stable namespaces for cache keys. prefix_seed: newsroom/app - # The "app" cache stores to the filesystem by default. - # The data in this cache should persist between deploys. - # Other options include: - - # Redis - app: cache.adapter.redis - default_redis_provider: Redis - + # Use filesystem cache + app: cache.adapter.filesystem + # Namespaced pools use the above "app" backend by default pools: #my.dedicated.cache: null diff --git a/config/services.yaml b/config/services.yaml index 8d01c84..e4217eb 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -27,17 +27,3 @@ services: Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler: arguments: - '%env(DATABASE_URL)%' - - # Redis (still used for cache, just not sessions) - Symfony\Component\Cache\Adapter\RedisAdapter: - arguments: - - '@Redis' - - Redis: - # you can also use \RedisArray, \RedisCluster, \Relay\Relay or \Predis\Client classes - class: Redis - calls: - - connect: - - '%env(REDIS_HOST)%' - - auth: - - '%env(REDIS_PASSWORD)%' diff --git a/docker/cron/Dockerfile b/docker/cron/Dockerfile index 59c3a5e..5750236 100644 --- a/docker/cron/Dockerfile +++ b/docker/cron/Dockerfile @@ -8,12 +8,6 @@ RUN apt-get update && apt-get install -y \ libpq-dev \ libonig-dev -# Install Redis PHP extension -RUN pecl install redis \ - && docker-php-ext-enable redis - -RUN docker-php-ext-install pdo pdo_pgsql - # Set working directory WORKDIR /var/www/html diff --git a/src/Controller/ArticleController.php b/src/Controller/ArticleController.php index 0a8ca3f..96eba22 100644 --- a/src/Controller/ArticleController.php +++ b/src/Controller/ArticleController.php @@ -6,7 +6,7 @@ use App\Entity\Article; use App\Enum\KindsEnum; use App\Form\EditorType; use App\Service\NostrClient; -use App\Service\RedisCacheService; +use App\Service\CacheService; use App\Util\CommonMark\Converter; use Doctrine\ORM\EntityManagerInterface; use League\CommonMark\Exception\CommonMarkException; @@ -62,7 +62,7 @@ class ArticleController extends AbstractController public function article( $slug, EntityManagerInterface $entityManager, - RedisCacheService $redisCacheService, + CacheService $cacheService, CacheItemPoolInterface $articlesCache, Converter $converter ): Response @@ -101,7 +101,7 @@ class ArticleController extends AbstractController $key = new Key(); $npub = $key->convertPublicKeyToBech32($article->getPubkey()); - $author = $redisCacheService->getMetadata($npub); + $author = $cacheService->getMetadata($npub); return $this->render('pages/article.html.twig', [ @@ -120,7 +120,7 @@ class ArticleController extends AbstractController public function articlePreviewEvent( Request $request, NostrClient $nostrClient, - RedisCacheService $redisCacheService, + CacheService $cacheService, CacheItemPoolInterface $articlesCache ): Response { $data = $request->getContent(); @@ -136,7 +136,7 @@ class ArticleController extends AbstractController $hint = json_decode($descriptor->decoded); $key = new Key(); $npub = $key->convertPublicKeyToBech32($hint->pubkey); - $metadata = $redisCacheService->getMetadata($npub); + $metadata = $cacheService->getMetadata($npub); $metadata->npub = $npub; $metadata->pubkey = $hint->pubkey; $metadata->type = 'nprofile'; diff --git a/src/Controller/AuthorController.php b/src/Controller/AuthorController.php index 6ab865d..4509dd6 100644 --- a/src/Controller/AuthorController.php +++ b/src/Controller/AuthorController.php @@ -6,7 +6,7 @@ namespace App\Controller; use App\Repository\ArticleRepository; use App\Service\NostrClient; -use App\Service\RedisCacheService; +use App\Service\CacheService; use Exception; use swentel\nostr\Key\Key; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -19,12 +19,12 @@ class AuthorController extends AbstractController * @throws Exception */ #[Route('/p/{npub}', name: 'author-profile', requirements: ['npub' => '^npub1.*'])] - public function index($npub, NostrClient $nostrClient, RedisCacheService $redisCacheService, ArticleRepository $articleRepository): Response + public function index($npub, NostrClient $nostrClient, CacheService $cacheService, ArticleRepository $articleRepository): Response { $keys = new Key(); $pubkey = $keys->convertToHex($npub); - $author = $redisCacheService->getMetadata($npub); + $author = $cacheService->getMetadata($npub); // Retrieve long-form content for the author try { $list = $nostrClient->getLongFormContentForPubkey($npub); diff --git a/src/Controller/EventController.php b/src/Controller/EventController.php index 495c212..3d9ab3b 100644 --- a/src/Controller/EventController.php +++ b/src/Controller/EventController.php @@ -6,7 +6,7 @@ namespace App\Controller; use App\Service\NostrClient; use App\Service\NostrLinkParser; -use App\Service\RedisCacheService; +use App\Service\CacheService; use Exception; use nostriphant\NIP19\Bech32; use nostriphant\NIP19\Data; @@ -23,7 +23,7 @@ class EventController extends AbstractController * @throws Exception */ #[Route('/e/{nevent}', name: 'nevent', requirements: ['nevent' => '^nevent1.*'])] - public function index($nevent, NostrClient $nostrClient, RedisCacheService $redisCacheService, NostrLinkParser $nostrLinkParser, LoggerInterface $logger): Response + public function index($nevent, NostrClient $nostrClient, CacheService $cacheService, NostrLinkParser $nostrLinkParser, LoggerInterface $logger): Response { $logger->info('Accessing event page', ['nevent' => $nevent]); @@ -89,7 +89,7 @@ class EventController extends AbstractController if (isset($event->pubkey)) { $key = new Key(); $npub = $key->convertPublicKeyToBech32($event->pubkey); - $authorMetadata = $redisCacheService->getMetadata($npub); + $authorMetadata = $cacheService->getMetadata($npub); } // Render template with the event data and extracted Nostr links diff --git a/src/Security/UserDTOProvider.php b/src/Security/UserDTOProvider.php index 5bf42d0..55d3b6f 100644 --- a/src/Security/UserDTOProvider.php +++ b/src/Security/UserDTOProvider.php @@ -3,7 +3,7 @@ namespace App\Security; use App\Entity\User; -use App\Service\RedisCacheService; +use App\Service\CacheService; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; use Symfony\Component\Security\Core\User\UserInterface; @@ -19,7 +19,7 @@ readonly class UserDTOProvider implements UserProviderInterface { public function __construct( private EntityManagerInterface $entityManager, - private RedisCacheService $redisCacheService, + private CacheService $cacheService, private LoggerInterface $logger ) { @@ -40,7 +40,7 @@ readonly class UserDTOProvider implements UserProviderInterface $this->logger->info('Refresh user.', ['user' => $user->getUserIdentifier()]); $freshUser = $this->entityManager->getRepository(User::class) ->findOneBy(['npub' => $user->getUserIdentifier()]); - $metadata = $this->redisCacheService->getMetadata($user->getUserIdentifier()); + $metadata = $this->cacheService->getMetadata($user->getUserIdentifier()); $freshUser->setMetadata($metadata); return $freshUser; } @@ -75,7 +75,7 @@ readonly class UserDTOProvider implements UserProviderInterface $this->entityManager->flush(); } - $metadata = $this->redisCacheService->getMetadata($identifier); + $metadata = $this->cacheService->getMetadata($identifier); $user->setMetadata($metadata); $this->logger->debug('User metadata set.', ['metadata' => json_encode($user->getMetadata())]); diff --git a/src/Service/RedisCacheService.php b/src/Service/RedisCacheService.php deleted file mode 100644 index 0f280be..0000000 --- a/src/Service/RedisCacheService.php +++ /dev/null @@ -1,70 +0,0 @@ -redisCache->get($cacheKey, function (ItemInterface $item) use ($npub) { - $item->expiresAfter(3600); // 1 hour, adjust as needed - try { - $meta = $this->nostrClient->getNpubMetadata($npub); - } catch (\Exception $e) { - $this->logger->error('Error getting user data.', ['exception' => $e]); - $meta = new \stdClass(); - $content = new \stdClass(); - $meta->name = substr($npub, 0, 8) . '…' . substr($npub, -4); - $meta->content = json_encode($content); - } - $this->logger->info('Metadata:', ['meta' => json_encode($meta)]); - return json_decode($meta->content); - }); - } catch (InvalidArgumentException $e) { - $this->logger->error('Error getting user data.', ['exception' => $e]); - $content = new \stdClass(); - $content->name = substr($npub, 0, 8) . '…' . substr($npub, -4); - return $content; - } - } - - public function getRelays($npub) - { - $cacheKey = '10002_' . $npub; - - try { - return $this->redisCache->get($cacheKey, function (ItemInterface $item) use ($npub) { - $item->expiresAfter(3600); // 1 hour, adjust as needed - try { - $relays = $this->nostrClient->getNpubRelays($npub); - } catch (\Exception $e) { - $this->logger->error('Error getting user relays.', ['exception' => $e]); - } - return $relays ?? []; - }); - } catch (InvalidArgumentException $e) { - $this->logger->error('Error getting user relays.', ['exception' => $e]); - return []; - } - } -} diff --git a/src/Twig/Components/Header.php b/src/Twig/Components/Header.php index 934be0d..18402b8 100644 --- a/src/Twig/Components/Header.php +++ b/src/Twig/Components/Header.php @@ -16,9 +16,9 @@ class Header /** * @throws InvalidArgumentException */ - public function __construct(private readonly CacheInterface $redisCache) + public function __construct(private readonly CacheInterface $cache) { - $mag = $this->redisCache->get('magazine-newsroom-magazine-by-newsroom', function (){ + $mag = $this->cache->get('magazine-newsroom-magazine-by-newsroom', function (){ return null; }); diff --git a/src/Twig/Components/Molecules/CategoryLink.php b/src/Twig/Components/Molecules/CategoryLink.php index eecc93d..aac327c 100644 --- a/src/Twig/Components/Molecules/CategoryLink.php +++ b/src/Twig/Components/Molecules/CategoryLink.php @@ -11,17 +11,16 @@ final class CategoryLink public string $title; public string $slug; - public function __construct(private CacheInterface $redisCache) + public function __construct(private CacheInterface $cache) { } - public function mount($coordinate): void + public function mount($category): void { - if (key_exists(1, $coordinate)) { - $parts = explode(':', $coordinate[1]); - $this->slug = $parts[2]; - $cat = $this->redisCache->get('magazine-' . $parts[2], function (){ - return null; + $parts = explode(':', $category[1]); + try { + $cat = $this->cache->get('magazine-' . $parts[2], function (){ + throw new \Exception('Not found'); }); $tags = $cat->getTags(); @@ -31,10 +30,8 @@ final class CategoryLink }); $this->title = $title[array_key_first($title)][1]; - } else { - dump($coordinate);die(); + } catch (\Exception $e) { + // Handle cache miss } - } - } diff --git a/src/Twig/Components/Molecules/UserFromNpub.php b/src/Twig/Components/Molecules/UserFromNpub.php index de04df2..b0c629a 100644 --- a/src/Twig/Components/Molecules/UserFromNpub.php +++ b/src/Twig/Components/Molecules/UserFromNpub.php @@ -2,7 +2,7 @@ namespace App\Twig\Components\Molecules; -use App\Service\RedisCacheService; +use App\Service\CacheService; use swentel\nostr\Key\Key; use Symfony\UX\TwigComponent\Attribute\AsTwigComponent; @@ -13,7 +13,7 @@ final class UserFromNpub public string $npub; public $user = null; - public function __construct(private readonly RedisCacheService $redisCacheService) + public function __construct(private readonly CacheService $cacheService) { } @@ -27,6 +27,6 @@ final class UserFromNpub } else { $this->npub = $ident; } - $this->user = $this->redisCacheService->getMetadata($this->npub); + $this->user = $this->cacheService->getMetadata($this->npub); } } diff --git a/src/Twig/Components/Organisms/FeaturedList.php b/src/Twig/Components/Organisms/FeaturedList.php index f3475e9..8969c0a 100644 --- a/src/Twig/Components/Organisms/FeaturedList.php +++ b/src/Twig/Components/Organisms/FeaturedList.php @@ -16,7 +16,7 @@ final class FeaturedList public array $list = []; public function __construct( - private readonly CacheInterface $redisCache, + private readonly CacheInterface $cache, private readonly ArticleRepository $articleRepository) { } @@ -29,7 +29,7 @@ final class FeaturedList { $parts = explode(':', $category[1]); /** @var Event $catIndex */ - $catIndex = $this->redisCache->get('magazine-' . $parts[2], function (){ + $catIndex = $this->cache->get('magazine-' . $parts[2], function (){ throw new \Exception('Not found'); }); diff --git a/src/Util/CommonMark/Converter.php b/src/Util/CommonMark/Converter.php index b037b6c..3c1284e 100644 --- a/src/Util/CommonMark/Converter.php +++ b/src/Util/CommonMark/Converter.php @@ -2,7 +2,7 @@ namespace App\Util\CommonMark; -use App\Service\RedisCacheService; +use App\Service\CacheService; use App\Util\CommonMark\ImagesExtension\RawImageLinkExtension; use App\Util\CommonMark\NostrSchemeExtension\NostrSchemeExtension; use League\CommonMark\Environment\Environment; @@ -25,8 +25,10 @@ use League\CommonMark\Renderer\HtmlDecorator; readonly class Converter { public function __construct( - private RedisCacheService $redisCacheService - ){} + private CacheService $cacheService + ) + { + } /** * @throws CommonMarkException @@ -64,7 +66,7 @@ readonly class Converter $environment->addExtension(new TableExtension()); $environment->addExtension(new StrikethroughExtension()); // create a custom extension, that handles nostr mentions - $environment->addExtension(new NostrSchemeExtension($this->redisCacheService)); + $environment->addExtension(new NostrSchemeExtension($this->cacheService)); $environment->addExtension(new SmartPunctExtension()); $environment->addExtension(new EmbedExtension()); $environment->addRenderer(Embed::class, new HtmlDecorator(new EmbedRenderer(), 'div', ['class' => 'embedded-content'])); diff --git a/src/Util/CommonMark/NostrSchemeExtension/NostrMentionParser.php b/src/Util/CommonMark/NostrSchemeExtension/NostrMentionParser.php index 2267b9b..571f8be 100644 --- a/src/Util/CommonMark/NostrSchemeExtension/NostrMentionParser.php +++ b/src/Util/CommonMark/NostrSchemeExtension/NostrMentionParser.php @@ -2,11 +2,10 @@ namespace App\Util\CommonMark\NostrSchemeExtension; -use App\Service\RedisCacheService; +use App\Service\CacheService; use League\CommonMark\Parser\Inline\InlineParserInterface; use League\CommonMark\Parser\Inline\InlineParserMatch; use League\CommonMark\Parser\InlineParserContext; -use swentel\nostr\Key\Key; /** * Class NostrMentionParser @@ -17,7 +16,7 @@ use swentel\nostr\Key\Key; readonly class NostrMentionParser implements InlineParserInterface { public function __construct( - private RedisCacheService $redisCacheService + private CacheService $cacheService ){} public function getMatchDefinition(): InlineParserMatch @@ -40,7 +39,7 @@ readonly class NostrMentionParser implements InlineParserInterface $npubLink = substr($fullMatch, strpos($fullMatch, 'npub1'), -1); // e.g., "npubXXXX" if (empty($label)) { - $metadata = $this->redisCacheService->getMetadata($npubLink); + $metadata = $this->cacheService->getMetadata($npubLink); $label = $metadata->display_name ?? $metadata->name; } diff --git a/src/Util/CommonMark/NostrSchemeExtension/NostrRawNpubParser.php b/src/Util/CommonMark/NostrSchemeExtension/NostrRawNpubParser.php index b641585..9b65dfb 100644 --- a/src/Util/CommonMark/NostrSchemeExtension/NostrRawNpubParser.php +++ b/src/Util/CommonMark/NostrSchemeExtension/NostrRawNpubParser.php @@ -2,7 +2,7 @@ namespace App\Util\CommonMark\NostrSchemeExtension; -use App\Service\RedisCacheService; +use App\Service\CacheService; use League\CommonMark\Parser\Inline\InlineParserInterface; use League\CommonMark\Parser\Inline\InlineParserMatch; use League\CommonMark\Parser\InlineParserContext; @@ -14,7 +14,7 @@ use League\CommonMark\Parser\InlineParserContext; readonly class NostrRawNpubParser implements InlineParserInterface { - public function __construct(private RedisCacheService $redisCacheService) + public function __construct(private CacheService $cacheService) { } @@ -28,7 +28,7 @@ readonly class NostrRawNpubParser implements InlineParserInterface $cursor = $inlineContext->getCursor(); // Get the match and extract relevant parts $fullMatch = $inlineContext->getFullMatch(); - $meta = $this->redisCacheService->getMetadata($fullMatch); + $meta = $this->cacheService->getMetadata($fullMatch); // Create a new inline node for the custom link $inlineContext->getContainer()->appendChild(new NostrMentionLink($meta->name, $fullMatch)); diff --git a/src/Util/CommonMark/NostrSchemeExtension/NostrSchemeExtension.php b/src/Util/CommonMark/NostrSchemeExtension/NostrSchemeExtension.php index ea5cec9..6a603f5 100644 --- a/src/Util/CommonMark/NostrSchemeExtension/NostrSchemeExtension.php +++ b/src/Util/CommonMark/NostrSchemeExtension/NostrSchemeExtension.php @@ -2,23 +2,23 @@ namespace App\Util\CommonMark\NostrSchemeExtension; -use App\Service\RedisCacheService; +use App\Service\CacheService; use League\CommonMark\Environment\EnvironmentBuilderInterface; use League\CommonMark\Extension\ExtensionInterface; class NostrSchemeExtension implements ExtensionInterface { - public function __construct(private readonly RedisCacheService $redisCacheService) + public function __construct(private readonly CacheService $cacheService) { } public function register(EnvironmentBuilderInterface $environment): void { $environment - ->addInlineParser(new NostrMentionParser($this->redisCacheService), 200) + ->addInlineParser(new NostrMentionParser($this->cacheService), 200) ->addInlineParser(new NostrSchemeParser(), 199) - ->addInlineParser(new NostrRawNpubParser($this->redisCacheService), 198) + ->addInlineParser(new NostrRawNpubParser($this->cacheService), 198) ->addRenderer(NostrSchemeData::class, new NostrEventRenderer(), 2) ->addRenderer(NostrMentionLink::class, new NostrMentionRenderer(), 1)