KJXDMDMJ4O4BMJL5HF2MY23OKBRZJ57JPD2BUBJXBUUQPMMBFZNAC
2QXUFAF3OJS7IMLP4K2IUUBX3X7QZEZSYRE3Z6O6UAJCSPKH4ZRAC
ZAHK7S53I3RLV7NAY7CND3N5SDQMKFWARDRJFP6JP5HMTYLJZYIQC
6YMH7UABZZQXOZWJOA4VKS63TRXJHBSZIZPYLNQYTBGXA7SRSV4AC
WFSTP2DNIG6QE5F7GEZQ6NRCO7UPDLP5L7PQPBBNYJ6TC2PXZGOQC
YYDITCHVLMT2AE3P65STHJVHNG47BE3TSW3FNSXK2XCOB3VIRJQQC
DIJO2HGF3PO7BSYOUZN2DMHU2SRR6CLQ245XKXSETZPJHF6RRKDAC
77ZDLLUTFQ3L3FELAWZQTOG5DUPINOXV5VYLEYBEONDOW2BSVZJAC
SDQM4ROF7EPX5G7Z4V37ZNWKWNC7ZHZQQ4ZVKLDZTLJSERCSC4CQC
FCCU7MKCCJF3WF3ZEJPLOERQYWX42UXS4QCVM7AXH6O4S765KJYAC
ICGDK5NMJH7PYZF3C6CAIXF6COSNX6ORYRGOPZNWJRRHWGZWMAHQC
56LYC22XXLMHGOXXDZ3V6ZVSPHXXBQ6XU75QSXJUW7PTKOMZHZ4QC
MU2YNCBOBEBDCFVQZZEMLQW6HF5AY53M62UYPIS6I2NVDPPFZKUQC
WY2RZ3DJUNJTIH3UOCQUQZLVGMEEDLEJIIYTWZFCPMJ4CJKKXXTQC
{:sentence, s} -> String.length(s) > 2
_ -> true
{:sentence, s} ->
Enum.all?(
[
&long_sentence?/1,
¬_blacklisted?/1
],
fn chk -> chk.(s) end
)
_ ->
true
end)
end
defp long_sentence?(sentence) do
String.length(sentence) > 2
end
defp not_blacklisted?("(Rim.") do
false
end
defp not_blacklisted?(_sentence) do
true
end
def is_esperanto?(word) do
check_esperanto(word)
end
defp check_esperanto(word) do
Enum.any?(
[
&is_alias?/1,
&is_table_word?/1,
&is_in_vocab?/1,
&is_conjuction?/1,
&is_pronoun?/1,
&is_preposition?/1,
&is_noun?/1,
&is_adjective?/1,
&is_adverb?/1,
&is_verb?/1
],
fn f -> f.(word) end
)
end
defp is_alias?({_, _}), do: true
defp is_alias?(_), do: false
defp is_noun?(word) do
String.ends_with?(word, ["o", "oj", "on", "ojn"])
end
defp is_adjective?(word) do
String.ends_with?(word, ["a", "aj", "an", "ajn"])
end
defp is_adverb?(word) do
String.ends_with?(word, ["e", "en"])
end
defp is_pronoun?(word) do
base = ~w(mi ni vi li ŝi ĝi ili oni si)
Enum.any?(base, fn b ->
word == b || word == b <> "a" || word == b <> "n" || word == b <> "aj" || word == b <> "an" ||
word == b <> "ajn"
end
defp is_preposition?(word) do
preps = ~w(
al
anstataŭ
antaŭ
apud
ĉe
ĉirkaŭ
da
de
ekster
el
en
ĝis
inter
je
kontraŭ
krom
malantaŭ
maltrans
po
post
preter
sub
super
sur
tra
trans
)
Enum.any?(preps, fn b -> word == b end)
end
defp is_table_word?(word) do
tws = ~w(
kio
tio
io
ĉio
nenio
kion
tion
ion
ĉion
nenion
kiu
tiu
iu
ĉiu
neniu
kiun
tiun
iun
ĉiun
neniun
kiuj
tiuj
iuj
ĉiuj
neniuj
kiujn
tiujn
iujn
ĉiujn
neniujn
kia
tia
ia
ĉia
nenia
kian
tian
ian
ĉian
nenian
kiaj
tiaj
iaj
ĉiaj
neniaj
kiajn
tiajn
iajn
ĉiajn
neniajn
kies
ties
ies
ĉies
nenies
kie
tie
ie
ĉie
nenie
kien
tien
ien
ĉien
nenien
kiam
tiam
iam
ĉiam
neniam
kial
tial
ial
ĉial
nenial
kiel
tiel
iel
ĉiel
neniel
kiom
tiom
iom
ĉiom
neniom
)
Enum.any?(tws, fn tw -> word == tw end)
end
defp is_conjuction?(word) do
Enum.any?(
~w(
kaj
aŭ
sed
plus
minus
nek
),
fn conj -> conj == word end
)
end
defp is_verb?(word) do
String.ends_with?(word, ["i", "as", "is", "os", "us", "u"])
end
defp is_in_vocab?(word) do
words = MapSet.new(~w(
ajn
almenaŭ
ankaŭ
apenaŭ
do
eĉ
ja
jen
kvazaŭ
mem
nur
pli
plej
preskaŭ
tamen
tre
tro
jes
ne
tuj
por
ĉar
morgaŭ
hieraŭ
))
MapSet.member?(words, word)
sentence
|> Esperantisto.Text.sentence_to_words()
|> Task.async_stream(
fn word ->
DB.save_word(sentence_id, word)
word
end,
timeout: 30000,
max_concurrency: 10
)
|> Stream.map(fn {:ok, v} -> v end)
|> Stream.scan(
{nil, nil},
fn word, {_, prev} -> {prev, word} end
)
|> Task.async_stream(
fn {prev, word} ->
DB.save_word_order(prev, word)
end,
timeout: 30000,
max_concurrency: 10
)
|> Stream.run()
check =
words
|> Enum.reduce({[], []}, fn word, {esp, not_esp} ->
case Esperantisto.Text.is_esperanto?(word) do
true ->
{[word | esp], not_esp}
false ->
{esp, [word | not_esp]}
end
end)
acc
case check do
{[], []} ->
Logger.debug("Empty sentence: #{inspect(sentence)}")
acc
{esp, not_esp} ->
len_esp = length(esp)
len_not_esp = length(not_esp)
total = len_esp + len_not_esp
percentage = len_esp * 100 / total
if percentage >= @desired_percentage do
sentence_id = DB.save_sentence(acc.book_id, sentence)
words
|> Task.async_stream(
fn word ->
DB.save_word(sentence_id, word)
word
end,
timeout: 30000,
max_concurrency: 10
)
|> Stream.map(fn {:ok, v} -> v end)
|> Stream.scan(
{nil, nil},
fn word, {_, prev} -> {prev, word} end
)
|> Task.async_stream(
fn {prev, word} ->
DB.save_word_order(prev, word)
end,
timeout: 30000,
max_concurrency: 10
)
|> Stream.run()
acc
else
Logger.warn(
"Too many non esperanto words: #{len_not_esp}/#{total} (#{inspect(not_esp)}) in sentence #{sentence}"
)
acc
end
end