~thirdplace/feed-finder

12ffe94acd27db145c4f0d271d01aaca5582452e — Dag a month ago 2b9709a main
refactor
6 files changed, 30 insertions(+), 34 deletions(-)

M src/FeedFinder.php
M src/Finder.php
M src/finders/Hidden.php
M src/finders/Html.php
M src/finders/Instagram.php
D src/finders/Posthaven.php
M src/FeedFinder.php => src/FeedFinder.php +3 -11
@@ 29,11 29,7 @@ final class FeedFinder
    {
        $result = [];
        foreach ($this->finders as $finder) {
            $findings = $finder->findByUrl($url);
            if (!$findings) {
                continue;
            }
            foreach ($findings as $finding) {
            foreach ($finder->findByUrl($url) as $finding) {
                $result[] = $finding;
            }
        }


@@ 45,11 41,7 @@ final class FeedFinder
        $result = [];
        $dom = $this->dom($response);
        foreach ($this->finders as $finder) {
            $findings = $finder->findByResponse($url, $response, $dom);
            if (!$findings) {
                continue;
            }
            foreach ($findings as $finding) {
            foreach ($finder->findByResponse($url, $response, $dom) as $finding) {
                $result[] = $finding;
            }
        }


@@ 94,7 86,7 @@ final class FeedFinder
                    $finders[] = new $className();
            }
        }
        usort($finders, fn($a, $b) => $a::INDEX <=> $b::INDEX);
        usort($finders, fn(Finder $a, Finder $b) => $a::INDEX <=> $b::INDEX);
        return $finders;
    }


M src/Finder.php => src/Finder.php +2 -0
@@ 24,6 24,8 @@ abstract class Finder
    }

    /**
     * Helper for creating a result array
     *
     * @param string|Url $url
     */
    protected function finding($url): array

M src/finders/Hidden.php => src/finders/Hidden.php +3 -0
@@ 3,6 3,9 @@ declare(strict_types=1);

namespace Thirdplace;

/**
 * Hardcoded feed urls
 */
final class Hidden extends Finder
{
    private array $feeds;

M src/finders/Html.php => src/finders/Html.php +21 -2
@@ 16,6 16,22 @@ final class Html extends Finder
    public function findByResponse(Url $url, Response $response, \DOMDocument $dom): array
    {
        $result = [];

        if (strpos($response->body, 'Powered&nbsp;by&nbsp;<a href="https://mataroa.blog/">mataroa.blog</a>')) {
            return [[
                'name'          => 'Mataroa (custom domain)',
                'description'   => 'This feed contains blog posts',
                'url'           => $url->withPath('/rss/'),
            ]];
        }
        if (strpos($response->body, 'window.Posthaven = window.Posthaven')) {
            return [[
                'name'          => 'Posthaven (custom domain)',
                'description'   => 'This feed contains blog items.',
                'url'           => $url->withPath('/posts.atom'),
            ]];
        }

        $links = $dom->getElementsByTagName('link');
        foreach ($links as $link) {
            $href = $link->getAttribute('href');


@@ 50,8 66,11 @@ final class Html extends Finder
            $title = strtolower(trim($anchor->getAttribute('title')));
            $nodeValue = strtolower(trim($anchor->nodeValue));

            if (array_filter(['rss', 'feed', 'atom', 'rss feed'], fn($s) => $nodeValue === $s)
                || array_filter(['rss', 'feed', 'atom', 'atom feed'], fn($s) => $s === $title)
            $nodeValues = ['rss', 'feed', 'atom', 'rss feed', 'via rss'];
            $titles = ['rss', 'feed', 'atom', 'atom feed'];

            if (array_filter($nodeValues, fn($s) => $nodeValue === $s)
                || array_filter($titles, fn($s) => $s === $title)
                || substr($href, -strlen('.rss')) === '.rss'
                || substr($href, -strlen('.xml')) === '.xml'
                || substr($href, -strlen('.atom')) === '.atom'

M src/finders/Instagram.php => src/finders/Instagram.php +1 -1
@@ 6,7 6,7 @@ namespace Thirdplace;
final class Instagram extends Finder
{
    public const NAME = 'Instagram';
    public const DESCRIPTION = 'This feed contains instamgram items. WARNING: This is a third-party provider.';
    public const DESCRIPTION = 'This feed contains instgram items. WARNING: This is a third-party provider.';

    private array $providers;


D src/finders/Posthaven.php => src/finders/Posthaven.php +0 -20
@@ 1,20 0,0 @@
<?php
declare(strict_types=1);

namespace Thirdplace;

final class Posthaven extends Finder
{
    public const NAME = 'Posthaven (custom domain)';
    public const DESCRIPTION = 'This feed contains blog items.';

    public function findByResponse(Url $url, Response $response, \DOMDocument $dom): array
    {
        if (strpos($response->body, 'window.Posthaven = window.Posthaven')) {
            return [
                $this->finding($url->withPath('/posts.atom')),
            ];
        }
        return [];
    }
}