Improve episode-level compatability with media center apps (#86)
* Add media profile presets (#85) * Added presets for output templates * Added presets for the entire media profile form * Append `-thumb` to thumbnails when downloading (#87) * Appended -thumb to thumbnails when downloading * Added code to compensate for yt-dlp bug * Squash all the commits from the other branch bc I broke things (#88)
This commit is contained in:
@@ -317,17 +317,7 @@ defmodule PinchflatWeb.CoreComponents do
|
||||
<span :if={@label_suffix} class="text-xs text-bodydark"><%= @label_suffix %></span>
|
||||
</.label>
|
||||
<div class="relative">
|
||||
<input type="hidden" name={@name} value="false" />
|
||||
<input
|
||||
type="checkbox"
|
||||
id={@id}
|
||||
name={@name}
|
||||
value="true"
|
||||
x-bind:checked="enabled"
|
||||
class="sr-only"
|
||||
@change="enabled = !enabled"
|
||||
{@rest}
|
||||
/>
|
||||
<input type="hidden" id={@id} name={@name} x-bind:value="enabled" {@rest} />
|
||||
<div class="inline-block cursor-pointer" @click="enabled = !enabled">
|
||||
<div x-bind:class="enabled && '!bg-primary'" class="block h-8 w-14 rounded-full bg-black"></div>
|
||||
<div
|
||||
@@ -349,23 +339,26 @@ defmodule PinchflatWeb.CoreComponents do
|
||||
def input(%{type: "select"} = assigns) do
|
||||
~H"""
|
||||
<div phx-feedback-for={@name}>
|
||||
<.label for={@id}>
|
||||
<.label :if={@label} for={@id}>
|
||||
<%= @label %><span :if={@label_suffix} class="text-xs text-bodydark"><%= @label_suffix %></span>
|
||||
</.label>
|
||||
<select
|
||||
id={@id}
|
||||
name={@name}
|
||||
class={[
|
||||
"relative z-20 w-full appearance-none rounded border border-stroke bg-transparent py-3 pl-5 pr-12 outline-none transition",
|
||||
"focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input text-black dark:text-white",
|
||||
@inputclass
|
||||
]}
|
||||
multiple={@multiple}
|
||||
{@rest}
|
||||
>
|
||||
<option :if={@prompt} value=""><%= @prompt %></option>
|
||||
<%= Phoenix.HTML.Form.options_for_select(@options, @value) %>
|
||||
</select>
|
||||
<div class="flex">
|
||||
<select
|
||||
id={@id}
|
||||
name={@name}
|
||||
class={[
|
||||
"relative z-20 w-full appearance-none rounded border border-stroke bg-transparent py-3 pl-5 pr-12 outline-none transition",
|
||||
"focus:border-primary active:border-primary dark:border-form-strokedark dark:bg-form-input text-black dark:text-white",
|
||||
@inputclass
|
||||
]}
|
||||
multiple={@multiple}
|
||||
{@rest}
|
||||
>
|
||||
<option :if={@prompt} value=""><%= @prompt %></option>
|
||||
<%= Phoenix.HTML.Form.options_for_select(@options, @value) %>
|
||||
</select>
|
||||
<%= render_slot(@inner_block) %>
|
||||
</div>
|
||||
<.help :if={@help}><%= @help %></.help>
|
||||
<.error :for={msg <- @errors}><%= msg %></.error>
|
||||
</div>
|
||||
|
||||
@@ -28,9 +28,10 @@ defmodule PinchflatWeb.CustomComponents.ButtonComponents do
|
||||
"#{@rounding} inline-flex items-center justify-center px-8 py-4",
|
||||
"#{@color}",
|
||||
"hover:bg-opacity-90 lg:px-8 xl:px-10",
|
||||
"disabled:bg-opacity-50 disabled:cursor-not-allowed disabled:text-gray-2",
|
||||
"disabled:bg-opacity-50 disabled:cursor-not-allowed disabled:text-grey-5",
|
||||
@class
|
||||
]}
|
||||
type={@type}
|
||||
disabled={@disabled}
|
||||
{@rest}
|
||||
>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do
|
||||
use PinchflatWeb, :html
|
||||
|
||||
alias Pinchflat.Profiles.MediaProfile
|
||||
|
||||
embed_templates "media_profile_html/*"
|
||||
|
||||
@doc """
|
||||
@@ -53,4 +55,25 @@ defmodule PinchflatWeb.MediaProfiles.MediaProfileHTML do
|
||||
duration_string
|
||||
)a
|
||||
end
|
||||
|
||||
def preset_options do
|
||||
[
|
||||
{"Default", "default"},
|
||||
{"Media Center (Plex, Jellyfin, Kodi, etc.)", "media_center"},
|
||||
{"Music", "audio"},
|
||||
{"Archiving", "archiving"}
|
||||
]
|
||||
end
|
||||
|
||||
defp default_output_template do
|
||||
%MediaProfile{}.output_path_template
|
||||
end
|
||||
|
||||
defp media_center_output_template do
|
||||
"/shows/{{ source_custom_name }}/{{ season_from_date }}/{{ season_episode_from_date }} - {{ title }}.{{ ext }}"
|
||||
end
|
||||
|
||||
defp audio_output_template do
|
||||
"/music/{{ source_custom_name }}/{{ title }}.{{ ext }}"
|
||||
end
|
||||
end
|
||||
|
||||
+203
-108
@@ -3,123 +3,218 @@
|
||||
Oops, something went wrong! Please check the errors below.
|
||||
</.error>
|
||||
|
||||
<h3 class="my-4 text-2xl text-black dark:text-white">
|
||||
General Options
|
||||
</h3>
|
||||
<.input
|
||||
field={f[:name]}
|
||||
type="text"
|
||||
label="Name"
|
||||
placeholder="New Profile"
|
||||
help="Something descriptive. Does not impact indexing or downloading (required)"
|
||||
/>
|
||||
<section x-data="{ selectedPreset: null }">
|
||||
<h3 class="my-4 text-2xl text-black dark:text-white">
|
||||
Use a Preset
|
||||
</h3>
|
||||
<section x-data="{ selection: null }">
|
||||
<.input
|
||||
prompt="Select preset"
|
||||
name="media_profile_preset"
|
||||
value=""
|
||||
options={preset_options()}
|
||||
type="select"
|
||||
x-model="selection"
|
||||
inputclass="w-full"
|
||||
help="You can further customize the settings after selecting a preset. This is just a starting point"
|
||||
>
|
||||
<.button
|
||||
class="h-13 w-2/5 lg:w-1/5 ml-2 md:ml-4"
|
||||
rounding="rounded"
|
||||
type="button"
|
||||
x-on:click="selectedPreset = selection; selection = null"
|
||||
x-bind:disabled="!selection"
|
||||
>
|
||||
<span x-text="selection ? 'Load' : 'Select'">Select</span><span class="hidden lg:inline ml-1">Preset</span>
|
||||
</.button>
|
||||
</.input>
|
||||
</section>
|
||||
|
||||
<.input
|
||||
field={f[:output_path_template]}
|
||||
type="text"
|
||||
inputclass="font-mono"
|
||||
label="Output path template"
|
||||
help="Must end with .{{ ext }}. See below for more details. The default is good for most cases (required)"
|
||||
/>
|
||||
<h3 class="mt-8 text-2xl text-black dark:text-white">
|
||||
General Options
|
||||
</h3>
|
||||
|
||||
<h3 class="mt-8 text-2xl text-black dark:text-white">
|
||||
Subtitle Options
|
||||
</h3>
|
||||
<.input
|
||||
field={f[:download_subs]}
|
||||
type="toggle"
|
||||
label="Download Subtitles"
|
||||
help="Downloads subtitle files alongside media file"
|
||||
/>
|
||||
<.input
|
||||
field={f[:download_auto_subs]}
|
||||
type="toggle"
|
||||
label="Download Autogenerated Subtitles"
|
||||
help="Prefers normal subs but will download autogenerated if needed. Requires 'Download Subtitles' to be enabled"
|
||||
/>
|
||||
<.input
|
||||
field={f[:embed_subs]}
|
||||
type="toggle"
|
||||
label="Embed Subtitles"
|
||||
help="Downloads and embeds subtitles in the media file itself, if supported. Uneffected by 'Download Subtitles' (recommended)"
|
||||
/>
|
||||
<.input
|
||||
field={f[:sub_langs]}
|
||||
type="text"
|
||||
label="Subtitle Languages"
|
||||
help="Use commas for multiple languages (eg: en,de)"
|
||||
/>
|
||||
<section x-data="{
|
||||
presets: {
|
||||
default: 'Default',
|
||||
media_center: 'TV Shows',
|
||||
audio: 'Audio',
|
||||
archiving: 'Archiving'
|
||||
}
|
||||
}">
|
||||
<.input
|
||||
field={f[:name]}
|
||||
type="text"
|
||||
label="Name"
|
||||
placeholder="New Profile"
|
||||
help="Something descriptive. Does not impact indexing or downloading (required)"
|
||||
x-init="$watch('selectedPreset', p => p && ($el.value = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<h3 class="mt-8 text-2xl text-black dark:text-white">
|
||||
Thumbnail Options
|
||||
</h3>
|
||||
<.input
|
||||
field={f[:download_thumbnail]}
|
||||
type="toggle"
|
||||
label="Download Thumbnail"
|
||||
help="Downloads thumbnail alongside media file"
|
||||
/>
|
||||
<.input
|
||||
field={f[:embed_thumbnail]}
|
||||
type="toggle"
|
||||
label="Embed Thumbnail"
|
||||
help="Downloads and embeds thumbnail in the media file itself, if supported. Uneffected by 'Download Thumbnail' (recommended)"
|
||||
/>
|
||||
<section x-data={"{
|
||||
presets: {
|
||||
default: '#{default_output_template()}',
|
||||
media_center: '#{media_center_output_template()}',
|
||||
audio: '#{audio_output_template()}',
|
||||
archiving: '#{default_output_template()}'
|
||||
}
|
||||
}"}>
|
||||
<.input
|
||||
field={f[:output_path_template]}
|
||||
type="text"
|
||||
inputclass="font-mono"
|
||||
label="Output path template"
|
||||
help="Must end with .{{ ext }}. See below for more details. The default is good for most cases (required)"
|
||||
x-init="$watch('selectedPreset', p => p && ($el.value = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<h3 class="mt-8 text-2xl text-black dark:text-white">
|
||||
Metadata Options
|
||||
</h3>
|
||||
<.input
|
||||
field={f[:download_metadata]}
|
||||
type="toggle"
|
||||
label="Download Metadata"
|
||||
help="Downloads metadata file alongside media file"
|
||||
/>
|
||||
<.input
|
||||
field={f[:embed_metadata]}
|
||||
type="toggle"
|
||||
label="Embed Metadata"
|
||||
help="Downloads and embeds metadata in the media file itself, if supported. Uneffected by 'Download Metadata' (recommended)"
|
||||
/>
|
||||
<.input
|
||||
field={f[:download_nfo]}
|
||||
type="toggle"
|
||||
label="Download NFO data"
|
||||
help="Downloads NFO data alongside media file for use with Jellyfin, Kodi, etc."
|
||||
/>
|
||||
<h3 class="mt-10 text-2xl text-black dark:text-white">
|
||||
Subtitle Options
|
||||
</h3>
|
||||
|
||||
<h3 class="mt-8 text-2xl text-black dark:text-white">
|
||||
Release Format Options
|
||||
</h3>
|
||||
<section x-data="{ presets: { default: true, media_center: true, audio: false, archiving: true } }">
|
||||
<.input
|
||||
field={f[:download_subs]}
|
||||
type="toggle"
|
||||
label="Download Subtitles"
|
||||
help="Downloads subtitle files alongside media file"
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<.input
|
||||
field={f[:shorts_behaviour]}
|
||||
options={friendly_format_type_options()}
|
||||
type="select"
|
||||
label="Include Shorts?"
|
||||
help="Experimental. Please report any issues on GitHub"
|
||||
/>
|
||||
<.input
|
||||
field={f[:livestream_behaviour]}
|
||||
options={friendly_format_type_options()}
|
||||
type="select"
|
||||
label="Include Livestreams?"
|
||||
help="Excludes media that comes from a past livestream"
|
||||
/>
|
||||
<section x-data="{ presets: { default: false, media_center: false, audio: false, archiving: false } }">
|
||||
<.input
|
||||
field={f[:download_auto_subs]}
|
||||
type="toggle"
|
||||
label="Download Autogenerated Subtitles"
|
||||
help="Prefers normal subs but will download autogenerated if needed. Requires 'Download Subtitles' to be enabled"
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<h3 class="mt-8 text-2xl text-black dark:text-white">
|
||||
Quality Options
|
||||
</h3>
|
||||
<section x-data="{ presets: { default: true, media_center: true, audio: false, archiving: true } }">
|
||||
<.input
|
||||
field={f[:embed_subs]}
|
||||
type="toggle"
|
||||
label="Embed Subtitles"
|
||||
help="Downloads and embeds subtitles in the media file itself, if supported. Uneffected by 'Download Subtitles' (recommended)"
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<.input
|
||||
field={f[:preferred_resolution]}
|
||||
options={friendly_resolution_options()}
|
||||
type="select"
|
||||
label="Preferred Resolution"
|
||||
help="Will grab the closest available resolution if your preferred is not available. 'Audio Only' grabs the highest quality m4a"
|
||||
/>
|
||||
<section x-data="{ presets: { default: 'en', media_center: 'en', audio: '', archiving: 'all' } }">
|
||||
<.input
|
||||
field={f[:sub_langs]}
|
||||
type="text"
|
||||
label="Subtitle Languages"
|
||||
help="Use commas for multiple languages (eg: en,de)"
|
||||
x-init="$watch('selectedPreset', p => p && ($el.value = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<.button class="my-10 sm:mb-7.5 w-full sm:w-auto">Save Media profile</.button>
|
||||
<h3 class="mt-10 text-2xl text-black dark:text-white">
|
||||
Thumbnail Options
|
||||
</h3>
|
||||
|
||||
<section x-data="{ presets: { default: true, media_center: true, audio: false, archiving: true } }">
|
||||
<.input
|
||||
field={f[:download_thumbnail]}
|
||||
type="toggle"
|
||||
label="Download Thumbnail"
|
||||
help="Downloads thumbnail alongside media file"
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section x-data="{ presets: { default: true, media_center: true, audio: true, archiving: true } }">
|
||||
<.input
|
||||
field={f[:embed_thumbnail]}
|
||||
type="toggle"
|
||||
label="Embed Thumbnail"
|
||||
help="Downloads and embeds thumbnail in the media file itself, if supported. Uneffected by 'Download Thumbnail' (recommended)"
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<h3 class="mt-10 text-2xl text-black dark:text-white">
|
||||
Metadata Options
|
||||
</h3>
|
||||
|
||||
<section x-data="{ presets: { default: false, media_center: false, audio: false, archiving: true } }">
|
||||
<.input
|
||||
field={f[:download_metadata]}
|
||||
type="toggle"
|
||||
label="Download Metadata"
|
||||
help="Downloads metadata file alongside media file"
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section x-data="{ presets: { default: true, media_center: true, audio: true, archiving: true } }">
|
||||
<.input
|
||||
field={f[:embed_metadata]}
|
||||
type="toggle"
|
||||
label="Embed Metadata"
|
||||
help="Downloads and embeds metadata in the media file itself, if supported. Uneffected by 'Download Metadata' (recommended)"
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section x-data="{ presets: { default: false, media_center: true, audio: false, archiving: true } }">
|
||||
<.input
|
||||
field={f[:download_nfo]}
|
||||
type="toggle"
|
||||
label="Download NFO data"
|
||||
help="Downloads NFO data alongside media file for use with Jellyfin, Kodi, etc."
|
||||
x-init="$watch('selectedPreset', p => p && (enabled = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<h3 class="mt-10 text-2xl text-black dark:text-white">
|
||||
Release Format Options
|
||||
</h3>
|
||||
|
||||
<section x-data="{ presets: { default: 'include', media_center: 'exclude', audio: 'exclude', archiving: 'include' } }">
|
||||
<.input
|
||||
field={f[:shorts_behaviour]}
|
||||
options={friendly_format_type_options()}
|
||||
type="select"
|
||||
label="Include Shorts?"
|
||||
help="Experimental. Please report any issues on GitHub"
|
||||
x-init="$watch('selectedPreset', p => p && ($el.value = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<section x-data="{ presets: { default: 'exclude', media_center: 'exclude', audio: 'exclude', archiving: 'include' } }">
|
||||
<.input
|
||||
field={f[:livestream_behaviour]}
|
||||
options={friendly_format_type_options()}
|
||||
type="select"
|
||||
label="Include Livestreams?"
|
||||
help="Excludes media that comes from a past livestream"
|
||||
x-init="$watch('selectedPreset', p => p && ($el.value = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<h3 class="mt-10 text-2xl text-black dark:text-white">
|
||||
Quality Options
|
||||
</h3>
|
||||
|
||||
<section x-data="{ presets: { default: '1080p', media_center: '1080p', audio: 'audio', archiving: '2160p' } }">
|
||||
<.input
|
||||
field={f[:preferred_resolution]}
|
||||
options={friendly_resolution_options()}
|
||||
type="select"
|
||||
label="Preferred Resolution"
|
||||
help="Will grab the closest available resolution if your preferred is not available. 'Audio Only' grabs the highest quality m4a"
|
||||
x-init="$watch('selectedPreset', p => p && ($el.value = presets[p]))"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<.button class="my-10 sm:mb-7.5 w-full sm:w-auto">Save Media profile</.button>
|
||||
</section>
|
||||
|
||||
<div class="rounded-sm dark:bg-meta-4 p-4 md:p-6 mb-5">
|
||||
<.output_template_help />
|
||||
|
||||
Reference in New Issue
Block a user