From c315e91cb5f9f58623476302bdd2ff494d9c3578 Mon Sep 17 00:00:00 2001 From: Kieran Eglin Date: Tue, 26 Mar 2024 15:14:31 -0700 Subject: [PATCH] Removed the need for url_base to be set --- config/config.exs | 1 - config/runtime.exs | 2 -- lib/pinchflat/podcasts/rss_feed_builder.ex | 33 ++++++++++--------- .../podcasts/podcast_controller.ex | 3 +- .../controllers/sources/source_html.ex | 7 ++-- .../sources/source_html/show.html.heex | 2 +- lib/pinchflat_web/endpoint.ex | 15 +++++++++ .../podcasts/rss_feed_builder_test.exs | 14 +++++--- 8 files changed, 47 insertions(+), 30 deletions(-) diff --git a/config/config.exs b/config/config.exs index 874c363..5038e77 100644 --- a/config/config.exs +++ b/config/config.exs @@ -23,7 +23,6 @@ config :pinchflat, basic_auth_username: "", basic_auth_password: "", expose_xml_feed: false, - url_base: System.get_env("BASIC_AUTH_PASSWORD") || "http://localhost:4008", file_watcher_poll_interval: 1000 # Configures the endpoint diff --git a/config/runtime.exs b/config/runtime.exs index e3d0166..f494884 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -49,7 +49,6 @@ if config_env() == :prod do # For running PF as a podcast host on self-hosted environments expose_xml_feed = String.length(System.get_env("EXPOSE_XML_FEED", "")) > 0 - url_base = System.get_env("URL_BASE", "") # We want to force _some_ level of useful logging in production acceptable_log_levels = ~w(debug info)a @@ -69,7 +68,6 @@ if config_env() == :prod do extras_directory: extras_path, tmpfile_directory: Path.join([System.tmp_dir!(), "pinchflat", "data"]), dns_cluster_query: System.get_env("DNS_CLUSTER_QUERY"), - url_base: url_base, expose_xml_feed: expose_xml_feed config :pinchflat, Pinchflat.Repo, diff --git a/lib/pinchflat/podcasts/rss_feed_builder.ex b/lib/pinchflat/podcasts/rss_feed_builder.ex index 72973f5..7e74010 100644 --- a/lib/pinchflat/podcasts/rss_feed_builder.ex +++ b/lib/pinchflat/podcasts/rss_feed_builder.ex @@ -20,15 +20,16 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do """ def build(source, opts \\ []) do limit = Keyword.get(opts, :limit, 300) + url_base = Keyword.get(opts, :url_base, PinchflatWeb.Endpoint.url()) media_items = PodcastHelpers.persisted_media_items_for(source, limit: limit) - build_source_xml(source, media_items) + build_source_xml(source, media_items, url_base) end - defp build_source_xml(source, media_items) do - media_item_xml = Enum.map(media_items, &build_media_item_xml(source, &1)) + defp build_source_xml(source, media_items, url_base) do + media_item_xml = Enum.map(media_items, &build_media_item_xml(source, &1, url_base)) # "caching" the image path since it requires some DB calls and is used twice - feed_image_path = feed_image_path(source, media_items) + feed_image_path = feed_image_path(url_base, source, media_items) # Useful: resources: # - https://validator.w3.org/feed/#validate_by_input @@ -49,7 +50,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do en-us #{Calendar.strftime(source.updated_at, @datetime_format)} #{Calendar.strftime(source.inserted_at, @datetime_format)} - + yes #{source.uuid} @@ -71,7 +72,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do """ end - defp build_media_item_xml(source, media_item) do + defp build_media_item_xml(source, media_item, url_base) do """ #{media_item.uuid} @@ -80,7 +81,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do #{media_item.description} #{generate_upload_date(media_item)} @@ -92,24 +93,24 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do """ end - defp generate_self_link(source) do - Path.join(url_base(), "#{podcast_route(:rss_feed, source.uuid)}.xml") + defp generate_self_link(url_base, source) do + Path.join(url_base, "#{podcast_route(:rss_feed, source.uuid)}.xml") end - defp media_stream_path(media_item) do + defp media_stream_path(url_base, media_item) do extension = Path.extname(media_item.media_filepath) - Path.join(url_base(), "#{media_route(:stream, media_item.uuid)}#{extension}") + Path.join(url_base, "#{media_route(:stream, media_item.uuid)}#{extension}") end - defp feed_image_path(source, media_items) do + defp feed_image_path(url_base, source, media_items) do case PodcastHelpers.select_cover_image(source, media_items) do {:error, _} -> "" {:ok, filepath} -> extension = Path.extname(filepath) - Path.join(url_base(), "#{podcast_route(:feed_image, source.uuid)}#{extension}") + Path.join(url_base, "#{podcast_route(:feed_image, source.uuid)}#{extension}") end end @@ -127,7 +128,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do Routes.media_item_path(PinchflatWeb.Endpoint, action, params) end - defp url_base do - Application.get_env(:pinchflat, :url_base) - end + # defp url_base do + # Application.get_env(:pinchflat, :url_base) + # end end diff --git a/lib/pinchflat_web/controllers/podcasts/podcast_controller.ex b/lib/pinchflat_web/controllers/podcasts/podcast_controller.ex index 284851e..aa65c57 100644 --- a/lib/pinchflat_web/controllers/podcasts/podcast_controller.ex +++ b/lib/pinchflat_web/controllers/podcasts/podcast_controller.ex @@ -9,7 +9,8 @@ defmodule PinchflatWeb.Podcasts.PodcastController do def rss_feed(conn, %{"uuid" => uuid}) do source = Repo.get_by!(Source, uuid: uuid) - xml = RssFeedBuilder.build(source, limit: 300) + url_base = url(conn, ~p"/") + xml = RssFeedBuilder.build(source, limit: 300, url_base: url_base) conn |> put_resp_content_type("application/rss+xml") diff --git a/lib/pinchflat_web/controllers/sources/source_html.ex b/lib/pinchflat_web/controllers/sources/source_html.ex index b7afe45..b93b754 100644 --- a/lib/pinchflat_web/controllers/sources/source_html.ex +++ b/lib/pinchflat_web/controllers/sources/source_html.ex @@ -25,10 +25,7 @@ defmodule PinchflatWeb.Sources.SourceHTML do ] end - def rss_feed_url(source) do - url_base = Application.get_env(:pinchflat, :url_base) - path = ~p"/sources/#{source.uuid}/feed" - - Path.join(url_base, "#{path}.rss") + def rss_feed_url(conn, source) do + url(conn, ~p"/sources/#{source.uuid}/feed") <> ".xml" end end diff --git a/lib/pinchflat_web/controllers/sources/source_html/show.html.heex b/lib/pinchflat_web/controllers/sources/source_html/show.html.heex index 1ad1642..3c2934b 100644 --- a/lib/pinchflat_web/controllers/sources/source_html/show.html.heex +++ b/lib/pinchflat_web/controllers/sources/source_html/show.html.heex @@ -25,7 +25,7 @@ copied = false, 4000); "} diff --git a/lib/pinchflat_web/endpoint.ex b/lib/pinchflat_web/endpoint.ex index 0bc99a6..3fdca80 100644 --- a/lib/pinchflat_web/endpoint.ex +++ b/lib/pinchflat_web/endpoint.ex @@ -48,10 +48,25 @@ defmodule PinchflatWeb.Endpoint do plug Plug.Head plug Plug.Session, @session_options + plug :override_base_url plug :strip_trailing_extension plug PinchflatWeb.Router + # URLs need to be generated using the host of the current page being accessed + # for things like Podcast RSS feeds to contain links to the right location. + # + # Normally you'd set the `url` option in the Endpoint configuration, but + # since this is self-hosted and often accessed at multiple different URLs, + # that would probably be more difficult for end-users to set up than just + # having the application figure it out. + defp override_base_url(conn, _opts) do + new_port = if conn.port in [80, 443], do: "", else: ":#{conn.port}" + new_base_url = "#{conn.scheme}://#{conn.host}#{new_port}" + + Phoenix.Controller.put_router_url(conn, new_base_url) + end + defp strip_trailing_extension(%{path_info: []} = conn, _opts), do: conn defp strip_trailing_extension(conn, _opts) do diff --git a/test/pinchflat/podcasts/rss_feed_builder_test.exs b/test/pinchflat/podcasts/rss_feed_builder_test.exs index 6e24c42..8146b55 100644 --- a/test/pinchflat/podcasts/rss_feed_builder_test.exs +++ b/test/pinchflat/podcasts/rss_feed_builder_test.exs @@ -28,6 +28,12 @@ defmodule Pinchflat.Podcasts.RssFeedBuilderTest do refute String.contains?(res, ~s(#{good_media.title})) end + + test "can optionally specify a URL base", %{source: source} do + res = RssFeedBuilder.build(source, url_base: "http://example.com") + + assert String.contains?(res, ~s(http://example.com/sources/#{source.uuid}/feed.xml)) + end end describe "build/2 when testing source XML" do @@ -55,7 +61,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilderTest do assert String.contains?( res, - ~s() + ~s() ) end @@ -65,13 +71,13 @@ defmodule Pinchflat.Podcasts.RssFeedBuilderTest do res = RssFeedBuilder.build(source) [_before, image_block, _after] = String.split(res, ~r()) - assert String.contains?(image_block, ~s(http://localhost:4008/sources/#{source.uuid}/feed_image.jpg)) + assert String.contains?(image_block, ~s(http://localhost:8945/sources/#{source.uuid}/feed_image.jpg)) assert String.contains?(image_block, ~s(#{source.custom_name})) assert String.contains?(image_block, ~s(#{source.original_url})) assert String.contains?( res, - ~s() + ~s() ) end end @@ -120,7 +126,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilderTest do [_before, item_xml, _after] = String.split(res, ~r()) assert String.contains?(item_xml, ~s(