Compare commits

...

22 Commits

Author SHA1 Message Date
Terranom674
86c0a75c7b Bump version to 0.9.3.27 2026-08-17 22:46:56 +02:00
Terranom674
7ad1d91b1b Fix productive API sync template context 2026-08-17 22:46:43 +02:00
Terranom674
eb45f6df74 Bump Bratonien Tools to 0.9.3.26 2026-08-17 22:44:07 +02:00
Terranom674
943e3c0aa7 NC Connector: persist concrete auth failure details 2026-08-17 22:43:47 +02:00
Terranom674
29001b7ccd NC Connector: expose Piwigo API HTTP error details 2026-08-17 22:43:02 +02:00
Terranom674
754d574626 Bump version to 0.9.3.25 2026-08-17 22:27:04 +02:00
Terranom674
6d34f321bb NC Connector: auto refresh admin after connector runs 2026-08-17 22:26:44 +02:00
Terranom674
d02a441cb7 NC Connector: add admin status polling endpoint 2026-08-17 22:26:18 +02:00
Terranom674
4ca2e0eba8 NC Connector: read UI status from Piwigo data directory 2026-08-17 22:26:05 +02:00
Terranom674
9e498e8fd0 NC Connector: write UI status into Piwigo data directory 2026-08-17 22:25:15 +02:00
Terranom674
9d30f7742b Bump Bratonien Tools to 0.9.3.24 2026-08-17 22:19:17 +02:00
Terranom674
64a4d72230 Read NC connector status from web-readable runtime status path 2026-08-17 22:19:00 +02:00
Terranom674
cf65bc0971 Write NC connector status to web-readable status directory 2026-08-17 22:18:38 +02:00
Terranom674
1db97e77fb Bump NC connector status fix to 0.9.3.23 2026-08-17 22:16:31 +02:00
Terranom674
aa506e7bfe Fix NC connector status lookup for active runtime connections 2026-08-17 22:16:13 +02:00
Terranom674
cea048a2ff Bump version to 0.9.3.22 2026-08-17 22:02:35 +02:00
Terranom674
cbf350a898 NC Connector: show API and fallback failures in admin status 2026-08-17 22:02:16 +02:00
Terranom674
7c6b019303 NC Connector: attach detailed sync state to admin view 2026-08-17 22:01:20 +02:00
Terranom674
7aa9343192 NC Connector: expose detailed per-connection sync status 2026-08-17 22:00:52 +02:00
Terranom674
5405ab0174 NC Connector: persist API and fallback sync diagnostics 2026-08-17 22:00:18 +02:00
Terranom674
aab3ae07ea Bump version to 0.9.3.21 2026-08-17 21:50:04 +02:00
Terranom674
a9a54720bb Fix XML reflection method discovery 2026-08-17 21:49:47 +02:00
10 changed files with 419 additions and 84 deletions

View File

