Removed the need for url_base to be set

This commit is contained in:
Kieran Eglin 2024-03-26 15:14:31 -07:00
parent 73b1e60e9f
commit c315e91cb5
No known key found for this signature in database
GPG key ID: 193984967FCF432D
8 changed files with 47 additions and 30 deletions

View file

@ -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

View file

@ -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,

View file

@ -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
<language>en-us</language>
<lastBuildDate>#{Calendar.strftime(source.updated_at, @datetime_format)}</lastBuildDate>
<pubDate>#{Calendar.strftime(source.inserted_at, @datetime_format)}</pubDate>
<atom:link href="#{generate_self_link(source)}" rel="self" type="application/rss+xml" />
<atom:link href="#{generate_self_link(url_base, source)}" rel="self" type="application/rss+xml" />
<podcast:locked>yes</podcast:locked>
<podcast:guid>#{source.uuid}</podcast:guid>
<image>
@ -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
"""
<item>
<guid isPermaLink="false">#{media_item.uuid}</guid>
@ -80,7 +81,7 @@ defmodule Pinchflat.Podcasts.RssFeedBuilder do
<description>#{media_item.description}</description>
<pubDate>#{generate_upload_date(media_item)}</pubDate>
<enclosure
url="#{media_stream_path(media_item)}"
url="#{media_stream_path(url_base, media_item)}"
length="#{media_item.media_size_bytes}"
type="#{MIME.from_path(media_item.media_filepath)}"
/>
@ -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

View file

@ -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")

View file

@ -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

View file

@ -25,7 +25,7 @@
<span
x-data="{ copied: false }"
x-on:click={"
navigator.clipboard.writeText('#{rss_feed_url(@source)}');
navigator.clipboard.writeText('#{rss_feed_url(@conn, @source)}');
copied = true;
setTimeout(() => copied = false, 4000);
"}

View file

@ -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

View file

@ -28,6 +28,12 @@ defmodule Pinchflat.Podcasts.RssFeedBuilderTest do
refute String.contains?(res, ~s(<title>#{good_media.title}</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(<atom:link href="http://localhost:4008/sources/#{source.uuid}/feed.xml" rel="self" type="application/rss+xml" />)
~s(<atom:link href="http://localhost:8945/sources/#{source.uuid}/feed.xml" rel="self" type="application/rss+xml" />)
)
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(<url>http://localhost:4008/sources/#{source.uuid}/feed_image.jpg</url>))
assert String.contains?(image_block, ~s(<url>http://localhost:8945/sources/#{source.uuid}/feed_image.jpg</url>))
assert String.contains?(image_block, ~s(<title>#{source.custom_name}</title>))
assert String.contains?(image_block, ~s(<link>#{source.original_url}</link>))
assert String.contains?(
res,
~s(<itunes:image href="http://localhost:4008/sources/#{source.uuid}/feed_image.jpg"></itunes:image>)
~s(<itunes:image href="http://localhost:8945/sources/#{source.uuid}/feed_image.jpg"></itunes:image>)
)
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(<enclosure))
assert String.contains?(item_xml, ~s(url="http://localhost:4008/media/#{media_item.uuid}/stream.mp4"))
assert String.contains?(item_xml, ~s(url="http://localhost:8945/media/#{media_item.uuid}/stream.mp4"))
assert String.contains?(item_xml, ~s(length="1234"))
assert String.contains?(item_xml, ~s(type="video/mp4"))
end