|
|
|
@ -32,7 +32,6 @@ use OCP\EventDispatcher\IEventListener; |
|
|
|
|
use OCP\Files\Cache\CacheEntryRemovedEvent; |
|
|
|
|
use OCP\Files\Events\Node\BeforeNodeDeletedEvent; |
|
|
|
|
use OCP\Files\Events\Node\BeforeNodeRenamedEvent; |
|
|
|
|
use OCP\Files\File; |
|
|
|
|
use OCP\Files\Folder; |
|
|
|
|
use OCP\Files\Node; |
|
|
|
|
use OCP\Files\NotFoundException; |
|
|
|
@ -46,11 +45,11 @@ use OCP\IUserSession; |
|
|
|
|
*/ |
|
|
|
|
class SyncLivePhotosListener implements IEventListener { |
|
|
|
|
/** @var Array<int, string> */ |
|
|
|
|
private $pendingRenames = []; |
|
|
|
|
private array $pendingRenames = []; |
|
|
|
|
/** @var Array<int, bool> */ |
|
|
|
|
private $pendingDeletion = []; |
|
|
|
|
private array $pendingDeletion = []; |
|
|
|
|
/** @var Array<int, bool> */ |
|
|
|
|
private $pendingRestores = []; |
|
|
|
|
private array $pendingRestores = []; |
|
|
|
|
|
|
|
|
|
public function __construct( |
|
|
|
|
private ?Folder $userFolder, |
|
|
|
@ -78,7 +77,7 @@ class SyncLivePhotosListener implements IEventListener { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($peerFile === null) { |
|
|
|
|
return; |
|
|
|
|
return; // not a Live Photo |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ($event instanceof BeforeNodeRenamedEvent) { |
|
|
|
@ -95,12 +94,9 @@ class SyncLivePhotosListener implements IEventListener { |
|
|
|
|
/** |
|
|
|
|
* During rename events, which also include move operations, |
|
|
|
|
* we rename the peer file using the same name. |
|
|
|
|
* This means that a move operation on the .jpg will trigger |
|
|
|
|
* another recursive one for the .mov. |
|
|
|
|
* Move operations on the .mov file directly are currently blocked. |
|
|
|
|
* The event listener being singleton, we can store the current state |
|
|
|
|
* of pending renames inside the 'pendingRenames' property, |
|
|
|
|
* to prevent infinite recursivity. |
|
|
|
|
* to prevent infinite recursive. |
|
|
|
|
*/ |
|
|
|
|
private function handleMove(BeforeNodeRenamedEvent $event, Node $peerFile): void { |
|
|
|
|
$sourceFile = $event->getSource(); |
|
|
|
@ -111,44 +107,35 @@ class SyncLivePhotosListener implements IEventListener { |
|
|
|
|
$targetName = $targetFile->getName(); |
|
|
|
|
$targetPath = $targetFile->getPath(); |
|
|
|
|
|
|
|
|
|
// Prevent rename of the .mov file if the peer file do not have the same path. |
|
|
|
|
if ($sourceFile->getMimetype() === 'video/quicktime') { |
|
|
|
|
$peerFilePath = $this->pendingRenames[$peerFile->getId()] ?? $peerFile->getPath(); |
|
|
|
|
$targetPathWithoutExtension = preg_replace("/\.$sourceExtension$/", '', $targetPath); |
|
|
|
|
$peerFilePathWithoutExtension = preg_replace("/\.$peerFileExtension$/", '', $peerFilePath); |
|
|
|
|
|
|
|
|
|
if ($targetPathWithoutExtension !== $peerFilePathWithoutExtension) { |
|
|
|
|
$event->abortOperation(new NotPermittedException("The video part of a live photo need to have the same name as the image")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
unset($this->pendingRenames[$peerFile->getId()]); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!str_ends_with($targetName, ".".$sourceExtension)) { |
|
|
|
|
$event->abortOperation(new NotPermittedException("Cannot change the extension of a live photo")); |
|
|
|
|
$event->abortOperation(new NotPermittedException("Cannot change the extension of a Live Photo")); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
$targetParent->get($targetName); |
|
|
|
|
$event->abortOperation(new NotPermittedException("A file already exist at destination path")); |
|
|
|
|
$event->abortOperation(new NotPermittedException("A file already exist at destination path of the Live Photo")); |
|
|
|
|
} catch (NotFoundException $ex) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$peerTargetName = substr($targetName, 0, -strlen($sourceExtension)) . $peerFileExtension; |
|
|
|
|
try { |
|
|
|
|
$peerTargetName = preg_replace("/\.$sourceExtension$/", '.mov', $targetName); |
|
|
|
|
$targetParent->get($peerTargetName); |
|
|
|
|
$event->abortOperation(new NotPermittedException("A file already exist at destination path")); |
|
|
|
|
$event->abortOperation(new NotPermittedException("A file already exist at destination path of the Live Photo")); |
|
|
|
|
} catch (NotFoundException $ex) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$peerTargetPath = preg_replace("/\.$sourceExtension$/", '.mov', $targetPath); |
|
|
|
|
// in case the rename was initiated from this listener, we stop right now |
|
|
|
|
if (array_key_exists($peerFile->getId(), $this->pendingRenames)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$this->pendingRenames[$sourceFile->getId()] = $targetPath; |
|
|
|
|
try { |
|
|
|
|
$peerFile->move($peerTargetPath); |
|
|
|
|
$peerFile->move($targetParent->getPath() . '/' . $peerTargetName); |
|
|
|
|
} catch (\Throwable $ex) { |
|
|
|
|
$event->abortOperation($ex); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
unset($this->pendingRenames[$sourceFile->getId()]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|