[VERY WIP] basic podcast RSS setup
This commit is contained in:
parent
0d9003cffd
commit
67f8000f5a
3 changed files with 98 additions and 51 deletions
|
|
@ -21,6 +21,7 @@ config :pinchflat,
|
||||||
# If either is unset, basic auth will not be used.
|
# If either is unset, basic auth will not be used.
|
||||||
basic_auth_username: System.get_env("BASIC_AUTH_USERNAME"),
|
basic_auth_username: System.get_env("BASIC_AUTH_USERNAME"),
|
||||||
basic_auth_password: System.get_env("BASIC_AUTH_PASSWORD"),
|
basic_auth_password: System.get_env("BASIC_AUTH_PASSWORD"),
|
||||||
|
url_base: System.get_env("BASIC_AUTH_PASSWORD") || "http://localhost:4008",
|
||||||
file_watcher_poll_interval: 1000
|
file_watcher_poll_interval: 1000
|
||||||
|
|
||||||
# Configures the endpoint
|
# Configures the endpoint
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ if config_env() == :prod do
|
||||||
config :pinchflat,
|
config :pinchflat,
|
||||||
yt_dlp_executable: System.find_executable("yt-dlp"),
|
yt_dlp_executable: System.find_executable("yt-dlp"),
|
||||||
metadata_directory: metadata_path,
|
metadata_directory: metadata_path,
|
||||||
dns_cluster_query: System.get_env("DNS_CLUSTER_QUERY")
|
dns_cluster_query: System.get_env("DNS_CLUSTER_QUERY"),
|
||||||
|
url_base: System.get_env("URL_BASE") || "http://localhost:8945"
|
||||||
|
|
||||||
config :pinchflat, Pinchflat.Repo,
|
config :pinchflat, Pinchflat.Repo,
|
||||||
database: db_path,
|
database: db_path,
|
||||||
|
|
@ -123,54 +124,4 @@ if config_env() == :prod do
|
||||||
formatter: Logger.Formatter.new()
|
formatter: Logger.Formatter.new()
|
||||||
}}
|
}}
|
||||||
]
|
]
|
||||||
|
|
||||||
# ## SSL Support
|
|
||||||
#
|
|
||||||
# To get SSL working, you will need to add the `https` key
|
|
||||||
# to your endpoint configuration:
|
|
||||||
#
|
|
||||||
# config :pinchflat, PinchflatWeb.Endpoint,
|
|
||||||
# https: [
|
|
||||||
# ...,
|
|
||||||
# port: 443,
|
|
||||||
# cipher_suite: :strong,
|
|
||||||
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
|
|
||||||
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH")
|
|
||||||
# ]
|
|
||||||
#
|
|
||||||
# The `cipher_suite` is set to `:strong` to support only the
|
|
||||||
# latest and more secure SSL ciphers. This means old browsers
|
|
||||||
# and clients may not be supported. You can set it to
|
|
||||||
# `:compatible` for wider support.
|
|
||||||
#
|
|
||||||
# `:keyfile` and `:certfile` expect an absolute path to the key
|
|
||||||
# and cert in disk or a relative path inside priv, for example
|
|
||||||
# "priv/ssl/server.key". For all supported SSL configuration
|
|
||||||
# options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1
|
|
||||||
#
|
|
||||||
# We also recommend setting `force_ssl` in your endpoint, ensuring
|
|
||||||
# no data is ever sent via http, always redirecting to https:
|
|
||||||
#
|
|
||||||
# config :pinchflat, PinchflatWeb.Endpoint,
|
|
||||||
# force_ssl: [hsts: true]
|
|
||||||
#
|
|
||||||
# Check `Plug.SSL` for all available options in `force_ssl`.
|
|
||||||
|
|
||||||
# ## Configuring the mailer
|
|
||||||
#
|
|
||||||
# In production you need to configure the mailer to use a different adapter.
|
|
||||||
# Also, you may need to configure the Swoosh API client of your choice if you
|
|
||||||
# are not using SMTP. Here is an example of the configuration:
|
|
||||||
#
|
|
||||||
# config :pinchflat, Pinchflat.Mailer,
|
|
||||||
# adapter: Swoosh.Adapters.Mailgun,
|
|
||||||
# api_key: System.get_env("MAILGUN_API_KEY"),
|
|
||||||
# domain: System.get_env("MAILGUN_DOMAIN")
|
|
||||||
#
|
|
||||||
# For this example you need include a HTTP client required by Swoosh API client.
|
|
||||||
# Swoosh supports Hackney and Finch out of the box:
|
|
||||||
#
|
|
||||||
# config :swoosh, :api_client, Swoosh.ApiClient.Hackney
|
|
||||||
#
|
|
||||||
# See https://hexdocs.pm/swoosh/Swoosh.html#module-installation for details.
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
95
lib/pinchflat/podcasts/rss_feed_builder.ex
Normal file
95
lib/pinchflat/podcasts/rss_feed_builder.ex
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
defmodule Pinchflat.Podcasts.RssFeedBuilder do
|
||||||
|
@datetime_format "%a, %d %b %Y %H:%M:%S %z"
|
||||||
|
|
||||||
|
# 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))
|
||||||
|
|
||||||
|
build_source_xml(source, media_item_xml)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_media_item_xml(source, media_item) do
|
||||||
|
# NOTE: improvements for future:
|
||||||
|
# - Add <itunes:duration>
|
||||||
|
# - Serve proper images instead of the placeholders
|
||||||
|
"""
|
||||||
|
<item>
|
||||||
|
<guid isPermaLink="false">#{media_item.uuid}</guid>
|
||||||
|
<title>#{media_item.title}</title>
|
||||||
|
<link>#{media_item.original_url}</link>
|
||||||
|
<description>#{media_item.description}</description>
|
||||||
|
<pubDate>#{generate_upload_date(media_item)}</pubDate>
|
||||||
|
<enclosure
|
||||||
|
url="#{generate_media_stream_path(media_item)}"
|
||||||
|
length="#{media_item.media_size_bytes}"
|
||||||
|
type="#{determine_content_type(media_item)}">
|
||||||
|
</enclosure>
|
||||||
|
<itunes:author>#{source.custom_name}</itunes:author>
|
||||||
|
<itunes:subtitle>#{media_item.title}</itunes:subtitle>
|
||||||
|
<itunes:summary><![CDATA[#{media_item.description}]]></itunes:summary>
|
||||||
|
<itunes:image href="https://raw.githubusercontent.com/kieraneglin/pinchflat/master/priv/static/images/originals/logo.png"></itunes:image>
|
||||||
|
<itunes:explicit>false</itunes:explicit>
|
||||||
|
</item>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_source_xml(source, media_item_xml) do
|
||||||
|
# Useful: https://validator.w3.org/feed/#validate_by_input
|
||||||
|
# NOTE: improvements for future:
|
||||||
|
# - Add real <description>
|
||||||
|
# - Add <itunes:summary>
|
||||||
|
# - Serve proper images instead of the placeholders
|
||||||
|
# - Ass <atom:link href="<LINK TO FEED>" rel="self" type="application/rss+xml" />
|
||||||
|
"""
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<rss version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
|
||||||
|
<channel>
|
||||||
|
<title>#{source.custom_name}</title>
|
||||||
|
<link>#{source.original_url}</link>
|
||||||
|
<description>#{source.custom_name}</description>
|
||||||
|
<category>TV & Film</category>
|
||||||
|
<generator>Generated by Pinchflat</generator>
|
||||||
|
<language>en-us</language>
|
||||||
|
<lastBuildDate>#{Calendar.strftime(DateTime.utc_now(), @datetime_format)}</lastBuildDate>
|
||||||
|
<pubDate>#{Calendar.strftime(source.inserted_at, @datetime_format)}</pubDate>
|
||||||
|
<image>
|
||||||
|
<url>https://raw.githubusercontent.com/kieraneglin/pinchflat/master/priv/static/images/originals/logo.png</url>
|
||||||
|
<title>#{source.custom_name}</title>
|
||||||
|
<link>#{source.original_url}</link>
|
||||||
|
</image>
|
||||||
|
<itunes:author>#{source.custom_name}</itunes:author>
|
||||||
|
<itunes:subtitle>#{source.custom_name}</itunes:subtitle>
|
||||||
|
<itunes:block>yes</itunes:block>
|
||||||
|
<itunes:image href="https://raw.githubusercontent.com/kieraneglin/pinchflat/master/priv/static/images/originals/logo.png"></itunes:image>
|
||||||
|
<itunes:explicit>false</itunes:explicit>
|
||||||
|
<itunes:category text="TV & Film"></itunes:category>
|
||||||
|
|
||||||
|
#{Enum.join(media_item_xml, "\n")}
|
||||||
|
|
||||||
|
</channel>
|
||||||
|
</rss>
|
||||||
|
"""
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_media_stream_path(media_item) do
|
||||||
|
extension = Path.extname(media_item.media_filepath)
|
||||||
|
|
||||||
|
"#{url_base()}/media/#{media_item.uuid}/stream#{extension}"
|
||||||
|
end
|
||||||
|
|
||||||
|
defp generate_upload_date(media_item) do
|
||||||
|
media_item.upload_date
|
||||||
|
|> Date.to_gregorian_days()
|
||||||
|
|> Kernel.*(86400)
|
||||||
|
|> DateTime.from_gregorian_seconds()
|
||||||
|
|> Calendar.strftime(@datetime_format)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp determine_content_type(media_item) do
|
||||||
|
MIME.from_path(media_item.media_filepath)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp url_base do
|
||||||
|
Application.get_env(:pinchflat, :url_base)
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue