Fix items w/o guids getting duplicated on every update

This commit is contained in:
Shadowfacts 2021-09-12 19:55:19 -04:00
parent 4d7843ee5f
commit 3b12f62379
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
2 changed files with 41 additions and 24 deletions

View File

@ -82,9 +82,20 @@ defmodule Frenzy.Item do
@doc false @doc false
def changeset(item, attrs) do def changeset(item, attrs) do
item item
|> cast(attrs, [:guid, :title, :url, :creator, :date, :content, :read, :read_date, :tombstone]) |> cast(attrs, [
|> validate_required([:guid, :url, :date, :content, :feed]) :guid,
|> unique_constraint(:items_feed_guid_index) :title,
:url,
:creator,
:date,
:content,
:read,
:read_date,
:tombstone,
:feed_id
])
|> validate_required([:guid, :url, :date, :content, :feed_id])
|> unique_constraint([:feed_id, :guid], name: :items_feed_guid_index)
end end
def exists?(feed_id, guid) do def exists?(feed_id, guid) do

View File

@ -1,7 +1,7 @@
defmodule Frenzy.Task.CreateItem do defmodule Frenzy.Task.CreateItem do
require Logger require Logger
use Task use Task
alias Frenzy.Repo alias Frenzy.{Repo, Item}
@spec start_link(Frenzy.Feed.t(), FeedParser.Item.t()) :: {:ok, pid()} @spec start_link(Frenzy.Feed.t(), FeedParser.Item.t()) :: {:ok, pid()}
def start_link(feed, entry) do def start_link(feed, entry) do
@ -29,7 +29,8 @@ defmodule Frenzy.Task.CreateItem do
end end
item_params = %{ item_params = %{
guid: entry.guid, # fallback to url if guid isn't present
guid: entry.guid || url,
title: entry.title, title: entry.title,
url: url, url: url,
date: date, date: date,
@ -61,36 +62,41 @@ defmodule Frenzy.Task.CreateItem do
{:ok, item_params} {:ok, item_params}
end end
case result do changeset =
{:error, error} -> case result do
Logger.error(error) {:error, error} ->
Logger.error(error)
:error
{:ok, item_params} -> {:ok, item_params} ->
changeset = Ecto.build_assoc(feed, :items, item_params) item_params = Map.put(item_params, :feed_id, feed.id)
Item.changeset(%Item{}, item_params)
case Repo.insert(changeset) do :tombstone ->
{:ok, item} -> Item.changeset(%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, guid: item_params.guid,
tombstone: true tombstone: true
}) })
end
case changeset do
nil ->
nil
changeset ->
case Repo.insert(changeset) do case Repo.insert(changeset) do
{:ok, item} -> {:ok, item} ->
item item
{:error, changeset} -> {:error, changeset} ->
Logger.error("Error inserting tombstone for #{entry.guid}") with [feed_id: {_, list}] <- changeset.errors,
Logger.error(changeset) true <- {:constraint_name, "items_feed_guid_index"} in list do
Logger.warn("Did not insert duplicate item for #{item_params.guid}")
else
_ ->
Logger.error("Error inserting item #{item_params.guid}")
Logger.error(changeset.errors)
end
end end
end end