A .gitignore => .gitignore +1 -0
@@ 0,0 1,1 @@
+composer.lock
M src/Finder.php => src/Finder.php +1 -1
@@ 11,7 11,7 @@ abstract class Finder
public const INDEX = 50;
public const NAME = 'Generic name';
- public const DESCRIPTION = 'Generic description';
+ public const DESCRIPTION = '';
public function findByUrl(Url $url): array
{
A src/finders/HackerNews.php => src/finders/HackerNews.php +27 -0
@@ 0,0 1,27 @@
+<?php
+declare(strict_types=1);
+
+namespace Thirdplace;
+
+/**
+ * https://hnrss.github.io/
+ */
+final class HackerNews extends Finder
+{
+ public const NAME = 'HackerNews';
+
+ public function findByUrl(Url $url): array
+ {
+ if (preg_match('#^https?://news\.ycombinator\.com/?$#', (string) $url)) {
+ return [$this->finding('https://hnrss.org/frontpage')];
+ }
+ if (preg_match('#^https?://news\.ycombinator\.com/newest$#', (string) $url)) {
+ return [$this->finding('https://hnrss.org/newest')];
+ }
+ if (preg_match('#^https?://news\.ycombinator\.com/item\?id=(\d+)$#', (string) $url, $m)) {
+ return [$this->finding(sprintf('https://hnrss.org/item?id=%s', $m[1]))];
+ }
+
+ return [];
+ }
+}<
\ No newline at end of file
M src/finders/Html.php => src/finders/Html.php +23 -5
@@ 50,18 50,36 @@ final class Html extends Finder
$title = strtolower(trim($anchor->getAttribute('title')));
$nodeValue = strtolower(trim($anchor->nodeValue));
- // todo: use php8 shim for str_ends_with()
-
if (array_filter(['rss', 'feed', 'atom', 'rss feed'], fn($s) => $nodeValue === $s)
|| array_filter(['rss', 'feed', 'atom', 'atom feed'], fn($s) => $s === $title)
|| substr($href, -strlen('.rss')) === '.rss'
|| substr($href, -strlen('.xml')) === '.xml'
|| substr($href, -strlen('.atom')) === '.atom'
|| substr($href, -strlen('/rss')) === '/rss'
- //|| strpos($href, 'feed:') === 0 test this one
- || preg_match('#^https?://feeds\.feedburner\.com#', $href)
) {
- $result[(string) $url->resolve($href)] = $this->finding($url->resolve($href));
+ // many false positives here
+ try {
+ $result[(string)$url->resolve($href)] = $this->finding($url->resolve($href));
+ } catch (UrlException $e) {
+ // pass
+ }
+ }
+
+ // todo: use php8 shim for str_ends_with()
+
+ if (preg_match('#^https?://feeds\.feedblitz\.com/#', $href)) {
+ // Works without &x=1 too when not using a browser
+ $result[$href] = $this->finding(sprintf('%s&x=1', $href));
+ }
+ if (preg_match('#^https?://feeds\.feedburner\.com/#', $href)) {
+ $result[$href] = $this->finding(rtrim($href, '/feed'));
+ }
+ if (preg_match('#^https?://www\.feedio.co/@#', $href)) {
+ $result[$href] = $this->finding(sprintf('%s/feed', $href));
+ }
+ if (preg_match('#^feed:#', $href)) {
+ // todo: fix
+ //$result[$href] = $this->finding($href);
}
}
return $result;
A src/finders/Instagram.php => src/finders/Instagram.php +32 -0
@@ 0,0 1,32 @@
+<?php
+declare(strict_types=1);
+
+namespace Thirdplace;
+
+final class Instagram extends Finder
+{
+ public const NAME = 'Instagram';
+
+ private array $providers;
+
+ // todo: inject providers
+ public function __construct(array $providers = [])
+ {
+ $this->providers = [
+ 'https://bibliogram.pussthecat.org/u/%s/rss.xml',
+ 'https://bibliogram.1d4.us/u/%s/rss.xml',
+ 'https://bib.actionsack.com/u/%s/rss.xml',
+ ];
+ }
+
+ public function findByUrl(Url $url): array
+ {
+ $provider = $this->providers[array_rand($this->providers)];
+
+ if (preg_match('#^https?://(?:www\.)?instagram\.com/(\w+)#', (string) $url, $m)) {
+ return [$this->finding(sprintf($provider, $m[1]))];
+ }
+ return [];
+ }
+
+}<
\ No newline at end of file
M src/finders/Telegram.php => src/finders/Telegram.php +2 -2
@@ 21,8 21,8 @@ final class Telegram extends Finder
if ($providers === []) {
return [];
}
- if (preg_match('#^https?://t\.me/(\w+)#', (string) $url, $m)) {
- // todo: might not be a public channel
+ if (preg_match('#^https?://t\.me/(?:s/)?(\w+)#', (string) $url, $m)) {
+ // Might not be a public channel
return [
$this->finding(sprintf($providers[array_rand($providers)], $m[1])),
];