Catch mediatomb browse errors
[noxon-gateway.git] / src / mediatomb.php
index 74b7f8479fdaa5d07f16cdf1ae621b8840355a72..33b9bd87305fbeedf076e65d341c4a3cbd72223e 100644 (file)
 <?php
 require_once 'Services/MediaTomb.php';
 
-function handleRequestMediatomb($fullPath, $prefix)
+function handleMediatomb($action, $fullPath, $prefix)
 {
     global $mediatomb;
 
     extract($mediatomb);
     try {
         $smt = new Services_MediaTomb($user, $pass, $host, $port);
+        if ($action == 'browse') {
+            mediatombBrowse($smt, $fullPath, $prefix);
+        } else if ($action == 'single') {
+            mediatombSingle($smt, $fullPath, $prefix);
+        }
+    } catch (Exception $e) {
+        sendMessage('Mediatomb error: ' . $e->getMessage());
+        return;
+    }
+}
+
+function mediatombBrowse(Services_MediaTomb $smt, $fullPath, $prefix)
+{
+    global $mediatomb;
+
+    $path = substr($fullPath, strlen($prefix));
+    $container = $smt->getContainerByPath($path);
+    if ($container === null) {
+        sendMessage('Error accessing ' . $fullPath);
+        return;
+    }
 
-        $path = substr(urldecode($fullPath), strlen($prefix));
-        $container = $smt->getContainerByPath($path);
-        $listItems = array();
-        addPreviousItem($listItems, $fullPath);
+    $listItems = array();
 
-        foreach ($container->getContainers() as $subContainer) {
+    $it = $container->getItemIterator(false);
+    $it->rewind();
+    $hasFiles = $it->valid();
+    if ($hasFiles && is_array($mediatomb['singleFileDirectories'])) {
+        $enableSingle = false;
+        foreach ($mediatomb['singleFileDirectories'] as $dir) {
+            if (substr($fullPath, 0, strlen($dir)) == $dir) {
+                $enableSingle = true;
+            }
+        }
+        if ($enableSingle) {
             $listItems[] = getDirItem(
-                $subContainer->title,
-                $fullPath . rawurlencode($subContainer->title) . '/'
+                'Einzeln',
+                pathEncode('.mt-single/' . $path)
             );
         }
+    }
+
+    foreach ($container->getContainers() as $subContainer) {
+        $listItems[] = getDirItem(
+            $subContainer->title,
+            pathEncode($fullPath . $subContainer->title) . '/'
+        );
+    }
 
+    foreach ($container->getItemIterator(false) as $item) {
+        mediatombAddFile($listItems, $item);
+    }
+
+    sendListItems($listItems, buildPreviousItem($fullPath));
+}
+
+function mediatombAddFile(&$listItems, $item)
+{
+    global $host1;
+
+    $di = $item->getDetailedItem();
+    $itemUrl = $item->url;
+    if (!clientSupportsType($di->mimetype)) {
+        //client wants transcoded file
+        //noxon iRadio cube does not want to play .ogg files
+        if (isset($GLOBALS['cacheDir']) && $GLOBALS['cacheDir'] != '') {
+            $itemUrl = $host1 . 'transcode-cache.php'
+                . '?url=' . urlencode($itemUrl);
+        } else {
+            $itemUrl = $host1 . 'transcode-nocache.php'
+                . '?url=' . urlencode($itemUrl);
+        }
+    }
+    $listItems[] = getEpisodeItem(
+        $item->title,
+        $itemUrl,
+        '',
+        'MP3'
+    );
+}
+
+function clientSupportsType($mimetype)
+{
+    if ($mimetype === 'audio/mpeg') {
+        return true;
+    }
+    $ip = $_SERVER['REMOTE_ADDR'];
+    if (isset($GLOBALS['clientSupport'][$ip][$mimetype])
+        && $GLOBALS['clientSupport'][$ip][$mimetype] === true
+    ) {
+        return true;
+    }
+    return false;
+}
+
+/**
+ * Single file mode - shows directories that only have a single file in them.
+ * Each audio file gets its own virtual directory, containing only the
+ * audio file itself.
+ *
+ * Useful children who want to listen a single story before sleeping,
+ * but the noxon's auto switch-off timer is not exactly at the end of
+ * the story. So the next story starts already, and the kid complains
+ * that it wanted to listen to that as well...
+ */
+function mediatombSingle(Services_MediaTomb $smt, $fullPath, $prefix)
+{
+    $path = substr($fullPath, strlen($prefix));
+
+    $parts = explode('/', $path);
+    $fileMode = false;
+    if (substr(end($parts), 0, 5) == 'file-') {
+        $fileMode = true;
+        $fileTitle = substr(end($parts), 5);
+        $path = substr($path, 0, -strlen($fileTitle) - 5);
+    }
+
+    $container = $smt->getContainerByPath($path);
+    $listItems = array();
+
+    $previous = null;
+    if ($fileMode) {
+        //show single file to play
+        $previous = buildPreviousItem(pathEncode($fullPath));
+        $item = $smt->getSingleItem($container, $fileTitle, false);
+        mediatombAddFile($listItems, $item);
+    } else {
+        $previous = buildPreviousItem(pathEncode('internetradio/' . $path . '/dummy'));
+
+        //browse directory
         foreach ($container->getItemIterator(false) as $item) {
-            $di = $item->getDetailedItem();
-            if ($di->mimetype !== 'audio/mpeg') {
-                //noxon iRadio cube does not want to play .ogg files
-                //FIXME: convert to mp3
-                //$di->location (on the server)
-            }
-            $listItems[] = getEpisodeItem(
+            $listItems[] = getDirItem(
                 $item->title,
-                $item->url,
-                '',
-                'MP3'
+                pathEncode($fullPath . 'file-' . $item->title)
             );
         }
-    } catch (Exception $e) {
-        sendMessage('Mediatomb error: ' . $e->getMessage());
-        return;
     }
 
-    sendListItems($listItems);
+    sendListItems($listItems, $previous);
 }
 ?>