From b845184c80295603e3a02dfad84ff2755d417aff Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Wed, 30 Apr 2025 14:23:32 -0400 Subject: [PATCH] chore: remove old memory lane implementation (#18000) --- mobile/openapi/README.md | Bin 34394 -> 34236 bytes mobile/openapi/lib/api.dart | Bin 12441 -> 12397 bytes mobile/openapi/lib/api/assets_api.dart | Bin 33501 -> 31644 bytes mobile/openapi/lib/api_client.dart | Bin 31663 -> 31569 bytes .../lib/model/memory_lane_response_dto.dart | Bin 3212 -> 0 bytes open-api/immich-openapi-specs.json | 74 ------------------ open-api/typescript-sdk/src/fetch-client.ts | 18 ----- server/src/controllers/asset.controller.ts | 9 +-- server/src/dtos/asset-response.dto.ts | 7 -- server/src/services/asset.service.spec.ts | 59 +------------- server/src/services/asset.service.ts | 29 +------ 11 files changed, 3 insertions(+), 193 deletions(-) delete mode 100644 mobile/openapi/lib/model/memory_lane_response_dto.dart diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index a4fbbf371a7cfea4c960194900f5f1b5f4aecfe8..7c8afb09e4f617f4a35703f20b74938c5fa4542d 100644 GIT binary patch delta 19 acmccB!?dTHX~PHM%^@Pq0h3jj5I0argd4)u1@rYqL^r<`ZVONV mDGo|4F38U-PIW2CkJU)YPuAB*GDt8lflj!DkqOYX@Dfb2n delta 25 hcmaExFf(yOlPF70VqWUxMp2E)DRK&%7m1#h0sxD{3J3rI diff --git a/mobile/openapi/lib/api/assets_api.dart b/mobile/openapi/lib/api/assets_api.dart index f52c70b37f11bfd7389a46a8b935ca9ab2dc5429..f744988449517ec0036332d9013cfeb843baf14d 100644 GIT binary patch delta 14 VcmccH$~5OY;|3|?&Cym(9sn_|1_%HE delta 348 zcmbR9o$+of(*`Ny$$VCF+_|Z_`9+nwIf;3xlOJe#a%AR}#44mDR!-iSAj1XbTH*`V;sewXo>`LNQBqRinU|KY0aOgqsG|U4fHmn%HY^Q9vB6R2 z@MKmAbsnHPbsdmuO-<`b5<2`~=0dxBjFSZ{tGE!BP42f;L+0+X4B0GY H+~ffOaxZ=~ diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index 9d0e80e58b2826e7993a8620fe626a951e014743..ec5eb097293564c238625a19d2227c5e1bac008e 100644 GIT binary patch delta 14 WcmZ4go$=x~#tltYn;%%6cK`r9%m=st delta 35 qcmcckjdA^V#tltYEIx^OsgoP!l;q$)ZY9HHefM69 zvYaYywui(vb-&L!R~!y|!y%mhc{_dc`{a6Zb9y^DgYyrUlNipXa6P?+tLfQ?^S@u9 z8Cky1gmI%^lDF@A^i!=0ZDhLCCS9sr9zj)9R%WTp!T+T&`01pv7~I%y_k}L36NO7vh6&YDNyF~8Gg+<*Y13R6D>QR!QKavF zP8VxoY_Esu9OxzJQWm0A3H}}TdW&3G3s-WZ&F)eZ@7JjrPI|xmD;Gd^omHg@fS82k-S4X$+1J-S4!{X#hqzZD2Htrgxv@0>|Rk(hOiU20!M7 z$RnyV4o|**_1{1}HLTaKxq~#5vYdRbM6TQ}LBK_BBMx8p9M{DTp!V<&L&;dw)8$id zE9qb@?D{vINi3L?HcTag7IGo26=p{SL(Z(FRhG>nKc*zO58x+%9+K~$d^5R^&ZuGq zPWvwr53Apa^US9iz4D)N)6eKtNHp(rf-6y;_;@j7J5+^Qj4{Q9)deQ-bXlrG-#;943&0jL)Au?1b2M%d?U7L^V{aBtyrE&jb4WUPAm;sdA%G|{@SDMcLbiVq zc_l3@jo#D&XMBX(S)xIo6gI<|%ws639EnP-+$zhGYGGU&xkP=lbWF8CD%+Gup5mr( zYLVhnS?i22_Xpi_{FMvgS=Y1o1%|;_<;sYR7D2>S#_+Ne?w6=c(lz$r4Ot_i3~>Ms zAmmudLZFTxLmzpKQ?MF=&V&)CBP$Q~5u83+2uY4>;vC1!-4SRb?Nc}*Kv{mj%72O$T^F1&WmvEtiaPcs;6J@Wpn`}zA3xN?U+>22i zUvF`#v+4eMK$Bs_+?}ZtqWA@-jIf1zRy6NDMP7`U;_bKuIyIDtEb~NadHP9{6e-TZ z+-onVskbN$?Fhm*j=~ZSYG`ep&hp1ZhlW0FXhOYyKxjqN4>azM6*d(09#BAye-{L{ z8+nkPQVK4l`g(E%%}pXjMc|!hf8zt{G9XE{YSO}P}MU)}ju4TiC=7Ndzvv@-gh(`/assets/memory-lane${QS.query(QS.explode({ - day, - month - }))}`, { - ...opts - })); -} /** * This property was deprecated in v1.116.0 */ diff --git a/server/src/controllers/asset.controller.ts b/server/src/controllers/asset.controller.ts index 9a7252a08..925b64c8a 100644 --- a/server/src/controllers/asset.controller.ts +++ b/server/src/controllers/asset.controller.ts @@ -1,7 +1,7 @@ import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, Post, Put, Query } from '@nestjs/common'; import { ApiOperation, ApiTags } from '@nestjs/swagger'; import { EndpointLifecycle } from 'src/decorators'; -import { AssetResponseDto, MemoryLaneResponseDto } from 'src/dtos/asset-response.dto'; +import { AssetResponseDto } from 'src/dtos/asset-response.dto'; import { AssetBulkDeleteDto, AssetBulkUpdateDto, @@ -13,7 +13,6 @@ import { UpdateAssetDto, } from 'src/dtos/asset.dto'; import { AuthDto } from 'src/dtos/auth.dto'; -import { MemoryLaneDto } from 'src/dtos/search.dto'; import { RouteKey } from 'src/enum'; import { Auth, Authenticated } from 'src/middleware/auth.guard'; import { AssetService } from 'src/services/asset.service'; @@ -24,12 +23,6 @@ import { UUIDParamDto } from 'src/validation'; export class AssetController { constructor(private service: AssetService) {} - @Get('memory-lane') - @Authenticated() - getMemoryLane(@Auth() auth: AuthDto, @Query() dto: MemoryLaneDto): Promise { - return this.service.getMemoryLane(auth, dto); - } - @Get('random') @Authenticated() @EndpointLifecycle({ deprecatedAt: 'v1.116.0' }) diff --git a/server/src/dtos/asset-response.dto.ts b/server/src/dtos/asset-response.dto.ts index c0e589f38..3732e665c 100644 --- a/server/src/dtos/asset-response.dto.ts +++ b/server/src/dtos/asset-response.dto.ts @@ -199,10 +199,3 @@ export function mapAsset(entity: MapAsset, options: AssetMapOptions = {}): Asset resized: true, }; } - -export class MemoryLaneResponseDto { - @ApiProperty({ type: 'integer' }) - yearsAgo!: number; - - assets!: AssetResponseDto[]; -} diff --git a/server/src/services/asset.service.spec.ts b/server/src/services/asset.service.spec.ts index af4fef5bd..ecfb7936d 100755 --- a/server/src/services/asset.service.spec.ts +++ b/server/src/services/asset.service.spec.ts @@ -1,6 +1,6 @@ import { BadRequestException } from '@nestjs/common'; import { DateTime } from 'luxon'; -import { MapAsset, mapAsset } from 'src/dtos/asset-response.dto'; +import { MapAsset } from 'src/dtos/asset-response.dto'; import { AssetJobName, AssetStatsResponseDto } from 'src/dtos/asset.dto'; import { AssetStatus, AssetType, JobName, JobStatus } from 'src/enum'; import { AssetStats } from 'src/repositories/asset.repository'; @@ -11,7 +11,6 @@ import { faceStub } from 'test/fixtures/face.stub'; import { userStub } from 'test/fixtures/user.stub'; import { factory } from 'test/small.factory'; import { makeStream, newTestService, ServiceMocks } from 'test/utils'; -import { vitest } from 'vitest'; const stats: AssetStats = { [AssetType.IMAGE]: 10, @@ -44,62 +43,6 @@ describe(AssetService.name, () => { mockGetById([assetStub.livePhotoStillAsset, assetStub.livePhotoMotionAsset]); }); - describe('getMemoryLane', () => { - beforeAll(() => { - vitest.useFakeTimers(); - vitest.setSystemTime(new Date('2024-01-15')); - }); - - afterAll(() => { - vitest.useRealTimers(); - }); - - it('should group the assets correctly', async () => { - const image1 = { ...assetStub.image, localDateTime: new Date(2023, 1, 15, 0, 0, 0) }; - const image2 = { ...assetStub.image, localDateTime: new Date(2023, 1, 15, 1, 0, 0) }; - const image3 = { ...assetStub.image, localDateTime: new Date(2015, 1, 15) }; - const image4 = { ...assetStub.image, localDateTime: new Date(2009, 1, 15) }; - - mocks.partner.getAll.mockResolvedValue([]); - mocks.asset.getByDayOfYear.mockResolvedValue([ - { - year: 2023, - assets: [image1, image2], - }, - { - year: 2015, - assets: [image3], - }, - { - year: 2009, - assets: [image4], - }, - ] as any); - - await expect(sut.getMemoryLane(authStub.admin, { day: 15, month: 1 })).resolves.toEqual([ - { yearsAgo: 1, title: '1 year ago', assets: [mapAsset(image1), mapAsset(image2)] }, - { yearsAgo: 9, title: '9 years ago', assets: [mapAsset(image3)] }, - { yearsAgo: 15, title: '15 years ago', assets: [mapAsset(image4)] }, - ]); - - expect(mocks.asset.getByDayOfYear.mock.calls).toEqual([[[authStub.admin.user.id], { day: 15, month: 1 }]]); - }); - - it('should get memories with partners with inTimeline enabled', async () => { - const partner = factory.partner(); - const auth = factory.auth({ user: { id: partner.sharedWithId } }); - - mocks.partner.getAll.mockResolvedValue([partner]); - mocks.asset.getByDayOfYear.mockResolvedValue([]); - - await sut.getMemoryLane(auth, { day: 15, month: 1 }); - - expect(mocks.asset.getByDayOfYear.mock.calls).toEqual([ - [[auth.user.id, partner.sharedById], { day: 15, month: 1 }], - ]); - }); - }); - describe('getStatistics', () => { it('should get the statistics for a user, excluding archived assets', async () => { mocks.asset.getStatistics.mockResolvedValue(stats); diff --git a/server/src/services/asset.service.ts b/server/src/services/asset.service.ts index 3e13ed0b8..bcbe86875 100644 --- a/server/src/services/asset.service.ts +++ b/server/src/services/asset.service.ts @@ -3,13 +3,7 @@ import _ from 'lodash'; import { DateTime, Duration } from 'luxon'; import { JOBS_ASSET_PAGINATION_SIZE } from 'src/constants'; import { OnJob } from 'src/decorators'; -import { - AssetResponseDto, - MapAsset, - MemoryLaneResponseDto, - SanitizedAssetResponseDto, - mapAsset, -} from 'src/dtos/asset-response.dto'; +import { AssetResponseDto, MapAsset, SanitizedAssetResponseDto, mapAsset } from 'src/dtos/asset-response.dto'; import { AssetBulkDeleteDto, AssetBulkUpdateDto, @@ -20,7 +14,6 @@ import { mapStats, } from 'src/dtos/asset.dto'; import { AuthDto } from 'src/dtos/auth.dto'; -import { MemoryLaneDto } from 'src/dtos/search.dto'; import { AssetStatus, JobName, JobStatus, Permission, QueueName } from 'src/enum'; import { BaseService } from 'src/services/base.service'; import { ISidecarWriteJob, JobItem, JobOf } from 'src/types'; @@ -28,26 +21,6 @@ import { getAssetFiles, getMyPartnerIds, onAfterUnlink, onBeforeLink, onBeforeUn @Injectable() export class AssetService extends BaseService { - async getMemoryLane(auth: AuthDto, dto: MemoryLaneDto): Promise { - const partnerIds = await getMyPartnerIds({ - userId: auth.user.id, - repository: this.partnerRepository, - timelineEnabled: true, - }); - const userIds = [auth.user.id, ...partnerIds]; - - const groups = await this.assetRepository.getByDayOfYear(userIds, dto); - return groups.map(({ year, assets }) => { - const yearsAgo = DateTime.utc().year - year; - return { - yearsAgo, - // TODO move this to clients - title: `${yearsAgo} year${yearsAgo > 1 ? 's' : ''} ago`, - assets: assets.map((asset) => mapAsset(asset, { auth })), - }; - }); - } - async getStatistics(auth: AuthDto, dto: AssetStatsDto) { const stats = await this.assetRepository.getStatistics(auth.user.id, dto); return mapStats(stats);