diff options
| author | Pridon Tetradze <[email protected]> | 2022-06-26 13:46:59 +0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-06-26 13:46:59 +0400 |
| commit | 2e058526d896ab4ee5173ceb80d1248ac08ff594 (patch) | |
| tree | 9550b812ea66f069396fef043cff1d10aeaec859 /src | |
| parent | 8626e2d8e258e11837d27a1e99ef3277e7dfdf3b (diff) | |
| download | countryfetch-2e058526d896ab4ee5173ceb80d1248ac08ff594.tar.xz countryfetch-2e058526d896ab4ee5173ceb80d1248ac08ff594.zip | |
Flag ASCII art, remove tabularization & refactor (#3)
* initial flag image converter
* add flags caching
* refactor, remove tabularization, make flag ASCII optional.
* update readme
* update readme
Diffstat (limited to 'src')
| -rw-r--r-- | src/app.ts | 9 | ||||
| -rw-r--r-- | src/countries.ts | 51 | ||||
| -rw-r--r-- | src/environment/environment.ts | 8 | ||||
| -rw-r--r-- | src/main.ts | 15 | ||||
| -rw-r--r-- | src/models/country.model.ts | 3 | ||||
| -rw-r--r-- | src/models/fetched-country.model.ts (renamed from src/models/FetchedCountry.model.ts) | 0 | ||||
| -rw-r--r-- | src/models/flag-ascii.model.ts | 4 | ||||
| -rw-r--r-- | src/util/image-converter.ts | 22 | ||||
| -rw-r--r-- | src/util/logger.ts | 30 |
9 files changed, 119 insertions, 23 deletions
@@ -20,10 +20,13 @@ export class App { this.logger.help(); break; case "sync": - await this.countries.sync({ force: true }); + await this.countries.sync({ + force: true, + flagAscii: Deno.args[1] === "flags", + }); break; case "random": - this.countries.print(this.countries.random()); + await this.countries.print(this.countries.random()); break; case "capital": const [, ...args] = Deno.args; @@ -34,7 +37,7 @@ export class App { this.logger.log(this.countries.find(Deno.args[1])); break; default: - this.countries.print(Deno.args.join(" ")); + await this.countries.print(Deno.args.join(" "), true); break; } } diff --git a/src/countries.ts b/src/countries.ts index 974edec..2485c49 100644 --- a/src/countries.ts +++ b/src/countries.ts @@ -5,17 +5,27 @@ import { Currencies, Languages, } from "./models/country.model.ts"; +import { FlagAscii } from "./models/flag-ascii.model.ts"; import { Cache } from "./util/cache.ts"; import { Logger } from "./util/logger.ts"; +import { ImageConverter } from "./util/image-converter.ts"; export class Countries { list: Country[] = []; names: string[] = []; + flags: FlagAscii[] = []; query = environment.queries; - constructor(private cache: Cache, private logger: Logger) {} + constructor( + private cache: Cache, + private logger: Logger, + private imageConverter: ImageConverter + ) {} - public async sync(config?: { force: boolean }): Promise<Country[]> { + public async sync(config?: { + force?: boolean; + flagAscii?: boolean; + }): Promise<Country[]> { if (this.shouldSync() || config?.force) { this.logger.alert( "Synchronizing countries database...", @@ -32,11 +42,21 @@ export class Countries { this.cache.saveJson("countries", countries); this.cache.saveTxt("last-synced", JSON.stringify(Date.now())); + if (config?.flagAscii) { + this.logger.alert( + "Generating ASCII art for each country flag. This may take a minute..." + ); + const flagStrings = await this.generateFlagImgs(countries); + this.flags = flagStrings; + this.cache.saveJson("flags", flagStrings); + } + this.logger.success( `Synced successfully: cache saved at ${environment.cacheDir}` ); } else { this.list = this.cache.readJson("countries") as Country[]; + this.flags = (this.cache.readJson("flags") as FlagAscii[]) || []; } this.names = this.list.map((c) => c.name.common); return this.list; @@ -94,10 +114,17 @@ export class Countries { return this.list.filter((country) => country.region === region); } - public print(name: string) { + public async print(name: string, flag?: boolean) { const country = this.find(name); const currencies = this.extractCurrencies(country.currencies); const languages = this.extractLanguages(country.languages); + const FlagAscii = this.flags.find( + (i) => i.countryName === country.name.common + ); + + if (FlagAscii) { + this.logger.log(FlagAscii.flagString[0]); + } this.logger.logCountry({ country: country.name.common, @@ -108,7 +135,7 @@ export class Countries { region: country.region, subregion: country.subregion, capitalLatLng: country.capitalInfo.latlng.join("/"), - timezones: country.timezones.join("\n\t\t\t "), + timezones: country.timezones.join(" | "), tld: country.tld.join(" | "), currencies, languages, @@ -135,7 +162,7 @@ export class Countries { const currency = currencies[currencyAbbr]; result.push(`${currency.name} [${currency.symbol}](${currencyAbbr})`); } - return result.join("\n\t\t\t "); + return result.join(" | "); } private extractLanguages(languages: Languages) { @@ -145,4 +172,18 @@ export class Countries { } return result.join(" | "); } + + private async generateFlagImgs(countries: Country[]): Promise<FlagAscii[]> { + const data = []; + for (const country of countries) { + // Replace png with jpg as the library used has trouble with png + const flagUrl = country.flags["png"].replace(".png", ".jpg"); + const flagString = await this.imageConverter.getImageStrings(flagUrl); + data.push({ + countryName: country.name.common, + flagString, + }); + } + return data; + } } diff --git a/src/environment/environment.ts b/src/environment/environment.ts index ef48c3d..18434f8 100644 --- a/src/environment/environment.ts +++ b/src/environment/environment.ts @@ -2,9 +2,15 @@ import home_dir from "https://deno.land/x/[email protected]/home_dir/mod.ts"; import { join } from "https://deno.land/[email protected]/path/mod.ts"; export const environment = { + // Backend from where the information is fetched baseUrl: "https://restcountries.com/v3.1/", + // Update cache if it has been longer than given DAYS since last sync syncInterval: 7, + // Directory where country information should be stored. cacheDir: join(home_dir() as string, ".cache", "countryfetch"), + // Determines the size of ASCII art flag size + flagWidth: 40, + // Fields that should be fetched from API queries: - "all?fields=name,capital,currencies,population,flag,languages,region,subregion,timezones,latlng,capitalInfo,tld", + "all?fields=name,capital,currencies,population,flag,languages,region,subregion,timezones,latlng,capitalInfo,tld,flags", }; diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..b5eaa1d --- /dev/null +++ b/src/main.ts @@ -0,0 +1,15 @@ +import { App } from "./app.ts"; +import { Logger } from "./util/logger.ts"; +import { Cache } from "./util/cache.ts"; +import { Countries } from "./countries.ts"; +import { ImageConverter } from "./util/image-converter.ts"; + +// I wanted to get the hang of OOP but this feels regrettable +const logger = new Logger(); +const cache = new Cache(); +const imageConverter = new ImageConverter(); + +const countries = new Countries(cache, logger, imageConverter); +const app = new App(logger, countries); + +export default app; diff --git a/src/models/country.model.ts b/src/models/country.model.ts index 61e0dfc..3ebe2b4 100644 --- a/src/models/country.model.ts +++ b/src/models/country.model.ts @@ -4,6 +4,8 @@ type CurrencyAbbr = string; type CurrencyInfo = { name: string; symbol: string }; type LangAbbr = string; +type ImageFormat = "png" | "svg"; +type Flags = Record<ImageFormat, string>; export type Currencies = Record<CurrencyAbbr, CurrencyInfo>; export type Languages = Record<LangAbbr, string>; @@ -35,4 +37,5 @@ export interface Country { latlng: number[]; }; tld: string[]; + flags: Flags; } diff --git a/src/models/FetchedCountry.model.ts b/src/models/fetched-country.model.ts index a53482e..a53482e 100644 --- a/src/models/FetchedCountry.model.ts +++ b/src/models/fetched-country.model.ts diff --git a/src/models/flag-ascii.model.ts b/src/models/flag-ascii.model.ts new file mode 100644 index 0000000..d11c9d1 --- /dev/null +++ b/src/models/flag-ascii.model.ts @@ -0,0 +1,4 @@ +export interface FlagAscii { + countryName: string; + flagString: string[]; +} diff --git a/src/util/image-converter.ts b/src/util/image-converter.ts new file mode 100644 index 0000000..17d070a --- /dev/null +++ b/src/util/image-converter.ts @@ -0,0 +1,22 @@ +import { + printImage, + getImageStrings, +} from "https://x.nest.land/[email protected]/mod.ts"; +import { environment } from "../environment/environment.ts"; + +export class ImageConverter { + width = environment.flagWidth; + public getImageStrings(path: string) { + return getImageStrings({ + path, + width: this.width, + }); + } + + public printImage(path: string) { + return printImage({ + path, + width: this.width, + }); + } +} diff --git a/src/util/logger.ts b/src/util/logger.ts index aaa92c5..58745b7 100644 --- a/src/util/logger.ts +++ b/src/util/logger.ts @@ -1,8 +1,8 @@ import * as nano from "https://deno.land/x/[email protected]/mod.ts"; -import { FetchedCountry } from "../models/FetchedCountry.model.ts"; +import { FetchedCountry } from "../models/fetched-country.model.ts"; export class Logger { - public log(...data: any) { + public log(data: any) { console.log(data); } @@ -15,33 +15,33 @@ export class Logger { } public error(...data: any) { - console.error(data); + console.error(nano.red(data)); } public logCountry(country: FetchedCountry) { console.log( - nano.cyan("\nCountry:\t\t"), + nano.cyan("Country:"), country.country, country.flag, - nano.green("\nLat/Lng\t\t\t"), + nano.green("\nLat/Lng:"), country.latlng, - nano.green("\nPopulation:\t\t"), + nano.green("\nPopulation:"), country.population, - nano.green("\nLanguages:\t\t"), + nano.green("\nLanguages:"), country.languages, - nano.green("\nCapital:\t\t"), + nano.green("\nCapital:"), country.capital, - nano.green("\nCapital Lat/Lng:\t"), + nano.green("\nCapital Lat/Lng:"), country.capitalLatLng, - nano.green("\nRegion:\t\t\t"), + nano.green("\nRegion:"), country.region, - nano.green("\nSubregion:\t\t"), + nano.green("\nSubregion:"), country.subregion, - nano.green("\nTimezones:\t\t"), + nano.green("\nTimezones:"), country.timezones, - nano.green("\nTop Level Domain:\t"), + nano.green("\nTop Level Domain:"), country.tld, - nano.green("\nCurrencies:\t\t"), + nano.green("\nCurrencies:"), country.currencies ); } @@ -63,6 +63,8 @@ export class Logger { "\nARGS:\n", "\tsync", "\n\t\tSynchronize database. Stores countries' data in ~/.cache/conntryfetch/countries.json.", + "\n\t\tPass additional argument 'sync flag' to fetch and convert flags in ASCII art.", + "\n\t\tAfter syncing flags, every countryfetch command will display flag ASCII art.", "\n", "\n\trandom", "\n\t\tPrint information about a random country.", |
