@rr0/cms
Version:
RR0 Content Management System (CMS)
77 lines (76 loc) • 2.56 kB
JavaScript
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");
}
}
}