Frairable/index.php
2024-01-07 04:47:57 +01:00

218 lines
5.7 KiB
PHP

<?php
$GLOBALS["frairable_host"] = getenv("FRAIRABLE_HOST");
if (empty($GLOBALS["frairable_host"])) {
$GLOBALS["frairable_host"] = "https://airable.wifiradiofrontier.com";
}
$GLOBALS["frairable_dir_radios"] = getenv("FRAIRABLE_DIR_RADIOS");
if (empty($GLOBALS["frairable_dir_radios"])) {
$GLOBALS["frairable_dir_radios"] = dirname(__FILE__) . DIRECTORY_SEPARATOR . "radios";
}
function respond_with_raw(&$data) {
ob_start();
{
ob_start("ob_data");
{
echo($data);
ob_end_flush();
}
header("Content-Length: " . ob_get_length());
ob_end_flush();
}
}
function respond_with_json(&$data) {
header("Content-Type: application/json");
ob_start();
{
ob_start("ob_data");
{
echo(json_encode($data));
ob_end_flush();
}
header("Content-Length: " . ob_get_length());
ob_end_flush();
}
}
function airable_proxy($cb = NULL) {
$ch = curl_init("$GLOBALS[frairable_host]$_SERVER[REQUEST_URI]");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $_SERVER["REQUEST_METHOD"]);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 );
$headers_req = getallheaders();
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Accept: " . ($headers_req["Accept"] ?? "audio/aac;mp3;dash"),
"Accept-Language: " . ($headers_req["Accept-Language"] ?? "en-US"),
"Authorization: " . ($headers_req["Authorization"] ?? "true"),
"Connection: " . ($headers_req["Connection"] ?? "Close"),
"Content-Length: " . ($headers_req["Content-Length"] ?? "0"),
"User-Agent: " . ($headers_req["User-Agent"] ?? "ir-cui-FS2340-0000-0165_V4.5.13.707296-1A17")
]);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $headerstr) {
$len = strlen($headerstr);
$header = explode(":", $headerstr, 2);
if (count($header) < 2) {
return $len;
}
$key = trim($header[0]);
$value = trim($header[1]);
if ($key !== "Content-Length") {
header($headerstr);
}
return $len;
});
$data = curl_exec($ch);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
http_response_code($httpCode);
if ($_SERVER["REQUEST_METHOD"] === "GET" && $httpCode === 200) {
if ($cb !== NULL) {
$data = json_decode($data, true);
$cb($data);
$data = json_encode($data);
}
if ($data === "null") {
$data = "";
if (200 <= $httpCode && $httpCode < 300) {
http_response_code(404);
}
}
}
respond_with_raw($data);
}
function get_radio_data($id) {
$path = $GLOBALS["frairable_dir_radios"] . DIRECTORY_SEPARATOR . $id . ".json";
$path = realpath($path);
if (!str_starts_with($path, dirname(__FILE__))) {
http_response_code(400);
die();
}
return json_decode(file_get_contents($path), true);
}
function get_radio_entry($id) {
$data = get_radio_data($id);
$data["contains"] = [];
$data["id"] = ["frontiersmart", "radio", "custom=$id"];
$data["url"] = "$GLOBALS[frairable_host]/frontiersmart/radio/custom=$id";
unset($data["streams"]);
return $data;
}
function get_radio_meta($id) {
$data = get_radio_data($id);
$data["id"] = ["frontiersmart", "radio", "custom=$id"];
$data["url"] = "$GLOBALS[frairable_host]/frontiersmart/radio/custom=$id";
foreach ($data["streams"] as $index => &$stream) {
$stream["url"] = "$GLOBALS[frairable_host]/frontiersmart/radio/custom=$id/play=$index";
}
return $data;
}
function get_radio_play($id, $index) {
$data = get_radio_data($id);
// clone loves to complain about the stream not being an object...
// deep clone using json is ugly, but eh.
$stream = json_decode(json_encode($data["streams"][$index]), true);
$stream["id"] = ["frontiersmart", "redirect", "custom=$id/play=$index"];
$stream["content"] = $data;
unset($stream["reliability"]);
return $stream;
}
if ($_SERVER["REQUEST_URI"] === "/frontiersmart/radios") {
airable_proxy(function(&$data) {
array_push($data["content"]["entries"], [
"id" => [
"frontiersmart",
"directory",
"custom"
],
"title" => "Frairable (Custom)",
"url" => "$GLOBALS[frairable_host]/frontiersmart/radios/custom"
]);
});
} elseif ($_SERVER["REQUEST_URI"] === "/frontiersmart/radios/custom") {
$entries = [];
foreach (new DirectoryIterator($GLOBALS["frairable_dir_radios"]) as $sub) {
if ($sub->isDot() || $sub->isDir()) {
continue;
}
$id = basename($sub->getFilename(), ".json");
$entries[] = get_radio_entry($id);
}
$data = [
"id" => [
"frontiersmart",
"directory",
"custom"
],
"title" => "Frairable (Custom)",
"url" => "$GLOBALS[frairable_host]$_SERVER[REQUEST_URI]",
"content" => [
"entries" => $entries
]
];
respond_with_json($data);
} elseif (str_starts_with($_SERVER["REQUEST_URI"], "/frontiersmart/radio/custom=")) {
$id = substr($_SERVER["REQUEST_URI"], strlen("/frontiersmart/radio/custom="));
$split = strpos($id, "/play=");
if ($split) {
$index = intval(substr($id, $split + strlen("/play=")));
$id = substr($id, 0, $split);
respond_with_json(get_radio_play($id, $index));
} else {
respond_with_json(get_radio_meta($id));
}
} else {
airable_proxy();
}
?>