From 4b679603437dcc6db79a890b33afab5fee7c93d1 Mon Sep 17 00:00:00 2001 From: Jerod Santo Date: Thu, 23 Jan 2025 12:19:58 -0600 Subject: [PATCH] [admin] Improve YT description output --- .formatter.exs | 2 +- assets/admin/views/episodeView.js | 10 +++++--- lib/changelog/kits/string_kit.ex | 9 +++++++ .../controllers/admin/episode_controller.ex | 20 ++++++++++++--- .../admin/episode/_yt_friends.text.eex | 25 +++++++++++++++++++ .../templates/admin/episode/_yt_news.text.eex | 7 ++++++ .../admin/episode/_yt_podcast.text.eex | 25 +++++++++++++++++++ .../templates/admin/episode/youtube.html.heex | 24 ++++++++++++++---- test/changelog/kits/string_kit_test.exs | 21 ++++++++++++++++ 9 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 lib/changelog_web/templates/admin/episode/_yt_friends.text.eex create mode 100644 lib/changelog_web/templates/admin/episode/_yt_news.text.eex create mode 100644 lib/changelog_web/templates/admin/episode/_yt_podcast.text.eex diff --git a/.formatter.exs b/.formatter.exs index 29b85518c1..88647da8b9 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,5 +1,5 @@ [ import_deps: [:ecto, :phoenix], - inputs: ["*.{heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{heex,ex,exs}"], + inputs: ["*.{eex,heex,ex,exs}", "priv/*/seeds.exs", "{config,lib,test}/**/*.{eex,heex,ex,exs}"], subdirectories: ["priv/*/migrations"] ] diff --git a/assets/admin/views/episodeView.js b/assets/admin/views/episodeView.js index c0e4051ed3..46bdacda87 100644 --- a/assets/admin/views/episodeView.js +++ b/assets/admin/views/episodeView.js @@ -92,6 +92,7 @@ export default class EpisodeView { youtube() { let $csvFileDropZone = $(".js-csv-file"); + let $selectInput = $(".js-episode-select input"); let outputTextArea = document.querySelector(".js-description-output"); $csvFileDropZone @@ -121,11 +122,14 @@ export default class EpisodeView { .querySelector("meta[name='csrf-token']") .getAttribute("content") }, - body: JSON.stringify({ csv: e.target.result }) + body: JSON.stringify({ + id: $selectInput.val(), + csv: e.target.result + }) }); - let output = await response.json(); + let json = await response.json(); - outputTextArea.value = output.markers; + outputTextArea.value = json.output; $csvFileDropZone.removeClass("loading"); outputTextArea.dispatchEvent(new Event("autosize:update")); diff --git a/lib/changelog/kits/string_kit.ex b/lib/changelog/kits/string_kit.ex index ea747dab79..32778c4c1f 100644 --- a/lib/changelog/kits/string_kit.ex +++ b/lib/changelog/kits/string_kit.ex @@ -64,6 +64,15 @@ defmodule Changelog.StringKit do Regex.replace(regex, string, "\\1") end + @doc """ + Removes Markdown-style descriptions from a link. Opposite of `md_delinkify` + """ + def md_bare_linkify(string) do + regex = ~r/\[(.*?)\]\((.*?)\)/ + + Regex.replace(regex, string, "\\2") + end + @doc """ Converts 'bare' mentions to Markdown-style links for further processing """ diff --git a/lib/changelog_web/controllers/admin/episode_controller.ex b/lib/changelog_web/controllers/admin/episode_controller.ex index 2a3d1a7bdd..3127bdc137 100644 --- a/lib/changelog_web/controllers/admin/episode_controller.ex +++ b/lib/changelog_web/controllers/admin/episode_controller.ex @@ -103,9 +103,22 @@ defmodule ChangelogWeb.Admin.EpisodeController do |> assign(:news_episodes, news_episodes) end - def youtube(conn = %{method: "POST"}, %{"csv" => csv}, _podcast) do - data = Changelog.Kits.MarkerKit.to_youtube(csv) - json(conn, %{markers: data}) + def youtube(conn = %{method: "POST"}, %{"csv" => csv, "id" => id}, podcast) do + episode = assoc(podcast, :episodes) |> Episode.preload_sponsors() |> Repo.get_by(id: id) + chapters = Changelog.Kits.MarkerKit.to_youtube(csv) + + text = + if episode do + Phoenix.View.render_to_string( + ChangelogWeb.Admin.EpisodeView, + "_yt_#{podcast.slug}.text", + %{episode: episode, chapters: chapters} + ) + else + chapters + end + + json(conn, %{output: String.trim(text)}) end def youtube(conn, _params, podcast) do @@ -114,6 +127,7 @@ defmodule ChangelogWeb.Admin.EpisodeController do |> assoc(:episodes) |> Episode.newest_first() |> Episode.limit(50) + |> Repo.all() conn |> assign(:episodes, episodes) diff --git a/lib/changelog_web/templates/admin/episode/_yt_friends.text.eex b/lib/changelog_web/templates/admin/episode/_yt_friends.text.eex new file mode 100644 index 0000000000..38e5f2d11b --- /dev/null +++ b/lib/changelog_web/templates/admin/episode/_yt_friends.text.eex @@ -0,0 +1,25 @@ +<%= @episode.summary %> + +SUBSCRIBE: + +RSS: https://changelog.am/rss +Apple: https://changelog.am/apple +Spotify: https://changelog.am/spotify +Android: https://changelog.am/android +Overcast: https://changelog.am/overcast +Email: https://changelog.am/email +X: https://x.com/changelog +Bluesky: https://bsky.app/profile/changelog.com +Mastodon: https://changelog.social/@changelog + +SPONSORS: +<%= for sponsor <- @episode.episode_sponsors do %> +<%= sponsor.title %> - <%= sponsor.description |> SharedHelpers.md_to_text() %> <%= sponsor.link_url %> +<% end %> +LINKS: + +<%= @episode.notes |> Changelog.StringKit.md_bare_linkify() %> + +CHAPTERS: + +<%= @chapters %> diff --git a/lib/changelog_web/templates/admin/episode/_yt_news.text.eex b/lib/changelog_web/templates/admin/episode/_yt_news.text.eex new file mode 100644 index 0000000000..b423705b9c --- /dev/null +++ b/lib/changelog_web/templates/admin/episode/_yt_news.text.eex @@ -0,0 +1,7 @@ +Moar links worth your attention! 👉 <%= EpisodeView.share_url(@episode) %> + +<%= SharedHelpers.md_to_text(@episode.summary) %> + +CHAPTERS: +<%= for chapter <- @episode.audio_chapters do %> +<%= TimeView.duration(chapter.starts_at) %> <%= chapter.title %><% end %> diff --git a/lib/changelog_web/templates/admin/episode/_yt_podcast.text.eex b/lib/changelog_web/templates/admin/episode/_yt_podcast.text.eex new file mode 100644 index 0000000000..f587de1d1b --- /dev/null +++ b/lib/changelog_web/templates/admin/episode/_yt_podcast.text.eex @@ -0,0 +1,25 @@ +<%= SharedHelpers.md_to_text(@episode.summary) %> + +SUBSCRIBE: + +RSS: https://changelog.fm/rss +Apple: https://changelog.fm/apple +Spotify: https://changelog.fm/spotify +Android: https://changelog.fm/android +Overcast: https://changelog.fm/overcast +Email: https://changelog.fm/email +X: https://x.com/changelog +Bluesky: https://bsky.app/profile/changelog.com +Mastodon: https://changelog.social/@changelog + +SPONSORS: +<%= for sponsor <- @episode.episode_sponsors do %> +<%= sponsor.title %> - <%= sponsor.description |> SharedHelpers.md_to_text() %> <%= sponsor.link_url %> +<% end %> +LINKS: + +<%= @episode.notes |> Changelog.StringKit.md_bare_linkify() %> + +CHAPTERS: + +<%= @chapters %> diff --git a/lib/changelog_web/templates/admin/episode/youtube.html.heex b/lib/changelog_web/templates/admin/episode/youtube.html.heex index a02ad76f69..780c217cc1 100644 --- a/lib/changelog_web/templates/admin/episode/youtube.html.heex +++ b/lib/changelog_web/templates/admin/episode/youtube.html.heex @@ -12,22 +12,36 @@
+
+ +
+
- Drop a markered .CSV file here to get a YouTube description + Select an episode & drop a markered .CSV file here
-
- - +
+ + +
-
diff --git a/test/changelog/kits/string_kit_test.exs b/test/changelog/kits/string_kit_test.exs index ddd940c996..6cc078fea3 100644 --- a/test/changelog/kits/string_kit_test.exs +++ b/test/changelog/kits/string_kit_test.exs @@ -165,6 +165,27 @@ defmodule Changelog.StringKitTest do end end + describe "md_bare_linkify/1" do + test "it leaves strings with no links in them alone" do + raw = "this has zero ! links." + assert StringKit.md_bare_linkify(raw) == raw + end + + test "it works with a single link in there" do + a = "This has [one](http://test.com) link and that's it" + b = "This has http://test.com link and that's it" + + assert StringKit.md_bare_linkify(a) == b + end + + test "it works with multiple links in there" do + a = "This has [two](http://test.com) links and that's [all](http://www.com)." + b = "This has http://test.com links and that's http://www.com." + + assert StringKit.md_bare_linkify(a) == b + end + end + describe "mentions_linkify/1" do test "it no-ops when no mentions to linkify" do raw = ~s{Yo here is my _super cool_ thing}