atlasq 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/cache/formatted_output/country_title.json +1 -0
- data/cache/formatted_output/multiline_country.json +1 -0
- data/cache/formatted_output/one_line_country.json +1 -0
- data/cache/formatted_output/one_line_currency.json +1 -0
- data/cache/list/all_countries.json +1 -0
- data/cache/list/all_subregions.json +1 -0
- data/cache/search_index/countries_by_currency.json +1 -0
- data/cache/search_index/countries_by_region.json +1 -0
- data/cache/search_index/direct_match_country.json +1 -0
- data/cache/search_index/direct_match_currency.json +1 -0
- data/cache/search_index/partial_match_country.json +1 -0
- data/cache/search_index/partial_match_currency.json +1 -0
- data/lib/atlasq/cache.rb +27 -0
- data/lib/atlasq/command/any.rb +7 -5
- data/lib/atlasq/command/base.rb +1 -1
- data/lib/atlasq/command/country.rb +6 -6
- data/lib/atlasq/command/help.rb +2 -0
- data/lib/atlasq/command/money.rb +6 -5
- data/lib/atlasq/command/region.rb +3 -4
- data/lib/atlasq/command.rb +1 -0
- data/lib/atlasq/data.rb +34 -91
- data/lib/atlasq/format.rb +53 -126
- data/lib/atlasq/partial_match.rb +19 -0
- data/lib/atlasq/util/string.rb +42 -6
- data/lib/atlasq/util/word_map.rb +34 -0
- data/lib/atlasq/util.rb +1 -0
- data/lib/atlasq/version.rb +1 -1
- data/lib/atlasq.rb +2 -0
- metadata +17 -60
- data/lib/atlasq/data/currency.rb +0 -20
- data/lib/atlasq/data/region.rb +0 -24
@@ -0,0 +1 @@
|
|
1
|
+
{"978":["eur"],"eur":["eur"],"€":["eur"],"euro":["eur"],"784":["aed"],"aed":["aed"],"د.ا":["aed","jod"],"united":["aed","usd"],"arab":["aed"],"emirates":["aed"],"dirham":["aed","mad"],"971":["afn"],"afn":["afn"],"؋":["afn"],"afghan":["afn"],"afghani":["afn"],"951":["xcd"],"xcd":["xcd"],"$":["xcd","usd","ars","aud","bbd","bmd","bnd","bsd","bzd","cad","nzd","clp","cop","cup","cve","dop","fjd","gyd","hkd","jmd","kyd","lrd","mxn","nad","sbd","sgd","srd","ttd","twd"],"east":["xcd"],"caribbean":["xcd"],"dollar":["xcd","usd","aud","bbd","bmd","bnd","bsd","bzd","cad","nzd","fjd","gyd","hkd","jmd","kyd","lrd","nad","sbd","sgd","srd","ttd","twd"],"008":["all"],"all":["all"],"l":["all","hnl","lsl","mdl"],"albanian":["all"],"lek":["all"],"051":["amd"],"amd":["amd"],"դր.":["amd"],"armenian":["amd"],"dram":["amd"],"973":["aoa"],"aoa":["aoa"],"kz":["aoa"],"angolan":["aoa"],"kwanza":["aoa"],"840":["usd"],"usd":["usd"],"states":["usd"],"032":["ars"],"ars":["ars"],"argentine":["ars"],"peso":["ars","clp","cop","cup","dop","mxn","php","uyu"],"036":["aud"],"aud":["aud"],"australian":["aud"],"533":["awg"],"awg":["awg"],"f":["awg","ang"],"aruban":["awg"],"florin":["awg"],"944":["azn"],"azn":["azn"],"₼":["azn"],"azerbaijani":["azn"],"manat":["azn","tmt"],"977":["bam"],"bam":["bam"],"км":["bam"],"bosnia":["bam"],"and":["bam","std","ttd"],"herzegovina":["bam"],"convertible":["bam"],"mark":["bam"],"052":["bbd"],"bbd":["bbd"],"barbadian":["bbd"],"050":["bdt"],"bdt":["bdt"],"৳":["bdt"],"bangladeshi":["bdt"],"taka":["bdt"],"952":["xof"],"xof":["xof"],"fr":["xof","bif","cdf","gnf","kmf","xpf"],"west":["xof"],"african":["xof","xaf","zar"],"cfa":["xof","xaf"],"franc":["xof","bif","cdf","xaf","chf","djf","gnf","kmf","xpf","rwf"],"975":["bgn"],"bgn":["bgn"],"лв.":["bgn"],"bulgarian":["bgn"],"lev":["bgn"],"048":["bhd"],"bhd":["bhd"],"د.ب":["bhd"],"bahraini":["bhd"],"dinar":["bhd","dzd","iqd","jod","kwd","lyd","rsd","tnd"],"108":["bif"],"bif":["bif"],"burundian":["bif"],"060":["bmd"],"bmd":["bmd"],"bermudian":["bmd"],"096":["bnd"],"bnd":["bnd"],"brunei":["bnd"],"068":["bob"],"bob":["bob"],"bs.":["bob"],"bolivian":["bob"],"boliviano":["bob"],"986":["brl"],"brl":["brl"],"r$":["brl"],"brazilian":["brl"],"real":["brl"],"044":["bsd"],"bsd":["bsd"],"bahamian":["bsd"],"064":["btn"],"btn":["btn"],"nu.":["btn"],"bhutanese":["btn"],"ngultrum":["btn"],"578":["nok"],"nok":["nok"],"kr":["nok","sek"],"norwegian":["nok"],"krone":["nok","dkk"],"072":["bwp"],"bwp":["bwp"],"p":["bwp","mop"],"botswana":["bwp"],"pula":["bwp"],"933":["byn"],"byn":["byn"],"br":["byn","etb"],"belarusian":["byn"],"ruble":["byn","rub"],"084":["bzd"],"bzd":["bzd"],"belize":["bzd"],"124":["cad"],"cad":["cad"],"canadian":["cad"],"976":["cdf"],"cdf":["cdf"],"congolese":["cdf"],"950":["xaf"],"xaf":["xaf"],"central":["xaf"],"756":["chf"],"chf":["chf"],"swiss":["chf"],"554":["nzd"],"nzd":["nzd"],"new":["nzd","ils","pgk","twd"],"zealand":["nzd"],"152":["clp"],"clp":["clp"],"chilean":["clp"],"156":["cny"],"cny":["cny"],"¥":["cny","jpy"],"chinese":["cny"],"renminbi":["cny"],"yuan":["cny"],"170":["cop"],"cop":["cop"],"colombian":["cop"],"188":["crc"],"crc":["crc"],"₡":["crc"],"costa":["crc"],"rican":["crc"],"colon":["crc"],"192":["cup"],"cup":["cup"],"cuban":["cup"],"132":["cve"],"cve":["cve"],"cape":["cve"],"verdean":["cve"],"escudo":["cve"],"532":["ang"],"ang":["ang"],"netherlands":["ang"],"antillean":["ang"],"gulden":["ang"],"203":["czk"],"czk":["czk"],"kc":["czk"],"czech":["czk"],"koruna":["czk"],"262":["djf"],"djf":["djf"],"fdj":["djf"],"djiboutian":["djf"],"208":["dkk"],"dkk":["dkk"],"kr.":["dkk","isk"],"danish":["dkk"],"214":["dop"],"dop":["dop"],"dominican":["dop"],"012":["dzd"],"dzd":["dzd"],"د.ج":["dzd"],"algerian":["dzd"],"818":["egp"],"egp":["egp"],"ج.م":["egp"],"egyptian":["egp"],"pound":["egp","fkp","gbp","gip","lbp","sdg","shp","ssp","syp"],"504":["mad"],"mad":["mad"],"د.م.":["mad"],"moroccan":["mad"],"230":["etb"],"etb":["etb"],"ethiopian":["etb"],"birr":["etb"],"242":["fjd"],"fjd":["fjd"],"fijian":["fjd"],"238":["fkp"],"fkp":["fkp"],"£":["fkp","gbp","gip","sdg","shp","ssp"],"falkland":["fkp"],"826":["gbp"],"gbp":["gbp"],"british":["gbp"],"981":["gel"],"gel":["gel"],"ლ":["gel"],"georgian":["gel"],"lari":["gel"],"936":["ghs"],"ghs":["ghs"],"₵":["ghs"],"ghanaian":["ghs"],"cedi":["ghs"],"292":["gip"],"gip":["gip"],"gibraltar":["gip"],"270":["gmd"],"gmd":["gmd"],"d":["gmd"],"gambian":["gmd"],"dalasi":["gmd"],"324":["gnf"],"gnf":["gnf"],"guinean":["gnf","pgk"],"320":["gtq"],"gtq":["gtq"],"q":["gtq"],"guatemalan":["gtq"],"quetzal":["gtq"],"328":["gyd"],"gyd":["gyd"],"guyanese":["gyd"],"344":["hkd"],"hkd":["hkd"],"hong":["hkd"],"kong":["hkd"],"340":["hnl"],"hnl":["hnl"],"honduran":["hnl"],"lempira":["hnl"],"332":["htg"],"htg":["htg"],"g":["htg"],"haitian":["htg"],"gourde":["htg"],"348":["huf"],"huf":["huf"],"ft":["huf"],"hungarian":["huf"],"forint":["huf"],"360":["idr"],"idr":["idr"],"rp":["idr"],"indonesian":["idr"],"rupiah":["idr"],"376":["ils"],"ils":["ils"],"₪":["ils"],"israeli":["ils"],"sheqel":["ils"],"356":["inr"],"inr":["inr"],"₹":["inr"],"indian":["inr"],"rupee":["inr","lkr","mur","npr","pkr","scr"],"368":["iqd"],"iqd":["iqd"],"ع.د":["iqd"],"iraqi":["iqd"],"364":["irr"],"irr":["irr"],"ریال":["irr","yer"],"iranian":["irr"],"rial":["irr","omr","yer"],"352":["isk"],"isk":["isk"],"icelandic":["isk"],"krona":["isk","sek"],"388":["jmd"],"jmd":["jmd"],"jamaican":["jmd"],"400":["jod"],"jod":["jod"],"jordanian":["jod"],"392":["jpy"],"jpy":["jpy"],"japanese":["jpy"],"yen":["jpy"],"404":["kes"],"kes":["kes"],"ksh":["kes"],"kenyan":["kes"],"shilling":["kes","sos","tzs","ugx"],"417":["kgs"],"kgs":["kgs"],"som":["kgs","uzs"],"kyrgyzstani":["kgs"],"116":["khr"],"khr":["khr"],"៛":["khr"],"cambodian":["khr"],"riel":["khr"],"174":["kmf"],"kmf":["kmf"],"comorian":["kmf"],"408":["kpw"],"kpw":["kpw"],"₩":["kpw","krw"],"north":["kpw"],"korean":["kpw","krw"],"won":["kpw","krw"],"410":["krw"],"krw":["krw"],"south":["krw","ssp","zar"],"414":["kwd"],"kwd":["kwd"],"د.ك":["kwd"],"kuwaiti":["kwd"],"136":["kyd"],"kyd":["kyd"],"cayman":["kyd"],"islands":["kyd","sbd"],"398":["kzt"],"kzt":["kzt"],"₸":["kzt"],"kazakhstani":["kzt"],"tenge":["kzt"],"418":["lak"],"lak":["lak"],"₭":["lak"],"lao":["lak"],"kip":["lak"],"422":["lbp"],"lbp":["lbp"],"ل.ل":["lbp"],"lebanese":["lbp"],"144":["lkr"],"lkr":["lkr"],"Rs":["lkr","mur","pkr","scr"],"sri":["lkr"],"lankan":["lkr"],"430":["lrd"],"lrd":["lrd"],"liberian":["lrd"],"426":["lsl"],"lsl":["lsl"],"lesotho":["lsl"],"loti":["lsl"],"434":["lyd"],"lyd":["lyd"],"ل.د":["lyd"],"libyan":["lyd"],"498":["mdl"],"mdl":["mdl"],"moldovan":["mdl"],"leu":["mdl","ron"],"969":["mga"],"mga":["mga"],"ar":["mga"],"malagasy":["mga"],"ariary":["mga"],"807":["mkd"],"mkd":["mkd"],"ден":["mkd"],"macedonian":["mkd"],"denar":["mkd"],"104":["mmk"],"mmk":["mmk"],"k":["mmk","pgk","zmw"],"myanmar":["mmk"],"kyat":["mmk"],"496":["mnt"],"mnt":["mnt"],"₮":["mnt"],"mongolian":["mnt"],"togrog":["mnt"],"446":["mop"],"mop":["mop"],"macanese":["mop"],"pataca":["mop"],"929":["mru"],"mru":["mru"],"um":["mru"],"mauritanian":["mru"],"ouguiya":["mru"],"480":["mur"],"mur":["mur"],"mauritian":["mur"],"462":["mvr"],"mvr":["mvr"],"maldivian":["mvr"],"rufiyaa":["mvr"],"454":["mwk"],"mwk":["mwk"],"mk":["mwk"],"malawian":["mwk"],"kwacha":["mwk","zmw"],"484":["mxn"],"mxn":["mxn"],"mexican":["mxn"],"458":["myr"],"myr":["myr"],"rm":["myr"],"malaysian":["myr"],"ringgit":["myr"],"943":["mzn"],"mzn":["mzn"],"mtn":["mzn"],"mozambican":["mzn"],"metical":["mzn"],"516":["nad"],"nad":["nad"],"namibian":["nad"],"953":["xpf"],"xpf":["xpf"],"cfp":["xpf"],"566":["ngn"],"ngn":["ngn"],"₦":["ngn"],"nigerian":["ngn"],"naira":["ngn"],"558":["nio"],"nio":["nio"],"c$":["nio"],"nicaraguan":["nio"],"cordoba":["nio"],"524":["npr"],"npr":["npr"],"rs.":["npr"],"nepalese":["npr"],"512":["omr"],"omr":["omr"],"ر.ع.":["omr"],"omani":["omr"],"590":["pab"],"pab":["pab"],"b/.":["pab"],"panamanian":["pab"],"balboa":["pab"],"604":["pen"],"pen":["pen"],"s/":["pen"],"peruvian":["pen"],"sol":["pen"],"598":["pgk"],"pgk":["pgk"],"papua":["pgk"],"kina":["pgk"],"608":["php"],"php":["php"],"₱":["php"],"philippine":["php"],"586":["pkr"],"pkr":["pkr"],"pakistani":["pkr"],"985":["pln"],"pln":["pln"],"zl":["pln"],"polish":["pln"],"zloty":["pln"],"600":["pyg"],"pyg":["pyg"],"₲":["pyg"],"paraguayan":["pyg"],"guarani":["pyg"],"634":["qar"],"qar":["qar"],"ر.ق":["qar"],"qatari":["qar"],"riyal":["qar","sar"],"946":["ron"],"ron":["ron"],"lei":["ron"],"romanian":["ron"],"941":["rsd"],"rsd":["rsd"],"рсд":["rsd"],"serbian":["rsd"],"643":["rub"],"rub":["rub"],"₽":["rub"],"russian":["rub"],"646":["rwf"],"rwf":["rwf"],"frw":["rwf"],"rwandan":["rwf"],"682":["sar"],"sar":["sar"],"ر.س":["sar"],"saudi":["sar"],"090":["sbd"],"sbd":["sbd"],"solomon":["sbd"],"690":["scr"],"scr":["scr"],"seychellois":["scr"],"938":["sdg"],"sdg":["sdg"],"sudanese":["sdg","ssp"],"752":["sek"],"sek":["sek"],"swedish":["sek"],"702":["sgd"],"sgd":["sgd"],"singapore":["sgd"],"654":["shp"],"shp":["shp"],"saint":["shp"],"helenian":["shp"],"694":["sll"],"sll":["sll"],"le":["sll"],"sierra":["sll"],"leonean":["sll"],"leone":["sll"],"706":["sos"],"sos":["sos"],"sh":["sos","tzs"],"somali":["sos"],"968":["srd"],"srd":["srd"],"surinamese":["srd"],"728":["ssp"],"ssp":["ssp"],"678":["std"],"std":["std"],"db":["std"],"sao":["std"],"tome":["std"],"principe":["std"],"dobra":["std"],"760":["syp"],"syp":["syp"],"£s":["syp"],"syrian":["syp"],"748":["szl"],"szl":["szl"],"e":["szl"],"swazi":["szl"],"lilangeni":["szl"],"764":["thb"],"thb":["thb"],"฿":["thb"],"thai":["thb"],"baht":["thb"],"972":["tjs"],"tjs":["tjs"],"ѕм":["tjs"],"tajikistani":["tjs"],"somoni":["tjs"],"934":["tmt"],"tmt":["tmt"],"t":["tmt","wst"],"turkmenistani":["tmt"],"788":["tnd"],"tnd":["tnd"],"د.ت":["tnd"],"tunisian":["tnd"],"776":["top"],"top":["top"],"t$":["top"],"tongan":["top"],"paʻanga":["top"],"949":["try"],"try":["try"],"₺":["try"],"turkish":["try"],"lira":["try"],"780":["ttd"],"ttd":["ttd"],"trinidad":["ttd"],"tobago":["ttd"],"901":["twd"],"twd":["twd"],"taiwan":["twd"],"834":["tzs"],"tzs":["tzs"],"tanzanian":["tzs"],"980":["uah"],"uah":["uah"],"₴":["uah"],"ukrainian":["uah"],"hryvnia":["uah"],"800":["ugx"],"ugx":["ugx"],"ush":["ugx"],"ugandan":["ugx"],"858":["uyu"],"uyu":["uyu"],"$u":["uyu"],"uruguayan":["uyu"],"860":["uzs"],"uzs":["uzs"],"so'm":["uzs"],"uzbekistan":["uzs"],"928":["ves"],"ves":["ves"],"bs":["ves"],"venezuelan":["ves"],"bolivar":["ves"],"soberano":["ves"],"704":["vnd"],"vnd":["vnd"],"₫":["vnd"],"vietnamese":["vnd"],"dong":["vnd"],"548":["vuv"],"vuv":["vuv"],"vt":["vuv"],"vanuatu":["vuv"],"vatu":["vuv"],"882":["wst"],"wst":["wst"],"samoan":["wst"],"tala":["wst"],"886":["yer"],"yer":["yer"],"yemeni":["yer"],"710":["zar"],"zar":["zar"],"r":["zar"],"rand":["zar"],"967":["zmw"],"zmw":["zmw"],"zambian":["zmw"]}
|
data/lib/atlasq/cache.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
module Atlasq
|
6
|
+
module Cache
|
7
|
+
CACHE_DIR = File.expand_path("../../cache", __dir__).freeze
|
8
|
+
private_constant :CACHE_DIR
|
9
|
+
|
10
|
+
# @param full_name [String] namespace + file name (ex. "info/countries.json")
|
11
|
+
# @return file
|
12
|
+
def self.get(full_name)
|
13
|
+
@get ||= {}
|
14
|
+
@get.fetch(full_name) do
|
15
|
+
path = "#{CACHE_DIR}/#{full_name}"
|
16
|
+
content = File.read(path)
|
17
|
+
|
18
|
+
case full_name
|
19
|
+
when /\.json$/
|
20
|
+
JSON.parse(content)
|
21
|
+
else
|
22
|
+
content
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/atlasq/command/any.rb
CHANGED
@@ -7,11 +7,13 @@ module Atlasq
|
|
7
7
|
class Any < Base
|
8
8
|
def content
|
9
9
|
search_terms.map do |term|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
Format.
|
10
|
+
if (country = Data.country(term))
|
11
|
+
Format.country(country)
|
12
|
+
elsif (country_codes = Data.countries_by_region(term))
|
13
|
+
region_name = Util::String.titleize(term)
|
14
|
+
Format.countries(country_codes, title: "Region: #{region_name}")
|
15
|
+
elsif (currencies = Data.countries_by_currencies(term))
|
16
|
+
Format.currencies(currencies)
|
15
17
|
else
|
16
18
|
Atlasq.failed!
|
17
19
|
"Unknown search term: #{term}"
|
data/lib/atlasq/command/base.rb
CHANGED
@@ -8,14 +8,14 @@ module Atlasq
|
|
8
8
|
# @return [String]
|
9
9
|
def content
|
10
10
|
if search_terms.empty?
|
11
|
-
|
12
|
-
Format.countries(
|
11
|
+
country_codes = Data.all_countries
|
12
|
+
Format.countries(country_codes, title: "All Countries")
|
13
13
|
else
|
14
14
|
search_terms.map do |term|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
Format.
|
15
|
+
if (country_code = Data.country(term))
|
16
|
+
Format.country(country_code)
|
17
|
+
elsif (country_codes = PartialMatch.countries(term)).any?
|
18
|
+
Format.countries(country_codes, title: "Countries (Partial Match)")
|
19
19
|
else
|
20
20
|
Atlasq.failed!
|
21
21
|
"Unknown country: #{term}"
|
data/lib/atlasq/command/help.rb
CHANGED
@@ -41,6 +41,7 @@ module Atlasq
|
|
41
41
|
2. alpha3 (ISO3166 standard 3 letter code)
|
42
42
|
3. number (ISO3166 standard 3 digit code)
|
43
43
|
4. name (common, localized, unofficial)
|
44
|
+
5. partial match on name
|
44
45
|
|
45
46
|
-r/--region
|
46
47
|
: Display all countries by subregion
|
@@ -58,6 +59,7 @@ module Atlasq
|
|
58
59
|
1. code (ISO4127 standard 3 letter code)
|
59
60
|
2. name (ISO4127 standard name)
|
60
61
|
3. symbol
|
62
|
+
4. partial match on name
|
61
63
|
|
62
64
|
-h/--help
|
63
65
|
: Display this page
|
data/lib/atlasq/command/money.rb
CHANGED
@@ -11,13 +11,14 @@ module Atlasq
|
|
11
11
|
Format.currencies(currencies)
|
12
12
|
else
|
13
13
|
search_terms.map do |term|
|
14
|
-
currencies = Data.
|
15
|
-
|
16
|
-
|
14
|
+
if (currencies = Data.countries_by_currencies(term))
|
15
|
+
Format.currencies(currencies)
|
16
|
+
elsif (currency_codes = PartialMatch.currencies(term)).any?
|
17
|
+
currencies = Data.countries_by_currencies(currency_codes)
|
18
|
+
Format.currencies(currencies, partial_match: true)
|
19
|
+
else
|
17
20
|
Atlasq.failed!
|
18
21
|
"Unknown currency: #{term}"
|
19
|
-
else
|
20
|
-
Format.currencies(currencies)
|
21
22
|
end
|
22
23
|
end.join("\n\n")
|
23
24
|
end
|
@@ -11,10 +11,9 @@ module Atlasq
|
|
11
11
|
Format.subregions(subregions)
|
12
12
|
else
|
13
13
|
search_terms.map do |term|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
Format.region(region)
|
14
|
+
if (country_codes = Data.countries_by_region(term))
|
15
|
+
region_name = Util::String.titleize(term)
|
16
|
+
Format.countries(country_codes, title: "Region: #{region_name}")
|
18
17
|
else
|
19
18
|
Atlasq.failed!
|
20
19
|
"Unknown region: #{term}"
|
data/lib/atlasq/command.rb
CHANGED
data/lib/atlasq/data.rb
CHANGED
@@ -1,113 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "countries"
|
4
|
-
require "iso-639"
|
5
|
-
require "money"
|
6
|
-
require "money-heuristics"
|
7
|
-
|
8
|
-
ISO3166.configure do |config|
|
9
|
-
# Needed to allow us to access the `ISO3166::Country#currency`
|
10
|
-
# object which ends up being an instance of `Money::Currency`.
|
11
|
-
config.enable_currency_extension!
|
12
|
-
|
13
|
-
# Needed to allow us to search by localized country name.
|
14
|
-
config.locales = %i[
|
15
|
-
af am ar as az be bg bn br bs
|
16
|
-
ca cs cy da de dz el en eo es
|
17
|
-
et eu fa fi fo fr ga gl gu he
|
18
|
-
hi hr hu hy ia id is it ja ka
|
19
|
-
kk km kn ko ku lt lv mi mk ml
|
20
|
-
mn mr ms mt nb ne nl nn oc or
|
21
|
-
pa pl ps pt ro ru rw si sk sl
|
22
|
-
so sq sr sv sw ta te th ti tk
|
23
|
-
tl tr tt ug uk ve vi wa wo xh
|
24
|
-
zh zu
|
25
|
-
]
|
26
|
-
end
|
27
|
-
|
28
3
|
module Atlasq
|
29
4
|
module Data
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
Data.country(term) ||
|
37
|
-
Data.region(term) ||
|
38
|
-
Data.currencies(term)
|
5
|
+
# @param term [String] search term
|
6
|
+
# @return [String, nil] ISO3166 2 letter country code
|
7
|
+
def self.country(term)
|
8
|
+
Cache
|
9
|
+
.get("search_index/direct_match_country.json")
|
10
|
+
.dig(term)
|
39
11
|
end
|
40
12
|
|
41
|
-
# @param term [String]
|
42
|
-
# @return [
|
43
|
-
def self.
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
ISO3166::Country.find_country_by_any_name(term)
|
13
|
+
# @param term [String] search term
|
14
|
+
# @return [Array<String>, nil] ISO3166 2 letter country codes
|
15
|
+
def self.countries_by_region(term)
|
16
|
+
Cache
|
17
|
+
.get("search_index/countries_by_region.json")
|
18
|
+
.dig(term)
|
48
19
|
end
|
49
20
|
|
50
|
-
# @return [Array<
|
21
|
+
# @return [Array<String>] ISO3166 2 letter country codes
|
51
22
|
def self.all_countries
|
52
|
-
|
23
|
+
Cache.get("list/all_countries.json")
|
53
24
|
end
|
54
25
|
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
# @return [Atlasq::Data::Region|nil]
|
59
|
-
def self.region(term)
|
60
|
-
REGION_TYPES.each do |region_type|
|
61
|
-
countries = ISO3166::Country.find_all_by(region_type, term)
|
62
|
-
next if countries.empty?
|
26
|
+
# @return [Array<String>]
|
27
|
+
def self.all_subregions
|
28
|
+
subregions = Cache.get("list/all_subregions.json")
|
63
29
|
|
64
|
-
|
65
|
-
|
66
|
-
|
30
|
+
Cache
|
31
|
+
.get("search_index/countries_by_region.json")
|
32
|
+
.slice(*subregions)
|
67
33
|
end
|
68
34
|
|
69
|
-
# @
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
# (334 | HM | HMD | Heard Island and McDonald Islands)
|
78
|
-
subregions.delete("")
|
79
|
-
end
|
80
|
-
end
|
35
|
+
# @param terms [String, Array<String>] search terms
|
36
|
+
# @return [Hash<String, Array<String>>] ISO4127 3 letter currency code to ISO3166 2 letter country codes
|
37
|
+
def self.countries_by_currencies(terms)
|
38
|
+
terms = Array(terms)
|
39
|
+
currency_codes = Cache
|
40
|
+
.get("search_index/direct_match_currency.json")
|
41
|
+
.values_at(*terms)
|
42
|
+
.compact
|
81
43
|
|
82
|
-
|
83
|
-
# @return [Array<Atlasq::Data::Currency>]
|
84
|
-
def self.currencies(term)
|
85
|
-
currency_codes = Money::Currency.analyze(term)
|
86
|
-
currency_codes.filter_map do |currency_code|
|
87
|
-
countries = ISO3166::Country.find_all_by(:currency_code, currency_code)
|
88
|
-
next if countries.empty?
|
44
|
+
return if currency_codes.empty?
|
89
45
|
|
90
|
-
|
91
|
-
|
46
|
+
Cache
|
47
|
+
.get("search_index/countries_by_currency.json")
|
48
|
+
.slice(*currency_codes)
|
92
49
|
end
|
93
50
|
|
94
|
-
# @return [Array<
|
51
|
+
# @return [Hash<String, Array<String>>] ISO4127 3 letter currency code to ISO3166 2 letter country codes
|
95
52
|
def self.all_currencies
|
96
|
-
|
97
|
-
.group_by(&:currency_code)
|
98
|
-
.map do |currency_code, countries|
|
99
|
-
Currency.new(countries: countries, currency_code: currency_code)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# @param number [String] ISO3166-1 numeric country code
|
104
|
-
# @return [String, nil]
|
105
|
-
def self.emoji_flag(iso_number)
|
106
|
-
@emoji_flag ||= all_countries
|
107
|
-
.to_h { |country| [country.number, country.emoji_flag] }
|
108
|
-
.freeze
|
109
|
-
|
110
|
-
@emoji_flag[iso_number]
|
53
|
+
Cache.get("search_index/countries_by_currency.json")
|
111
54
|
end
|
112
55
|
end
|
113
56
|
end
|
data/lib/atlasq/format.rb
CHANGED
@@ -13,7 +13,7 @@ module Atlasq
|
|
13
13
|
[
|
14
14
|
"*",
|
15
15
|
"* #{title}",
|
16
|
-
"*#{" *" * ((title.size / 2) + 2)}"
|
16
|
+
"*#{" *" * ((title.size / 2) + 2)}",
|
17
17
|
].join("\n")
|
18
18
|
end
|
19
19
|
|
@@ -56,168 +56,95 @@ module Atlasq
|
|
56
56
|
|
57
57
|
[
|
58
58
|
Format.title(title),
|
59
|
-
*elements
|
59
|
+
*elements,
|
60
60
|
].join("\n")
|
61
61
|
end
|
62
62
|
|
63
|
-
# @
|
64
|
-
# *
|
65
|
-
# * Title
|
66
|
-
# * * * * *
|
67
|
-
# (attr1 | attr2 | attr3)
|
68
|
-
# | Info One: 1
|
69
|
-
# | Info Two: 2
|
70
|
-
# | Info Three: 3
|
71
|
-
# |________________________________________
|
72
|
-
#
|
63
|
+
# @param country_codes [Array<String>] ISO3166 2 letter country codes
|
73
64
|
# @param title [String]
|
74
|
-
# @param attributes [String]
|
75
|
-
# @param info [Hash<String, String>]
|
76
|
-
# @return [String]
|
77
|
-
def self.verbose_template(title:, attributes:, info:)
|
78
|
-
info_ladder = info.map.with_index do |(name, value), index|
|
79
|
-
"#{" " * (index + 1)}| #{name}: #{value}"
|
80
|
-
end
|
81
|
-
info_ladder << "#{" " * (info_ladder.size + 1)}|#{"_" * 40}"
|
82
|
-
|
83
|
-
[
|
84
|
-
Format.title(title),
|
85
|
-
attributes,
|
86
|
-
*info_ladder
|
87
|
-
].join("\n")
|
88
|
-
end
|
89
|
-
|
90
|
-
# @param value
|
91
|
-
# @param search_term [String]
|
92
|
-
# @return [String]
|
93
|
-
def self.any(value, search_term)
|
94
|
-
case value
|
95
|
-
in ISO3166::Country
|
96
|
-
Format.country(value, search_term)
|
97
|
-
in Atlasq::Data::Region
|
98
|
-
Format.region(value)
|
99
|
-
in [Atlasq::Data::Currency, *]
|
100
|
-
Format.currencies(value)
|
101
|
-
else
|
102
|
-
raise Error, "Unknown format type: #{value.class}"
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
# @param country [ISO3166::Country]
|
107
|
-
# @param search_term [String]
|
108
|
-
# @return [String]
|
109
|
-
def self.country(country, search_term)
|
110
|
-
Format.verbose_template(
|
111
|
-
title: "Country: #{country.iso_long_name}",
|
112
|
-
attributes: Format.one_line_country(country),
|
113
|
-
info: {
|
114
|
-
"Search Term" => search_term,
|
115
|
-
"Languages" => Format.languages(country.languages),
|
116
|
-
"Nationality" => country.nationality,
|
117
|
-
"Region" => country.subregion,
|
118
|
-
"Continent" => country.continent,
|
119
|
-
"Currency" => "#{country.currency.symbol} #{country.currency.name}"
|
120
|
-
}.reject do |_, value|
|
121
|
-
# "countries" like Antarctica can have missing language, nationality,
|
122
|
-
# and region data so we remove that missing data beforehand.
|
123
|
-
value.nil? || value.empty?
|
124
|
-
end.to_h
|
125
|
-
)
|
126
|
-
end
|
127
|
-
|
128
|
-
# @example "English / Shona / Ndebele, North; North Ndebele"
|
129
|
-
# @param language_codes [Array<String>] Ex. ["id"]
|
130
65
|
# @return [String]
|
131
|
-
def self.
|
132
|
-
language_codes
|
133
|
-
.take(4) # arbitrary limit to avoid long lines
|
134
|
-
.map do |lang|
|
135
|
-
ISO_639.find(lang).english_name
|
136
|
-
end
|
137
|
-
.join(" / ")
|
138
|
-
end
|
139
|
-
|
140
|
-
# @param countries [Array<ISO3166::Country|Hash>]
|
141
|
-
# @param title [String]
|
142
|
-
# @return [String]
|
143
|
-
def self.countries(countries, title:)
|
66
|
+
def self.countries(country_codes, title:)
|
144
67
|
Format.brief_template(
|
145
68
|
title: title,
|
146
|
-
elements:
|
69
|
+
elements: country_codes.map do |country|
|
147
70
|
Format.one_line_country(country)
|
148
71
|
end
|
149
72
|
)
|
150
73
|
end
|
151
74
|
|
152
|
-
# @param
|
75
|
+
# @param country_code [String] ISO3166 2 letter country code
|
153
76
|
# @return [String]
|
154
|
-
def self.
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
country.alpha3,
|
162
|
-
country.iso_short_name
|
163
|
-
]
|
164
|
-
when Hash
|
165
|
-
values = country.slice(
|
166
|
-
"number",
|
167
|
-
"alpha2",
|
168
|
-
"alpha3",
|
169
|
-
"iso_short_name"
|
170
|
-
).values
|
77
|
+
def self.country(country_code)
|
78
|
+
[
|
79
|
+
Format.country_title(country_code),
|
80
|
+
Format.one_line_country(country_code),
|
81
|
+
Format.multiline_country(country_code),
|
82
|
+
].join("\n")
|
83
|
+
end
|
171
84
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
"(#{country_values.compact.join(" | ")})"
|
180
|
-
end
|
85
|
+
# @param country_code [String] ISO3166 2 letter country code
|
86
|
+
# @return [String]
|
87
|
+
def self.country_title(country_code)
|
88
|
+
Cache
|
89
|
+
.get("formatted_output/country_title.json")
|
90
|
+
.fetch(country_code)
|
91
|
+
.then(&Format.method(:title))
|
181
92
|
end
|
182
93
|
|
183
|
-
# @param
|
94
|
+
# @param country_code [String] ISO3166 2 letter country code
|
184
95
|
# @return [String]
|
185
|
-
def self.
|
186
|
-
|
187
|
-
|
96
|
+
def self.one_line_country(country_code)
|
97
|
+
Cache
|
98
|
+
.get("formatted_output/one_line_country.json")
|
99
|
+
.fetch(country_code)
|
100
|
+
end
|
188
101
|
|
189
|
-
|
102
|
+
# @param country_code [String] ISO3166 2 letter country code
|
103
|
+
# @return [String]
|
104
|
+
def self.multiline_country(country_code)
|
105
|
+
Cache
|
106
|
+
.get("formatted_output/multiline_country.json")
|
107
|
+
.fetch(country_code)
|
190
108
|
end
|
191
109
|
|
192
|
-
# @param subregions [Hash<String, Array<
|
110
|
+
# @param subregions [Hash<String, Array<String>>] region name to ISO3166 2 letter country codes
|
193
111
|
# @return [String]
|
194
112
|
def self.subregions(subregions)
|
195
|
-
subregions.
|
196
|
-
|
113
|
+
subregions = subregions.to_h do |region, countries|
|
114
|
+
[
|
115
|
+
Util::String.titleize(region),
|
116
|
+
countries.map(&Format.method(:one_line_country)),
|
117
|
+
]
|
197
118
|
end
|
198
119
|
|
199
120
|
Format.brief_template(title: "All Subregions", elements: subregions)
|
200
121
|
end
|
201
122
|
|
202
|
-
# @param currencies [Array<
|
123
|
+
# @param currencies [Hash<String, Array<String>>] 3 letter currency code to ISO3166 2 letter country codes
|
124
|
+
# @param partial_match [Boolean] defaults to false
|
203
125
|
# @return [String]
|
204
|
-
def self.currencies(currencies)
|
205
|
-
currencies = currencies.to_h do |
|
206
|
-
currency = Money::Currency.new(currency_class.currency_code)
|
207
|
-
|
126
|
+
def self.currencies(currencies, partial_match: false)
|
127
|
+
currencies = currencies.to_h do |currency, countries|
|
208
128
|
[
|
209
|
-
|
210
|
-
|
129
|
+
Format.one_line_currency(currency),
|
130
|
+
countries.map(&Format.method(:one_line_country)),
|
211
131
|
]
|
212
132
|
end
|
213
133
|
|
214
|
-
if currencies.size == 1
|
134
|
+
if !partial_match && currencies.size == 1
|
215
135
|
title, elements = currencies.first
|
216
136
|
title = "Currency: #{title}"
|
217
137
|
Format.brief_template(title: title, elements: elements)
|
218
138
|
else
|
219
|
-
|
139
|
+
title = partial_match ? "Currencies (Partial Match)" : "Currencies"
|
140
|
+
Format.brief_template(title: title, elements: currencies)
|
220
141
|
end
|
221
142
|
end
|
143
|
+
|
144
|
+
def self.one_line_currency(currency_code)
|
145
|
+
Cache
|
146
|
+
.get("formatted_output/one_line_currency.json")
|
147
|
+
.fetch(currency_code)
|
148
|
+
end
|
222
149
|
end
|
223
150
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Atlasq
|
4
|
+
module PartialMatch
|
5
|
+
# @param term [String]
|
6
|
+
# @return [Array<String>] 3 digit country codes (ISO3166)
|
7
|
+
def self.countries(term)
|
8
|
+
@countries ||= Util::WordMap.new(index: Cache.get("search_index/partial_match_country.json"))
|
9
|
+
@countries.search(term)
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param term [String]
|
13
|
+
# @return [Array<String>] 3 letter currency codes (ISO4217)
|
14
|
+
def self.currencies(term)
|
15
|
+
@currencies ||= Util::WordMap.new(index: Cache.get("search_index/partial_match_currency.json"))
|
16
|
+
@currencies.search(term)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/atlasq/util/string.rb
CHANGED
@@ -1,16 +1,52 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "unaccent"
|
4
|
+
|
3
5
|
module Atlasq
|
4
6
|
module Util
|
5
7
|
module String
|
6
|
-
|
8
|
+
ABBREVIATIONS = {
|
9
|
+
"AMER" => "North, Central and South America",
|
10
|
+
"APAC" => "Asia-Pacific",
|
11
|
+
"EMEA" => "Europe, Middle East, and Africa",
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
# @param string [String]
|
7
15
|
# @return [String]
|
8
16
|
def self.titleize(string)
|
9
|
-
string
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
17
|
+
abbreviation = string.upcase
|
18
|
+
|
19
|
+
if (full_name = ABBREVIATIONS[abbreviation])
|
20
|
+
"#{full_name} (#{abbreviation})"
|
21
|
+
else
|
22
|
+
words = string.split(/[-_ \t]+/)
|
23
|
+
words.map! do |word|
|
24
|
+
if word.match?(/^(?:of|the|and)$/i)
|
25
|
+
word.downcase
|
26
|
+
else
|
27
|
+
word.capitalize
|
28
|
+
end
|
29
|
+
end
|
30
|
+
words.join(" ")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Make string lowercase and remove accents.
|
35
|
+
#
|
36
|
+
# @param string [String]
|
37
|
+
# @return [String]
|
38
|
+
def self.normalize(string)
|
39
|
+
@normalize ||= {}
|
40
|
+
@normalize[string] ||= Unaccent.unaccent(string.downcase)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Split on spaces, tabs and punctuation separators.
|
44
|
+
# Note: Some punctuation can be connectors or separators based on the language.
|
45
|
+
#
|
46
|
+
# @param sentence [String]
|
47
|
+
# @return [Array<String>]
|
48
|
+
def self.word_split(sentence)
|
49
|
+
sentence.split(/[ \t,;:()]+/).reject(&:empty?)
|
14
50
|
end
|
15
51
|
end
|
16
52
|
end
|