Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 8 additions & 32 deletions frontend/src/components/SongTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,6 @@ const SortableRow = ({ track, id, index, isDraggable }: SortableRowProps) => {
zIndex: isDragging ? 1 : 0,
};

// Mock data
const trackData = {
tempo: track.tempo || Math.floor(Math.random() * 30) + 110,
key:
track.key ||
["5A", "6A", "7A", "8A", "9A", "10A", "11B", "12B"][
Math.floor(Math.random() * 8)
],
loudness: track.loudness || (Math.random() * 0.9 + 0.1).toFixed(3),
energy: track.energy || Math.floor(Math.random() * 40) + 60,
};

return (
<Box
ref={setNodeRef}
Expand Down Expand Up @@ -126,25 +114,25 @@ const SortableRow = ({ track, id, index, isDraggable }: SortableRowProps) => {

<Box sx={{ width: 60, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.tempo}
{track.tempo}
</Typography>
</Box>

<Box sx={{ width: 60, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.key}
{track.key}
</Typography>
</Box>

<Box sx={{ width: 90, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.loudness}
{track.loudness}
</Typography>
</Box>

<Box sx={{ width: 60, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.energy}
{track.energy}
</Typography>
</Box>

Expand All @@ -159,18 +147,6 @@ const SortableRow = ({ track, id, index, isDraggable }: SortableRowProps) => {

// Non-sortable row for when dragging is disabled
const StaticRow = ({ track, index }: { track: NextTrack; index: number }) => {
// Mock data for additional columns
const trackData = {
tempo: track.tempo || Math.floor(Math.random() * 30) + 110,
key:
track.key ||
["5A", "6A", "7A", "8A", "9A", "10A", "11B", "12B"][
Math.floor(Math.random() * 8)
],
loudness: track.loudness || (Math.random() * 0.9 + 0.1).toFixed(3),
energy: track.energy || Math.floor(Math.random() * 40) + 60,
};

return (
<Box
sx={{
Expand Down Expand Up @@ -221,25 +197,25 @@ const StaticRow = ({ track, index }: { track: NextTrack; index: number }) => {

<Box sx={{ width: 60, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.tempo}
{track.tempo}
</Typography>
</Box>

<Box sx={{ width: 60, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.key}
{track.key}
</Typography>
</Box>

<Box sx={{ width: 90, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.loudness}
{track.loudness}
</Typography>
</Box>

<Box sx={{ width: 60, textAlign: "center" }}>
<Typography variant="body2" sx={{ color: "#aaa" }}>
{trackData.energy}
{track.energy}
</Typography>
</Box>

Expand Down
7 changes: 7 additions & 0 deletions frontend/src/models/next-track.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@ export interface NextTrack {
key?: string;
loudness?: string;
energy?: number;
danceability?: number;
mode?: string;
speechiness?: number;
acousticness?: number;
instrumentalness?: number;
liveness?: number;
valence?: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.nexttrack.spring_boot_app.Services;

import com.nexttrack.spring_boot_app.model.NextTrackAudioFeatures;
import com.nexttrack.spring_boot_app.repository.NextTrackAudioFeaturesRepo;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Optional;

@Service
public class NextTrackAudioFeaturesService {

private final NextTrackAudioFeaturesRepo nextTrackAudioFeaturesRepo;

public NextTrackAudioFeaturesService(NextTrackAudioFeaturesRepo nextTrackAudioFeaturesRepo) {
this.nextTrackAudioFeaturesRepo = nextTrackAudioFeaturesRepo;
}

public NextTrackAudioFeatures findOrCreateTrack(String name, String artist) {

var track = nextTrackAudioFeaturesRepo.findByNameAndArtist(name, artist);

// TODO: Make call to audio feature extraction
return track.orElse(new NextTrackAudioFeatures());

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ public ReshuffleService() {
.build();
}

public List<Map<String, String>> reshuffle(String email, Map<String, NextTrack> songInfoMap) {
public List<NextTrack> reshuffle(String email, Map<String, NextTrack> songInfoMap) {
try {
List<Map<String, String>> songDetailsList = new ArrayList<>();
List<NextTrack> songDetailsList = new ArrayList<>();

extractSongDetailsList(songInfoMap, songDetailsList);

Expand All @@ -42,7 +42,7 @@ public List<Map<String, String>> reshuffle(String email, Map<String, NextTrack>
.uri("/shuffle")
.bodyValue(request)
.retrieve()
.bodyToMono(new ParameterizedTypeReference<List<Map<String, String>>>() {
.bodyToMono(new ParameterizedTypeReference<List<NextTrack>>() {
})
.block();
} catch (Exception e) {
Expand All @@ -57,7 +57,8 @@ public List<Map<String, String>> saveReshuffleFeedback(String email, List<Playli
FeedbackRequest feedbackRequest = new FeedbackRequest(email, feedbackTracks);

// Log the payload being sent (for debugging purposes)
System.out.println("Sending payload: " + new ObjectMapper().writeValueAsString(feedbackRequest));
// System.out.println("Sending payload: " + new
// ObjectMapper().writeValueAsString(feedbackRequest));

// Send the POST request with the payload
return webClient.post()
Expand All @@ -73,20 +74,9 @@ public List<Map<String, String>> saveReshuffleFeedback(String email, List<Playli
}
}

private void extractSongDetailsList(Map<String, NextTrack> songInfoMap, List<Map<String, String>> songDetailsList) {
for (String key : songInfoMap.keySet()) {
String[] parts = key.split(" - ", 2);

if (parts.length == 2) {
String songName = parts[0];
String artistName = parts[1];

Map<String, String> songMap = new HashMap<>();
songMap.put("name", songName);
songMap.put("artist", artistName);

songDetailsList.add(songMap);
}
private void extractSongDetailsList(Map<String, NextTrack> songInfoMap, List<NextTrack> songDetailsList) {
for (NextTrack track : songInfoMap.values()) {
songDetailsList.add(track);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.nexttrack.spring_boot_app.Services.NextTrackAudioFeaturesService;
import com.nexttrack.spring_boot_app.Services.ReshuffleService;
import com.nexttrack.spring_boot_app.Services.SpotifyService;
import com.nexttrack.spring_boot_app.Services.UserService;
import com.nexttrack.spring_boot_app.model.NextTrack;
import com.nexttrack.spring_boot_app.model.NextTrackAudioFeatures;
import com.nexttrack.spring_boot_app.model.PlaylistFeedback;
import com.nexttrack.spring_boot_app.requests.FeedbackRequest;
import com.nexttrack.spring_boot_app.requests.PlaylistReshuffleRequest;
Expand All @@ -24,6 +26,7 @@
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.data.mongodb.core.aggregation.ComparisonOperators.Ne;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand All @@ -36,12 +39,15 @@ public class PlaylistController {
private SpotifyService spotifyService;
private ReshuffleService reshuffleService;
private UserService userService;
private NextTrackAudioFeaturesService nextTrackAudioFeaturesService;

public PlaylistController(SpotifyService spotifyService, ReshuffleService reshuffleService,
UserService userService) {
UserService userService,
NextTrackAudioFeaturesService nextTrackAudioFeaturesService) {
this.spotifyService = spotifyService;
this.reshuffleService = reshuffleService;
this.userService = userService;
this.nextTrackAudioFeaturesService = nextTrackAudioFeaturesService;
}

@GetMapping("playlists/all")
Expand Down Expand Up @@ -100,8 +106,23 @@ public List<NextTrack> getPlaylist(@PathVariable String playlistId) {
if (full.getAlbum() != null && full.getAlbum().getImages().length > 0) {
albumCover = full.getAlbum().getImages()[0].getUrl();
}

return new NextTrack(id, name, artistNames, uri, albumCover, durationMs);
var track = new NextTrack(id, name, artistNames, uri, albumCover, durationMs);
NextTrackAudioFeatures audioFeatures = nextTrackAudioFeaturesService.findOrCreateTrack(name,
artistNames.get(0));

track.setDanceability(audioFeatures.getDanceability());
track.setEnergy(audioFeatures.getEnergy());
track.setKey(audioFeatures.getKey());
track.setLoudness(audioFeatures.getLoudness());
track.setMode(audioFeatures.getMode());
track.setSpeechiness(audioFeatures.getSpeechiness());
track.setAcousticness(audioFeatures.getAcousticness());
track.setInstrumentalness(audioFeatures.getInstrumentalness());
track.setLiveness(audioFeatures.getLiveness());
track.setValence(audioFeatures.getValence());
track.setTempo(audioFeatures.getTempo());

return track;

}).filter(Objects::nonNull).collect(Collectors.toList());
}
Expand All @@ -114,22 +135,9 @@ public List<NextTrack> reshuffle(@RequestBody PlaylistReshuffleRequest reshuffle

generateSongInfoMap(tracks, songInfoMap);
// Use the reshuffle service to process the list
List<Map<String, String>> result = reshuffleService.reshuffle(email, songInfoMap);
List<NextTrack> reshuffledTracks = new ArrayList<>();
for (Map<String, String> entry : result) {
String name = entry.get("name");
String artist = entry.get("artist");
String key = name + " - " + artist;

NextTrack track = songInfoMap.get(key);
if (track != null) {
reshuffledTracks.add(track);
} else {
System.err.println("Track not found for key: " + key);
}
}
List<NextTrack> result = reshuffleService.reshuffle(email, songInfoMap);

return reshuffledTracks;
return result;
}

@PostMapping("playlist/save")
Expand Down Expand Up @@ -159,7 +167,7 @@ public String reshuffle(@RequestBody PlaylistSaveRequest payload) {

@PostMapping("playlist/feedback")
public List<Map<String, String>> feedback(@RequestBody FeedbackRequest payload) {
return reshuffleService.saveReshuffleFeedback(payload.getEmail(), payload.getFeedbackTracks());
return reshuffleService.saveReshuffleFeedback(payload.getEmail(), payload.getFeedbackTracks());
}

private void generateSongInfoMap(List<NextTrack> tracks, Map<String, NextTrack> songInfoMap) {
Expand All @@ -168,6 +176,7 @@ private void generateSongInfoMap(List<NextTrack> tracks, Map<String, NextTrack>
List<String> artists = track.getArtists();
if (artists != null && !artists.isEmpty()) {
String key = name + " - " + artists.get(0); // Only use first artist for key

songInfoMap.put(key, track);
}
}
Expand Down
Loading