Implement history for uploading local tracks
This commit is contained in:
@ -13,20 +13,24 @@ import org.springframework.web.bind.annotation.PostMapping;
|
|||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.bivashy.backend.composer.dto.importing.TrackProgressDTO;
|
||||||
import com.bivashy.backend.composer.dto.track.AddLocalTrackRequest;
|
import com.bivashy.backend.composer.dto.track.AddLocalTrackRequest;
|
||||||
import com.bivashy.backend.composer.dto.track.PlaylistTrackResponse;
|
import com.bivashy.backend.composer.dto.track.PlaylistTrackResponse;
|
||||||
import com.bivashy.backend.composer.dto.track.TrackBulkReorderRequest;
|
import com.bivashy.backend.composer.dto.track.TrackBulkReorderRequest;
|
||||||
import com.bivashy.backend.composer.dto.track.TrackReorderAfterRequest;
|
|
||||||
import com.bivashy.backend.composer.dto.track.TrackResponse;
|
import com.bivashy.backend.composer.dto.track.TrackResponse;
|
||||||
|
import com.bivashy.backend.composer.model.SourceTypes;
|
||||||
import com.bivashy.backend.composer.model.User;
|
import com.bivashy.backend.composer.model.User;
|
||||||
import com.bivashy.backend.composer.service.TrackService;
|
import com.bivashy.backend.composer.service.TrackService;
|
||||||
|
import com.bivashy.backend.composer.service.importing.RedisProgressService;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
public class TrackController {
|
public class TrackController {
|
||||||
private final TrackService trackService;
|
private final TrackService trackService;
|
||||||
|
private final RedisProgressService redisProgressService;
|
||||||
|
|
||||||
public TrackController(TrackService trackService) {
|
public TrackController(TrackService trackService, RedisProgressService redisProgressService) {
|
||||||
this.trackService = trackService;
|
this.trackService = trackService;
|
||||||
|
this.redisProgressService = redisProgressService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping(path = "/playlist/{playlistId}/track/local", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
@PostMapping(path = "/playlist/{playlistId}/track/local", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
@ -35,6 +39,15 @@ public class TrackController {
|
|||||||
@PathVariable Long playlistId,
|
@PathVariable Long playlistId,
|
||||||
@ModelAttribute AddLocalTrackRequest request) throws IOException {
|
@ModelAttribute AddLocalTrackRequest request) throws IOException {
|
||||||
TrackResponse response = trackService.addLocalTrack(user, playlistId, request);
|
TrackResponse response = trackService.addLocalTrack(user, playlistId, request);
|
||||||
|
redisProgressService.saveProgress(new TrackProgressDTO(playlistId,
|
||||||
|
response.trackId(),
|
||||||
|
response.title(),
|
||||||
|
response.fileFormat(),
|
||||||
|
SourceTypes.FILE,
|
||||||
|
100,
|
||||||
|
"",
|
||||||
|
null,
|
||||||
|
user.getId()));
|
||||||
return ResponseEntity.ok(response);
|
return ResponseEntity.ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -33,15 +33,6 @@ public class ProgressSSEController {
|
|||||||
this.redisSubscriber = redisSubscriber;
|
this.redisSubscriber = redisSubscriber;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/importing/test/{playlistId}")
|
|
||||||
public void test(@PathVariable long playlistId, @AuthenticationPrincipal CustomUserDetails user) {
|
|
||||||
var userId = user.getId();
|
|
||||||
redisProgressService.saveProgress(new TrackProgressDTO(
|
|
||||||
playlistId,
|
|
||||||
"test",
|
|
||||||
userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping(value = "/importing/stream/{playlistId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
@GetMapping(value = "/importing/stream/{playlistId}", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
|
||||||
public Flux<ServerSentEvent<String>> streamProgress(
|
public Flux<ServerSentEvent<String>> streamProgress(
|
||||||
@PathVariable long playlistId,
|
@PathVariable long playlistId,
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
package com.bivashy.backend.composer.dto;
|
|
||||||
|
|
||||||
public enum SourceType {
|
|
||||||
AUDIO("AUDIO"),
|
|
||||||
PLAYLIST("PLAYLIST"),
|
|
||||||
FILE("FILE"),
|
|
||||||
URL("URL");
|
|
||||||
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
SourceType(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SourceType fromValue(String value) {
|
|
||||||
for (SourceType type : values()) {
|
|
||||||
if (type.value.equalsIgnoreCase(value)) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown source type: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -5,7 +5,7 @@ public class ImportTrackKey {
|
|||||||
return String.format("progress:%d:%d", userId, playlistId);
|
return String.format("progress:%d:%d", userId, playlistId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String trackKey(long playlistId, String trackId, long userId) {
|
public static String trackKey(long playlistId, long trackId, long userId) {
|
||||||
return String.format("track:%d:%d:%s", userId, playlistId, trackId);
|
return String.format("track:%d:%d:%s", userId, playlistId, trackId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package com.bivashy.backend.composer.dto.importing;
|
|||||||
|
|
||||||
public class TrackProgressDTO {
|
public class TrackProgressDTO {
|
||||||
private long playlistId;
|
private long playlistId;
|
||||||
private String trackId;
|
private long trackId;
|
||||||
private String trackTitle;
|
private String trackTitle;
|
||||||
private String format;
|
private String format;
|
||||||
private String sourceType;
|
private String sourceType;
|
||||||
@ -14,7 +14,7 @@ public class TrackProgressDTO {
|
|||||||
public TrackProgressDTO() {
|
public TrackProgressDTO() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrackProgressDTO(long playlistId, String trackId, long userId) {
|
public TrackProgressDTO(long playlistId, long trackId, long userId) {
|
||||||
this.playlistId = playlistId;
|
this.playlistId = playlistId;
|
||||||
this.trackId = trackId;
|
this.trackId = trackId;
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
@ -22,7 +22,7 @@ public class TrackProgressDTO {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TrackProgressDTO(long playlistId,
|
public TrackProgressDTO(long playlistId,
|
||||||
String trackId,
|
long trackId,
|
||||||
String trackTitle,
|
String trackTitle,
|
||||||
String format,
|
String format,
|
||||||
String sourceType,
|
String sourceType,
|
||||||
@ -49,11 +49,11 @@ public class TrackProgressDTO {
|
|||||||
this.playlistId = playlistId;
|
this.playlistId = playlistId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTrackId() {
|
public long getTrackId() {
|
||||||
return trackId;
|
return trackId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTrackId(String trackId) {
|
public void setTrackId(long trackId) {
|
||||||
this.trackId = trackId;
|
this.trackId = trackId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ public record TrackResponse(
|
|||||||
String title,
|
String title,
|
||||||
String artist,
|
String artist,
|
||||||
String audioPath,
|
String audioPath,
|
||||||
|
String fileFormat,
|
||||||
Integer durationSeconds,
|
Integer durationSeconds,
|
||||||
String fileName) {
|
String fileName) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,6 +43,7 @@ public class MetadataParseService {
|
|||||||
|
|
||||||
var format = Optional.ofNullable(result.getFormat());
|
var format = Optional.ofNullable(result.getFormat());
|
||||||
|
|
||||||
|
var formatNameOpt = format.map(f -> f.getFormatName());
|
||||||
Optional<Float> formatDuration = format.map(f -> f.getDuration());
|
Optional<Float> formatDuration = format.map(f -> f.getDuration());
|
||||||
List<Optional<Float>> streamDuration = Optional.ofNullable(result.getStreams())
|
List<Optional<Float>> streamDuration = Optional.ofNullable(result.getStreams())
|
||||||
.map(streams -> streams.stream()
|
.map(streams -> streams.stream()
|
||||||
@ -58,12 +59,14 @@ public class MetadataParseService {
|
|||||||
|
|
||||||
var jsonResult = ffprobeObjectMapper.writeValueAsString(result);
|
var jsonResult = ffprobeObjectMapper.writeValueAsString(result);
|
||||||
|
|
||||||
|
var formatName = formatNameOpt.orElse("unknown");
|
||||||
var title = format.map(f -> f.getTag("title")).orElse(null);
|
var title = format.map(f -> f.getTag("title")).orElse(null);
|
||||||
var artist = format.map(f -> f.getTag("artist")).orElse(null);
|
var artist = format.map(f -> f.getTag("artist")).orElse(null);
|
||||||
|
|
||||||
return Optional.of(new Metadata(title, artist, foundDuration.orElse(0f), jsonResult));
|
return Optional.of(new Metadata(title, artist, formatName, foundDuration.orElse(0f), jsonResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static record Metadata(String title, String artist, Float durationSeconds, String rawJson) {
|
public static record Metadata(String title, String artist, String formatName, Float durationSeconds,
|
||||||
|
String rawJson) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,11 +61,17 @@ public class TrackService {
|
|||||||
track, title, fileName, trackSource.getSourceUrl(), artist, null, durationSeconds);
|
track, title, fileName, trackSource.getSourceUrl(), artist, null, durationSeconds);
|
||||||
|
|
||||||
trackPlaylistService.insertTrackAtEnd(playlistId, track.getId());
|
trackPlaylistService.insertTrackAtEnd(playlistId, track.getId());
|
||||||
|
|
||||||
|
String fileFormat = "unknown";
|
||||||
|
if (metadata.isPresent()) {
|
||||||
|
fileFormat = metadata.map(m -> m.formatName()).get();
|
||||||
|
}
|
||||||
return new TrackResponse(
|
return new TrackResponse(
|
||||||
track.getId(),
|
track.getId(),
|
||||||
title,
|
title,
|
||||||
artist,
|
artist,
|
||||||
trackSource.getSourceUrl(),
|
trackSource.getSourceUrl(),
|
||||||
|
fileFormat,
|
||||||
durationSeconds,
|
durationSeconds,
|
||||||
fileName);
|
fileName);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user