Skip to content

Commit

Permalink
Merge pull request #15 from RomanMager/issue-11
Browse files Browse the repository at this point in the history
Add endpoints for moving videos and playlist title update
  • Loading branch information
leingenm authored Apr 3, 2024
2 parents 450ed52 + 930cc74 commit 0e73d34
Show file tree
Hide file tree
Showing 15 changed files with 601 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;

Expand All @@ -14,6 +15,7 @@ public class SecurityConfiguration {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.authorizeHttpRequests(auth -> auth.anyRequest().authenticated())
.oauth2Login(config -> {
config.defaultSuccessUrl("/auth/success", true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
import com.google.api.services.youtube.YouTube;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import java.io.IOException;
import java.security.GeneralSecurityException;

@Configuration
@Lazy
public class YouTubeClientConfiguration {

@Bean
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/com/ypm/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,24 @@
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {

@GetMapping("/success")
public ModelAndView success() {
ModelAndView modelAndView = new ModelAndView("auth");
modelAndView.addObject("type", "success");
modelAndView.addObject("title", "Login Successful");
modelAndView.addObject("message",
return getModelAndView("success", "Login Success",
"Welcome back! You have successfully logged in.");

return modelAndView;
}

@GetMapping("/error")
public ModelAndView error() {
return getModelAndView("error", "Login Error",
"An error occurred while logging in. Please try again.");
}

private ModelAndView getModelAndView(String type, String title, String message) {
ModelAndView modelAndView = new ModelAndView("auth");
modelAndView.addObject("type", "error");
modelAndView.addObject("title", "Login Error");
modelAndView.addObject("message",
"Sorry, there was an error with your login credentials. Please try again.");
modelAndView.addObject("type", type);
modelAndView.addObject("title", title);
modelAndView.addObject("message", message);

return modelAndView;
}
Expand Down
66 changes: 51 additions & 15 deletions src/main/java/com/ypm/controller/PlayListController.java
Original file line number Diff line number Diff line change
@@ -1,40 +1,76 @@
package com.ypm.controller;

import com.google.api.services.youtube.model.Playlist;
import com.google.api.services.youtube.model.VideoSnippet;
import com.ypm.service.YouTubeService;
import com.google.api.services.youtube.model.PlaylistItem;
import com.google.api.services.youtube.model.PlaylistSnippet;
import com.ypm.service.PlayListService;
import com.ypm.service.VideoService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.List;

@RestController
@RequestMapping("/playlist")
@RequestMapping("/playlists")
@RequiredArgsConstructor
public class PlayListController {
private final YouTubeService youTubeService;

@GetMapping("/list")
private final PlayListService playListService;
private final VideoService videosService;

@GetMapping
public ResponseEntity<List<Playlist>> getPlayLists(
@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authentication) throws IOException {

String accessToken = authentication.getAccessToken().getTokenValue();
return ResponseEntity.ok(youTubeService.getMyPlayLists(accessToken));
String accessToken = authentication
.getAccessToken()
.getTokenValue();

return ResponseEntity.ok(playListService.getPlayLists(accessToken));
}

@GetMapping("/{playlistId}/videos")
public ResponseEntity<List<VideoSnippet>> getVideos(
@GetMapping("/{playlistId}")
public ResponseEntity<List<PlaylistItem>> getPlayListVideos(
@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authentication,
@PathVariable String playlistId) throws IOException {

String accessToken = authentication.getAccessToken().getTokenValue();
return ResponseEntity.ok(youTubeService.getPlayListVideos(accessToken, playlistId));
String accessToken = authentication
.getAccessToken()
.getTokenValue();

return ResponseEntity.ok(videosService.getPlayListVideos(accessToken, playlistId));
}

@PutMapping("/{playlistId}")
public ResponseEntity<Playlist> updatePlayListTitle(
@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authentication,
@PathVariable String playlistId,
@RequestBody PlaylistSnippet dataWithUpdatedTitle) throws IOException {

String accessToken = authentication
.getAccessToken()
.getTokenValue();

String newTitle = dataWithUpdatedTitle.getTitle();
return ResponseEntity.ok(playListService.updatePlayListTitle(accessToken, playlistId, newTitle));
}

@PutMapping("/{playlistId}/{targetPlaylistId}")
public ResponseEntity<List<PlaylistItem>> moveVideos(
@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authentication,
@PathVariable String playlistId,
@PathVariable String targetPlaylistId,
@RequestBody List<String> videosIds) throws IOException {

String accessToken = authentication
.getAccessToken()
.getTokenValue();

return ResponseEntity.ok(videosService.moveVideos(accessToken, playlistId,
targetPlaylistId, videosIds));
}
}
32 changes: 32 additions & 0 deletions src/main/java/com/ypm/controller/VideoController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.ypm.controller;

import com.ypm.service.VideoService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.annotation.RegisteredOAuth2AuthorizedClient;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@RestController
@RequestMapping("/videos")
@RequiredArgsConstructor
public class VideoController {

private final VideoService videosService;

@DeleteMapping("/{videoId}")
public ResponseEntity<?> deleteVideos(
@RegisteredOAuth2AuthorizedClient OAuth2AuthorizedClient authentication,
@PathVariable String videoId) throws IOException {

String accessToken = authentication
.getAccessToken()
.getTokenValue();

videosService.deleteVideo(accessToken, videoId);

return ResponseEntity.noContent().build();
}
}
52 changes: 52 additions & 0 deletions src/main/java/com/ypm/service/PlayListService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.ypm.service;

import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.Playlist;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;

@Service
@RequiredArgsConstructor
public class PlayListService {

private final YouTube youTubeClient;

public List<Playlist> getPlayLists(String accessToken) throws IOException {
return youTubeClient
.playlists()
.list(List.of("snippet"))
.setAccessToken(accessToken)
.setMine(true)
.execute()
.getItems();
}

public Playlist updatePlayListTitle(String accessToken, String playListId,
String newTitle) throws IOException {

Playlist playlistToEdit = getPlayListById(accessToken, playListId);
playlistToEdit.getSnippet().setTitle(newTitle);

return youTubeClient
.playlists()
.update(List.of("snippet"), playlistToEdit)
.setAccessToken(accessToken)
.execute();
}

public Playlist getPlayListById(String accessToken, String playListId) throws IOException {
return youTubeClient
.playlists()
.list(List.of("snippet"))
.setId(List.of(playListId))
.setAccessToken(accessToken)
.execute()
.getItems()
.stream()
.findFirst()
.orElseThrow();
}
}
83 changes: 83 additions & 0 deletions src/main/java/com/ypm/service/VideoService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.ypm.service;

import com.google.api.services.youtube.YouTube;
import com.google.api.services.youtube.model.PlaylistItem;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class VideoService {

private final YouTube youTubeClient;

public List<PlaylistItem> moveVideos(String accessToken,
String playListId,
String targetPlayListId,
List<String> videosIds) throws IOException {

List<PlaylistItem> videosToMove = getVideos(accessToken, videosIds);
List<PlaylistItem> movedVideos = new ArrayList<>(videosIds.size());

for (PlaylistItem video : videosToMove) {
if (isVideoInPlayList(playListId, video)) {
video.getSnippet().setPlaylistId(targetPlayListId);
movedVideos.add(insertVideo(accessToken, video));
deleteVideo(accessToken, video.getId());
}
}

return movedVideos;
}

public List<PlaylistItem> getVideos(String accessToken,
List<String> videosIds) throws IOException {

return youTubeClient
.playlistItems()
.list(List.of("snippet"))
.setId(videosIds)
.setAccessToken(accessToken)
.execute()
.getItems();
}

public PlaylistItem insertVideo(String accessToken, PlaylistItem playlistItem) throws IOException {
return youTubeClient
.playlistItems()
.insert(List.of("snippet"), playlistItem)
.setAccessToken(accessToken)
.execute();
}

public void deleteVideo(String accessToken, String id) throws IOException {
youTubeClient
.playlistItems()
.delete(id)
.setAccessToken(accessToken)
.execute();
}

public List<PlaylistItem> getPlayListVideos(String accessToken,
String playListId) throws IOException {

return youTubeClient
.playlistItems()
.list(List.of("snippet"))
.setPlaylistId(playListId)
.setAccessToken(accessToken)
.execute()
.getItems();
}

private boolean isVideoInPlayList(String playListId, PlaylistItem video) {
return video
.getSnippet()
.getPlaylistId()
.equals(playListId);
}
}
41 changes: 0 additions & 41 deletions src/main/java/com/ypm/service/YouTubeService.java

This file was deleted.

2 changes: 1 addition & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ spring:
client-name: Google
client-id: ${google.application.client-id}
client-secret: ${google.application.client-secret}
scope: profile, email, https://www.googleapis.com/auth/youtube.readonly
scope: profile, email, https://www.googleapis.com/auth/youtube
authorization-grant-type: authorization_code
redirect-uri: http://localhost:8080/login/oauth2/code/google
provider:
Expand Down
Loading

0 comments on commit 0e73d34

Please sign in to comment.