Merge pull request #29 from Terranom674/fix/0974-gallery-derivative-only

0.9.7.7: Connector-Altbestand einmalig zurücksetzen
This commit is contained in:
Terranom674
2026-08-19 21:50:57 +02:00
committed by GitHub
8 changed files with 221 additions and 13 deletions

1
.ci-trigger-0977 Normal file
View File

@@ -0,0 +1 @@
0.9.7.7

View File

@@ -16,6 +16,7 @@ function bratonien_tools_nc_scheduler_paths()
'trigger_lock'=>$base.'/nc-connector-scheduler/trigger.lock', 'trigger_lock'=>$base.'/nc-connector-scheduler/trigger.lock',
'worker_lock'=>$base.'/nc-connector-scheduler/worker.lock', 'worker_lock'=>$base.'/nc-connector-scheduler/worker.lock',
'log'=>$base.'/nc-connector-scheduler/last-worker.log', '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']); 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() function bratonien_tools_nc_scheduler_install()
{ {
if (!bratonien_tools_nc_scheduler_ensure_dirs()) return false; if (!bratonien_tools_nc_scheduler_ensure_dirs()) return false;
@@ -82,8 +108,9 @@ function bratonien_tools_nc_scheduler_php_binary()
return ''; 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(); $paths = bratonien_tools_nc_scheduler_paths();
if (!bratonien_tools_nc_scheduler_ensure_dirs()) if (!bratonien_tools_nc_scheduler_ensure_dirs())
{ {
@@ -118,14 +145,20 @@ function bratonien_tools_nc_scheduler_spawn($force = false)
$state['enabled'] = true; $state['enabled'] = true;
$state['mode'] = 'piwigo-native'; $state['mode'] = 'piwigo-native';
$state['state'] = 'queued'; $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['queued_at'] = $now;
$state['timestamp'] = $now; $state['timestamp'] = $now;
$state['connection_id'] = $connection_id;
$state['next_due'] = $now + bratonien_tools_nc_scheduler_interval(); $state['next_due'] = $now + bratonien_tools_nc_scheduler_interval();
bratonien_tools_nc_scheduler_write_state($state); 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'; $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( $spec = array(
0=>array('file','/dev/null','r'), 0=>array('file','/dev/null','r'),
1=>array('file','/dev/null','a'), 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['message'] = 'Der native NC-Abgleich konnte nicht gestartet werden.';
$state['timestamp'] = time(); $state['timestamp'] = time();
bratonien_tools_nc_scheduler_write_state($state); 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.'); 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() function bratonien_tools_nc_scheduler_tick()
@@ -159,7 +196,7 @@ function bratonien_tools_nc_scheduler_tick()
try try
{ {
bratonien_tools_nc_scheduler_spawn(false); bratonien_tools_nc_scheduler_spawn(false, 0);
} }
catch (Throwable $e) catch (Throwable $e)
{ {

View File

@@ -0,0 +1,115 @@
<?php
if (!defined('PHPWG_ROOT_PATH'))
{
die('Hacking attempt!');
}
function bratonien_tools_nc_legacy_remove_tree($path, $allowed_root)
{
$path = rtrim(str_replace('\\', '/', (string)$path), '/');
$allowed_root = rtrim(str_replace('\\', '/', (string)$allowed_root), '/');
if ($path === '' || $allowed_root === '' || $path === $allowed_root || strpos($path, $allowed_root.'/') !== 0)
{
return 0;
}
if (!file_exists($path) && !is_link($path)) return 0;
if (is_link($path) || is_file($path))
{
return @unlink($path) ? 1 : 0;
}
$removed = 0;
$items = @scandir($path);
if (is_array($items))
{
foreach ($items as $item)
{
if ($item === '.' || $item === '..') continue;
$removed += bratonien_tools_nc_legacy_remove_tree($path.'/'.$item, $allowed_root);
}
}
if (@rmdir($path)) $removed++;
return $removed;
}
function bratonien_tools_nc_legacy_remove_state_files($state_root)
{
$removed = 0;
foreach (glob(rtrim($state_root, '/').'/connection-*') ?: array() as $connection_dir)
{
if (!is_dir($connection_dir)) continue;
foreach (array('webdav-map.json', 'webdav-manifest.tsv', 'webdav-shadow-map.json') as $name)
{
$path = $connection_dir.'/'.$name;
if (is_file($path) && @unlink($path)) $removed++;
}
}
return $removed;
}
function bratonien_tools_nc_reset_legacy_imports()
{
include_once(PHPWG_ROOT_PATH.'admin/include/functions.php');
$ids = array();
$result = pwg_query(
"SELECT id FROM ".IMAGES_TABLE.
" WHERE path LIKE '%nc-webdav-source/connection-%'"
);
while ($row = pwg_db_fetch_assoc($result))
{
$ids[] = (int)$row['id'];
}
if ($ids)
{
delete_elements($ids, false);
}
$data_root = rtrim(PHPWG_ROOT_PATH, '/').'/_data';
$tool_root = $data_root.'/bratonien-tools';
$removed_files = 0;
foreach (array(
$tool_root.'/nc-webdav-source',
$tool_root.'/nc-webdav-preview',
$tool_root.'/nc-webdav-gallery',
) as $generated_root)
{
$removed_files += bratonien_tools_nc_legacy_remove_tree($generated_root, $data_root);
}
if (defined('PWG_DERIVATIVE_DIR'))
{
$derivative_root = rtrim(PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR, '/');
foreach (array(
$derivative_root.'/_data/bratonien-tools/nc-webdav-source',
$derivative_root.'/_data/bratonien-tools/nc-webdav-gallery',
) as $generated_derivative_root)
{
$removed_files += bratonien_tools_nc_legacy_remove_tree($generated_derivative_root, $derivative_root);
}
}
$removed_state_files = bratonien_tools_nc_legacy_remove_state_files($tool_root.'/nc-connector-state');
if ($ids)
{
update_category('all');
invalidate_user_cache(true);
}
$result = array(
'timestamp'=>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;
}

View File

@@ -47,8 +47,17 @@ require_once(BRATONIEN_TOOLS_PATH . 'include/nc_connector_system.inc.php');
function bratonien_tools_nc_connector_run_now() function bratonien_tools_nc_connector_run_now()
{ {
$result = bratonien_tools_nc_scheduler_spawn(true); $connection_id = isset($_POST['connection_id']) ? max(0, (int)$_POST['connection_id']) : 0;
return array('message'=>(string)($result['message'] ?? 'NC-Abgleich wurde gestartet.')); 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() function bratonien_tools_get_tools()

View File

@@ -1,7 +1,7 @@
<?php <?php
/* /*
Plugin Name: Bratonien Tools Plugin Name: Bratonien Tools
Version: 0.9.7.6 Version: 0.9.7.7
Description: Erweiterbare Administrationswerkzeuge fuer die Bratonien-Piwigo-Installation. Description: Erweiterbare Administrationswerkzeuge fuer die Bratonien-Piwigo-Installation.
Plugin URI: https://github.com/Terranom674/Piwigo_Bratonien_Tools Plugin URI: https://github.com/Terranom674/Piwigo_Bratonien_Tools
Author: Bratonien Author: Bratonien

View File

@@ -9,6 +9,7 @@ require_once(dirname(__FILE__) . '/include/database.class.php');
require_once(dirname(__FILE__) . '/tools/watermark_profiles.inc.php'); require_once(dirname(__FILE__) . '/tools/watermark_profiles.inc.php');
require_once(dirname(__FILE__) . '/include/dependencies.inc.php'); require_once(dirname(__FILE__) . '/include/dependencies.inc.php');
require_once(dirname(__FILE__) . '/include/nc_connector_scheduler.inc.php'); require_once(dirname(__FILE__) . '/include/nc_connector_scheduler.inc.php');
require_once(dirname(__FILE__) . '/include/nc_legacy_reset.inc.php');
class bratonien_tools_maintain extends PluginMaintain class bratonien_tools_maintain extends PluginMaintain
{ {
@@ -51,6 +52,18 @@ class bratonien_tools_maintain extends PluginMaintain
public function update($old_version, $new_version, &$errors = array()) public function update($old_version, $new_version, &$errors = array())
{ {
$this->prepare($errors); $this->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() public function uninstall()

View File

@@ -6,6 +6,9 @@ if (PHP_SAPI !== 'cli')
exit(1); exit(1);
} }
$options = getopt('', array('connection-id::'));
$connectionId = isset($options['connection-id']) ? (int)$options['connection-id'] : 0;
$pluginRoot = dirname(__DIR__); $pluginRoot = dirname(__DIR__);
$piwigoRoot = dirname($pluginRoot, 2); $piwigoRoot = dirname($pluginRoot, 2);
$base = rtrim($piwigoRoot, '/').'/_data/bratonien-tools'; $base = rtrim($piwigoRoot, '/').'/_data/bratonien-tools';
@@ -44,9 +47,10 @@ $state = native_scheduler_state($stateFile);
$state['enabled'] = true; $state['enabled'] = true;
$state['mode'] = 'piwigo-native'; $state['mode'] = 'piwigo-native';
$state['state'] = 'running'; $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['started_at'] = time();
$state['timestamp'] = time(); $state['timestamp'] = time();
$state['connection_id'] = $connectionId;
native_scheduler_write($stateFile, $state); native_scheduler_write($stateFile, $state);
$env = $_ENV; $env = $_ENV;
@@ -55,6 +59,7 @@ $env['BRATONIEN_NC_NATIVE'] = '1';
$env['BRATONIEN_NC_PIWIGO_ROOT'] = $piwigoRoot; $env['BRATONIEN_NC_PIWIGO_ROOT'] = $piwigoRoot;
$env['BRATONIEN_NC_CONFIG_DIR'] = $runtimeDir; $env['BRATONIEN_NC_CONFIG_DIR'] = $runtimeDir;
$env['BRATONIEN_NC_STATE_ROOT'] = $stateRoot; $env['BRATONIEN_NC_STATE_ROOT'] = $stateRoot;
$env['BRATONIEN_NC_CONNECTION_ID'] = (string)$connectionId;
$env['LC_ALL'] = 'C'; $env['LC_ALL'] = 'C';
$env['LANG'] = 'C'; $env['LANG'] = 'C';
@@ -86,10 +91,13 @@ $state = native_scheduler_state($stateFile);
$state['enabled'] = true; $state['enabled'] = true;
$state['mode'] = 'piwigo-native'; $state['mode'] = 'piwigo-native';
$state['state'] = $exit === 0 ? 'success' : 'error'; $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['timestamp'] = time();
$state['finished_at'] = time(); $state['finished_at'] = time();
$state['exit_code'] = $exit; $state['exit_code'] = $exit;
$state['connection_id'] = $connectionId;
$state['stdout'] = trim($stdout); $state['stdout'] = trim($stdout);
$state['stderr'] = trim($stderr); $state['stderr'] = trim($stderr);
if (empty($state['next_due']) || (int)$state['next_due'] < time()) if (empty($state['next_due']) || (int)$state['next_due'] < time())

View File

@@ -5,6 +5,7 @@ SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PIWIGO_ROOT_DEFAULT="${BRATONIEN_NC_PIWIGO_ROOT:-$(cd -- "$SCRIPT_DIR/../../.." && pwd)}" PIWIGO_ROOT_DEFAULT="${BRATONIEN_NC_PIWIGO_ROOT:-$(cd -- "$SCRIPT_DIR/../../.." && pwd)}"
CONFIG_DIR="${BRATONIEN_NC_CONFIG_DIR:-/etc/bratonien-tools/nc-connector}" CONFIG_DIR="${BRATONIEN_NC_CONFIG_DIR:-/etc/bratonien-tools/nc-connector}"
NATIVE_MODE="${BRATONIEN_NC_NATIVE:-0}" 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_DIR="${PIWIGO_ROOT_DEFAULT%/}/_data/bratonien-tools/nc-connector-scheduler"
GLOBAL_LOCK_FILE="$GLOBAL_LOCK_DIR/worker.lock" GLOBAL_LOCK_FILE="$GLOBAL_LOCK_DIR/worker.lock"
mkdir -p -- "$GLOBAL_LOCK_DIR" mkdir -p -- "$GLOBAL_LOCK_DIR"
@@ -15,6 +16,11 @@ if ! flock -n 8; then
fi fi
shopt -s nullglob 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() { read_config_value() {
local key="$1" local key="$1"
local file="$2" local file="$2"
@@ -69,6 +75,10 @@ fi
route_piwigo_root="" route_piwigo_root=""
for candidate in "${webdav_configs[@]}" "${configs[@]}"; do for candidate in "${webdav_configs[@]}" "${configs[@]}"; do
[[ -f "$candidate" ]] || continue [[ -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")" route_piwigo_root="$(read_config_value PIWIGO_ROOT "$candidate")"
[[ -n "$route_piwigo_root" ]] && break [[ -n "$route_piwigo_root" ]] && break
done done
@@ -79,6 +89,7 @@ failure_count=0
webdav_count=0 webdav_count=0
local_count=0 local_count=0
summary_parts=() summary_parts=()
matched_count=0
for config in "${webdav_configs[@]}"; do for config in "${webdav_configs[@]}"; do
[[ -f "$config" ]] || continue [[ -f "$config" ]] || continue
@@ -90,7 +101,11 @@ for config in "${webdav_configs[@]}"; do
summary_parts+=("$name: ungueltige Verbindungs-ID") summary_parts+=("$name: ungueltige Verbindungs-ID")
continue continue
fi 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)) webdav_count=$((webdav_count + 1))
echo "NC Connector WebDAV #$connection_id: $name" echo "NC Connector WebDAV #$connection_id: $name"
output="" output=""
@@ -119,7 +134,11 @@ if [[ "$NATIVE_MODE" != "1" ]]; then
summary_parts+=("$name: ungueltige Verbindungs-ID") summary_parts+=("$name: ungueltige Verbindungs-ID")
continue continue
fi 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")" piwigo_root="$(read_config_value PIWIGO_ROOT "$config")"
[[ -n "$piwigo_root" ]] || piwigo_root="$PIWIGO_ROOT_DEFAULT" [[ -n "$piwigo_root" ]] || piwigo_root="$PIWIGO_ROOT_DEFAULT"
tombstone_dir="${piwigo_root%/}/_data/bratonien-tools/nc-connector-status" tombstone_dir="${piwigo_root%/}/_data/bratonien-tools/nc-connector-status"
@@ -145,6 +164,12 @@ if [[ "$NATIVE_MODE" != "1" ]]; then
done done
fi 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[*]}")" summary_detail="$(IFS='; '; printf '%s' "${summary_parts[*]}")"
[[ -n "$summary_detail" ]] || summary_detail="Keine Verbindung wurde ausgefuehrt." [[ -n "$summary_detail" ]] || summary_detail="Keine Verbindung wurde ausgefuehrt."
@@ -160,10 +185,10 @@ if [[ "$failure_count" -eq 0 ]]; then
label="Local" label="Local"
fi fi
write_route_status "$route" "$label" "$summary_detail" "1" 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 exit 0
fi fi
write_route_status "failed" "FEHLER - mindestens eine Verbindung" "$summary_detail" "0" write_route_status "failed" "FEHLER - angeforderte Verbindung" "$summary_detail" "0"
echo "NC Connector: mindestens eine Verbindung ist fehlgeschlagen." >&2 echo "NC Connector: die angeforderte Verbindung ist fehlgeschlagen." >&2
exit 1 exit 1