mirror of
https://github.com/immich-app/immich.git
synced 2025-06-01 04:36:19 -04:00
feat(server): memory includes partners assets on timeline (#7993)
* feat(server): memory includes partners assets on timeline * remove unsued code, generate sql * fix test * add test
This commit is contained in:
parent
cd8a124b25
commit
761e7fdd2d
@ -15,6 +15,8 @@ import {
|
|||||||
newStorageRepositoryMock,
|
newStorageRepositoryMock,
|
||||||
newSystemConfigRepositoryMock,
|
newSystemConfigRepositoryMock,
|
||||||
newUserRepositoryMock,
|
newUserRepositoryMock,
|
||||||
|
partnerStub,
|
||||||
|
userStub,
|
||||||
} from '@test';
|
} from '@test';
|
||||||
import { when } from 'jest-when';
|
import { when } from 'jest-when';
|
||||||
import { JobName } from '../job';
|
import { JobName } from '../job';
|
||||||
@ -317,6 +319,7 @@ describe(AssetService.name, () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should set the title correctly', async () => {
|
it('should set the title correctly', async () => {
|
||||||
|
partnerMock.getAll.mockResolvedValue([]);
|
||||||
assetMock.getByDayOfYear.mockResolvedValue([assetStub.image, assetStub.imageFrom2015]);
|
assetMock.getByDayOfYear.mockResolvedValue([assetStub.image, assetStub.imageFrom2015]);
|
||||||
|
|
||||||
await expect(sut.getMemoryLane(authStub.admin, { day: 15, month: 1 })).resolves.toEqual([
|
await expect(sut.getMemoryLane(authStub.admin, { day: 15, month: 1 })).resolves.toEqual([
|
||||||
@ -324,7 +327,17 @@ describe(AssetService.name, () => {
|
|||||||
{ title: '9 years since...', assets: [mapAsset(assetStub.imageFrom2015)] },
|
{ title: '9 years since...', assets: [mapAsset(assetStub.imageFrom2015)] },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(assetMock.getByDayOfYear.mock.calls).toEqual([[authStub.admin.user.id, { day: 15, month: 1 }]]);
|
expect(assetMock.getByDayOfYear.mock.calls).toEqual([[[authStub.admin.user.id], { day: 15, month: 1 }]]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get memories with partners with inTimeline enabled', async () => {
|
||||||
|
partnerMock.getAll.mockResolvedValue([partnerStub.user1ToAdmin1]);
|
||||||
|
|
||||||
|
await sut.getMemoryLane(authStub.admin, { day: 15, month: 1 });
|
||||||
|
|
||||||
|
expect(assetMock.getByDayOfYear.mock.calls).toEqual([
|
||||||
|
[[authStub.admin.user.id, userStub.user1.id], { day: 15, month: 1 }],
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -172,7 +172,16 @@ export class AssetService {
|
|||||||
|
|
||||||
async getMemoryLane(auth: AuthDto, dto: MemoryLaneDto): Promise<MemoryLaneResponseDto[]> {
|
async getMemoryLane(auth: AuthDto, dto: MemoryLaneDto): Promise<MemoryLaneResponseDto[]> {
|
||||||
const currentYear = new Date().getFullYear();
|
const currentYear = new Date().getFullYear();
|
||||||
const assets = await this.assetRepository.getByDayOfYear(auth.user.id, dto);
|
|
||||||
|
// get partners id
|
||||||
|
const userIds: string[] = [auth.user.id];
|
||||||
|
const partners = await this.partnerRepository.getAll(auth.user.id);
|
||||||
|
const partnersIds = partners
|
||||||
|
.filter((partner) => partner.sharedBy && partner.inTimeline)
|
||||||
|
.map((partner) => partner.sharedById);
|
||||||
|
userIds.push(...partnersIds);
|
||||||
|
|
||||||
|
const assets = await this.assetRepository.getByDayOfYear(userIds, dto);
|
||||||
|
|
||||||
return _.chain(assets)
|
return _.chain(assets)
|
||||||
.filter((asset) => asset.localDateTime.getFullYear() < currentYear)
|
.filter((asset) => asset.localDateTime.getFullYear() < currentYear)
|
||||||
|
@ -123,7 +123,7 @@ export interface IAssetRepository {
|
|||||||
select?: FindOptionsSelect<AssetEntity>,
|
select?: FindOptionsSelect<AssetEntity>,
|
||||||
): Promise<AssetEntity[]>;
|
): Promise<AssetEntity[]>;
|
||||||
getByIdsWithAllRelations(ids: string[]): Promise<AssetEntity[]>;
|
getByIdsWithAllRelations(ids: string[]): Promise<AssetEntity[]>;
|
||||||
getByDayOfYear(ownerId: string, monthDay: MonthDay): Promise<AssetEntity[]>;
|
getByDayOfYear(ownerIds: string[], monthDay: MonthDay): Promise<AssetEntity[]>;
|
||||||
getByChecksum(userId: string, checksum: Buffer): Promise<AssetEntity | null>;
|
getByChecksum(userId: string, checksum: Buffer): Promise<AssetEntity | null>;
|
||||||
getByAlbumId(pagination: PaginationOptions, albumId: string): Paginated<AssetEntity>;
|
getByAlbumId(pagination: PaginationOptions, albumId: string): Paginated<AssetEntity>;
|
||||||
getByUserId(pagination: PaginationOptions, userId: string, options?: AssetSearchOptions): Paginated<AssetEntity>;
|
getByUserId(pagination: PaginationOptions, userId: string, options?: AssetSearchOptions): Paginated<AssetEntity>;
|
||||||
|
@ -109,18 +109,18 @@ export class AssetRepository implements IAssetRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] })
|
@GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] })
|
||||||
getByDayOfYear(ownerId: string, { day, month }: MonthDay): Promise<AssetEntity[]> {
|
getByDayOfYear(ownerIds: string[], { day, month }: MonthDay): Promise<AssetEntity[]> {
|
||||||
return this.repository
|
return this.repository
|
||||||
.createQueryBuilder('entity')
|
.createQueryBuilder('entity')
|
||||||
.where(
|
.where(
|
||||||
`entity.ownerId = :ownerId
|
`entity.ownerId IN (:...ownerIds)
|
||||||
AND entity.isVisible = true
|
AND entity.isVisible = true
|
||||||
AND entity.isArchived = false
|
AND entity.isArchived = false
|
||||||
AND entity.resizePath IS NOT NULL
|
AND entity.resizePath IS NOT NULL
|
||||||
AND EXTRACT(DAY FROM entity.localDateTime AT TIME ZONE 'UTC') = :day
|
AND EXTRACT(DAY FROM entity.localDateTime AT TIME ZONE 'UTC') = :day
|
||||||
AND EXTRACT(MONTH FROM entity.localDateTime AT TIME ZONE 'UTC') = :month`,
|
AND EXTRACT(MONTH FROM entity.localDateTime AT TIME ZONE 'UTC') = :month`,
|
||||||
{
|
{
|
||||||
ownerId,
|
ownerIds,
|
||||||
day,
|
day,
|
||||||
month,
|
month,
|
||||||
},
|
},
|
||||||
|
@ -76,89 +76,6 @@ WHERE
|
|||||||
ORDER BY
|
ORDER BY
|
||||||
"AssetEntity"."fileCreatedAt" DESC
|
"AssetEntity"."fileCreatedAt" DESC
|
||||||
|
|
||||||
-- AssetRepository.getByDayOfYear
|
|
||||||
SELECT
|
|
||||||
"entity"."id" AS "entity_id",
|
|
||||||
"entity"."deviceAssetId" AS "entity_deviceAssetId",
|
|
||||||
"entity"."ownerId" AS "entity_ownerId",
|
|
||||||
"entity"."libraryId" AS "entity_libraryId",
|
|
||||||
"entity"."deviceId" AS "entity_deviceId",
|
|
||||||
"entity"."type" AS "entity_type",
|
|
||||||
"entity"."originalPath" AS "entity_originalPath",
|
|
||||||
"entity"."resizePath" AS "entity_resizePath",
|
|
||||||
"entity"."webpPath" AS "entity_webpPath",
|
|
||||||
"entity"."thumbhash" AS "entity_thumbhash",
|
|
||||||
"entity"."encodedVideoPath" AS "entity_encodedVideoPath",
|
|
||||||
"entity"."createdAt" AS "entity_createdAt",
|
|
||||||
"entity"."updatedAt" AS "entity_updatedAt",
|
|
||||||
"entity"."deletedAt" AS "entity_deletedAt",
|
|
||||||
"entity"."fileCreatedAt" AS "entity_fileCreatedAt",
|
|
||||||
"entity"."localDateTime" AS "entity_localDateTime",
|
|
||||||
"entity"."fileModifiedAt" AS "entity_fileModifiedAt",
|
|
||||||
"entity"."isFavorite" AS "entity_isFavorite",
|
|
||||||
"entity"."isArchived" AS "entity_isArchived",
|
|
||||||
"entity"."isExternal" AS "entity_isExternal",
|
|
||||||
"entity"."isReadOnly" AS "entity_isReadOnly",
|
|
||||||
"entity"."isOffline" AS "entity_isOffline",
|
|
||||||
"entity"."checksum" AS "entity_checksum",
|
|
||||||
"entity"."duration" AS "entity_duration",
|
|
||||||
"entity"."isVisible" AS "entity_isVisible",
|
|
||||||
"entity"."livePhotoVideoId" AS "entity_livePhotoVideoId",
|
|
||||||
"entity"."originalFileName" AS "entity_originalFileName",
|
|
||||||
"entity"."sidecarPath" AS "entity_sidecarPath",
|
|
||||||
"entity"."stackId" AS "entity_stackId",
|
|
||||||
"exifInfo"."assetId" AS "exifInfo_assetId",
|
|
||||||
"exifInfo"."description" AS "exifInfo_description",
|
|
||||||
"exifInfo"."exifImageWidth" AS "exifInfo_exifImageWidth",
|
|
||||||
"exifInfo"."exifImageHeight" AS "exifInfo_exifImageHeight",
|
|
||||||
"exifInfo"."fileSizeInByte" AS "exifInfo_fileSizeInByte",
|
|
||||||
"exifInfo"."orientation" AS "exifInfo_orientation",
|
|
||||||
"exifInfo"."dateTimeOriginal" AS "exifInfo_dateTimeOriginal",
|
|
||||||
"exifInfo"."modifyDate" AS "exifInfo_modifyDate",
|
|
||||||
"exifInfo"."timeZone" AS "exifInfo_timeZone",
|
|
||||||
"exifInfo"."latitude" AS "exifInfo_latitude",
|
|
||||||
"exifInfo"."longitude" AS "exifInfo_longitude",
|
|
||||||
"exifInfo"."projectionType" AS "exifInfo_projectionType",
|
|
||||||
"exifInfo"."city" AS "exifInfo_city",
|
|
||||||
"exifInfo"."livePhotoCID" AS "exifInfo_livePhotoCID",
|
|
||||||
"exifInfo"."autoStackId" AS "exifInfo_autoStackId",
|
|
||||||
"exifInfo"."state" AS "exifInfo_state",
|
|
||||||
"exifInfo"."country" AS "exifInfo_country",
|
|
||||||
"exifInfo"."make" AS "exifInfo_make",
|
|
||||||
"exifInfo"."model" AS "exifInfo_model",
|
|
||||||
"exifInfo"."lensModel" AS "exifInfo_lensModel",
|
|
||||||
"exifInfo"."fNumber" AS "exifInfo_fNumber",
|
|
||||||
"exifInfo"."focalLength" AS "exifInfo_focalLength",
|
|
||||||
"exifInfo"."iso" AS "exifInfo_iso",
|
|
||||||
"exifInfo"."exposureTime" AS "exifInfo_exposureTime",
|
|
||||||
"exifInfo"."profileDescription" AS "exifInfo_profileDescription",
|
|
||||||
"exifInfo"."colorspace" AS "exifInfo_colorspace",
|
|
||||||
"exifInfo"."bitsPerSample" AS "exifInfo_bitsPerSample",
|
|
||||||
"exifInfo"."fps" AS "exifInfo_fps"
|
|
||||||
FROM
|
|
||||||
"assets" "entity"
|
|
||||||
LEFT JOIN "exif" "exifInfo" ON "exifInfo"."assetId" = "entity"."id"
|
|
||||||
WHERE
|
|
||||||
(
|
|
||||||
"entity"."ownerId" = $1
|
|
||||||
AND "entity"."isVisible" = true
|
|
||||||
AND "entity"."isArchived" = false
|
|
||||||
AND "entity"."resizePath" IS NOT NULL
|
|
||||||
AND EXTRACT(
|
|
||||||
DAY
|
|
||||||
FROM
|
|
||||||
"entity"."localDateTime" AT TIME ZONE 'UTC'
|
|
||||||
) = $2
|
|
||||||
AND EXTRACT(
|
|
||||||
MONTH
|
|
||||||
FROM
|
|
||||||
"entity"."localDateTime" AT TIME ZONE 'UTC'
|
|
||||||
) = $3
|
|
||||||
)
|
|
||||||
AND ("entity"."deletedAt" IS NULL)
|
|
||||||
ORDER BY
|
|
||||||
"entity"."localDateTime" DESC
|
|
||||||
|
|
||||||
-- AssetRepository.getByIds
|
-- AssetRepository.getByIds
|
||||||
SELECT
|
SELECT
|
||||||
"AssetEntity"."id" AS "AssetEntity_id",
|
"AssetEntity"."id" AS "AssetEntity_id",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user