update jukebox to play if not running

This commit is contained in:
_Bastler 2022-02-10 12:01:30 +01:00
parent bf0f280985
commit 4536357642
5 changed files with 153 additions and 38 deletions

View File

@ -74,9 +74,9 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
@Value("${jitsi.urlFormat:%s/jwt?%s}") @Value("${jitsi.urlFormat:%s/jwt?%s}")
private String urlFormat; private String urlFormat;
/* /*
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated() * @see org.springframework.beans.factory.SmartInitializingSingleton#
* afterSingletonsInstantiated()
*/ */
@Override @Override
public void afterSingletonsInstantiated() { public void afterSingletonsInstantiated() {
@ -110,9 +110,9 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
/** /**
* Gets the. * Gets the.
* *
* @param page the page * @param page the page
* @param size the size * @param size the size
* @param sortBy the sort by * @param sortBy the sort by
* @param descending the descending * @param descending the descending
* @return the page * @return the page
*/ */
@ -124,10 +124,10 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
/** /**
* Gets the for user id. * Gets the for user id.
* *
* @param userId the user id * @param userId the user id
* @param page the page * @param page the page
* @param size the size * @param size the size
* @param sortBy the sort by * @param sortBy the sort by
* @param descending the descending * @param descending the descending
* @return the for user id * @return the for user id
*/ */
@ -144,11 +144,11 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
/** /**
* Creates the. * Creates the.
* *
* @param owner the owner * @param owner the owner
* @param room the room * @param room the room
* @param starts the starts * @param starts the starts
* @param moderationStarts the moderation starts * @param moderationStarts the moderation starts
* @param expires the expires * @param expires the expires
* @return the jitsi room * @return the jitsi room
* @throws JOSEException the JOSE exception * @throws JOSEException the JOSE exception
*/ */
@ -213,7 +213,8 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
ShortenedUrl shortenedUrl = shortenedUrlManager.get(jitsiRoom.getCode()); ShortenedUrl shortenedUrl = shortenedUrlManager.get(jitsiRoom.getCode());
if (shortenedUrl != null) { if (shortenedUrl != null) {
shortenedUrl.setUrl(jitsiRoom.getUrl()); shortenedUrl.setUrl(jitsiRoom.getUrl());
shortenedUrl.setNote("JitsiRoom: " + jitsiRoom.getRoom()); shortenedUrl.setNote("JitsiRoom: "
+ jitsiRoom.getRoom());
shortenedUrl.setExpires(jitsiRoom.getExpires()); shortenedUrl.setExpires(jitsiRoom.getExpires());
shortenedUrlManager.save(shortenedUrl); shortenedUrlManager.save(shortenedUrl);
jitsiRoom.setOrgUrl(jitsiRoom.getUrl()); jitsiRoom.setOrgUrl(jitsiRoom.getUrl());
@ -234,8 +235,9 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
*/ */
public JitsiRoom createShortenedUrl(JitsiRoom jitsiRoom) { public JitsiRoom createShortenedUrl(JitsiRoom jitsiRoom) {
ShortenedUrl shortenedUrl = shortenedUrlManager.create(jitsiRoom.getOwner(), ShortenedUrl shortenedUrl = shortenedUrlManager.create(jitsiRoom.getOwner(),
jitsiRoom.getUrl(), "JitsiRoom: " + jitsiRoom.getRoom(), null, jitsiRoom.getUrl(), "JitsiRoom: "
jitsiRoom.getExpires(), null, false, true); + jitsiRoom.getRoom(),
null, jitsiRoom.getExpires(), null, false, true);
jitsiRoom.setOrgUrl(jitsiRoom.getUrl()); jitsiRoom.setOrgUrl(jitsiRoom.getUrl());
jitsiRoom.setCode(shortenedUrl.getCode()); jitsiRoom.setCode(shortenedUrl.getCode());
jitsiRoom.setUrl(shortenedUrl.getLink()); jitsiRoom.setUrl(shortenedUrl.getLink());
@ -246,7 +248,7 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
* Delete. * Delete.
* *
* @param jitsiRoom the jitsi room * @param jitsiRoom the jitsi room
* @param quota the quota * @param quota the quota
*/ */
public void delete(JitsiRoom jitsiRoom, boolean quota) { public void delete(JitsiRoom jitsiRoom, boolean quota) {
if (quota) { if (quota) {
@ -299,7 +301,6 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
} }
} }
/* /*
* @see de.bstly.we.businesslogic.UserDataProvider#getId() * @see de.bstly.we.businesslogic.UserDataProvider#getId()
*/ */
@ -308,7 +309,6 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
return "jitsiRooms"; return "jitsiRooms";
} }
/* /*
* @see de.bstly.we.businesslogic.UserDataProvider#getUserData(java.lang.Long) * @see de.bstly.we.businesslogic.UserDataProvider#getUserData(java.lang.Long)
*/ */
@ -321,7 +321,6 @@ public class JitsiRoomManager implements SmartInitializingSingleton, UserDataPro
return result; return result;
} }
/* /*
* @see de.bstly.we.businesslogic.UserDataProvider#purgeUserData(java.lang.Long) * @see de.bstly.we.businesslogic.UserDataProvider#purgeUserData(java.lang.Long)
*/ */

View File

@ -67,9 +67,9 @@ public class JitsiRoomValidator implements Validator {
/** /**
* Validate. * Validate.
* *
* @param owner the owner * @param owner the owner
* @param roomName the room name * @param roomName the room name
* @param errors the errors * @param errors the errors
*/ */
public void validate(Long owner, String roomName, Errors errors) { public void validate(Long owner, String roomName, Errors errors) {
if (owner == null) { if (owner == null) {
@ -97,7 +97,7 @@ public class JitsiRoomValidator implements Validator {
* Validate room. * Validate room.
* *
* @param roomName the room name * @param roomName the room name
* @param errors the errors * @param errors the errors
*/ */
public void validateRoom(String roomName, Errors errors) { public void validateRoom(String roomName, Errors errors) {
for (String systemRoomName : systemPropertyManager.get(RESERVED_JITSI_ROOMS, "") for (String systemRoomName : systemPropertyManager.get(RESERVED_JITSI_ROOMS, "")
@ -115,7 +115,7 @@ public class JitsiRoomValidator implements Validator {
* Validate expiry. * Validate expiry.
* *
* @param jitsiRoom the jitsi room * @param jitsiRoom the jitsi room
* @param errors the errors * @param errors the errors
*/ */
public void validateExpiry(JitsiRoom jitsiRoom, Errors errors) { public void validateExpiry(JitsiRoom jitsiRoom, Errors errors) {

View File

@ -3,6 +3,7 @@
*/ */
package de.bstly.we.jukebox.businesslogic; package de.bstly.we.jukebox.businesslogic;
import java.io.IOException;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.Base64; import java.util.Base64;
@ -11,6 +12,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
@ -58,6 +60,13 @@ public class JukeboxManager implements SmartInitializingSingleton {
private JukeboxConfig config; private JukeboxConfig config;
protected static Gson gson = new Gson(); protected static Gson gson = new Gson();
@Value("${we.bstly.jukebox.daemon.retries:5}")
private int daemonRetries;
/*
* @see org.springframework.beans.factory.SmartInitializingSingleton#
* afterSingletonsInstantiated()
*/
@Override @Override
public void afterSingletonsInstantiated() { public void afterSingletonsInstantiated() {
getConfig(); getConfig();
@ -239,10 +248,18 @@ public class JukeboxManager implements SmartInitializingSingleton {
return JsonNull.INSTANCE; return JsonNull.INSTANCE;
} }
/**
* Try start playback.
*/
protected void tryStartPlayback() { protected void tryStartPlayback() {
tryStartPlayback(null); tryStartPlayback(null);
} }
/**
* Try start playback.
*
* @param context_uri the context uri
*/
protected void tryStartPlayback(String context_uri) { protected void tryStartPlayback(String context_uri) {
if (!checkToken()) { if (!checkToken()) {
config.setActive(false); config.setActive(false);
@ -371,6 +388,8 @@ public class JukeboxManager implements SmartInitializingSingleton {
JsonElement status = getStatus(); JsonElement status = getStatus();
boolean queue = true;
// start playing if not running // start playing if not running
if (status == null || !status.isJsonObject()) { if (status == null || !status.isJsonObject()) {
MultiValueMap<String, String> queryParameters = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> queryParameters = new LinkedMultiValueMap<String, String>();
@ -382,13 +401,19 @@ public class JukeboxManager implements SmartInitializingSingleton {
+ config.getAccessToken()); + config.getAccessToken());
JsonObject body = new JsonObject(); JsonObject body = new JsonObject();
JsonArray uris = new JsonArray(); if (StringUtils.hasText(config.getFallbackContextId())) {
uris.add(uri); body.addProperty("context_uri", config.getFallbackContextId());
body.add("uris", uris); } else {
JsonArray uris = new JsonArray();
uris.add(uri);
body.add("uris", uris);
queue = false;
}
request.bodyValue(body.toString()); request.bodyValue(body.toString());
request.retrieve().bodyToMono(String.class).block(); request.retrieve().bodyToMono(String.class).block();
} else { }
if (queue) {
MultiValueMap<String, String> queryParameters = new LinkedMultiValueMap<String, String>(); MultiValueMap<String, String> queryParameters = new LinkedMultiValueMap<String, String>();
queryParameters.add("uri", uri); queryParameters.add("uri", uri);
queryParameters.add("device_id", config.getDeviceId()); queryParameters.add("device_id", config.getDeviceId());
@ -412,4 +437,88 @@ public class JukeboxManager implements SmartInitializingSingleton {
} }
} }
/**
* Check devices.
*/
public void checkDevices() {
checkDevices(0);
}
/**
* Check devices.
*
* @param tries the tries
*/
public void checkDevices(int tries) {
if (tries > daemonRetries) {
logger.warn("Could not setup spotifyd device!");
return;
}
if (!checkToken()) {
logger.warn("Failed token check!");
return;
}
if (!StringUtils.hasText(config.getDeviceId())) {
logger.info("No device ID set.");
return;
}
WebClient.RequestBodySpec request = webClient.method(HttpMethod.GET)
.uri(uriBuilder -> uriBuilder.path("/v1/me/player/devices").build())
.header(HttpHeaders.AUTHORIZATION, "Bearer "
+ config.getAccessToken());
boolean deviceFound = false;
String jsonString = request.retrieve().bodyToMono(String.class).block();
if (StringUtils.hasText(jsonString)) {
JsonElement response = JsonParser.parseString(jsonString);
if (response != null && !response.isJsonNull() && response.isJsonObject()) {
JsonArray devices = response.getAsJsonObject().getAsJsonArray("devices");
for (JsonElement deviceElement : devices) {
JsonObject device = deviceElement.getAsJsonObject();
if (device.has("id")
&& device.get("id").getAsString().equals(config.getDeviceId())) {
deviceFound = true;
return;
}
}
}
}
if (!deviceFound) {
String command = "sudo /bin/systemctl restart spotifyd.service";
try {
Runtime.getRuntime().exec(command);
} catch (IOException e) {
logger.warn("Could execute command: "
+ command, e);
return;
}
try {
tries++;
Thread.sleep(5000 * tries);
checkDevices(tries);
} catch (InterruptedException e) {
logger.warn("Could not sleep!");
return;
}
}
}
/**
* Check spotify D.
*/
@Scheduled(cron = "${we.bstly.jukebox.daemon.cron:0 */15 * * * * }")
public void checkSpotifyD() {
if (config.isActive()) {
checkDevices();
}
}
} }

View File

@ -203,14 +203,18 @@ public class JukeboxConfig {
} }
/** /**
* @return the fallbackContextId * Gets the fallback context id.
*
* @return the fallback context id
*/ */
public String getFallbackContextId() { public String getFallbackContextId() {
return fallbackContextId; return fallbackContextId;
} }
/** /**
* @param fallbackContextId the fallbackContextId to set * Sets the fallback context id.
*
* @param fallbackContextId the new fallback context id
*/ */
public void setFallbackContextId(String fallbackContextId) { public void setFallbackContextId(String fallbackContextId) {
this.fallbackContextId = fallbackContextId; this.fallbackContextId = fallbackContextId;

View File

@ -52,6 +52,8 @@ public class JukeboxController extends BaseController {
/** /**
* Check queue permission. * Check queue permission.
*
* @return the json element
*/ */
protected JsonElement checkQueuePermission() { protected JsonElement checkQueuePermission() {
if (!permissionManager.hasPermission(getCurrentUserId(), ParteyPermissions.PARTEY)) { if (!permissionManager.hasPermission(getCurrentUserId(), ParteyPermissions.PARTEY)) {
@ -101,8 +103,9 @@ public class JukeboxController extends BaseController {
/** /**
* Check. * Check.
* *
* @param response the response
* @throws JsonIOException the json IO exception * @throws JsonIOException the json IO exception
* @throws IOException Signals that an I/O exception has occurred. * @throws IOException Signals that an I/O exception has occurred.
*/ */
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping @GetMapping
@ -126,11 +129,11 @@ public class JukeboxController extends BaseController {
/** /**
* Search. * Search.
* *
* @param query the query * @param query the query
* @param offset the offset * @param offset the offset
* @param response the response * @param response the response
* @throws JsonIOException the json IO exception * @throws JsonIOException the json IO exception
* @throws IOException Signals that an I/O exception has occurred. * @throws IOException Signals that an I/O exception has occurred.
*/ */
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/search") @GetMapping("/search")
@ -162,7 +165,7 @@ public class JukeboxController extends BaseController {
* *
* @param response the response * @param response the response
* @throws JsonIOException the json IO exception * @throws JsonIOException the json IO exception
* @throws IOException Signals that an I/O exception has occurred. * @throws IOException Signals that an I/O exception has occurred.
*/ */
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/current") @GetMapping("/current")
@ -194,10 +197,10 @@ public class JukeboxController extends BaseController {
/** /**
* Last. * Last.
* *
* @param limit the limit * @param limit the limit
* @param response the response * @param response the response
* @throws JsonIOException the json IO exception * @throws JsonIOException the json IO exception
* @throws IOException Signals that an I/O exception has occurred. * @throws IOException Signals that an I/O exception has occurred.
*/ */
@PreAuthorize("isAuthenticated()") @PreAuthorize("isAuthenticated()")
@GetMapping("/last") @GetMapping("/last")