atlasq 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- 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/country.rb +6 -3
- 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 +48 -60
- data/lib/atlasq/format.rb +14 -39
- data/lib/atlasq/partial_match.rb +19 -0
- data/lib/atlasq/util/string.rb +41 -6
- data/lib/atlasq/util/word_map.rb +46 -0
- data/lib/atlasq/util.rb +1 -0
- data/lib/atlasq/version.rb +1 -1
- data/lib/atlasq.rb +2 -0
- metadata +11 -18
- 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, term)
|
12
|
+
elsif (countries = Data.countries_by_region(term))
|
13
|
+
region_name = Util::String.titleize(term)
|
14
|
+
Format.countries(countries, 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}"
|
@@ -12,10 +12,13 @@ module Atlasq
|
|
12
12
|
Format.countries(countries, title: "All Countries")
|
13
13
|
else
|
14
14
|
search_terms.map do |term|
|
15
|
-
country = Data.country(term)
|
16
|
-
|
17
|
-
if country
|
15
|
+
if (country = Data.country(term))
|
18
16
|
Format.country(country, term)
|
17
|
+
elsif (country_codes = PartialMatch.countries(term)).any?
|
18
|
+
countries = country_codes.map do |code|
|
19
|
+
Data.country_by_code(code)
|
20
|
+
end
|
21
|
+
Format.countries(countries, title: "Countries (Partial Match)")
|
19
22
|
else
|
20
23
|
Atlasq.failed!
|
21
24
|
"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 (countries = Data.countries_by_region(term))
|
15
|
+
region_name = Util::String.titleize(term)
|
16
|
+
Format.countries(countries, 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
@@ -3,48 +3,28 @@
|
|
3
3
|
require "countries"
|
4
4
|
require "iso-639"
|
5
5
|
require "money"
|
6
|
-
require "money-heuristics"
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
7
|
+
# Needed to allow us to access the `ISO3166::Country#currency`
|
8
|
+
# object which ends up being an instance of `Money::Currency`.
|
9
|
+
ISO3166.configure(&:enable_currency_extension!)
|
27
10
|
|
28
11
|
module Atlasq
|
29
12
|
module Data
|
30
13
|
autoload :Currency, "atlasq/data/currency"
|
31
|
-
autoload :Region, "atlasq/data/region"
|
32
14
|
|
33
15
|
# @param term [String]
|
34
|
-
# @return [ISO3166::Country,
|
35
|
-
def self.
|
36
|
-
|
37
|
-
|
38
|
-
|
16
|
+
# @return [ISO3166::Country, nil]
|
17
|
+
def self.country(term)
|
18
|
+
Cache
|
19
|
+
.get("search_index/direct_match_country.json")
|
20
|
+
.dig(Util::String.normalize(term))
|
21
|
+
&.then { |key| ISO3166::Country.new(key) }
|
39
22
|
end
|
40
23
|
|
41
|
-
# @param
|
42
|
-
# @return [ISO3166::Country
|
43
|
-
def self.
|
44
|
-
ISO3166::Country.find_country_by_alpha2(
|
45
|
-
ISO3166::Country.find_country_by_alpha3(term) ||
|
46
|
-
ISO3166::Country.find_country_by_number(term) ||
|
47
|
-
ISO3166::Country.find_country_by_any_name(term)
|
24
|
+
# @param code [String] alpha2 country code
|
25
|
+
# @return [ISO3166::Country, nil]
|
26
|
+
def self.country_by_code(code)
|
27
|
+
ISO3166::Country.find_country_by_alpha2(code)
|
48
28
|
end
|
49
29
|
|
50
30
|
# @return [Array<ISO3166::Country>]
|
@@ -52,18 +32,13 @@ module Atlasq
|
|
52
32
|
@all_countries ||= ISO3166::Country.all
|
53
33
|
end
|
54
34
|
|
55
|
-
#
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
next if countries.empty?
|
63
|
-
|
64
|
-
return Region.new(countries: countries.values, type: region_type)
|
65
|
-
end
|
66
|
-
nil
|
35
|
+
# @param term [String]
|
36
|
+
# @return [Array<ISO3166::Country>, nil]
|
37
|
+
def self.countries_by_region(term)
|
38
|
+
Cache
|
39
|
+
.get("search_index/countries_by_region.json")
|
40
|
+
.dig(Util::String.normalize(term))
|
41
|
+
&.map { |key| ISO3166::Country.new(key) }
|
67
42
|
end
|
68
43
|
|
69
44
|
# @return [Hash<String, Array<ISO3166::Country>>] Ex. { "Central Asia" => [...], ... }
|
@@ -79,24 +54,37 @@ module Atlasq
|
|
79
54
|
end
|
80
55
|
end
|
81
56
|
|
82
|
-
# @param
|
83
|
-
# @return [Array<
|
84
|
-
def self.
|
85
|
-
|
86
|
-
currency_codes
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
57
|
+
# @param terms [String, Array<String>]
|
58
|
+
# @return [Hash<Money::Currency, Array<ISO3166::Country>>]
|
59
|
+
def self.countries_by_currencies(terms)
|
60
|
+
terms = Array(terms).map(&Util::String.method(:normalize))
|
61
|
+
currency_codes = Cache
|
62
|
+
.get("search_index/direct_match_currency.json")
|
63
|
+
.values_at(*terms)
|
64
|
+
.compact
|
65
|
+
|
66
|
+
return if currency_codes.empty?
|
67
|
+
|
68
|
+
Cache
|
69
|
+
.get("search_index/countries_by_currency.json")
|
70
|
+
.slice(*currency_codes)
|
71
|
+
.to_h do |currency_code, country_codes|
|
72
|
+
[
|
73
|
+
Money::Currency.new(currency_code),
|
74
|
+
country_codes.map(&Data.method(:country_by_code)),
|
75
|
+
]
|
76
|
+
end
|
92
77
|
end
|
93
78
|
|
94
|
-
# @return [Array<
|
79
|
+
# @return [Hash<Money::Currency, Array<ISO3166::Country>>]
|
95
80
|
def self.all_currencies
|
96
|
-
|
97
|
-
.
|
98
|
-
.
|
99
|
-
|
81
|
+
Cache
|
82
|
+
.get("search_index/countries_by_currency.json")
|
83
|
+
.to_h do |currency_code, country_codes|
|
84
|
+
[
|
85
|
+
Money::Currency.new(currency_code),
|
86
|
+
country_codes.map(&Data.method(:country_by_code)),
|
87
|
+
]
|
100
88
|
end
|
101
89
|
end
|
102
90
|
|
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,7 +56,7 @@ module Atlasq
|
|
56
56
|
|
57
57
|
[
|
58
58
|
Format.title(title),
|
59
|
-
*elements
|
59
|
+
*elements,
|
60
60
|
].join("\n")
|
61
61
|
end
|
62
62
|
|
@@ -83,26 +83,10 @@ module Atlasq
|
|
83
83
|
[
|
84
84
|
Format.title(title),
|
85
85
|
attributes,
|
86
|
-
*info_ladder
|
86
|
+
*info_ladder,
|
87
87
|
].join("\n")
|
88
88
|
end
|
89
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
90
|
# @param country [ISO3166::Country]
|
107
91
|
# @param search_term [String]
|
108
92
|
# @return [String]
|
@@ -116,7 +100,7 @@ module Atlasq
|
|
116
100
|
"Nationality" => country.nationality,
|
117
101
|
"Region" => country.subregion,
|
118
102
|
"Continent" => country.continent,
|
119
|
-
"Currency" => "#{country.currency.symbol} #{country.currency.name}"
|
103
|
+
"Currency" => "#{country.currency.symbol} #{country.currency.name}",
|
120
104
|
}.reject do |_, value|
|
121
105
|
# "countries" like Antarctica can have missing language, nationality,
|
122
106
|
# and region data so we remove that missing data beforehand.
|
@@ -159,7 +143,7 @@ module Atlasq
|
|
159
143
|
country.number,
|
160
144
|
country.alpha2,
|
161
145
|
country.alpha3,
|
162
|
-
country.iso_short_name
|
146
|
+
country.iso_short_name,
|
163
147
|
]
|
164
148
|
when Hash
|
165
149
|
values = country.slice(
|
@@ -171,7 +155,7 @@ module Atlasq
|
|
171
155
|
|
172
156
|
[
|
173
157
|
Data.emoji_flag(country.fetch("number")),
|
174
|
-
*values
|
158
|
+
*values,
|
175
159
|
]
|
176
160
|
else
|
177
161
|
raise Error, "Unknown country type: #{country.class}"
|
@@ -180,15 +164,6 @@ module Atlasq
|
|
180
164
|
end
|
181
165
|
end
|
182
166
|
|
183
|
-
# @param region [Atlasq::Data::Region]
|
184
|
-
# @return [String]
|
185
|
-
def self.region(region)
|
186
|
-
type = Util::String.titleize(region.type)
|
187
|
-
title = "#{type}: #{region.name}"
|
188
|
-
|
189
|
-
Format.countries(region.countries, title: title)
|
190
|
-
end
|
191
|
-
|
192
167
|
# @param subregions [Hash<String, Array<ISO3166::Country>>]
|
193
168
|
# @return [String]
|
194
169
|
def self.subregions(subregions)
|
@@ -199,24 +174,24 @@ module Atlasq
|
|
199
174
|
Format.brief_template(title: "All Subregions", elements: subregions)
|
200
175
|
end
|
201
176
|
|
202
|
-
# @param currencies [Array<
|
177
|
+
# @param currencies [Hash<Money::Currency, Array<ISO3166::Country>>]
|
178
|
+
# @param partial_match [Boolean] defaults to false
|
203
179
|
# @return [String]
|
204
|
-
def self.currencies(currencies)
|
205
|
-
currencies = currencies.to_h do |
|
206
|
-
currency = Money::Currency.new(currency_class.currency_code)
|
207
|
-
|
180
|
+
def self.currencies(currencies, partial_match: false)
|
181
|
+
currencies = currencies.to_h do |currency, countries|
|
208
182
|
[
|
209
183
|
"[#{currency.iso_code}] #{currency.symbol} #{currency.name}",
|
210
|
-
|
184
|
+
countries.map(&Format.method(:one_line_country)),
|
211
185
|
]
|
212
186
|
end
|
213
187
|
|
214
|
-
if currencies.size == 1
|
188
|
+
if !partial_match && currencies.size == 1
|
215
189
|
title, elements = currencies.first
|
216
190
|
title = "Currency: #{title}"
|
217
191
|
Format.brief_template(title: title, elements: elements)
|
218
192
|
else
|
219
|
-
|
193
|
+
title = partial_match ? "Currencies (Partial Match)" : "Currencies"
|
194
|
+
Format.brief_template(title: title, elements: currencies)
|
220
195
|
end
|
221
196
|
end
|
222
197
|
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,51 @@
|
|
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 a sentence on words ignoring irrelevant punctuation.
|
44
|
+
#
|
45
|
+
# @param sentence [String]
|
46
|
+
# @return [Array<String>]
|
47
|
+
def self.word_split(sentence)
|
48
|
+
sentence.split(/[ \t,;:()]+/).reject(&:empty?)
|
14
49
|
end
|
15
50
|
end
|
16
51
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
4
|
+
require "unaccent"
|
5
|
+
|
6
|
+
module Atlasq
|
7
|
+
module Util
|
8
|
+
# This data structure provides partial match support for words in sentences.
|
9
|
+
#
|
10
|
+
# For example, if we take a country like "Bonaire, Sint Eustatius and Saba"
|
11
|
+
# the searches "Bonaire", "Sint Eustatius" and "saba bonaire" should all match
|
12
|
+
# while the searches "bonaire france" and "saba bolivia" should not because
|
13
|
+
# they include words not found in the original sentence.
|
14
|
+
class WordMap
|
15
|
+
# @param index [Hash<String, Array<String>>]
|
16
|
+
def initialize(index:)
|
17
|
+
@index = index
|
18
|
+
end
|
19
|
+
|
20
|
+
# Search for ids that include all of the search term words.
|
21
|
+
#
|
22
|
+
# @param search_term [String]
|
23
|
+
# @return [Array<String>] list of ids
|
24
|
+
def search(search_term)
|
25
|
+
search_term
|
26
|
+
.then { |string| split(string) }
|
27
|
+
.map { |word| Util::String.normalize(word) }
|
28
|
+
.uniq
|
29
|
+
.map { |word| @index.fetch(word, []) }
|
30
|
+
.inject(&:intersection)
|
31
|
+
.sort
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# Split on spaces, tabs and punctuation separators.
|
37
|
+
# Note: Some punctuation can be connectors or separators based on the language.
|
38
|
+
#
|
39
|
+
# @param sentence [String]
|
40
|
+
# @return [Array<String>]
|
41
|
+
def split(sentence)
|
42
|
+
sentence.split(/[ \t,;:()]+/).reject(&:empty?)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/atlasq/util.rb
CHANGED
data/lib/atlasq/version.rb
CHANGED
data/lib/atlasq.rb
CHANGED
@@ -6,9 +6,11 @@ module Atlasq
|
|
6
6
|
class Error < StandardError; end
|
7
7
|
DEBUG = ENV.key?("ATLASQ_DEBUG")
|
8
8
|
|
9
|
+
autoload :Cache, "atlasq/cache"
|
9
10
|
autoload :Command, "atlasq/command"
|
10
11
|
autoload :Data, "atlasq/data"
|
11
12
|
autoload :Format, "atlasq/format"
|
13
|
+
autoload :PartialMatch, "atlasq/partial_match"
|
12
14
|
autoload :Shell, "atlasq/shell"
|
13
15
|
autoload :Util, "atlasq/util"
|
14
16
|
|