<commit_before><?php
/* php-dlna v1.0
 * Copyright 2014 <NAME> (<EMAIL>)
 *
 * This file is part of php-dlna.

 *   php-dlna is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License version 3
 *   as published by the Free Software Foundation
 *
 *   php-dlna 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 can get a copy The GNU Affero General Public license from
 *   http://www.gnu.org/licenses/agpl-3.0.html
 *
 * This program was initially a fork of umspx (https://code.google.com/p/umspx/)
 * umspx is copyright <NAME> <<EMAIL>>
*/
error_reporting(E_ALL | E_STRICT);
/*
http://www.upnp.org/specs/av/UPnP-av-ContentDirectory-v1-Service.pdf
https://github.com/ronenmiz/TVersity/wiki/Content-Directory-Metadata
 */

require_once("config.php");
require_once("didl.php");
require_once("polyfills.php");

function _debug($someText, $someVar = null) {
    $logFile = "/tmp/phpdlna-debug.txt";
    $fh = fopen($logFile, 'a') or die();
    fwrite($fh, date('Y.m.d H:i:s') . ' ' . $someText . "\n");
    if ($someVar) fwrite($fh, print_r($someVar, true) . "\n");
    fclose($fh);
}

class InvalidInputException extends Exception { }

class ContentDirectory {
    private function lookup_real_path($id) {
        // hide realpath by mapping folders to numbers: 1.1.2 is second folder in the first folder
        // under the first configured root..  prevent infoleak by listing non-shared folders.
        $path_key = explode('.', $id);
        $key = intval(array_shift($path_key));
        if ($key > count(Config::$folders)) throw new InvalidInputException();
        $path = Config::$folders[$key-1]['hostpath'];
        $webpath=Config::$folders[$key-1]['webpath'];

        _debug("mapping..");
        foreach ($path_key as $key) {
            $folderid=0;
            $folders=array();
            foreach (new DirectoryIterator($path) as $fileInfo) {
                if($fileInfo->isDot()) continue;
                if(!$fileInfo->isDir()) continue;
                $folders[] = $fileInfo->getFilename();
            }
            sort($folders);
            if ($key > count($folders)) throw new InvalidInputException();
            $path.=$folders[$key-1].'/';
            $webpath.=$folders[$key-1].'/';
        }
        return array($path, $webpath);
    }

