mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-21 06:26:26 +00:00
refactor(server): move the KML importer and place-image helpers into places/ (#1832)
Two of the three files in be-places-helpers-fold. placePhotoCache is left for its own PR — it holds three module-level caches and its sweep hangs off the cron, so it needs both a provider with real state and a second entry in the scheduler contract. kmlImport.ts is 212 lines with no state, no database and no I/O — parsing, sanitising and coordinate arithmetic. It is nest/places/kml-import.helpers.ts now, unchanged, next to the places.helpers.ts that already consumes it. placeImage.ts moves to nest/places/place-image.ts as free functions. Making reclaimPlaceImage a provider would have split it from PLACE_IMAGES_DIR, which cannot be injected: nest/common/place-image-upload.ts reads it at module scope to configure multer's storage, before any container exists. That constant is the one thing here that could have broken quietly: path.resolve(__dirname, '../../uploads/places') __dirname moves with the file. From src/services that resolved to <server>/uploads/places; from src/nest/places the same string would have resolved to <server>/src/uploads/places — a directory multer would have happily created, leaving every uploaded place image in the wrong place and every existing one unreachable. The path is now '../../../uploads/places', verified to resolve to the identical absolute directory, and uploads-dirs.test.ts covers it.
This commit is contained in:
@@ -31,7 +31,7 @@ import { ADDON_IDS } from '../../addons';
|
||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||
import { CurrentUser } from '../auth/current-user.decorator';
|
||||
import { PLACE_IMAGE_UPLOAD } from '../common/place-image-upload';
|
||||
import { placeImageUrl } from '../../services/placeImage';
|
||||
import { placeImageUrl } from '../places/place-image';
|
||||
import {
|
||||
CollectionCreateDto,
|
||||
CollectionUpdateDto,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Injectable } from '@nestjs/common';
|
||||
import { DatabaseService } from '../database/database.service';
|
||||
import { PermissionsService } from '../permissions/permissions.service';
|
||||
import { RealtimeService } from '../realtime/realtime.service';
|
||||
import { reclaimPlaceImage } from '../../services/placeImage';
|
||||
import { reclaimPlaceImage } from '../places/place-image';
|
||||
import type {
|
||||
Collection,
|
||||
CollectionDetailResponse,
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from 'path';
|
||||
import { diskStorage } from 'multer';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import type { Request } from 'express';
|
||||
import { PLACE_IMAGES_DIR } from '../../services/placeImage';
|
||||
import { PLACE_IMAGES_DIR } from '../places/place-image';
|
||||
|
||||
const MAX_PLACE_IMAGE_SIZE = 20 * 1024 * 1024; // 20 MB — same cap as covers.
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { db } from '../db/database';
|
||||
import { db } from '../../db/database';
|
||||
|
||||
// Custom place images (the user-uploaded thumbnails from #1136) live in their own
|
||||
// uploads subdir, served statically like covers. Storing the full /uploads/places/…
|
||||
// path in image_url lets every existing thumbnail renderer show it unchanged.
|
||||
export const PLACE_IMAGES_DIR = path.resolve(__dirname, '../../uploads/places');
|
||||
export const PLACE_IMAGES_DIR = path.resolve(__dirname, '../../../uploads/places');
|
||||
const URL_PREFIX = '/uploads/places/';
|
||||
|
||||
export function placeImageUrl(filename: string): string {
|
||||
@@ -25,7 +25,7 @@ import { isUpdateConflict } from '../common/conflictResult';
|
||||
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
|
||||
import { CurrentUser } from '../auth/current-user.decorator';
|
||||
import { PLACE_IMAGE_UPLOAD } from '../common/place-image-upload';
|
||||
import { placeImageUrl } from '../../services/placeImage';
|
||||
import { placeImageUrl } from './place-image';
|
||||
import {
|
||||
PlaceBulkDeleteDto,
|
||||
PlaceBulkUpdateDto,
|
||||
|
||||
@@ -2,7 +2,7 @@ import { XMLParser } from 'fast-xml-parser';
|
||||
import unzipper from 'unzipper';
|
||||
import type { Place } from '../../types';
|
||||
import type { PlaceWithTags } from '../database/database.service';
|
||||
import type { KmlImportSummary } from '../../services/kmlImport';
|
||||
import type { KmlImportSummary } from './kml-import.helpers';
|
||||
import * as placePhotoCache from '../../services/placePhotoCache';
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,10 +18,10 @@ import {
|
||||
extractKmlPlacemarkNodes,
|
||||
parsePlacemarkNode,
|
||||
resolveCategoryIdForFolder,
|
||||
} from '../../services/kmlImport';
|
||||
} from './kml-import.helpers';
|
||||
import { UnsplashService } from '../unsplash/unsplash.service';
|
||||
import { type UpdateConflict, isUpdateConflict } from '../common/conflictResult';
|
||||
import { reclaimPlaceImage } from '../../services/placeImage';
|
||||
import { reclaimPlaceImage } from './place-image';
|
||||
import { onPlaceCreated, onPlaceUpdated, onPlaceDeleted } from '../../services/journeyService';
|
||||
import {
|
||||
COORD_DEDUP_TOLERANCE,
|
||||
|
||||
@@ -54,7 +54,7 @@ import { PermissionsService } from '../../../src/nest/permissions/permissions.se
|
||||
import { RealtimeService } from '../../../src/nest/realtime/realtime.service';
|
||||
import { CollectionsService } from '../../../src/nest/collections/collections.service';
|
||||
import { removeIfUnreferenced } from '../../../src/services/placePhotoCache';
|
||||
import { PLACE_IMAGES_DIR } from '../../../src/services/placeImage';
|
||||
import { PLACE_IMAGES_DIR } from '../../../src/nest/places/place-image';
|
||||
|
||||
const svc = new CollectionsService(new DatabaseService(testDb), new PermissionsService(new DatabaseService(testDb)), new RealtimeService());
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ import { RealtimeService } from '../../../src/nest/realtime/realtime.service';
|
||||
import { PlacesService } from '../../../src/nest/places/places.service';
|
||||
import { MapsService } from '../../../src/nest/maps/maps.service';
|
||||
import { QueryHelpersService } from '../../../src/nest/query-helpers/query-helpers.service';
|
||||
import { PLACE_IMAGES_DIR } from '../../../src/services/placeImage';
|
||||
import { PLACE_IMAGES_DIR } from '../../../src/nest/places/place-image';
|
||||
|
||||
const GPX_FIXTURE = path.join(__dirname, '../../fixtures/test.gpx');
|
||||
const KML_FIXTURE = path.join(__dirname, '../../fixtures/test.kml');
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import {
|
||||
parsePlacemarkNode,
|
||||
resolveCategoryIdForFolder,
|
||||
sanitizeKmlDescription,
|
||||
} from '../../../src/services/kmlImport';
|
||||
} from '../../../../src/nest/places/kml-import.helpers';
|
||||
|
||||
describe('kmlImportUtils', () => {
|
||||
it('sanitizes HTML descriptions with br to newline', () => {
|
||||
Reference in New Issue
Block a user