mirror of
https://github.com/Terranom674/Piwigo_Bratonien_Tools.git
synced 2026-09-19 19:54:31 +00:00
Compare commits
2 Commits
fix/09629-
...
fix/09629-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
298710e9d6 | ||
|
|
8f1162519e |
@@ -52,18 +52,7 @@ function bratonien_tools_nc_find_album($parent_id, $dir, $name, $excluded_site_i
|
||||
$where_parent = $parent_id === null ? 'id_uppercat IS NULL' : 'id_uppercat='.(int)$parent_id;
|
||||
$dir_sql = pwg_db_real_escape_string((string)$dir);
|
||||
$name_sql = pwg_db_real_escape_string((string)$name);
|
||||
$query = '
|
||||
SELECT id, dir, name
|
||||
FROM '.CATEGORIES_TABLE.'
|
||||
WHERE '.$where_parent.'
|
||||
AND (site_id IS NULL OR site_id <> '.(int)$excluded_site_id.')
|
||||
AND (
|
||||
dir = \''.$dir_sql.'\'
|
||||
OR LOWER(name) = LOWER(\''.$name_sql.'\')
|
||||
)
|
||||
ORDER BY CASE WHEN dir = \''.$dir_sql.'\' THEN 0 ELSE 1 END, id
|
||||
LIMIT 1
|
||||
;';
|
||||
$query = '\nSELECT id, dir, name\n FROM '.CATEGORIES_TABLE.'\n WHERE '.$where_parent.'\n AND (site_id IS NULL OR site_id <> '.(int)$excluded_site_id.')\n AND (\n dir = \\''.$dir_sql.'\\'\n OR LOWER(name) = LOWER(\\''.$name_sql.'\\')\n )\n ORDER BY CASE WHEN dir = \\''.$dir_sql.'\\' THEN 0 ELSE 1 END, id\n LIMIT 1\n;';
|
||||
$result = pwg_query($query);
|
||||
if (!pwg_db_num_rows($result)) return null;
|
||||
$row = pwg_db_fetch_assoc($result);
|
||||
|
||||
22
runtime/lib/build_webdav_placeholder_source.py
Executable file → Normal file
22
runtime/lib/build_webdav_placeholder_source.py
Executable file → Normal file
@@ -3,7 +3,7 @@
|
||||
|
||||
This creates only tiny placeholder files plus a metadata mapping; no Nextcloud
|
||||
original media is downloaded. The authenticated Nextcloud user is never used as
|
||||
an album name.
|
||||
an album name. Selecting the user's WebDAV root mirrors its children directly.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -249,32 +249,20 @@ def main() -> int:
|
||||
|
||||
for remote_root_raw in args.root:
|
||||
remote_root = validate_relative(remote_root_raw)
|
||||
current, root_children = client.list_collection(remote_root)
|
||||
current, _ = client.list_collection(remote_root)
|
||||
fileid = int(current["fileid"])
|
||||
if fileid in used_fileids:
|
||||
fail(f"duplicate selected Nextcloud root fileid: {fileid}")
|
||||
used_fileids.add(fileid)
|
||||
# An explicitly selected folder keeps its own name. The authenticated
|
||||
# user's WebDAV root is transparent and must never become an album.
|
||||
display = "" if remote_root == "" else (str(current.get("display_name", "")).strip() or PurePosixPath(remote_root).name)
|
||||
local_name = f"root-{fileid}"
|
||||
local_root = staging / local_name
|
||||
files, folders, skipped = build_root(client, remote_root, local_root, seed, mapping)
|
||||
total_files += files
|
||||
total_folders += folders
|
||||
total_skipped += skipped
|
||||
|
||||
if remote_root == "":
|
||||
for child in sorted(root_children, key=lambda item: str(item.get("display_name", "")).casefold()):
|
||||
name = safe_local_name(str(child.get("display_name", "")))
|
||||
child_fileid = int(child.get("fileid", 0))
|
||||
if child_fileid < 1:
|
||||
fail(f"Nextcloud returned no stable fileid for root child {name!r}")
|
||||
child_path = source_dir / local_name / name
|
||||
if bool(child.get("is_dir")):
|
||||
manifest.append(f"webdav:{child_fileid}\tfolder\t{name}\t{child_path}")
|
||||
elif Path(name).suffix.lower() in SUPPORTED_IMAGE_EXTENSIONS:
|
||||
manifest.append(f"webdav:{child_fileid}\tfile\t{name}\t{child_path}")
|
||||
continue
|
||||
|
||||
display = str(current.get("display_name", "")).strip() or PurePosixPath(remote_root).name
|
||||
manifest.append(f"webdav:{fileid}\tfolder\t{display}\t{source_dir / local_name}")
|
||||
|
||||
if previous.exists():
|
||||
|
||||
0
runtime/lib/piwigo-sync.php
Executable file → Normal file
0
runtime/lib/piwigo-sync.php
Executable file → Normal file
31
runtime/lib/shadow_tree.py
Executable file → Normal file
31
runtime/lib/shadow_tree.py
Executable file → Normal file
@@ -79,15 +79,23 @@ def preferred_target(source_key: str, raw_name: str, parent_target: Path, old_ma
|
||||
return safe_name(raw_name)
|
||||
|
||||
|
||||
def mirror_directory(source: Path, target: Path, source_key: str, target_key: Path, old_map: dict[str, str], new_map: dict[str, str]) -> None:
|
||||
def mirror_directory(
|
||||
source: Path,
|
||||
target: Path,
|
||||
source_key: str,
|
||||
target_key: Path,
|
||||
old_map: dict[str, str],
|
||||
new_map: dict[str, str],
|
||||
used: set[str] | None = None,
|
||||
) -> None:
|
||||
target.mkdir(parents=True, exist_ok=True)
|
||||
used: set[str] = set()
|
||||
used_names = used if used is not None else set()
|
||||
for child in sorted(source.iterdir(), key=lambda item: (item.name.casefold(), item.name)):
|
||||
if child.is_symlink():
|
||||
continue
|
||||
child_source_key = f"{source_key}/{child.name}"
|
||||
preferred = preferred_target(child_source_key, child.name, target_key, old_map)
|
||||
child_name = unique_name(preferred, used, child.is_file())
|
||||
child_name = unique_name(preferred, used_names, child.is_file())
|
||||
child_target = target / child_name
|
||||
child_target_key = target_key / child_name
|
||||
new_map[child_source_key] = child_target_key.as_posix()
|
||||
@@ -120,11 +128,26 @@ def build(manifest: Path, destination: Path, state_file: Path) -> None:
|
||||
|
||||
try:
|
||||
used_roots: set[str] = set()
|
||||
transparent_roots = 0
|
||||
for entry in sorted(entries, key=lambda item: (item["display_name"].casefold(), item["share_id"])):
|
||||
source = Path(entry["source_path"])
|
||||
source_key = f"share:{entry['share_id']}"
|
||||
preferred = preferred_target(source_key, entry["display_name"], Path("."), old_map)
|
||||
is_file_share = entry["item_type"] == "file"
|
||||
|
||||
# Empty display_name is intentional: it represents the authenticated
|
||||
# user's WebDAV root. Its children belong directly at destination;
|
||||
# the Nextcloud username must never become an album wrapper.
|
||||
if not is_file_share and entry["display_name"] == "":
|
||||
transparent_roots += 1
|
||||
if transparent_roots > 1:
|
||||
raise ValueError("only one transparent WebDAV root is allowed")
|
||||
if not source.is_dir():
|
||||
raise FileNotFoundError(f"source is not a readable directory: {source}")
|
||||
new_map[source_key] = "."
|
||||
mirror_directory(source, staging, source_key, Path("."), old_map, new_map, used_roots)
|
||||
continue
|
||||
|
||||
preferred = preferred_target(source_key, entry["display_name"], Path("."), old_map)
|
||||
root_name = unique_name(preferred, used_roots, is_file_share)
|
||||
root_key = Path(root_name)
|
||||
new_map[source_key] = root_key.as_posix()
|
||||
|
||||
Reference in New Issue
Block a user