Current section
Files
Jump to
Current section
Files
lib/search_cli.ex
defmodule Superls.SearchCLI do
@moduledoc false
alias Superls.{
MatchJaro,
MatchSize,
MatchDate,
MatchTag,
Prompt,
Tag,
Store,
MergedIndex,
StrFmt
}
@num_files_search_oldness Application.compile_env!(:superls, :num_files_search_oldness)
@num_days_search_bydate Application.compile_env!(:superls, :num_days_search_bydate)
@spec command_line(MergedIndex.t(), Keyword.t()) :: no_return()
def command_line(mi, opts) do
IO.write("""
Enter a string to search a tag in store '#{Keyword.fetch!(opts, :store)}' (#{MergedIndex.get_num_tags(mi)} tags) or use the commands:
q]uit, dt]upl_tags, ds]upl_size, xo|xn|ro|rn]date_old, xd|rd]bydate, s]ort_tags, m]etrics.
""")
cmd = IO.gets("-? ") |> String.trim_trailing()
_ = command(mi, cmd, opts)
command_line(mi, opts)
end
defp command(_merged_index, "", _opts),
do: :ok
defp command(_merged_index, "q", _opts) do
IO.puts("CLI exits.")
exit(:normal)
end
# metrics command
defp command(mi, "m", opts) do
max_freq_tags = 500
store = Keyword.fetch!(opts, :store)
passwd = Keyword.fetch!(opts, :passwd)
info = MergedIndex.metrics(mi, max_freq_tags)
IO.puts(String.pad_trailing("Volumes", 50) <> " " <> String.pad_trailing("Digest", 50))
Store.volume_path_from_digests(store, passwd)
|> Enum.map(fn {vol, digest} ->
[
{vol, :str, [:bright]},
" ",
{digest, :scr, []},
"\n"
]
end)
|> StrFmt.to_string()
|> IO.puts()
IO.puts("""
Details for the `#{store}` store :
- Top #{max_freq_tags} frequent tags:\n#{info.most_frequent}
- Tags: #{info.num_tags}
- Files: #{info.num_files}
""")
if !Superls.Prompt.valid_default_no?("dump files names") do
File.write!("/tmp/dump_superls", "")
MergedIndex.files_index_from_tags(mi)
|> Enum.each(fn {vol, files} ->
File.write!("/tmp/dump_superls", "* Volume: #{vol}:\n", [:append])
dump_files(files)
end)
IO.puts("files names stored in /tmp/dump_superls")
end
end
defp command(mi, cmd, _opts) when cmd in ~w(xd rd) do
today = Date.utc_today()
date =
Prompt.valid_default_or_new_input(
"Enter a date like #{Date.to_string(today)}: ",
today,
&Date.from_iso8601!/1
)
ndays =
Prompt.valid_default_or_new_input(
"Confirm #{@num_days_search_bydate} days around the date (Y/new_value) ? ",
@num_days_search_bydate,
&Superls.string_to_numeric/1
)
result = MergedIndex.search_bydate(mi, cmd, date, ndays)
[MatchDate.to_string(result, cmd), "[CLI found #{MatchDate.size(result)} result(s)]"]
|> IO.puts()
end
defp command(mi, cmd, _opts) when cmd in ~w(xo xn ro rn) do
nentries =
Prompt.valid_default_or_new_input(
"Confirm display first #{@num_files_search_oldness} entries (Y/new_value) ? ",
@num_files_search_oldness,
&Superls.string_to_numeric/1
)
result = MergedIndex.search_oldness(mi, cmd, nentries)
[MatchDate.to_string(result, cmd), "[CLI found #{MatchDate.size(result)} result(s)]"]
|> IO.puts()
end
defp command(mi, "ds", _opts) do
IO.write("group files with similar size, this may take a while ...\r")
result =
MergedIndex.search_similar_size(mi)
[MatchSize.to_string(result), "[CLI found #{MatchSize.size(result)} result(s)]"] |> IO.puts()
end
defp command(mi, "dt", _opts) do
IO.write("group files with similar tags, this may take a while ...\r")
result = MergedIndex.search_duplicated_tags(mi)
[MatchJaro.to_string(result), "[CLI found #{MatchJaro.size(result)} result(s)]"] |> IO.puts()
end
# @limit_top_tags 500
defp command(mi, "s", _opts) do
tag_freqs = MergedIndex.tag_freq(mi)
tags_by_occur =
Enum.reduce(tag_freqs, %{}, fn {tag, count}, acc ->
Map.get_and_update(acc, count, fn
nil ->
{nil, [tag]}
tags ->
{tags, [tag | tags]}
end)
|> elem(1)
end)
|> Map.delete(1)
|> Enum.to_list()
|> Enum.sort_by(fn {count, _} -> count end, &>/2)
count = map_size(tag_freqs)
[
{"Number of tags: #{count}", :str, []},
"\n",
{"Occur. Tags", :str, []},
"\n",
for {count, tags} <- tags_by_occur do
[
{count, :str, [:light_magenta, :reverse]},
" ",
for tag <- tags do
[{tag, :str, [:bright]}, " "]
end,
"\n"
]
end
]
|> StrFmt.to_string()
|> IO.puts()
end
defp command(mi, user_input, _opts) when byte_size(user_input) > 1 do
{result, user_tags} = Tag.search_matching_tags(mi, user_input)
user_tags =
user_tags |> Enum.map(&{&1, :str, [:bright]}) |> Enum.intersperse(" * ") |> StrFmt.puts()
IO.puts([
MatchTag.to_string(result),
"[CLI found #{MatchTag.size(result)} result(s) for #{user_tags}]"
])
end
defp command(_merged_index, user_input, _opts) do
IO.puts("Unrecognized command: \"#{user_input}\"")
end
defp dump_files(files) do
for {fp, finfo} <- files,
do:
File.write!(
"/tmp/dump_superls",
StrFmt.to_string([{finfo.size, :sizeb, []}, " ", {fp, :str, []}, "\n"]),
[:append]
)
end
end