mirror of
https://github.com/Crosstalk-Solutions/project-nomad.git
synced 2026-03-28 03:29:25 +01:00
feat(Maps): automatically download base assets if missing
This commit is contained in:
parent
e7336f2a8e
commit
c8de767052
|
|
@ -13,7 +13,7 @@ export default class MapsController {
|
|||
constructor(private mapService: MapService) {}
|
||||
|
||||
async index({ inertia }: HttpContext) {
|
||||
const baseAssetsCheck = await this.mapService.checkBaseAssetsExist()
|
||||
const baseAssetsCheck = await this.mapService.ensureBaseAssets()
|
||||
const regionFiles = await this.mapService.listRegions()
|
||||
return inertia.render('maps', {
|
||||
maps: {
|
||||
|
|
@ -23,11 +23,6 @@ export default class MapsController {
|
|||
})
|
||||
}
|
||||
|
||||
async checkBaseAssets({}: HttpContext) {
|
||||
const exists = await this.mapService.checkBaseAssetsExist()
|
||||
return { exists }
|
||||
}
|
||||
|
||||
async downloadBaseAssets({ request }: HttpContext) {
|
||||
const payload = await request.validateUsing(remoteDownloadValidatorOptional)
|
||||
await this.mapService.downloadBaseAssets(payload.url)
|
||||
|
|
@ -75,6 +70,15 @@ export default class MapsController {
|
|||
}
|
||||
|
||||
async styles({ response }: HttpContext) {
|
||||
// Automatically ensure base assets are present before generating styles
|
||||
const baseAssetsExist = await this.mapService.ensureBaseAssets()
|
||||
if (!baseAssetsExist) {
|
||||
return response.status(500).send({
|
||||
message:
|
||||
'Base map assets are missing and could not be downloaded. Please check your connection and try again.',
|
||||
})
|
||||
}
|
||||
|
||||
const styles = await this.mapService.generateStylesJSON()
|
||||
return response.json(styles)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export default class SettingsController {
|
|||
}
|
||||
|
||||
async maps({ inertia }: HttpContext) {
|
||||
const baseAssetsCheck = await this.mapService.checkBaseAssetsExist();
|
||||
const baseAssetsCheck = await this.mapService.ensureBaseAssets();
|
||||
const regionFiles = await this.mapService.listRegions();
|
||||
return inertia.render('settings/maps', {
|
||||
maps: {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { extract } from 'tar'
|
|||
import env from '#start/env'
|
||||
import {
|
||||
listDirectoryContentsRecursive,
|
||||
listDirectoryContents,
|
||||
getFileStatsIfExists,
|
||||
deleteFileIfExists,
|
||||
getFile,
|
||||
|
|
@ -50,6 +49,7 @@ export class MapService implements IMapService {
|
|||
private readonly basemapsAssetsDir = 'basemaps-assets'
|
||||
private readonly baseAssetsTarFile = 'base-assets.tar.gz'
|
||||
private readonly baseDirPath = join(process.cwd(), this.mapStoragePath)
|
||||
private baseAssetsExistCache: boolean | null = null
|
||||
|
||||
async listRegions() {
|
||||
const files = (await this.listAllMapStorageItems()).filter(
|
||||
|
|
@ -93,6 +93,9 @@ export class MapService implements IMapService {
|
|||
|
||||
await deleteFileIfExists(tempTarPath)
|
||||
|
||||
// Invalidate cache since we just downloaded new assets
|
||||
this.baseAssetsExistCache = true
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +173,15 @@ export class MapService implements IMapService {
|
|||
|
||||
const filepath = join(process.cwd(), this.mapStoragePath, 'pmtiles', filename)
|
||||
|
||||
|
||||
// First, ensure base assets are present - regions depend on them
|
||||
const baseAssetsExist = await this.ensureBaseAssets()
|
||||
if (!baseAssetsExist) {
|
||||
throw new Error(
|
||||
'Base map assets are missing and could not be downloaded. Please check your connection and try again.'
|
||||
)
|
||||
}
|
||||
|
||||
// Dispatch background job
|
||||
const result = await RunDownloadJob.dispatch({
|
||||
url,
|
||||
|
|
@ -250,18 +262,6 @@ export class MapService implements IMapService {
|
|||
return styles
|
||||
}
|
||||
|
||||
async checkBaseAssetsExist() {
|
||||
const storageContents = await this.listMapStorageItems()
|
||||
const baseStyleItem = storageContents.find(
|
||||
(item) => item.type === 'file' && item.name === this.baseStylesFile
|
||||
)
|
||||
const basemapsAssetsItem = storageContents.find(
|
||||
(item) => item.type === 'directory' && item.name === this.basemapsAssetsDir
|
||||
)
|
||||
|
||||
return !!baseStyleItem && !!basemapsAssetsItem
|
||||
}
|
||||
|
||||
async listCuratedCollections(): Promise<CuratedCollectionWithStatus[]> {
|
||||
const collections = await CuratedCollection.query().where('type', 'map').preload('resources')
|
||||
return collections.map((collection) => ({
|
||||
|
|
@ -303,9 +303,37 @@ export class MapService implements IMapService {
|
|||
}
|
||||
}
|
||||
|
||||
private async listMapStorageItems(): Promise<FileEntry[]> {
|
||||
async ensureBaseAssets(): Promise<boolean> {
|
||||
const exists = await this.checkBaseAssetsExist()
|
||||
if (exists) {
|
||||
return true
|
||||
}
|
||||
|
||||
return await this.downloadBaseAssets()
|
||||
}
|
||||
|
||||
private async checkBaseAssetsExist(useCache: boolean = true): Promise<boolean> {
|
||||
// Return cached result if available and caching is enabled
|
||||
if (useCache && this.baseAssetsExistCache !== null) {
|
||||
return this.baseAssetsExistCache
|
||||
}
|
||||
|
||||
await ensureDirectoryExists(this.baseDirPath)
|
||||
return await listDirectoryContents(this.baseDirPath)
|
||||
|
||||
const baseStylePath = join(this.baseDirPath, this.baseStylesFile)
|
||||
const basemapsAssetsPath = join(this.baseDirPath, this.basemapsAssetsDir)
|
||||
|
||||
const [baseStyleExists, basemapsAssetsExists] = await Promise.all([
|
||||
getFileStatsIfExists(baseStylePath),
|
||||
getFileStatsIfExists(basemapsAssetsPath),
|
||||
])
|
||||
|
||||
const exists = !!baseStyleExists && !!basemapsAssetsExists
|
||||
|
||||
// update cache
|
||||
this.baseAssetsExistCache = exists
|
||||
|
||||
return exists
|
||||
}
|
||||
|
||||
private async listAllMapStorageItems(): Promise<FileEntry[]> {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@ router
|
|||
.group(() => {
|
||||
router.get('/regions', [MapsController, 'listRegions'])
|
||||
router.get('/styles', [MapsController, 'styles'])
|
||||
router.get('/preflight', [MapsController, 'checkBaseAssets'])
|
||||
router.get('/curated-collections', [MapsController, 'listCuratedCollections'])
|
||||
router.post('/fetch-latest-collections', [MapsController, 'fetchLatestCollections'])
|
||||
router.post('/download-base-assets', [MapsController, 'downloadBaseAssets'])
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user