Skip to content

Commit

Permalink
Merge pull request #155
Browse files Browse the repository at this point in the history
[Update] Improve MAL Import
  • Loading branch information
kiritokatklian authored Jun 14, 2021
2 parents 6bd72fc + ebf0700 commit 54658d1
Show file tree
Hide file tree
Showing 14 changed files with 407 additions and 36 deletions.
15 changes: 15 additions & 0 deletions app/Enums/MALImportBehavior.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace App\Enums;

use BenSampo\Enum\Enum;

/**
* @method static MALImportBehavior Overwrite()
* @method static MALImportBehavior Merge()
*/
final class MALImportBehavior extends Enum
{
const Overwrite = 0;
const Merge = 1;
}
9 changes: 5 additions & 4 deletions app/Events/MALImportFinished.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Events;

use App\Enums\MALImportBehavior;
use App\Models\User;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
Expand All @@ -27,18 +28,18 @@ class MALImportFinished
/**
* The behavior of the import.
*
* @var string
* @var MALImportBehavior
*/
public string $behavior;
public MALImportBehavior $behavior;

/**
* Create a new event instance.
*
* @param User $user
* @param array $results
* @param string $behavior
* @param MALImportBehavior $behavior
*/
public function __construct(User $user, array $results, string $behavior)
public function __construct(User $user, array $results, MALImportBehavior $behavior)
{
$this->user = $user;
$this->results = $results;
Expand Down
6 changes: 5 additions & 1 deletion app/Http/Controllers/LibraryController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Controllers;

use App\Enums\MALImportBehavior;
use App\Models\Anime;
use App\Enums\UserLibraryStatus;
use App\Helpers\JSONResult;
Expand Down Expand Up @@ -153,8 +154,11 @@ function malImport(MALImportRequest $request): JsonResponse
// Read XML file
$xmlContent = File::get($data['file']->getRealPath());

// Get import behavior
$behavior = MALImportBehavior::fromValue((int) $data['behavior']);

// Dispatch job
dispatch(new ProcessMALImport($user, $xmlContent, $data['behavior']));
dispatch(new ProcessMALImport($user, $xmlContent, $behavior));

// Update last MAL import date for user
$user->last_mal_import_at = now();
Expand Down
3 changes: 2 additions & 1 deletion app/Http/Requests/MALImportRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Requests;

use App\Enums\MALImportBehavior;
use Illuminate\Foundation\Http\FormRequest;

class MALImportRequest extends FormRequest
Expand All @@ -25,7 +26,7 @@ public function rules(): array
{
return [
'file' => ['required', 'file', 'mimes:xml', 'max:' . config('mal-import.max_xml_file_size')],
'behavior' => ['required', 'string', 'in:overwrite']
'behavior' => ['required', 'integer', 'in:' . implode(',', MALImportBehavior::getValues())]
];
}
}
69 changes: 53 additions & 16 deletions app/Jobs/ProcessMALImport.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

namespace App\Jobs;

use App\Enums\MALImportBehavior;
use App\Models\Anime;
use App\Enums\UserLibraryStatus;
use App\Models\AnimeRating;
use App\Models\UserLibrary;
use App\Notifications\MALImportFinished;
use App\Models\User;
use Illuminate\Bus\Queueable;
Expand Down Expand Up @@ -40,9 +43,9 @@ class ProcessMALImport implements ShouldQueue
/**
* The behavior of the import action.
*
* @var string
* @var MALImportBehavior
*/
protected string $behavior;
protected MALImportBehavior $behavior;

