Created
June 13, 2025 11:24
-
-
Save rikmeijer/fc9b7341731806c93b05fd361666fb7c to your computer and use it in GitHub Desktop.
Trigger checksum generator in Nextcloud, remotely
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 | |
| /** | |
| * This script uses "sabre/dav" Client to make webdav requests to a Nextcloud instance. | |
| * The "nextcloud-checksum-update" option is a, somewhat, hidden feature in the Sabre Connector (Checksum Update Plugin) | |
| * https://github.com/nextcloud/server/blob/master/apps/dav/lib/Connector/Sabre/ChecksumUpdatePlugin.php | |
| * | |
| * The basic flow is: | |
| * - PROPFIND on /remote.php/dav/Photos (explicitly asking for '{http://owncloud.org/ns}checksums' property) | |
| * - use the proper hash from the response | |
| * - OR do a PATCH request, with the X-Recalculate-Hash header, to trigger the recalculation | |
| * - FOLLOWED BY a HEAD, with the X-Hash header, request on $file_path | |
| * - use the hash from that response (in the oc-checksum response-header) | |
| **/ | |
| define('USED_ALGORITHM', 'md5'); | |
| define('WORKING_PATH', '/Photos'); | |
| $client = new Sabre\DAV\Client([ | |
| 'baseUri' => 'https://nextcloud.example.org/remote.php/dav', | |
| 'userName' => 'john', | |
| 'password' => 's3cr3t' | |
| ]); | |
| $options = $client->options(); | |
| if (in_array("nextcloud-checksum-update", $options) === false) { | |
| exit('Cannot update checksum, so media comparison is impossible'); | |
| } | |
| $available_media_files = $client->propFind(WORKING_PATH, ['{http://owncloud.org/ns}checksums'], 1); | |
| foreach ($available_media_files as $file_path => $available_media_file) { | |
| $hash = null; | |
| if (array_key_exists('{http://owncloud.org/ns}checksums', $available_media_file)) { | |
| foreach ($available_media_file['{http://owncloud.org/ns}checksums'] as $checksum) { | |
| list($algo, $possible_hash) = explode(':', $checksum['value'], 2); | |
| if (strcasecmp($algo, USED_ALGORITHM) === 0) { | |
| $hash = $possible_hash; | |
| break; | |
| } | |
| } | |
| } | |
| if (isset($hash) === false) { | |
| $client->request('PATCH', $file_path, headers: [ | |
| 'X-Recalculate-Hash' => USED_ALGORITHM | |
| ]); | |
| $file = $attempt('request', 'HEAD', $file_path, headers: [ | |
| 'X-Hash' => USED_ALGORITHM | |
| ]); | |
| foreach ($file['headers']['oc-checksum'] as $checksum) { | |
| list($algo, $hash) = explode(':', $checksum, 2); | |
| if (strcasecmp($algo, USED_ALGORITHM) === 0) { | |
| break; | |
| } | |
| } | |
| } | |
| print 'Found '.USED_ALGORITHM.' hash ' . $hash . ' for file ' . $file_id; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment