Added Basic mode for WebUI & added new env var for selecting default preset.
This commit is contained in:
parent
bd065692fc
commit
b1388eff6b
10 changed files with 78 additions and 34 deletions
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
|
|
@ -41,6 +41,8 @@
|
|||
"YTP_LOG_LEVEL": "DEBUG",
|
||||
"YTP_DEBUG": "true",
|
||||
"YTP_YTDL_DEBUG": "false",
|
||||
"YTP_BASIC_MODE": "true",
|
||||
"YTP_DEFAULT_PRESET": "Best video and audio",
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ YTPTube started as a fork of [meTube](https://github.com/alexta69/metube), Since
|
|||
* Queue multiple URLs separated by comma.
|
||||
* Basic Authentication support.
|
||||
* Support for curl_cffi, see [yt-dlp documentation](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#impersonation)
|
||||
* Support for both advanced and basic mode for WebUI.
|
||||
|
||||
### Tips
|
||||
Your `yt-dlp` config should include the following options for optimal working conditions.
|
||||
|
|
@ -94,6 +95,8 @@ Certain values can be set via environment variables, using the `-e` parameter on
|
|||
* __YTP_UI_UPDATE_TITLE__: Whether to update the title of the page with the current stats. Defaults to `true`.
|
||||
* __YTP_PIP_PACKAGES__: a space separated list of pip packages to install. Defaults to `""`, you can also use `{config_path}/pip.txt` to install the packages.
|
||||
* __YTP_PIP_IGNORE_UPDATES__: Do not update the custom pip packages. Defaults to `false`.
|
||||
* __YTP_BASIC_MODE__: Whether to run WebUI in basic mode. Defaults to `false`. In basic mode, A minimal UI will be shown, the majority of the features will be disabled.
|
||||
* __YTP_DEFAULT_PRESET__: The default preset to use for the download. Defaults to `default`.
|
||||
|
||||
## Running behind a reverse proxy
|
||||
|
||||
|
|
|
|||
|
|
@ -69,10 +69,14 @@ class Config:
|
|||
ytdlp_version: str = YTDLP_VERSION
|
||||
started: int = 0
|
||||
ignore_ui: bool = False
|
||||
basic_mode: bool = False
|
||||
|
||||
presets: list = [
|
||||
{"name": "default", "format": "default"},
|
||||
]
|
||||
|
||||
default_preset: str = "default"
|
||||
|
||||
_manual_vars: tuple = (
|
||||
"temp_path",
|
||||
"config_path",
|
||||
|
|
@ -108,6 +112,7 @@ class Config:
|
|||
"ignore_ui",
|
||||
"ui_update_title",
|
||||
"pip_ignore_updates",
|
||||
"basic_mode",
|
||||
)
|
||||
|
||||
_frontend_vars: tuple = (
|
||||
|
|
@ -122,6 +127,8 @@ class Config:
|
|||
"remove_files",
|
||||
"ui_update_title",
|
||||
"max_workers",
|
||||
"basic_mode",
|
||||
"default_preset",
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
|
@ -286,6 +293,9 @@ class Config:
|
|||
if self.auth_password and self.auth_username:
|
||||
LOG.warning(f"Basic authentication enabled with username '{self.auth_username}'.")
|
||||
|
||||
if self.basic_mode:
|
||||
LOG.info("The frontend is running in basic mode.")
|
||||
|
||||
self.started = time.time()
|
||||
|
||||
def _getAttributes(self) -> dict:
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@
|
|||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="column is-half-mobile" v-if="item.url">
|
||||
<div class="column is-half-mobile" v-if="item.url && !config.app.basic_mode">
|
||||
<button class="button is-info is-fullwidth" @click="emitter('getInfo', item.url)">
|
||||
<span class="icon-text is-block">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-4-tablet is-12-mobile">
|
||||
<div class="column is-4-tablet is-12-mobile" v-if="!config.app.basic_mode">
|
||||
<div class="field has-addons">
|
||||
<div class="control">
|
||||
<a href="#" class="button is-static">Preset</a>
|
||||
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column is-6-tablet is-12-mobile">
|
||||
<div class="column is-6-tablet is-12-mobile" v-if="!config.app.basic_mode">
|
||||
<div class="field has-addons" v-tooltip="'Folder relative to ' + config.app.download_path">
|
||||
<div class="control">
|
||||
<a href="#" class="button is-static">Save in</a>
|
||||
|
|
@ -47,7 +47,20 @@
|
|||
<span>Add</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="column has-text-right" v-if="config.app.basic_mode">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button type="submit" class="button is-danger" @click="resetConfig" :disabled="!socket.isConnected"
|
||||
v-tooltip="'This configuration are stored locally in your browser.'">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-trash" />
|
||||
</span>
|
||||
<span>Reset Local Config</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="column" v-if="!config.app.basic_mode">
|
||||
<button type="submit" class="button is-info" @click="showAdvanced = !showAdvanced"
|
||||
:class="{ 'is-loading': !socket.isConnected }" :disabled="!socket.isConnected">
|
||||
<span class="icon"><i class="fa-solid fa-cog" /></span>
|
||||
|
|
@ -55,7 +68,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="columns is-multiline is-mobile" v-if="showAdvanced">
|
||||
<div class="columns is-multiline is-mobile" v-if="showAdvanced && !config.app.basic_mode">
|
||||
<div class="column is-12">
|
||||
<div class="field">
|
||||
<label class="label is-inline" for="output_format"
|
||||
|
|
@ -139,11 +152,11 @@
|
|||
import { useStorage } from '@vueuse/core'
|
||||
|
||||
const emitter = defineEmits(['getInfo'])
|
||||
const config = useConfigStore();
|
||||
const socket = useSocketStore();
|
||||
const toast = useToast();
|
||||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
const toast = useToast()
|
||||
|
||||
const selectedPreset = useStorage('selectedPreset', '')
|
||||
const selectedPreset = useStorage('selectedPreset', config.app.default_preset)
|
||||
const ytdlpConfig = useStorage('ytdlp_config', '')
|
||||
const ytdlpCookies = useStorage('ytdlp_cookies', '')
|
||||
const output_template = useStorage('output_template', null)
|
||||
|
|
@ -153,36 +166,36 @@ const showAdvanced = useStorage('show_advanced', false)
|
|||
const addInProgress = ref(false)
|
||||
|
||||
const addDownload = () => {
|
||||
addInProgress.value = true;
|
||||
addInProgress.value = true
|
||||
url.value.split(',').forEach(url => {
|
||||
if (!url.trim()) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
socket.emit('add_url', {
|
||||
url: url,
|
||||
preset: selectedPreset.value,
|
||||
preset: config.app.basic_mode ? config.app.default_preset : selectedPreset.value,
|
||||
folder: downloadPath.value,
|
||||
ytdlp_config: ytdlpConfig.value,
|
||||
ytdlp_cookies: ytdlpCookies.value,
|
||||
output_template: output_template.value,
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const resetConfig = () => {
|
||||
if (true !== confirm('Reset your local configuration?')) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
selectedPreset.value = 'default';
|
||||
ytdlpConfig.value = '';
|
||||
ytdlpCookies.value = '';
|
||||
output_template.value = null;
|
||||
url.value = null;
|
||||
downloadPath.value = null;
|
||||
showAdvanced.value = false;
|
||||
selectedPreset.value = config.app.default_preset.value
|
||||
ytdlpConfig.value = ''
|
||||
ytdlpCookies.value = ''
|
||||
output_template.value = null
|
||||
url.value = null
|
||||
downloadPath.value = null
|
||||
showAdvanced.value = false
|
||||
|
||||
toast.success('Local configuration has been reset.');
|
||||
toast.success('Local configuration has been reset.')
|
||||
}
|
||||
|
||||
const statusHandler = async data => {
|
||||
|
|
@ -195,13 +208,13 @@ const statusHandler = async data => {
|
|||
return
|
||||
}
|
||||
|
||||
url.value = '';
|
||||
url.value = ''
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
socket.on('status', statusHandler)
|
||||
if ('' === selectedPreset.value) {
|
||||
selectedPreset.value = 'default'
|
||||
selectedPreset.value = config.app.default_preset.value
|
||||
}
|
||||
})
|
||||
onUnmounted(() => socket.off('status', statusHandler))
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@
|
|||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="column is-half-mobile" v-if="item.url">
|
||||
<div class="column is-half-mobile" v-if="item.url && !config.app.basic_mode">
|
||||
<button class="button is-info is-fullwidth" @click="emitter('getInfo', item.url)">
|
||||
<span class="icon-text is-block">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@
|
|||
</div>
|
||||
<div class="navbar-end is-flex">
|
||||
|
||||
<div class="navbar-item" v-if="socket.isConnected && config.app.has_cookies">
|
||||
<div class="navbar-item" v-if="socket.isConnected && config.app.has_cookies && !config.app.basic_mode">
|
||||
<button class="button is-dark" @click="checkCookies" v-tooltip="'Check youtube cookies status.'"
|
||||
:disabled="isChecking">
|
||||
<span class="icon has-text-info"><i class="fas fa-cookie"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-item" v-if="socket.isConnected">
|
||||
<div class="navbar-item" v-if="socket.isConnected && !config.app.basic_mode">
|
||||
<button class="button is-dark" @click="pauseDownload" v-if="false === config.paused"
|
||||
v-tooltip="'Pause non-active downloads.'">
|
||||
<span class="icon has-text-warning"><i class="fas fa-pause"></i></span>
|
||||
|
|
@ -29,20 +29,20 @@
|
|||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-item">
|
||||
<div class="navbar-item" v-if="!config.app.basic_mode">
|
||||
<NuxtLink class="button is-dark has-tooltip-bottom" to="/console" v-tooltip.bottom="'Terminal'">
|
||||
<span class="icon"><i class="fa-solid fa-terminal" /></span>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
|
||||
<div class="navbar-item">
|
||||
<div class="navbar-item" v-if="!config.app.basic_mode">
|
||||
<button v-tooltip.bottom="'Toggle Add Form'" class="button is-dark has-tooltip-bottom"
|
||||
@click="config.showForm = !config.showForm">
|
||||
<span class="icon"><i class="fa-solid fa-plus" /></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="navbar-item" v-if="config.tasks.length > 0" v-tooltip.bottom="'Tasks'">
|
||||
<div class="navbar-item" v-if="!config.app.basic_mode && config.tasks.length > 0" v-tooltip.bottom="'Tasks'">
|
||||
<NuxtLink class="button is-dark has-tooltip-bottom" to="/tasks">
|
||||
<span class="icon"><i class="fa-solid fa-tasks" /></span>
|
||||
</NuxtLink>
|
||||
|
|
@ -67,7 +67,7 @@
|
|||
</div>
|
||||
</nav>
|
||||
|
||||
<NewDownload v-if="config.showForm" @getInfo="url => get_info = url" />
|
||||
<NewDownload v-if="config.showForm || config.app.basic_mode" @getInfo="url => get_info = url" />
|
||||
<NuxtPage @getInfo="url => get_info = url" />
|
||||
<GetInfo v-if="get_info" :link="get_info" @closeModel="get_info = ''" />
|
||||
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const command = ref('')
|
|||
const terminal_window = ref()
|
||||
const command_input = ref()
|
||||
const isLoading = ref(false)
|
||||
|
||||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
|
||||
watch(() => isLoading.value, async value => {
|
||||
|
|
@ -149,6 +149,13 @@ const writer = s => {
|
|||
|
||||
const loader = () => isLoading.value = false
|
||||
|
||||
watch(() => config.app.basic_mode, async () => {
|
||||
if (!config.app.basic_mode) {
|
||||
return
|
||||
}
|
||||
await navigateTo('/')
|
||||
})
|
||||
|
||||
onMounted(async () => {
|
||||
window.addEventListener('resize', reSizeTerminal);
|
||||
focusInput()
|
||||
|
|
|
|||
|
|
@ -64,4 +64,11 @@ div.table-container {
|
|||
import moment from 'moment'
|
||||
import { parseExpression } from 'cron-parser'
|
||||
const config = useConfigStore()
|
||||
|
||||
watch(() => config.app.basic_mode, async () => {
|
||||
if (!config.app.basic_mode) {
|
||||
return
|
||||
}
|
||||
await navigateTo('/')
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -14,10 +14,12 @@ const CONFIG_KEYS = {
|
|||
url_host: '',
|
||||
url_prefix: '',
|
||||
has_cookies: false,
|
||||
basic_mode: true,
|
||||
default_preset: 'default',
|
||||
},
|
||||
presets: [
|
||||
{
|
||||
'name': 'Default',
|
||||
'name': 'default',
|
||||
'format': 'default'
|
||||
}
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in a new issue