diff --git a/src/main/java/com/backend/extractor/kodik/service/anyame_backend/config/CacheConfig.java b/src/main/java/com/backend/extractor/kodik/service/anyame_backend/config/CacheConfig.java new file mode 100644 index 0000000..8ecd0ba --- /dev/null +++ b/src/main/java/com/backend/extractor/kodik/service/anyame_backend/config/CacheConfig.java @@ -0,0 +1,20 @@ +package com.backend.extractor.kodik.service.anyame_backend.config; + +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CacheConfig { + + @Bean + public CacheManager cacheManager() { + return new ConcurrentMapCacheManager( + "kodikIDPlayerLink", + "shikimoriIDPlayerLink", + "kinopoiskIDPlayerLink", + "imdbIDPlayerLink"); + } + +} diff --git a/src/main/java/com/backend/extractor/kodik/service/anyame_backend/controller/MetadataController.java b/src/main/java/com/backend/extractor/kodik/service/anyame_backend/controller/MetadataController.java index 54b126f..4979306 100644 --- a/src/main/java/com/backend/extractor/kodik/service/anyame_backend/controller/MetadataController.java +++ b/src/main/java/com/backend/extractor/kodik/service/anyame_backend/controller/MetadataController.java @@ -11,66 +11,70 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.server.ResponseStatusException; -import com.backend.extractor.kodik.service.anyame_backend.api.KodikPlayerAPI; -import com.backend.extractor.kodik.service.anyame_backend.api.model.KodikPlayerResponse; -import com.backend.extractor.kodik.service.anyame_backend.component.KodikAPITokenProvider; import com.backend.extractor.kodik.service.anyame_backend.exception.KodikExtractionException; import com.backend.extractor.kodik.service.anyame_backend.service.KodikExtractService; +import com.backend.extractor.kodik.service.anyame_backend.service.KodikPlayerLinkResolveService; import com.backend.extractor.kodik.service.anyame_backend.service.model.KodikMetadata; -import retrofit2.Response; - @RestController @RequestMapping("/metadata") public class MetadataController { Logger logger = LoggerFactory.getLogger(MetadataController.class); - private final KodikPlayerAPI kodikPlayerAPI; - private final KodikAPITokenProvider tokenProvider; private final KodikExtractService extractService; + private final KodikPlayerLinkResolveService linkResolveService; - public MetadataController( - KodikPlayerAPI kodikPlayerAPI, - KodikAPITokenProvider tokenProvider, KodikExtractService extractService) { - this.kodikPlayerAPI = kodikPlayerAPI; - this.tokenProvider = tokenProvider; + public MetadataController(KodikExtractService extractService, KodikPlayerLinkResolveService linkResolveService) { this.extractService = extractService; + this.linkResolveService = linkResolveService; } @GetMapping("/shikimori") public KodikMetadata shikimori(@RequestParam("id") String shikimoriId) { - try { - Response response = kodikPlayerAPI - .getShikimoriPlayer(shikimoriId, tokenProvider.getKodikToken()).execute(); - if (!response.isSuccessful()) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "cannot find player, check id validity"); - } - KodikPlayerResponse responseResult = response.body(); - String url = responseResult.getLink(); + return findMetadata(() -> { + String url = linkResolveService.resolveShikimoriLink(shikimoriId); return extractService.getMetadata(url); - } catch (KodikExtractionException e) { - logger.error("cannot retrieve metadata", e); - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "cannot retrieve metadata", e); - } catch (IOException e) { - throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "i/o error"); - } + }); } @GetMapping("/kodik") public KodikMetadata kodik(@RequestParam("id") String kodikId) { - try { - Response response = kodikPlayerAPI - .getKodikIDPlayer(kodikId, tokenProvider.getKodikToken()).execute(); - if (!response.isSuccessful()) { - throw new ResponseStatusException(HttpStatus.NOT_FOUND, "cannot find player, check id validity"); - } - KodikPlayerResponse responseResult = response.body(); - String url = responseResult.getLink(); + return findMetadata(() -> { + String url = linkResolveService.resolveKodikLink(kodikId); return extractService.getMetadata(url); + }); + } + + @GetMapping("/kinopoisk") + public KodikMetadata kinopoisk(@RequestParam("id") String kinopoiskId) { + return findMetadata(() -> { + String url = linkResolveService.resolveKinopoiskLink(kinopoiskId); + return extractService.getMetadata(url); + }); + } + + @GetMapping("/imdb") + public KodikMetadata imdb(@RequestParam("id") String imdbId) { + return findMetadata(() -> { + String url = linkResolveService.resolveIMDBLink(imdbId); + return extractService.getMetadata(url); + }); + } + + private KodikMetadata findMetadata(SupplierWithException supplier) { + try { + return supplier.get(); } catch (KodikExtractionException e) { logger.error("cannot retrieve metadata", e); throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "cannot retrieve metadata", e); } catch (IOException e) { throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "i/o error"); + } catch (Exception e) { + logger.error("Unknown error", e); + throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "unknown error"); } } + + private static interface SupplierWithException { + T get() throws Exception; + } } diff --git a/src/main/java/com/backend/extractor/kodik/service/anyame_backend/service/KodikPlayerLinkResolveService.java b/src/main/java/com/backend/extractor/kodik/service/anyame_backend/service/KodikPlayerLinkResolveService.java new file mode 100644 index 0000000..d622f57 --- /dev/null +++ b/src/main/java/com/backend/extractor/kodik/service/anyame_backend/service/KodikPlayerLinkResolveService.java @@ -0,0 +1,61 @@ +package com.backend.extractor.kodik.service.anyame_backend.service; + +import java.io.IOException; + +import org.springframework.cache.annotation.Cacheable; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import com.backend.extractor.kodik.service.anyame_backend.api.KodikPlayerAPI; +import com.backend.extractor.kodik.service.anyame_backend.api.model.KodikPlayerResponse; +import com.backend.extractor.kodik.service.anyame_backend.component.KodikAPITokenProvider; + +import retrofit2.Response; + +@Service +public class KodikPlayerLinkResolveService { + private final KodikPlayerAPI kodikPlayerAPI; + private final KodikAPITokenProvider tokenProvider; + + public KodikPlayerLinkResolveService(KodikPlayerAPI kodikPlayerAPI, KodikAPITokenProvider tokenProvider) { + this.kodikPlayerAPI = kodikPlayerAPI; + this.tokenProvider = tokenProvider; + } + + @Cacheable("kodikIDPlayerLink") + public String resolveKodikLink(String kodikID) throws IOException { + Response response = kodikPlayerAPI.getKodikIDPlayer(kodikID, tokenProvider.getKodikToken()) + .execute(); + return retrieveLink(response); + } + + @Cacheable("shikimoriIDPlayerLink") + public String resolveShikimoriLink(String shikimoriID) throws IOException { + Response response = kodikPlayerAPI + .getShikimoriPlayer(shikimoriID, tokenProvider.getKodikToken()).execute(); + return retrieveLink(response); + } + + @Cacheable("kinopoiskIDPlayerLink") + public String resolveKinopoiskLink(String kinopoiskID) throws IOException { + Response response = kodikPlayerAPI + .getKinopoiskPlayer(kinopoiskID, tokenProvider.getKodikToken()).execute(); + return retrieveLink(response); + } + + @Cacheable("imdbIDPlayerLink") + public String resolveIMDBLink(String imdbID) throws IOException { + Response response = kodikPlayerAPI.getIMDBPlayer(imdbID, tokenProvider.getKodikToken()) + .execute(); + return retrieveLink(response); + } + + private String retrieveLink(Response response) { + if (response.isSuccessful()) { + return response.body().getLink(); + } else { + throw new ResponseStatusException(HttpStatus.NOT_FOUND, "cannot find player, check id validity"); + } + } +}