/*
|
Calypso - Media Player Remote Control via HTTP for Raspberry Pi
|
Copyright (C) 2021-2023 Ulrich Hilger
|
|
This program is free software: you can redistribute it and/or modify
|
it under the terms of the GNU Affero General Public License as
|
published by the Free Software Foundation, either version 3 of the
|
License, or (at your option) any later version.
|
|
This program is distributed in the hope that it will be useful,
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
GNU Affero General Public License for more details.
|
|
You should have received a copy of the GNU Affero General Public License
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
*/
|
|
package de.uhilger.calypso.http;
|
|
import com.sun.net.httpserver.HttpContext;
|
import com.sun.net.httpserver.HttpExchange;
|
import de.uhilger.calypso.actor.PlayActor;
|
import de.uhilger.calypso.actor.ShellActor;
|
import de.uhilger.calypso.actor.StopServerActor;
|
import java.io.IOException;
|
import java.io.OutputStream;
|
import java.util.Collection;
|
import java.util.Map;
|
import java.util.logging.Level;
|
import java.util.logging.Logger;
|
|
/**
|
* Der ApiHandler ist die proprietaer fuer Calypso vorgesehene
|
* Weise, HTTP-Anfragen zu verarbeiten.
|
*
|
* Der ApiHandler ist ein HttpHandler, der vom Server ueber die
|
* gesamte Laufzeit des Programmes hinweg gehalten wird. Deswegen
|
* beschraenkt sich der Programmcode des ApiHandlers auf die
|
* Verteilung der Kommandos auf Aktoren. Die Aktoren werden je nach
|
* Bedarf instanziiert und enthalten zusammengenommen den Code
|
* des Anwendungskerns.
|
*
|
* @author Ulrich Hilger
|
*/
|
public class ApiHandler extends HttpApi {
|
|
public static final int PLAYERCMD = 2;
|
public static final int SERVERCMD = 3;
|
public static final String PLAY = "play";
|
public static final String PAUSE = "pause";
|
public static final String SEEK = "seek";
|
public static final String STOP = "stop";
|
public static final String SERVER = "server";
|
public static final String PING = "ping";
|
|
public static final String PLAYER = "player-proc";
|
|
/**
|
* Die HTTP-Anfrage ausführen
|
*
|
* WICHTIG: Die HTTP-Parameter aus dem Query-Teil muessen in
|
* der Reihenfolge sein, die vom Shell-Skript erwartet wird.
|
*
|
* @param elems die Elemente des URI-Pfads
|
* @param parameter die Parameter des Query-Teils der URI
|
* @param exchange das Objekt mit Infos zum HTTP-Aufruf
|
* @return die Antwort, die gesendet werden soll
|
*/
|
@Override
|
protected String process(String[] elems, Map parameter, HttpExchange exchange) {
|
String antwort;
|
Object o;
|
|
switch (elems[PLAYERCMD]) {
|
case PLAY:
|
PlayActor a = new PlayActor();
|
o = a.run(parameter);
|
if (o instanceof Process) {
|
exchange.getHttpContext().getAttributes().put(PLAYER, o);
|
antwort = "Abspielprozess gestartet.";
|
} else {
|
// kein Prozess, es ist etwas schief gelaufen
|
antwort = "Abspielen konnte nicht gestartet werden.";
|
}
|
break;
|
|
case PAUSE:
|
case SEEK:
|
ShellActor pa = new ShellActor();
|
try {
|
pa.run(getSkriptDir(exchange), elems[PLAYERCMD], toShellParams(parameter));
|
antwort = elems[PLAYERCMD] + " ausgefuehrt";
|
} catch (IOException ex) {
|
Logger.getLogger(ApiHandler.class.getName()).log(Level.SEVERE, null, ex);
|
antwort = "Fehler bei der Ausfuehrung von " + elems[PLAYERCMD];
|
}
|
break;
|
|
case STOP:
|
o = exchange.getHttpContext().getAttributes().get(PLAYER);
|
if(o instanceof Process) {
|
Process p = (Process) o;
|
p.destroy();
|
antwort = "Player gestoppt.";
|
} else {
|
antwort = "Es wurde kein Player-Prozess zum Stoppen gefunden.";
|
}
|
break;
|
|
case SERVER:
|
if(elems[SERVERCMD].equals(STOP)) {
|
try {
|
antwort = "Calypso: Der Server wird angehalten und die App beendet.";
|
sendResponse(exchange, antwort);
|
new StopServerActor().run(exchange.getHttpContext());
|
} catch (IOException ex) {
|
Logger.getLogger(ApiHandler.class.getName()).log(Level.SEVERE, null, ex);
|
antwort = "Fehler: " + ex.getLocalizedMessage();
|
}
|
} else {
|
antwort = elems[SERVERCMD] + " ist ein unbekanntes Serverkommando";
|
}
|
break;
|
|
case PING:
|
antwort = elems[PLAYERCMD];
|
break;
|
|
default:
|
antwort = "Kommando " + elems[PLAYERCMD] + " unbekannt";
|
break;
|
}
|
|
return antwort;
|
}
|
|
private String[] toShellParams(Map parameter) {
|
Collection<String> c = parameter.values();
|
return c.toArray(String[]::new);
|
}
|
|
private String getSkriptDir(HttpExchange exchange) {
|
HttpContext context = exchange.getHttpContext();
|
Object o = context.getAttributes().get(Server.SKRIPT_DIR);
|
if (o instanceof String) {
|
return (String) o;
|
} else {
|
// kein Skript-Dir
|
return "";
|
}
|
}
|
}
|