Fix details
This commit is contained in:
@@ -2,6 +2,7 @@ package com.backend.unifier.title.mapper;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.mapstruct.AfterMapping;
|
import org.mapstruct.AfterMapping;
|
||||||
@@ -13,7 +14,6 @@ import org.mapstruct.MappingTarget;
|
|||||||
import org.mapstruct.Named;
|
import org.mapstruct.Named;
|
||||||
import org.mapstruct.NullValuePropertyMappingStrategy;
|
import org.mapstruct.NullValuePropertyMappingStrategy;
|
||||||
|
|
||||||
import com.backend.metadata.kodik.api.model.KodikResponse;
|
|
||||||
import com.backend.metadata.kodik.api.model.KodikResponse.Result;
|
import com.backend.metadata.kodik.api.model.KodikResponse.Result;
|
||||||
import com.backend.metadata.shikimori.api.model.Anime;
|
import com.backend.metadata.shikimori.api.model.Anime;
|
||||||
import com.backend.metadata.shikimori.api.model.CharacterRole;
|
import com.backend.metadata.shikimori.api.model.CharacterRole;
|
||||||
@@ -43,22 +43,18 @@ public interface KodikAndShikimoriDetailMapper {
|
|||||||
@Mapping(target = "directors", source = "result.materialData.directors")
|
@Mapping(target = "directors", source = "result.materialData.directors")
|
||||||
@Mapping(target = "related", ignore = true)
|
@Mapping(target = "related", ignore = true)
|
||||||
@Mapping(target = "characters", ignore = true)
|
@Mapping(target = "characters", ignore = true)
|
||||||
ContentDetailEntry toDto(Result result, @Context KodikResponse allKodikResults, @Context Anime anime);
|
ContentDetailEntry toDto(Result result, @Context Anime anime);
|
||||||
|
|
||||||
@AfterMapping
|
@AfterMapping
|
||||||
default void mergeShikimoriAndKodik(@MappingTarget ContentDetailEntry dto,
|
default void mergeShikimoriAndKodik(@MappingTarget ContentDetailEntry dto,
|
||||||
Result result,
|
Result result,
|
||||||
@Context KodikResponse allKodikResults,
|
|
||||||
@Context Anime anime) {
|
@Context Anime anime) {
|
||||||
|
|
||||||
if (allKodikResults != null && allKodikResults.results != null) {
|
if (result.translations != null) {
|
||||||
Map<Integer, TranslationDto> seen = allKodikResults.results.stream()
|
dto.translations = result.translations.stream()
|
||||||
.filter(r -> r.translation != null)
|
.filter(Objects::nonNull)
|
||||||
.collect(Collectors.toMap(
|
.map(t -> new TranslationDto(t.id, t.title, t.type))
|
||||||
r -> r.translation.id,
|
.toList();
|
||||||
r -> new TranslationDto(r.translation.id, r.translation.title, r.translation.type),
|
|
||||||
(a, b) -> a));
|
|
||||||
dto.translations = List.copyOf(seen.values());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anime == null)
|
if (anime == null)
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package com.backend.unifier.title.service;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import com.backend.unifier.title.model.ContentDetailEntry;
|
import com.backend.unifier.title.model.ContentDetailEntry;
|
||||||
import com.backend.unifier.title.model.ContentIdentifier;
|
import com.backend.unifier.title.model.ContentIdentifier;
|
||||||
import com.backend.unifier.title.model.ContentProviderSource;
|
import com.backend.unifier.title.model.ContentProviderSource;
|
||||||
@@ -12,6 +14,8 @@ import jakarta.enterprise.inject.Instance;
|
|||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class GeneralDetailService {
|
public class GeneralDetailService {
|
||||||
|
Logger logger = Logger.getLogger(GeneralDetailService.class);
|
||||||
|
|
||||||
private final IdentifierMaskService maskService;
|
private final IdentifierMaskService maskService;
|
||||||
private final Instance<DetailService> detailServices;
|
private final Instance<DetailService> detailServices;
|
||||||
|
|
||||||
@@ -22,8 +26,10 @@ public class GeneralDetailService {
|
|||||||
|
|
||||||
public Optional<ContentDetailEntry> details(UUID id) {
|
public Optional<ContentDetailEntry> details(UUID id) {
|
||||||
ContentIdentifier realIdentifier = maskService.realIdentifier(id);
|
ContentIdentifier realIdentifier = maskService.realIdentifier(id);
|
||||||
if (realIdentifier == null)
|
if (realIdentifier == null) {
|
||||||
throw new IllegalStateException("content identifier not found for id '" + id + "'");
|
logger.info("content identifier not found for id '" + id + "', returning no details");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
ContentProviderSource source = ContentProviderSource.valueOf(realIdentifier.source());
|
ContentProviderSource source = ContentProviderSource.valueOf(realIdentifier.source());
|
||||||
for (DetailService detailService : detailServices) {
|
for (DetailService detailService : detailServices) {
|
||||||
if (detailService.source() == source)
|
if (detailService.source() == source)
|
||||||
|
|||||||
@@ -11,21 +11,37 @@ import jakarta.enterprise.context.ApplicationScoped;
|
|||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class IdentifierMaskService {
|
public class IdentifierMaskService {
|
||||||
private ValueCommands<String, ContentIdentifier> countCommands;
|
private ValueCommands<String, ContentIdentifier> pointerToIdentifier;
|
||||||
|
private ValueCommands<String, String> identifierToPointer;
|
||||||
|
|
||||||
public IdentifierMaskService(RedisDataSource ds) {
|
public IdentifierMaskService(RedisDataSource ds) {
|
||||||
countCommands = ds.value(ContentIdentifier.class);
|
pointerToIdentifier = ds.value(ContentIdentifier.class);
|
||||||
|
identifierToPointer = ds.value(String.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String reverseKey(String id, ContentProviderSource source) {
|
||||||
|
return "reverse:" + source.name() + ":" + id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID createMask(String id, ContentProviderSource source) {
|
public UUID createMask(String id, ContentProviderSource source) {
|
||||||
|
String rKey = reverseKey(id, source);
|
||||||
|
|
||||||
|
String existingPointer = identifierToPointer.get(rKey);
|
||||||
|
if (existingPointer != null) {
|
||||||
|
return UUID.fromString(existingPointer);
|
||||||
|
}
|
||||||
|
|
||||||
ContentIdentifier contentIdentifier = new ContentIdentifier(source.name(), id);
|
ContentIdentifier contentIdentifier = new ContentIdentifier(source.name(), id);
|
||||||
UUID pointerID = UUID.randomUUID();
|
UUID pointerID = UUID.randomUUID();
|
||||||
countCommands.set(pointerID.toString(), contentIdentifier);
|
|
||||||
|
pointerToIdentifier.set(pointerID.toString(), contentIdentifier);
|
||||||
|
identifierToPointer.set(rKey, pointerID.toString());
|
||||||
|
|
||||||
return pointerID;
|
return pointerID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentIdentifier realIdentifier(UUID id) {
|
public ContentIdentifier realIdentifier(UUID id) {
|
||||||
return countCommands.get(id.toString());
|
return pointerToIdentifier.get(id.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package com.backend.unifier.title.service.kodik;
|
package com.backend.unifier.title.service.kodik;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import org.eclipse.microprofile.rest.client.inject.RestClient;
|
import org.eclipse.microprofile.rest.client.inject.RestClient;
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
import com.backend.metadata.kodik.api.model.KodikResponse;
|
||||||
import com.backend.unifier.title.api.KodikAPI;
|
import com.backend.unifier.title.api.KodikAPI;
|
||||||
import com.backend.unifier.title.api.ShikimoriAPI;
|
import com.backend.unifier.title.api.ShikimoriAPI;
|
||||||
import com.backend.unifier.title.mapper.KodikAndShikimoriDetailMapper;
|
import com.backend.unifier.title.mapper.KodikAndShikimoriDetailMapper;
|
||||||
@@ -15,6 +18,8 @@ import jakarta.enterprise.context.ApplicationScoped;
|
|||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class KodikDetailService implements DetailService {
|
public class KodikDetailService implements DetailService {
|
||||||
|
Logger LOG = Logger.getLogger(KodikDetailService.class);
|
||||||
|
|
||||||
private final KodikAPI kodikAPI;
|
private final KodikAPI kodikAPI;
|
||||||
private final ShikimoriAPI shikimoriAPI;
|
private final ShikimoriAPI shikimoriAPI;
|
||||||
private final KodikAndShikimoriDetailMapper detailMapper;
|
private final KodikAndShikimoriDetailMapper detailMapper;
|
||||||
@@ -33,15 +38,46 @@ public class KodikDetailService implements DetailService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<ContentDetailEntry> details(String id) {
|
public Optional<ContentDetailEntry> details(String id) {
|
||||||
var kodikResponse = kodikAPI.findByKodikId(id);
|
var firstOnlyKodikResponse = kodikAPI.findByKodikId(id);
|
||||||
int totalSize = kodikResponse.total;
|
var firstResult = findFirst(firstOnlyKodikResponse);
|
||||||
if (kodikResponse.results != null)
|
if (firstResult.isEmpty())
|
||||||
totalSize = kodikResponse.results.size();
|
return Optional.empty();
|
||||||
|
var groupedResponse = findAllGrouped(firstResult.get());
|
||||||
|
var firstGroupedResult = findFirst(groupedResponse);
|
||||||
|
if (firstGroupedResult.isEmpty())
|
||||||
|
return Optional.empty();
|
||||||
|
|
||||||
|
var shikimoriResponse = shikimoriAPI.findById(firstGroupedResult.get().shikimoriId);
|
||||||
|
return Optional.ofNullable(detailMapper.toDto(firstGroupedResult.get(), shikimoriResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<KodikResponse.Result> findFirst(KodikResponse response) {
|
||||||
|
int totalSize = response.total;
|
||||||
|
if (response.results != null)
|
||||||
|
totalSize = response.results.size();
|
||||||
if (totalSize <= 0)
|
if (totalSize <= 0)
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
var kodikResult = kodikResponse.results.get(0);
|
if (totalSize > 1)
|
||||||
var shikimoriResponse = shikimoriAPI.findById(kodikResult.shikimoriId);
|
LOG.infof("excess results, {}", response);
|
||||||
return Optional.ofNullable(detailMapper.toDto(kodikResult, kodikResponse, shikimoriResponse));
|
return Optional.ofNullable(response.results.get(0));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private KodikResponse findAllGrouped(KodikResponse.Result firstOnly) {
|
||||||
|
if (firstOnly.shikimoriId != null) {
|
||||||
|
return kodikAPI.findByShikimoriId(firstOnly.shikimoriId);
|
||||||
|
}
|
||||||
|
if (firstOnly.kinopoiskId != null) {
|
||||||
|
return kodikAPI.findByKinopoiskId(firstOnly.kinopoiskId);
|
||||||
|
}
|
||||||
|
if (firstOnly.imdbId != null) {
|
||||||
|
return kodikAPI.findByImdbId(firstOnly.imdbId);
|
||||||
|
}
|
||||||
|
LOG.warnf("cannot form grouped result, {}", firstOnly);
|
||||||
|
KodikResponse result = new KodikResponse();
|
||||||
|
result.total = 1;
|
||||||
|
result.results = List.of(firstOnly);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user