add jukebox feature
This commit is contained in:
parent
9ad604d012
commit
40a2d1da52
@ -42,6 +42,11 @@
|
||||
<artifactId>webstly-jitsi</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.bstly.we</groupId>
|
||||
<artifactId>webstly-jukebox</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.bstly.we</groupId>
|
||||
<artifactId>webstly-membership</artifactId>
|
||||
|
@ -42,12 +42,13 @@ public class SystemPropertyManager {
|
||||
/**
|
||||
* Gets the.
|
||||
*
|
||||
* @param key the key
|
||||
* @param key the key
|
||||
* @param defaultValue the default value
|
||||
* @return the string
|
||||
*/
|
||||
public String get(String key, String defaultValue) {
|
||||
return systemPropertyRepository.findById(key).orElse(new SystemProperty(key, defaultValue)).getValue();
|
||||
return systemPropertyRepository.findById(key).orElse(new SystemProperty(key, defaultValue))
|
||||
.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +64,7 @@ public class SystemPropertyManager {
|
||||
/**
|
||||
* Gets the boolean.
|
||||
*
|
||||
* @param key the key
|
||||
* @param key the key
|
||||
* @param defaultValue the default value
|
||||
* @return the boolean
|
||||
*/
|
||||
@ -84,7 +85,7 @@ public class SystemPropertyManager {
|
||||
/**
|
||||
* Gets the integer.
|
||||
*
|
||||
* @param key the key
|
||||
* @param key the key
|
||||
* @param defaultValue the default value
|
||||
* @return the integer
|
||||
*/
|
||||
@ -105,7 +106,7 @@ public class SystemPropertyManager {
|
||||
/**
|
||||
* Gets the long.
|
||||
*
|
||||
* @param key the key
|
||||
* @param key the key
|
||||
* @param defaultValue the default value
|
||||
* @return the long
|
||||
*/
|
||||
@ -116,7 +117,7 @@ public class SystemPropertyManager {
|
||||
/**
|
||||
* Adds the.
|
||||
*
|
||||
* @param key the key
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
public void add(String key, String value) {
|
||||
@ -128,7 +129,7 @@ public class SystemPropertyManager {
|
||||
/**
|
||||
* Update.
|
||||
*
|
||||
* @param key the key
|
||||
* @param key the key
|
||||
* @param value the value
|
||||
*/
|
||||
public void update(String key, String value) {
|
||||
@ -139,4 +140,12 @@ public class SystemPropertyManager {
|
||||
systemPropertyRepository.save(systemProperty);
|
||||
}
|
||||
|
||||
public void set(String key, String value) {
|
||||
if (systemPropertyRepository.existsById(key)) {
|
||||
update(key, value);
|
||||
} else {
|
||||
add(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
21
jukebox/pom.xml
Normal file
21
jukebox/pom.xml
Normal file
@ -0,0 +1,21 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>de.bstly.we</groupId>
|
||||
<artifactId>webstly-main</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<name>jukebox</name>
|
||||
<artifactId>webstly-jukebox</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.bstly.we</groupId>
|
||||
<artifactId>webstly-partey</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,280 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.jukebox.businesslogic;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import de.bstly.we.businesslogic.SystemPropertyManager;
|
||||
import de.bstly.we.jukebox.businesslogic.model.JukeboxConfig;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
/**
|
||||
* The Class JukeboxManager.
|
||||
*/
|
||||
@Component
|
||||
public class JukeboxManager implements SmartInitializingSingleton {
|
||||
public static final String CLIENT_ID = "jukebox.client_id";
|
||||
public static final String CLIENT_SECRET = "jukebox.client_secret";
|
||||
public static final String REDIRECT_URL = "jukebox.redirect_url";
|
||||
public static final String ACCOUNT_URL = "jukebox.account_url";
|
||||
public static final String API_URL = "jukebox.api_url";
|
||||
public static final String ACTIVE = "jukebox.active";
|
||||
public static final String ACCESS_TOKEN = "jukebox.access_token";
|
||||
public static final String REFRESH_TOKEN = "jukebox.refresh_token";
|
||||
public static final String EXPIRES = "jukebox.expires";
|
||||
|
||||
@Autowired
|
||||
private SystemPropertyManager systemPropertyManager;
|
||||
|
||||
protected WebClient webClient;
|
||||
private JukeboxConfig config;
|
||||
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
||||
* afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
||||
* afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
||||
* afterSingletonsInstantiated()
|
||||
*/
|
||||
@Override
|
||||
public void afterSingletonsInstantiated() {
|
||||
getConfig();
|
||||
|
||||
if (StringUtils.hasText(config.getApiUrl())) {
|
||||
webClient = WebClient.builder().baseUrl(config.getApiUrl())
|
||||
.defaultHeader(HttpHeaders.CONTENT_TYPE, "application/json").build();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the config.
|
||||
*
|
||||
* @return the config
|
||||
*/
|
||||
public JukeboxConfig getConfig() {
|
||||
if (config == null) {
|
||||
config = new JukeboxConfig();
|
||||
config.setClientId(systemPropertyManager.get(CLIENT_ID));
|
||||
config.setClientSecret(systemPropertyManager.get(CLIENT_SECRET));
|
||||
config.setRedirectUrl(systemPropertyManager.get(REDIRECT_URL));
|
||||
config.setApiUrl(systemPropertyManager.get(API_URL));
|
||||
config.setAccountUrl(systemPropertyManager.get(ACCOUNT_URL));
|
||||
config.setActive(systemPropertyManager.getBoolean(ACTIVE, false));
|
||||
config.setAccessToken(systemPropertyManager.get(ACCESS_TOKEN));
|
||||
config.setRefreshToken(systemPropertyManager.get(REFRESH_TOKEN));
|
||||
if (StringUtils.hasText(systemPropertyManager.get(EXPIRES))) {
|
||||
config.setExpires(Instant.parse(systemPropertyManager.get(EXPIRES)));
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the config.
|
||||
*
|
||||
* @param config the config
|
||||
* @return the jukebox config
|
||||
*/
|
||||
public JukeboxConfig setConfig(JukeboxConfig config) {
|
||||
this.config = config;
|
||||
|
||||
systemPropertyManager.set(CLIENT_ID, config.getClientId());
|
||||
systemPropertyManager.set(CLIENT_SECRET, config.getClientSecret());
|
||||
systemPropertyManager.set(REDIRECT_URL, config.getRedirectUrl());
|
||||
systemPropertyManager.set(API_URL, config.getApiUrl());
|
||||
systemPropertyManager.set(ACCOUNT_URL, config.getAccountUrl());
|
||||
systemPropertyManager.set(ACTIVE, String.valueOf(config.isActive()));
|
||||
systemPropertyManager.set(ACCESS_TOKEN, config.getAccessToken());
|
||||
systemPropertyManager.set(REFRESH_TOKEN, config.getRefreshToken());
|
||||
|
||||
if (config.getExpires() != null) {
|
||||
systemPropertyManager.set(EXPIRES, config.getExpires().toString());
|
||||
}
|
||||
|
||||
if (StringUtils.hasText(config.getApiUrl())) {
|
||||
webClient = WebClient.builder().baseUrl(config.getApiUrl())
|
||||
.defaultHeader(HttpHeaders.CONTENT_TYPE, "application/json").build();
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check token.
|
||||
*
|
||||
* @return true, if successful
|
||||
*/
|
||||
protected boolean checkToken() {
|
||||
if (webClient == null || !StringUtils.hasText(config.getRefreshToken())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(config.getAccessToken()) || config.getExpires() == null
|
||||
|| config.getExpires().isBefore(Instant.now())) {
|
||||
|
||||
String authHeader = "Basic "
|
||||
+ new String(Base64.getEncoder()
|
||||
.encode(String
|
||||
.format("%s:%s", config.getClientId(), config.getClientSecret())
|
||||
.getBytes()));
|
||||
WebClient.RequestBodySpec request = WebClient.builder().baseUrl(config.getAccountUrl())
|
||||
.build().method(HttpMethod.POST)
|
||||
.uri(uriBuilder -> uriBuilder.path("/api/token").build())
|
||||
.header(HttpHeaders.AUTHORIZATION, authHeader)
|
||||
.header(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
|
||||
|
||||
request.bodyValue("grant_type=refresh_token&refresh_token="
|
||||
+ config.getRefreshToken());
|
||||
|
||||
String jsonString = request.retrieve().bodyToMono(String.class).block();
|
||||
|
||||
if (StringUtils.hasText(jsonString)) {
|
||||
JsonObject response = JsonParser.parseString(jsonString).getAsJsonObject();
|
||||
config.setAccessToken(response.get("access_token").getAsString());
|
||||
config.setExpires(Instant.now().plus(response.get("expires_in").getAsLong(),
|
||||
ChronoUnit.SECONDS));
|
||||
|
||||
if (response.has("refresh_token")) {
|
||||
config.setRefreshToken(response.get("refresh_token").getAsString());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status.
|
||||
*
|
||||
* @return the status
|
||||
*/
|
||||
public JsonElement getStatus() {
|
||||
if (!checkToken()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
WebClient.RequestBodySpec request = webClient.method(HttpMethod.GET)
|
||||
.uri(uriBuilder -> uriBuilder.path("/v1/me/player").build())
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer "
|
||||
+ config.getAccessToken());
|
||||
|
||||
String jsonString = request.retrieve().bodyToMono(String.class).block();
|
||||
|
||||
if (StringUtils.hasText(jsonString)) {
|
||||
JsonElement status = JsonParser.parseString(jsonString);
|
||||
if (config.isActive()) {
|
||||
boolean disable = false;
|
||||
if (status == null || status.isJsonNull() || !status.isJsonObject()) {
|
||||
disable = true;
|
||||
} else {
|
||||
JsonObject statusObject = status.getAsJsonObject();
|
||||
if (!statusObject.has("device")) {
|
||||
disable = true;
|
||||
}
|
||||
JsonObject device = statusObject.getAsJsonObject("device");
|
||||
if (!device.has("is_private_session")
|
||||
|| !device.get("is_private_session").getAsBoolean()) {
|
||||
disable = true;
|
||||
}
|
||||
}
|
||||
if (disable) {
|
||||
config.setActive(false);
|
||||
systemPropertyManager.set(ACTIVE, String.valueOf(config.isActive()));
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search track.
|
||||
*
|
||||
* @param query the query
|
||||
* @param offset the offset
|
||||
* @return the json element
|
||||
*/
|
||||
public JsonElement searchTrack(String query, Long offset) {
|
||||
if (!checkToken()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MultiValueMap<String, String> queryParameters = new LinkedMultiValueMap<String, String>();
|
||||
queryParameters.add("q", query);
|
||||
queryParameters.add("type", "track");
|
||||
if (offset != null) {
|
||||
queryParameters.add("offset", String.valueOf(offset));
|
||||
}
|
||||
WebClient.RequestBodySpec request = webClient.method(HttpMethod.GET).uri(
|
||||
uriBuilder -> uriBuilder.path("/v1/search").queryParams(queryParameters).build())
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer "
|
||||
+ config.getAccessToken());
|
||||
|
||||
String jsonString = request.retrieve().bodyToMono(String.class)
|
||||
.onErrorResume(e -> Mono.just(e.getMessage())).block();
|
||||
|
||||
if (StringUtils.hasText(jsonString)) {
|
||||
return JsonParser.parseString(jsonString);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the to queue.
|
||||
*
|
||||
* @param uri the uri
|
||||
*/
|
||||
public void addToQueue(String uri) {
|
||||
if (!checkToken()) {
|
||||
return;
|
||||
}
|
||||
|
||||
MultiValueMap<String, String> queryParameters = new LinkedMultiValueMap<String, String>();
|
||||
queryParameters.add("uri", uri);
|
||||
WebClient.RequestBodySpec request = webClient.method(HttpMethod.POST)
|
||||
.uri(uriBuilder -> uriBuilder.path("/v1/me/player/queue")
|
||||
.queryParams(queryParameters).build())
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer "
|
||||
+ config.getAccessToken());
|
||||
|
||||
request.retrieve().bodyToMono(String.class).block();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check active.
|
||||
*/
|
||||
@Scheduled(cron = "${we.bstly.jukebox.cron:0 */5 0 * * * }")
|
||||
public void checkActive() {
|
||||
getStatus();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,181 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.jukebox.businesslogic.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* The Class JukeboxConfig.
|
||||
*/
|
||||
public class JukeboxConfig {
|
||||
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
private String redirectUrl;
|
||||
private String apiUrl;
|
||||
private String accountUrl;
|
||||
private boolean active;
|
||||
private String accessToken;
|
||||
private String refreshToken;
|
||||
private Instant expires;
|
||||
|
||||
/**
|
||||
* Gets the client id.
|
||||
*
|
||||
* @return the client id
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client id.
|
||||
*
|
||||
* @param clientId the new client id
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the client secret.
|
||||
*
|
||||
* @return the client secret
|
||||
*/
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the client secret.
|
||||
*
|
||||
* @param clientSecret the new client secret
|
||||
*/
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the redirect url.
|
||||
*
|
||||
* @return the redirect url
|
||||
*/
|
||||
public String getRedirectUrl() {
|
||||
return redirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the redirect url.
|
||||
*
|
||||
* @param redirectUrl the new redirect url
|
||||
*/
|
||||
public void setRedirectUrl(String redirectUrl) {
|
||||
this.redirectUrl = redirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the api url.
|
||||
*
|
||||
* @return the api url
|
||||
*/
|
||||
public String getApiUrl() {
|
||||
return apiUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the api url.
|
||||
*
|
||||
* @param apiUrl the new api url
|
||||
*/
|
||||
public void setApiUrl(String apiUrl) {
|
||||
this.apiUrl = apiUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the accountUrl
|
||||
*/
|
||||
public String getAccountUrl() {
|
||||
return accountUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param accountUrl the accountUrl to set
|
||||
*/
|
||||
public void setAccountUrl(String accountUrl) {
|
||||
this.accountUrl = accountUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is active.
|
||||
*
|
||||
* @return true, if is active
|
||||
*/
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the active.
|
||||
*
|
||||
* @param active the new active
|
||||
*/
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the access token.
|
||||
*
|
||||
* @return the access token
|
||||
*/
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the access token.
|
||||
*
|
||||
* @param accessToken the new access token
|
||||
*/
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the refresh token.
|
||||
*
|
||||
* @return the refresh token
|
||||
*/
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the refresh token.
|
||||
*
|
||||
* @param refreshToken the new refresh token
|
||||
*/
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expires.
|
||||
*
|
||||
* @return the expires
|
||||
*/
|
||||
public Instant getExpires() {
|
||||
return expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the expires.
|
||||
*
|
||||
* @param expires the new expires
|
||||
*/
|
||||
public void setExpires(Instant expires) {
|
||||
this.expires = expires;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.jukebox.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.beust.jcommander.internal.Maps;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonIOException;
|
||||
|
||||
import de.bstly.we.businesslogic.PermissionManager;
|
||||
import de.bstly.we.controller.BaseController;
|
||||
import de.bstly.we.controller.support.EntityResponseStatusException;
|
||||
import de.bstly.we.jukebox.businesslogic.JukeboxManager;
|
||||
import de.bstly.we.partey.businesslogic.ParteyPermissions;
|
||||
|
||||
/**
|
||||
* The Class JukeboxController.
|
||||
*/
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/jukebox")
|
||||
public class JukeboxController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private PermissionManager permissionManager;
|
||||
@Autowired
|
||||
private JukeboxManager jukeboxManager;
|
||||
private Gson gson = new Gson();
|
||||
|
||||
private Map<Long, Instant> queueList = Maps.newHashMap();
|
||||
private Map<Long, Instant> searchList = Maps.newHashMap();
|
||||
|
||||
/**
|
||||
* Check queue permission.
|
||||
*/
|
||||
protected void checkQueuePermission() {
|
||||
if (!permissionManager.hasPermission(getCurrentUserId(), ParteyPermissions.PARTEY)) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
if (!jukeboxManager.getConfig().isActive()) {
|
||||
throw new EntityResponseStatusException(HttpStatus.GONE);
|
||||
}
|
||||
|
||||
jukeboxManager.getStatus();
|
||||
|
||||
if (!jukeboxManager.getConfig().isActive()) {
|
||||
throw new EntityResponseStatusException(HttpStatus.GONE);
|
||||
}
|
||||
|
||||
if (queueList.containsKey(getCurrentUserId()) && queueList.get(getCurrentUserId())
|
||||
.isAfter(Instant.now().minus(1, ChronoUnit.MINUTES))) {
|
||||
throw new EntityResponseStatusException(
|
||||
Duration.between(queueList.get(getCurrentUserId()), Instant.now()).getSeconds(),
|
||||
HttpStatus.PAYMENT_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check search permission.
|
||||
*/
|
||||
protected void checkSearchPermission() {
|
||||
if (!permissionManager.hasPermission(getCurrentUserId(), ParteyPermissions.PARTEY)) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
if (!jukeboxManager.getConfig().isActive()) {
|
||||
throw new EntityResponseStatusException(HttpStatus.GONE);
|
||||
}
|
||||
|
||||
if (searchList.containsKey(getCurrentUserId()) && searchList.get(getCurrentUserId())
|
||||
.isAfter(Instant.now().minus(3, ChronoUnit.SECONDS))) {
|
||||
throw new EntityResponseStatusException(Duration
|
||||
.between(searchList.get(getCurrentUserId()), Instant.now()).getSeconds(),
|
||||
HttpStatus.PAYMENT_REQUIRED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check.
|
||||
*
|
||||
* @throws JsonIOException the json IO exception
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping
|
||||
public void check() throws JsonIOException, IOException {
|
||||
checkQueuePermission();
|
||||
}
|
||||
|
||||
/**
|
||||
* Search.
|
||||
*
|
||||
* @param query the query
|
||||
* @param offset the offset
|
||||
* @param response the response
|
||||
* @throws JsonIOException the json IO exception
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@GetMapping("/search")
|
||||
public void search(@RequestParam("q") String query,
|
||||
@RequestParam("offset") Optional<Long> offset, HttpServletResponse response)
|
||||
throws JsonIOException, IOException {
|
||||
checkSearchPermission();
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
gson.toJson(jukeboxManager.searchTrack(query, offset.orElse(null)), response.getWriter());
|
||||
searchList.put(getCurrentUserId(), Instant.now());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.
|
||||
*
|
||||
* @param uri the uri
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PostMapping("/queue")
|
||||
public void queue(@RequestParam("uri") String uri) {
|
||||
checkQueuePermission();
|
||||
jukeboxManager.addToQueue(uri);
|
||||
queueList.put(getCurrentUserId(), Instant.now());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.we.jukebox.controller;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonIOException;
|
||||
|
||||
import de.bstly.we.controller.BaseController;
|
||||
import de.bstly.we.jukebox.businesslogic.JukeboxManager;
|
||||
import de.bstly.we.jukebox.businesslogic.model.JukeboxConfig;
|
||||
|
||||
/**
|
||||
* The Class JukeboxManagementController.
|
||||
*/
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/jukebox/manage")
|
||||
public class JukeboxManagementController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private JukeboxManager jukeboxManager;
|
||||
private Gson gson = new Gson();
|
||||
|
||||
/**
|
||||
* Gets the config.
|
||||
*
|
||||
* @return the config
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@GetMapping("/config")
|
||||
public JukeboxConfig getConfig() {
|
||||
return jukeboxManager.getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the config.
|
||||
*
|
||||
* @param config the config
|
||||
* @return the jukebox config
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PostMapping("/config")
|
||||
public JukeboxConfig setConfig(@RequestBody JukeboxConfig config) {
|
||||
return jukeboxManager.setConfig(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the config.
|
||||
*
|
||||
* @param config the config
|
||||
* @return the jukebox config
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PutMapping
|
||||
public void setActive() {
|
||||
JukeboxConfig config = getConfig();
|
||||
config.setActive(true);
|
||||
jukeboxManager.setConfig(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the config.
|
||||
*
|
||||
* @param config the config
|
||||
* @return the jukebox config
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@DeleteMapping
|
||||
public void disable() {
|
||||
JukeboxConfig config = getConfig();
|
||||
config.setActive(false);
|
||||
jukeboxManager.setConfig(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status.
|
||||
*
|
||||
* @param response the response
|
||||
* @return the status
|
||||
* @throws JsonIOException the json IO exception
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@GetMapping()
|
||||
public void getStatus(HttpServletResponse response) throws JsonIOException, IOException {
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
gson.toJson(jukeboxManager.getStatus(), response.getWriter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Search.
|
||||
*
|
||||
* @param query the query
|
||||
* @param offset the offset
|
||||
* @param response the response
|
||||
* @throws JsonIOException the json IO exception
|
||||
* @throws IOException Signals that an I/O exception has occurred.
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@GetMapping("/search")
|
||||
public void search(@RequestParam("q") String query,
|
||||
@RequestParam("offset") Optional<Long> offset, HttpServletResponse response)
|
||||
throws JsonIOException, IOException {
|
||||
response.setContentType("application/json");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
gson.toJson(jukeboxManager.searchTrack(query, offset.orElse(null)), response.getWriter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Queue.
|
||||
*
|
||||
* @param uri the uri
|
||||
*/
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@PostMapping("/queue")
|
||||
public void queue(@RequestParam("uri") String uri) {
|
||||
jukeboxManager.addToQueue(uri);
|
||||
}
|
||||
|
||||
}
|
3
pom.xml
3
pom.xml
@ -12,7 +12,7 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>11</java.version>
|
||||
<revision>1.4.2-SNAPSHOT</revision>
|
||||
<revision>1.4.3-SNAPSHOT</revision>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
@ -30,6 +30,7 @@
|
||||
<module>i18n</module>
|
||||
<module>invite</module>
|
||||
<module>jitsi</module>
|
||||
<module>jukebox</module>
|
||||
<module>jwt</module>
|
||||
<module>membership</module>
|
||||
<module>minetest</module>
|
||||
|
Loading…
Reference in New Issue
Block a user