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 Last.fm 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), &iso8601_to_unix("#{&1}T00:00:00Z", "#{&1}T23:59:59Z"))
end
def build_time_range(year, %Lastfm.Archive{} = archive) when is_integer(year) do
{from, to} = iso8601_to_unix("#{year}-01-01T00:00:00Z", "#{year}-12-31T23:59:59Z")
{registered_time, last_scrobble_time} = archive.temporal
from = if from <= registered_time, do: registered_time, else: from
to = if to >= last_scrobble_time, do: last_scrobble_time, else: to
{from, to}
end
defp iso8601_to_unix(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
def display_api_error_message({from, _to}, reason) do
from_date = DateTime.from_unix!(from) |> DateTime.to_date()
IO.puts("\n")
IO.puts("Last.fm API error while syncing #{from_date}: #{reason}")
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