You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

161 lines
4.0 KiB

<?php
/*
* This file is part of video_metadata.
*
* video_metadata is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* video_metadata 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with video_metadata. If not, see <https://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
const FOLDER_PATH = '../video/unwatched';
const MAX_RECURSE_DEPTH = 5;
$g_errors = [];
class path_entry
{
public $base_name = '';
public $full_path = '';
public $depth = 0;
public $media_type = 'unknown'; // 'movie' or 'tv_show' or 'unknown'
public $path_type = ''; // 'file' or 'directory'
public $file_extension = '';
public $content_size = 0;
public $contents = []; // directory contents, array of path_entry objects
public $parent = null; // reference to parent path_entry
}
function guessMediaType($filename) : string
{
$current_year = getdate()['year'];
if (false !== stristr($filename, 'season')) {
return 'tv_show';
} else if (preg_match('/s[0-9]{2}/i', $filename)) {
return 'tv_show';
// TODO: this will only match the first 4 digit number in the string
} else if (preg_match('/[0-9]{4}/', $filename, $match)) {
if ((int) $match[0] >= 1878 && (int) $match[0] <= $current_year)
return 'movie';
}
return 'unknown';
}
// NOTE: use parent reference to recursively set media types detected by children nodes
function setMediaType(&$path_entry, $media_type) : void
{
// NOTE: don't set media type of top-level directory
if ($path_entry->depth > 0) {
$path_entry->media_type = $media_type;
if ($path_entry->parent)
setMediaType($path_entry->parent, $media_type);
}
}
function getPathEntry($fs_path, $depth = 0, $media_type = '', &$parent = null) : ?path_entry
{
$pe = new path_entry();
$pe->base_name = basename($fs_path);
$pe->full_path = $fs_path;
$pe->depth = $depth;
if ($parent !== null)
$pe->parent =& $parent;
if ($depth != 0 && ($media_type == '' || $media_type == 'unknown'))
setMediaType($pe, guessMediaType($pe->base_name));
else
$pe->media_type = $media_type;
if (is_dir($fs_path) && is_readable($fs_path)) {
$pe->path_type = 'directory';
if ($depth <= MAX_RECURSE_DEPTH) {
foreach (scandir($fs_path) as $path) {
if ($path != '.' && $path != '..') {
$new_entry = getPathEntry($fs_path . '/' . $path, $depth + 1, $pe->media_type, $pe);
if ($new_entry !== null)
$pe->contents[] = $new_entry;
}
}
}
$pe->content_size = count($pe->contents);
} else if (is_file($fs_path)) {
$pe->path_type = 'file';
$pe->file_extension = pathinfo($fs_path, PATHINFO_EXTENSION);
if (!in_array($pe->file_extension, ['avi', 'mkv', 'm4v', 'mp4', 'mpg']))
return null;
} else {
global $g_errors;
$g_errors[] = __FUNCTION__ . ", invalid path: $fs_path";
return null;
}
return $pe;
}
function unsetParentReferences(&$path_entry) : void
{
unset($path_entry->parent);
foreach ($path_entry->contents as &$entry)
unsetParentReferences($entry);
}
function getUnsavedMetadata() : void
{
$path_info = getPathEntry(FOLDER_PATH);
global $g_errors;
$out = new StdClass();
header('Content-Type: text/json');
if (count($g_errors) == 0) {
unsetParentReferences($path_info); // NOTE: don't encode parent references
$out->mem_usage = memory_get_peak_usage();
$out->path_info = $path_info;
$json = json_encode($out);
if ($json)
echo $json;
else
echo '{"errors":"error enconding json in ' . __FUNCTION__ . '"}';
} else {
$out->errors = $g_errors;
echo json_encode($out);
}
}
function main() : void
{
switch (@$_GET['action']) {
case 'scan':
getUnsavedMetadata();
break;
case 'file_map';
//
break;
}
}
main();
?>