diff --git a/.ci-trigger-0977 b/.ci-trigger-0977 new file mode 100644 index 0000000..d8fac25 --- /dev/null +++ b/.ci-trigger-0977 @@ -0,0 +1 @@ +0.9.7.7 diff --git a/include/nc_connector_scheduler.inc.php b/include/nc_connector_scheduler.inc.php index cea60a4..9a329e5 100644 --- a/include/nc_connector_scheduler.inc.php +++ b/include/nc_connector_scheduler.inc.php @@ -16,6 +16,7 @@ function bratonien_tools_nc_scheduler_paths() 'trigger_lock'=>$base.'/nc-connector-scheduler/trigger.lock', 'worker_lock'=>$base.'/nc-connector-scheduler/worker.lock', 'log'=>$base.'/nc-connector-scheduler/last-worker.log', + 'status_root'=>$base.'/nc-connector-status', ); } @@ -59,6 +60,31 @@ function bratonien_tools_nc_scheduler_write_state(array $state) return @rename($tmp, $paths['state']); } +function bratonien_tools_nc_scheduler_write_connection_status($connection_id, $state, $message) +{ + $connection_id = (int)$connection_id; + if ($connection_id < 1) return false; + $paths = bratonien_tools_nc_scheduler_paths(); + if (!bratonien_tools_nc_scheduler_ensure_dirs()) return false; + $target = $paths['status_root'].'/connection-'.$connection_id.'.json'; + $existing = array(); + if (is_readable($target)) + { + $decoded = json_decode((string)@file_get_contents($target), true); + if (is_array($decoded)) $existing = $decoded; + } + $existing['state'] = (string)$state; + $existing['message'] = (string)$message; + $existing['timestamp'] = time(); + $existing['connection_id'] = $connection_id; + $json = json_encode($existing, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); + if (!is_string($json)) return false; + $tmp = $target.'.tmp'; + if (@file_put_contents($tmp, $json."\n", LOCK_EX) === false) return false; + @chmod($tmp, 0644); + return @rename($tmp, $target); +} + function bratonien_tools_nc_scheduler_install() { if (!bratonien_tools_nc_scheduler_ensure_dirs()) return false; @@ -82,8 +108,9 @@ function bratonien_tools_nc_scheduler_php_binary() return ''; } -function bratonien_tools_nc_scheduler_spawn($force = false) +function bratonien_tools_nc_scheduler_spawn($force = false, $connection_id = 0) { + $connection_id = max(0, (int)$connection_id); $paths = bratonien_tools_nc_scheduler_paths(); if (!bratonien_tools_nc_scheduler_ensure_dirs()) { @@ -118,14 +145,20 @@ 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['message'] = $connection_id > 0 ? 'NC-Abgleich für Verbindung #'.$connection_id.' wurde angefordert.' : 'NC-Abgleich für alle Verbindungen wurde angefordert.'; $state['queued_at'] = $now; $state['timestamp'] = $now; + $state['connection_id'] = $connection_id; $state['next_due'] = $now + bratonien_tools_nc_scheduler_interval(); bratonien_tools_nc_scheduler_write_state($state); + if ($connection_id > 0) + { + bratonien_tools_nc_scheduler_write_connection_status($connection_id, 'queued', 'Abgleich wurde angefordert.'); + } $runner = BRATONIEN_TOOLS_PATH.'runtime/native-runner.php'; - $command = escapeshellarg($php).' '.escapeshellarg($runner).' >> '.escapeshellarg($paths['log']).' 2>&1 &'; + $runner_args = $connection_id > 0 ? ' --connection-id='.escapeshellarg((string)$connection_id) : ''; + $command = escapeshellarg($php).' '.escapeshellarg($runner).$runner_args.' >> '.escapeshellarg($paths['log']).' 2>&1 &'; $spec = array( 0=>array('file','/dev/null','r'), 1=>array('file','/dev/null','a'), @@ -144,10 +177,14 @@ function bratonien_tools_nc_scheduler_spawn($force = false) $state['message'] = 'Der native NC-Abgleich konnte nicht gestartet werden.'; $state['timestamp'] = time(); bratonien_tools_nc_scheduler_write_state($state); + if ($connection_id > 0) + { + bratonien_tools_nc_scheduler_write_connection_status($connection_id, 'error', 'Abgleich konnte nicht gestartet werden.'); + } throw new RuntimeException('Der native NC-Abgleich konnte nicht gestartet werden.'); } - return array('started'=>true, 'message'=>'NC-Abgleich wurde angefordert.'); + return array('started'=>true, 'message'=>$connection_id > 0 ? 'Abgleich für Verbindung #'.$connection_id.' wurde angefordert.' : 'Abgleich für alle Verbindungen wurde angefordert.'); } function bratonien_tools_nc_scheduler_tick() @@ -159,7 +196,7 @@ function bratonien_tools_nc_scheduler_tick() try { - bratonien_tools_nc_scheduler_spawn(false); + bratonien_tools_nc_scheduler_spawn(false, 0); } catch (Throwable $e) { diff --git a/include/nc_legacy_reset.inc.php b/include/nc_legacy_reset.inc.php new file mode 100644 index 0000000..cdf6f85 --- /dev/null +++ b/include/nc_legacy_reset.inc.php @@ -0,0 +1,115 @@ +time(), + 'removed_image_records'=>count($ids), + 'removed_generated_entries'=>$removed_files, + 'removed_state_files'=>$removed_state_files, + ); + + if (function_exists('conf_update_param')) + { + conf_update_param('bratonien_nc_legacy_reset_0977', json_encode($result)); + } + + return $result; +} diff --git a/include/tool_registry.inc.php b/include/tool_registry.inc.php index b49f033..3f00f0f 100644 --- a/include/tool_registry.inc.php +++ b/include/tool_registry.inc.php @@ -47,8 +47,17 @@ require_once(BRATONIEN_TOOLS_PATH . 'include/nc_connector_system.inc.php'); function bratonien_tools_nc_connector_run_now() { - $result = bratonien_tools_nc_scheduler_spawn(true); - return array('message'=>(string)($result['message'] ?? 'NC-Abgleich wurde gestartet.')); + $connection_id = isset($_POST['connection_id']) ? max(0, (int)$_POST['connection_id']) : 0; + if ($connection_id > 0) + { + $connection = bratonien_tools_nc_connector_connection($connection_id, false); + if (!$connection) + { + throw new RuntimeException('Die ausgewählte Verbindung existiert nicht.'); + } + } + $result = bratonien_tools_nc_scheduler_spawn(true, $connection_id); + return array('message'=>(string)($result['message'] ?? ($connection_id > 0 ? 'Abgleich wurde gestartet.' : 'Abgleich für alle Verbindungen wurde gestartet.'))); } function bratonien_tools_get_tools() diff --git a/main.inc.php b/main.inc.php index 1507d99..6064276 100644 --- a/main.inc.php +++ b/main.inc.php @@ -1,7 +1,7 @@ prepare($errors); + + if (version_compare((string)$old_version, '0.9.7.7', '<') && version_compare((string)$new_version, '0.9.7.7', '>=')) + { + try + { + bratonien_tools_nc_reset_legacy_imports(); + } + catch (Throwable $e) + { + $errors[] = 'Connector-Altbestand konnte nicht vollständig bereinigt werden: '.$e->getMessage(); + } + } } public function uninstall() diff --git a/runtime/native-runner.php b/runtime/native-runner.php index 817c54c..d4545dc 100644 --- a/runtime/native-runner.php +++ b/runtime/native-runner.php @@ -6,6 +6,9 @@ if (PHP_SAPI !== 'cli') exit(1); } +$options = getopt('', array('connection-id::')); +$connectionId = isset($options['connection-id']) ? (int)$options['connection-id'] : 0; + $pluginRoot = dirname(__DIR__); $piwigoRoot = dirname($pluginRoot, 2); $base = rtrim($piwigoRoot, '/').'/_data/bratonien-tools'; @@ -44,9 +47,10 @@ $state = native_scheduler_state($stateFile); $state['enabled'] = true; $state['mode'] = 'piwigo-native'; $state['state'] = 'running'; -$state['message'] = 'NC-Abgleich läuft.'; +$state['message'] = $connectionId > 0 ? 'NC-Abgleich für Verbindung #'.$connectionId.' läuft.' : 'NC-Abgleich läuft.'; $state['started_at'] = time(); $state['timestamp'] = time(); +$state['connection_id'] = $connectionId; native_scheduler_write($stateFile, $state); $env = $_ENV; @@ -55,6 +59,7 @@ $env['BRATONIEN_NC_NATIVE'] = '1'; $env['BRATONIEN_NC_PIWIGO_ROOT'] = $piwigoRoot; $env['BRATONIEN_NC_CONFIG_DIR'] = $runtimeDir; $env['BRATONIEN_NC_STATE_ROOT'] = $stateRoot; +$env['BRATONIEN_NC_CONNECTION_ID'] = (string)$connectionId; $env['LC_ALL'] = 'C'; $env['LANG'] = 'C'; @@ -86,10 +91,13 @@ $state = native_scheduler_state($stateFile); $state['enabled'] = true; $state['mode'] = 'piwigo-native'; $state['state'] = $exit === 0 ? 'success' : 'error'; -$state['message'] = $exit === 0 ? 'NC-Abgleich erfolgreich abgeschlossen.' : 'NC-Abgleich fehlgeschlagen.'; +$state['message'] = $exit === 0 + ? ($connectionId > 0 ? 'NC-Abgleich für Verbindung #'.$connectionId.' erfolgreich abgeschlossen.' : 'NC-Abgleich erfolgreich abgeschlossen.') + : ($connectionId > 0 ? 'NC-Abgleich für Verbindung #'.$connectionId.' fehlgeschlagen.' : 'NC-Abgleich fehlgeschlagen.'); $state['timestamp'] = time(); $state['finished_at'] = time(); $state['exit_code'] = $exit; +$state['connection_id'] = $connectionId; $state['stdout'] = trim($stdout); $state['stderr'] = trim($stderr); if (empty($state['next_due']) || (int)$state['next_due'] < time()) diff --git a/runtime/run-all.sh b/runtime/run-all.sh index 65582eb..631312b 100644 --- a/runtime/run-all.sh +++ b/runtime/run-all.sh @@ -5,6 +5,7 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" PIWIGO_ROOT_DEFAULT="${BRATONIEN_NC_PIWIGO_ROOT:-$(cd -- "$SCRIPT_DIR/../../.." && pwd)}" CONFIG_DIR="${BRATONIEN_NC_CONFIG_DIR:-/etc/bratonien-tools/nc-connector}" NATIVE_MODE="${BRATONIEN_NC_NATIVE:-0}" +TARGET_CONNECTION_ID="${BRATONIEN_NC_CONNECTION_ID:-0}" GLOBAL_LOCK_DIR="${PIWIGO_ROOT_DEFAULT%/}/_data/bratonien-tools/nc-connector-scheduler" GLOBAL_LOCK_FILE="$GLOBAL_LOCK_DIR/worker.lock" mkdir -p -- "$GLOBAL_LOCK_DIR" @@ -15,6 +16,11 @@ if ! flock -n 8; then fi shopt -s nullglob +if [[ ! "$TARGET_CONNECTION_ID" =~ ^[0-9]+$ ]]; then + echo "NC Connector: ungültige Ziel-Verbindungs-ID: $TARGET_CONNECTION_ID" >&2 + exit 1 +fi + read_config_value() { local key="$1" local file="$2" @@ -69,6 +75,10 @@ fi route_piwigo_root="" for candidate in "${webdav_configs[@]}" "${configs[@]}"; do [[ -f "$candidate" ]] || continue + candidate_id="$(read_config_value CONNECTION_ID "$candidate")" + if [[ "$TARGET_CONNECTION_ID" -gt 0 && "$candidate_id" != "$TARGET_CONNECTION_ID" ]]; then + continue + fi route_piwigo_root="$(read_config_value PIWIGO_ROOT "$candidate")" [[ -n "$route_piwigo_root" ]] && break done @@ -79,6 +89,7 @@ failure_count=0 webdav_count=0 local_count=0 summary_parts=() +matched_count=0 for config in "${webdav_configs[@]}"; do [[ -f "$config" ]] || continue @@ -90,7 +101,11 @@ for config in "${webdav_configs[@]}"; do summary_parts+=("$name: ungueltige Verbindungs-ID") continue fi + if [[ "$TARGET_CONNECTION_ID" -gt 0 && "$connection_id" != "$TARGET_CONNECTION_ID" ]]; then + continue + fi + matched_count=$((matched_count + 1)) webdav_count=$((webdav_count + 1)) echo "NC Connector WebDAV #$connection_id: $name" output="" @@ -119,7 +134,11 @@ if [[ "$NATIVE_MODE" != "1" ]]; then summary_parts+=("$name: ungueltige Verbindungs-ID") continue fi + if [[ "$TARGET_CONNECTION_ID" -gt 0 && "$connection_id" != "$TARGET_CONNECTION_ID" ]]; then + continue + fi + matched_count=$((matched_count + 1)) piwigo_root="$(read_config_value PIWIGO_ROOT "$config")" [[ -n "$piwigo_root" ]] || piwigo_root="$PIWIGO_ROOT_DEFAULT" tombstone_dir="${piwigo_root%/}/_data/bratonien-tools/nc-connector-status" @@ -145,6 +164,12 @@ if [[ "$NATIVE_MODE" != "1" ]]; then done fi +if [[ "$TARGET_CONNECTION_ID" -gt 0 && "$matched_count" -eq 0 ]]; then + write_route_status "failed" "FEHLER - Verbindung #$TARGET_CONNECTION_ID" "Keine Laufzeitkonfiguration für Verbindung #$TARGET_CONNECTION_ID gefunden." "0" + echo "NC Connector: keine Laufzeitkonfiguration für Verbindung #$TARGET_CONNECTION_ID gefunden." >&2 + exit 1 +fi + summary_detail="$(IFS='; '; printf '%s' "${summary_parts[*]}")" [[ -n "$summary_detail" ]] || summary_detail="Keine Verbindung wurde ausgefuehrt." @@ -160,10 +185,10 @@ if [[ "$failure_count" -eq 0 ]]; then label="Local" fi write_route_status "$route" "$label" "$summary_detail" "1" - echo "NC Connector: alle Verbindungen wurden erfolgreich verarbeitet." + echo "NC Connector: angeforderte Verbindung wurde erfolgreich verarbeitet." exit 0 fi -write_route_status "failed" "FEHLER - mindestens eine Verbindung" "$summary_detail" "0" -echo "NC Connector: mindestens eine Verbindung ist fehlgeschlagen." >&2 +write_route_status "failed" "FEHLER - angeforderte Verbindung" "$summary_detail" "0" +echo "NC Connector: die angeforderte Verbindung ist fehlgeschlagen." >&2 exit 1