mirror of
https://github.com/Terranom674/Piwigo_Bratonien_Tools.git
synced 2026-09-19 10:34:30 +00:00
Compare commits
17 Commits
a437f5d205
...
8023f7b5d7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8023f7b5d7 | ||
|
|
8a5435ea6b | ||
|
|
880ff2a2b1 | ||
|
|
062d38ab08 | ||
|
|
10065ece46 | ||
|
|
bccc5cafda | ||
|
|
2c52228265 | ||
|
|
7277a8b287 | ||
|
|
9155a52290 | ||
|
|
afa6d02c46 | ||
|
|
9c94953267 | ||
|
|
66d62321d0 | ||
|
|
cb9a4b7d2a | ||
|
|
388351c356 | ||
|
|
ea71b54c94 | ||
|
|
99edfc84d8 | ||
|
|
b224cd40f6 |
@@ -2,7 +2,7 @@
|
||||
|
||||
## Version
|
||||
|
||||
**Bratonien Tools 0.9.6.8.19**
|
||||
**Bratonien Tools 9.7.1.0**
|
||||
|
||||
Zielplattform der produktiven NC-Connector-Synchronisierung ist derzeit **Piwigo 16.4.0**.
|
||||
|
||||
@@ -40,10 +40,12 @@ Die verbindungsspezifischen Runtime-Konfigurationen liegen unter `/etc/bratonien
|
||||
|
||||
Der Reconcile- und Shell-Pfad unterstützt den leeren WebDAV-Root ausdrücklich und gibt ihn als `--root ""` an den Platzhalter-Builder weiter.
|
||||
|
||||
### Platzhalterquelle und Shadow Tree
|
||||
### Platzhalterquelle, Metadaten und Shadow Tree
|
||||
|
||||
`runtime/lib/build_webdav_placeholder_source.py` bildet die Nextcloud-Inhalte als lokale Platzhalterquelle ab. Für Bilder existieren physische 1×1-Platzhalterdateien; die Originale werden dabei nicht dauerhaft heruntergeladen.
|
||||
|
||||
Der WebDAV-Scan übernimmt zusätzlich die von Nextcloud gelieferten Bildmaße aus `nc:metadata-photos-size`. `width`, `height` und `fileid` werden im `webdav-map.json` geführt. Nach dem normalen Piwigo-Dateisync überträgt `runtime/lib/sync-webdav-metadata.php` die Originalmaße in `piwigo_images`, damit Piwigo seine Derivatgrößen und Lazy-Loading-Geometrie auf Basis der echten Bildabmessungen berechnet.
|
||||
|
||||
`runtime/lib/shadow_tree.py` erzeugt atomar die Dateisystemstruktur, die Piwigo als physische Site sieht. Shadow-Verzeichnisse werden so angelegt, dass der Webserver die für die On-Demand-Materialisierung nötigen Dateisystemoperationen ausführen kann.
|
||||
|
||||
Jede WebDAV-Verbindung besitzt ihre eigene Piwigo-Site. Es gibt keinen zusätzlichen Sync auf Site 1.
|
||||
@@ -56,23 +58,26 @@ Danach wird `bratonien.nc.syncOrphans` für die konkrete WebDAV-Site ausgeführt
|
||||
|
||||
Der Shadow Tree stellt Piwigo ausschließlich die physische Album-/Bildstruktur bereit. Albumdatensätze, Bilddatensätze, Bild-Kategorie-Verknüpfungen und Piwigo-Derivate bleiben Aufgabe von Piwigo.
|
||||
|
||||
### On-Demand-Materialisierung vor `i.php`
|
||||
### On-Demand-Materialisierung und Derivaterzeugung
|
||||
|
||||
Die produktive WebDAV-Derivaterzeugung sitzt vor Piwigos `i.php`.
|
||||
|
||||
`include/webdav_materialize_runtime.inc.php` löst aus dem Piwigo-Bildpfad die konkrete Verbindung, den ausgewählten Nextcloud-Root und den relativen WebDAV-Pfad auf.
|
||||
`include/webdav_materialize_runtime.inc.php` löst aus dem Piwigo-Bildpfad die konkrete Verbindung, den ausgewählten Nextcloud-Root, den relativen WebDAV-Pfad sowie die Mapping-Metadaten `fileid`, `width`, `height`, MIME-Typ, Größe und ETag auf.
|
||||
|
||||
Für ein noch nicht vorhandenes Derivat läuft `webdav-derivative.php`:
|
||||
|
||||
1. Zugriffsprüfung für das Piwigo-Bild;
|
||||
2. Download des Originals aus Nextcloud in eine temporäre Datei;
|
||||
3. temporäres Bereitstellen des Originals am exakten von Piwigo erwarteten Quellpfad;
|
||||
4. Aufruf des nativen Piwigo-`i.php`;
|
||||
5. Piwigo erzeugt sein normales Derivat;
|
||||
6. Wiederherstellung des Shadow-/Platzhalterzustands;
|
||||
7. Auslieferung des Piwigo-Derivats.
|
||||
2. Auswahl einer temporären Nextcloud-Quelle;
|
||||
3. temporäres Bereitstellen dieser Quelle am exakten von Piwigo erwarteten Quellpfad;
|
||||
4. Erzeugung des normalen Piwigo-Derivats mit Piwigos eigener `pwg_image`-/Derivative-Logik im selben PHP-Prozess;
|
||||
5. Wiederherstellung des Shadow-/Platzhalterzustands;
|
||||
6. Auslieferung des Piwigo-Derivats.
|
||||
|
||||
Das Original verbleibt in Nextcloud. Es gibt keine dauerhafte vollständige Originalkopie in Piwigo.
|
||||
Ein interner HTTP-Self-Request auf `i.php` wird nicht mehr verwendet. Damit wird kein zusätzlicher PHP-FPM-Worker pro Derivaterzeugung benötigt.
|
||||
|
||||
Für die erste Preview-Stufe verwenden ausschließlich `custom:s9999x250` und `standard:square` den authentifizierten Nextcloud-Endpunkt `/core/preview` anhand der Nextcloud-`fileid`. Die Preview wird mit etwa doppelter benötigter Piwigo-Auflösung und erhaltenem Seitenverhältnis angefordert. Die Berechnung berücksichtigt das Original-Seitenverhältnis, damit auch Crop-Derivate genügend Pixel erhalten. Varianten mit Bildrotation werden in dieser Stufe nicht über Preview erzeugt.
|
||||
|
||||
Ist keine geeignete Preview planbar oder schlägt der Preview-Abruf fehl, fällt der Gate automatisch auf den vollständigen WebDAV-Originaldownload zurück. Große/originale Anforderungen verwenden weiterhin die Originalquelle.
|
||||
|
||||
Die temporäre Preview bzw. das temporäre Original wird nach der Derivaterzeugung entfernt. Das fertige Derivat verbleibt ausschließlich in Piwigos normalem `_data/i`-Cache. Der Connector führt keinen parallelen permanenten Derivat-Cache.
|
||||
|
||||
### Orphan-Logik
|
||||
|
||||
@@ -104,13 +109,13 @@ Eine WebDAV-Verbindung kann unabhängig von ihrer Reihenfolge gelöscht werden.
|
||||
|
||||
### Diagnose
|
||||
|
||||
Der WebDAV-Derivative-Gate schreibt Request-bezogene `[BRAT-WD ...]`-Diagnoseeinträge. Der Verbindungsstatus wird pro Verbindung geführt. Runtime-Probleme lassen sich zusätzlich über `bratonien-nc-connector.service` nachvollziehen.
|
||||
Der WebDAV-Derivative-Gate schreibt Request-bezogene `[BRAT-WD ...]`-Diagnoseeinträge. Für neue Derivate zeigen `preview_start`, `preview_failed`, `download_done mode=preview|original`, `generate_start` und `generate_done` den verwendeten Quellpfad und die Laufzeiten. Der Verbindungsstatus wird pro Verbindung geführt. Runtime-Probleme lassen sich zusätzlich über `bratonien-nc-connector.service` nachvollziehen.
|
||||
|
||||
## Aktuell relevante Dateien
|
||||
|
||||
- `main.inc.php` – Plugin-Hooks, Connector-Sync-Hilfen, Dashboard-Prefilter
|
||||
- `include/webdav_materialize_runtime.inc.php` – WebDAV-Quellauflösung und Materialisierung
|
||||
- `webdav-derivative.php` – On-Demand-Gate vor Piwigos `i.php`
|
||||
- `include/webdav_materialize_runtime.inc.php` – WebDAV-Quellauflösung einschließlich `fileid` und Originalmaßen
|
||||
- `webdav-derivative.php` – On-Demand-Gate, Nextcloud-Preview/Original-Fallback und Piwigo-Derivaterzeugung
|
||||
- `webdav-image.php` – direkte WebDAV-Originalauslieferung
|
||||
- `include/nc_productive_ws.inc.php` – direkter Piwigo-Core-Sync für 16.4.0
|
||||
- `include/nc_orphan_ws.inc.php` – Root-Orphan-Synchronisierung
|
||||
@@ -119,15 +124,16 @@ Der WebDAV-Derivative-Gate schreibt Request-bezogene `[BRAT-WD ...]`-Diagnoseein
|
||||
- `runtime/cleanup-webdav-piwigo.php` – Bereinigung verwaister Piwigo-Sites
|
||||
- `runtime/sync-webdav.sh` – verbindungsspezifischer Sync
|
||||
- `runtime/run-all.sh` – gemeinsamer Runner
|
||||
- `runtime/lib/build_webdav_placeholder_source.py` – WebDAV-Scan und Platzhalterquelle
|
||||
- `runtime/lib/build_webdav_placeholder_source.py` – WebDAV-Scan, Bildmetadaten und Platzhalterquelle
|
||||
- `runtime/lib/sync-webdav-metadata.php` – Übernahme der Originalmaße nach Piwigo
|
||||
- `runtime/lib/shadow_tree.py` – atomarer Shadow Tree
|
||||
- `runtime/lib/piwigo-sync.php` – Piwigo-API/Fallback-Sync
|
||||
|
||||
## Nicht mehr das produktive WebDAV-Modell
|
||||
|
||||
Nicht mehr maßgeblich für die produktive WebDAV-Derivaterzeugung ist das frühere Modell, bei dem Bild-URLs einfach auf einen separaten WebDAV-Bildstream umgebogen wurden oder der Connector selbst einen parallelen vollständigen Derivatbestand verwalten sollte.
|
||||
Nicht mehr maßgeblich sind das frühere Modell eines separaten WebDAV-Bildstreams als Derivatquelle, ein paralleler vollständiger Connector-Derivatbestand oder ein interner HTTP-Aufruf von `webdav-derivative.php` zurück auf Piwigos `i.php`.
|
||||
|
||||
Maßgeblich ist: **physischer Platzhalter + On-Demand-Original + natives Piwigo-`i.php` + Wiederherstellung des Platzhalters**.
|
||||
Maßgeblich ist: **physischer Platzhalter + passende temporäre Nextcloud-Preview bzw. Original-Fallback + Piwigos Bildverarbeitung im selben PHP-Prozess + normales Piwigo-Derivat + Wiederherstellung des Platzhalters**.
|
||||
|
||||
## Prüfpflicht vor Merge
|
||||
|
||||
|
||||
32
README.md
32
README.md
@@ -2,7 +2,7 @@
|
||||
|
||||
Modulares Piwigo-Plugin für Administration, Bildverarbeitung, geschützte Freigaben, Fotoauswahl und die Anbindung von Nextcloud an Piwigo.
|
||||
|
||||
Aktuelle Plugin-Version: **0.9.6.8.19**
|
||||
Aktuelle Plugin-Version: **9.7.1.0**
|
||||
|
||||
## Grundprinzip
|
||||
|
||||
@@ -64,27 +64,27 @@ Nicht benötigt werden Nextcloud-Datenbankzugriff, `occ`-Adminzugriff, Storage-I
|
||||
|
||||
1. Der Assistent prüft Nextcloud und liest die sichtbaren Verzeichnisse per WebDAV.
|
||||
2. Ausgewählte Verzeichnisse werden rekursiv per PROPFIND eingelesen.
|
||||
3. Ordner, Dateiname, Nextcloud-Datei-ID, MIME-Typ, Größe, ETag und WebDAV-Pfad werden erfasst.
|
||||
3. Ordner, Dateiname, Nextcloud-Datei-ID, MIME-Typ, Größe, ETag, Originalabmessungen und WebDAV-Pfad werden erfasst.
|
||||
4. `runtime/lib/build_webdav_placeholder_source.py` erzeugt eine lokale Platzhalterquelle ohne dauerhafte Originalkopie.
|
||||
5. `runtime/lib/shadow_tree.py` baut atomar den verbindungseigenen Shadow Tree.
|
||||
6. Der WebDAV-Galeriebaum liegt unter `_data/bratonien-tools/nc-webdav-gallery/connection-ID`.
|
||||
7. Jede WebDAV-Verbindung wird als eigene physische Piwigo-Site registriert.
|
||||
8. Piwigos Dateisynchronisierung erhält ausschließlich diese verbindungseigene Site.
|
||||
9. `runtime/lib/sync-webdav-metadata.php` übernimmt die von Nextcloud gelieferten Originalmaße in Piwigos Bilddatensätze.
|
||||
|
||||
### On-Demand-Bildauslieferung und Piwigo-Derivate
|
||||
|
||||
Die produktive Bildauslieferung sitzt vor Piwigos `i.php`.
|
||||
|
||||
`include/webdav_materialize_runtime.inc.php` erkennt anhand des Piwigo-Bildpfads die zugehörige WebDAV-Verbindung, den Nextcloud-Root und den relativen WebDAV-Pfad. Der Hook `get_derivative_url` leitet fehlende WebDAV-Derivate an `webdav-derivative.php` um.
|
||||
`include/webdav_materialize_runtime.inc.php` erkennt anhand des Piwigo-Bildpfads die zugehörige WebDAV-Verbindung, den Nextcloud-Root und den relativen WebDAV-Pfad. Aus dem Mapping stehen zusätzlich `fileid`, Originalbreite/-höhe, MIME-Typ, Dateigröße und ETag zur Verfügung. Der Hook `get_derivative_url` leitet fehlende WebDAV-Derivate an `webdav-derivative.php` um.
|
||||
|
||||
Wenn ein benötigtes Piwigo-Derivat noch nicht existiert:
|
||||
|
||||
1. `webdav-derivative.php` prüft den Piwigo-Zugriff auf das Bild.
|
||||
2. Das Original wird temporär direkt aus Nextcloud geladen.
|
||||
3. Die physische 1×1-Platzhalterdatei bzw. der Shadow-Link am von Piwigo erwarteten Quellpfad wird für die Dauer der Erzeugung ersetzt.
|
||||
4. Piwigos eigenes `i.php` erzeugt das normale Piwigo-Derivat.
|
||||
5. Danach wird der temporäre Originalzustand entfernt und der Platzhalter-/Shadow-Zustand wiederhergestellt.
|
||||
6. Das von Piwigo erzeugte Derivat wird ausgeliefert und künftig normal aus Piwigos Derivat-Cache verwendet.
|
||||
2. Für `custom:s9999x250` und `standard:square` wird bevorzugt eine passende authentifizierte Nextcloud-Preview anhand der `fileid` geladen. Die Preview wird mit ungefähr doppelter benötigter Piwigo-Auflösung und erhaltenem Seitenverhältnis angefordert.
|
||||
3. Ist keine passende Preview planbar oder schlägt der Preview-Abruf fehl, wird automatisch das vollständige Original per WebDAV geladen. Große bzw. originale Anforderungen verwenden weiterhin die Originalquelle.
|
||||
4. Die temporäre Bildquelle ersetzt für die Dauer der Erzeugung die physische 1×1-Platzhalterdatei bzw. den Shadow-Link am von Piwigo erwarteten Quellpfad.
|
||||
5. Piwigos eigene `pwg_image`-/Derivative-Logik erzeugt das normale Piwigo-Derivat direkt im selben PHP-Prozess. Ein interner HTTP-Self-Request auf `i.php` wird nicht verwendet.
|
||||
6. Danach wird die temporäre Bildquelle entfernt und der Platzhalter-/Shadow-Zustand wiederhergestellt.
|
||||
7. Das fertige Derivat wird ausgeliefert und künftig normal aus Piwigos `_data/i`-Derivat-Cache verwendet.
|
||||
|
||||
Damit bleibt Piwigo für Größen, Derivate und Lazy-Loading verantwortlich. Der Connector hält keinen parallelen eigenen vollständigen Derivat-Cache vor.
|
||||
|
||||
@@ -133,7 +133,7 @@ Der gemeinsame Lauf besteht aktuell aus:
|
||||
3. `runtime/cleanup-webdav-piwigo.php` – verwaiste WebDAV-Piwigo-Daten bereinigen;
|
||||
4. `runtime/sync-webdav.sh` – jede vorhandene WebDAV-Verbindung synchronisieren.
|
||||
|
||||
Der verbindungsspezifische Lauf erzeugt Platzhalterquelle und Shadow Tree, führt Piwigos Sync und Orphan-Sync aus und enthält weiterhin die vorhandenen Preview-/Derivative-Schritte. Die produktive Auslieferung fehlender WebDAV-Derivate erfolgt jedoch über den On-Demand-Gate vor `i.php`.
|
||||
Der verbindungsspezifische Lauf erzeugt Platzhalterquelle und Shadow Tree, führt Piwigos Sync und Orphan-Sync aus und überträgt anschließend die Originalabmessungen aus dem WebDAV-Mapping in Piwigo. Eine vollständige Vorab-Erzeugung von Connector-Derivaten findet nicht statt; fehlende Derivate werden On-Demand erzeugt.
|
||||
|
||||
## Bildcache
|
||||
|
||||
@@ -192,16 +192,17 @@ Der integrierte Updater liest den Zielstand aus GitHub, bindet ein Update an ein
|
||||
- `include/nc_connector_delete_safe.inc.php` – Löschen einschließlich WebDAV-Piwigo-Inhalten
|
||||
- `include/nc_productive_ws.inc.php` – direkter Piwigo-Core-Dateisync für Piwigo 16.4.0
|
||||
- `include/nc_orphan_ws.inc.php` – Orphan-Synchronisierung der konkreten WebDAV-Site
|
||||
- `include/webdav_materialize_runtime.inc.php` – WebDAV-Quellauflösung und On-Demand-Materialisierung
|
||||
- `include/webdav_materialize_runtime.inc.php` – WebDAV-Quellauflösung und On-Demand-Materialisierung einschließlich `fileid` und Originalmaßen
|
||||
- `include/webdav_image_runtime.inc.php` – vorhandene WebDAV-Bildzuordnung/Originalauslieferung
|
||||
- `webdav-derivative.php` – Gate vor `i.php` für fehlende WebDAV-Derivate
|
||||
- `webdav-derivative.php` – On-Demand-Gate, Nextcloud-Preview/Original-Fallback und Piwigo-Derivaterzeugung
|
||||
- `webdav-image.php` – serverseitige WebDAV-Originalauslieferung
|
||||
- `runtime/reconcile-webdav.php` – WebDAV-Runtime-Reconcile, einschließlich gültigem leerem Root
|
||||
- `runtime/repair-webdav-orphans.php` – Reparatur vorhandener Orphan-Zustände
|
||||
- `runtime/cleanup-webdav-piwigo.php` – Bereinigung verwaister WebDAV-Piwigo-Sites
|
||||
- `runtime/sync-webdav.sh` – Ablauf einer WebDAV-Verbindung
|
||||
- `runtime/run-all.sh` – gemeinsamer WebDAV-Runner
|
||||
- `runtime/lib/build_webdav_placeholder_source.py` – rekursiver WebDAV-Scan und physische Platzhalterquelle
|
||||
- `runtime/lib/build_webdav_placeholder_source.py` – rekursiver WebDAV-Scan, Bildmetadaten und physische Platzhalterquelle
|
||||
- `runtime/lib/sync-webdav-metadata.php` – Übernahme der Originalabmessungen in Piwigo
|
||||
- `runtime/lib/shadow_tree.py` – atomarer, Piwigo-kompatibler Shadow Tree
|
||||
- `runtime/lib/piwigo-sync.php` – Piwigo-Sync mit API/Fallback
|
||||
- `main-cache-build.php` – allgemeiner Piwigo-Derivat-/Cache-Builder
|
||||
@@ -222,5 +223,6 @@ Der integrierte Updater liest den Zielstand aus GitHub, bindet ein Update an ein
|
||||
- produktive Piwigo-API ist versionsgebunden;
|
||||
- Originalbilder werden vom Connector nicht gelöscht;
|
||||
- WebDAV-Originalbilder werden nur bei Bedarf temporär lokal materialisiert;
|
||||
- temporäre Originale werden nach der Piwigo-Derivaterzeugung wieder entfernt;
|
||||
- kleine Derivate können stattdessen eine temporäre authentifizierte Nextcloud-Preview verwenden;
|
||||
- temporäre Preview-/Originalquellen werden nach der Piwigo-Derivaterzeugung wieder entfernt;
|
||||
- Update-Pakete werden an Commit und Hash gebunden.
|
||||
|
||||
@@ -75,6 +75,9 @@ function bratonien_tools_webdav_materialize_source_info($image_id)
|
||||
$content_type = '';
|
||||
$size = 0;
|
||||
$etag = '';
|
||||
$fileid = 0;
|
||||
$width = 0;
|
||||
$height = 0;
|
||||
$state_dir = rtrim((string)($config['state_dir'] ?? ''), '/');
|
||||
if ($state_dir !== '')
|
||||
{
|
||||
@@ -84,7 +87,18 @@ function bratonien_tools_webdav_materialize_source_info($image_id)
|
||||
$mapping = json_decode((string)file_get_contents($mapping_file), true);
|
||||
if (is_array($mapping) && isset($mapping['files']) && is_array($mapping['files']))
|
||||
{
|
||||
$entry = $mapping['files'][$resolved] ?? $mapping['files'][$normalized] ?? null;
|
||||
$files = $mapping['files'];
|
||||
$entry = $files[$resolved] ?? $files[$normalized] ?? null;
|
||||
if (!is_array($entry))
|
||||
{
|
||||
foreach ($files as $candidate)
|
||||
{
|
||||
if (!is_array($candidate) || (string)($candidate['kind'] ?? '') !== 'file') continue;
|
||||
if (trim((string)($candidate['webdav_path'] ?? ''), '/') !== $webdav_path) continue;
|
||||
$entry = $candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_array($entry) && (string)($entry['kind'] ?? '') === 'file')
|
||||
{
|
||||
$mapped_path = trim((string)($entry['webdav_path'] ?? ''), '/');
|
||||
@@ -92,6 +106,9 @@ function bratonien_tools_webdav_materialize_source_info($image_id)
|
||||
$content_type = (string)($entry['content_type'] ?? '');
|
||||
$size = (int)($entry['size'] ?? 0);
|
||||
$etag = (string)($entry['etag'] ?? '');
|
||||
$fileid = (int)($entry['fileid'] ?? 0);
|
||||
$width = (int)($entry['width'] ?? 0);
|
||||
$height = (int)($entry['height'] ?? 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,6 +123,9 @@ function bratonien_tools_webdav_materialize_source_info($image_id)
|
||||
'content_type'=>$content_type,
|
||||
'size'=>$size,
|
||||
'etag'=>$etag,
|
||||
'fileid'=>$fileid,
|
||||
'width'=>$width,
|
||||
'height'=>$height,
|
||||
'coi'=>$row['coi'] ?? null,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
/*
|
||||
Plugin Name: Bratonien Tools
|
||||
Version: 0.9.6.8.22
|
||||
Version: 9.7.1.2
|
||||
Description: Erweiterbare Administrationswerkzeuge fuer die Bratonien-Piwigo-Installation.
|
||||
Plugin URI: https://github.com/Terranom674/Piwigo_Bratonien_Tools
|
||||
Author: Bratonien
|
||||
|
||||
@@ -56,8 +56,30 @@ def safe_local_name(name: str) -> str:
|
||||
|
||||
|
||||
def parse_image_dimensions(prop: ET.Element) -> tuple[int, int]:
|
||||
for property_name in ("file-metadata-size", "metadata-photos-size"):
|
||||
raw = prop.findtext(f"{{{NC}}}{property_name}", default="").strip()
|
||||
for property_name in ("metadata-photos-size", "file-metadata-size"):
|
||||
element = prop.find(f"{{{NC}}}{property_name}")
|
||||
if element is None:
|
||||
continue
|
||||
|
||||
width = 0
|
||||
height = 0
|
||||
for child in list(element):
|
||||
local_name = child.tag.rsplit("}", 1)[-1]
|
||||
text = (child.text or "").strip()
|
||||
if not text:
|
||||
continue
|
||||
try:
|
||||
value = int(text)
|
||||
except ValueError:
|
||||
continue
|
||||
if local_name == "width":
|
||||
width = value
|
||||
elif local_name == "height":
|
||||
height = value
|
||||
if width > 0 and height > 0:
|
||||
return width, height
|
||||
|
||||
raw = (element.text or "").strip()
|
||||
if not raw:
|
||||
continue
|
||||
try:
|
||||
|
||||
@@ -20,6 +20,7 @@ function decrypt_webdav_credentials($blob, $hexKey)
|
||||
$iv = base64_decode((string)($payload['iv'] ?? ''), true);
|
||||
$tag = base64_decode((string)($payload['tag'] ?? ''), true);
|
||||
$cipher = base64_decode((string)($payload['data'] ?? ''), true);
|
||||
if (!is_string($iv) || !is_string($tag) || !is_string($cipher)) fail_webdav_reconcile('Connector-Zugangsdaten sind unvollstaendig.');
|
||||
$plain = openssl_decrypt($cipher, 'aes-256-gcm', hex2bin($hexKey), OPENSSL_RAW_DATA, $iv, $tag);
|
||||
if ($plain === false || $plain === '') fail_webdav_reconcile('Connector-Zugangsdaten konnten nicht entschluesselt werden.');
|
||||
$decoded = json_decode($plain, true);
|
||||
@@ -75,11 +76,19 @@ function webdav_source_fingerprint($baseUrl, $user, array $roots)
|
||||
return hash('sha256', strtolower(rtrim((string)$baseUrl, '/'))."\n".strtolower(trim((string)$user))."\n".json_encode($normalized));
|
||||
}
|
||||
|
||||
function webdav_set_runtime_dir_permissions($dir)
|
||||
{
|
||||
if (!is_dir($dir)) return false;
|
||||
if (!@chgrp($dir, 'www-data')) return false;
|
||||
return @chmod($dir, 0750);
|
||||
}
|
||||
|
||||
$pluginRoot = dirname(__DIR__);
|
||||
$piwigoRoot = dirname($pluginRoot, 2);
|
||||
$dbConfig = $piwigoRoot.'/local/config/database.inc.php';
|
||||
$configDir = '/etc/bratonien-tools/nc-connector';
|
||||
$stateRoot = '/var/lib/bratonien-tools/nc-connector';
|
||||
$stateBase = '/var/lib/bratonien-tools';
|
||||
$stateRoot = $stateBase.'/nc-connector';
|
||||
$publicSourceRoot = rtrim($piwigoRoot, '/').'/_data/bratonien-tools/nc-webdav-source';
|
||||
$publicGalleryRoot = rtrim($piwigoRoot, '/').'/_data/bratonien-tools/nc-webdav-gallery';
|
||||
|
||||
@@ -111,7 +120,8 @@ try
|
||||
if (!is_dir($dir) && !mkdir($dir, $dir === $configDir ? 0700 : 0750, true)) fail_webdav_reconcile('Runtime-Verzeichnis konnte nicht angelegt werden: '.$dir);
|
||||
}
|
||||
@chmod($configDir, 0700);
|
||||
@chmod($stateRoot, 0750);
|
||||
if (!webdav_set_runtime_dir_permissions($stateBase)) fail_webdav_reconcile('Runtime-State-Basis konnte nicht fuer den Webserver freigegeben werden.');
|
||||
if (!webdav_set_runtime_dir_permissions($stateRoot)) fail_webdav_reconcile('Runtime-State-Verzeichnis konnte nicht fuer den Webserver freigegeben werden.');
|
||||
@chmod($publicSourceRoot, 0755);
|
||||
@chmod($publicGalleryRoot, 0755);
|
||||
|
||||
@@ -151,7 +161,7 @@ try
|
||||
$stateDir = rtrim((string)($config['state_dir'] ?? ''), '/');
|
||||
if ($stateDir === '') $stateDir = $stateRoot.'/connection-'.$id;
|
||||
if (!is_dir($stateDir) && !mkdir($stateDir, 0750, true)) fail_webdav_reconcile('State-Verzeichnis konnte nicht angelegt werden.');
|
||||
@chmod($stateDir, 0750);
|
||||
if (!webdav_set_runtime_dir_permissions($stateDir)) fail_webdav_reconcile('State-Verzeichnis konnte nicht fuer den Webserver freigegeben werden.');
|
||||
|
||||
$galleryRoot = rtrim((string)($config['parallel_gallery_root'] ?? ''), '/');
|
||||
$expectedGalleryRoot = $publicGalleryRoot.'/connection-'.$id;
|
||||
|
||||
@@ -28,6 +28,8 @@ source "$CONFIG_FILE"
|
||||
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
LOCK_FILE="$STATE_DIR/webdav-sync.lock"
|
||||
mkdir -p -- "$STATE_DIR"
|
||||
chgrp www-data -- "$STATE_DIR"
|
||||
chmod 0750 -- "$STATE_DIR"
|
||||
exec 9>"$LOCK_FILE"
|
||||
flock -n 9 || exit 0
|
||||
|
||||
@@ -92,6 +94,9 @@ python3 "$SCRIPT_DIR/lib/build_webdav_placeholder_source.py" \
|
||||
--manifest "$MANIFEST" \
|
||||
--mapping "$WEBDAV_MAPPING_FILE"
|
||||
|
||||
chgrp www-data -- "$WEBDAV_MAPPING_FILE"
|
||||
chmod 0640 -- "$WEBDAV_MAPPING_FILE"
|
||||
|
||||
python3 "$SCRIPT_DIR/lib/shadow_tree.py" \
|
||||
--manifest "$MANIFEST" \
|
||||
--destination "$GALLERY_ROOT" \
|
||||
|
||||
@@ -55,38 +55,44 @@ function bratonien_tools_webdav_derivative_quote_path($path)
|
||||
return implode('/', array_map('rawurlencode', $parts));
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_download(array $source, $destination, &$detail=null)
|
||||
function bratonien_tools_webdav_derivative_connection(array $source, &$detail=null)
|
||||
{
|
||||
$detail = '';
|
||||
$table = $GLOBALS['prefixeTable'].'bratonien_tools_nc_connections';
|
||||
$result = pwg_query('SELECT config_json, secret_blob FROM `'.$table.'` WHERE id='.(int)$source['connection_id'].' LIMIT 1');
|
||||
if (!pwg_db_num_rows($result)) { $detail = 'WebDAV-Verbindung nicht gefunden.'; return false; }
|
||||
if (!pwg_db_num_rows($result)) { $detail = 'WebDAV-Verbindung nicht gefunden.'; return null; }
|
||||
|
||||
$row = pwg_db_fetch_assoc($result);
|
||||
$config = json_decode((string)$row['config_json'], true);
|
||||
if (!is_array($config)) { $detail = 'WebDAV-Konfiguration ist ungueltig.'; return false; }
|
||||
if (!is_array($config)) { $detail = 'WebDAV-Konfiguration ist ungueltig.'; return null; }
|
||||
|
||||
$key_result = pwg_query("SELECT value FROM ".$GLOBALS['prefixeTable']."config WHERE param='bratonien_nc_connector_secret' LIMIT 1");
|
||||
if (!pwg_db_num_rows($key_result)) { $detail = 'Connector-Schluessel fehlt.'; return false; }
|
||||
if (!pwg_db_num_rows($key_result)) { $detail = 'Connector-Schluessel fehlt.'; return null; }
|
||||
$key_row = pwg_db_fetch_assoc($key_result);
|
||||
$credentials = bratonien_tools_webdav_derivative_decrypt_secret((string)$row['secret_blob'], (string)$key_row['value']);
|
||||
if (!is_array($credentials)) { $detail = 'WebDAV-Zugangsdaten konnten nicht gelesen werden.'; return false; }
|
||||
if (!is_array($credentials)) { $detail = 'WebDAV-Zugangsdaten konnten nicht gelesen werden.'; return null; }
|
||||
|
||||
$base_url = rtrim((string)($config['nextcloud_url'] ?? ''), '/');
|
||||
$user = trim((string)($credentials['nextcloud_user'] ?? ''));
|
||||
$password = (string)($credentials['nextcloud_password'] ?? '');
|
||||
$webdav_path = trim((string)($source['webdav_path'] ?? ''), '/');
|
||||
if ($base_url === '' || $user === '' || $password === '' || $webdav_path === '') { $detail = 'WebDAV-Bildquelle ist unvollstaendig.'; return false; }
|
||||
if ($base_url === '' || $user === '' || $password === '') { $detail = 'WebDAV-Verbindung ist unvollstaendig.'; return null; }
|
||||
|
||||
return array('base_url'=>$base_url, 'user'=>$user, 'password'=>$password);
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_download_url($url, array $connection, $destination, &$detail=null)
|
||||
{
|
||||
$detail = '';
|
||||
$fp = @fopen($destination, 'xb');
|
||||
if (!$fp) { $detail = 'Temporaere Quelldatei konnte nicht angelegt werden.'; return false; }
|
||||
|
||||
$url = $base_url.'/remote.php/dav/files/'.rawurlencode($user).'/'.bratonien_tools_webdav_derivative_quote_path($webdav_path);
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, array(
|
||||
CURLOPT_FOLLOWLOCATION => false,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 180,
|
||||
CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
|
||||
CURLOPT_USERPWD => $user.':'.$password,
|
||||
CURLOPT_USERPWD => $connection['user'].':'.$connection['password'],
|
||||
CURLOPT_RETURNTRANSFER => false,
|
||||
CURLOPT_FAILONERROR => false,
|
||||
CURLOPT_FILE => $fp,
|
||||
@@ -98,6 +104,7 @@ function bratonien_tools_webdav_derivative_download(array $source, $destination,
|
||||
$http = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
fclose($fp);
|
||||
|
||||
if ($ok === false || $errno !== 0 || $http < 200 || $http >= 300)
|
||||
{
|
||||
@unlink($destination);
|
||||
@@ -113,40 +120,209 @@ function bratonien_tools_webdav_derivative_download(array $source, $destination,
|
||||
return true;
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_inner_url($derivative_path)
|
||||
function bratonien_tools_webdav_derivative_download(array $source, array $connection, $destination, &$detail=null)
|
||||
{
|
||||
$derivative_root = PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR;
|
||||
if (strpos($derivative_path, $derivative_root) !== 0) return null;
|
||||
$location = ltrim(substr($derivative_path, strlen($derivative_root)), '/');
|
||||
if ($location === '') return null;
|
||||
$segments = array_map('rawurlencode', explode('/', $location));
|
||||
return rtrim(get_absolute_root_url(), '/').'/i.php?/'.implode('/', $segments);
|
||||
$webdav_path = trim((string)($source['webdav_path'] ?? ''), '/');
|
||||
if ($webdav_path === '') { $detail = 'WebDAV-Bildquelle ist unvollstaendig.'; return false; }
|
||||
|
||||
$url = $connection['base_url'].'/remote.php/dav/files/'.rawurlencode($connection['user']).'/'.bratonien_tools_webdav_derivative_quote_path($webdav_path);
|
||||
return bratonien_tools_webdav_derivative_download_url($url, $connection, $destination, $detail);
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_call_i($url, &$status, &$detail=null)
|
||||
function bratonien_tools_webdav_derivative_preview_plan($variant, array $derivative_size, array $source, array $image_row)
|
||||
{
|
||||
$detail = '';
|
||||
$status = 500;
|
||||
$ch = curl_init($url);
|
||||
curl_setopt_array($ch, array(
|
||||
CURLOPT_FOLLOWLOCATION => false,
|
||||
CURLOPT_CONNECTTIMEOUT => 10,
|
||||
CURLOPT_TIMEOUT => 180,
|
||||
CURLOPT_RETURNTRANSFER => false,
|
||||
CURLOPT_FAILONERROR => false,
|
||||
CURLOPT_USERAGENT => 'Bratonien-Tools-WebDAV-Materialize-Gate',
|
||||
CURLOPT_WRITEFUNCTION => function($ch, $data) { return strlen($data); },
|
||||
));
|
||||
$ok = curl_exec($ch);
|
||||
$errno = curl_errno($ch);
|
||||
$error = curl_error($ch);
|
||||
$status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
if ($ok === false || $errno !== 0) { $detail = 'Interner i.php-Aufruf fehlgeschlagen (cURL '.$errno.($error !== '' ? ': '.$error : '').').'; return false; }
|
||||
if ($status < 200 || $status >= 400) { $detail = 'i.php antwortete mit HTTP '.$status.'.'; return false; }
|
||||
if ($variant !== 'custom:s9999x250' && $variant !== 'standard:square') return null;
|
||||
if ((int)($source['fileid'] ?? 0) < 1) return null;
|
||||
if ((int)($source['width'] ?? 0) < 1 || (int)($source['height'] ?? 0) < 1) return null;
|
||||
if ((int)($image_row['rotation'] ?? 0) !== 0) return null;
|
||||
|
||||
$target_width = (int)($derivative_size[0] ?? 0);
|
||||
$target_height = (int)($derivative_size[1] ?? 0);
|
||||
if ($target_width < 1 || $target_height < 1 || max($target_width, $target_height) > 800) return null;
|
||||
|
||||
$source_width = (int)$source['width'];
|
||||
$source_height = (int)$source['height'];
|
||||
$required_width = $target_width * 2;
|
||||
$required_height = $target_height * 2;
|
||||
$scale = max($required_width / $source_width, $required_height / $source_height);
|
||||
$preview_width = max(32, (int)ceil($source_width * $scale));
|
||||
$preview_height = max(32, (int)ceil($source_height * $scale));
|
||||
|
||||
if (max($preview_width, $preview_height) > 1600) return null;
|
||||
|
||||
return array(
|
||||
'fileid'=>(int)$source['fileid'],
|
||||
'width'=>$preview_width,
|
||||
'height'=>$preview_height,
|
||||
);
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_download_preview(array $plan, array $connection, $destination, &$detail=null)
|
||||
{
|
||||
$query = http_build_query(array(
|
||||
'fileId'=>(int)$plan['fileid'],
|
||||
'x'=>(int)$plan['width'],
|
||||
'y'=>(int)$plan['height'],
|
||||
'a'=>'true',
|
||||
'forceIcon'=>'false',
|
||||
'mode'=>'fill',
|
||||
'mimeFallback'=>'false',
|
||||
), '', '&', PHP_QUERY_RFC3986);
|
||||
$url = $connection['base_url'].'/core/preview?'.$query;
|
||||
return bratonien_tools_webdav_derivative_download_url($url, $connection, $destination, $detail);
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_make_dir($dir)
|
||||
{
|
||||
global $conf;
|
||||
if (!is_dir($dir))
|
||||
{
|
||||
$mode = isset($conf['chmod_value']) ? (int)$conf['chmod_value'] : 0755;
|
||||
$umask = umask(0);
|
||||
$ok = @mkdir($dir, $mode, true);
|
||||
umask($umask);
|
||||
if (!$ok && !is_dir($dir)) return false;
|
||||
}
|
||||
if (!is_writable($dir)) return false;
|
||||
$index = rtrim($dir, '/').'/index.htm';
|
||||
if (!file_exists($index)) @file_put_contents($index, 'Not allowed!');
|
||||
return true;
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_generate($source_path, $target_path, $params, array $image_row, &$detail=null)
|
||||
{
|
||||
global $conf;
|
||||
$detail = '';
|
||||
include_once(PHPWG_ROOT_PATH.'admin/include/image.class.php');
|
||||
|
||||
if (!is_object($params)) { $detail = 'Piwigo-Derivatparameter fehlen.'; return false; }
|
||||
if (!is_file($source_path) || !is_readable($source_path)) { $detail = 'Materialisierte Bildquelle ist nicht lesbar.'; return false; }
|
||||
if (!bratonien_tools_webdav_derivative_make_dir(dirname($target_path))) { $detail = 'Piwigo-Derivatverzeichnis konnte nicht angelegt werden.'; return false; }
|
||||
|
||||
$rotation_angle = isset($image_row['rotation'])
|
||||
? pwg_image::get_rotation_angle_from_code($image_row['rotation'])
|
||||
: pwg_image::get_rotation_angle($source_path);
|
||||
$coi = $image_row['coi'] ?? null;
|
||||
|
||||
if (($params->type ?? '') === IMG_CUSTOM)
|
||||
{
|
||||
$defined = ImageStdParams::get_defined_type_map();
|
||||
if (count($defined) > 0)
|
||||
{
|
||||
$sharpen = 0;
|
||||
foreach ($defined as $std_params) $sharpen += $std_params->sharpen;
|
||||
$params->sharpen = round($sharpen / count($defined));
|
||||
}
|
||||
}
|
||||
|
||||
$image = null;
|
||||
$wm_image = null;
|
||||
try
|
||||
{
|
||||
$image = new pwg_image($source_path);
|
||||
$changes = 0;
|
||||
|
||||
if (0 != $rotation_angle)
|
||||
{
|
||||
$image->rotate($rotation_angle);
|
||||
$changes++;
|
||||
}
|
||||
|
||||
$o_size = $d_size = array($image->get_width(), $image->get_height());
|
||||
$crop_rect = null;
|
||||
$scaled_size = null;
|
||||
$params->sizing->compute($o_size, $coi, $crop_rect, $scaled_size);
|
||||
if ($crop_rect)
|
||||
{
|
||||
$image->crop($crop_rect->width(), $crop_rect->height(), $crop_rect->l, $crop_rect->t);
|
||||
$changes++;
|
||||
}
|
||||
if ($scaled_size)
|
||||
{
|
||||
$image->resize($scaled_size[0], $scaled_size[1]);
|
||||
$d_size = $scaled_size;
|
||||
$changes++;
|
||||
}
|
||||
if ($params->sharpen)
|
||||
{
|
||||
$changes += $image->sharpen($params->sharpen);
|
||||
}
|
||||
|
||||
if ($params->will_watermark($d_size))
|
||||
{
|
||||
$wm = ImageStdParams::get_watermark();
|
||||
$wm_image = new pwg_image(PHPWG_ROOT_PATH.$wm->file);
|
||||
$wm_size = array($wm_image->get_width(), $wm_image->get_height());
|
||||
if ($d_size[0] < $wm_size[0] || $d_size[1] < $wm_size[1])
|
||||
{
|
||||
$wm_scaling_params = SizingParams::classic($d_size[0], $d_size[1]);
|
||||
$tmp = null;
|
||||
$wm_scaled_size = null;
|
||||
$wm_scaling_params->compute($wm_size, null, $tmp, $wm_scaled_size);
|
||||
$wm_size = $wm_scaled_size;
|
||||
$wm_image->resize($wm_scaled_size[0], $wm_scaled_size[1]);
|
||||
}
|
||||
$x = round(($wm->xpos / 100) * ($d_size[0] - $wm_size[0]));
|
||||
$y = round(($wm->ypos / 100) * ($d_size[1] - $wm_size[1]));
|
||||
if ($image->compose($wm_image, $x, $y, $wm->opacity))
|
||||
{
|
||||
$changes++;
|
||||
if ($wm->xrepeat || $wm->yrepeat)
|
||||
{
|
||||
$xpad = $wm_size[0] + max(30, round($wm_size[0] / 4));
|
||||
$ypad = $wm_size[1] + max(30, round($wm_size[1] / 4));
|
||||
for ($i = -$wm->xrepeat; $i <= $wm->xrepeat; $i++)
|
||||
{
|
||||
for ($j = -$wm->yrepeat; $j <= $wm->yrepeat; $j++)
|
||||
{
|
||||
if (!$i && !$j) continue;
|
||||
$x2 = $x + $i * $xpad;
|
||||
$y2 = $y + $j * $ypad;
|
||||
if ($x2 >= 0 && $x2 + $wm_size[0] < $d_size[0] && $y2 >= 0 && $y2 + $wm_size[1] < $d_size[1])
|
||||
{
|
||||
if (!$image->compose($wm_image, $x2, $y2, $wm->opacity)) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$wm_image->destroy();
|
||||
$wm_image = null;
|
||||
}
|
||||
|
||||
if (!$changes)
|
||||
{
|
||||
$detail = 'Piwigo-Derivat benoetigt keine Bildaenderung.';
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($d_size[0] * $d_size[1] < ($conf['derivatives_strip_metadata_threshold'] ?? PHP_INT_MAX))
|
||||
{
|
||||
$image->strip();
|
||||
}
|
||||
|
||||
$image->write($target_path);
|
||||
@chmod($target_path, 0644);
|
||||
clearstatcache(true, $target_path);
|
||||
if (!is_file($target_path) || !is_readable($target_path) || @getimagesize($target_path) === false)
|
||||
{
|
||||
$detail = 'Piwigo hat kein gueltiges finales Derivat erzeugt.';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Throwable $e)
|
||||
{
|
||||
$detail = 'Piwigo-Derivaterzeugung fehlgeschlagen: '.$e->getMessage();
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ($wm_image) $wm_image->destroy();
|
||||
if ($image) $image->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
function bratonien_tools_webdav_derivative_after_url($encoded)
|
||||
{
|
||||
$encoded = trim((string)$encoded);
|
||||
@@ -233,7 +409,12 @@ if (!$source)
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'source_resolve_failed');
|
||||
bratonien_tools_webdav_derivative_abort(404, 'Keine WebDAV-Quelle fuer dieses Bild gefunden.');
|
||||
}
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'source_resolved', array('connection_id'=>$source['connection_id'] ?? 0, 'root_fileid'=>$source['root_fileid'] ?? 0, 'webdav_path'=>$source['webdav_path'] ?? ''));
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'source_resolved', array(
|
||||
'connection_id'=>$source['connection_id'] ?? 0,
|
||||
'root_fileid'=>$source['root_fileid'] ?? 0,
|
||||
'fileid'=>$source['fileid'] ?? 0,
|
||||
'webdav_path'=>$source['webdav_path'] ?? '',
|
||||
));
|
||||
|
||||
$params = bratonien_tools_webdav_materialize_params_from_variant($variant);
|
||||
if (!$params) bratonien_tools_webdav_derivative_abort(400, 'Unbekannte Derivat-Variante.');
|
||||
@@ -246,6 +427,7 @@ if ($real_derivative->same_as_source())
|
||||
header('Location: '.$source_url, true, 302);
|
||||
exit;
|
||||
}
|
||||
$derivative_size = $real_derivative->get_size();
|
||||
|
||||
$target_path = $real_derivative->get_path();
|
||||
$derivative_root = PHPWG_ROOT_PATH.PWG_DERIVATIVE_DIR;
|
||||
@@ -324,41 +506,63 @@ try
|
||||
{
|
||||
if (is_link($placeholder_backup)) bratonien_tools_webdav_derivative_abort(503, 'WebDAV-Placeholder-Backup existiert bereits; vorheriger Materialisierungslauf ist nicht sauber abgeschlossen.');
|
||||
$detail = '';
|
||||
$download_start = microtime(true);
|
||||
if (!bratonien_tools_webdav_derivative_download($source, $download_path, $detail)) bratonien_tools_webdav_derivative_abort(502, $detail);
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'download_done', array('ms'=>round((microtime(true)-$download_start)*1000, 1), 'bytes'=>@filesize($download_path) ?: 0));
|
||||
$connection = bratonien_tools_webdav_derivative_connection($source, $detail);
|
||||
if (!$connection) bratonien_tools_webdav_derivative_abort(502, $detail);
|
||||
|
||||
if (!@copy($download_path, $staging_path)) bratonien_tools_webdav_derivative_abort(500, 'Original konnte nicht in den WebDAV-Shadow-Baum kopiert werden.');
|
||||
$source_mode = 'original';
|
||||
$preview_plan = bratonien_tools_webdav_derivative_preview_plan($variant, $derivative_size, $source, $image_row);
|
||||
$download_start = microtime(true);
|
||||
if ($preview_plan !== null)
|
||||
{
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'preview_start', $preview_plan);
|
||||
if (bratonien_tools_webdav_derivative_download_preview($preview_plan, $connection, $download_path, $detail))
|
||||
{
|
||||
$source_mode = 'preview';
|
||||
}
|
||||
else
|
||||
{
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'preview_failed', array('detail'=>$detail));
|
||||
$detail = '';
|
||||
}
|
||||
}
|
||||
if ($source_mode !== 'preview')
|
||||
{
|
||||
if (!bratonien_tools_webdav_derivative_download($source, $connection, $download_path, $detail)) bratonien_tools_webdav_derivative_abort(502, $detail);
|
||||
}
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'download_done', array(
|
||||
'mode'=>$source_mode,
|
||||
'ms'=>round((microtime(true)-$download_start)*1000, 1),
|
||||
'bytes'=>@filesize($download_path) ?: 0,
|
||||
));
|
||||
|
||||
if (!@copy($download_path, $staging_path)) bratonien_tools_webdav_derivative_abort(500, 'Bildquelle konnte nicht in den WebDAV-Shadow-Baum kopiert werden.');
|
||||
@chmod($staging_path, 0644);
|
||||
if (@getimagesize($staging_path) === false) bratonien_tools_webdav_derivative_abort(500, 'Materialisierte Shadow-Quelle ist kein gueltiges Bild.');
|
||||
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'swap_begin', array('placeholder'=>$placeholder_target));
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'swap_begin', array('placeholder'=>$placeholder_target, 'mode'=>$source_mode));
|
||||
if (!@rename($shadow_path, $placeholder_backup)) bratonien_tools_webdav_derivative_abort(500, 'WebDAV-Placeholder konnte nicht temporaer gesichert werden.');
|
||||
if (!@rename($staging_path, $shadow_path))
|
||||
{
|
||||
@rename($placeholder_backup, $shadow_path);
|
||||
bratonien_tools_webdav_derivative_abort(500, 'Materialisiertes Original konnte nicht am Piwigo-Quellpfad aktiviert werden.');
|
||||
bratonien_tools_webdav_derivative_abort(500, 'Materialisierte Bildquelle konnte nicht am Piwigo-Quellpfad aktiviert werden.');
|
||||
}
|
||||
$swapped = true;
|
||||
clearstatcache(true, $shadow_path);
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'swapped', array('is_link'=>is_link($shadow_path), 'realpath'=>realpath($shadow_path) ?: 'FALSE'));
|
||||
if (!is_file($shadow_path) || is_link($shadow_path) || @getimagesize($shadow_path) === false) bratonien_tools_webdav_derivative_abort(500, 'Piwigo-Quellpfad enthaelt nach Materialisierung kein gueltiges Original.');
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'swapped', array('is_link'=>is_link($shadow_path), 'realpath'=>realpath($shadow_path) ?: 'FALSE', 'mode'=>$source_mode));
|
||||
if (!is_file($shadow_path) || is_link($shadow_path) || @getimagesize($shadow_path) === false) bratonien_tools_webdav_derivative_abort(500, 'Piwigo-Quellpfad enthaelt nach Materialisierung keine gueltige Bildquelle.');
|
||||
|
||||
$inner_url = bratonien_tools_webdav_derivative_inner_url($target_path);
|
||||
if ($inner_url === null) bratonien_tools_webdav_derivative_abort(500, 'Piwigo-i.php-URL konnte nicht bestimmt werden.');
|
||||
$inner_status = 500;
|
||||
$i_start = microtime(true);
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'i_start', array('url'=>$inner_url));
|
||||
$i_ok = bratonien_tools_webdav_derivative_call_i($inner_url, $inner_status, $detail);
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'i_done', array('status'=>$inner_status, 'ok'=>$i_ok, 'ms'=>round((microtime(true)-$i_start)*1000, 1), 'detail'=>$detail));
|
||||
if (!$i_ok) bratonien_tools_webdav_derivative_abort(502, $detail);
|
||||
$generate_start = microtime(true);
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'generate_start', array('target'=>$target_path, 'mode'=>$source_mode));
|
||||
$generate_ok = bratonien_tools_webdav_derivative_generate($shadow_path, $target_path, $params, $image_row, $detail);
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'generate_done', array('ok'=>$generate_ok, 'mode'=>$source_mode, 'ms'=>round((microtime(true)-$generate_start)*1000, 1), 'detail'=>$detail));
|
||||
if (!$generate_ok) bratonien_tools_webdav_derivative_abort(500, $detail);
|
||||
|
||||
clearstatcache(true, $target_path);
|
||||
$final_size = @getimagesize($target_path);
|
||||
if (!is_file($target_path) || !is_readable($target_path) || !is_array($final_size)) bratonien_tools_webdav_derivative_abort(500, 'Piwigo hat kein gueltiges finales Derivat erzeugt.');
|
||||
|
||||
$cleanup();
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'serve', array('target'=>$target_path, 'width'=>$final_size[0] ?? 0, 'height'=>$final_size[1] ?? 0));
|
||||
bratonien_tools_webdav_derivative_debug($request_id, 'serve', array('target'=>$target_path, 'width'=>$final_size[0] ?? 0, 'height'=>$final_size[1] ?? 0, 'mode'=>$source_mode));
|
||||
if ($redirect_after !== null) { header('Location: '.$redirect_after, true, 302); exit; }
|
||||
bratonien_tools_webdav_derivative_serve($target_path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user