kitsu <-> mal comparison for anime, see #18
This commit is contained in:
parent
06213df29f
commit
510ae24dca
@ -77,21 +77,34 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
|
|
||||||
$data = $this->diffAnimeLists();
|
$data = $this->diffAnimeLists();
|
||||||
|
|
||||||
$this->echoBox("Number of anime items that need to be added to MAL: " . count($data['addToMAL']));
|
|
||||||
|
|
||||||
if ( ! empty($data['addToMAL']))
|
if ( ! empty($data['addToMAL']))
|
||||||
{
|
{
|
||||||
$this->echoBox("Adding missing anime list items to MAL");
|
$count = count($data['addToMAL']);
|
||||||
|
$this->echoBox("Adding {$count} missing anime list items to MAL");
|
||||||
$this->createMALListItems($data['addToMAL'], 'anime');
|
$this->createMALListItems($data['addToMAL'], 'anime');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->echoBox('Number of anime items that need to be added to Kitsu: ' . count($data['addToKitsu']));
|
|
||||||
|
|
||||||
if ( ! empty($data['addToKitsu']))
|
if ( ! empty($data['addToKitsu']))
|
||||||
{
|
{
|
||||||
$this->echoBox("Adding missing anime list items to Kitsu");
|
$count = count($data['addToKitsu']);
|
||||||
|
$this->echoBox("Adding {$count} missing anime list items to Kitsu");
|
||||||
$this->createKitsuListItems($data['addToKitsu'], 'anime');
|
$this->createKitsuListItems($data['addToKitsu'], 'anime');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! empty($data['updateMAL']))
|
||||||
|
{
|
||||||
|
$count = count($data['updateMAL']);
|
||||||
|
$this->echoBox("Updating {$count} outdated MAL anime list items");
|
||||||
|
$this->updateMALListItems($data['updateMAL'], 'anime');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty($data['updateKitsu']))
|
||||||
|
{
|
||||||
|
print_r($data['updateKitsu']);
|
||||||
|
$count = count($data['updateKitsu']);
|
||||||
|
$this->echoBox("Updating {$count} outdated Kitsu anime list items");
|
||||||
|
// $this->updateKitsuListItems($data['updateKitsu'], 'anime');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function syncManga()
|
public function syncManga()
|
||||||
@ -104,21 +117,33 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
|
|
||||||
$data = $this->diffMangaLists();
|
$data = $this->diffMangaLists();
|
||||||
|
|
||||||
$this->echoBox("Number of manga items that need to be added to MAL: " . count($data['addToMAL']));
|
|
||||||
|
|
||||||
if ( ! empty($data['addToMAL']))
|
if ( ! empty($data['addToMAL']))
|
||||||
{
|
{
|
||||||
$this->echoBox("Adding missing manga list items to MAL");
|
$count = count($data['addToMAL']);
|
||||||
|
$this->echoBox("Adding {$count} missing manga list items to MAL");
|
||||||
$this->createMALListItems($data['addToMAL'], 'manga');
|
$this->createMALListItems($data['addToMAL'], 'manga');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->echoBox('Number of manga items that need to be added to Kitsu: ' . count($data['addToKitsu']));
|
|
||||||
|
|
||||||
if ( ! empty($data['addToKitsu']))
|
if ( ! empty($data['addToKitsu']))
|
||||||
{
|
{
|
||||||
$this->echoBox("Adding missing manga list items to Kitsu");
|
$count = count($data['addToKitsu']);
|
||||||
|
$this->echoBox("Adding {$count} missing manga list items to Kitsu");
|
||||||
$this->createKitsuListItems($data['addToKitsu'], 'manga');
|
$this->createKitsuListItems($data['addToKitsu'], 'manga');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! empty($data['updateMAL']))
|
||||||
|
{
|
||||||
|
$count = count($data['updateMAL']);
|
||||||
|
$this->echoBox("Updating {$count} outdated MAL manga list items");
|
||||||
|
$this->updateMALListItems($data['updateMAL'], 'manga');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! empty($data['updateKitsu']))
|
||||||
|
{
|
||||||
|
$count = count($data['updateKitsu']);
|
||||||
|
$this->echoBox("Updating {$count} outdated Kitsu manga list items");
|
||||||
|
$this->updateKitsuListItems($data['updateKitsu'], 'manga');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function filterMappings(array $includes, string $type = 'anime'): array
|
public function filterMappings(array $includes, string $type = 'anime'): array
|
||||||
@ -186,56 +211,19 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function filterKitsuAnimeList()
|
public function filterKitsuList(string $type = 'anime'): array
|
||||||
{
|
{
|
||||||
$data = $this->kitsuModel->getFullAnimeList();
|
$method = "getFull{$type}List";
|
||||||
|
$data = $this->kitsuModel->$method();
|
||||||
$includes = JsonAPI::organizeIncludes($data['included']);
|
$includes = JsonAPI::organizeIncludes($data['included']);
|
||||||
$includes['mappings'] = $this->filterMappings($includes['mappings']);
|
$includes['mappings'] = $this->filterMappings($includes['mappings'], $type);
|
||||||
|
|
||||||
$output = [];
|
$output = [];
|
||||||
|
|
||||||
foreach($data['data'] as $listItem)
|
foreach($data['data'] as $listItem)
|
||||||
{
|
{
|
||||||
$animeId = $listItem['relationships']['anime']['data']['id'];
|
$id = $listItem['relationships'][$type]['data']['id'];
|
||||||
$potentialMappings = $includes['anime'][$animeId]['relationships']['mappings'];
|
$potentialMappings = $includes[$type][$id]['relationships']['mappings'];
|
||||||
$malId = NULL;
|
|
||||||
|
|
||||||
foreach ($potentialMappings as $mappingId)
|
|
||||||
{
|
|
||||||
if (array_key_exists($mappingId, $includes['mappings']))
|
|
||||||
{
|
|
||||||
$malId = $includes['mappings'][$mappingId]['externalId'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip to the next item if there isn't a MAL ID
|
|
||||||
if (is_null($malId))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$output[$listItem['id']] = [
|
|
||||||
'id' => $listItem['id'],
|
|
||||||
'malId' => $malId,
|
|
||||||
'data' => $listItem['attributes'],
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function filterKitsuMangaList()
|
|
||||||
{
|
|
||||||
$data = $this->kitsuModel->getFullMangaList();
|
|
||||||
$includes = JsonAPI::organizeIncludes($data['included']);
|
|
||||||
$includes['mappings'] = $this->filterMappings($includes['mappings'], 'manga');
|
|
||||||
|
|
||||||
$output = [];
|
|
||||||
|
|
||||||
foreach($data['data'] as $listItem)
|
|
||||||
{
|
|
||||||
$mangaId = $listItem['relationships']['manga']['data']['id'];
|
|
||||||
$potentialMappings = $includes['manga'][$mangaId]['relationships']['mappings'];
|
|
||||||
$malId = NULL;
|
$malId = NULL;
|
||||||
|
|
||||||
foreach ($potentialMappings as $mappingId)
|
foreach ($potentialMappings as $mappingId)
|
||||||
@ -264,7 +252,7 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
|
|
||||||
public function diffMangaLists()
|
public function diffMangaLists()
|
||||||
{
|
{
|
||||||
$kitsuList = $this->filterKitsuMangaList();
|
$kitsuList = $this->filterKitsuList('manga');
|
||||||
$malList = $this->formatMALMangaList();
|
$malList = $this->formatMALMangaList();
|
||||||
|
|
||||||
$itemsToAddToMAL = [];
|
$itemsToAddToMAL = [];
|
||||||
@ -308,7 +296,7 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
{
|
{
|
||||||
// Get libraryEntries with media.mappings from Kitsu
|
// Get libraryEntries with media.mappings from Kitsu
|
||||||
// Organize mappings, and ignore entries without mappings
|
// Organize mappings, and ignore entries without mappings
|
||||||
$kitsuList = $this->filterKitsuAnimeList();
|
$kitsuList = $this->filterKitsuList('anime');
|
||||||
|
|
||||||
// Get MAL list data
|
// Get MAL list data
|
||||||
$malList = $this->formatMALAnimeList();
|
$malList = $this->formatMALAnimeList();
|
||||||
@ -337,6 +325,23 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
{
|
{
|
||||||
// Eventually, compare the list entries, and determine which
|
// Eventually, compare the list entries, and determine which
|
||||||
// needs to be updated
|
// needs to be updated
|
||||||
|
$item = $this->compareAnimeListItems($kitsuItem, $malList[$kitsuItem['malId']]);
|
||||||
|
|
||||||
|
if (is_null($item))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('kitsu', $item['updateType']))
|
||||||
|
{
|
||||||
|
$kitsuUpdateItems[] = $item['data'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_array('mal', $item['updateType']))
|
||||||
|
{
|
||||||
|
$malUpdateItems[] = $item['data'];
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -348,15 +353,6 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare each list entry
|
|
||||||
// If a list item exists only on MAL, create it on Kitsu with the existing data from MAL
|
|
||||||
// If a list item exists only on Kitsu, create it on MAL with the existing data from Kitsu
|
|
||||||
// If an item already exists on both APIS:
|
|
||||||
// Compare last updated dates, and use the later one
|
|
||||||
// Otherwise, use rewatch count, then episode progress as critera for selecting the more up
|
|
||||||
// to date entry
|
|
||||||
// Based on the 'newer' entry, update the other api list item
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'addToMAL' => $itemsToAddToMAL,
|
'addToMAL' => $itemsToAddToMAL,
|
||||||
'updateMAL' => $malUpdateItems,
|
'updateMAL' => $malUpdateItems,
|
||||||
@ -365,6 +361,174 @@ class SyncKitsuWithMal extends BaseCommand {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function compareAnimeListItems(array $kitsuItem, array $malItem)
|
||||||
|
{
|
||||||
|
$compareKeys = ['status', 'progress', 'rating', 'reconsuming'];
|
||||||
|
$diff = [];
|
||||||
|
$dateDiff = (new \DateTime($kitsuItem['data']['updatedAt'])) <=> (new \DateTime($malItem['data']['updatedAt']));
|
||||||
|
|
||||||
|
foreach($compareKeys as $key)
|
||||||
|
{
|
||||||
|
$diff[$key] = $kitsuItem['data'][$key] <=> $malItem['data'][$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// No difference? Bail out early
|
||||||
|
$diffValues = array_values($diff);
|
||||||
|
$diffValues = array_unique($diffValues);
|
||||||
|
if (count($diffValues) === 1 && $diffValues[0] === 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$update = [
|
||||||
|
'id' => $kitsuItem['id'],
|
||||||
|
'mal_id' => $kitsuItem['malId'],
|
||||||
|
'data' => []
|
||||||
|
];
|
||||||
|
$return = [
|
||||||
|
'updateType' => []
|
||||||
|
];
|
||||||
|
|
||||||
|
$sameStatus = $diff['status'] === 0;
|
||||||
|
$sameProgress = $diff['progress'] === 0;
|
||||||
|
$sameRating = $diff['rating'] === 0;
|
||||||
|
|
||||||
|
|
||||||
|
// If status is the same, and progress count is different, use greater progress
|
||||||
|
if ($sameStatus && ( ! $sameProgress))
|
||||||
|
{
|
||||||
|
if ($diff['progress'] === 1)
|
||||||
|
{
|
||||||
|
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
||||||
|
$return['updateType'][] = 'mal';
|
||||||
|
}
|
||||||
|
else if($diff['progress'] === -1)
|
||||||
|
{
|
||||||
|
$update['data']['progress'] = $malItem['data']['progress'];
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If status and progress are different, it's a bit more complicated...
|
||||||
|
// But, at least for now, assume newer record is correct
|
||||||
|
if ( ! ($sameStatus || $sameProgress))
|
||||||
|
{
|
||||||
|
if ($dateDiff === 1)
|
||||||
|
{
|
||||||
|
$update['data']['status'] = $kitsuItem['data']['status'];
|
||||||
|
|
||||||
|
if ((int)$kitsuItem['data']['progress'] !== 0)
|
||||||
|
{
|
||||||
|
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$return['updateType'][] = 'mal';
|
||||||
|
}
|
||||||
|
else if($dateDiff === -1)
|
||||||
|
{
|
||||||
|
$update['data']['status'] = $malItem['data']['status'];
|
||||||
|
|
||||||
|
if ((int)$malItem['data']['progress'] !== 0)
|
||||||
|
{
|
||||||
|
$update['data']['progress'] = $kitsuItem['data']['progress'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If rating is different, use the rating from the item most recently updated
|
||||||
|
if ( ! $sameRating)
|
||||||
|
{
|
||||||
|
if ($dateDiff === 1)
|
||||||
|
{
|
||||||
|
$update['data']['rating'] = $kitsuItem['data']['rating'];
|
||||||
|
$return['updateType'][] = 'mal';
|
||||||
|
}
|
||||||
|
else if ($dateDiff === -1)
|
||||||
|
{
|
||||||
|
$update['data']['rating'] = $malItem['data']['rating'];
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If status is different, use the status of the more recently updated item
|
||||||
|
if ( ! $sameStatus)
|
||||||
|
{
|
||||||
|
if ($dateDiff === 1)
|
||||||
|
{
|
||||||
|
$update['data']['status'] = $kitsuItem['data']['status'];
|
||||||
|
$return['updateType'][] = 'mal';
|
||||||
|
}
|
||||||
|
else if ($dateDiff === -1)
|
||||||
|
{
|
||||||
|
$update['data']['status'] = $malItem['data']['status'];
|
||||||
|
$return['updateType'][] = 'kitsu';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$return['meta'] = [
|
||||||
|
'kitsu' => $kitsuItem['data'],
|
||||||
|
'mal' => $malItem['data'],
|
||||||
|
'dateDiff' => $dateDiff,
|
||||||
|
'diff' => $diff,
|
||||||
|
];
|
||||||
|
$return['data'] = $update;
|
||||||
|
$return['updateType'] = array_unique($return['updateType']);
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateKitsuListItems($itemsToUpdate, $type = 'anime')
|
||||||
|
{
|
||||||
|
$requester = new ParallelAPIRequest();
|
||||||
|
foreach($itemsToUpdate as $item)
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->kitsuModel->updateListItem($item));
|
||||||
|
}
|
||||||
|
|
||||||
|
$responses = $requester->makeRequests();
|
||||||
|
|
||||||
|
foreach($responses as $key => $response)
|
||||||
|
{
|
||||||
|
$id = $itemsToUpdate[$key]['id'];
|
||||||
|
if ($response->getStatus() === 200)
|
||||||
|
{
|
||||||
|
$this->echoBox("Successfully updated Kitsu {$type} list item with id: {$id}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
echo $response->getBody();
|
||||||
|
$this->echoBox("Failed to update Kitsu {$type} list item with id: {$id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateMALListItems($itemsToUpdate, $type = 'anime')
|
||||||
|
{
|
||||||
|
$transformer = new ALT();
|
||||||
|
$requester = new ParallelAPIRequest();
|
||||||
|
|
||||||
|
foreach($itemsToUpdate as $item)
|
||||||
|
{
|
||||||
|
$requester->addRequest($this->malModel->updateListItem($item, $type));
|
||||||
|
}
|
||||||
|
|
||||||
|
$responses = $requester->makeRequests();
|
||||||
|
|
||||||
|
foreach($responses as $key => $response)
|
||||||
|
{
|
||||||
|
$id = $itemsToUpdate[$key]['mal_id'];
|
||||||
|
if ($response->getBody() === 'Updated')
|
||||||
|
{
|
||||||
|
$this->echoBox("Successfully updated MAL {$type} list item with id: {$id}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->echoBox("Failed to update MAL {$type} list item with id: {$id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function createKitsuListItems($itemsToAdd, $type = 'anime')
|
public function createKitsuListItems($itemsToAdd, $type = 'anime')
|
||||||
{
|
{
|
||||||
$requester = new ParallelAPIRequest();
|
$requester = new ParallelAPIRequest();
|
||||||
|
Loading…
Reference in New Issue
Block a user