Current section

Files

Jump to
lastfm_archive lib utils.ex
Raw

lib/utils.ex

defmodule LastfmArchive.Utils do
@moduledoc false
@data_dir Application.get_env(:lastfm_archive, :data_dir, "./archive_data/")
@metadata_file ".archive"
@file_io Application.get_env(:lastfm_archive, :file_io)
@doc """
Generate {from, to} daily time ranges for querying LastFM API based on
the first and last scrobble unix timestamps.
"""
def build_time_range({from, to}) do
from = DateTime.from_unix!(from) |> DateTime.to_date()
to = DateTime.from_unix!(to) |> DateTime.to_date()
Enum.map(Date.range(from, to), &build_time_range("#{&1}T00:00:00Z", "#{&1}T23:59:59Z"))
end
def build_time_range(year) when is_integer(year) do
build_time_range("#{year}-01-01T00:00:00Z", "#{year}-12-31T23:59:59Z")
end
defp build_time_range(from, to) do
{:ok, from, _} = DateTime.from_iso8601(from)
{:ok, to, _} = DateTime.from_iso8601(to)
{DateTime.to_unix(from), DateTime.to_unix(to)}
end
def year_range({from, to}) do
DateTime.from_unix!(from).year..DateTime.from_unix!(to).year
end
def data_dir(options \\ []), do: Keyword.get(options, :data_dir, @data_dir)
def user_dir(user, options \\ []), do: Path.join([data_dir(options), user])
def metadata(user, options), do: Path.join([data_dir(options), user, @metadata_file])
def display_progress(archive) do
IO.puts("Archiving #{archive.extent} scrobbles for #{archive.creator}")
end
def display_progress({from, _to}, playcount, pages) do
from_date = DateTime.from_unix!(from) |> DateTime.to_date()
IO.puts("\n")
IO.puts("#{from_date}")
IO.puts("#{playcount} scrobble(s)")
IO.puts("#{pages} page(s)")
end
def display_skip_message({from, _to}, playcount) do
from_date = DateTime.from_unix!(from) |> DateTime.to_date()
IO.puts("\n")
IO.puts("Skipping #{from_date}, previously synced: #{playcount} scrobble(s)")
end
@doc """
Read and unzip a file from the archive of a Lastfm user.
### Example
```
LastfmArchive.Load.read "a_lastfm_user", "tsv/2007.tsv.gz"
```
"""
def read(user, filename) do
file_path = Path.join(user_dir(user, []), filename)
case @file_io.read(file_path) do
{:ok, gzip_data} ->
{:ok, gzip_data |> :zlib.gunzip()}
error ->
error
end
end
def create_tsv_dir(user) do
dir = Path.join(user_dir(user, []), "tsv")
unless @file_io.exists?(dir), do: @file_io.mkdir_p(dir)
:ok
end
end