diff --git a/docker/cron/article_discovery.sh b/docker/cron/article_discovery.sh
new file mode 100644
index 0000000..7b06124
--- /dev/null
+++ b/docker/cron/article_discovery.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+set -e
+export PATH="/usr/local/bin:/usr/bin:/bin"
+
+LOG_PREFIX="[media_discovery.sh]"
+TIMESTAMP() { date '+%Y-%m-%d %H:%M:%S'; }
+
+# Log start
+echo "$(TIMESTAMP) $LOG_PREFIX STARTING media discovery cache update" >&2
+
+# Run Symfony command
+php /var/www/html/bin/console app:cache_latest_articles
+EXIT_CODE=$?
+
+if [ $EXIT_CODE -eq 0 ]; then
+ echo "$(TIMESTAMP) $LOG_PREFIX FINISHED successfully (exit code: $EXIT_CODE)" >&2
+else
+ echo "$(TIMESTAMP) $LOG_PREFIX ERROR (exit code: $EXIT_CODE)" >&2
+fi
diff --git a/docker/cron/crontab b/docker/cron/crontab
index 13d5ea5..328cf05 100644
--- a/docker/cron/crontab
+++ b/docker/cron/crontab
@@ -1,2 +1,3 @@
0 */6 * * * /index_articles.sh >> /var/log/cron.log 2>&1
0 */2 * * * /media_discovery.sh >> /var/log/cron.log 2>&1
+0 */2 * * * /article_discovery.sh >> /var/log/cron.log 2>&1
diff --git a/src/Command/CacheLatestArticlesCommand.php b/src/Command/CacheLatestArticlesCommand.php
new file mode 100644
index 0000000..0ab246a
--- /dev/null
+++ b/src/Command/CacheLatestArticlesCommand.php
@@ -0,0 +1,75 @@
+finder = $finder;
+ $this->articlesCache = $articlesCache;
+ $this->params = $params;
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $env = $this->params->get('kernel.environment');
+ $cacheKey = 'latest_articles_list_' . $env;
+ $cacheItem = $this->articlesCache->getItem($cacheKey);
+
+ $key = new Key();
+ $excludedPubkeys = [
+ $key->convertToHex('npub1etsrcjz24fqewg4zmjze7t5q8c6rcwde5zdtdt4v3t3dz2navecscjjz94'), // Bitcoin Magazine (News Bot)
+ $key->convertToHex('npub1m7szwpud3jh2k3cqe73v0fd769uzsj6rzmddh4dw67y92sw22r3sk5m3ys'), // No Bullshit Bitcoin (News Bot)
+ $key->convertToHex('npub13wke9s6njrmugzpg6mqtvy2d49g4d6t390ng76dhxxgs9jn3f2jsmq82pk'), // TFTC (News Bot)
+ $key->convertToHex('npub10akm29ejpdns52ca082skmc3hr75wmv3ajv4987c9lgyrfynrmdqduqwlx'), // Discreet Log (News Bot)
+ $key->convertToHex('npub13uvnw9qehqkds68ds76c4nfcn3y99c2rl9z8tr0p34v7ntzsmmzspwhh99'), // Batcoinz (Just annoying)
+ $key->convertToHex('npub1fls5au5fxj6qj0t36sage857cs4tgfpla0ll8prshlhstagejtkqc9s2yl'), // AGORA Marketplace - feed 𝚋𝚘𝚝 (Just annoying)
+ ];
+
+ if (!$cacheItem->isHit()) {
+ $boolQuery = new BoolQuery();
+ $boolQuery->addMustNot(new Terms('pubkey', $excludedPubkeys));
+
+ $query = new Query($boolQuery);
+ $query->setSize(50);
+ $query->setSort(['createdAt' => ['order' => 'desc']]);
+
+ $collapse = new Collapse();
+ $collapse->setFieldname('slug');
+ $query->setCollapse($collapse);
+
+ $articles = $this->finder->find($query);
+
+ $cacheItem->set($articles);
+ $cacheItem->expiresAfter(3600); // Cache for 1 hour
+ $this->articlesCache->save($cacheItem);
+ $output->writeln('Cached ' . count($articles) . ' articles.');
+ } else {
+ $output->writeln('Cache already exists for key: ' . $cacheKey . '');
+ }
+
+ return Command::SUCCESS;
+ }
+}
diff --git a/src/Controller/DefaultController.php b/src/Controller/DefaultController.php
index 1335361..9c3f9de 100644
--- a/src/Controller/DefaultController.php
+++ b/src/Controller/DefaultController.php
@@ -54,6 +54,9 @@ class DefaultController extends AbstractController
#[Route('/latest-articles', name: 'latest_articles')]
public function latestArticles(FinderInterface $finder, CacheItemPoolInterface $articlesCache): Response
{
+ set_time_limit(300); // 5 minutes
+ ini_set('max_execution_time', '300');
+
$env = $this->getParameter('kernel.environment');
$cacheKey = 'latest_articles_list_' . $env ; // Use env to differentiate cache between environments
$cacheItem = $articlesCache->getItem($cacheKey);
@@ -86,7 +89,7 @@ class DefaultController extends AbstractController
$articles = $finder->find($query);
$cacheItem->set($articles);
- $cacheItem->expiresAfter(300); // Cache for 5 minutes
+ $cacheItem->expiresAfter(3600); // Cache for 1 hour
$articlesCache->save($cacheItem);
}
@@ -185,8 +188,6 @@ class DefaultController extends AbstractController
}
}
- dump($tags);die;
-
if (!empty($coordinates)) {
// Extract slugs for elasticsearch query
$slugs = array_map(function($coordinate) {