-
Notifications
You must be signed in to change notification settings - Fork 197
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Keep old track IDs when moving files within the library
Our previous FileHooks implementation was such that moving a scanned audio file from on folder within the library to another folder within the library caused the track object matching the said file to be deleted and the recreated. Hence, the track got a new ID and it got removed from any playlists where it belonged to. Now we handle file moving separately and differently than a file deletion followed by file recreation, and the track gets updated "in place", without changing the ID or removing it from existing playlists. If, on the other hand, an entire folder full of scanned audio files gets moved, then we do one of two things: 1) In case there's 30 or less audio files contained, we handle each file separately the same way as if those 30 files were moved individually 2) In case there are more than 30 audio files contained, we remove them all from the library and the user needs to rescan the files. The second case is suboptimal but we can't handle any number of files one-by-one during the moving because that could slow down the moving operation too much. In the best case this would annoy the user and in the worst case it would cause a time-out and break the entire operation. This is a partial fix for #1173.
- Loading branch information
Showing
2 changed files
with
116 additions
and
44 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ | |
* @author Morris Jobke <[email protected]> | ||
* @author Pauli Järvinen <[email protected]> | ||
* @copyright Morris Jobke 2013, 2014 | ||
* @copyright Pauli Järvinen 2016 - 2023 | ||
* @copyright Pauli Järvinen 2016 - 2024 | ||
*/ | ||
|
||
namespace OCA\Music\Utility; | ||
|
@@ -83,25 +83,71 @@ public function __construct(Extractor $extractor, | |
* Gets called by 'post_write' (file creation, file update) and 'post_share' hooks | ||
*/ | ||
public function update(File $file, string $userId, string $filePath) : void { | ||
// debug logging | ||
$this->logger->log("update - $filePath", 'debug'); | ||
$mimetype = $file->getMimeType(); | ||
$this->logger->log("update - $filePath - $mimetype", 'debug'); | ||
|
||
// skip files that aren't inside the user specified path | ||
if (!$this->librarySettings->pathBelongsToMusicLibrary($filePath, $userId)) { | ||
$this->logger->log("skipped - file is outside of specified music folder", 'debug'); | ||
return; | ||
} | ||
elseif (Util::startsWith($mimetype, 'image')) { | ||
$this->updateImage($file, $userId); | ||
} | ||
elseif (Util::startsWith($mimetype, 'audio') && !self::isPlaylistMime($mimetype)) { | ||
$libraryRoot = $this->librarySettings->getFolder($userId); | ||
$this->updateAudio($file, $userId, $libraryRoot, $filePath, $mimetype, /*partOfScan=*/false); | ||
} | ||
} | ||
|
||
public function fileMoved(File $file, string $userId) : void { | ||
$mimetype = $file->getMimeType(); | ||
|
||
// debug logging | ||
$this->logger->log("update - mimetype $mimetype", 'debug'); | ||
$this->logger->log('fileMoved - '. $file->getPath() . " - $mimetype", 'debug'); | ||
|
||
if (Util::startsWith($mimetype, 'image')) { | ||
// we don't need to track the identity of images and moving a file can be handled as it was | ||
// a file deletion followed by a file addition | ||
$this->deleteImage([$file->getId()], [$userId]); | ||
$this->updateImage($file, $userId); | ||
} elseif (Util::startsWith($mimetype, 'audio') && !self::isPlaylistMime($mimetype)) { | ||
$libraryRoot = $this->librarySettings->getFolder($userId); | ||
$this->updateAudio($file, $userId, $libraryRoot, $filePath, $mimetype, /*partOfScan=*/false); | ||
} | ||
elseif (Util::startsWith($mimetype, 'audio') && !self::isPlaylistMime($mimetype)) { | ||
if ($this->librarySettings->pathBelongsToMusicLibrary($file->getPath(), $userId)) { | ||
// In the new path, the file (now or still) belongs to the library. Even if it was already in the lib, | ||
// the new path may have an influence on the album or artist name (in case of incomplete metadata). | ||
$libraryRoot = $this->librarySettings->getFolder($userId); | ||
$this->updateAudio($file, $userId, $libraryRoot, $file->getPath(), $mimetype, /*partOfScan=*/false); | ||
} else { | ||
// In the new path, the file doesn't (still or any longer) belong to the library. Remove it if | ||
// it happened to be in the library. | ||
$this->deleteAudio([$file->getId()], [$userId]); | ||
} | ||
} | ||
} | ||
|
||
public function folderMoved(Folder $folder, string $userId) : void { | ||
$this->logger->log('folderMoved - '. $folder->getPath(), 'debug'); | ||
|
||
$audioFiles = $folder->searchByMime('audio'); | ||
|
||
if (\count($audioFiles) > 0) { | ||
if ($this->librarySettings->pathBelongsToMusicLibrary($folder->getPath(), $userId)) { | ||
// The new path of the folder belongs to the library but this doesn't necessarily mean | ||
// that all the file paths below belong to the library, because of the path exclusions. | ||
// Each file needs to be checked and updated separately but this may take too much time | ||
// if there is extensive number of files. | ||
if (\count($audioFiles) <= 30) { | ||
foreach ($audioFiles as $file) { | ||
$this->fileMoved($file, $userId); | ||
} | ||
} else { | ||
// Remove the scanned files to get them rescanned when the Music app is opened. | ||
// TODO: Better handling e.g. by marking the files as dirty. | ||
$this->deleteAudio(Util::extractIds($audioFiles), [$userId]); | ||
} | ||
} | ||
else { | ||
// The new path of the folder doesn't belong to the library so neither does any of the | ||
// contained files. Remove audio files from the lib if found. | ||
$this->deleteAudio(Util::extractIds($audioFiles), [$userId]); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -172,7 +218,6 @@ private function updateAudio(File $file, string $userId, Folder $libraryRoot, st | |
$this->cache->remove($userId, 'collection'); | ||
} | ||
|
||
// debug logging | ||
$this->logger->log('imported entities - ' . | ||
"artist: $artistId, albumArtist: $albumArtistId, album: $albumId, track: {$track->getId()}", | ||
'debug'); | ||
|