Skip to content

Commit

Permalink
feat: external lists (#710)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kyrch committed Jul 2, 2024
1 parent 294ab4f commit 9238fd3
Show file tree
Hide file tree
Showing 179 changed files with 5,481 additions and 414 deletions.
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ ELASTIC_SCOUT_DRIVER_REFRESH_DOCUMENTS=false
# elastic migrations
ELASTIC_MIGRATIONS_TABLE=elastic_migrations

# external profile
PROFILE_MAX_ENTRIES=1000
USER_MAX_PROFILES=5

# ffmpeg
FFMPEG_BINARIES=
FFPROBE_BINARIES=
Expand Down
106 changes: 106 additions & 0 deletions app/Actions/Models/List/ExternalProfile/StoreExternalProfileAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

declare(strict_types=1);

namespace App\Actions\Models\List\ExternalProfile;

use App\Actions\Http\Api\StoreAction;
use App\Enums\Models\List\AnimeWatchStatus;
use App\Enums\Models\List\ExternalProfileSite;
use App\Models\List\External\ExternalEntry;
use App\Models\Wiki\Anime;
use App\Models\Wiki\ExternalResource;
use Exception;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

/**
* Class StoreExternalProfileAction.
*/
class StoreExternalProfileAction
{
/**
* Store external profile and its entries.
*
* @param Builder $builder
* @param array $profileParameters
* @return Model
*
* @throws Exception
*/
public function store(Builder $builder, array $profileParameters): Model
{
try {
DB::beginTransaction();

// $getEntriesAction = new GetEntries();

// $entries = $getEntriesAction->get($profileParameters);

$entries = [
'name' => 'Kyrch Profile',
'entries' => [
[
ExternalResource::ATTRIBUTE_EXTERNAL_ID => 101573,
ExternalEntry::ATTRIBUTE_SCORE => 10,
ExternalEntry::ATTRIBUTE_IS_FAVORITE => true,
ExternalEntry::ATTRIBUTE_WATCH_STATUS => AnimeWatchStatus::COMPLETED->value,
],
[
ExternalResource::ATTRIBUTE_EXTERNAL_ID => 477,
ExternalEntry::ATTRIBUTE_SCORE => 9.5,
ExternalEntry::ATTRIBUTE_IS_FAVORITE => false,
ExternalEntry::ATTRIBUTE_WATCH_STATUS => AnimeWatchStatus::WATCHING->value,
],
[
ExternalResource::ATTRIBUTE_EXTERNAL_ID => 934,
ExternalEntry::ATTRIBUTE_SCORE => 8,
ExternalEntry::ATTRIBUTE_IS_FAVORITE => false,
ExternalEntry::ATTRIBUTE_WATCH_STATUS => AnimeWatchStatus::PAUSED->value,
],
],
];

$storeProfileAction = new StoreAction();

$profile = $storeProfileAction->store($builder, $profileParameters);

foreach (Arr::get($entries, 'entries') as $entryParameters) {
$storeEntryAction = new StoreAction();

$externalSite = Arr::get($profileParameters, 'site');
$external_id = Arr::get($entryParameters, 'external_id');

$animes = Anime::query()->whereHas(ExternalResource::TABLE, function (Builder $query) use ($externalSite, $external_id) {
$query->where(ExternalResource::ATTRIBUTE_SITE, ExternalProfileSite::getResourceSite($externalSite)->value)
->where(ExternalResource::ATTRIBUTE_EXTERNAL_ID, $external_id);
})->get();

foreach ($animes as $anime) {
if ($anime instanceof Anime) {
$storeEntryAction->store(ExternalEntry::query(), array_merge(
$entryParameters,
[
ExternalEntry::ATTRIBUTE_ANIME => $anime->getKey(),
ExternalEntry::ATTRIBUTE_EXTERNAL_PROFILE => $profile->getKey(),
]
));
}
}
}

DB::commit();

return $storeProfileAction->cleanup($profile);
} catch (Exception $e) {
Log::error($e->getMessage());

DB::rollBack();

throw $e;
}
}
}
15 changes: 15 additions & 0 deletions app/Constants/Config/ExternalProfileConstants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace App\Constants\Config;

/**
* Class ExternalProfileConstants.
*/
class ExternalProfileConstants
{
final public const MAX_PROFILES_QUALIFIED = 'externalprofile.user_max_profiles';
final public const MAX_ENTRIES_QUALIFIED = 'externalprofile.profile_max_entries';
}
21 changes: 21 additions & 0 deletions app/Enums/Models/List/AnimeWatchStatus.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace App\Enums\Models\List;

use App\Concerns\Enums\LocalizesName;

/**
* Enum AnimeWatchStatus.
*/
enum AnimeWatchStatus: int
{
use LocalizesName;

case WATCHING = 0;
case COMPLETED = 1;
case PAUSED = 2;
case DROPPED = 3;
case PLAN_TO_WATCH = 4;
}
36 changes: 36 additions & 0 deletions app/Enums/Models/List/ExternalProfileSite.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace App\Enums\Models\List;

use App\Concerns\Enums\LocalizesName;
use App\Enums\Models\Wiki\ResourceSite;

/**
* Enum ExternalProfileSite.
*/
enum ExternalProfileSite: int
{
use LocalizesName;

case MAL = 0;
case ANILIST = 1;
case KITSU = 2;

/**
* Get the ResourceSite by the ExternalProfileSite value.
*
* @param int|null $value
* @return ResourceSite|null
*/
public static function getResourceSite(?int $value): ?ResourceSite
{
return match ($value) {
static::MAL->value => ResourceSite::MAL,
static::ANILIST->value => ResourceSite::ANILIST,
static::KITSU->value => ResourceSite::KITSU,
default => null,
};
}
}
18 changes: 18 additions & 0 deletions app/Enums/Models/List/ExternalProfileVisibility.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\Enums\Models\List;

use App\Concerns\Enums\LocalizesName;

/**
* Enum ExternalProfileVisibility.
*/
enum ExternalProfileVisibility: int
{
use LocalizesName;

case PUBLIC = 0;
case PRIVATE = 1;
}
41 changes: 41 additions & 0 deletions app/Events/Base/List/ListCreatedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace App\Events\Base\List;

use App\Constants\Config\ServiceConstants;
use App\Events\Base\BaseCreatedEvent;
use Illuminate\Support\Facades\Config;

/**
* Class ListCreatedEvent.
*
* @template TModel of \App\Models\BaseModel
*
* @extends BaseCreatedEvent<TModel>
*/
abstract class ListCreatedEvent extends BaseCreatedEvent
{
/**
* Get Discord channel the message will be sent to.
*
* @return string
*/
public function getDiscordChannel(): string
{
return Config::get(ServiceConstants::ADMIN_DISCORD_CHANNEL_QUALIFIED);
}

/**
* Determine if the message should be sent.
*
* @return bool
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function shouldSendDiscordMessage(): bool
{
return true;
}
}
41 changes: 41 additions & 0 deletions app/Events/Base/List/ListDeletedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace App\Events\Base\List;

use App\Constants\Config\ServiceConstants;
use App\Events\Base\BaseDeletedEvent;
use Illuminate\Support\Facades\Config;

/**
* Class ListDeletedEvent.
*
* @template TModel of \App\Models\BaseModel
*
* @extends BaseDeletedEvent<TModel>
*/
abstract class ListDeletedEvent extends BaseDeletedEvent
{
/**
* Get Discord channel the message will be sent to.
*
* @return string
*/
public function getDiscordChannel(): string
{
return Config::get(ServiceConstants::ADMIN_DISCORD_CHANNEL_QUALIFIED);
}

/**
* Determine if the message should be sent.
*
* @return bool
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function shouldSendDiscordMessage(): bool
{
return true;
}
}
41 changes: 41 additions & 0 deletions app/Events/Base/List/ListRestoredEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace App\Events\Base\List;

use App\Constants\Config\ServiceConstants;
use App\Events\Base\BaseRestoredEvent;
use Illuminate\Support\Facades\Config;

/**
* Class ListRestoredEvent.
*
* @template TModel of \App\Models\BaseModel
*
* @extends BaseRestoredEvent<TModel>
*/
abstract class ListRestoredEvent extends BaseRestoredEvent
{
/**
* Get Discord channel the message will be sent to.
*
* @return string
*/
public function getDiscordChannel(): string
{
return Config::get(ServiceConstants::ADMIN_DISCORD_CHANNEL_QUALIFIED);
}

/**
* Determine if the message should be sent.
*
* @return bool
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function shouldSendDiscordMessage(): bool
{
return true;
}
}
41 changes: 41 additions & 0 deletions app/Events/Base/List/ListUpdatedEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace App\Events\Base\List;

use App\Constants\Config\ServiceConstants;
use App\Events\Base\BaseUpdatedEvent;
use Illuminate\Support\Facades\Config;

/**
* Class ListUpdatedEvent.
*
* @template TModel of \App\Models\BaseModel
*
* @extends BaseUpdatedEvent<TModel>
*/
abstract class ListUpdatedEvent extends BaseUpdatedEvent
{
/**
* Get Discord channel the message will be sent to.
*
* @return string
*/
public function getDiscordChannel(): string
{
return Config::get(ServiceConstants::ADMIN_DISCORD_CHANNEL_QUALIFIED);
}

/**
* Determine if the message should be sent.
*
* @return bool
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function shouldSendDiscordMessage(): bool
{
return true;
}
}
Loading

0 comments on commit 9238fd3

Please sign in to comment.