fix: make media inventory discovery deterministic
This commit is contained in:
1 parent
4426969d63
commit
a5cee5e98f
4 files changed
+8
-8
No files matched your search
BIN
Binary file not shown.
+2
-2
@@ -8,7 +8,7 @@
|
|||||||
<!ENTITY pluginLOC "/boot/config/plugins/&name;">
|
<!ENTITY pluginLOC "/boot/config/plugins/&name;">
|
||||||
<!ENTITY emhttpLOC "/usr/local/emhttp/plugins/&name;">
|
<!ENTITY emhttpLOC "/usr/local/emhttp/plugins/&name;">
|
||||||
<!ENTITY txzURL "http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.24.r020-x86_64-1.txz">
|
<!ENTITY txzURL "http://192.168.1.2:4000/michael/MUA-Mikes-Unraid-Agent/raw/branch/main/dist/mua-2026.08.24.r020-x86_64-1.txz">
|
||||||
<!ENTITY txzSHA256 "8172c825494216ca3c969816054483fd6fdca2c9dc18b54257061ec0be2d8048">
|
<!ENTITY txzSHA256 "ad4d2f0b8d52f4a7cea0ae99bf5c7f7aebedc60488bb8d88c70cf43beacdb538">
|
||||||
]>
|
]>
|
||||||
|
|
||||||
<PLUGIN name="&name;"
|
<PLUGIN name="&name;"
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<CHANGES>
|
<CHANGES>
|
||||||
### 2026.08.24.r020
|
### 2026.08.24.r020
|
||||||
- Neues begrenztes Nur-Lese-Werkzeug `unraid_files_inventory` erfasst Datei- und Ordnernamen eines Shares in einem Aufruf, ohne Dateiinhalte zu lesen.
|
- Neues begrenztes Nur-Lese-Werkzeug `unraid_files_inventory` erfasst Datei- und Ordnernamen eines Shares in einem Aufruf, ohne Dateiinhalte zu lesen.
|
||||||
- Ein Namensfilter findet gezielt Sammlungsordner und liefert deren Nachfahren; Medien- und Folgenprüfungen benötigen keine Kette aus wiederholten `ls`/`find`-Aufrufen mehr.
|
- Ein Namensfilter findet gezielt Sammlungsordner; ein zweiter gebündelter Aufruf inventarisiert den exakten Treffer. Medienprüfungen benötigen keine Kette aus wiederholten `ls`/`find`-Aufrufen mehr.
|
||||||
- Bestehende Freigaben der Nur-Lese-Shell erhalten das engere Inventarwerkzeug automatisch, ohne Schreibrechte hinzuzufügen.
|
- Bestehende Freigaben der Nur-Lese-Shell erhalten das engere Inventarwerkzeug automatisch, ohne Schreibrechte hinzuzufügen.
|
||||||
|
|
||||||
### 2026.08.24.r019
|
### 2026.08.24.r019
|
||||||
|
|||||||
@@ -263,14 +263,14 @@ function files_inventory(
|
|||||||
$max_depth = max(1, min(20, $max_depth));
|
$max_depth = max(1, min(20, $max_depth));
|
||||||
$max_entries = max(1, min(5000, $max_entries));
|
$max_entries = max(1, min(5000, $max_entries));
|
||||||
$needle = mb_strtolower(trim($name_contains));
|
$needle = mb_strtolower(trim($name_contains));
|
||||||
$queue = [[$root, '', 0, $needle === '']];
|
$queue = [[$root, '', 0]];
|
||||||
$entries = [];
|
$entries = [];
|
||||||
$scanned = 0;
|
$scanned = 0;
|
||||||
$max_scanned = max(1000, min(100000, $max_entries * 50));
|
$max_scanned = max(1000, min(100000, $max_entries * 50));
|
||||||
$truncated = false;
|
$truncated = false;
|
||||||
|
|
||||||
while ($queue) {
|
while ($queue) {
|
||||||
[$directory, $directory_relative, $depth, $inside_match] = array_shift($queue);
|
[$directory, $directory_relative, $depth] = array_shift($queue);
|
||||||
if ($depth >= $max_depth) continue;
|
if ($depth >= $max_depth) continue;
|
||||||
$children = @scandir($directory);
|
$children = @scandir($directory);
|
||||||
if (!is_array($children)) continue;
|
if (!is_array($children)) continue;
|
||||||
@@ -282,7 +282,7 @@ function files_inventory(
|
|||||||
$is_link = is_link($full);
|
$is_link = is_link($full);
|
||||||
$is_dir = !$is_link && is_dir($full);
|
$is_dir = !$is_link && is_dir($full);
|
||||||
$matches = $needle === '' || mb_stripos($relative, $needle) !== false;
|
$matches = $needle === '' || mb_stripos($relative, $needle) !== false;
|
||||||
$selected = $inside_match || $matches;
|
$selected = $matches;
|
||||||
$scanned++;
|
$scanned++;
|
||||||
if ($scanned > $max_scanned) {
|
if ($scanned > $max_scanned) {
|
||||||
$truncated = true;
|
$truncated = true;
|
||||||
@@ -304,7 +304,7 @@ function files_inventory(
|
|||||||
break 2;
|
break 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($is_dir) $queue[] = [$full, $relative, $depth + 1, $inside_match || $matches];
|
if ($is_dir) $queue[] = [$full, $relative, $depth + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -536,13 +536,13 @@ export const TOOLS: ToolDef[] = [
|
|||||||
{
|
{
|
||||||
name: "unraid_files_inventory",
|
name: "unraid_files_inventory",
|
||||||
description:
|
description:
|
||||||
"Inventory file and directory names below one exact Unraid share in one bounded read-only call. Use this instead of repeated ls/find calls for media-library audits, missing-episode checks and locating a named collection. It never reads file contents. If name_contains matches a directory, that directory and its descendants are returned; unrelated trees are omitted.",
|
"Inventory file and directory names below one exact Unraid share in a bounded read-only call. Use this instead of repeated ls/find calls for media-library audits and missing-episode checks. It never reads file contents. To locate a collection, first search directories with name_contains; then call this tool once more with the returned directory as relative_path and an empty name_contains to inventory that collection.",
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: "object",
|
type: "object",
|
||||||
properties: {
|
properties: {
|
||||||
share: str("Exact Unraid share name, for example Audiobooks"),
|
share: str("Exact Unraid share name, for example Audiobooks"),
|
||||||
relative_path: str("Optional path below the share; never use /mnt/user or an absolute path"),
|
relative_path: str("Optional path below the share; never use /mnt/user or an absolute path"),
|
||||||
name_contains: str("Optional case-insensitive name fragment, for example 'drei'. Matching directories include their descendants"),
|
name_contains: str("Optional case-insensitive path fragment, for example 'drei'. It filters returned entries; use a second call on a matched directory to list its descendants"),
|
||||||
max_depth: int("Maximum directory depth below relative_path (1-20, default 10)"),
|
max_depth: int("Maximum directory depth below relative_path (1-20, default 10)"),
|
||||||
max_entries: int("Maximum returned entries (1-5000, default 2000)"),
|
max_entries: int("Maximum returned entries (1-5000, default 2000)"),
|
||||||
include_files: { type: "boolean", description: "Include files (default true)" },
|
include_files: { type: "boolean", description: "Include files (default true)" },
|
||||||
|
|||||||
Reference in new issue
Block a user