-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Update gradle-wrapper version * Update dependencies versions * Update the method name that creates the YouTube client * Add "content details" part constant * Add method to TokenService to get access token from the `authorizedClientService` * Add a service-layer method to retrieve data for videos * Add controller to load video data by ids and update service layer * Add JPA and Docker Compose dependencies * Add docker compose & set necessary properties inside application.yml * Update uri for VideoController to load data by video ids * Create a basic flow to add watch later data in DB * Remove commented out line * Update how env variables are set in compose file * Remove commented out code in application.yml * Update `getVideoData` method to iteratively get video data YouTube API does not allow getting more than 50 videos at once, so we need to iteratively request data if the provided list with ids has more than 50 items. * Update method name * Remove hibernate.ddl-auto property in config * Bump spring version to 3.3.3 * Implement token caching * Move mapper into `dto` package * Move YouTube-related services into a separate package * Replace an explicit constructor call with @requiredargsconstructor annotation * Add @transactional to `importCsv` method * PR fixes
- Loading branch information
Showing
26 changed files
with
303 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
services: | ||
postgres-db: | ||
image: 'postgres:latest' | ||
environment: | ||
- POSTGRES_DB=ypm-db | ||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD} | ||
- POSTGRES_USER=${POSTGRES_USERNAME} | ||
ports: | ||
- '5432:5432' | ||
volumes: | ||
- ypm-db:/var/lib/postgresql/data | ||
|
||
volumes: | ||
ypm-db: |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
src/main/java/com/ypm/controller/LibraryImportController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.ypm.controller; | ||
|
||
import com.ypm.persistence.entity.VideoImport; | ||
import com.ypm.service.youtube.ImportService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import java.io.IOException; | ||
import java.util.List; | ||
|
||
@RestController | ||
@RequestMapping("/import") | ||
@RequiredArgsConstructor | ||
public class LibraryImportController { | ||
|
||
private final ImportService importService; | ||
|
||
@PostMapping("/watch-later") | ||
public ResponseEntity<String> importWatchLaterLibrary(@RequestParam("file") MultipartFile file) throws IOException { | ||
if (file.isEmpty()) { | ||
return ResponseEntity.badRequest().build(); | ||
} | ||
|
||
List<VideoImport> savedVideos; | ||
savedVideos = importService.importCsv(file); | ||
|
||
var responseBody = String.format("Saved %s videos", savedVideos.size()); | ||
return ResponseEntity.ok().body(responseBody); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package com.ypm.dto; | ||
|
||
import java.util.List; | ||
|
||
public record VideoDto( | ||
String id, | ||
String title, | ||
String description, | ||
List<String> tags, | ||
String channelName) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.ypm.dto.mapper; | ||
|
||
import com.google.api.services.youtube.model.Video; | ||
import com.ypm.dto.VideoDto; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
public class VideoMapper { | ||
|
||
public static List<VideoDto> mapToVideoDto(List<Video> videos) { | ||
return videos.stream() | ||
.map(video -> { | ||
var snippet = video.getSnippet(); | ||
return new VideoDto( | ||
video.getId(), | ||
snippet.getTitle(), | ||
snippet.getDescription(), | ||
snippet.getTags(), | ||
snippet.getChannelTitle() | ||
); | ||
}) | ||
.collect(Collectors.toList()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.ypm.persistence.entity; | ||
|
||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.Id; | ||
import lombok.Data; | ||
import lombok.NoArgsConstructor; | ||
|
||
import java.time.OffsetDateTime; | ||
|
||
@Entity | ||
@Data | ||
@NoArgsConstructor | ||
public class VideoImport { | ||
|
||
@Id | ||
private String videoId; | ||
|
||
@Column(name = "creation_timestamp") | ||
private OffsetDateTime dateAdded; | ||
|
||
public VideoImport(String videoId, String videoTimeStamp) { | ||
this.videoId = videoId; | ||
this.dateAdded = OffsetDateTime.parse(videoTimeStamp); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
src/main/java/com/ypm/persistence/repository/VideoRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.ypm.persistence.repository; | ||
|
||
import com.ypm.persistence.entity.VideoImport; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
@Repository | ||
public interface VideoRepository extends JpaRepository<VideoImport, Long> { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,45 @@ | ||
package com.ypm.service; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.security.core.context.SecurityContextHolder; | ||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; | ||
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; | ||
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.time.Instant; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class TokenService { | ||
|
||
private final OAuth2AuthorizedClientService authorizedClientService; | ||
|
||
private String cachedToken; | ||
private Instant expiresAt; | ||
|
||
public String getToken(OAuth2AuthorizedClient authClient) { | ||
return authClient.getAccessToken().getTokenValue(); | ||
} | ||
|
||
public String getToken() { | ||
if (isTokenExpired()) refreshToken(); | ||
|
||
return cachedToken; | ||
} | ||
|
||
private boolean isTokenExpired() { | ||
return cachedToken == null || Instant.now().isAfter(expiresAt); | ||
} | ||
|
||
private void refreshToken() { | ||
var oauthToken = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); | ||
var clientRegistrationId = oauthToken.getAuthorizedClientRegistrationId(); | ||
var principalName = oauthToken.getPrincipal().getName(); | ||
var client = authorizedClientService.loadAuthorizedClient(clientRegistrationId, principalName); | ||
|
||
var accessToken = client.getAccessToken(); | ||
cachedToken = accessToken.getTokenValue(); | ||
expiresAt = accessToken.getExpiresAt(); | ||
} | ||
} |
Oops, something went wrong.