@@ -77,6 +77,7 @@ $private_albums = bratonien_tools_get_private_albums();
$nc_connector = bratonien_tools_nc_connector_status();
foreach ($nc_connector['connections'] as &$nc_connection)
{
$nc_connection['last_sync'] = bratonien_tools_nc_connector_connection_last_status($nc_connection);
if (!empty($nc_connection['fallback_stored']))
{
$nc_connection['name'] .= ' · Fallback gespeichert';
@@ -97,6 +98,12 @@ $nc_system_defaults = array(
'last_run_label' => 'Nicht verfügbar',
'last_run_state' => '',
'last_run_message' => '',
'last_run_auth_mode' => '',
'last_run_api_state' => '',
'last_run_api_message' => '',
'last_run_fallback_state' => '',
'last_run_fallback_message' => '',
'last_run_error_detail' => '',
'next_run_timestamp' => 0,
'next_run_label' => 'Nicht verfügbar',
'legacy_runtime_exists' => false,

View File

@@ -86,6 +86,38 @@ function bratonien_tools_nc_connector_api_payload(array $decoded)
return $decoded;
}
function bratonien_tools_nc_connector_collect_method_names($value, array &$methods)
{
if (is_string($value))
{
$value = trim($value);
if ($value !== '' && preg_match('/^[A-Za-z0-9_]+(?:\.[A-Za-z0-9_]+)+$/', $value))
{
$methods[$value] = true;
}
return;
}
if (!is_array($value))
{
return;
}
if (isset($value['name']) && is_string($value['name']))
{
$name = trim($value['name']);
if ($name !== '')
{
$methods[$name] = true;
}
}
foreach ($value as $entry)
{
bratonien_tools_nc_connector_collect_method_names($entry, $methods);
}
}
function bratonien_tools_nc_connector_piwigo_api_request($api_key_id, $api_key_secret, $method)
{
if (!function_exists('curl_init'))
@@ -175,30 +207,10 @@ function bratonien_tools_nc_connector_piwigo_api_test()
}
$method_result = bratonien_tools_nc_connector_piwigo_api_request($api_key_id, $api_key_secret, 'reflection.getMethodList');
$methods = array();
if (is_array($method_result))
{
if (isset($method_result['method']))
{
$entries = is_array($method_result['method']) ? $method_result['method'] : array($method_result['method']);
}
else
{
$entries = $method_result;
}
foreach ($entries as $entry)
{
if (is_string($entry))
{
$methods[] = $entry;
}
elseif (is_array($entry) && isset($entry['name']))
{
$methods[] = (string)$entry['name'];
}
}
}
$method_map = array();
bratonien_tools_nc_connector_collect_method_names($method_result, $method_map);
$methods = array_keys($method_map);
sort($methods, SORT_STRING);
$required_methods = array('bratonien.nc.syncProductive', 'bratonien.nc.syncOrphans');
$missing = array_values(array_diff($required_methods, $methods));
@@ -213,7 +225,6 @@ function bratonien_tools_nc_connector_piwigo_api_test()
{
return preg_match('/sync|synchron|site/i', (string)$method) === 1;
}));
sort($sync_candidates, SORT_STRING);
$result = array(
'ok' => true,

View File

@@ -94,9 +94,79 @@ function bratonien_tools_nc_connector_next_from_timer_list($timer)
return 0;
}
function bratonien_tools_nc_connector_connection_last_status(array $connection)
{
$empty = array(
'timestamp'=>0,
'label'=>'Nicht verfügbar',
'state'=>'',
'message'=>'',
'auth_mode'=>'',
'api_state'=>'',
'api_message'=>'',
'fallback_state'=>'',
'fallback_message'=>'',
'error_detail'=>'',
);
$connection_id = (int)($connection['id'] ?? 0);
$candidates = array();
if ($connection_id > 0)
{
$candidates[] = rtrim(PHPWG_ROOT_PATH, '/').'/_data/bratonien-tools/nc-connector-status/connection-'.$connection_id.'.json';
}
$config = isset($connection['config']) && is_array($connection['config']) ? $connection['config'] : array();
$state_dir = rtrim((string)($config['state_dir'] ?? ''), '/');
if ($state_dir === '' && $connection_id > 0)
{
$state_dir = '/var/lib/bratonien-tools/nc-connector/connection-'.$connection_id;
}
if ($state_dir !== '')
{
$candidates[] = $state_dir.'/connector-status.json';
}
$decoded = null;
foreach ($candidates as $candidate)
{
if (!is_readable($candidate))
{
continue;
}
$value = json_decode((string)@file_get_contents($candidate), true);
if (is_array($value))
{
$decoded = $value;
break;
}
}
if (!is_array($decoded))
{
return $empty;
}
$timestamp = (int)($decoded['timestamp'] ?? 0);
$api = isset($decoded['api']) && is_array($decoded['api']) ? $decoded['api'] : array();
$fallback = isset($decoded['fallback']) && is_array($decoded['fallback']) ? $decoded['fallback'] : array();
return array(
'timestamp'=>$timestamp,
'label'=>$timestamp > 0 ? date('d.m.Y H:i:s', $timestamp) : 'Nicht verfügbar',
'state'=>(string)($decoded['state'] ?? ''),
'message'=>(string)($decoded['message'] ?? ''),
'auth_mode'=>(string)($decoded['auth_mode'] ?? ''),
'api_state'=>(string)($api['state'] ?? ''),
'api_message'=>(string)($api['message'] ?? ''),
'fallback_state'=>(string)($fallback['state'] ?? ''),
'fallback_message'=>(string)($fallback['message'] ?? ''),
'error_detail'=>(string)($decoded['error_detail'] ?? ''),
);
}
function bratonien_tools_nc_connector_last_status(array $connections)
{
$latest = array('timestamp'=>0, 'state'=>'', 'message'=>'');
$latest = array('timestamp'=>0, 'state'=>'', 'message'=>'', 'auth_mode'=>'', 'api_state'=>'', 'api_message'=>'', 'fallback_state'=>'', 'fallback_message'=>'', 'error_detail'=>'');
foreach ($connections as $connection)
{
@@ -105,33 +175,10 @@ function bratonien_tools_nc_connector_last_status(array $connections)
continue;
}
$config = isset($connection['config']) && is_array($connection['config']) ? $connection['config'] : array();
$state_dir = rtrim((string)($config['state_dir'] ?? ''), '/');
if ($state_dir === '')
$status = bratonien_tools_nc_connector_connection_last_status($connection);
if ((int)$status['timestamp'] >= (int)$latest['timestamp'])
{
continue;
}
$status_path = $state_dir.'/connector-status.json';
if (!is_readable($status_path))
{
continue;
}
$decoded = json_decode((string)@file_get_contents($status_path), true);
if (!is_array($decoded))
{
continue;
}
$timestamp = (int)($decoded['timestamp'] ?? 0);
if ($timestamp >= $latest['timestamp'])
{
$latest = array(
'timestamp' => $timestamp,
'state' => (string)($decoded['state'] ?? ''),
'message' => (string)($decoded['message'] ?? ''),
);
$latest = $status;
}
}
@@ -175,6 +222,12 @@ function bratonien_tools_nc_connector_system_status(array $connections = array()
'last_run_label' => $last['timestamp'] > 0 ? date('d.m.Y H:i:s', (int)$last['timestamp']) : 'Nicht verfügbar',
'last_run_state' => (string)$last['state'],
'last_run_message' => (string)$last['message'],
'last_run_auth_mode' => (string)$last['auth_mode'],
'last_run_api_state' => (string)$last['api_state'],
'last_run_api_message' => (string)$last['api_message'],
'last_run_fallback_state' => (string)$last['fallback_state'],
'last_run_fallback_message' => (string)$last['fallback_message'],
'last_run_error_detail' => (string)$last['error_detail'],
'next_run_timestamp' => $next_timestamp,
'next_run_label' => $next_timestamp > 0 ? date('d.m.Y H:i:s', $next_timestamp) : 'Nicht verfügbar',
'legacy_runtime_exists' => is_dir('/opt/piwigo-sync'),

View File

@@ -55,6 +55,7 @@ function bratonien_tools_ws_nc_sync_productive($params, &$service)
$saved_post = $_POST;
$saved_request_method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : null;
$saved_default_status = isset($conf['newcat_default_status']) ? $conf['newcat_default_status'] : null;
$saved_template_dirs = null;
$output = '';
$counts = array();
@@ -65,6 +66,15 @@ function bratonien_tools_ws_nc_sync_productive($params, &$service)
define('IN_ADMIN', true);
}
// ws.php uses the gallery template context. Piwigo's admin/site_update.php
// also initializes the admin tabsheet and therefore needs the admin
// template directory (tabsheet.tpl, site_update.tpl, ...).
if (is_object($template) && isset($template->smarty) && method_exists($template, 'set_template_dir'))
{
$saved_template_dirs = $template->smarty->getTemplateDir();
$template->set_template_dir(PHPWG_ROOT_PATH.'admin/themes/default/template');
}
$conf['newcat_default_status'] = 'private';
$_SERVER['REQUEST_METHOD'] = 'POST';
$_GET = array(
@@ -98,6 +108,12 @@ function bratonien_tools_ws_nc_sync_productive($params, &$service)
{
$_GET = $saved_get;
$_POST = $saved_post;
if ($saved_template_dirs !== null && is_object($template) && isset($template->smarty))
{
$template->smarty->setTemplateDir($saved_template_dirs);
}
if ($saved_default_status === null)
{
unset($conf['newcat_default_status']);

View File

@@ -1,7 +1,7 @@
<?php
/*
Plugin Name: Bratonien Tools
Version: 0.9.3.20
Version: 0.9.3.27
Description: Erweiterbare Administrationswerkzeuge fuer die Bratonien-Piwigo-Installation.
Plugin URI: https://github.com/Terranom674/Piwigo_Bratonien_Tools
Author: Bratonien
@@ -37,12 +37,6 @@ add_event_handler('ws_add_methods', 'bratonien_tools_register_ws_methods');
add_event_handler('ws_add_methods', 'bratonien_tools_register_nc_orphan_ws_methods');
add_event_handler('ws_add_methods', 'bratonien_tools_register_nc_productive_ws_methods');
/**
* The NC Connector uses Piwigo's native filesystem synchronization for folder
* shares. Mark only connector-triggered synchronization requests so every new
* physical album created during that run starts private. The global Piwigo
* default remains untouched for manual album creation and unrelated imports.
*/
function bratonien_tools_prepare_connector_private_import()
{
global $conf;
@@ -60,12 +54,6 @@ function bratonien_tools_prepare_connector_private_import()
$conf['newcat_default_status'] = 'private';
}
/**
* Piwigo's per-album permissions form rewrites the complete direct-user
* permission list when an album is saved as private. Add the acting user to
* that submitted list on the public -> private transition so Piwigo itself
* persists the permission together with the other selected users.
*/
function bratonien_tools_prepare_private_album_permissions()
{
global $user;

59
nc-connector-status.php Normal file
View File

@@ -0,0 +1,59 @@
<?php
$piwigo_root = realpath(dirname(__DIR__, 2));
if ($piwigo_root === false)
{
http_response_code(500);
exit;
}
define('PHPWG_ROOT_PATH', rtrim($piwigo_root, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR);
include_once(PHPWG_ROOT_PATH.'include/common.inc.php');
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store, max-age=0');
if (!defined('BRATONIEN_TOOLS_PATH'))
{
http_response_code(404);
echo json_encode(array('state'=>'unavailable','message'=>'Bratonien Tools ist nicht aktiv.'));
exit;
}
if (!function_exists('is_admin') || !is_admin())
{
http_response_code(403);
echo json_encode(array('state'=>'forbidden','message'=>'Administratorrechte erforderlich.'));
exit;
}
$dir = PHPWG_ROOT_PATH.'_data/bratonien-tools/nc-connector-status';
$latest = array(
'state'=>'idle',
'message'=>'Noch kein Connector-Status verfügbar.',
'timestamp'=>0,
'auth_mode'=>'',
'api'=>array('state'=>'not_run','message'=>''),
'fallback'=>array('state'=>'not_run','message'=>''),
'error_detail'=>'',
);
if (is_dir($dir))
{
foreach (glob($dir.'/connection-*.json') ?: array() as $file)
{
if (!is_readable($file))
{
continue;
}
$decoded = json_decode((string)@file_get_contents($file), true);
if (!is_array($decoded))
{
continue;
}
if ((int)($decoded['timestamp'] ?? 0) >= (int)$latest['timestamp'])
{
$latest = array_merge($latest, $decoded);
$latest['connection_file'] = basename($file);
}
}
}
echo json_encode($latest, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);

View File

@@ -11,6 +11,48 @@ function fail_sync($message)
throw new RuntimeException($message);
}
function http_error_detail($body)
{
$body = trim((string)$body);
if ($body === '')
{
return '';
}
$decoded = json_decode($body, true);
if (is_array($decoded))
{
$detail = (string)($decoded['message'] ?? $decoded['err'] ?? '');
if ($detail !== '')
{
return $detail;
}
}
if (function_exists('simplexml_load_string'))
{
$previous = libxml_use_internal_errors(true);
$xml = simplexml_load_string($body);
libxml_clear_errors();
libxml_use_internal_errors($previous);
if ($xml !== false)
{
$detail = trim((string)($xml->message ?? $xml->err ?? ''));
if ($detail !== '')
{
return $detail;
}
}
}
$plain = trim(preg_replace('/\s+/', ' ', strip_tags($body)));
if ($plain === '')
{
return '';
}
return mb_substr($plain, 0, 500);
}
function http_request($url, array $fields, array $headers = array(), $cookie_file = null)
{
$ch = curl_init($url);
@@ -21,7 +63,7 @@ function http_request($url, array $fields, array $headers = array(), $cookie_fil
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 900,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_USERAGENT => 'Bratonien-NC-Connector/0.9.3.19',
CURLOPT_USERAGENT => 'Bratonien-NC-Connector/0.9.3.26',
);
if ($headers)
{
@@ -45,7 +87,8 @@ function http_request($url, array $fields, array $headers = array(), $cookie_fil
}
if ($http < 200 || $http >= 300)
{
fail_sync('HTTP-Aufruf antwortete mit Status '.$http.'.');
$detail = http_error_detail((string)$body);
fail_sync('HTTP-Aufruf antwortete mit Status '.$http.($detail !== '' ? ': '.$detail : '.'));
}
return (string)$body;

View File

@@ -37,27 +37,53 @@ if [[ -z "$CONNECTION_ID" ]]; then
fi
fi
PUBLIC_STATUS_DIR="${PIWIGO_ROOT%/}/_data/bratonien-tools/nc-connector-status"
PUBLIC_STATUS_FILE="$PUBLIC_STATUS_DIR/connection-$CONNECTION_ID.json"
install -d -m 0755 "${PIWIGO_ROOT%/}/_data/bratonien-tools" "$PUBLIC_STATUS_DIR"
exec 9>"$LOCK_FILE"
flock -n 9 || exit 0
AUTH_MODE=""
API_STATE="not_run"
API_MESSAGE=""
FALLBACK_STATE="not_run"
FALLBACK_MESSAGE=""
ERROR_DETAIL=""
write_status() {
local state="$1" message="$2"
python3 - "$STATUS_FILE" "$state" "$message" <<'PY'
python3 - "$STATUS_FILE" "$PUBLIC_STATUS_FILE" "$state" "$message" "$AUTH_MODE" "$API_STATE" "$API_MESSAGE" "$FALLBACK_STATE" "$FALLBACK_MESSAGE" "$ERROR_DETAIL" <<'PY'
import json, os, sys, tempfile, time
path, state, message = sys.argv[1:]
os.makedirs(os.path.dirname(path), exist_ok=True)
payload = {"state": state, "message": message, "timestamp": int(time.time())}
fd, temporary = tempfile.mkstemp(dir=os.path.dirname(path))
with os.fdopen(fd, "w", encoding="utf-8") as handle:
json.dump(payload, handle, ensure_ascii=False)
handle.write("\n")
os.chmod(temporary, 0o644)
os.replace(temporary, path)
(path, public_path, state, message, auth_mode, api_state, api_message,
fallback_state, fallback_message, error_detail) = sys.argv[1:]
payload = {
"state": state,
"message": message,
"timestamp": int(time.time()),
"auth_mode": auth_mode,
"api": {"state": api_state, "message": api_message},
"fallback": {"state": fallback_state, "message": fallback_message},
"error_detail": error_detail,
}
def write_json(target):
os.makedirs(os.path.dirname(target), exist_ok=True)
fd, temporary = tempfile.mkstemp(dir=os.path.dirname(target))
with os.fdopen(fd, "w", encoding="utf-8") as handle:
json.dump(payload, handle, ensure_ascii=False)
handle.write("\n")
os.chmod(temporary, 0o644)
os.replace(temporary, target)
write_json(path)
write_json(public_path)
PY
}
failure() {
write_status error "Synchronisierung fehlgeschlagen; bestehende Galerie blieb unverändert"
[[ -n "$ERROR_DETAIL" ]] || ERROR_DETAIL="Synchronisierung wurde durch einen technischen Fehler abgebrochen."
write_status error "Synchronisierung fehlgeschlagen"
}
trap failure ERR
@@ -111,7 +137,7 @@ if [[ "$GATE_RESULT" == "3" ]]; then
write_status ok "Keine Änderungen gefunden"
exit 0
fi
[[ "$GATE_RESULT" == "0" ]] || exit "$GATE_RESULT"
[[ "$GATE_RESULT" == "0" ]] || { ERROR_DETAIL="Activity-Gate fehlgeschlagen (Exit-Code $GATE_RESULT)."; exit "$GATE_RESULT"; }
python3 "$SCRIPT_DIR/lib/build_manifest.py" \
--host "$NC_DB_HOST" --port "$NC_DB_PORT" --database "$NC_DB_NAME" --user "$NC_DB_USER" \
@@ -122,10 +148,48 @@ python3 "$SCRIPT_DIR/lib/shadow_tree.py" \
--manifest "$MANIFEST" --destination "$GALLERY_ROOT" --state "$MAP_FILE"
if [[ "${PIWIGO_SYNC_ENABLED:-0}" == "1" ]]; then
php "$SCRIPT_DIR/lib/piwigo-sync.php" \
set +e
PIWIGO_OUTPUT="$(php "$SCRIPT_DIR/lib/piwigo-sync.php" \
--piwigo-root="$PIWIGO_ROOT" \
--connection-id="$CONNECTION_ID" \
--base-url="http://127.0.0.1"
--base-url="http://127.0.0.1" 2>&1)"
PIWIGO_EXIT=$?
set -e
printf '%s\n' "$PIWIGO_OUTPUT"
if grep -q 'Piwigo-Synchronisierung per API erfolgreich' <<<"$PIWIGO_OUTPUT"; then
AUTH_MODE="api"
API_STATE="ok"
API_MESSAGE="API-Synchronisierung erfolgreich"
FALLBACK_STATE="not_needed"
FALLBACK_MESSAGE="Fallback wurde nicht benötigt"
else
API_LINE="$(grep -m1 '^Piwigo-API nicht nutzbar:' <<<"$PIWIGO_OUTPUT" || true)"
if [[ -n "$API_LINE" ]]; then
API_STATE="error"
API_MESSAGE="${API_LINE#Piwigo-API nicht nutzbar: }"
else
API_STATE="error"
API_MESSAGE="API-Synchronisierung war nicht erfolgreich"
fi
if grep -q 'Piwigo-Datenbanksynchronisierung per Benutzername/Passwort-Fallback erfolgreich' <<<"$PIWIGO_OUTPUT"; then
AUTH_MODE="fallback"
FALLBACK_STATE="ok"
FALLBACK_MESSAGE="Benutzername/Passwort-Fallback erfolgreich"
elif [[ "$PIWIGO_EXIT" -ne 0 ]]; then
AUTH_MODE="failed"
FALLBACK_STATE="error"
FALLBACK_MESSAGE="$(tail -n 1 <<<"$PIWIGO_OUTPUT")"
fi
fi
if [[ "$PIWIGO_EXIT" -ne 0 ]]; then
ERROR_DETAIL="$(tail -n 3 <<<"$PIWIGO_OUTPUT" | tr '\n' ' ' | sed 's/[[:space:]]\+/ /g; s/[[:space:]]$//')"
trap - ERR
write_status error "Synchronisierung fehlgeschlagen"
exit "$PIWIGO_EXIT"
fi
fi
python3 "$SCRIPT_DIR/lib/activity_gate.py" commit \
@@ -134,4 +198,10 @@ python3 "$SCRIPT_DIR/lib/activity_gate.py" commit \
--view "$NC_ACTIVITY_VIEW" --source-view "$NC_DB_VIEW"
trap - ERR
write_status ok "Synchronisierung erfolgreich"
if [[ "$AUTH_MODE" == "fallback" ]]; then
write_status warning "Synchronisierung erfolgreich über Fallback; API war nicht nutzbar"
elif [[ "$AUTH_MODE" == "api" ]]; then
write_status ok "Synchronisierung erfolgreich über API"
else
write_status ok "Synchronisierung erfolgreich"
fi

View File

@@ -89,7 +89,52 @@
if(!panels.some(function(i){return i.definition.id===initial})) initial=panels[0].definition.id;
activate(initial,false);
}
if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',initBratonienTabs); else initBratonienTabs();
function initNCConnectorPolling() {
var section=document.getElementById('nc-connector');
if(!section) return;
var lastSeen=null;
var endpoint='plugins/bratonien_tools/nc-connector-status.php';
function poll() {
fetch(endpoint+'?_='+Date.now(),{credentials:'same-origin',cache:'no-store'})
.then(function(response){if(!response.ok) throw new Error('HTTP '+response.status); return response.json();})
.then(function(data){
var timestamp=parseInt(data.timestamp||0,10);
if(!timestamp) return;
if(lastSeen===null) {
lastSeen=timestamp;
var resultVisible=section.textContent.indexOf('Letztes Ergebnis:')!==-1;
if(!resultVisible && data.message) {
var reloadKey='bratonien-nc-status-reload-'+timestamp;
try {
if(sessionStorage.getItem(reloadKey)!=='1') {
sessionStorage.setItem(reloadKey,'1');
window.location.reload();
}
} catch(e) {}
}
return;
}
if(timestamp>lastSeen) {
lastSeen=timestamp;
window.location.reload();
}
})
.catch(function(){});
}
poll();
window.setInterval(poll,5000);
}
function initAll() {
initBratonienTabs();
initNCConnectorPolling();
}
if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',initAll); else initAll();
})();
</script>
{/literal}

View File

@@ -18,6 +18,17 @@
{if $nc_system_available && $NC_CONNECTOR.system.last_run_message}
<p class="bratonien-base-note">Letztes Ergebnis: <strong>{$NC_CONNECTOR.system.last_run_message|escape:html}</strong></p>
{/if}
{if $nc_system_available && $NC_CONNECTOR.system.last_run_api_state == 'error'}
<p class="bratonien-main-cache__warning"><strong>API:</strong> {$NC_CONNECTOR.system.last_run_api_message|escape:html}</p>
{/if}
{if $nc_system_available && $NC_CONNECTOR.system.last_run_fallback_state == 'ok'}
<p class="bratonien-base-note"><strong>Fallback:</strong> erfolgreich übernommen.</p>
{elseif $nc_system_available && $NC_CONNECTOR.system.last_run_fallback_state == 'error'}
<p class="bratonien-main-cache__warning"><strong>Fallback:</strong> {$NC_CONNECTOR.system.last_run_fallback_message|escape:html}</p>
{/if}
{if $nc_system_available && $NC_CONNECTOR.system.last_run_error_detail}
<p class="bratonien-main-cache__warning"><strong>Fehler:</strong> {$NC_CONNECTOR.system.last_run_error_detail|escape:html}</p>
{/if}
</div>
<div class="bratonien-card">
@@ -194,6 +205,27 @@
</td>
</tr>
{/if}
{if isset($connection.last_sync) && $connection.last_sync.timestamp > 0}
<tr>
<td colspan="7">
<strong>Letzter Sync · {$connection.last_sync.label|escape:html}</strong>
<p class="bratonien-base-note"><strong>Ergebnis:</strong> {$connection.last_sync.message|escape:html}</p>
{if $connection.last_sync.api_state == 'ok'}
<p class="bratonien-base-note"><strong>API:</strong> erfolgreich</p>
{elseif $connection.last_sync.api_state == 'error'}
<p class="bratonien-main-cache__warning"><strong>API fehlgeschlagen:</strong> {$connection.last_sync.api_message|escape:html}</p>
{/if}
{if $connection.last_sync.fallback_state == 'ok'}
<p class="bratonien-base-note"><strong>Fallback:</strong> erfolgreich</p>
{elseif $connection.last_sync.fallback_state == 'error'}
<p class="bratonien-main-cache__warning"><strong>Fallback fehlgeschlagen:</strong> {$connection.last_sync.fallback_message|escape:html}</p>
{/if}
{if $connection.last_sync.error_detail}
<p class="bratonien-main-cache__warning"><strong>Technischer Fehler:</strong> {$connection.last_sync.error_detail|escape:html}</p>
{/if}
</td>
</tr>
{/if}
{/foreach}
</tbody>
</table>
@@ -210,7 +242,18 @@
<span class="bratonien-label">Nächster Lauf</span><strong>{if $nc_system_available}{$NC_CONNECTOR.system.next_run_label|escape:html}{else}Nicht verfügbar{/if}</strong>
</div>
{if $nc_system_available && $NC_CONNECTOR.system.last_run_message}
<p class="bratonien-base-note">{$NC_CONNECTOR.system.last_run_message|escape:html}</p>
<p class="bratonien-base-note"><strong>Ergebnis:</strong> {$NC_CONNECTOR.system.last_run_message|escape:html}</p>
{/if}
{if $nc_system_available && $NC_CONNECTOR.system.last_run_api_state == 'error'}
<p class="bratonien-main-cache__warning"><strong>API fehlgeschlagen:</strong> {$NC_CONNECTOR.system.last_run_api_message|escape:html}</p>
{/if}
{if $nc_system_available && $NC_CONNECTOR.system.last_run_fallback_state == 'ok'}
<p class="bratonien-base-note"><strong>Fallback:</strong> erfolgreich</p>
{elseif $nc_system_available && $NC_CONNECTOR.system.last_run_fallback_state == 'error'}
<p class="bratonien-main-cache__warning"><strong>Fallback fehlgeschlagen:</strong> {$NC_CONNECTOR.system.last_run_fallback_message|escape:html}</p>
{/if}
{if $nc_system_available && $NC_CONNECTOR.system.last_run_error_detail}
<p class="bratonien-main-cache__warning"><strong>Technischer Fehler:</strong> {$NC_CONNECTOR.system.last_run_error_detail|escape:html}</p>
{/if}
</div>