2019-11-10 19:04:00 +00:00
|
|
|
defmodule Frenzy.Task.CreateItem do
|
2019-11-01 02:21:17 +00:00
|
|
|
require Logger
|
|
|
|
use Task
|
|
|
|
alias Frenzy.Repo
|
|
|
|
|
|
|
|
def start_link(feed, entry) do
|
|
|
|
Task.start_link(__MODULE__, :run, [feed, entry])
|
|
|
|
end
|
|
|
|
|
|
|
|
def run(feed, entry) do
|
|
|
|
Logger.metadata(item_task_id: generate_task_id())
|
|
|
|
|
|
|
|
url = get_real_url(entry)
|
|
|
|
|
|
|
|
Logger.debug("Creating item for #{url}")
|
|
|
|
|
2020-01-13 02:51:58 +00:00
|
|
|
date =
|
|
|
|
entry.date
|
|
|
|
|> Timex.Timezone.convert(:utc)
|
|
|
|
|> case do
|
|
|
|
{:error, reason} ->
|
|
|
|
Logger.debug("Couldn't convert date '#{entry.date}' to UTC: #{reason}")
|
2020-01-30 02:59:50 +00:00
|
|
|
Timex.now() |> DateTime.truncate(:second)
|
2020-01-13 02:51:58 +00:00
|
|
|
|
|
|
|
utc_date ->
|
|
|
|
DateTime.truncate(utc_date, :second)
|
|
|
|
end
|
|
|
|
|
2019-11-01 02:21:17 +00:00
|
|
|
item_params = %{
|
|
|
|
guid: entry.guid,
|
|
|
|
title: entry.title,
|
|
|
|
url: url,
|
2020-01-13 02:51:58 +00:00
|
|
|
date: date,
|
2019-11-01 02:21:17 +00:00
|
|
|
creator: "",
|
|
|
|
content: entry.content
|
|
|
|
}
|
|
|
|
|
2019-11-09 03:27:46 +00:00
|
|
|
feed = Repo.preload(feed, :pipeline)
|
2019-11-01 02:21:17 +00:00
|
|
|
|
|
|
|
result =
|
2019-11-09 03:27:46 +00:00
|
|
|
if feed.pipeline do
|
|
|
|
feed.pipeline.stages
|
|
|
|
|> Enum.reduce({:ok, item_params}, fn
|
|
|
|
stage, {:ok, item_params} ->
|
|
|
|
apply(String.to_existing_atom("Elixir." <> stage["module_name"]), :apply, [
|
|
|
|
stage["options"],
|
|
|
|
item_params
|
|
|
|
])
|
2019-11-01 02:21:17 +00:00
|
|
|
|
2019-11-09 03:27:46 +00:00
|
|
|
_stage, :tombstone ->
|
|
|
|
:tombstone
|
2019-11-01 02:21:17 +00:00
|
|
|
|
2019-11-09 03:27:46 +00:00
|
|
|
_stage, {:error, _error} = error ->
|
|
|
|
error
|
|
|
|
end)
|
|
|
|
else
|
|
|
|
{:ok, item_params}
|
|
|
|
end
|
2019-11-01 02:21:17 +00:00
|
|
|
|
|
|
|
case result do
|
|
|
|
{:err, error} ->
|
|
|
|
Logger.error(error)
|
|
|
|
|
|
|
|
{:ok, item_params} ->
|
|
|
|
changeset = Ecto.build_assoc(feed, :items, item_params)
|
|
|
|
|
|
|
|
case Repo.insert(changeset) do
|
|
|
|
{:ok, item} ->
|
|
|
|
item
|
|
|
|
|
|
|
|
{:error, changeset} ->
|
|
|
|
Logger.error("Error inserting item #{entry.guid}")
|
|
|
|
Logger.error(changeset)
|
|
|
|
end
|
|
|
|
|
|
|
|
:tombstone ->
|
|
|
|
changeset =
|
|
|
|
Ecto.build_assoc(feed, :items, %{
|
|
|
|
guid: item_params.guid,
|
|
|
|
tombstone: true
|
|
|
|
})
|
|
|
|
|
|
|
|
case Repo.insert(changeset) do
|
|
|
|
{:ok, item} ->
|
|
|
|
item
|
|
|
|
|
|
|
|
{:error, changeset} ->
|
|
|
|
Logger.error("Error inserting tombstone for #{entry.guid}")
|
|
|
|
Logger.error(changeset)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defp get_real_url(entry) do
|
|
|
|
links = Enum.reject(entry.links, fn {_, rel} -> rel == "shorturl" end)
|
|
|
|
|
|
|
|
case Enum.find(links, fn {_, rel} -> rel == "related" end) do
|
|
|
|
nil ->
|
|
|
|
case Enum.find(links, fn {_, rel} -> rel == "alternate" end) do
|
|
|
|
nil ->
|
|
|
|
[{href, _} | _] = links
|
|
|
|
href
|
|
|
|
|
|
|
|
{href, _} ->
|
|
|
|
href
|
|
|
|
end
|
|
|
|
|
|
|
|
{href, _} ->
|
|
|
|
href
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# from https://github.com/elixir-plug/plug/blob/v1.8.3/lib/plug/request_id.ex#L60
|
|
|
|
defp generate_task_id() do
|
|
|
|
binary = <<
|
|
|
|
System.system_time(:nanosecond)::64,
|
|
|
|
:erlang.phash2({node(), self()}, 16_777_216)::24,
|
|
|
|
:erlang.unique_integer()::32
|
|
|
|
>>
|
|
|
|
|
|
|
|
Base.url_encode64(binary)
|
|
|
|
end
|
|
|
|
end
|