From ac6353b050cdf30db79ab20716e66e6a6c841abb Mon Sep 17 00:00:00 2001 From: Terranom674 Date: Thu, 3 Sep 2026 17:43:46 +0200 Subject: [PATCH] Add independent WebDAV source index --- include/webdav_source_index.inc.php | 136 ++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 include/webdav_source_index.inc.php diff --git a/include/webdav_source_index.inc.php b/include/webdav_source_index.inc.php new file mode 100644 index 0000000..cbc77b0 --- /dev/null +++ b/include/webdav_source_index.inc.php @@ -0,0 +1,136 @@ +1, + 'connection_id'=>(int)$connection_id, + 'updated_at'=>0, + 'last_periodic_at'=>0, + 'sources'=>array(), + ); +} + +function bratonien_tools_webdav_source_index_load($connection_id) +{ + $file = bratonien_tools_webdav_source_index_file($connection_id); + if (!is_file($file) || !is_readable($file)) return null; + + $raw = @file_get_contents($file); + $index = $raw !== false ? json_decode($raw, true) : null; + if (!is_array($index)) return null; + + $base = bratonien_tools_webdav_source_index_empty($connection_id); + $index = array_merge($base, $index); + if (!isset($index['sources']) || !is_array($index['sources'])) $index['sources'] = array(); + $index['connection_id'] = (int)$connection_id; + return $index; +} + +function bratonien_tools_webdav_source_index_save($connection_id, array $index) +{ + $file = bratonien_tools_webdav_source_index_file($connection_id); + $directory = dirname($file); + if (!is_dir($directory) && !@mkdir($directory, 0775, true) && !is_dir($directory)) + { + throw new RuntimeException('WebDAV-Quellenindex-Verzeichnis konnte nicht angelegt werden.'); + } + + $index['schema_version'] = 1; + $index['connection_id'] = (int)$connection_id; + $index['updated_at'] = time(); + if (!isset($index['sources']) || !is_array($index['sources'])) $index['sources'] = array(); + ksort($index['sources'], SORT_STRING); + + $json = json_encode($index, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT); + if ($json === false) throw new RuntimeException('WebDAV-Quellenindex konnte nicht serialisiert werden.'); + + $tmp = $file.'.tmp-'.bin2hex(random_bytes(4)); + if (@file_put_contents($tmp, $json."\n", LOCK_EX) === false) + { + throw new RuntimeException('WebDAV-Quellenindex konnte nicht geschrieben werden.'); + } + @chmod($tmp, 0664); + if (!@rename($tmp, $file)) + { + @unlink($tmp); + throw new RuntimeException('WebDAV-Quellenindex konnte nicht atomar gespeichert werden.'); + } +} + +function bratonien_tools_webdav_source_index_key(array $source) +{ + $connection_id = (int)($source['connection_id'] ?? 0); + $fileid = (int)($source['fileid'] ?? 0); + if ($fileid > 0) + { + return 'c'.$connection_id.':f'.$fileid; + } + + $root_fileid = (int)($source['root_fileid'] ?? 0); + $path = trim((string)($source['webdav_path'] ?? ''), '/'); + return 'c'.$connection_id.':r'.$root_fileid.':p'.sha1($path); +} + +function bratonien_tools_webdav_source_index_signature(array $source) +{ + return sha1(implode('|', array( + (int)($source['connection_id'] ?? 0), + (int)($source['root_fileid'] ?? 0), + (int)($source['fileid'] ?? 0), + trim((string)($source['webdav_path'] ?? ''), '/'), + (string)($source['etag'] ?? ''), + (int)($source['size'] ?? 0), + strtolower((string)($source['content_type'] ?? $source['mime'] ?? '')), + (int)($source['width'] ?? 0), + (int)($source['height'] ?? 0), + ))); +} + +function bratonien_tools_webdav_source_index_metadata(array $source, $image_id) +{ + $path = trim((string)($source['webdav_path'] ?? ''), '/'); + return array( + 'image_id'=>(int)$image_id, + 'fileid'=>(int)($source['fileid'] ?? 0), + 'root_fileid'=>(int)($source['root_fileid'] ?? 0), + 'webdav_path'=>$path, + 'name'=>basename($path), + 'etag'=>(string)($source['etag'] ?? ''), + 'size'=>(int)($source['size'] ?? 0), + 'content_type'=>(string)($source['content_type'] ?? $source['mime'] ?? ''), + 'width'=>(int)($source['width'] ?? 0), + 'height'=>(int)($source['height'] ?? 0), + 'source_signature'=>bratonien_tools_webdav_source_index_signature($source), + 'last_seen_at'=>time(), + ); +} + +function bratonien_tools_webdav_source_index_is_current(array $entry, $signature) +{ + return isset($entry['source_signature']) && hash_equals((string)$entry['source_signature'], (string)$signature); +} + +function bratonien_tools_webdav_source_index_prune(array &$index, array $current_keys) +{ + $keep = array_fill_keys($current_keys, true); + $removed = 0; + foreach (array_keys((array)$index['sources']) as $key) + { + if (!isset($keep[$key])) + { + unset($index['sources'][$key]); + $removed++; + } + } + return $removed; +}