defmodule Memex do
@moduledoc """
Expand your memory with the magic of Elixir.
The concept behind this project is basically throwing any resource against it
and `Memex` should be able to figure out how to handle and store this stuff in
a meaningful and queryable way.
"""
alias Memex.Repo
@doc """
Slurp stuff.
## Examples
iex> Memex.slurp("https://soundcloud.com/podcast")
%Podcast{
__meta__: #Ecto.Schema.Metadata<:loaded, "podcasts">,
...
}
"""
def slurp("https://soundcloud.com/" <> username) do
feed = Soundcloud.Feed.fetch(username: username) |> Feedraptor.parse()
podcast =
Repo.insert!(%Podcast{
title: feed.title,
summary: feed.itunes_summary,
description: feed.description,
subtitle: feed.itunes_subtitle
})
|> Repo.preload([:categories, :episodes])
podcast_changeset = Ecto.Changeset.change(podcast)
for category_name <- feed.itunes_categories do
category = get_or_create(Category, name: category_name)
podcast_category_changeset =
podcast_changeset |> Ecto.Changeset.put_assoc(:categories, [category])
Repo.update!(podcast_category_changeset)
end
Enum.map(feed.entries, fn e ->
episode =
Ecto.build_assoc(podcast, :episodes, %Episode{
title: e.title,
enclosure_url: e.enclosure_url,
subtitle: e.itunes_subtitle,
summary: e.summary,
url: e.url
})
Repo.insert!(episode)
end)
Repo.preload(Repo.get(Podcast, podcast.id), [:categories, :episodes])
end
defp get_or_create(queryable, clauses) do
result = Repo.get_by(queryable, clauses)
if result do
result
else
Map.merge(queryable.__struct__, Map.new(clauses)) |> Repo.insert!()
end
end
end