/**
* The results of the import action.
Expand All @@ -59,9 +62,9 @@ class ProcessMALImport implements ShouldQueue
*
* @param User $user
* @param string $xmlContent
* @param string $behavior
* @param MALImportBehavior $behavior
*/
public function __construct(User $user, string $xmlContent, string $behavior)
public function __construct(User $user, string $xmlContent, MALImportBehavior $behavior)
{
$this->user = $user;
$this->xmlContent = $xmlContent;
Expand All @@ -74,8 +77,9 @@ public function __construct(User $user, string $xmlContent, string $behavior)
public function handle()
{
// Wipe current library if behavior is set to overwrite
if ($this->behavior === 'overwrite') {
if ($this->behavior->value === MALImportBehavior::Overwrite) {
$this->user->library()->detach();
$this->user->animeRating()->delete();
}

// Create XML object
Expand All @@ -87,7 +91,7 @@ public function handle()

// Loop through the anime in the export file
foreach($json['anime'] as $anime) {
$this->handleXMLFileAnime($anime['series_animedb_id'], $anime['my_status']);
$this->handleXMLFileAnime($anime['series_animedb_id'], $anime['my_status'], $anime['my_score']);
}

// Notify the user that the MAL import was finished
Expand All @@ -99,16 +103,18 @@ public function handle()
*
* @param int $malID
* @param string $malStatus
* @param int $malRating
*/
protected function handleXMLFileAnime(int $malID, string $malStatus)
protected function handleXMLFileAnime(int $malID, string $malStatus, int $malRating)
{
// Try to find the Anime in our DB
$animeMatch = Anime::where('mal_id', $malID)->first();
$anime = Anime::firstWhere('mal_id', $malID);

// If a match was found
if ($animeMatch) {
// Convert the MAL status to one of our own
if (!empty($anime)) {
// Convert the MAL data to our own
$status = $this->convertMALStatus($malStatus);
$rating = $this->convertMALRating($malRating);

// Status not found
if ($status === null) {
Expand All @@ -117,11 +123,25 @@ protected function handleXMLFileAnime(int $malID, string $malStatus)
}

// Add the anime to their library
$this->user->library()->attach($animeMatch, ['status' => $status]);

$this->registerSuccess($animeMatch->id, $malID, $status);
UserLibrary::updateOrCreate([
'user_id' => $this->user->id,
'anime_id' => $anime->id,
], [
'status' => $status
]);

// Updated their anime score
AnimeRating::updateOrCreate([
'user_id' => $this->user->id,
'anime_id' => $anime->id,
], [
'rating' => $rating,
]);

$this->registerSuccess($anime->id, $malID, $status, $rating);
} else {
$this->registerFailure($malID, 'MAL ID could not be found.');
}
else $this->registerFailure($malID, 'MAL ID could not be found.');
}

/**
Expand All @@ -142,19 +162,36 @@ protected function convertMALStatus(string $malStatus): ?int
};
}

/**
* Converts and returns Kurozora specific rating.
*
* @param int $malRating
* @return int
*/
protected function convertMALRating(int $malRating): int
{
if ($malRating == 0) {
return $malRating;
}

return round($malRating) * 0.5;
}

/**
* Registers a success in the import process.
*
* @param int $animeID
* @param int $malID
* @param string $status
* @param int $rating
*/
protected function registerSuccess(int $animeID, int $malID, string $status)
protected function registerSuccess(int $animeID, int $malID, string $status, int $rating)
{
$this->results['successful'][] = [
'anime_id' => $animeID,
'mal_id' => $malID,
'status' => $status
'status' => $status,
'rating' => $rating,
];
}

Expand Down
10 changes: 10 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@ class User extends Authenticatable implements HasMedia, MustVerifyEmail, Reacter
*/
protected string $profileImageCollectionName = 'profile';

/**
* Returns the anime ratings the user has.
*
* @return HasMany
*/
public function animeRating(): HasMany
{
return $this->hasMany(AnimeRating::class);
}

/**
* Returns the associated feed messages for the user.
*
Expand Down
11 changes: 6 additions & 5 deletions app/Notifications/MALImportFinished.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Notifications;

use App\Enums\MALImportBehavior;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
Expand All @@ -23,17 +24,17 @@ class MALImportFinished extends Notification implements ShouldQueue
/**
* The behavior used when importing.
*
* @var string $behavior
* @var MALImportBehavior $behavior
*/
private string $behavior;
private MALImportBehavior $behavior;

/**
* Create a new notification instance.
*
* @param array $results
* @param string $behavior
* @param MALImportBehavior $behavior
*/
public function __construct(array $results, string $behavior)
public function __construct(array $results, MALImportBehavior $behavior)
{
$this->results = $results;
$this->behavior = $behavior;
Expand Down Expand Up @@ -61,7 +62,7 @@ public function toDatabase(mixed $notifiable): array
return [
'successful_count' => count($this->results['successful']),
'failure_count' => count($this->results['failure']),
'behavior' => $this->behavior
'behavior' => $this->behavior->description
];
}

Expand Down
2 changes: 1 addition & 1 deletion config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
| or any other location as required by the application or its packages.
*/

'version' => '1.2.0-alpha.89',
'version' => '1.2.0-alpha.91',

/*
|--------------------------------------------------------------------------
Expand Down
8 changes: 4 additions & 4 deletions config/mal-import.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
| This option controls the cooldown in days for users between importing
| a MAL export file.
|
| Default: 7
| Default: 3
|
*/

'cooldown_in_days' => 7,
'cooldown_in_days' => 3,

/*
|--------------------------------------------------------------------------
Expand All @@ -24,10 +24,10 @@
| This option controls the maximum allowed file size for a MAL export file
| in kilobytes.
|
| Default: 5000
| Default: 10000
|
*/

'max_xml_file_size' => 5000
'max_xml_file_size' => 10000

];
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ public function up()
});

Schema::table(AnimeRating::TABLE_NAME, function(Blueprint $table) {
// Set unique key constraints
$table->unique(['anime_id', 'user_id']);

// Set foreign key constraints
$table->foreign('anime_id')->references('id')->on(Anime::TABLE_NAME)->onDelete('cascade');
$table->foreign('user_id')->references('id')->on(User::TABLE_NAME)->onDelete('cascade');
Expand Down
9 changes: 5 additions & 4 deletions public/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3491,12 +3491,13 @@
"description": "The lock status used to lock or unlock a thread.\n- 0 = unlock\n- 1 = lock"
},
"MALImportBehavior": {
"type": "string",
"type": "integer",
"enum": [
"overwrite"
0,
1
],
"default": "overwrite",
"description": "The set of available MAL import behavior types."
"default": 1,
"description": "The set of available MAL import behavior types.\n- 0 = overwrite\n- 1 = merge"
},
"NotificationReadStatus": {
"type": "integer",
Expand Down
Loading

0 comments on commit 54658d1

Please sign in to comment.