open api changes
This commit is contained in:
Generated
+9
@@ -11,6 +11,15 @@
|
|||||||
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar" />
|
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar" />
|
||||||
</processorPath>
|
</processorPath>
|
||||||
<module name="musix" />
|
<module name="musix" />
|
||||||
|
</profile>
|
||||||
|
<profile name="Annotation profile for mpv-client" enabled="true">
|
||||||
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
|
<outputRelativeToContentRoot value="true" />
|
||||||
|
<processorPath useClasspath="false">
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar" />
|
||||||
|
<entry name="$MAVEN_REPOSITORY$/org/projectlombok/lombok/1.18.46/lombok-1.18.46.jar" />
|
||||||
|
</processorPath>
|
||||||
<module name="mpv-client" />
|
<module name="mpv-client" />
|
||||||
</profile>
|
</profile>
|
||||||
</annotationProcessing>
|
</annotationProcessing>
|
||||||
|
|||||||
Generated
-8
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/musix/musix.iml" filepath="$PROJECT_DIR$/musix/musix.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
// Generated using typescript-generator version 4.1.1 on 2026-07-24 16:46:55.
|
// Generated using typescript-generator version 4.1.1 on 2026-07-26 14:02:29.
|
||||||
|
|
||||||
export interface Session {
|
export interface Session {
|
||||||
sessionId: string;
|
sessionId: string;
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export class YoutubeSearchResult implements OnChanges {
|
|||||||
this._album = this.musicRecord.album?.name || 'Album Name';
|
this._album = this.musicRecord.album?.name || 'Album Name';
|
||||||
this._duration = this.musicRecord.duration || '0:00';
|
this._duration = this.musicRecord.duration || '0:00';
|
||||||
this._views = this.musicRecord.views || '0 views';
|
this._views = this.musicRecord.views || '0 views';
|
||||||
this._thumbnailUrl = this.musicRecord.thumbnails?.[1]?.url || this._thumbnailUrl;
|
this._thumbnailUrl = this.musicRecord.thumbnails?.[0]?.url || this._thumbnailUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
<mat-label>Search</mat-label>
|
<mat-label>Search</mat-label>
|
||||||
<input matInput [(ngModel)]="searchQuery" placeholder="Enter search query">
|
<input matInput [(ngModel)]="searchQuery" placeholder="Enter search query">
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<mat-form-field class="filter-field">
|
||||||
|
<mat-label>Filter</mat-label>
|
||||||
|
<mat-select [(ngModel)]="searchFilter">
|
||||||
|
<mat-option *ngFor="let f of filters" [value]="f">{{f}}</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
<button mat-raised-button color="primary" (click)="performSearch()">Search</button>
|
<button mat-raised-button color="primary" (click)="performSearch()">Search</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -11,23 +11,47 @@ import { YoutubeSearchResult } from '../youtube-search-result/youtube-search-res
|
|||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-youtube-search-tab',
|
selector: 'app-youtube-search-tab',
|
||||||
imports: [YoutubeSearchResult, CommonModule, MatFormFieldModule, MatInputModule, MatButtonModule, FormsModule],
|
imports: [
|
||||||
|
YoutubeSearchResult,
|
||||||
|
CommonModule,
|
||||||
|
MatFormFieldModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatSelectModule,
|
||||||
|
MatButtonModule,
|
||||||
|
FormsModule,
|
||||||
|
],
|
||||||
templateUrl: './youtube-search-tab.html',
|
templateUrl: './youtube-search-tab.html',
|
||||||
styleUrl: './youtube-search-tab.css'
|
styleUrl: './youtube-search-tab.css',
|
||||||
})
|
})
|
||||||
export class YoutubeSearchTab {
|
export class YoutubeSearchTab {
|
||||||
private readonly youtubeService = inject(YoutubeControllerService);
|
private readonly youtubeService = inject(YoutubeControllerService);
|
||||||
searchResults: WritableSignal<MusicRecord[]> = signal([]);
|
searchResults: WritableSignal<MusicRecord[]> = signal([]);
|
||||||
searchQuery: string = '';
|
searchQuery: string = '';
|
||||||
|
searchFilter: QueryDto['filter'] = 'SONGS';
|
||||||
|
filters: QueryDto['filter'][] = [
|
||||||
|
'SONGS',
|
||||||
|
'VIDEOS',
|
||||||
|
'ALBUMS',
|
||||||
|
'ARTISTS',
|
||||||
|
'PLAYLISTS',
|
||||||
|
'COMMUNITY_PLAYLISTS',
|
||||||
|
'FEATURED_PLALISTS',
|
||||||
|
'PROFILES',
|
||||||
|
'PODCASTS',
|
||||||
|
'EPISODES',
|
||||||
|
'NONE',
|
||||||
|
];
|
||||||
|
|
||||||
performSearch(): void {
|
performSearch(): void {
|
||||||
const queryDto: QueryDto = {
|
const queryDto: QueryDto = {
|
||||||
queryString: this.searchQuery,
|
queryString: this.searchQuery,
|
||||||
|
filter: this.searchFilter,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.youtubeService.query(queryDto).subscribe({
|
this.youtubeService.query(queryDto).subscribe({
|
||||||
@@ -40,8 +64,5 @@ export class YoutubeSearchTab {
|
|||||||
console.error('Query error:', error);
|
console.error('Query error:', error);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-2
@@ -88,6 +88,11 @@
|
|||||||
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
|
||||||
<version>2.8.5</version>
|
<version>2.8.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-text</artifactId>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -168,12 +173,12 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<repositories>
|
<!--repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>rpi-nexus</id>
|
<id>rpi-nexus</id>
|
||||||
<name>RPI Nexus proxy repository</name>
|
<name>RPI Nexus proxy repository</name>
|
||||||
<url>http://192.168.0.187:7781/repository/maven-central/</url>
|
<url>http://192.168.0.187:7781/repository/maven-central/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
<repositories-->
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -16,7 +16,13 @@ if(args.limit != None):
|
|||||||
limit=args.limit;
|
limit=args.limit;
|
||||||
if(args.filter != None):
|
if(args.filter != None):
|
||||||
filter=args.filter
|
filter=args.filter
|
||||||
|
tries = 1
|
||||||
ytmusic = YTMusic()
|
ytmusic = YTMusic()
|
||||||
search_results = ytmusic.search(args.query, filter=filter, limit = limit)
|
search_results = ytmusic.search(args.query, filter=filter, limit = limit)
|
||||||
|
while(len(search_results)< limit and tries <10):
|
||||||
|
limit = limit*2
|
||||||
|
search_results = ytmusic.search(args.query, filter=filter, limit = limit)
|
||||||
|
tries = tries + 1
|
||||||
|
|
||||||
|
|
||||||
print(search_results)
|
print(search_results)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package zv.musix.controller;
|
package zv.musix.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Description;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
@@ -18,6 +20,12 @@ public class ClientController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ClientService clientService;
|
private ClientService clientService;
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Client registration",
|
||||||
|
description = "End point for MPV clients to register themselves to the server. " +
|
||||||
|
"This is used to send MPV commands (like 'play') to each MPV client" +
|
||||||
|
"The request must contain the host url where the server can reach the MPV client"
|
||||||
|
)
|
||||||
@PostMapping("/register")
|
@PostMapping("/register")
|
||||||
public ResponseEntity<Client> registerClient(@RequestBody ClientRegistrationRequestDto clientRegistrationRequestDto){
|
public ResponseEntity<Client> registerClient(@RequestBody ClientRegistrationRequestDto clientRegistrationRequestDto){
|
||||||
return ResponseEntity.ok(clientService.register(clientRegistrationRequestDto));
|
return ResponseEntity.ok(clientService.register(clientRegistrationRequestDto));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package zv.musix.controller;
|
package zv.musix.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
@@ -9,6 +10,10 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
@RequestMapping(value = "/health", produces = MediaType.APPLICATION_JSON_VALUE)
|
@RequestMapping(value = "/health", produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
public class HealthController {
|
public class HealthController {
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Ping Pong",
|
||||||
|
description = "End point used to check if the server is up and running (mainly for docker compose health check)"
|
||||||
|
)
|
||||||
@GetMapping("/ping")
|
@GetMapping("/ping")
|
||||||
public String ping(){
|
public String ping(){
|
||||||
return "pong";
|
return "pong";
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package zv.musix.controller;
|
package zv.musix.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -17,6 +18,10 @@ public class PlayerController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PlayerService playerService;
|
private PlayerService playerService;
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Play song with id",
|
||||||
|
description = "Searches the music from the cache and if it founds it, sends a request to each MPV client to play the requested music"
|
||||||
|
)
|
||||||
@PostMapping("/play/{id}")
|
@PostMapping("/play/{id}")
|
||||||
public ResponseEntity<String> play(@PathVariable String id){
|
public ResponseEntity<String> play(@PathVariable String id){
|
||||||
playerService.play(id);
|
playerService.play(id);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package zv.musix.controller;
|
package zv.musix.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -16,11 +17,21 @@ public class SessionController {
|
|||||||
private SessionService sessionService;
|
private SessionService sessionService;
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Session information",
|
||||||
|
description = "Returns the current state of the session, includes User data, their queues, " +
|
||||||
|
"The session queue etc etc"
|
||||||
|
)
|
||||||
@GetMapping
|
@GetMapping
|
||||||
public ResponseEntity<Session> getSession(){
|
public ResponseEntity<Session> getSession(){
|
||||||
return ResponseEntity.ok(sessionService.getSession());
|
return ResponseEntity.ok(sessionService.getSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Add music to user's queue",
|
||||||
|
description = "Requires music ID and userName on the Authorization Request Header"
|
||||||
|
|
||||||
|
)
|
||||||
@PostMapping("/music/add/{musicId}")
|
@PostMapping("/music/add/{musicId}")
|
||||||
public ResponseEntity<User> addMusic(@RequestHeader("Authorization") String userName, @PathVariable String musicId){
|
public ResponseEntity<User> addMusic(@RequestHeader("Authorization") String userName, @PathVariable String musicId){
|
||||||
return ResponseEntity.ok(sessionService.addMusicToQueue(userName,musicId));
|
return ResponseEntity.ok(sessionService.addMusicToQueue(userName,musicId));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package zv.musix.controller;
|
package zv.musix.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -17,6 +18,12 @@ public class UserController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
SessionService sessionService;
|
SessionService sessionService;
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Add new User to session",
|
||||||
|
description = "Creates a new user in the session, and returns the user list from the session"
|
||||||
|
|
||||||
|
)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity<List<User>> createUser(@RequestBody CreateUserRequest userRequest) {
|
public ResponseEntity<List<User>> createUser(@RequestBody CreateUserRequest userRequest) {
|
||||||
return ResponseEntity.ok(sessionService.addUser(userRequest));
|
return ResponseEntity.ok(sessionService.addUser(userRequest));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package zv.musix.controller;
|
package zv.musix.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -8,7 +9,6 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import zv.musix.dto.yt.QueryDto;
|
import zv.musix.dto.yt.QueryDto;
|
||||||
import zv.musix.entity.QueryCache;
|
|
||||||
import zv.musix.python.json.MusicRecord;
|
import zv.musix.python.json.MusicRecord;
|
||||||
import zv.musix.service.YtService;
|
import zv.musix.service.YtService;
|
||||||
|
|
||||||
@@ -22,6 +22,14 @@ public class YoutubeController {
|
|||||||
private YtService ytService;
|
private YtService ytService;
|
||||||
|
|
||||||
|
|
||||||
|
@Operation(
|
||||||
|
summary = "Youtube search",
|
||||||
|
description = "Queries youtube based on the given parameters" +
|
||||||
|
"queryString = The string you are searching for" +
|
||||||
|
"filter = the type of result you are looking for, for example songs are things youtube.music would display as a result, videos are default youtube, playlists are playlists etc." +
|
||||||
|
"limit = the number of results to return "
|
||||||
|
|
||||||
|
)
|
||||||
@PostMapping("/query")
|
@PostMapping("/query")
|
||||||
public ResponseEntity<List<MusicRecord>> query(@RequestBody QueryDto queryDto ) {
|
public ResponseEntity<List<MusicRecord>> query(@RequestBody QueryDto queryDto ) {
|
||||||
return ResponseEntity.ok(ytService.query(queryDto));
|
return ResponseEntity.ok(ytService.query(queryDto));
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import zv.musix.enums.YTQueryFilter;
|
|||||||
@Data
|
@Data
|
||||||
public class QueryDto {
|
public class QueryDto {
|
||||||
String queryString;
|
String queryString;
|
||||||
YTQueryFilter filter;
|
|
||||||
Integer limit;
|
Integer limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,10 +23,10 @@ public class QueryCache {
|
|||||||
@TimeToLive
|
@TimeToLive
|
||||||
private Long timeoutInSeconds = 600L;
|
private Long timeoutInSeconds = 600L;
|
||||||
|
|
||||||
public QueryCache(QueryDto dto){
|
public QueryCache(String query, YTQueryFilter filter, Integer limit ){
|
||||||
this.query = dto.getQueryString();
|
this.query = query;
|
||||||
this.filter = dto.getFilter() == null ? YTQueryFilter.SONGS : dto.getFilter();
|
this.filter = filter;
|
||||||
this.limit = dto.getLimit() == null ? 20 : dto.getLimit() ;
|
this.limit = limit == null ? 20 : limit ;
|
||||||
this.id = query.hashCode() + filter.label + limit;
|
this.id = query.hashCode() + filter.label + limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,19 +45,19 @@ public class PythonRunner {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String query_py(QueryDto request){
|
public String query_py(String query, YTQueryFilter filter, Integer limit){
|
||||||
ArrayList<String> args = new ArrayList<>();
|
ArrayList<String> args = new ArrayList<>();
|
||||||
args.add(PYTHON);
|
args.add(PYTHON);
|
||||||
args.add(QUERY_PY);
|
args.add(QUERY_PY);
|
||||||
args.add("--query");
|
args.add("--query");
|
||||||
args.add(request.getQueryString());
|
args.add(query);
|
||||||
if(request.getFilter() != null && request.getFilter() != YTQueryFilter.NONE){
|
if(filter != null && filter != YTQueryFilter.NONE){
|
||||||
args.add("--filter");
|
args.add("--filter");
|
||||||
args.add(request.getFilter().label);
|
args.add(filter.label);
|
||||||
}
|
}
|
||||||
if(request.getLimit() != null) {
|
if(limit != null) {
|
||||||
args.add("--limit");
|
args.add("--limit");
|
||||||
args.add(request.getLimit().toString());
|
args.add(limit.toString());
|
||||||
}
|
}
|
||||||
return runScript(args);
|
return runScript(args);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,12 @@ package zv.musix.service;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import org.apache.commons.text.similarity.JaroWinklerDistance;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import zv.musix.dto.yt.QueryDto;
|
import zv.musix.dto.yt.QueryDto;
|
||||||
import zv.musix.entity.QueryCache;
|
import zv.musix.entity.QueryCache;
|
||||||
|
import zv.musix.enums.YTQueryFilter;
|
||||||
import zv.musix.python.PythonRunner;
|
import zv.musix.python.PythonRunner;
|
||||||
import zv.musix.python.json.MusicRecord;
|
import zv.musix.python.json.MusicRecord;
|
||||||
import zv.musix.repository.MusicRepository;
|
import zv.musix.repository.MusicRepository;
|
||||||
@@ -14,8 +16,11 @@ import com.google.gson.reflect.TypeToken;
|
|||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@@ -30,34 +35,66 @@ public class YtService {
|
|||||||
|
|
||||||
|
|
||||||
public List<MusicRecord> query(QueryDto request){
|
public List<MusicRecord> query(QueryDto request){
|
||||||
|
JaroWinklerDistance jaroWinkler = new JaroWinklerDistance();
|
||||||
|
|
||||||
log.trace("Search query in cache: {}", request);
|
log.trace("Search query in cache: {}", request);
|
||||||
|
|
||||||
QueryCache qc = new QueryCache(request);
|
List<QueryCache> queryCacheList = new ArrayList<>();
|
||||||
|
List<MusicRecord> result = new ArrayList<>();
|
||||||
|
|
||||||
|
queryCacheList.add(performSearch(request.getQueryString(),YTQueryFilter.SONGS, request.getLimit()));
|
||||||
|
//queryCacheList.add(performSearch(request.getQueryString(),YTQueryFilter.VIDEOS, request.getLimit()));
|
||||||
|
//queryCacheList.add(performSearch(request.getQueryString(),YTQueryFilter.NONE, request.getLimit()));
|
||||||
|
|
||||||
|
for (QueryCache qc : queryCacheList){
|
||||||
|
result.addAll(processQueryResult(qc));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(MusicRecord mr : result){
|
||||||
|
System.out.println(jaroWinkler.apply("asd","asd"));
|
||||||
|
log.trace(mr.getTitle() + (jaroWinkler.apply(mr.getTitle() != null ? mr.getTitle().toLowerCase() : "null", request.getQueryString().toLowerCase())));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
/*return result.stream().sorted(Comparator.comparingDouble((MusicRecord m) ->
|
||||||
|
jaroWinkler.apply(m.getTitle() != null ? m.getTitle().toLowerCase() : "null", request.getQueryString().toLowerCase())
|
||||||
|
)).collect(Collectors.toList());*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private QueryCache performSearch(String queryString, YTQueryFilter filter, Integer limit){
|
||||||
|
QueryCache qc = new QueryCache(queryString, filter, limit);
|
||||||
Optional<QueryCache> byQuery = queryCacheRepository.findById(qc.getId());
|
Optional<QueryCache> byQuery = queryCacheRepository.findById(qc.getId());
|
||||||
if(byQuery.isPresent()){
|
if(byQuery.isPresent()){
|
||||||
log.trace("Search query was found in cache");
|
log.trace("Search query was found in cache");
|
||||||
return processQueryResult(byQuery.get());
|
return byQuery.get();
|
||||||
}
|
}
|
||||||
log.trace("Search query was NOT found in cache, running python script");
|
else{
|
||||||
String response = pythonRunner.query_py(request);
|
String response = pythonRunner.query_py(queryString,filter, limit);
|
||||||
if(response.isBlank() || response.isEmpty()){
|
if(response.isBlank()){
|
||||||
throw new RuntimeException();
|
throw new RuntimeException("python response is empty");
|
||||||
}
|
}
|
||||||
qc.setResponse(response);
|
qc.setResponse(response);
|
||||||
|
|
||||||
log.trace("Saving search query: {}",qc);
|
log.trace("Saving search query: {}",qc);
|
||||||
queryCacheRepository.save(qc);
|
return queryCacheRepository.save(qc);
|
||||||
return processQueryResult(qc);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<MusicRecord> processQueryResult(QueryCache queryCache){
|
private List<MusicRecord> processQueryResult(QueryCache queryCache){
|
||||||
Gson gson = new Gson();
|
try{
|
||||||
Type listType = new TypeToken<List<MusicRecord>>(){}.getType();
|
Gson gson = new Gson();
|
||||||
|
Type listType = new TypeToken<List<MusicRecord>>(){}.getType();
|
||||||
|
|
||||||
|
// Map the entire JSON hierarchy to your parent class
|
||||||
|
List<MusicRecord> musicRecordList = gson.fromJson(queryCache.getResponse(), listType);
|
||||||
|
musicRepository.saveAll(musicRecordList);
|
||||||
|
return musicRecordList;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
// Map the entire JSON hierarchy to your parent class
|
|
||||||
List<MusicRecord> musicRecordList = gson.fromJson(queryCache.getResponse(), listType);
|
|
||||||
System.out.println(musicRecordList);
|
|
||||||
musicRepository.saveAll(musicRecordList);
|
|
||||||
return musicRecordList;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user