Separate metadata and extraction to controllers
This commit is contained in:
151
pom.xml
151
pom.xml
@ -1,79 +1,86 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<parent>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<parent>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<version>3.5.0</version>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<version>3.5.0</version>
|
||||||
</parent>
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
<groupId>com.backend.extractor.kodik.service</groupId>
|
</parent>
|
||||||
<artifactId>anyame-backend</artifactId>
|
<groupId>com.backend.extractor.kodik.service</groupId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<artifactId>anyame-backend</artifactId>
|
||||||
<name>anyame-backend</name>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<description>Kodik video URL extractor for anyame</description>
|
<name>anyame-backend</name>
|
||||||
<url/>
|
<description>Kodik video URL extractor for anyame</description>
|
||||||
<licenses>
|
<url />
|
||||||
<license/>
|
<licenses>
|
||||||
</licenses>
|
<license />
|
||||||
<developers>
|
</licenses>
|
||||||
<developer/>
|
<developers>
|
||||||
</developers>
|
<developer />
|
||||||
<scm>
|
</developers>
|
||||||
<connection/>
|
<scm>
|
||||||
<developerConnection/>
|
<connection />
|
||||||
<tag/>
|
<developerConnection />
|
||||||
<url/>
|
<tag />
|
||||||
</scm>
|
<url />
|
||||||
<properties>
|
</scm>
|
||||||
<java.version>21</java.version>
|
<properties>
|
||||||
|
<java.version>21</java.version>
|
||||||
|
|
||||||
<retrofit.version>3.0.0</retrofit.version>
|
<retrofit.version>3.0.0</retrofit.version>
|
||||||
<jsoup.version>1.20.1</jsoup.version>
|
<jsoup.version>1.20.1</jsoup.version>
|
||||||
<spring-dotenv.version>4.0.0</spring-dotenv.version>
|
<spring-dotenv.version>4.0.0</spring-dotenv.version>
|
||||||
</properties>
|
<springdoc-openapi-starter.version>2.8.9</springdoc-openapi-starter.version>
|
||||||
<dependencies>
|
</properties>
|
||||||
<dependency>
|
<dependencies>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<dependency>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
</dependency>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.retrofit2</groupId>
|
<groupId>com.squareup.retrofit2</groupId>
|
||||||
<artifactId>retrofit</artifactId>
|
<artifactId>retrofit</artifactId>
|
||||||
<version>${retrofit.version}</version>
|
<version>${retrofit.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.squareup.retrofit2</groupId>
|
<groupId>com.squareup.retrofit2</groupId>
|
||||||
<artifactId>converter-jackson</artifactId>
|
<artifactId>converter-jackson</artifactId>
|
||||||
<version>${retrofit.version}</version>
|
<version>${retrofit.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jsoup</groupId>
|
<groupId>org.jsoup</groupId>
|
||||||
<artifactId>jsoup</artifactId>
|
<artifactId>jsoup</artifactId>
|
||||||
<version>${jsoup.version}</version>
|
<version>${jsoup.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.paulschwarz</groupId>
|
<groupId>me.paulschwarz</groupId>
|
||||||
<artifactId>spring-dotenv</artifactId>
|
<artifactId>spring-dotenv</artifactId>
|
||||||
<version>${spring-dotenv.version}</version>
|
<version>${spring-dotenv.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId>
|
||||||
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
|
<version>${springdoc-openapi-starter.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -2,12 +2,26 @@ package com.backend.extractor.kodik.service.anyame_backend;
|
|||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class AnyameBackendApplication {
|
public class AnyameBackendApplication {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(AnyameBackendApplication.class, args);
|
SpringApplication.run(AnyameBackendApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Research if this is good approach or not?
|
||||||
|
@Bean
|
||||||
|
public WebMvcConfigurer corsConfigurer() {
|
||||||
|
return new WebMvcConfigurer() {
|
||||||
|
@Override
|
||||||
|
public void addCorsMappings(CorsRegistry registry) {
|
||||||
|
registry.addMapping("/**").allowedOrigins("http://localhost:3000");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,74 +4,40 @@ import java.io.IOException;
|
|||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
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.api.model.KodikVideoLinks;
|
import com.backend.extractor.kodik.service.anyame_backend.api.model.KodikVideoLinks;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.component.KodikAPITokenProvider;
|
import com.backend.extractor.kodik.service.anyame_backend.dto.KodikTranslationDTO;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikAPINotFoundException;
|
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikAPINotFoundException;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikDecryptionException;
|
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikDecryptionException;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikExtractionException;
|
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikExtractionException;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikPlayerNotFoundException;
|
import com.backend.extractor.kodik.service.anyame_backend.exception.KodikPlayerNotFoundException;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.service.KodikExtractService;
|
import com.backend.extractor.kodik.service.anyame_backend.service.KodikExtractService;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.service.KodikURLDecoderService;
|
import com.backend.extractor.kodik.service.anyame_backend.service.KodikURLDecoderService;
|
||||||
import com.backend.extractor.kodik.service.anyame_backend.service.model.KodikMetadata;
|
|
||||||
|
|
||||||
import retrofit2.Response;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ExtractController
|
* ExtractController
|
||||||
*/
|
*/
|
||||||
@RestController
|
@RestController
|
||||||
|
@RequestMapping("/extract")
|
||||||
public class ExtractController {
|
public class ExtractController {
|
||||||
|
|
||||||
private final KodikPlayerAPI kodikPlayerAPI;
|
|
||||||
private final KodikAPITokenProvider tokenProvider;
|
|
||||||
private final KodikExtractService extractService;
|
private final KodikExtractService extractService;
|
||||||
private final KodikURLDecoderService decoderService;
|
private final KodikURLDecoderService decoderService;
|
||||||
|
|
||||||
public ExtractController(
|
public ExtractController(
|
||||||
KodikPlayerAPI kodikPlayerAPI,
|
KodikExtractService extractService,
|
||||||
KodikAPITokenProvider tokenProvider, KodikExtractService extractService,
|
|
||||||
KodikURLDecoderService decoderService) {
|
KodikURLDecoderService decoderService) {
|
||||||
this.kodikPlayerAPI = kodikPlayerAPI;
|
|
||||||
this.tokenProvider = tokenProvider;
|
|
||||||
this.extractService = extractService;
|
this.extractService = extractService;
|
||||||
this.decoderService = decoderService;
|
this.decoderService = decoderService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/shikimori")
|
@GetMapping("/video")
|
||||||
public KodikMetadata shikimori(@RequestParam("id") String shikimoriId) {
|
public KodikVideoLinks video(KodikTranslationDTO translationDTO, String quality, int episode) {
|
||||||
try {
|
try {
|
||||||
Response<KodikPlayerResponse> response = kodikPlayerAPI
|
KodikVideoLinks links = extractService.retrieveVideoLinks(translationDTO.buildUrl(quality, episode));
|
||||||
.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 extractService.getMetadata(url);
|
|
||||||
} catch (KodikExtractionException e) {
|
|
||||||
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "cannot retrieve metadat", e);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "i/o error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/shikimori/video")
|
|
||||||
public KodikVideoLinks shikimoriVideo(@RequestParam("id") String shikimoriId) {
|
|
||||||
try {
|
|
||||||
Response<KodikPlayerResponse> 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();
|
|
||||||
KodikVideoLinks links = extractService.retrieveVideoLinks(url);
|
|
||||||
links.decodeLinks(decoderService);
|
links.decodeLinks(decoderService);
|
||||||
return links;
|
return links;
|
||||||
} catch (KodikExtractionException e) {
|
} catch (KodikExtractionException e) {
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
package com.backend.extractor.kodik.service.anyame_backend.controller;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
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.model.KodikMetadata;
|
||||||
|
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/metadata")
|
||||||
|
public class MetadataController {
|
||||||
|
private final KodikPlayerAPI kodikPlayerAPI;
|
||||||
|
private final KodikAPITokenProvider tokenProvider;
|
||||||
|
private final KodikExtractService extractService;
|
||||||
|
|
||||||
|
public MetadataController(
|
||||||
|
KodikPlayerAPI kodikPlayerAPI,
|
||||||
|
KodikAPITokenProvider tokenProvider, KodikExtractService extractService) {
|
||||||
|
this.kodikPlayerAPI = kodikPlayerAPI;
|
||||||
|
this.tokenProvider = tokenProvider;
|
||||||
|
this.extractService = extractService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/shikimori")
|
||||||
|
public KodikMetadata shikimori(@RequestParam("id") String shikimoriId) {
|
||||||
|
try {
|
||||||
|
Response<KodikPlayerResponse> 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 extractService.getMetadata(url);
|
||||||
|
} catch (KodikExtractionException e) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "cannot retrieve metadat", 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<KodikPlayerResponse> 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 extractService.getMetadata(url);
|
||||||
|
} catch (KodikExtractionException e) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "cannot retrieve metadat", e);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "i/o error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.backend.extractor.kodik.service.anyame_backend.dto;
|
||||||
|
|
||||||
|
public class KodikTranslationDTO {
|
||||||
|
|
||||||
|
// TODO: NotBlank and other validation annotations can be added as needed
|
||||||
|
private String mediaType;
|
||||||
|
private String mediaId;
|
||||||
|
private String mediaHash;
|
||||||
|
|
||||||
|
public KodikTranslationDTO(String mediaType, String mediaId, String mediaHash) {
|
||||||
|
this.mediaType = mediaType;
|
||||||
|
this.mediaId = mediaId;
|
||||||
|
this.mediaHash = mediaHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMediaType() {
|
||||||
|
return mediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMediaType(String mediaType) {
|
||||||
|
this.mediaType = mediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMediaId() {
|
||||||
|
return mediaId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMediaId(String mediaId) {
|
||||||
|
this.mediaId = mediaId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMediaHash() {
|
||||||
|
return mediaHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMediaHash(String mediaHash) {
|
||||||
|
this.mediaHash = mediaHash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String buildUrl(String quality, int episodeNumber) {
|
||||||
|
return String.format("https://kodik.info/%s/%s/%s/720p?min_age=16&first_url=false&season=1&episode=%d",
|
||||||
|
mediaType, mediaId, mediaHash, episodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -38,12 +38,6 @@ public class KodikExtractService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public KodikVideoLinks retrieveVideoLinks(KodikTranslation translation, int episode)
|
|
||||||
throws KodikExtractionException, IOException, KodikPlayerNotFoundException, KodikAPINotFoundException {
|
|
||||||
String episodeUrl = translation.buildUrl(episode);
|
|
||||||
return retrieveVideoLinks(episodeUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
public KodikVideoLinks retrieveVideoLinks(String episodeUrl)
|
public KodikVideoLinks retrieveVideoLinks(String episodeUrl)
|
||||||
throws KodikExtractionException, IOException, KodikPlayerNotFoundException, KodikAPINotFoundException {
|
throws KodikExtractionException, IOException, KodikPlayerNotFoundException, KodikAPINotFoundException {
|
||||||
KodikMetadata metadata = getMetadata(episodeUrl);
|
KodikMetadata metadata = getMetadata(episodeUrl);
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
spring.application.name=anyame-backend
|
spring.application.name=anyame-backend
|
||||||
server.error.include-message=always
|
server.error.include-message=always
|
||||||
|
server.port=8081
|
||||||
|
Reference in New Issue
Block a user