From 1413aa153a256c24fe72d881005df500d5549f44 Mon Sep 17 00:00:00 2001 From: Kieran Eglin Date: Sat, 23 Mar 2024 19:02:46 -0700 Subject: [PATCH] [WIP] got basic podcast RSS working --- lib/pinchflat/podcasts/rss_feed_builder.ex | 68 +++++++++++-------- .../controllers/sources/source_controller.ex | 14 ++++ lib/pinchflat_web/router.ex | 1 + 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/lib/pinchflat/podcasts/rss_feed_builder.ex b/lib/pinchflat/podcasts/rss_feed_builder.ex index 45f07ed..d7b041b 100644 --- a/lib/pinchflat/podcasts/rss_feed_builder.ex +++ b/lib/pinchflat/podcasts/rss_feed_builder.ex @@ -1,6 +1,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do @datetime_format "%a, %d %b %Y %H:%M:%S %z" + # TODO: test # TODO: only MIs that are confirmed to exist on-disk should be provided def build(source, media_items) do media_item_xml = Enum.map(media_items, &build_media_item_xml(source, &1)) @@ -8,41 +9,20 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do build_source_xml(source, media_item_xml) end - defp build_media_item_xml(source, media_item) do - # NOTE: improvements for future: - # - Add - # - Serve proper images instead of the placeholders - """ - - #{media_item.uuid} - #{media_item.title} - #{media_item.original_url} - #{media_item.description} - #{generate_upload_date(media_item)} - - - #{source.custom_name} - #{media_item.title} - - - false - - """ - end - defp build_source_xml(source, media_item_xml) do - # Useful: https://validator.w3.org/feed/#validate_by_input - # NOTE: improvements for future: + # Useful: resources: + # - https://validator.w3.org/feed/#validate_by_input + # - https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md + # - https://podba.se/validate + # # - Add real - # - Add # - Serve proper images instead of the placeholders - # - Ass """ - + #{source.custom_name} #{source.original_url} @@ -52,6 +32,9 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do en-us #{Calendar.strftime(DateTime.utc_now(), @datetime_format)} #{Calendar.strftime(source.inserted_at, @datetime_format)} + + false + #{source.uuid} https://raw.githubusercontent.com/kieraneglin/pinchflat/master/priv/static/images/originals/logo.png #{source.custom_name} @@ -71,6 +54,31 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do """ end + defp build_media_item_xml(source, media_item) do + """ + + #{media_item.uuid} + #{media_item.title} + #{media_item.original_url} + #{media_item.description} + #{generate_upload_date(media_item)} + + + #{source.custom_name} + #{media_item.title} + + false + + """ + end + + defp generate_self_link(source) do + "#{url_base()}/sources/#{source.uuid}/feed.xml" + end + defp generate_media_stream_path(media_item) do extension = Path.extname(media_item.media_filepath) diff --git a/lib/pinchflat_web/controllers/sources/source_controller.ex b/lib/pinchflat_web/controllers/sources/source_controller.ex index 3211ccc..ae5b3f1 100644 --- a/lib/pinchflat_web/controllers/sources/source_controller.ex +++ b/lib/pinchflat_web/controllers/sources/source_controller.ex @@ -7,6 +7,7 @@ defmodule PinchflatWeb.Sources.SourceController do alias Pinchflat.Sources alias Pinchflat.Profiles alias Pinchflat.Sources.Source + alias Pinchflat.Podcasts.RssFeedBuilder def index(conn, _params) do sources = Repo.preload(Sources.list_sources(), :media_profile) @@ -58,6 +59,19 @@ defmodule PinchflatWeb.Sources.SourceController do ) end + def feed(conn, %{"id" => uuid}) do + # TODO: change this to UUID + source = Repo.get_by!(Source, id: uuid) + media_items = Media.list_downloaded_media_items_for(source, limit: 100) + + xml = RssFeedBuilder.build(source, media_items) + + conn + |> put_resp_content_type("application/rss+xml") + |> put_resp_header("content-disposition", "inline") + |> send_resp(200, xml) + end + def edit(conn, %{"id" => id}) do source = Sources.get_source!(id) changeset = Sources.change_source(source) diff --git a/lib/pinchflat_web/router.ex b/lib/pinchflat_web/router.ex index 0aff573..c452b58 100644 --- a/lib/pinchflat_web/router.ex +++ b/lib/pinchflat_web/router.ex @@ -36,6 +36,7 @@ defmodule PinchflatWeb.Router do # TODO: consider putting the basic auth here behind a config flag # so people that want RSS feeds to work can enable it. scope "/", PinchflatWeb do + get "/sources/:id/feed", Sources.SourceController, :feed get "/media/:id/stream", MediaItems.MediaItemController, :stream end