diff --git a/src/Controller/Admin/AdminRssController.php b/src/Controller/Admin/AdminRssController.php new file mode 100644 index 0000000..85ab51e --- /dev/null +++ b/src/Controller/Admin/AdminRssController.php @@ -0,0 +1,117 @@ +getUser(); + if (!$user) { + throw $this->createAccessDeniedException('You must be logged in to access this page.'); + } + + $pubkey = NostrKeyUtil::npubToHex($user->getUserIdentifier()); + + $magazines = $entityManager->getRepository(Event::class)->findBy([ + 'kind' => KindsEnum::PUBLICATION_INDEX, + 'pubkey' => $pubkey, + ]); + $filteredMagazines = array_filter($magazines, function ($mag) { + $tags = $mag->getTags(); + $isMagType = false; + $isTopLevel = false; + $hasSource = false; + foreach ($tags as $tag) { + if ($tag[0] === 'type' && $tag[1] === 'magazine') { + $isMagType = true; + } + if ($tag[0] === 'a' && $isTopLevel === false) { + $parts = explode(':', $tag[1]); + if ($parts[0] == (string)KindsEnum::PUBLICATION_INDEX->value) { + $isTopLevel = true; + } + } + if ($tag[0] === 'source' && !empty($tag[1])) { + $hasSource = true; + } + } + // Optionally, filter by user ownership if needed + return $isMagType && $isTopLevel && $hasSource; + }); + + $form = $this->createFormBuilder() + ->add('feedUrl', TextType::class, [ + 'label' => 'RSS Feed URL', + 'required' => true, + ]) + ->add('magazine', TextType::class, [ + 'label' => 'Magazine (optional)', + 'required' => false, + ]) + ->getForm(); + + $form->handleRequest($request); + $articles = []; + if ($form->isSubmitted() && $form->isValid()) { + $feedUrl = $form->get('feedUrl')->getData(); + $magazineSlug = $form->get('magazine')->getData(); + $feed = $rssFeedService->fetchFeed($feedUrl); + $articles = $feed['items'] ?? []; + $request->getSession()->set('rss_articles', $articles); + $request->getSession()->set('selected_magazine', $magazineSlug); + return $this->redirectToRoute('admin_rss_review'); + } + + return $this->render('admin/rss_submit.html.twig', [ + 'form' => $form->createView(), + 'magazines' => $filteredMagazines, + ]); + } + + #[Route('/admin/rss/review', name: 'admin_rss_review', methods: ['GET', 'POST'])] + public function reviewRssArticles(Request $request, RssToNostrConverter $converter): Response + { + $articles = $request->getSession()->get('rss_articles', []); + $drafts = []; + foreach ($articles as $item) { + $drafts[] = $converter->convertToNostrEvent($item); + } + + if ($request->isMethod('POST')) { + $toSign = $request->request->all('sign'); + $signed = []; + foreach ($toSign as $idx) { + if (isset($drafts[$idx])) { + // Here, you would sign and persist the article + // For now, just collect for confirmation + $signed[] = $drafts[$idx]; + } + } + // TODO: Persist signed articles as needed + $this->addFlash('success', count($signed) . ' articles signed and published.'); + $request->getSession()->remove('rss_articles'); + return $this->redirectToRoute('admin_rss_submit'); + } + + return $this->render('admin/rss_review.html.twig', [ + 'drafts' => $drafts, + ]); + } + + // Add a route for signing and persisting selected articles as needed +} diff --git a/src/Service/RssFeedService.php b/src/Service/RSS/RssFeedService.php similarity index 99% rename from src/Service/RssFeedService.php rename to src/Service/RSS/RssFeedService.php index 1551c97..cb12112 100644 --- a/src/Service/RssFeedService.php +++ b/src/Service/RSS/RssFeedService.php @@ -1,6 +1,6 @@ getNzineBot(); - if (!$bot) { - throw new \RuntimeException('Nzine bot not found'); - } - - $bot->setEncryptionService($this->encryptionService); - $privateKey = $bot->getNsec(); - - if (!$privateKey) { - throw new \RuntimeException('Bot private key not found'); - } + $privateKey = 'your-private-key'; // Replace with actual private key retrieval logic // Create the event $event = new Event(); @@ -80,11 +64,6 @@ class RssToNostrConverter $event->addTag(['published_at', (string) $rssItem['pubDate']->getTimestamp()]); } - // Add category tag (t tag) - only if category matched - if ($matchedCategory && isset($matchedCategory['slug'])) { - $event->addTag(['t', $matchedCategory['slug']]); - } - // Add source tag for original article URL if (!empty($rssItem['link'])) { $event->addTag(['source', $rssItem['link']]); @@ -95,12 +74,6 @@ class RssToNostrConverter $event->addTag(['r', $rssItem['link']]); } - // Add reference to category index if provided and category matched - if ($categoryIndexEventId && $matchedCategory && isset($matchedCategory['slug'])) { - $npub = $nzine->getNpub(); - $event->addTag(['a', KindsEnum::PUBLICATION_INDEX->value . ':' . $npub . ':' . $matchedCategory['slug']]); - } - // Add client tag to indicate source $event->addTag(['client', 'newsroom-rss-aggregator']); @@ -111,7 +84,6 @@ class RssToNostrConverter $this->logger->info('Created Nostr event from RSS item', [ 'title' => $rssItem['title'], 'slug' => $slug, - 'category' => $matchedCategory['name'] ?? null, ]); return $event; diff --git a/src/Service/TagMatchingService.php b/src/Service/RSS/TagMatchingService.php similarity index 99% rename from src/Service/TagMatchingService.php rename to src/Service/RSS/TagMatchingService.php index bab805c..19351e9 100644 --- a/src/Service/TagMatchingService.php +++ b/src/Service/RSS/TagMatchingService.php @@ -1,6 +1,6 @@