From 32f972b2ac74e4fa553ef27ef004c8cce85aad36 Mon Sep 17 00:00:00 2001 From: horus Date: Mon, 15 Jan 2024 23:03:17 +0100 Subject: adds support for mastofeed.org to publish automatically to Mastodon --- app/Http/Controllers/FeedController.php | 6 ++ app/Http/Controllers/IndexController.php | 6 ++ app/Libraries/Helper.php | 124 ++++++++++++++++++++++++------- resources/views/about.blade.php | 4 + resources/views/layouts/app.blade.php | 2 + resources/views/layouts/footer.blade.php | 2 + resources/views/list.blade.php | 2 + routes/web.php | 2 + 8 files changed, 122 insertions(+), 26 deletions(-) diff --git a/app/Http/Controllers/FeedController.php b/app/Http/Controllers/FeedController.php index 9fd73a5..5b9c36a 100644 --- a/app/Http/Controllers/FeedController.php +++ b/app/Http/Controllers/FeedController.php @@ -19,6 +19,12 @@ class FeedController extends Controller return Helper::makeFeed($articles, "new"); } + public function mastodon() + { + $articles = Article::orderBy('created_at', 'desc')->take(20)->get(); + return Helper::makeFeed($articles, "mastodon"); + } + public function popular() { diff --git a/app/Http/Controllers/IndexController.php b/app/Http/Controllers/IndexController.php index 50f2bf4..824a2e2 100644 --- a/app/Http/Controllers/IndexController.php +++ b/app/Http/Controllers/IndexController.php @@ -47,6 +47,12 @@ class IndexController extends Controller return view('list', ["articles" => $articles, "count" => $count]); } + public function show( $id ) { + $articles = Article::where('id', $id); + $articles = $articles->simplePaginate(10); + return view('list', ["articles" => $articles, "count" => 1]); + } + public function search(Request $request) { $search_unsafe = $request->input("q"); diff --git a/app/Libraries/Helper.php b/app/Libraries/Helper.php index be055b9..a900b87 100644 --- a/app/Libraries/Helper.php +++ b/app/Libraries/Helper.php @@ -27,6 +27,10 @@ class Helper { $feed_title = 'Popular Articles'; $feed_description = 'The most popular articles. Keep exploring.'; break; + case( "mastodon"): + $feed_title = 'Feed for Mastodon'; + $feed_description = 'New articles are published automatically to Mastodon.'; + break; default: $feed_title = 'Search for: ' . $title; $feed_description = 'All articles for "' . $title . '".'; @@ -54,41 +58,89 @@ class Helper { $feed->pubdate = $model[0]->created_at; $feed->lang = 'en'; $feed->setShortening(false); // true or false - $feed->setTextLimit(100); // maximum length of description text + + if ( "mastodon" == $title ) { + $feed->setTextLimit(500); // maximum length of description text + } else { + $feed->setTextLimit(100); // maximum length of description text + } foreach ($model as $post) { $desc = ($post->excerpt_html); - if ( ! $post->getCategories()->get()->isEmpty() ) { - $categories = "
"; - foreach( $post->getCategories()->get() as $cat ) { - $categories .= "name) ."'>". $cat->name . " | "; + if ( "mastodon" == $title ) { + + $cat_len= 0; + if ( ! $post->getCategories()->get()->isEmpty() ) { + $categories = "#MostDiscussed "; + foreach( $post->getCategories()->get() as $cat ) { + $categories .= "#". $cat->name . " "; + } + $cat_counter = $post->getCategories()->get()->count(); + $cat_len = mb_strlen($categories, "UTF-8"); } - $categories = rtrim($categories, " | "); - $desc .= "
Topics:"; - $desc .= $categories; - } - $discussions = "
"; - foreach( $post->getDiscussions()->orderBy('comments', 'desc')->get() as $dis ) { - $discussions .= "" . $dis->title . " "; - $discussions .= $dis->upvotes . " Upvotes | " . $dis->comments . " Comments
"; + $discussions = ""; + if ( $post->getDiscussions()->orderBy('created_at', 'desc')->get()->count() > 1 ) { + // multiple discussions on HN. show one link where you can find them all + $discussions = env('APP_URL') . "/article/" . $post->id; + } else { + // only on disc link. ### TODO foreach not needed + foreach( $post->getDiscussions()->orderBy('created_at', 'desc')->get() as $dis ) { + $discussions = $dis->source_url; + } + } + + // max desc length is 500 - 23 (Link) - $cat_len - 2 (white spaces) + $max_len = 500 - 23 - $cat_len - 2; + + $desc = Helper::first_sentence($desc, $max_len); + + $desc .= " " . $categories;# . $discussions; + + // set item's title, author, url, pubdate, description, content, enclosure (optional)* + $feed->addItem([ + 'title' => $desc, // mastofeed.org seems to ignore the description field + 'author' => env('APP_NAME'), + 'url' => \URL::to($post->url), + 'link' => \URL::to($post->url), + 'pubdate' => $post->created_at, + 'description' => $desc, + 'content' => $desc + ]); + + } else { + if ( ! $post->getCategories()->get()->isEmpty() ) { + $categories = "
"; + foreach( $post->getCategories()->get() as $cat ) { + $categories .= "name) ."'>". $cat->name . " | "; + } + $categories = rtrim($categories, " | "); + $desc .= "
Topics:"; + $desc .= $categories; + } + + $discussions = "
"; + foreach( $post->getDiscussions()->orderBy('comments', 'desc')->get() as $dis ) { + $discussions .= "" . $dis->title . " "; + $discussions .= $dis->upvotes . " Upvotes | " . $dis->comments . " Comments
"; + } + $desc .= "

Discussions:"; + $desc .= $discussions; + + // set item's title, author, url, pubdate, description, content, enclosure (optional)* + $feed->addItem([ + 'title' => $post->title, + 'author' => env('APP_NAME'), + 'url' => \URL::to($post->url), + 'link' => \URL::to($post->url), + 'pubdate' => $post->created_at, + 'description' => $desc, + 'content' => $desc + ]); } - $desc .= "

Discussions:"; - $desc .= $discussions; - - // set item's title, author, url, pubdate, description, content, enclosure (optional)* - $feed->addItem([ - 'title' => $post->title, - 'author' => env('APP_NAME'), - 'url' => \URL::to($post->url), - 'link' => \URL::to($post->url), - 'pubdate' => $post->created_at, - 'description' => $desc, - 'content' => $desc - ]); } } @@ -98,4 +150,24 @@ class Helper { // optional: you can set custom cache key with 3rd param as string return $feed->render('atom', $cache, 'feed_' . $title); } + + public static function first_sentence($content, $max_len = NULL) { + + $content = html_entity_decode(strip_tags($content)); + $content = ltrim($content); + $pos = strpos($content, '.'); + + if($pos === false) { + if ( is_null($max_len) ) { + return $content; + } else { + return substr($content, 0, $max_len); + } + } + else { + return substr($content, 0, $pos+1); + } + + } } + diff --git a/resources/views/about.blade.php b/resources/views/about.blade.php index e76f15f..14b62dc 100644 --- a/resources/views/about.blade.php +++ b/resources/views/about.blade.php @@ -46,6 +46,10 @@ For starters I recommend to start with the most If you have feedback, want to report a bug or just say hello, hit me up by e-mail: hi @ thisdomain without the www .com +
+
+You can now also follow on Mastodon
@MostDiscussed. + + + {{ config('app.name', 'Laravel') }}@if( "index" != Request::route()->getName() ) - {{ ucwords(Request::route()->getName()) }} Articles @endif diff --git a/resources/views/layouts/footer.blade.php b/resources/views/layouts/footer.blade.php index a037c25..1f56b8e 100644 --- a/resources/views/layouts/footer.blade.php +++ b/resources/views/layouts/footer.blade.php @@ -11,6 +11,8 @@ About {{ env('APP_NAME') }} +
+ Follow on Mastodon
diff --git a/resources/views/list.blade.php b/resources/views/list.blade.php index 5b64214..575af7c 100644 --- a/resources/views/list.blade.php +++ b/resources/views/list.blade.php @@ -75,6 +75,8 @@ Have a deep view into what people are curious about.

+ @elseif ( "show" == Request::route()->getName() ) + @else

{{ ucwords(Request::route()->getName()) }} Articles diff --git a/routes/web.php b/routes/web.php index 0693118..ff3046b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -22,8 +22,10 @@ Route::get('/search', 'IndexController@search')->name('search'); Route::get('/popular/topics', 'IndexController@populartopics')->name('popular_topics'); Route::get('/popular', 'IndexController@popular')->name('popular'); Route::get('/random', 'IndexController@random')->name('random'); +Route::get('/article/{id}', 'IndexController@show')->name('show')->where('id', '[0-9]+'); Route::get('/feed/new', 'FeedController@new')->name('feed_new'); +Route::get('/feed/mastodon', 'FeedController@mastodon')->name('feed_mastodon'); Route::get('/feed/popular', 'FeedController@popular')->name('feed_popular'); Route::get('/feed/search', 'FeedController@search')->name('feed_search'); -- cgit v1.2.3