    function Search($req) {
        //TODO: implement :)
        //TODO: Consider $req->StartingIndex and $req->RequestedCount
        $items = new DIDL(DIDL::ROOT_ID);
        return array('Result'=>$items->getXML(), 'NumberReturned'=>$items->count, 'TotalMatches'=>$items->count, 'UpdateID'=>13);
    }
    function Browse($req) {
        //TODO (maybe): Consider $req->Filter

        # The objectId should be '0' for the root container.
        if ($req->BrowseFlag == 'BrowseDirectChildren')
            $items = new DIDL($req->ObjectID);
        else if ($req->ObjectID == '0') {
            _debug("root metadata: ".$req->BrowseFlag);
            $items = new DIDL(DIDL::ROOT_ID);

            $items->addFolder("root", '0')
                ->searchclass("object.item.audioItem")
                ->searchclass("object.item.videoItem")
                ->searchclass("object.item.imageItem");
            return $items;
        } else {
            _debug("Don't really know what to do here objid=".$req->ObjectID);
            $items = new DIDL(0);
        }
        _debug("Direct children of ".$req->ObjectID);

        if ($req->ObjectID == '0') { //ROOT
            $folderid=0;
            foreach (Config::$folders as $folder) {
                $items->addFolder(basename($folder['webpath']), sprintf("%d", ++$folderid))
                ->creator('Creator')
                ->genre('Genre')
                ->artist('Artist')
                ->author('Author')
                ->album('Album')
                ->date('2014-01-01')
                ->actor('Actor')
                ->director('Director')
//                 ->icon(MEDIABASE.'/that_folder/folder.jpg')();
                ;
            }
        } else {
            try {
                list($path, $webpath) = $this->lookup_real_path($req->ObjectID);
            } catch (InvalidInputException $e) {
                return array('illegal');
            }

            _debug("listing: ".$path);
            $folders=array();
            $files=array();
            foreach (new DirectoryIterator($path) as $fileInfo) {
                if ($fileInfo->isDot()) continue;
                if ($fileInfo->isDir()) {
                    $folders[] = $fileInfo->getFilename();
                } else {
                    $files[] = $fileInfo->getFilename();
                }
            }
            sort($files);
            sort($folders);

            $folderid=0;
            foreach ($folders as $f) {
                $itm = $items->addFolder($f, sprintf('%s.%d', $req->ObjectID, ++$folderid));
                foreach (array('folder.png','folder.jpg','album.png','album.jpg') as $icon) {
                    if (file_exists($path.$f.'/'.$icon)) {
                        $itm->icon($webpath.$f."/".$icon);
                        break;
                    }
                }
            }

            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            foreach ($files as $f)
            {
                $ct = finfo_file($finfo, $path.$f);

                $fname = pathinfo($f, PATHINFO_FILENAME);
                if (substr($ct, 0, 6) === 'video/') {
                    $itm = $items->addVideo(str_replace(array('.','_'),' ', $fname));
                } else if (substr($ct, 0, 6) === 'audio/') {
                    $itm = $items->addSong(str_replace(array('.','_'),' ', $fname));
                } else
                    continue;
                $itm->resource($webpath.$f, array('filesize'=>filesize($path.$f)))
                    //->creator('Creator')
                    //->genre('Genre')
                    //->artist('Artist')<commit_msg>keep file name fixup in a single function<commit_after><?php
/* php-dlna v1.0
 * Copyright 2014 <NAME> (<EMAIL>)
 *
 * This file is part of php-dlna.

 *   php-dlna is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU Affero General Public License version 3
 *   as published by the Free Software Foundation
 *
 *   php-dlna 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 can get a copy The GNU Affero General Public license from
 *   http://www.gnu.org/licenses/agpl-3.0.html
 *
 * This program was initially a fork of umspx (https://code.google.com/p/umspx/)
 * umspx is copyright <NAME> <<EMAIL>>
*/
error_reporting(E_ALL | E_STRICT);
/*
http://www.upnp.org/specs/av/UPnP-av-ContentDirectory-v1-Service.pdf
https://github.com/ronenmiz/TVersity/wiki/Content-Directory-Metadata
 */

require_once("config.php");
require_once("didl.php");
require_once("polyfills.php");

function _debug($someText, $someVar = null) {
    $logFile = "/tmp/phpdlna-debug.txt";
    $fh = fopen($logFile, 'a') or die();
    fwrite($fh, date('Y.m.d H:i:s') . ' ' . $someText . "\n");
    if ($someVar) fwrite($fh, print_r($someVar, true) . "\n");
    fclose($fh);
}

function demangle_fname($fname)
{
    return str_replace(array('.','_'),' ', $fname);
}

class InvalidInputException extends Exception { }

class ContentDirectory {
    private function lookup_real_path($id) {
        // hide realpath by mapping folders to numbers: 1.1.2 is second folder in the first folder
        // under the first configured root..  prevent infoleak by listing non-shared folders.
        $path_key = explode('.', $id);
        $key = intval(array_shift($path_key));
        if ($key > count(Config::$folders)) throw new InvalidInputException();
        $path = Config::$folders[$key-1]['hostpath'];
        $webpath=Config::$folders[$key-1]['webpath'];

        _debug("mapping..");
        foreach ($path_key as $key) {
            $folderid=0;
            $folders=array();
            foreach (new DirectoryIterator($path) as $fileInfo) {
                if($fileInfo->isDot()) continue;
                if(!$fileInfo->isDir()) continue;
                $folders[] = $fileInfo->getFilename();
            }
            sort($folders);
            if ($key > count($folders)) throw new InvalidInputException();
            $path.=$folders[$key-1].'/';
            $webpath.=$folders[$key-1].'/';
        }
        return array($path, $webpath);
    }

    function Search($req) {
        //TODO: implement :)
        //TODO: Consider $req->StartingIndex and $req->RequestedCount
        $items = new DIDL(DIDL::ROOT_ID);
        return array('Result'=>$items->getXML(), 'NumberReturned'=>$items->count, 'TotalMatches'=>$items->count, 'UpdateID'=>13);
    }
    function Browse($req) {
        //TODO (maybe): Consider $req->Filter

        # The objectId should be '0' for the root container.
        if ($req->BrowseFlag == 'BrowseDirectChildren')
            $items = new DIDL($req->ObjectID);
        else if ($req->ObjectID == '0') {
            _debug("root metadata: ".$req->BrowseFlag);
            $items = new DIDL(DIDL::ROOT_ID);

            $items->addFolder("root", '0')
                ->searchclass("object.item.audioItem")
                ->searchclass("object.item.videoItem")
                ->searchclass("object.item.imageItem");
            return $items;
        } else {
            _debug("Don't really know what to do here objid=".$req->ObjectID);
            $items = new DIDL(0);
        }
        _debug("Direct children of ".$req->ObjectID);

        if ($req->ObjectID == '0') { //ROOT
            $folderid=0;
            foreach (Config::$folders as $folder) {
                $items->addFolder(basename($folder['webpath']), sprintf("%d", ++$folderid))
                ->creator('Creator')
                ->genre('Genre')
                ->artist('Artist')
                ->author('Author')
                ->album('Album')
                ->date('2014-01-01')
                ->actor('Actor')
                ->director('Director')
//                 ->icon(MEDIABASE.'/that_folder/folder.jpg')();
                ;
            }
        } else {
            try {
                list($path, $webpath) = $this->lookup_real_path($req->ObjectID);
            } catch (InvalidInputException $e) {
                return array('illegal');
            }

            _debug("listing: ".$path);
            $folders=array();
            $files=array();
            foreach (new DirectoryIterator($path) as $fileInfo) {
                if ($fileInfo->isDot()) continue;
                if ($fileInfo->isDir()) {
                    $folders[] = $fileInfo->getFilename();
                } else {
                    $files[] = $fileInfo->getFilename();
                }
            }
            sort($files);
            sort($folders);

            $folderid=0;
            foreach ($folders as $f) {
                $itm = $items->addFolder($f, sprintf('%s.%d', $req->ObjectID, ++$folderid));
                foreach (array('folder.png','folder.jpg','album.png','album.jpg') as $icon) {
                    if (file_exists($path.$f.'/'.$icon)) {
                        $itm->icon($webpath.$f."/".$icon);
                        break;
                    }
                }
            }

            $finfo = finfo_open(FILEINFO_MIME_TYPE);
            foreach ($files as $f)
            {
                $ct = finfo_file($finfo, $path.$f);

                $fname = pathinfo($f, PATHINFO_FILENAME);
                if (substr($ct, 0, 6) === 'video/') {
                    $itm = $items->addVideo(demangle_fname($fname));
                } else if (substr($ct, 0, 6) === 'audio/') {
                    $itm = $items->addSong(demangle_fname($fname));
                } else
                    continue;
                $itm->resource($webpath.$f, array('filesize'=>filesize($path.$f)))
                    //->creator('Creator')
                    //->genre('Genre')
                    //->artist('Artist')
{'fraction_non_alphanumeric': 0.16051764327626397, 'fraction_numerical': 0.006269592476489028, 'mean_word_length': 1.8988816402609505, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 117, 'https://': 4, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3572250', 'n_tokens_mistral': 3779, 'n_tokens_neox': 3598, 'n_words': 797}