Name the source YouTube
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LG4iASZnHb1yEM1JAASiWn
diff --git a/AGENTS.md b/AGENTS.md
index c1ac1d5..52ebd61 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -52,7 +52,7 @@ fly.toml — Fly config for the main demo and PR previews
- **User** has many Lists; identified by the login on the `Remote-User` header. Their settings page (`/settings`) connects a Google account (**GoogleAccount**, which keeps only the refresh token)
- **List** belongs to a User and has many Items and Axes, and one source (`source_kind` names a class in `Sources`). Each source renders its own sync dialog on the list page and applies what it posts: `Text`'s edits items by id, and a kind that fetches calls `Sync.call`. A fetching kind keeps its config in its own table keyed by `list_id` and its per-item details in a table keyed by `item_id`
-- Sources: `Text` (typed in, edited by id) and `YouTubePlaylist` (follows one of the owner's playlists through their Google account; `youtube_sources` by `list_id`, `youtube_items` by `item_id`)
+- Sources: `Text` (typed in, edited by id) and `YouTube` (follows one of the owner's playlists through their Google account; `youtube_sources` by `list_id`, `youtube_items` by `item_id`)
- **Item** belongs to a List; removed items, and items missing from the latest sync, are archived (`archived_at`) and hidden everywhere
- **Axis** belongs to a List, has many Results
- **Result** belongs to an Axis, a winner (Item), and a loser (Item)
diff --git a/db/migrate/005_add_youtube.rb b/db/migrate/005_add_youtube.rb
index cca97fe..b6bf69f 100644
--- a/db/migrate/005_add_youtube.rb
+++ b/db/migrate/005_add_youtube.rb
@@ -13,13 +13,13 @@ Sequel.migration do
DateTime :updated_at, null: false
end
- # The YouTubePlaylist source's config: which playlist a list follows.
+ # The YouTube source's config: which playlist a list follows.
create_table(:youtube_sources) do
foreign_key :list_id, :lists, primary_key: true, on_delete: :cascade
String :playlist_id, null: false
end
- # The video behind each item of a YouTubePlaylist list, which is how
+ # The video behind each item of a YouTube list, which is how
# a sync recognizes the item again, and what YouTube said about it at
# the last sync.
create_table(:youtube_items) do
diff --git a/lib/rank_king/sources.rb b/lib/rank_king/sources.rb
index 3be114e..c3bf080 100644
--- a/lib/rank_king/sources.rb
+++ b/lib/rank_king/sources.rb
@@ -12,13 +12,13 @@ module RankKing
end
require_relative "sources/text"
-require_relative "sources/youtube_playlist"
+require_relative "sources/youtube"
module RankKing
module Sources
# Every kind a list can be made from, in the order the new-list form
# offers them. A list keeps its kind for good.
- KINDS = %w[Text YouTubePlaylist].freeze #: Array[String]
+ KINDS = %w[Text YouTube].freeze #: Array[String]
# A list's source_kind names a class in this module.
#: (String kind) -> _SourceClass
diff --git a/lib/rank_king/sources/youtube_playlist.rb b/lib/rank_king/sources/youtube.rb
similarity index 88%
rename from lib/rank_king/sources/youtube_playlist.rb
rename to lib/rank_king/sources/youtube.rb
index 3d63408..c29ce4b 100644
--- a/lib/rank_king/sources/youtube_playlist.rb
+++ b/lib/rank_king/sources/youtube.rb
@@ -2,14 +2,14 @@
require_relative "../google"
require_relative "../sync"
-require_relative "../views/sources/youtube_playlist"
+require_relative "../views/sources/youtube"
module RankKing
module Sources
# A list that follows one of the owner's YouTube playlists, read
# through their connected Google account, so private ones work too.
# Each sync fetches the whole playlist again.
- class YouTubePlaylist
+ class YouTube
# Which playlist each list follows, keyed by list_id.
TABLE = :youtube_sources
# Which video each item is, keyed by item_id.
@@ -18,7 +18,7 @@ module RankKing
#: () -> String
def self.title = "YouTube playlist"
- #: (List list) -> YouTubePlaylist
+ #: (List list) -> YouTube
def self.for(list) = new(list)
# A choice of the user's playlists, fetched as the form is drawn. A
@@ -28,9 +28,9 @@ module RankKing
def self.fields(user)
account = user.google_account
playlists = account && Google.playlists(Google.access_token(account.refresh_token))
- Views::Sources::YouTubePlaylistFields.new(playlists:, configured: Google.configured?)
+ Views::Sources::YouTubeFields.new(playlists:, configured: Google.configured?)
rescue Google::Error => e
- Views::Sources::YouTubePlaylistFields.new(playlists: nil, configured: true, error: e.message)
+ Views::Sources::YouTubeFields.new(playlists: nil, configured: true, error: e.message)
end
# Follows the playlist chosen on the new-list form and fetches it.
@@ -53,7 +53,7 @@ module RankKing
def label = "Sync from YouTube"
#: (csrf: Method) -> _Component
- def form(csrf:) = Views::Sources::YouTubePlaylist.new(list: @list, csrf:)
+ def form(csrf:) = Views::Sources::YouTube.new(list: @list, csrf:)
# The dialog posts nothing to apply: syncing is fetching.
#: (Hash[String, untyped] params) -> void
diff --git a/lib/rank_king/views/sources/youtube_playlist.rb b/lib/rank_king/views/sources/youtube.rb
similarity index 96%
rename from lib/rank_king/views/sources/youtube_playlist.rb
rename to lib/rank_king/views/sources/youtube.rb
index d100da2..43128a2 100644
--- a/lib/rank_king/views/sources/youtube_playlist.rb
+++ b/lib/rank_king/views/sources/youtube.rb
@@ -8,7 +8,7 @@ module RankKing
# The YouTube playlist source's fields on the new-list form: a choice
# of the user's playlists, once they have connected Google. playlists
# is nil until then.
- class YouTubePlaylistFields < Phlex::HTML
+ class YouTubeFields < Phlex::HTML
def initialize(playlists:, configured:, error: nil)
@playlists = playlists
@configured = configured
@@ -44,7 +44,7 @@ module RankKing
# The YouTube playlist source's sync dialog: there is nothing to
# fill in, so it says what syncing does and shows it working.
- class YouTubePlaylist < Phlex::HTML
+ class YouTube < Phlex::HTML
def initialize(list:, csrf:)
@list = list
@csrf = csrf
diff --git a/sig/rank_king/views.rbs b/sig/rank_king/views.rbs
index 79b75e1..8513dba 100644
--- a/sig/rank_king/views.rbs
+++ b/sig/rank_king/views.rbs
@@ -24,12 +24,12 @@ module RankKing
def call: () -> String
end
- class YouTubePlaylist
+ class YouTube
def initialize: (list: List, csrf: Method) -> void
def call: () -> String
end
- class YouTubePlaylistFields
+ class YouTubeFields
def initialize: (playlists: Array[[String, String]]?, configured: bool, ?error: String?) -> void
def call: () -> String
end
diff --git a/test/test_youtube.rb b/test/test_youtube.rb
index 6186190..33799bd 100644
--- a/test/test_youtube.rb
+++ b/test/test_youtube.rb
@@ -150,7 +150,7 @@ class TestYouTube < Minitest::Test
def test_new_list_asks_to_connect_google_first
get "/lists/new"
- assert_includes last_response.body, %(<option value="YouTubePlaylist">YouTube playlist</option>)
+ assert_includes last_response.body, %(<option value="YouTube">YouTube playlist</option>)
assert_includes last_response.body, %(<a href="/settings">your settings</a>)
refute_includes last_response.body, %(name="playlist")
end
@@ -192,7 +192,7 @@ class TestYouTube < Minitest::Test
assert last_response.redirect?
list = RankKing::List.first
- assert_equal "YouTubePlaylist", list.source_kind
+ assert_equal "YouTube", list.source_kind
refute_nil list.synced_at
assert_equal %w[First Third Fourth], names(list)
assert_equal PLAYLIST, RankKing::DB[:youtube_sources].where(list_id: list.id).get(:playlist_id)
@@ -303,7 +303,7 @@ class TestYouTube < Minitest::Test
def names(list) = list.items_dataset.order(:id).map(:name)
def create_list(playlist:)
- csrf_post "/lists", { name: "Videos", source: "YouTubePlaylist", playlist: }, from: "/lists/new"
+ csrf_post "/lists", { name: "Videos", source: "YouTube", playlist: }, from: "/lists/new"
end
def sync(list)