Release v1.2.0 #87
50 changed files with 125 additions and 134 deletions
|
|
@ -11,6 +11,7 @@ public function canParse(string $url): bool;
|
|||
|
||||
/**
|
||||
* Extract article data from HTML
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
public function extractData(string $html): array;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ public function canParse(string $url): bool;
|
|||
|
||||
/**
|
||||
* Extract article URLs from homepage HTML
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public function extractArticleUrls(string $html): array;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@ class ExceptionLogged
|
|||
|
||||
public function __construct(
|
||||
public Log $log
|
||||
) {
|
||||
}
|
||||
) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,5 @@ public function __construct(
|
|||
public string $message,
|
||||
/** @var array<string, mixed> */
|
||||
public array $context = []
|
||||
) {
|
||||
}
|
||||
) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,5 @@ class NewArticleFetched
|
|||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public function __construct(public Article $article)
|
||||
{
|
||||
}
|
||||
public function __construct(public Article $article) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,4 @@
|
|||
|
||||
use Exception;
|
||||
|
||||
class ChannelException extends Exception
|
||||
{
|
||||
}
|
||||
class ChannelException extends Exception {}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class PublishException extends Exception
|
|||
{
|
||||
public function __construct(
|
||||
private readonly Article $article,
|
||||
private readonly PlatformEnum|null $platform,
|
||||
private readonly ?PlatformEnum $platform,
|
||||
?Throwable $previous = null
|
||||
) {
|
||||
$message = "Failed to publish article #$article->id";
|
||||
|
|
|
|||
|
|
@ -4,6 +4,4 @@
|
|||
|
||||
use Exception;
|
||||
|
||||
class RoutingException extends Exception
|
||||
{
|
||||
}
|
||||
class RoutingException extends Exception {}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,12 @@
|
|||
namespace App\Http\Controllers\Api\V1;
|
||||
|
||||
use App\Http\Resources\ArticleResource;
|
||||
use App\Jobs\ArticleDiscoveryJob;
|
||||
use App\Models\Article;
|
||||
use App\Models\Setting;
|
||||
use App\Jobs\ArticleDiscoveryJob;
|
||||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class ArticlesController extends BaseController
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
use App\Models\User;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
use Exception;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use InvalidArgumentException;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use InvalidArgumentException;
|
||||
|
||||
class FeedsController extends BaseController
|
||||
{
|
||||
|
|
@ -37,7 +37,7 @@ public function index(Request $request): JsonResponse
|
|||
'total' => $feeds->total(),
|
||||
'from' => $feeds->firstItem(),
|
||||
'to' => $feeds->lastItem(),
|
||||
]
|
||||
],
|
||||
], 'Feeds retrieved successfully.');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ public function store(StorePlatformAccountRequest $request, CreatePlatformAccoun
|
|||
if (str_contains($e->getMessage(), 'Rate limited by')) {
|
||||
return $this->sendError($e->getMessage(), [], 429);
|
||||
}
|
||||
|
||||
return $this->sendError('Invalid username or password. Please check your credentials and try again.', [], 422);
|
||||
} catch (Exception $e) {
|
||||
return $this->sendError('Unable to connect to the Lemmy instance. Please check the URL and try again.', [], 422);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public function rules(): array
|
|||
'provider' => "required|in:{$providers}",
|
||||
'language_id' => 'required|exists:languages,id',
|
||||
'description' => 'nullable|string',
|
||||
'is_active' => 'boolean'
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ public function rules(): array
|
|||
'type' => 'required|in:website,rss',
|
||||
'language_id' => 'required|exists:languages,id',
|
||||
'description' => 'nullable|string',
|
||||
'is_active' => 'boolean'
|
||||
'is_active' => 'boolean',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ public function handle(LogSaver $logSaver, ArticleFetcher $articleFetcher): void
|
|||
$logSaver->info('Starting feed article fetch', null, [
|
||||
'feed_id' => $this->feed->id,
|
||||
'feed_name' => $this->feed->name,
|
||||
'feed_url' => $this->feed->url
|
||||
'feed_url' => $this->feed->url,
|
||||
]);
|
||||
|
||||
$articles = $articleFetcher->getArticlesFromFeed($this->feed);
|
||||
|
|
@ -33,7 +33,7 @@ public function handle(LogSaver $logSaver, ArticleFetcher $articleFetcher): void
|
|||
$logSaver->info('Feed article fetch completed', null, [
|
||||
'feed_id' => $this->feed->id,
|
||||
'feed_name' => $this->feed->name,
|
||||
'articles_count' => $articles->count()
|
||||
'articles_count' => $articles->count(),
|
||||
]);
|
||||
|
||||
$this->feed->update(['last_fetched_at' => now()]);
|
||||
|
|
@ -56,7 +56,7 @@ public static function dispatchForAllActiveFeeds(): void
|
|||
$logSaver->info('Dispatched feed discovery job', null, [
|
||||
'feed_id' => $feed->id,
|
||||
'feed_name' => $feed->name,
|
||||
'delay_minutes' => $delayMinutes
|
||||
'delay_minutes' => $delayMinutes,
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Queue\Queueable;
|
||||
|
||||
class PublishNextArticleJob implements ShouldQueue, ShouldBeUnique
|
||||
class PublishNextArticleJob implements ShouldBeUnique, ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
|
|
@ -28,6 +28,7 @@ public function __construct()
|
|||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @throws PublishException
|
||||
*/
|
||||
public function handle(ArticleFetcher $articleFetcher, ArticlePublishingService $publishingService): void
|
||||
|
|
@ -56,7 +57,7 @@ public function handle(ArticleFetcher $articleFetcher, ArticlePublishingService
|
|||
'article_id' => $article->id,
|
||||
'title' => $article->title,
|
||||
'url' => $article->url,
|
||||
'created_at' => $article->created_at
|
||||
'created_at' => $article->created_at,
|
||||
]);
|
||||
|
||||
// Fetch article data
|
||||
|
|
@ -67,12 +68,12 @@ public function handle(ArticleFetcher $articleFetcher, ArticlePublishingService
|
|||
|
||||
logger()->info('Successfully published article', [
|
||||
'article_id' => $article->id,
|
||||
'title' => $article->title
|
||||
'title' => $article->title,
|
||||
]);
|
||||
} catch (PublishException $e) {
|
||||
logger()->error('Failed to publish article', [
|
||||
'article_id' => $article->id,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
use Illuminate\Foundation\Queue\Queueable;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
class SyncChannelPostsJob implements ShouldQueue, ShouldBeUnique
|
||||
class SyncChannelPostsJob implements ShouldBeUnique, ShouldQueue
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ private function syncLemmyChannelPosts(LogSaver $logSaver): void
|
|||
|
||||
} catch (Exception $e) {
|
||||
$logSaver->error('Failed to sync channel posts', $this->channel, [
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
throw $e;
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
use App\Events\ExceptionLogged;
|
||||
use App\Events\ExceptionOccurred;
|
||||
use App\Models\Log;
|
||||
|
||||
class LogExceptionToDatabase
|
||||
{
|
||||
|
||||
public function handle(ExceptionOccurred $event): void
|
||||
{
|
||||
// Truncate the message to prevent database errors
|
||||
|
|
@ -24,15 +24,15 @@ public function handle(ExceptionOccurred $event): void
|
|||
'file' => $event->exception->getFile(),
|
||||
'line' => $event->exception->getLine(),
|
||||
'trace' => $event->exception->getTraceAsString(),
|
||||
...$event->context
|
||||
]
|
||||
...$event->context,
|
||||
],
|
||||
]);
|
||||
|
||||
ExceptionLogged::dispatch($log);
|
||||
} catch (\Exception $e) {
|
||||
// Prevent infinite recursion by not logging this exception
|
||||
// Optionally log to file or other non-database destination
|
||||
error_log("Failed to log exception to database: " . $e->getMessage());
|
||||
error_log('Failed to log exception to database: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public function handle(NewArticleFetched $event): void
|
|||
'article_id' => $article->id,
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@
|
|||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
}
|
||||
public function register(): void {}
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\ArticlePublication;
|
||||
use App\Models\Article;
|
||||
use App\Models\ArticlePublication;
|
||||
use App\Models\PlatformChannel;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ public function inactive(): static
|
|||
]);
|
||||
}
|
||||
|
||||
public function community(string $name = null): static
|
||||
public function community(?string $name = null): static
|
||||
{
|
||||
$communityName = $name ?: $this->faker->word();
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace Database\Factories;
|
||||
|
||||
use App\Models\Route;
|
||||
use App\Models\Feed;
|
||||
use App\Models\PlatformChannel;
|
||||
use App\Models\Route;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class RouteFactory extends Factory
|
||||
|
|
|
|||
|
|
@ -17,8 +17,7 @@ public function run(): void
|
|||
'name' => 'Belgae Social',
|
||||
'description' => 'A Belgian Lemmy instance on the fediverse',
|
||||
],
|
||||
])->each (fn ($instanceData) =>
|
||||
PlatformInstance::updateOrCreate(
|
||||
])->each(fn ($instanceData) => PlatformInstance::updateOrCreate(
|
||||
[
|
||||
'platform' => $instanceData['platform'],
|
||||
'url' => $instanceData['url'],
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SettingsSeeder extends Seeder
|
||||
|
|
|
|||
|
|
@ -4,12 +4,12 @@
|
|||
use App\Http\Controllers\Api\V1\AuthController;
|
||||
use App\Http\Controllers\Api\V1\DashboardController;
|
||||
use App\Http\Controllers\Api\V1\FeedsController;
|
||||
use App\Http\Controllers\Api\V1\KeywordsController;
|
||||
use App\Http\Controllers\Api\V1\LogsController;
|
||||
use App\Http\Controllers\Api\V1\OnboardingController;
|
||||
use App\Http\Controllers\Api\V1\PlatformAccountsController;
|
||||
use App\Http\Controllers\Api\V1\PlatformChannelsController;
|
||||
use App\Http\Controllers\Api\V1\RoutingController;
|
||||
use App\Http\Controllers\Api\V1\KeywordsController;
|
||||
use App\Http\Controllers\Api\V1\SettingsController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue