Current section
Files
Jump to
Current section
Files
lib/api/utils.ex
defmodule UrbitEx.Utils do
@moduledoc """
Utils module with some useful functions, such as a tokenizer for graph store, regex for urls and @ps, etc.
"""
def random_hex(num) do
:crypto.strong_rand_bytes(num) |> Base.encode16(case: :lower)
end
# TODO need romanization here
def group_name(string) do
string |> String.downcase() |> String.replace(" ", "-")
end
def channel_name(string) do
name = string |> String.downcase() |> String.replace(" ", "-")
"#{name}-#{Enum.random(1_000..9_999)}"
end
def calculate_index(unix_time) do
da_unix_epoch = 170_141_184_475_152_167_957_503_069_145_530_368_000
da_second = 18_446_744_073_709_551_616
time_since_epoch = (unix_time * da_second / 1000) |> round
da_unix_epoch + time_since_epoch
end
def tokenize(string) do
urls = tokenize_item(string, :url)
mentions = tokenize_item(string, :mention)
non_text = [urls, mentions] |> List.flatten()
text = extract_text(string)
[text, non_text]
|> List.flatten()
|> Enum.sort_by(fn {_token, index} -> index end)
|> Enum.map(fn {token, _ind} -> token end)
end
def tokenize_item(string, type) do
list = extract_token(string, type)
indexes = Regex.scan(regexes()[type], string, return: :index) |> List.flatten()
list
|> Enum.with_index()
|> Enum.map(fn {item, index} -> {item, indexes |> Enum.at(index) |> elem(0)} end)
|> Enum.map(fn {item, ind} -> {%{type => item}, ind} end)
end
def extract_text(string) do
t =
string
|> String.split(regexes().url)
|> Enum.map(&String.split(&1, regexes().mention))
|> List.flatten()
indexes =
t
|> Enum.map(fn x -> Regex.scan(Regex.compile!(x), string, return: :index) end)
|> List.flatten()
|> Enum.map(fn {ind, _length} -> ind end)
t
|> Enum.with_index()
|> Enum.map(fn {item, ind} -> {item, Enum.at(indexes, ind)} end)
|> Enum.map(fn {item, ind} -> {%{text: item}, ind} end)
end
def extract_token(string, type) do
Regex.scan(regexes()[type], string) |> List.flatten()
end
def add_tilde(ship) do
case Regex.match?(~r(^~), ship) do
true -> ship
false -> "~#{ship}"
end
end
def remove_tilde(patp), do: patp |> String.replace(~r([~^]), "")
def abbreviate_patp(patp) do
cond do
String.length(patp) < 16 ->
patp
String.length(patp) < 30 ->
p = syllabize(patp)
"~#{Enum.at(p, 0)}#{Enum.at(p, 1)}^#{Enum.at(p, -2)}#{Enum.at(p, -1)}"
String.length(patp) == 57 ->
p = syllabize(patp)
"~#{Enum.at(p, 0)}#{Enum.at(p, 1)}_#{Enum.at(p, -2)}#{Enum.at(p, -1)}"
true ->
:error
end
end
def check_patp(shipname) do
syllables = syllabize(shipname)
if syllables do
case length(syllables) do
1 -> syllable_list().s |> Enum.member?(Enum.at(syllables, 0))
2 -> check_bisyllable(syllables)
4 -> check_long(syllables)
6 -> check_long(syllables)
8 -> check_long(syllables)
16 -> check_long(syllables)
_ -> false
end
else
false
end
end
def no_comets(shipname) do
syllables = syllabize(shipname)
cond do
length(syllables) > 8 -> :gtfo
true -> :ok
end
end
def check_long(syllables) do
join = syllables |> Enum.join()
pairs =
Regex.scan(~r(.{6}), join)
|> List.flatten()
|> Enum.map(fn x -> Regex.scan(~r/.{3}/, x) |> List.flatten() end)
Enum.all?(pairs, fn x -> check_bisyllable(x) end)
end
def check_bisyllable(pair) do
[pref, suf] = pair
syllable_list().p |> Enum.member?(pref) && syllable_list().s |> Enum.member?(suf)
end
def syllabize(shipname) do
clean = shipname |> String.replace(~r([~^-]), "")
case rem(String.length(clean), 3) do
0 -> Regex.scan(~r(.{3}), clean) |> List.flatten()
_ -> false
end
end
defp regexes do
%{
url: ~r/\w+:\/\/[-a-zA-Z0-9:@;?&=\/%\+\.\*!'\(\),\$_\{\}\^~\[\]`#|]+\w/,
mention: ~r/~[bcdfghjlmnprstwz][aeiouy][\w^-]+/,
code: ~r/`.+`/
}
end
def syllable_list do
%{
p: [
"bac",
"bal",
"ban",
"bar",
"bat",
"bic",
"bid",
"bil",
"bin",
"bis",
"bit",
"bol",
"bon",
"bor",
"bos",
"bot",
"dab",
"dac",
"dal",
"dan",
"dap",
"dar",
"das",
"dat",
"dav",
"dib",
"dif",
"dig",
"dil",
"din",
"dir",
"dis",
"div",
"doc",
"dol",
"don",
"dop",
"dor",
"dos",
"dot",
"dov",
"doz",
"fab",
"fad",
"fal",
"fam",
"fan",
"fas",
"fid",
"fig",
"fil",
"fin",
"fip",
"fir",
"fit",
"fod",
"fog",
"fol",
"fon",
"fop",
"for",
"fos",
"fot",
"hab",
"hac",
"had",
"hal",
"han",
"hap",
"har",
"has",
"hat",
"hav",
"hid",
"hil",
"hin",
"hob",
"hoc",
"hod",
"hol",
"hop",
"hos",
"lab",
"lac",
"lad",
"lag",
"lan",
"lap",
"lar",
"las",
"lat",
"lav",
"lib",
"lid",
"lig",
"lin",
"lis",
"lit",
"liv",
"loc",
"lod",
"lom",
"lon",
"lop",
"lor",
"los",
"mac",
"mag",
"mal",
"map",
"mar",
"mas",
"mat",
"mic",
"mid",
"mig",
"mil",
"min",
"mip",
"mir",
"mis",
"mit",
"moc",
"mod",
"mog",
"mol",
"mon",
"mop",
"mor",
"mos",
"mot",
"nac",
"nal",
"nam",
"nap",
"nar",
"nat",
"nav",
"nib",
"nid",
"nil",
"nim",
"nis",
"noc",
"nod",
"nol",
"nom",
"nop",
"nor",
"nos",
"nov",
"pac",
"pad",
"pag",
"pal",
"pan",
"par",
"pas",
"pat",
"pic",
"pid",
"pil",
"pin",
"pit",
"poc",
"pod",
"pol",
"pon",
"pos",
"rab",
"rac",
"rad",
"rag",
"ral",
"ram",
"ran",
"rap",
"rav",
"rib",
"ric",
"rid",
"rig",
"ril",
"rin",
"rip",
"ris",
"rit",
"riv",
"roc",
"rol",
"ron",
"rop",
"ros",
"rov",
"sab",
"sal",
"sam",
"san",
"sap",
"sar",
"sat",
"sav",
"sib",
"sic",
"sid",
"sig",
"sil",
"sim",
"sip",
"sit",
"siv",
"soc",
"sog",
"sol",
"som",
"son",
"sop",
"sor",
"sov",
"tab",
"tac",
"tad",
"tag",
"tal",
"tam",
"tan",
"tap",
"tar",
"tas",
"tic",
"tid",
"til",
"tim",
"tin",
"tip",
"tir",
"tob",
"toc",
"tod",
"tog",
"tol",
"tom",
"ton",
"top",
"tor",
"wac",
"wal",
"wan",
"wat",
"wic",
"wid",
"win",
"wis",
"wit",
"wol",
"wor"
],
s: [
"bec",
"bel",
"ben",
"bep",
"ber",
"bes",
"bet",
"bex",
"bud",
"bur",
"bus",
"byl",
"byn",
"byr",
"byt",
"deb",
"dec",
"def",
"deg",
"del",
"dem",
"den",
"dep",
"der",
"des",
"det",
"dev",
"dex",
"duc",
"dul",
"dun",
"dur",
"dus",
"dut",
"dux",
"dyl",
"dyn",
"dyr",
"dys",
"dyt",
"feb",
"fed",
"fel",
"fen",
"fep",
"fer",
"fes",
"fet",
"fex",
"ful",
"fun",
"fur",
"fus",
"fyl",
"fyn",
"fyr",
"heb",
"hec",
"hep",
"hes",
"het",
"hex",
"hul",
"hus",
"hut",
"leb",
"lec",
"led",
"leg",
"len",
"lep",
"ler",
"let",
"lev",
"lex",
"luc",
"lud",
"lug",
"lun",
"lup",
"lur",
"lus",
"lut",
"lux",
"lyd",
"lyn",
"lyr",
"lys",
"lyt",
"lyx",
"meb",
"mec",
"med",
"meg",
"mel",
"mep",
"mer",
"mes",
"met",
"mev",
"mex",
"mud",
"mug",
"mul",
"mun",
"mur",
"mus",
"mut",
"myl",
"myn",
"myr",
"neb",
"nec",
"ned",
"nel",
"nem",
"nep",
"ner",
"nes",
"net",
"nev",
"nex",
"nub",
"nul",
"num",
"nup",
"nus",
"nut",
"nux",
"nyd",
"nyl",
"nym",
"nyr",
"nys",
"nyt",
"nyx",
"pec",
"ped",
"peg",
"pel",
"pem",
"pen",
"per",
"pes",
"pet",
"pex",
"pub",
"pun",
"pur",
"put",
"pyl",
"pyx",
"reb",
"rec",
"red",
"ref",
"reg",
"rel",
"rem",
"ren",
"rep",
"res",
"ret",
"rev",
"rex",
"ruc",
"rud",
"rul",
"rum",
"run",
"rup",
"rus",
"rut",
"rux",
"ryc",
"ryd",
"ryg",
"ryl",
"rym",
"ryn",
"ryp",
"rys",
"ryt",
"ryx",
"seb",
"sec",
"sed",
"sef",
"seg",
"sel",
"sem",
"sen",
"sep",
"ser",
"set",
"sev",
"sub",
"sud",
"sug",
"sul",
"sum",
"sun",
"sup",
"sur",
"sut",
"syd",
"syl",
"sym",
"syn",
"syp",
"syr",
"syt",
"syx",
"teb",
"tec",
"ted",
"teg",
"tel",
"tem",
"ten",
"tep",
"ter",
"tes",
"tev",
"tex",
"tuc",
"tud",
"tug",
"tul",
"tun",
"tus",
"tux",
"tyc",
"tyd",
"tyl",
"tyn",
"typ",
"tyr",
"tyv",
"web",
"wed",
"weg",
"wel",
"wen",
"wep",
"wer",
"wes",
"wet",
"wex",
"wyc",
"wyd",
"wyl",
"wyn",
"wyt",
"wyx",
"zod"
]
}
end
end