From 0b405e9efb724fc9dba6abddd2b9a06ab61a3d03 Mon Sep 17 00:00:00 2001 From: Terranom674 Date: Wed, 19 Aug 2026 20:48:25 +0200 Subject: [PATCH 1/5] 0.9.7.2: Abgleich sofort als angefordert markieren --- include/nc_connector_scheduler.inc.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/nc_connector_scheduler.inc.php b/include/nc_connector_scheduler.inc.php index b07577d..cea60a4 100644 --- a/include/nc_connector_scheduler.inc.php +++ b/include/nc_connector_scheduler.inc.php @@ -117,7 +117,10 @@ function bratonien_tools_nc_scheduler_spawn($force = false) $state['enabled'] = true; $state['mode'] = 'piwigo-native'; + $state['state'] = 'queued'; + $state['message'] = 'NC-Abgleich wurde angefordert.'; $state['queued_at'] = $now; + $state['timestamp'] = $now; $state['next_due'] = $now + bratonien_tools_nc_scheduler_interval(); bratonien_tools_nc_scheduler_write_state($state); @@ -136,10 +139,15 @@ function bratonien_tools_nc_scheduler_spawn($force = false) if ($exit !== 0) { + $state = bratonien_tools_nc_scheduler_read_state(); + $state['state'] = 'error'; + $state['message'] = 'Der native NC-Abgleich konnte nicht gestartet werden.'; + $state['timestamp'] = time(); + bratonien_tools_nc_scheduler_write_state($state); throw new RuntimeException('Der native NC-Abgleich konnte nicht gestartet werden.'); } - return array('started'=>true, 'message'=>'NC-Abgleich wurde gestartet.'); + return array('started'=>true, 'message'=>'NC-Abgleich wurde angefordert.'); } function bratonien_tools_nc_scheduler_tick() From 4847d2ff113e9cdcc971c588b217b8e160318c52 Mon Sep 17 00:00:00 2001 From: Terranom674 Date: Wed, 19 Aug 2026 20:48:48 +0200 Subject: [PATCH 2/5] 0.9.7.2: aktuellen Schedulerstatus in Statuskarte spiegeln --- include/nc_connector_system.inc.php | 31 +++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/include/nc_connector_system.inc.php b/include/nc_connector_system.inc.php index caa2138..34b462e 100644 --- a/include/nc_connector_system.inc.php +++ b/include/nc_connector_system.inc.php @@ -67,7 +67,9 @@ function bratonien_tools_nc_connector_system_status(array $connections = array() { $scheduler = bratonien_tools_nc_scheduler_read_state(); $enabled = !isset($scheduler['enabled']) || !empty($scheduler['enabled']); - $running = (string)($scheduler['state'] ?? '') === 'running'; + $scheduler_state = (string)($scheduler['state'] ?? ''); + $running = $scheduler_state === 'running'; + $queued = $scheduler_state === 'queued'; $started = (int)($scheduler['started_at'] ?? 0); $next = (int)($scheduler['next_due'] ?? 0); $last = bratonien_tools_nc_connector_last_status($connections); @@ -81,10 +83,23 @@ function bratonien_tools_nc_connector_system_status(array $connections = array() $next_label = 'Beim nächsten Piwigo-Aufruf'; } - if ((int)$last['timestamp'] <= 0 && !empty($scheduler['finished_at'])) + $scheduler_timestamp = (int)($scheduler['timestamp'] ?? 0); + if ($scheduler_timestamp > (int)$last['timestamp']) + { + $last['timestamp'] = $scheduler_timestamp; + $last['state'] = $scheduler_state; + $last['message'] = (string)($scheduler['message'] ?? ''); + if ($scheduler_state === 'error') + { + $detail = trim((string)($scheduler['stderr'] ?? '')); + if ($detail === '') $detail = trim((string)($scheduler['stdout'] ?? '')); + $last['error_detail'] = $detail; + } + } + elseif ((int)$last['timestamp'] <= 0 && !empty($scheduler['finished_at'])) { $last['timestamp'] = (int)$scheduler['finished_at']; - $last['state'] = (string)($scheduler['state'] ?? ''); + $last['state'] = $scheduler_state; $last['message'] = (string)($scheduler['message'] ?? ''); if ((string)$last['state'] === 'error') { @@ -94,13 +109,17 @@ function bratonien_tools_nc_connector_system_status(array $connections = array() } } + $current_label = 'Kein Lauf aktiv'; + if ($queued) $current_label = 'Abgleich angefordert'; + if ($running) $current_label = $started > 0 ? 'Läuft seit '.date('d.m.Y H:i:s', $started) : 'Läuft gerade'; + return array( 'timer_name'=>'Piwigo nativer NC-Scheduler', 'timer_active'=>$enabled, 'timer_enabled'=>$enabled, - 'service_active'=>$running, - 'current_run_timestamp'=>$started, - 'current_run_label'=>$running ? ($started > 0 ? 'Läuft seit '.date('d.m.Y H:i:s', $started) : 'Läuft gerade') : 'Kein Lauf aktiv', + 'service_active'=>$running || $queued, + 'current_run_timestamp'=>$queued ? (int)($scheduler['queued_at'] ?? 0) : $started, + 'current_run_label'=>$current_label, 'last_run_timestamp'=>(int)$last['timestamp'], 'last_run_label'=>(int)$last['timestamp'] > 0 ? date('d.m.Y H:i:s', (int)$last['timestamp']) : 'Nicht verfügbar', 'last_run_state'=>(string)$last['state'], From fc3d855e5e2d654ec90de745f3bf3bc03747c038 Mon Sep 17 00:00:00 2001 From: Terranom674 Date: Wed, 19 Aug 2026 20:49:18 +0200 Subject: [PATCH 3/5] 0.9.7.2: Version anheben --- main.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.inc.php b/main.inc.php index 53c06dc..29c8076 100644 --- a/main.inc.php +++ b/main.inc.php @@ -1,7 +1,7 @@ Date: Wed, 19 Aug 2026 20:51:23 +0200 Subject: [PATCH 4/5] 0.9.7.2: WebDAV-Sync nicht-destruktiv machen --- include/nc_productive_ws.inc.php | 42 ++++++++++---------------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/include/nc_productive_ws.inc.php b/include/nc_productive_ws.inc.php index 29f9fd1..d0d7037 100644 --- a/include/nc_productive_ws.inc.php +++ b/include/nc_productive_ws.inc.php @@ -56,7 +56,6 @@ function bratonien_tools_nc_find_album($parent_id, $dir, $name, $excluded_site_i 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.'\') @@ -122,10 +121,9 @@ function bratonien_tools_nc_managed_images($basedir) function bratonien_tools_nc_remove_storage_categories($site_id) { - $ids = query2array('SELECT id FROM '.CATEGORIES_TABLE.' WHERE site_id='.(int)$site_id.' AND dir IS NOT NULL', null, 'id'); - if (!$ids) return 0; - delete_categories(array_map('intval', $ids)); - return count($ids); + // Bestehende Piwigo-Alben gehoeren nicht automatisch dem Connector. + // Ohne eindeutige Connector-Eigentumsmarkierung darf hier nichts geloescht werden. + return 0; } function bratonien_tools_ws_nc_sync_productive($params, &$service) @@ -169,8 +167,6 @@ function bratonien_tools_ws_nc_sync_productive($params, &$service) try { - $counts['removed_duplicate_categories'] = bratonien_tools_nc_remove_storage_categories($site_id); - list($dbnow) = pwg_db_fetch_row(pwg_query('SELECT NOW()')); $fs_dirs = $site_reader->get_full_directories($basedir); usort($fs_dirs, function($a, $b) @@ -199,20 +195,10 @@ function bratonien_tools_ws_nc_sync_productive($params, &$service) $db_elements = bratonien_tools_nc_managed_images($basedir); $db_by_path = array_flip($db_elements); - $to_delete = array(); - foreach ($db_elements as $id=>$path) - { - if (!array_key_exists($path, $fs)) $to_delete[] = (int)$id; - } - if ($to_delete) - { - delete_elements($to_delete, false); - $counts['del_elements'] = count($to_delete); - foreach ($to_delete as $id) - { - if (isset($db_elements[$id])) unset($db_by_path[$db_elements[$id]], $db_elements[$id]); - } - } + // Nicht-destruktiver Schutz: Bestehende Piwigo-Bilder werden niemals allein + // deshalb geloescht, weil sie im aktuellen WebDAV-Scan nicht vorkommen. + // Das Entfernen ist erst wieder zulaessig, wenn Connector-Eigentum eindeutig + // und verbindungsbezogen gespeichert wird. $next_element_id = pwg_db_nextval('id', IMAGES_TABLE); $image_inserts = array(); @@ -232,13 +218,9 @@ function bratonien_tools_ws_nc_sync_productive($params, &$service) if (isset($db_by_path[$path])) { - $id = (int)$db_by_path[$path]; - $all_ids[] = $id; - pwg_query('DELETE FROM '.IMAGE_CATEGORY_TABLE.' WHERE image_id='.$id); - if ($category_id !== null) - { - single_insert(IMAGE_CATEGORY_TABLE, array('image_id'=>$id, 'category_id'=>$category_id)); - } + // Altbestand niemals umhaengen. Vorhandene Bild-Album-Zuordnungen bleiben + // exakt bestehen; der Connector darf nur neue Datensaetze ergaenzen. + $all_ids[] = (int)$db_by_path[$path]; continue; } @@ -276,8 +258,10 @@ function bratonien_tools_ws_nc_sync_productive($params, &$service) $counts['new_elements'] = count($new_ids); } + // Bestehende Bilder werden nicht durch den Connector aktualisiert. Nur neu + // angelegte Connector-Bilder erhalten die aus der Quelle ermittelten Attribute. $updates = array(); - foreach ($all_ids as $id) + foreach ($new_ids as $id) { $path_result = pwg_query('SELECT path FROM '.IMAGES_TABLE.' WHERE id='.(int)$id.' LIMIT 1'); if (!pwg_db_num_rows($path_result)) continue; From 017cbdbd3b95f28a3dbb0ce05d249f7ce746216b Mon Sep 17 00:00:00 2001 From: Terranom674 Date: Wed, 19 Aug 2026 20:52:16 +0200 Subject: [PATCH 5/5] =?UTF-8?q?0.9.7.2:=20private=20Alben=20nicht=20von=20?= =?UTF-8?q?=C3=B6ffentlichen=20Regeln=20erben=20lassen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/album_rules.inc.php | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/tools/album_rules.inc.php b/tools/album_rules.inc.php index eae4c7b..101767a 100644 --- a/tools/album_rules.inc.php +++ b/tools/album_rules.inc.php @@ -93,7 +93,37 @@ function bratonien_tools_resolve_album_rule($category_id, array $categories, arr $by_id[(int)$category['id']] = $category; } - $current = (int)$category_id; + $category_id = (int)$category_id; + $root = $by_id[$category_id] ?? null; + $is_private = $root && isset($root['status']) && $root['status'] === 'private'; + + // Privat ist eine Vererbungsgrenze. Eine direkt auf diesem privaten Album + // gesetzte Regel bleibt moeglich, aber Regeln oeffentlicher Eltern duerfen + // nicht in ein privates Album hineinvererbt werden. + if ($is_private) + { + if (isset($rules[$category_id])) + { + $rule = $rules[$category_id]; + if ($rule['mode'] === 'disabled') + { + return array('mode'=>'disabled','profile_id'=>null,'source'=>'album'); + } + if ($rule['mode'] === 'profile') + { + return array('mode'=>'profile','profile_id'=>(int)$rule['profile_id'],'source'=>'album'); + } + } + + $profile_id = $defaults['private_profile'] ?? null; + if (empty($profile_id)) + { + return array('mode'=>'disabled','profile_id'=>null,'source'=>'global'); + } + return array('mode'=>'profile','profile_id'=>(int)$profile_id,'source'=>'global'); + } + + $current = $category_id; $visited = array(); while ($current > 0 && isset($by_id[$current]) && !isset($visited[$current])) @@ -116,10 +146,7 @@ function bratonien_tools_resolve_album_rule($category_id, array $categories, arr $current = (int)($by_id[$current]['id_uppercat'] ?? 0); } - $root = $by_id[(int)$category_id] ?? null; - $is_private = $root && isset($root['status']) && $root['status'] === 'private'; - $profile_id = $is_private ? ($defaults['private_profile'] ?? null) : ($defaults['public_profile'] ?? null); - + $profile_id = $defaults['public_profile'] ?? null; if (empty($profile_id)) { return array('mode'=>'disabled','profile_id'=>null,'source'=>'global');