UNPKG

@rr0/cms

Version:

RR0 Content Management System (CMS)

77 lines (76 loc) 2.56 kB
import fs from "fs"; import { Place, PlaceLocation } from "@rr0/place"; import { writeFile } from "@javarome/fileutil"; export class PlaceService { constructor(rootDir) { this.rootDir = rootDir; this.cache = new Map(); this.regex = /lat([\d.\-]+)lng([\d.\-]+)/; } async read(fileName) { const fileBuffer = fs.readFileSync(fileName); const execArray = this.regex.exec(fileName); if (!execArray) { throw Error("file name must match " + this.regex.source); } const location = new PlaceLocation(parseFloat(execArray[1]), parseFloat(execArray[2])); const fileContent = fileBuffer.toString(); try { const fileObj = JSON.parse(fileContent); const place = { location, ...fileObj }; this.cachePlace(place); return place; } catch (e) { throw e; } } async get(address) { let place = this.cache.get(address); if (!place) { place = await this.create(address); if (place) { try { const fileName = this.getFileName(place.locations[0]); place = await this.read(fileName); } catch (e) { if (e.code === "ENOENT") { await this.save(place); } else { throw e; } } finally { this.cachePlace(place); } } } return place; } getFileName(location) { return `${this.rootDir}/${this.key(location)}.json`; } key(location) { return `lat${location.lat}lng${location.lng}`; } cachePlace(place) { place.locations.forEach(location => this.cache.set(this.key(location), place)); } async create(address) { const geocodeResult = await this.geocode(address); if (geocodeResult) { const { location, data } = geocodeResult; const elevation = await this.getElevation(location); return new Place([new PlaceLocation(location.lat, location.lng)], elevation, "", data); } } async save(place) { for (const location of place.locations) { const fileName = this.getFileName(location); const contents = JSON.stringify(place, null, 2); await writeFile(fileName, contents, "utf-8"); } } }