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(?image>))
- 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(?item>))
assert String.contains?(item_xml, ~s(