mirror of
https://github.com/immich-app/immich.git
synced 2026-03-26 03:28:59 +03:00
chore(server): Improve add to multiple albums via bulk checks and inserts (#21052)
* - add addAssetIdsToAlbums to album repo - update albumService to determine all albums and assets with access and coalesce into one set of album_assets to insert * - remove hasAsset check (unnecessary) * - lint * - cleanup * - remove success counts from addAssetsToAlbums results - Fix tests * open-api * await album update
This commit is contained in:
@@ -191,36 +191,57 @@ export class AlbumService extends BaseService {
|
||||
async addAssetsToAlbums(auth: AuthDto, dto: AlbumsAddAssetsDto): Promise<AlbumsAddAssetsResponseDto> {
|
||||
const results: AlbumsAddAssetsResponseDto = {
|
||||
success: false,
|
||||
albumSuccessCount: 0,
|
||||
assetSuccessCount: 0,
|
||||
error: BulkIdErrorReason.DUPLICATE,
|
||||
};
|
||||
const successfulAssetIds: Set<string> = new Set();
|
||||
for (const albumId of dto.albumIds) {
|
||||
try {
|
||||
const albumResults = await this.addAssets(auth, albumId, { ids: dto.assetIds });
|
||||
|
||||
let success = false;
|
||||
for (const res of albumResults) {
|
||||
if (res.success) {
|
||||
success = true;
|
||||
results.success = true;
|
||||
results.error = undefined;
|
||||
successfulAssetIds.add(res.id);
|
||||
} else if (results.error && res.error !== BulkIdErrorReason.DUPLICATE) {
|
||||
results.error = BulkIdErrorReason.UNKNOWN;
|
||||
}
|
||||
}
|
||||
if (success) {
|
||||
results.albumSuccessCount++;
|
||||
}
|
||||
} catch {
|
||||
if (results.error) {
|
||||
results.error = BulkIdErrorReason.UNKNOWN;
|
||||
}
|
||||
const allowedAlbumIds = await this.checkAccess({
|
||||
auth,
|
||||
permission: Permission.AlbumAssetCreate,
|
||||
ids: dto.albumIds,
|
||||
});
|
||||
if (allowedAlbumIds.size === 0) {
|
||||
results.error = BulkIdErrorReason.NO_PERMISSION;
|
||||
return results;
|
||||
}
|
||||
|
||||
const allowedAssetIds = await this.checkAccess({ auth, permission: Permission.AssetShare, ids: dto.assetIds });
|
||||
if (allowedAssetIds.size === 0) {
|
||||
results.error = BulkIdErrorReason.NO_PERMISSION;
|
||||
return results;
|
||||
}
|
||||
|
||||
const albumAssetValues: { albumsId: string; assetsId: string }[] = [];
|
||||
const events: { id: string; recipients: string[] }[] = [];
|
||||
for (const albumId of allowedAlbumIds) {
|
||||
const existingAssetIds = await this.albumRepository.getAssetIds(albumId, [...allowedAssetIds]);
|
||||
const notPresentAssetIds = [...allowedAssetIds].filter((id) => !existingAssetIds.has(id));
|
||||
if (notPresentAssetIds.length === 0) {
|
||||
continue;
|
||||
}
|
||||
const album = await this.findOrFail(albumId, { withAssets: false });
|
||||
results.error = undefined;
|
||||
results.success = true;
|
||||
|
||||
for (const assetId of notPresentAssetIds) {
|
||||
albumAssetValues.push({ albumsId: albumId, assetsId: assetId });
|
||||
}
|
||||
await this.albumRepository.update(albumId, {
|
||||
id: albumId,
|
||||
updatedAt: new Date(),
|
||||
albumThumbnailAssetId: album.albumThumbnailAssetId ?? notPresentAssetIds[0],
|
||||
});
|
||||
const allUsersExceptUs = [...album.albumUsers.map(({ user }) => user.id), album.owner.id].filter(
|
||||
(userId) => userId !== auth.user.id,
|
||||
);
|
||||
events.push({ id: albumId, recipients: allUsersExceptUs });
|
||||
}
|
||||
|
||||
await this.albumRepository.addAssetIdsToAlbums(albumAssetValues);
|
||||
for (const event of events) {
|
||||
for (const recipientId of event.recipients) {
|
||||
await this.eventRepository.emit('AlbumUpdate', { id: event.id, recipientId });
|
||||
}
|
||||
}
|
||||
results.assetSuccessCount = successfulAssetIds.size;
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user