Skip to content

Commit

Permalink
feat(filament): added playlist fix & sync external profile actions to…
Browse files Browse the repository at this point in the history
… Filament (#773)
  • Loading branch information
Kyrch authored Jan 15, 2025
1 parent d45545e commit c406d73
Show file tree
Hide file tree
Showing 85 changed files with 438 additions and 252 deletions.
142 changes: 142 additions & 0 deletions app/Actions/Models/List/Playlist/FixPlaylistAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
<?php

declare(strict_types=1);

namespace App\Actions\Models\List\Playlist;

use App\Models\List\Playlist;
use App\Models\List\Playlist\PlaylistTrack;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;

/**
* Class FixPlaylistAction.
*/
class FixPlaylistAction
{
/**
* Handle the action.
*
* @param Playlist $playlist,
* @param mixed $context
* @return int
*/
public function handle(Playlist $playlist, mixed $context = null): int
{
// Fetch all tracks in the playlist and index them by track_id
$this->sendMessage("Fetching tracks for playlist ID: {$playlist->getKey()}...", $context, 'info');

/** @var Collection<int, PlaylistTrack> $tracks */
$tracks = PlaylistTrack::where(PlaylistTrack::ATTRIBUTE_PLAYLIST, $playlist->getKey())
->orderBy(PlaylistTrack::ATTRIBUTE_ID)
->get()
->keyBy(PlaylistTrack::ATTRIBUTE_ID);

// Find the playlist and get the first_id
$this->sendMessage("Fetching playlist details...", $context, 'info');

$first_id = $playlist->first_id;

// Initialize arrays for ordered tracks and visited tracks
$orderedTracks = [];
$visitedTracks = [];

// Start at the first_id and follow the next_id chain
$this->sendMessage("Reconstructing the playlist order...", $context, 'info');

$current_id = $first_id;

while ($current_id !== null) {
if (isset($visitedTracks[$current_id])) {
// If we encounter a previously visited track, we've detected a cycle
$this->sendMessage("Cycle detected at track ID: $current_id, stopping...", $context, 'warn');
break;
}

// Mark the current track as visited and add to ordered tracks
$visitedTracks[$current_id] = true;
$orderedTracks[] = $current_id;

// Get the next track in sequence
$currentTrack = $tracks[$current_id];
$current_id = $currentTrack->next_id;
}

// Check if we have traversed all tracks; if not, some tracks are broken
if (count($orderedTracks) != count($tracks)) {
$this->sendMessage("Detected broken tracks, attempting to add them to the end of the list...", $context, 'warn');

// Find all tracks that were not visited (potentially broken)
$remainingTracks = $tracks->filter(function ($track) use ($visitedTracks) {
return !isset($visitedTracks[$track->track_id]);
});

// Add remaining tracks to the end, preserving the existing order as much as possible
foreach ($remainingTracks as $remainingTrack) {
$orderedTracks[] = $remainingTrack->track_id;
}
}

// Update the previous_id and next_id for all tracks in the correct order
$this->sendMessage("Updating track links (previous_id and next_id)...", $context, 'info');
DB::transaction(function () use ($orderedTracks, $tracks, $playlist, $context) {
$previous_id = null;

foreach ($orderedTracks as $index => $track_id) {
$track = $tracks[$track_id];

// Get the next track in the sequence or set null if it's the last one
$next_id = $orderedTracks[$index + 1] ?? null;

// Update the previous_id and next_id for the track
$track->previous_id = $previous_id;
$track->next_id = $next_id;
$track->save();

// Move the previous_id pointer forward
$previous_id = $track_id;
}

// Update the playlist's first_id and last_id
$playlist->first_id = $orderedTracks[0];
$playlist->last_id = $orderedTracks[count($orderedTracks) - 1];
$playlist->save();

$this->sendMessage("Playlist first_id and last_id updated successfully.", $context, 'info');
});

$this->sendMessage("Playlist fixed successfully.", $context, 'info');
return 1;
}

/**
* Send the message given the context.
*
* @param string $message
* @param mixed $context
* @param string $type
* @return void
*/
protected function sendMessage(string $message, mixed $context, string $type): void
{
if (is_null($context)) {
return;
}

$translatedType = match (true) {
$context === 'log' => match ($type) {
'warn' => 'warning',
default => $type,
},
default => $type,
};

match (true) {
$context instanceof Command => $context->$translatedType($message),
$context === 'log' => Log::$translatedType($message),
default => null,
};
}
}
2 changes: 1 addition & 1 deletion app/Actions/Models/Wiki/AttachResourceAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class AttachResourceAction
* @param ResourceSite[] $sites
* @return void
*/
public function handle(BaseModel&HasResources $model,array $fields, array $sites): void
public function handle(BaseModel&HasResources $model, array $fields, array $sites): void
{
foreach ($sites as $resourceSite) {
$link = Arr::get($fields, $resourceSite->name);
Expand Down
12 changes: 2 additions & 10 deletions app/Actions/Models/Wiki/BackfillSongAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,10 @@ class BackfillSongAction extends BackfillAction
*
* @param Song $song
* @param string $lnkto
* @param array|null $fields
* @param ResourceSite[]|null $sites
*/
public function __construct(
Song $song,
protected readonly string $lnkto,
protected readonly ?array $fields = [],
protected readonly ?array $sites = [],
) {
parent::__construct($song);
}
Expand All @@ -54,13 +50,9 @@ public function handle(): ActionResult
try {
DB::beginTransaction();

// Attach other resources
$attachResourceAction = new AttachResourceAction();

$attachResourceAction->handle($this->getModel(), $this->fields, $this->sites);

// Request to lnk.to site
$response = Http::get($this->lnkto);
$response = Http::get($this->lnkto)
->throw();

$pattern = '/<a[^>]*class="[^"]*music-service-list__link[^"]*js-redirect[^"]*"[^>]*href="([^"]+)"[^>]*data-label="([^"]*)"[^>]*>/i';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ protected function setUp(): void
{
parent::setUp();

$this->label(__('filament.actions.anime.discord.thread.name'));
$this->icon('heroicon-o-chat-bubble-left-right');
$this->label(__('filament.actions.anime.discord_thread.name'));
$this->icon(__('filament-icons.actions.anime.discord_thread'));

$this->authorize('create', DiscordThread::class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace App\Concerns\Filament\Actions\Models;
namespace App\Concerns\Filament\Actions\Models\List;

use App\Actions\Models\AssignHashidsAction as AssignHashids;
use App\Contracts\Models\HasHashids;
Expand All @@ -26,7 +26,7 @@ protected function setUp(): void
{
parent::setUp();

$this->label(__('filament.actions.models.assign_hashids.name'));
$this->label(__('filament.actions.models.list.assign_hashids.name'));

$this->authorize('update', Playlist::class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ protected function setUp(): void
parent::setUp();

$this->label(__('filament.actions.anime.backfill.name'));
$this->icon('heroicon-o-bars-4');
$this->icon(__('filament-icons.actions.anime.backfill'));

$this->authorize('create', Anime::class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected function setUp(): void
parent::setUp();

$this->label(__('filament.actions.models.wiki.attach_image.name'));
$this->icon('heroicon-o-photo');
$this->icon(__('filament-icons.actions.models.wiki.attach_image'));

$this->authorize('create', Image::class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ protected function setUp(): void
parent::setUp();

$this->label(__('filament.actions.models.wiki.attach_resource.name'));
$this->icon('heroicon-o-queue-list');
$this->icon(__('filament-icons.actions.models.wiki.attach_resource'));

$this->modalWidth(MaxWidth::FourExtraLarge);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protected function setUp(): void

$this->label(__('filament.actions.video.backfill.name'));

$this->icon('heroicon-o-speaker-wave');
$this->icon(__('filament-icons.actions.video.backfill'));

$this->authorize('create', Audio::class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ protected function setUp(): void

$this->color('danger');

$this->icon('heroicon-m-trash');
$this->icon(__('filament-icons.actions.base.delete'));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ protected function setUp(): void
{
parent::setUp();

$this->icon('heroicon-o-arrow-long-right');
$this->icon(__('filament-icons.actions.storage.move'));
}

/**
Expand Down
4 changes: 2 additions & 2 deletions app/Concerns/Filament/Actions/Storage/MoveAllActionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ protected function setUp(): void
{
parent::setUp();

$this->label(__('filament.actions.base.moveAll'));
$this->icon('heroicon-o-arrow-long-right');
$this->label(__('filament.actions.base.move_all'));
$this->icon(__('filament-icons.actions.base.move_all'));

$this->authorize('create', [Audio::class, Video::class, VideoScript::class]);

Expand Down
11 changes: 7 additions & 4 deletions app/Concerns/Models/CanCreateExternalResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\BaseModel;
use App\Models\Wiki\ExternalResource;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Log;

/**
Expand All @@ -28,7 +29,7 @@ trait CanCreateExternalResource
public function createResource(string $url, ResourceSite $site, (BaseModel&HasResources)|null $model = null): ExternalResource
{
$url = $this->ensureHttpsUrl($url);
$id = $site::parseIdFromLink($url);
$id = ResourceSite::parseIdFromLink($url);

if ($model instanceof BaseModel) {
$urlPattern = $site->getUrlCaptureGroups($model);
Expand All @@ -37,15 +38,17 @@ public function createResource(string $url, ResourceSite $site, (BaseModel&HasRe
$url = $site->formatResourceLink($model::class, intval($matches[2]), $matches[2], $matches[1]);
}

if ($id !== null && !$site->usesIdInLink()) {
if ($id !== null && $site->usesIdInLink()) {
$url = $site->formatResourceLink($model::class, intval($id), $id);
}
}

$resource = ExternalResource::query()
->where(ExternalResource::ATTRIBUTE_SITE, $site->value)
->where(ExternalResource::ATTRIBUTE_LINK, $url)
->orWhere(ExternalResource::ATTRIBUTE_LINK, $url . '/')
->where(function (Builder $query) use ($url) {
return $query->where(ExternalResource::ATTRIBUTE_LINK, $url)
->orWhere(ExternalResource::ATTRIBUTE_LINK, $url . '/');
})
->first();

if ($resource === null) {
Expand Down
Loading

0 comments on commit c406d73

Please sign in to comment.