-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbrowser.php
More file actions
162 lines (146 loc) · 5.67 KB
/
Copy pathbrowser.php
File metadata and controls
162 lines (146 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
<?php
/*
* MiniDLNA Database Browser
*
* Author: Gergely Nagy <gna@r-us.hu>
* URL: https://github.com/gnanet/minidlna-browser-php
*
* Runs and tested with PHP8.3
*/
define('BASEPATH', __DIR__);
define('APP_SETTINGS_FILE', __DIR__.'/.env');
if ( ! file_exists(APP_SETTINGS_FILE) ) {
echo "Need ".APP_SETTINGS_FILE." for configuration".PHP_EOL;
echo "Use example.env as basis".PHP_EOL;
exit;
}
if ( ! file_exists(__DIR__ . '/vendor/autoload.php') ) {
echo "Run composer install, first".PHP_EOL;
exit;
}
// Autoload files using composer
require_once __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli-server') {
echo "Usage:".PHP_EOL;
echo "php -S 0.0.0.0:8299 browser.php".PHP_EOL;
exit;
}
// Use this namespace
use Symfony\Component\Dotenv\Dotenv;
// Use this namespace
use Steampixel\Route;
$dotenv = new Dotenv();
$dotenv->load(APP_SETTINGS_FILE);
$app_config = array(
'DATABASE' => $_SERVER['DATABASE'],
'BASE_URL' => $_SERVER['BASE_URL'],
'MPV_PLAY_URI' => $_SERVER['MPV_PLAY_URI'],
'ROOT_ID' => $_SERVER['ROOT_ID'],
'PFW_CMD' => (isset($_SERVER['PFW_CMD']) ? $_SERVER['PFW_CMD'] : ''),
'PFW_URL' => (isset($_SERVER['PFW_URL']) ? $_SERVER['PFW_URL'] : ''),
);
if ( ! file_exists($app_config['DATABASE']) ) {
error_log("Missing ".$app_config['DATABASE']);
exit;
}
// Initialize TWIG
$loader = new \Twig\Loader\FilesystemLoader( BASEPATH . '/templates');
$twig = new \Twig\Environment($loader, [
'cache' => false,
]);
function filesizeformat($bytes, $binary = false) {
$unit = 'Byte';
$prefix = '';
$bytes = (float)$bytes;
$base = $binary ? 1024 : 1000;
$prefixes = array('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y');
if ($bytes == 1) {
return '1 Byte';
} elseif ($bytes < $base) {
return $bytes . ' Bytes';
}
foreach ($prefixes as $i => $prefix) {
$unit = pow($base, ($i + 2));
if ($bytes < $unit) {
return sprintf('%.1f %s', ($base * $bytes / $unit), $prefix . ($binary ? 'iB' : 'B'));
}
}
return sprintf('%.1f %s', ($base * $bytes / $unit), $prefix . ($binary ? 'iB' : 'B'));
}
function browse($object_id = NULL) {
global $app_config, $twig;
$db = new SQLite3($app_config['DATABASE'], SQLITE3_OPEN_READONLY );
$root_path = $db->querySingle("SELECT VALUE FROM SETTINGS WHERE KEY = 'media_dir'");
$items = [];
$template_vars = [];
$breadcrumb_ids = [];
$breadcrumbs_string="";
if (( $object_id == NULL ) || ( $object_id == $app_config['ROOT_ID'] )) {
$object_id = $app_config['ROOT_ID'];
$path_array = array( 'PARENT_ID' => NULL, 'PATH' => NULL);
} else {
$path_array = $db->querySingle('select PARENT_ID, PATH FROM OBJECTS JOIN DETAILS ON OBJECTS.DETAIL_ID=DETAILS.ID WHERE OBJECT_ID = "'. $object_id.'"', true);
// Start making crumbles from bread
$path_elements = explode('$',$object_id);
$path_elements_cnt = count($path_elements);
$rpath_elements = array_reverse($path_elements);
$ei = 1; // skip the "home" item
while ($ei < $path_elements_cnt ) {
$breadcrumb_ids[] = urlencode(implode('$',$path_elements));
array_pop($path_elements);
$ei++;
};
$breadcrumb_ids=array_reverse($breadcrumb_ids);
$path_elements_title = explode("/",str_replace($root_path."/","",$path_array['PATH']));
$breadcrumbs = array_combine($breadcrumb_ids,$path_elements_title);
// build the HTML code-snippet for breadcrumbs
foreach ( $breadcrumbs as $crumb_id => $crumb_title ) {
$breadcrumbs_string .= ' <li class="breadcrumb-item';
if ( urlencode($object_id) == $crumb_id ) { $breadcrumbs_string .= " active"; }
$breadcrumbs_string .= '">'.PHP_EOL;
if ( urlencode($object_id) == $crumb_id ) {
$breadcrumbs_string .= ' <span data-minidlna-object-id="'.urldecode($crumb_id).'">'.$crumb_title.'</span>'.PHP_EOL;
} else {
$breadcrumbs_string .= ' <a href="/browse/'.$crumb_id.'/" data-minidlna-object-id="'.urldecode($crumb_id).'">'.$crumb_title.'</a>'.PHP_EOL;
}
$breadcrumbs_string .= ' </li>'.PHP_EOL;
}
// Finish building breadcrumbs
}
// build the media items of the current folder
$cur = $db->query('select OBJECTS.ID, CLASS, OBJECT_ID, NAME, PATH, TITLE, MIME, SIZE, DURATION, DETAIL_ID FROM OBJECTS JOIN DETAILS ON OBJECTS.DETAIL_ID=DETAILS.ID WHERE PARENT_ID="'.$object_id.'" ORDER BY CLASS ASC, NAME ASC, OBJECT_ID ASC');
while ($item = $cur->fetchArray()) {
$item = array_change_key_case($item);
$item['basename'] = basename($item['path']);
$item['filesizeformat'] = filesizeformat($item['size']);
$items[] = $item;
}
// set template variables
$template_vars = array(
'root_path' => $root_path,
'parent_id' => $path_array['PARENT_ID'],
'path' => $path_array['PATH'],
'breadcrumbs' => $breadcrumbs_string,
'items' => $items,
'BASE_URL' => $app_config['BASE_URL'],
'MPV_PLAY_URI' => $app_config['MPV_PLAY_URI'],
'root_id' => $app_config['ROOT_ID'],
'PFW_URL' => $app_config['PFW_URL'],
'PFW_CMD' => $app_config['PFW_CMD'],
);
// Render the result using twig
return $twig->render('browse.twig.html', $template_vars);
}
// build routes
// home
Route::add('/', function() {
global $app_config, $twig;
return browse();
});
// browse folders
Route::add('/browse/(.*)', function($object_id) {
global $app_config, $twig;
return browse($object_id);
});
// Run the router
Route::run('/');