diff options
Diffstat (limited to 'src/countries.ts')
| -rw-r--r-- | src/countries.ts | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/countries.ts b/src/countries.ts new file mode 100644 index 0000000..895a93f --- /dev/null +++ b/src/countries.ts @@ -0,0 +1,107 @@ +import * as nano from "https://deno.land/x/[email protected]/mod.ts"; +import { environment } from "./environment/environment.ts"; +import { Country } from "./models/country.model.ts"; +import { Cache } from "./util/cache.ts"; + +export class Countries { + list: Country[] = []; + names: string[] = []; + query = environment.queries; + + constructor(private cache: Cache) {} + + async sync(config?: { force: boolean }): Promise<Country[]> { + const lastSynced = this.cache.readTxt("last-synced"); + const savedCountries = this.cache.readJson("countries") as + | Country[] + | undefined; + const week = environment.syncInterval * 23 * 60 * 60 * 1000; + + const shouldSync = + !savedCountries || + !lastSynced || + config?.force || + Date.now() - Number(lastSynced) > week; + + if (shouldSync) { + console.log( + nano.cyan("Syncronizing countries database..."), + config?.force + ? "" + : `\nThis will only happen every ${environment.syncInterval} days` + ); + + // Fetch and parse countries data from API + const response = await fetch(environment.baseUrl + this.query); + const countries = (await response.json()) as Country[]; + + this.list = countries; + this.cache.saveJson("countries", countries); + this.cache.saveTxt("last-synced", JSON.stringify(Date.now())); + + console.log("Synced successfully"); + } else { + this.list = savedCountries; + } + this.names = this.list.map((c) => c.name.common); + return this.list; + } + + find(name: string): Country { + // Replace snake case or kebab case with whitespaces + name = name.toLowerCase().replace(/-|_/g, " "); + + // Find exact match first, then fall back to fuzzy match + const country = this.list.find((c) => { + const countryName = c.name.common.toLocaleLowerCase(); + return countryName === name || countryName.includes(name); + }); + + if (!country) { + throw Error(`Cannot find country named ${name}`); + } + + return country; + } + + print(name: string) { + const country = this.find(name); + let currencies = []; + let iteration = 0; + for (const currencyAbbr in country.currencies) { + iteration++; + const currency = country.currencies[currencyAbbr]; + currencies.push( + `${iteration > 1 ? "\t\t " : ""}${currency.name} [${ + currency.symbol + }](${currencyAbbr})\n` + ); + } + + let languages = []; + for (const langAbbr in country.languages) { + languages.push(country.languages[langAbbr] + " "); + } + + console.log( + nano.cyan("\nCountry:\t"), + country.flag, + country.name.common, + nano.green("\nLanguages:\t"), + ...languages, + nano.green("\nCapital:\t"), + country.capital[0], + nano.green("\nRegion:\t\t"), + country.region, + nano.green("\nPopulation:\t"), + country.population.toLocaleString(), + nano.green("\nCurrencies:\t"), + ...currencies + ); + } + + random(): string { + const randomNum = Math.floor(Math.random() * this.names.length); + return this.names[randomNum]; + } +} |
