Skip to content

Commit

Permalink
Further refactoring and local storing
Browse files Browse the repository at this point in the history
  • Loading branch information
afoeder committed Jun 12, 2024
1 parent cb9bbce commit 57bcef8
Show file tree
Hide file tree
Showing 5 changed files with 21,509 additions and 1 deletion.
22 changes: 22 additions & 0 deletions amex-dining-credit/build-places-data.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// run: `$ node --env-file=.env --experimental-fetch build-places-data.mjs
// the standard "Fetch" API is only available experimentally in Node, with the above flag we can make it available.
// handy command line infos: https://nodejs.org/en/learn/command-line/output-to-the-command-line-using-nodejs

import {PlaceRepository} from "./modules/place-repository.mjs";

import merchantsData from "./amex-merchants.json" with { type: "json" };
import fs from "node:fs";

const placeRepository =
PlaceRepository.fromAmexCountriesMerchantsData(merchantsData);

fs.writeFile(
'./places.json',
JSON.stringify(
placeRepository
.findAll()
.map(place => place.toJson()),
null,
2),
error => error && console.error(error));
console.info("All places written.");
2 changes: 1 addition & 1 deletion amex-dining-credit/cache-merchants.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,5 @@ Promise.all(merchantsPromise).then(merchantsInCountries => {
merchants[country] = countryMerchants;
});
fs.writeFile('./amex-merchants.json', JSON.stringify(merchants, null, 2), error => error && console.error(error));
console.info("All merchants written successfully.");
console.info("All merchants data written.");
});
49 changes: 49 additions & 0 deletions amex-dining-credit/modules/place-repository.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {Place} from "./place.mjs";

export class PlaceRepository {

/**
*
* @type {Array<Place>}
*/
#places = []

constructor(places) {
this.#places = places
}

/**
* @returns {Array<Place>}
*/
findAll() {
return this.#places;
}

findByCountry(countryCode) {
return this.#places.filter(place => place.isInCountry(countryCode));
}

static fromAmexCountriesMerchantsData(countriesMerchantsData) {
const places = [];
Object.entries(countriesMerchantsData).forEach(countryMerchantsData => {
const [countryCode, merchantsData] = countryMerchantsData;

places.push(...this.fromAmexMerchantsData(merchantsData, countryCode));
});
return new PlaceRepository(places);
}

static fromAmexMerchantsData(merchantsData, countryCode) {
return merchantsData.flatMap(merchantData => {
if (merchantData.isMerchantGroup) {
// this happens when there is a "merchantGroup";
// like Gordon Ramsey etc. Those have a sub node in ".merchants"
// that again look like the merchants on the first level.
// We have to make a recursion here (yay), like:
console.log("Merchant group!", merchantData.name);
return this.fromAmexMerchantsData(merchantData.merchants, countryCode);
}
return Place.fromAmexMerchantData(merchantData, countryCode);
});
}
}
63 changes: 63 additions & 0 deletions amex-dining-credit/modules/place.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
export class Place {
#name
#address
#zip
#city
#amexId
#assumedLocation = null
#googleMapsUrl
#countryCode;

constructor(name, address, zip, city, amexId, googleMapsUrl, countryCode) {
this.#name = name
this.#address = address
this.#zip = zip
this.#city = city
this.#amexId = amexId
this.#setGoogleMapsUrl(googleMapsUrl)
this.#countryCode = countryCode
}

isInCountry(countryCode) {
return this.#countryCode === countryCode
}

#setGoogleMapsUrl(googleMapsUrl) {
if (!googleMapsUrl) {
return;
}
this.#googleMapsUrl = googleMapsUrl

this.#assumedLocation =
googleMapsUrl
.match(/@(?<lat>-?\d+(?:\.\d+)?),(?<lon>-?\d+(?:\.\d+)?)/)
?.groups ?? null;
if (this.#assumedLocation?.lat) this.#assumedLocation.lat = parseFloat(this.#assumedLocation.lat);
if (this.#assumedLocation?.lon) this.#assumedLocation.lon = parseFloat(this.#assumedLocation.lon);
}

toJson() {
return {
name: this.#name,
address: this.#address,
zip: this.#zip,
city: this.#city,
amexId: this.#amexId,
assumedLocation: this.#assumedLocation,
googleMapsUrl: this.#googleMapsUrl,
countryCode: this.#countryCode,
}
}

static fromAmexMerchantData(merchantData, countryCode) {
return new Place(
merchantData.name,
merchantData.address,
merchantData.postcode,
merchantData.city.title,
merchantData.id,
merchantData.googleMapsUrl,
countryCode
);
}
}
Loading

0 comments on commit 57bcef8

Please sign in to comment.