Current section

Files

Jump to
superls lib match_date.ex
Raw

lib/match_date.ex

defmodule Superls.MatchDate do
@day_seconds 3600 * 24
@moduledoc false
# list oldest / newest files according to mtime / atime
@doc ~S"""
returns files between date from a list of files according to cmd:
- `xd`: created / modified date
- `rd`: accessed date
"""
def search_bydate(files, cmd, date, ndays) when cmd in ~w(xd rd) do
{_sorter, field} = sorter_field(cmd)
# mtime : 1696153262 ~U[2023-10-01 09:41:02Z]
date_unix = Date.diff(date, ~D[1970-01-01]) * @day_seconds
date_min = date_unix - ndays * @day_seconds
date_max = date_unix + ndays * @day_seconds
IO.puts(
"search result files between #{from_unix!(date_min)} and #{from_unix!(date_max)} (#{ndays} days): "
)
Enum.reduce(files, [], fn e = {{f, _}, _}, acc ->
if field.(f) >= date_min and f.mtime <= date_max do
[e | acc]
else
acc
end
end)
|> output_friendly(field)
end
@doc ~S"""
returns the oldest or newest files from a list of files according to:
- `xo`: created / modified oldest
- `xn`: created / modified newest
- `ro`: accessed oldest
- `rn`: accessed newest
the default number of returned files is set by the config parameter `:num_files`
"""
def search_oldness(files, cmd, nentries) do
{sorter, field} = sorter_field(cmd)
IO.puts("search newest/oldest (#{cmd}) files, max: (#{nentries} files): ")
Enum.sort(files, sorter)
|> Enum.take(nentries)
|> output_friendly(field)
end
@doc false
def output_friendly(result, field) do
for {{f, path}, _} <- result do
(IO.ANSI.bright() <>
Path.basename(f.name) <>
IO.ANSI.reset() <>
"\t" <>
Superls.pp_sz(f.size) <>
"\t" <>
datetime_human_str(field.(f)) <>
"\t" <>
path <>
"/" <>
Path.dirname(f.name) <>
IO.ANSI.reset())
|> IO.puts()
end
end
defp sorter_field(cmd) do
case cmd do
"xo" -> {fn {{a, _}, _}, {{b, _}, _} -> a.mtime < b.mtime end, & &1.mtime}
"xn" -> {fn {{a, _}, _}, {{b, _}, _} -> a.mtime >= b.mtime end, & &1.mtime}
"ro" -> {fn {{a, _}, _}, {{b, _}, _} -> a.atime < b.atime end, & &1.atime}
"rn" -> {fn {{a, _}, _}, {{b, _}, _} -> a.atime >= b.atime end, & &1.atime}
"xd" -> {nil, & &1.mtime}
"rd" -> {nil, & &1.atime}
end
end
defp from_unix!(posix) do
DateTime.from_unix!(posix)
|> DateTime.to_date()
|> Date.to_string()
end
# defp date_human_str(posix_time),
# do: posix_time |> DateTime.from_unix!() |> DateTime.to_date() |> Date.to_string()
defp datetime_human_str(posix_time),
do: posix_time |> DateTime.from_unix!() |> DateTime.to_string()
end