[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. final destination. Returns the parsed JSON output from yt-dlp.
""" """
def download(url, command_opts \\ []) do 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 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 err -> err
end end
end end

View file

@ -1,13 +1,15 @@
defmodule Pinchflat.Downloader.Backends.YtDlp.VideoCollection do defmodule Pinchflat.Downloader.Backends.YtDlp.VideoCollection do
@moduledoc """ @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 """ @doc """
Returns a list of strings representing the video ids in the collection Returns a list of strings representing the video ids in the collection
""" """
def get_video_ids(url, command_opts \\ []) do 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 case backend_runner().run(url, opts) do
{:ok, output} -> {:ok, String.split(output, "\n", trim: true)} {: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) - # 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! # 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, {:ok,
[ [
:write_thumbnail, :write_thumbnail,

View file

@ -4,7 +4,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.CommandRunnerTest do
alias Pinchflat.Downloader.Backends.YtDlp.CommandRunner, as: Runner alias Pinchflat.Downloader.Backends.YtDlp.CommandRunner, as: Runner
@original_executable Application.compile_env(:pinchflat, :yt_dlp_executable) @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 setup do
on_exit(&reset_executable/0) 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 test "it passes the expected default args" do
expect(CommandRunnerMock, :run, fn _url, opts -> expect(CommandRunnerMock, :run, fn _url, opts ->
assert opts == [:simulate, :skip_download, :get_id] assert opts == [:simulate, :skip_download, {:print, :id}]
{:ok, ""} {:ok, ""}
end) end)
@ -27,7 +27,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.VideoCollectionTest do
test "it passes the expected custom args" do test "it passes the expected custom args" do
expect(CommandRunnerMock, :run, fn _url, opts -> 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, ""} {:ok, ""}
end) end)

View file

@ -11,7 +11,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.VideoTest do
describe "download/2" do describe "download/2" do
test "it calls the backend runner with the expected arguments" do test "it calls the backend runner with the expected arguments" do
expect(CommandRunnerMock, :run, fn @video_url, opts -> expect(CommandRunnerMock, :run, fn @video_url, opts ->
assert opts == [:no_simulate, :dump_json] assert opts == [:no_simulate, {:print, "%()j"}]
{:ok, "{}"} {:ok, "{}"}
end) end)
@ -21,7 +21,7 @@ defmodule Pinchflat.Downloader.Backends.YtDlp.VideoTest do
test "it passes along additional options" do test "it passes along additional options" do
expect(CommandRunnerMock, :run, fn _url, opts -> expect(CommandRunnerMock, :run, fn _url, opts ->
assert opts == [:no_simulate, :dump_json, :custom_arg] assert opts == [:no_simulate, {:print, "%()j"}, :custom_arg]
{:ok, "{}"} {:ok, "{}"}
end) 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 test "it calls the backend runner with the arguments built from the media profile" do
expect(CommandRunnerMock, :run, fn @video_url, opts -> expect(CommandRunnerMock, :run, fn @video_url, opts ->
assert :no_simulate in 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 assert {:output, "/tmp/yt-dlp/videos/%(title)S.%(ext)s"} in opts
{:ok, "{}"} {:ok, "{}"}