aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.ts9
-rw-r--r--src/countries.ts51
-rw-r--r--src/environment/environment.ts8
-rw-r--r--src/main.ts15
-rw-r--r--src/models/country.model.ts3
-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.ts4
-rw-r--r--src/util/image-converter.ts22
-rw-r--r--src/util/logger.ts30
9 files changed, 119 insertions, 23 deletions
diff --git a/src/app.ts b/src/app.ts
index 7064d74..1994462 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -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.",