From 2880fd0c2809e4bd260348fe4e153c6f98e0abbb Mon Sep 17 00:00:00 2001 From: Dirk Schumann Date: Sun, 29 Dec 2024 15:12:45 +0100 Subject: [PATCH] fix(server) - add publish date (#58) implements #57 --- client/src/sagas/import.saga.ts | 1 + client/src/types/episode.types.ts | 1 + server/lib/publisher/feed_parser.ex | 3 +- server/lib/publisher/wordpress/episode.ex | 51 +++++++++++++++++-- .../controllers/validator/save_chapters.ex | 2 +- .../controllers/validator/save_episode.ex | 34 ++++++++++++- server/mix.exs | 3 +- 7 files changed, 88 insertions(+), 7 deletions(-) diff --git a/client/src/sagas/import.saga.ts b/client/src/sagas/import.saga.ts index ec01c3d..af90527 100644 --- a/client/src/sagas/import.saga.ts +++ b/client/src/sagas/import.saga.ts @@ -176,6 +176,7 @@ function* fetchEpisodeDetails({ payload }: Action) { explicit: get(episode, 'explicit', null), duration: get(episode, 'duration', null), cover: get(episode, 'cover', null), + pub_date: get(episode, 'pub_date', null), transcript: { language: get(episode, ['transcript', 'language'], null), rel: get(episode, ['transcript', 'rel'], null), diff --git a/client/src/types/episode.types.ts b/client/src/types/episode.types.ts index 5ff3b29..8e5845d 100644 --- a/client/src/types/episode.types.ts +++ b/client/src/types/episode.types.ts @@ -46,6 +46,7 @@ export interface EpisodeDetailsPayload { explicit: boolean; duration: string; cover: string; + pub_date: string; transcript: { language: string; rel: string; diff --git a/server/lib/publisher/feed_parser.ex b/server/lib/publisher/feed_parser.ex index 13f40b0..44e8219 100644 --- a/server/lib/publisher/feed_parser.ex +++ b/server/lib/publisher/feed_parser.ex @@ -86,7 +86,8 @@ defmodule Publisher.FeedParser do cover: episode.image_url, chapters: episode.chapters, transcript: transcript(episode), - contributors: episode.contributors + contributors: episode.contributors, + pub_date: episode.pub_date } }} end diff --git a/server/lib/publisher/wordpress/episode.ex b/server/lib/publisher/wordpress/episode.ex index d4ebb15..9b00fd1 100644 --- a/server/lib/publisher/wordpress/episode.ex +++ b/server/lib/publisher/wordpress/episode.ex @@ -100,12 +100,57 @@ defmodule Publisher.WordPress.Episode do Enum.reject(map, fn {_, v} -> is_nil(v) end) end - defp upload_content(req, post_id, %{"content" => content} = _params) - when not is_nil(content) do + defp wordpress_date(date) do + date + |> parse_date() + |> DateTime.to_iso8601() + end + + defp parse_date(date) do + formats = [ + "{RFC822}", + "{RFC822z}", + "{RFC1123}", + "{RFC1123z}", + "{RFC3339}", + "{RFC3339z}", + "{ISO:Extended}", + "{ISO:Extended:Z}" + ] + + Enum.find_value(formats, fn format -> + case Timex.parse(date, format) do + {:ok, date} -> date + {:error, _} -> false + end + end) + end + + defp upload_content(req, post_id, %{"content" => content, "pub_date" => pub_date} = _params) + when not is_nil(content) and not is_nil(pub_date) do Logger.info("Episode post #{post_id} content is #{String.length(content)}") + Logger.info("Episode post #{post_id} release date is #{pub_date}") + + payload = %{ + content: content, + date: wordpress_date(pub_date) + } + + Req.post(req, + url: "wp/v2/episodes/#{post_id}", + json: payload + ) + + :ok + end + + defp upload_content(req, post_id, %{"content" => content, "pub_date" => pub_date} = _params) + when is_nil(content) and not is_nil(pub_date) do + Logger.info("Episode post has no post content") + Logger.info("Episode post #{post_id} release date is #{pub_date}") payload = %{ - content: content + date: wordpress_date(pub_date) } Req.post(req, diff --git a/server/lib/publisher_web/controllers/validator/save_chapters.ex b/server/lib/publisher_web/controllers/validator/save_chapters.ex index 7c3fe91..5a3104a 100644 --- a/server/lib/publisher_web/controllers/validator/save_chapters.ex +++ b/server/lib/publisher_web/controllers/validator/save_chapters.ex @@ -20,7 +20,7 @@ defmodule PublisherWeb.Controllers.Validator.SaveChapters do if normalplaytime_valid?(value) do [] else - [{field, "is not conform with NormalPlayTime"}] + [{field, " is not conform with NormalPlayTime"}] end end) end diff --git a/server/lib/publisher_web/controllers/validator/save_episode.ex b/server/lib/publisher_web/controllers/validator/save_episode.ex index 4eadadb..76b9fd8 100644 --- a/server/lib/publisher_web/controllers/validator/save_episode.ex +++ b/server/lib/publisher_web/controllers/validator/save_episode.ex @@ -9,14 +9,46 @@ defmodule PublisherWeb.Controllers.Validator.SaveEpisode do field(:slug, :string) field(:content, :string) field(:cover, :string) + field(:pub_date, :string) end - @allowed_attrs [:guid, :title, :subtitle, :summary, :slug, :content, :cover] + @allowed_attrs [:guid, :title, :subtitle, :summary, :slug, :content, :cover, :pub_date] @required_attrs [:guid, :title, :slug] def changeset(attrs) do %__MODULE__{} |> cast(attrs, @allowed_attrs) |> validate_required(@required_attrs) + |> validate_date(:pub_date) + end + + defp validate_date(changeset, field) do + validate_change(changeset, field, fn _, value -> + if publication_date_valid?(value) do + [] + else + [{field, " is not a conformed date"}] + end + end) + end + + defp publication_date_valid?(field) do + formats = [ + "{RFC822}", + "{RFC822z}", + "{RFC1123}", + "{RFC1123z}", + "{RFC3339}", + "{RFC3339z}", + "{ISO:Extended}", + "{ISO:Extended:Z}" + ] + + Enum.find_value(formats, fn format -> + case Timex.parse(field, format) do + {:ok, field} -> field + {:error, _} -> false + end + end) end end diff --git a/server/mix.exs b/server/mix.exs index 158adf0..33f9b27 100644 --- a/server/mix.exs +++ b/server/mix.exs @@ -29,7 +29,8 @@ defmodule Publisher.MixProject do {:slugify, "~> 1.3"}, {:nimble_options, "~> 1.1"}, {:metalove, git: "https://github.com/podlove/metalove", branch: "master"}, - {:honeybadger, "~> 0.22"} + {:honeybadger, "~> 0.22"}, + {:timex, "~> 3.7"} ] end end