Created
February 24, 2026 17:11
-
-
Save rikmeijer/ad692f1e4ef02616e6e9e89be860f91d to your computer and use it in GitHub Desktop.
fix originalDatetime based on filename for immich assets (searching for signal- in this example)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| $uri = "https://immich.example.org/api"; | |
| $api_key = "<API_KEY_HERE>"; | |
| $request = function(string $method, string $endpoint, mixed $body = null, array $headers = []) use ($uri, $api_key) { | |
| $curl = curl_init($uri . $endpoint); | |
| curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); | |
| curl_setopt($curl, CURLOPT_HEADER, true); | |
| curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method); | |
| switch ($method) { | |
| case 'HEAD': | |
| curl_setopt($curl, CURLOPT_NOBODY, true); | |
| break; | |
| case 'PUT': | |
| case 'POST': | |
| curl_setopt($curl, CURLOPT_POST, 1); | |
| curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($body)); | |
| $headers[] = 'Content-Type:application/json'; | |
| break; | |
| default: | |
| break; | |
| } | |
| $headers[] = 'x-api-key: ' . $api_key; | |
| curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); | |
| $raw_response = curl_exec($curl); | |
| if ($raw_response === false) { | |
| $error = curl_error($curl); | |
| curl_close($curl); | |
| throw new \Exception($error); | |
| } | |
| $info = curl_getinfo($curl); | |
| curl_close($curl); | |
| $response_headers = []; | |
| foreach(array_filter(explode("\r\n", substr($raw_response, 0, $info['header_size']))) as $response_header) { | |
| if (str_starts_with($response_header, 'HTTP/')) { | |
| list($protocol, $status) = explode(' ', $response_header, 2); | |
| $response_headers['protocol'] = [$protocol]; | |
| $response_headers['status'] = [trim($status)]; | |
| continue; | |
| } | |
| list($header, $value) = explode(':', $response_header, 2); | |
| $response_headers[strtolower($header)] = array_map('trim', explode(';', $value ?? '')); | |
| }; | |
| $response_body = substr($raw_response, $info['header_size']); | |
| if (isset($response_headers['status']) === false) { | |
| throw new \Exception(var_export($raw_response, true)); | |
| } | |
| return [$response_headers['status'], json_decode($response_body)]; | |
| }; | |
| $signal_assets = $request('POST', '/search/metadata', ['originalFileName' => "signal-"])[1]->assets; | |
| while ($signal_assets->nextPage !== null) { | |
| foreach ($signal_assets->items as $signal_asset) { | |
| if (property_exists($signal_asset, 'id') === false) { | |
| continue; | |
| } | |
| print $signal_asset->originalFileName . ": " . $signal_asset->fileCreatedAt; | |
| // signal-2023-02-19-15-08-31-693-1.jpg | |
| if (preg_match('/signal-(?<year>\d\d\d\d)-(?<month>\d\d)-(?<day>\d\d)-(?<hour>\d\d)-?(?<minutes>\d\d)-?(?<seconds>\d\d)/', $signal_asset->originalFileName, $matches) !== 1) { | |
| var_dump($signal_asset->originalFileName); | |
| exit; | |
| } | |
| $datetime = new DateTimeImmutable($matches['year'] . '-' . $matches['month'] . '-' . $matches['day'] . 'T' . $matches['hour'] . ':' . $matches['minutes'] . ':' . $matches['seconds'], new DateTimeZone('europe/amsterdam')); | |
| print ' --> ' . $datetime->format('Y-m-d\\TH:i:s.vp') . PHP_EOL; | |
| print $request('PUT', '/assets/' . $signal_asset->id, ['dateTimeOriginal' => $datetime->format('Y-m-d\\TH:i:s.vp')])[0][0] . PHP_EOL; | |
| } | |
| $signal_assets = $request('POST', '/search/metadata', ['originalFileName' => "signal-", "page" => $signal_assets->nextPage])[1]->assets; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment