Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8c0dd0bb6b | |||
| 7a374f1162 | |||
| a5afcf168b | |||
| 2f83fe03d2 | |||
| 3c10d78e78 | |||
| 8c0df65c0c | |||
| 47bb1cb98d |
@@ -53,7 +53,7 @@ If it doesn't work for your use case, please make a feature request! You can als
|
|||||||
- Self-contained - just one Docker container with no external dependencies
|
- Self-contained - just one Docker container with no external dependencies
|
||||||
- Powerful naming system so content is stored where and how you want it
|
- Powerful naming system so content is stored where and how you want it
|
||||||
- Easy-to-use web interface with presets to get you started right away
|
- Easy-to-use web interface with presets to get you started right away
|
||||||
- First-class support for media center apps like Plex, Jellyfin, and Kodi
|
- First-class support for media center apps like Plex, Jellyfin, and Kodi ([docs](https://github.com/kieraneglin/pinchflat/wiki/Frequently-Asked-Questions#how-do-i-get-media-into-plexjellyfinkodi))
|
||||||
- Supports serving RSS feeds to your favourite podcast app ([docs](https://github.com/kieraneglin/pinchflat/wiki/Podcast-RSS-Feeds))
|
- Supports serving RSS feeds to your favourite podcast app ([docs](https://github.com/kieraneglin/pinchflat/wiki/Podcast-RSS-Feeds))
|
||||||
- Automatically downloads new content from channels and playlists
|
- Automatically downloads new content from channels and playlists
|
||||||
- Uses a novel approach to download new content more quickly than other apps
|
- Uses a novel approach to download new content more quickly than other apps
|
||||||
@@ -63,7 +63,7 @@ If it doesn't work for your use case, please make a feature request! You can als
|
|||||||
- Allows automatically redownloading new media after a set period
|
- Allows automatically redownloading new media after a set period
|
||||||
- This can help improve the download quality of new content or improve SponsorBlock tags
|
- This can help improve the download quality of new content or improve SponsorBlock tags
|
||||||
- Optionally automatically delete old content ([docs](https://github.com/kieraneglin/pinchflat/wiki/Automatically-Delete-Media))
|
- Optionally automatically delete old content ([docs](https://github.com/kieraneglin/pinchflat/wiki/Automatically-Delete-Media))
|
||||||
- Advanced options like setting cutoff dates and filtering by title
|
- Advanced options like setting cutoff dates and filtering by title ([docs](https://github.com/kieraneglin/pinchflat/wiki/Frequently-Asked-Questions#i-only-want-certain-videos-from-a-source---how-can-i-only-download-those))
|
||||||
- Reliable hands-off operation
|
- Reliable hands-off operation
|
||||||
- Can pass cookies to YouTube to download your private playlists ([docs](https://github.com/kieraneglin/pinchflat/wiki/YouTube-Cookies))
|
- Can pass cookies to YouTube to download your private playlists ([docs](https://github.com/kieraneglin/pinchflat/wiki/YouTube-Cookies))
|
||||||
- Sponsorblock integration
|
- Sponsorblock integration
|
||||||
@@ -161,9 +161,9 @@ Prior to 2024-05-10, a portion of all donations were given to the [Electronic Fr
|
|||||||
|
|
||||||
The EFF defends your online liberties and [backed](https://github.com/github/dmca/blob/9a85e0f021f7967af80e186b890776a50443f06c/2020/11/2020-11-16-RIAA-reversal-effletter.pdf) `youtube-dl` when Google took them down.
|
The EFF defends your online liberties and [backed](https://github.com/github/dmca/blob/9a85e0f021f7967af80e186b890776a50443f06c/2020/11/2020-11-16-RIAA-reversal-effletter.pdf) `youtube-dl` when Google took them down.
|
||||||
|
|
||||||
## Pre-release disclaimer
|
## Stability disclaimer
|
||||||
|
|
||||||
This is pre-release software and anything can break at any time. I make not guarantees about the stability of this software, forward-compatibility of updates, or integrity (both related to and independent of Pinchflat). Essentially, use at your own risk and expect there will be rough edges for now.
|
This software is in active development and anything can break at any time. I make no guarantees about the stability of this software, forward-compatibility of updates, or integrity (both related to and independent of Pinchflat).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -79,11 +79,12 @@ if config_env() == :prod do
|
|||||||
tmpfile_directory: Path.join([System.tmp_dir!(), "pinchflat", "data"]),
|
tmpfile_directory: Path.join([System.tmp_dir!(), "pinchflat", "data"]),
|
||||||
dns_cluster_query: System.get_env("DNS_CLUSTER_QUERY"),
|
dns_cluster_query: System.get_env("DNS_CLUSTER_QUERY"),
|
||||||
expose_feed_endpoints: expose_feed_endpoints,
|
expose_feed_endpoints: expose_feed_endpoints,
|
||||||
timezone: System.get_env("TIMEZONE") || System.get_env("TZ") || "UTC",
|
# This is configured in application.ex
|
||||||
|
timezone: "UTC",
|
||||||
log_path: log_path,
|
log_path: log_path,
|
||||||
base_route_path: base_route_path
|
base_route_path: base_route_path
|
||||||
|
|
||||||
config :tzdata, :data_dir, System.get_env("TZ_DATA_DIR", "/etc/elixir_tzdata_data")
|
config :tzdata, :data_dir, System.get_env("TZ_DATA_DIR", "/config/extras/elixir_tz_data")
|
||||||
|
|
||||||
config :pinchflat, Pinchflat.Repo,
|
config :pinchflat, Pinchflat.Repo,
|
||||||
database: db_path,
|
database: db_path,
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ defmodule Pinchflat.Application do
|
|||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
use Application
|
use Application
|
||||||
|
require Logger
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def start(_type, _args) do
|
def start(_type, _args) do
|
||||||
|
check_and_update_timezone()
|
||||||
|
|
||||||
children = [
|
children = [
|
||||||
PinchflatWeb.Telemetry,
|
PinchflatWeb.Telemetry,
|
||||||
Pinchflat.Repo,
|
Pinchflat.Repo,
|
||||||
@@ -47,4 +50,20 @@ defmodule Pinchflat.Application do
|
|||||||
:ok = Oban.Telemetry.attach_default_logger()
|
:ok = Oban.Telemetry.attach_default_logger()
|
||||||
:telemetry.attach_many("job-telemetry-broadcast", events, &PinchflatWeb.Telemetry.job_state_change_broadcast/4, [])
|
:telemetry.attach_many("job-telemetry-broadcast", events, &PinchflatWeb.Telemetry.job_state_change_broadcast/4, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This has to be here (rather than runtime.exs) since the `tzdata` application
|
||||||
|
# has to be started before we can check the timezone
|
||||||
|
defp check_and_update_timezone do
|
||||||
|
attempted_timezone = System.get_env("TIMEZONE") || System.get_env("TZ") || "UTC"
|
||||||
|
|
||||||
|
valid_timezone =
|
||||||
|
if Tzdata.zone_exists?(attempted_timezone) do
|
||||||
|
attempted_timezone
|
||||||
|
else
|
||||||
|
Logger.warning("Invalid timezone #{attempted_timezone}, defaulting to UTC")
|
||||||
|
"UTC"
|
||||||
|
end
|
||||||
|
|
||||||
|
Application.put_env(:pinchflat, :timezone, valid_timezone)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ defmodule Pinchflat.Media do
|
|||||||
|
|
||||||
alias Pinchflat.Lifecycle.UserScripts.CommandRunner, as: UserScriptRunner
|
alias Pinchflat.Lifecycle.UserScripts.CommandRunner, as: UserScriptRunner
|
||||||
|
|
||||||
|
# Some fields should only be set on insert and not on update.
|
||||||
|
@fields_to_drop_on_update [:playlist_index]
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of media_items.
|
Returns the list of media_items.
|
||||||
|
|
||||||
@@ -131,8 +134,6 @@ defmodule Pinchflat.Media do
|
|||||||
"""
|
"""
|
||||||
def create_media_item_from_backend_attrs(source, media_attrs_struct) do
|
def create_media_item_from_backend_attrs(source, media_attrs_struct) do
|
||||||
attrs = Map.merge(%{source_id: source.id}, Map.from_struct(media_attrs_struct))
|
attrs = Map.merge(%{source_id: source.id}, Map.from_struct(media_attrs_struct))
|
||||||
# Some fields should only be set on insert and not on update.
|
|
||||||
fields_to_drop_on_update = [:playlist_index]
|
|
||||||
|
|
||||||
%MediaItem{}
|
%MediaItem{}
|
||||||
|> MediaItem.changeset(attrs)
|
|> MediaItem.changeset(attrs)
|
||||||
@@ -140,7 +141,7 @@ defmodule Pinchflat.Media do
|
|||||||
on_conflict: [
|
on_conflict: [
|
||||||
set:
|
set:
|
||||||
attrs
|
attrs
|
||||||
|> Map.drop(fields_to_drop_on_update)
|
|> Map.drop(@fields_to_drop_on_update)
|
||||||
|> Map.to_list()
|
|> Map.to_list()
|
||||||
],
|
],
|
||||||
conflict_target: [:source_id, :media_id]
|
conflict_target: [:source_id, :media_id]
|
||||||
@@ -153,8 +154,10 @@ defmodule Pinchflat.Media do
|
|||||||
Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}
|
Returns {:ok, %MediaItem{}} | {:error, %Ecto.Changeset{}}
|
||||||
"""
|
"""
|
||||||
def update_media_item(%MediaItem{} = media_item, attrs) do
|
def update_media_item(%MediaItem{} = media_item, attrs) do
|
||||||
|
update_attrs = Map.drop(attrs, @fields_to_drop_on_update)
|
||||||
|
|
||||||
media_item
|
media_item
|
||||||
|> MediaItem.changeset(attrs)
|
|> MediaItem.changeset(update_attrs)
|
||||||
|> Repo.update()
|
|> Repo.update()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -87,9 +87,11 @@ defmodule Pinchflat.YtDlp.Media do
|
|||||||
Returns the output template for yt-dlp's indexing command.
|
Returns the output template for yt-dlp's indexing command.
|
||||||
|
|
||||||
NOTE: playlist_index is really only useful for playlists that will never change their order.
|
NOTE: playlist_index is really only useful for playlists that will never change their order.
|
||||||
|
NOTE: I've switched back to `original_url` (from `webpage_url`) since it's started indicating
|
||||||
|
if something is a short via the URL again
|
||||||
"""
|
"""
|
||||||
def indexing_output_template do
|
def indexing_output_template do
|
||||||
"%(.{id,title,live_status,webpage_url,description,aspect_ratio,duration,upload_date,timestamp,playlist_index})j"
|
"%(.{id,title,live_status,original_url,description,aspect_ratio,duration,upload_date,timestamp,playlist_index})j"
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
@@ -103,17 +105,17 @@ defmodule Pinchflat.YtDlp.Media do
|
|||||||
media_id: response["id"],
|
media_id: response["id"],
|
||||||
title: response["title"],
|
title: response["title"],
|
||||||
description: response["description"],
|
description: response["description"],
|
||||||
original_url: response["webpage_url"],
|
original_url: response["original_url"],
|
||||||
livestream: !!response["live_status"] && response["live_status"] != "not_live",
|
livestream: !!response["live_status"] && response["live_status"] != "not_live",
|
||||||
duration_seconds: response["duration"] && round(response["duration"]),
|
duration_seconds: response["duration"] && round(response["duration"]),
|
||||||
short_form_content: response["webpage_url"] && short_form_content?(response),
|
short_form_content: response["original_url"] && short_form_content?(response),
|
||||||
uploaded_at: response["upload_date"] && parse_uploaded_at(response),
|
uploaded_at: response["upload_date"] && parse_uploaded_at(response),
|
||||||
playlist_index: response["playlist_index"] || 0
|
playlist_index: response["playlist_index"] || 0
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp short_form_content?(response) do
|
defp short_form_content?(response) do
|
||||||
if String.contains?(response["webpage_url"], "/shorts/") do
|
if String.contains?(response["original_url"], "/shorts/") do
|
||||||
true
|
true
|
||||||
else
|
else
|
||||||
# Sometimes shorts are returned without /shorts/ in the URL,
|
# Sometimes shorts are returned without /shorts/ in the URL,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ defmodule Pinchflat.MixProject do
|
|||||||
def project do
|
def project do
|
||||||
[
|
[
|
||||||
app: :pinchflat,
|
app: :pinchflat,
|
||||||
version: "2024.10.25",
|
version: "2024.10.30",
|
||||||
elixir: "~> 1.17",
|
elixir: "~> 1.17",
|
||||||
elixirc_paths: elixirc_paths(Mix.env()),
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
start_permanent: Mix.env() == :prod,
|
start_permanent: Mix.env() == :prod,
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ defmodule Pinchflat.FastIndexing.FastIndexingHelpersTest do
|
|||||||
Phoenix.json_library().encode!(%{
|
Phoenix.json_library().encode!(%{
|
||||||
id: "video2",
|
id: "video2",
|
||||||
title: "Video 2",
|
title: "Video 2",
|
||||||
webpage_url: "https://example.com/shorts/video2",
|
original_url: "https://example.com/shorts/video2",
|
||||||
live_status: "is_live",
|
live_status: "is_live",
|
||||||
description: "desc2",
|
description: "desc2",
|
||||||
aspect_ratio: 1.67,
|
aspect_ratio: 1.67,
|
||||||
|
|||||||
@@ -712,6 +712,21 @@ defmodule Pinchflat.MediaTest do
|
|||||||
assert media_item.media_filepath == update_attrs.media_filepath
|
assert media_item.media_filepath == update_attrs.media_filepath
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "updating strips playlist_index from the provided attrs" do
|
||||||
|
media_item = media_item_fixture(playlist_index: 5)
|
||||||
|
|
||||||
|
update_attrs = %{
|
||||||
|
media_id: Faker.String.base64(12),
|
||||||
|
title: Faker.Commerce.product_name(),
|
||||||
|
media_filepath: "/video/#{Faker.File.file_name(:video)}",
|
||||||
|
source_id: source_fixture().id,
|
||||||
|
playlist_index: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
assert {:ok, %MediaItem{} = media_item} = Media.update_media_item(media_item, update_attrs)
|
||||||
|
assert media_item.playlist_index == 5
|
||||||
|
end
|
||||||
|
|
||||||
test "updating with invalid data returns error changeset" do
|
test "updating with invalid data returns error changeset" do
|
||||||
media_item = media_item_fixture()
|
media_item = media_item_fixture()
|
||||||
assert {:error, %Ecto.Changeset{}} = Media.update_media_item(media_item, @invalid_attrs)
|
assert {:error, %Ecto.Changeset{}} = Media.update_media_item(media_item, @invalid_attrs)
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpersTest do
|
|||||||
description: "desc3",
|
description: "desc3",
|
||||||
# Only focusing on these because these are passed to functions that
|
# Only focusing on these because these are passed to functions that
|
||||||
# could fail if they're not present
|
# could fail if they're not present
|
||||||
webpage_url: nil,
|
original_url: nil,
|
||||||
aspect_ratio: nil,
|
aspect_ratio: nil,
|
||||||
duration: nil,
|
duration: nil,
|
||||||
upload_date: nil
|
upload_date: nil
|
||||||
@@ -299,7 +299,7 @@ defmodule Pinchflat.SlowIndexing.SlowIndexingHelpersTest do
|
|||||||
Phoenix.json_library().encode!(%{
|
Phoenix.json_library().encode!(%{
|
||||||
id: "video2",
|
id: "video2",
|
||||||
title: "Video 2",
|
title: "Video 2",
|
||||||
webpage_url: "https://example.com/shorts/video2",
|
original_url: "https://example.com/shorts/video2",
|
||||||
live_status: "is_live",
|
live_status: "is_live",
|
||||||
description: "desc2",
|
description: "desc2",
|
||||||
aspect_ratio: 1.67,
|
aspect_ratio: 1.67,
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
describe "indexing_output_template/0" do
|
describe "indexing_output_template/0" do
|
||||||
test "contains all the greatest hits" do
|
test "contains all the greatest hits" do
|
||||||
attrs =
|
attrs =
|
||||||
~w(id title live_status webpage_url description aspect_ratio duration upload_date timestamp playlist_index)a
|
~w(id title live_status original_url description aspect_ratio duration upload_date timestamp playlist_index)a
|
||||||
|
|
||||||
formatted_attrs = "%(.{#{Enum.join(attrs, ",")}})j"
|
formatted_attrs = "%(.{#{Enum.join(attrs, ",")}})j"
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
"id" => "TiZPUDkDYbk",
|
"id" => "TiZPUDkDYbk",
|
||||||
"title" => "Trying to Wheelie Without the Rear Brake",
|
"title" => "Trying to Wheelie Without the Rear Brake",
|
||||||
"description" => "I'm not sure what I expected.",
|
"description" => "I'm not sure what I expected.",
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"live_status" => "not_live",
|
"live_status" => "not_live",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 60,
|
"duration" => 60,
|
||||||
@@ -177,7 +177,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "sets short_form_content to true if the URL contains /shorts/" do
|
test "sets short_form_content to true if the URL contains /shorts/" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/shorts/TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/shorts/TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 61,
|
"duration" => 61,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -188,7 +188,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "sets short_form_content to true if the aspect ratio are duration are right" do
|
test "sets short_form_content to true if the aspect ratio are duration are right" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 0.5,
|
"aspect_ratio" => 0.5,
|
||||||
"duration" => 59,
|
"duration" => 59,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -199,7 +199,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "sets short_form_content to false otherwise" do
|
test "sets short_form_content to false otherwise" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 61,
|
"duration" => 61,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -210,7 +210,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "doesn't blow up if short form content-related fields are missing" do
|
test "doesn't blow up if short form content-related fields are missing" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => nil,
|
"original_url" => nil,
|
||||||
"aspect_ratio" => nil,
|
"aspect_ratio" => nil,
|
||||||
"duration" => nil,
|
"duration" => nil,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -221,7 +221,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "parses the duration" do
|
test "parses the duration" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 60.4,
|
"duration" => 60.4,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -232,7 +232,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "doesn't blow up if duration is missing" do
|
test "doesn't blow up if duration is missing" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => nil,
|
"duration" => nil,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -243,7 +243,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "sets livestream to false if the live_status field isn't present" do
|
test "sets livestream to false if the live_status field isn't present" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 60,
|
"duration" => 60,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -254,7 +254,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "doesn't blow up if playlist_index is missing" do
|
test "doesn't blow up if playlist_index is missing" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => nil,
|
"duration" => nil,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -267,7 +267,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
describe "response_to_struct/1 when testing uploaded_at" do
|
describe "response_to_struct/1 when testing uploaded_at" do
|
||||||
test "parses the upload date from the timestamp if present" do
|
test "parses the upload date from the timestamp if present" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 61,
|
"duration" => 61,
|
||||||
"upload_date" => "20210101",
|
"upload_date" => "20210101",
|
||||||
@@ -281,7 +281,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "parses the upload date from the uploaded_at if timestamp is present but nil" do
|
test "parses the upload date from the uploaded_at if timestamp is present but nil" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 61,
|
"duration" => 61,
|
||||||
"upload_date" => "20210101",
|
"upload_date" => "20210101",
|
||||||
@@ -295,7 +295,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "parses the upload date from the uploaded_at if timestamp absent" do
|
test "parses the upload date from the uploaded_at if timestamp absent" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 61,
|
"duration" => 61,
|
||||||
"upload_date" => "20210101"
|
"upload_date" => "20210101"
|
||||||
@@ -308,7 +308,7 @@ defmodule Pinchflat.YtDlp.MediaTest do
|
|||||||
|
|
||||||
test "doesn't blow up if upload date is missing" do
|
test "doesn't blow up if upload date is missing" do
|
||||||
response = %{
|
response = %{
|
||||||
"webpage_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
"original_url" => "https://www.youtube.com/watch?v=TiZPUDkDYbk",
|
||||||
"aspect_ratio" => 1.0,
|
"aspect_ratio" => 1.0,
|
||||||
"duration" => 61,
|
"duration" => 61,
|
||||||
"upload_date" => nil
|
"upload_date" => nil
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ defmodule Pinchflat.MediaFixtures do
|
|||||||
media_attributes = %{
|
media_attributes = %{
|
||||||
id: "video1",
|
id: "video1",
|
||||||
title: "Video 1",
|
title: "Video 1",
|
||||||
webpage_url: "https://example.com/video1",
|
original_url: "https://example.com/video1",
|
||||||
live_status: "not_live",
|
live_status: "not_live",
|
||||||
description: "desc1",
|
description: "desc1",
|
||||||
aspect_ratio: 1.67,
|
aspect_ratio: 1.67,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ defmodule Pinchflat.SourcesFixtures do
|
|||||||
%{
|
%{
|
||||||
id: "video1",
|
id: "video1",
|
||||||
title: "Video 1",
|
title: "Video 1",
|
||||||
webpage_url: "https://example.com/video1",
|
original_url: "https://example.com/video1",
|
||||||
live_status: "not_live",
|
live_status: "not_live",
|
||||||
description: "desc1",
|
description: "desc1",
|
||||||
aspect_ratio: 1.67,
|
aspect_ratio: 1.67,
|
||||||
@@ -90,7 +90,7 @@ defmodule Pinchflat.SourcesFixtures do
|
|||||||
%{
|
%{
|
||||||
id: "video2",
|
id: "video2",
|
||||||
title: "Video 2",
|
title: "Video 2",
|
||||||
webpage_url: "https://example.com/video2",
|
original_url: "https://example.com/video2",
|
||||||
live_status: "is_live",
|
live_status: "is_live",
|
||||||
description: "desc2",
|
description: "desc2",
|
||||||
aspect_ratio: 1.67,
|
aspect_ratio: 1.67,
|
||||||
@@ -100,7 +100,7 @@ defmodule Pinchflat.SourcesFixtures do
|
|||||||
%{
|
%{
|
||||||
id: "video3",
|
id: "video3",
|
||||||
title: "Video 3",
|
title: "Video 3",
|
||||||
webpage_url: "https://example.com/video3",
|
original_url: "https://example.com/video3",
|
||||||
live_status: "not_live",
|
live_status: "not_live",
|
||||||
description: "desc3",
|
description: "desc3",
|
||||||
aspect_ratio: 1.0,
|
aspect_ratio: 1.0,
|
||||||
|
|||||||
Reference in New Issue
Block a user