[WIP] Working on fetching channel metadata in yt-dlp backend

This commit is contained in:
Kieran Eglin 2024-01-22 21:59:11 -08:00
parent 4252c27f87
commit cdd708f813
No known key found for this signature in database
GPG key ID: 193984967FCF432D
8 changed files with 48 additions and 10 deletions

View file

@ -0,0 +1,33 @@
defmodule Pinchflat.Downloader.Backends.YtDlp.Channel do
@moduledoc """
Contains utilities for working with a channel's videos
"""
# TODO: convert to `use`
import Pinchflat.Downloader.Backends.YtDlp.VideoCollection
alias __MODULE__
defstruct [:id, :name]
def new(id, name) do
%__MODULE__{id: id, name: name}
end
def get_channel_info(channel_url) do
opts = [print: "%(.{channel,channel_id})j", playlist_end: 1]
case backend_runner().run(channel_url, opts) do
{:ok, output} ->
result = Phoenix.json_library().decode!(output)
{:ok, Channel.new(result["channel_id"], result["channel"])}
res ->
res
end
end
defp backend_runner do
Application.get_env(:pinchflat, :yt_dlp_runner)
end
end

View file

@ -8,10 +8,11 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.Video do
final destination. Returns the parsed JSON output from yt-dlp.
"""
def download(url, command_opts \\ []) do
opts = [:no_simulate, :dump_json] ++ command_opts
opts = [:no_simulate, print: "%()j"] ++ command_opts
case backend_runner().run(url, opts) do
{:ok, output} -> Phoenix.json_library().decode(output)
# TODO: test that I changed this to a ! method
{:ok, output} -> {:ok, Phoenix.json_library().decode!(output)}
err -> err
end
end

View file

@ -1,13 +1,15 @@
defmodule Pinchflat.Downloader.Backends.YtDlp.VideoCollection do
@moduledoc """
Contains utilities for working with collections of videos (ie: channels, playlists)
Contains utilities for working with collections of videos (ie: channels, playlists).
Meant to be included in other modules but can be used on its own.
"""
@doc """
Returns a list of strings representing the video ids in the collection
"""
def get_video_ids(url, command_opts \\ []) do
opts = command_opts ++ [:simulate, :skip_download, :get_id]
opts = command_opts ++ [:simulate, :skip_download, print: :id]
case backend_runner().run(url, opts) do
{:ok, output} -> {:ok, String.split(output, "\n", trim: true)}

View file

@ -20,6 +20,8 @@ defmodule Pinchflat.Profiles.Options.YtDlp.OptionBuilder do
# NOTE: I'll be hardcoding most things for now (esp. options to help me test) -
# add more configuration later as I build out the models. Walk before you can run!
# NOTE: Looks like you can put different media types in different directories.
# see: https://github.com/yt-dlp/yt-dlp#output-template
{:ok,
[
:write_thumbnail,

View file

@ -4,7 +4,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.CommandRunnerTest do
alias Pinchflat.Downloader.Backends.YtDlp.CommandRunner, as: Runner
@original_executable Application.compile_env(:pinchflat, :yt_dlp_executable)
@video_url "https://www.youtube.com/watch?v=9bZkp7q19f0"
@video_url "https://www.youtube.com/watch?v=-LHXuyzpex0"
setup do
on_exit(&reset_executable/0)

View file

@ -17,7 +17,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.VideoCollectionTest do
test "it passes the expected default args" do
expect(CommandRunnerMock, :run, fn _url, opts ->
assert opts == [:simulate, :skip_download, :get_id]
assert opts == [:simulate, :skip_download, {:print, :id}]
{:ok, ""}
end)
@ -27,7 +27,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.VideoCollectionTest do
test "it passes the expected custom args" do
expect(CommandRunnerMock, :run, fn _url, opts ->
assert opts == [:custom_arg, :simulate, :skip_download, :get_id]
assert opts == [:custom_arg, :simulate, :skip_download, {:print, :id}]
{:ok, ""}
end)

View file

@ -11,7 +11,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.VideoTest do
describe "download/2" do
test "it calls the backend runner with the expected arguments" do
expect(CommandRunnerMock, :run, fn @video_url, opts ->
assert opts == [:no_simulate, :dump_json]
assert opts == [:no_simulate, {:print, "%()j"}]
{:ok, "{}"}
end)
@ -21,7 +21,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.VideoTest do
test "it passes along additional options" do
expect(CommandRunnerMock, :run, fn _url, opts ->
assert opts == [:no_simulate, :dump_json, :custom_arg]
assert opts == [:no_simulate, {:print, "%()j"}, :custom_arg]
{:ok, "{}"}
end)

View file

@ -16,7 +16,7 @@ defmodule Pinchflat.Downloader.VideoDownloaderTest do
test "it calls the backend runner with the arguments built from the media profile" do
expect(CommandRunnerMock, :run, fn @video_url, opts ->
assert :no_simulate in opts
assert :dump_json in opts
assert {:print, "%()j"} in opts
assert {:output, "/tmp/yt-dlp/videos/%(title)S.%(ext)s"} in opts
{:ok, "{}"}