feat(downloader): tier-limited classification, config defaults, yt-dlp support

- Classify Patreon "Not allowed to view post" warnings as TIER_LIMITED so
  subscription-gated runs are distinguished from genuine failures, and persist
  error_type/message on completed runs so the distinction survives to the UI.
- Fold PLATFORM_DEFAULTS into _get_default_config so gallery-dl.conf is a
  complete, editable document; _build_config_for_source now preserves the
  user's conf and only re-seeds missing platform sections.
- Add Reset-to-Defaults action in Settings (vs. Revert Changes which just
  reloads disk); show info banner when no gallery-dl.conf exists yet.
- Fix Discord embeds option: must be "all" string, not bool (gallery-dl
  iterates the value).
- Install yt-dlp + ffmpeg in Docker images so Patreon/Mux HLS video posts
  download instead of logging "Cannot import yt-dlp" and skipping.
- Recognize yt-dlp import failures as per-item errors so they don't mask
  TIER_LIMITED/NO_NEW_CONTENT classification.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 19:32:44 -04:00
parent f747750f97
commit 86bf43c80a
10 changed files with 435 additions and 48 deletions
+8 -1
View File
@@ -27,7 +27,7 @@ export const useSettingsStore = defineStore('settings', () => {
async function fetchGalleryDLConfig() {
const response = await settingsApi.getGalleryDL()
galleryDLConfig.value = response.data.config
return response.data.config
return response.data
}
async function updateGalleryDLConfig(config) {
@@ -36,6 +36,12 @@ export const useSettingsStore = defineStore('settings', () => {
return response.data.config
}
async function resetGalleryDLConfig() {
const response = await settingsApi.resetGalleryDL()
galleryDLConfig.value = response.data.config
return response.data.config
}
return {
settings,
galleryDLConfig,
@@ -44,5 +50,6 @@ export const useSettingsStore = defineStore('settings', () => {
updateSettings,
fetchGalleryDLConfig,
updateGalleryDLConfig,
resetGalleryDLConfig,
}
})
+63 -3
View File
@@ -184,6 +184,16 @@
Invalid configuration may cause downloads to fail.
</v-alert>
<v-alert
v-if="configIsDefault"
type="info"
variant="tonal"
class="mb-4"
density="compact"
>
No gallery-dl.conf found on disk. Showing computed defaults — click Save Configuration to persist.
</v-alert>
<v-textarea
v-model="galleryDLConfigText"
label="gallery-dl.conf (JSON)"
@@ -205,12 +215,20 @@
Documentation
</v-btn>
<v-spacer />
<v-btn
variant="text"
color="warning"
@click="resetConfigDialog = true"
:disabled="savingConfig"
>
Reset to Defaults
</v-btn>
<v-btn
variant="text"
@click="loadGalleryDLConfig"
:disabled="savingConfig"
>
Reset
Revert Changes
</v-btn>
<v-btn
color="primary"
@@ -223,6 +241,27 @@
</v-card-actions>
</v-card>
<v-dialog v-model="resetConfigDialog" max-width="500">
<v-card>
<v-card-title>Reset to Defaults?</v-card-title>
<v-card-text>
This overwrites gallery-dl.conf with computed defaults, replacing any
customizations. Use this to recover after misconfiguring the file.
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn variant="text" @click="resetConfigDialog = false">Cancel</v-btn>
<v-btn
color="warning"
:loading="resettingConfig"
@click="resetGalleryDLConfigToDefaults"
>
Reset
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<!-- Platform Default Settings -->
<v-card class="mb-6">
<v-card-title>
@@ -414,6 +453,9 @@ const savingConfig = ref(false)
const settings = ref({})
const galleryDLConfigText = ref('')
const configError = ref('')
const configIsDefault = ref(false)
const resetConfigDialog = ref(false)
const resettingConfig = ref(false)
const platforms = ref({})
const apiHealthy = ref(true)
const showApiKey = ref(false)
@@ -492,8 +534,9 @@ async function saveSettings() {
async function loadGalleryDLConfig() {
try {
const config = await settingsStore.fetchGalleryDLConfig()
galleryDLConfigText.value = JSON.stringify(config, null, 2)
const data = await settingsStore.fetchGalleryDLConfig()
galleryDLConfigText.value = JSON.stringify(data.config, null, 2)
configIsDefault.value = data.is_default === true
configError.value = ''
} catch (error) {
notifications.error(`Failed to load config: ${error.message}`)
@@ -516,6 +559,7 @@ async function saveGalleryDLConfig() {
try {
const config = JSON.parse(galleryDLConfigText.value)
await settingsStore.updateGalleryDLConfig(config)
configIsDefault.value = false
notifications.success('Gallery-dl configuration saved')
} catch (error) {
notifications.error(`Failed to save: ${error.message}`)
@@ -524,6 +568,22 @@ async function saveGalleryDLConfig() {
}
}
async function resetGalleryDLConfigToDefaults() {
resettingConfig.value = true
try {
const config = await settingsStore.resetGalleryDLConfig()
galleryDLConfigText.value = JSON.stringify(config, null, 2)
configIsDefault.value = false
configError.value = ''
resetConfigDialog.value = false
notifications.success('Gallery-dl configuration reset to defaults')
} catch (error) {
notifications.error(`Failed to reset: ${error.message}`)
} finally {
resettingConfig.value = false
}
}
async function loadPlatforms() {
try {
const response = await platformsApi.list()