minor changes to newDownload form
This commit is contained in:
parent
93e830f029
commit
260901cfa9
6 changed files with 128 additions and 61 deletions
|
|
@ -18,7 +18,7 @@ from .AsyncPool import AsyncPool
|
|||
from .config import Config
|
||||
from .DataStore import DataStore
|
||||
from .Download import Download
|
||||
from .Events import EventBus, Events
|
||||
from .Events import EventBus, Events, info
|
||||
from .ItemDTO import Item, ItemDTO
|
||||
from .Presets import Presets
|
||||
from .Singleton import Singleton
|
||||
|
|
@ -307,6 +307,14 @@ class DownloadQueue(metaclass=Singleton):
|
|||
dlInfo.info.status = "not_live"
|
||||
itemDownload = self.done.put(dlInfo)
|
||||
NotifyEvent = Events.COMPLETED
|
||||
log_message = f"{dl.title or dl.id or dl._id}: stream is not live yet."
|
||||
if dlInfo.info.live_in:
|
||||
log_message += f" Will start in {dlInfo.info.live_in}."
|
||||
|
||||
await self._notify.emit(
|
||||
Events.LOG_INFO,
|
||||
data=info(msg=log_message, data=itemDownload.info.serialize()),
|
||||
)
|
||||
elif self.config.allow_manifestless is False and is_manifestless is True:
|
||||
dlInfo.info.status = "error"
|
||||
dlInfo.info.error = "Video is in post-live manifestless mode."
|
||||
|
|
|
|||
|
|
@ -309,3 +309,7 @@ hr {
|
|||
.is-auto {
|
||||
unicode-bidi: embed;
|
||||
}
|
||||
|
||||
.is-justify-self-end {
|
||||
justify-self: end;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@
|
|||
</div>
|
||||
<div class="control" v-if="item.status != 'finished' || !item.filename">
|
||||
<button class="button is-warning is-fullwidth is-small" v-tooltip="'Re-queue video'"
|
||||
@click="reQueueItem(item)">
|
||||
@click="(event) => reQueueItem(item, event)">
|
||||
<span class="icon"><i class="fa-solid fa-rotate-right" /></span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
@ -283,7 +283,7 @@
|
|||
</div>
|
||||
<div class="columns is-mobile is-multiline">
|
||||
<div class="column is-half-mobile" v-if="item.status != 'finished' || !item.filename">
|
||||
<a class="button is-warning is-fullwidth" @click="reQueueItem(item)">
|
||||
<a class="button is-warning is-fullwidth" @click="(event) => reQueueItem(item, event)">
|
||||
<span class="icon-text is-block">
|
||||
<span class="icon"><i class="fa-solid fa-rotate-right" /></span>
|
||||
<span>Re-queue</span>
|
||||
|
|
@ -371,13 +371,13 @@
|
|||
import moment from 'moment'
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { makeDownload, formatBytes } from '~/utils/index'
|
||||
import toast from '~/plugins/toast'
|
||||
import { isEmbedable, getEmbedable } from '~/utils/embedable'
|
||||
|
||||
const emitter = defineEmits(['getInfo'])
|
||||
const emitter = defineEmits(['getInfo', 'add_new'])
|
||||
const config = useConfigStore()
|
||||
const stateStore = useStateStore()
|
||||
const socket = useSocketStore()
|
||||
const toast = useToast()
|
||||
|
||||
const selectedElms = ref([])
|
||||
const masterSelectAll = ref(false)
|
||||
|
|
@ -624,9 +624,7 @@ const removeItem = item => {
|
|||
})
|
||||
}
|
||||
|
||||
const reQueueItem = item => {
|
||||
socket.emit('item_delete', { id: item._id, remove_file: false })
|
||||
|
||||
const reQueueItem = (item, event = null) => {
|
||||
let extras = {}
|
||||
|
||||
if (item.extras) {
|
||||
|
|
@ -637,7 +635,7 @@ const reQueueItem = item => {
|
|||
})
|
||||
}
|
||||
|
||||
socket.emit('add_url', {
|
||||
const item_req = {
|
||||
url: item.url,
|
||||
preset: item.preset,
|
||||
folder: item.folder,
|
||||
|
|
@ -645,7 +643,17 @@ const reQueueItem = item => {
|
|||
template: item.template,
|
||||
cli: item?.cli,
|
||||
extras: extras
|
||||
})
|
||||
};
|
||||
|
||||
socket.emit('item_delete', { id: item._id, remove_file: false })
|
||||
|
||||
if (event && (event?.altKey && true === event?.altKey)) {
|
||||
toast.info('Removed the item from history, and added it to the new download form.')
|
||||
emitter('add_new', item_req)
|
||||
return
|
||||
}
|
||||
|
||||
socket.emit('add_url', item_req)
|
||||
}
|
||||
|
||||
const pImg = e => e.target.naturalHeight > e.target.naturalWidth ? e.target.classList.add('image-portrait') : null
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" id="url" placeholder="Video or playlist link"
|
||||
:disabled="!socket.isConnected || addInProgress" v-model="url">
|
||||
:disabled="!socket.isConnected || addInProgress" v-model="form.url">
|
||||
</div>
|
||||
<span class="help">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
<div class="control is-expanded">
|
||||
<div class="select is-fullwidth">
|
||||
<select id="preset" class="is-fullwidth"
|
||||
:disabled="!socket.isConnected || addInProgress || hasFormatInConfig" v-model="selectedPreset"
|
||||
:disabled="!socket.isConnected || addInProgress || hasFormatInConfig" v-model="form.preset"
|
||||
v-tooltip.bottom="hasFormatInConfig ? 'Presets are disabled. Format key is present in the Command arguments for yt-dlp.' : ''">
|
||||
<optgroup label="Custom presets" v-if="config?.presets.filter(p => !p?.default).length > 0">
|
||||
<option v-for="item in filter_presets(false)" :key="item.name" :value="item.name">
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
</a>
|
||||
</div>
|
||||
<div class="control is-expanded">
|
||||
<input type="text" class="input is-fullwidth" id="path" v-model="downloadPath" placeholder="Default"
|
||||
<input type="text" class="input is-fullwidth" id="path" v-model="form.folder" placeholder="Default"
|
||||
:disabled="!socket.isConnected || addInProgress" list="folders">
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -63,7 +63,7 @@
|
|||
<div class="column">
|
||||
<button type="submit" class="button is-primary"
|
||||
:class="{ 'is-loading': !socket.isConnected || addInProgress }"
|
||||
:disabled="!socket.isConnected || addInProgress || !url">
|
||||
:disabled="!socket.isConnected || addInProgress || !form?.url">
|
||||
<span class="icon"><i class="fa-solid fa-plus" /></span>
|
||||
<span>Add</span>
|
||||
</button>
|
||||
|
|
@ -85,7 +85,7 @@
|
|||
Output Template
|
||||
</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" v-model="output_template" id="output_format"
|
||||
<input type="text" class="input" v-model="form.template" id="output_format"
|
||||
:disabled="!socket.isConnected || addInProgress"
|
||||
placeholder="Uses default output template naming if empty.">
|
||||
</div>
|
||||
|
|
@ -104,7 +104,7 @@
|
|||
Command arguments for yt-dlp
|
||||
</label>
|
||||
<div class="control">
|
||||
<textarea class="textarea is-pre" v-model="ytdlp_cli" id="cli_options"
|
||||
<textarea class="textarea is-pre" v-model="form.cli" id="cli_options"
|
||||
:disabled="!socket.isConnected || addInProgress"
|
||||
placeholder="command options to use, e.g. --no-embed-metadata --no-embed-thumbnail" />
|
||||
</div>
|
||||
|
|
@ -127,7 +127,7 @@
|
|||
Cookies
|
||||
</label>
|
||||
<div class="control">
|
||||
<textarea class="textarea is-pre" id="ytdlpCookies" v-model="ytdlpCookies"
|
||||
<textarea class="textarea is-pre" id="ytdlpCookies" v-model="form.cookies"
|
||||
:disabled="!socket.isConnected || addInProgress" />
|
||||
</div>
|
||||
<span class="help">
|
||||
|
|
@ -140,21 +140,20 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="column is-6-tablet is-4-mobile has-text-left">
|
||||
<button type="button" class="button is-info" @click="emitter('getInfo', url)"
|
||||
:class="{ 'is-loading': !socket.isConnected }" :disabled="!socket.isConnected || addInProgress || !url">
|
||||
<button type="button" class="button is-info" @click="emitter('getInfo', form.url)"
|
||||
:class="{ 'is-loading': !socket.isConnected }"
|
||||
:disabled="!socket.isConnected || addInProgress || !form?.url">
|
||||
<span class="icon"><i class="fa-solid fa-info" /></span>
|
||||
<span>Information</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="column is-6-tablet is-6-mobile has-text-right">
|
||||
<div class="field">
|
||||
<div class="field is-grouped is-justify-self-end">
|
||||
<div class="control">
|
||||
<button type="button" 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 Configuration</span>
|
||||
<button type="button" class="button is-danger" @click="resetConfig"
|
||||
:disabled="!socket.isConnected || form?.id" v-tooltip="'Reset local settings'">
|
||||
<span class="icon"><i class="fa-solid fa-rotate-left" /></span>
|
||||
<span>Reset</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -172,24 +171,35 @@
|
|||
<script setup>
|
||||
import { useStorage } from '@vueuse/core'
|
||||
|
||||
const emitter = defineEmits(['getInfo'])
|
||||
const props = defineProps({
|
||||
item: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => { },
|
||||
},
|
||||
})
|
||||
|
||||
const emitter = defineEmits(['getInfo', 'clear_form'])
|
||||
const config = useConfigStore()
|
||||
const socket = useSocketStore()
|
||||
const toast = useToast()
|
||||
|
||||
const selectedPreset = useStorage('selectedPreset', config.app.default_preset)
|
||||
const ytdlpCookies = useStorage('ytdlp_cookies', '')
|
||||
const ytdlp_cli = useStorage('ytdlp_cli', '')
|
||||
const output_template = useStorage('output_template', null)
|
||||
const downloadPath = useStorage('downloadPath', null)
|
||||
const url = useStorage('downloadUrl', null)
|
||||
const showAdvanced = useStorage('show_advanced', false)
|
||||
const addInProgress = ref(false)
|
||||
|
||||
const form = useStorage('local_config', {
|
||||
id: null,
|
||||
url: '',
|
||||
preset: config.app.default_preset,
|
||||
cookies: '',
|
||||
cli: '',
|
||||
template: '',
|
||||
folder: '',
|
||||
})
|
||||
|
||||
const addDownload = async () => {
|
||||
// -- send request to convert cli options to JSON
|
||||
if (ytdlp_cli.value && '' !== ytdlp_cli.value) {
|
||||
const options = await convertOptions(ytdlp_cli.value)
|
||||
if (form.value?.cli && '' !== form.value.cli) {
|
||||
const options = await convertOptions(form.value.cli)
|
||||
if (null === options) {
|
||||
return
|
||||
}
|
||||
|
|
@ -197,17 +207,17 @@ const addDownload = async () => {
|
|||
|
||||
addInProgress.value = true
|
||||
|
||||
url.value.split(',').forEach(url => {
|
||||
form.value.url.split(',').forEach(url => {
|
||||
if (!url.trim()) {
|
||||
return
|
||||
}
|
||||
socket.emit('add_url', {
|
||||
url: url,
|
||||
preset: config.app.basic_mode ? config.app.default_preset : selectedPreset.value,
|
||||
folder: config.app.basic_mode ? null : downloadPath.value,
|
||||
cookies: config.app.basic_mode ? '' : ytdlpCookies.value,
|
||||
template: config.app.basic_mode ? null : output_template.value,
|
||||
cli: config.app.basic_mode ? null : ytdlp_cli.value,
|
||||
preset: config.app.basic_mode ? config.app.default_preset : form.value.preset,
|
||||
folder: config.app.basic_mode ? null : form.value.folder,
|
||||
template: config.app.basic_mode ? null : form.value.template,
|
||||
cookies: config.app.basic_mode ? '' : form.value.cookies,
|
||||
cli: config.app.basic_mode ? null : form.value.cli,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
@ -217,12 +227,16 @@ const resetConfig = () => {
|
|||
return
|
||||
}
|
||||
|
||||
selectedPreset.value = config.app.default_preset
|
||||
ytdlpCookies.value = ''
|
||||
ytdlp_cli.value = ''
|
||||
output_template.value = null
|
||||
url.value = null
|
||||
downloadPath.value = null
|
||||
form.value = {
|
||||
id: null,
|
||||
url: '',
|
||||
preset: config.app.default_preset,
|
||||
cookies: '',
|
||||
cli: '',
|
||||
template: '',
|
||||
folder: '',
|
||||
}
|
||||
|
||||
showAdvanced.value = false
|
||||
|
||||
toast.success('Local configuration has been reset.')
|
||||
|
|
@ -238,7 +252,7 @@ const statusHandler = async stream => {
|
|||
return
|
||||
}
|
||||
|
||||
url.value = ''
|
||||
form.value.url = ''
|
||||
}
|
||||
|
||||
const unlockDownload = async stream => {
|
||||
|
|
@ -246,7 +260,7 @@ const unlockDownload = async stream => {
|
|||
if (!json?.data) {
|
||||
return
|
||||
}
|
||||
if ("unlock" in json.data && json.data.unlock === true) {
|
||||
if ("unlock" in json.data && true === json.data.unlock) {
|
||||
addInProgress.value = false
|
||||
}
|
||||
}
|
||||
|
|
@ -256,11 +270,11 @@ const convertOptions = async args => {
|
|||
const response = await convertCliOptions(args)
|
||||
|
||||
if (response.output_template) {
|
||||
output_template.value = response.output_template
|
||||
form.value.template = response.output_template
|
||||
}
|
||||
|
||||
if (response.download_path) {
|
||||
downloadPath.value = response.download_path
|
||||
form.value.folder = response.download_path
|
||||
}
|
||||
|
||||
return response.opts
|
||||
|
|
@ -271,11 +285,24 @@ const convertOptions = async args => {
|
|||
return null;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
socket.on('status', statusHandler)
|
||||
socket.on('error', unlockDownload)
|
||||
if ('' === selectedPreset.value) {
|
||||
selectedPreset.value = config.app.default_preset.value
|
||||
|
||||
await nextTick()
|
||||
|
||||
if ('' === form.value?.preset) {
|
||||
form.value.preset = config.app.default_preset
|
||||
}
|
||||
|
||||
if (props?.item) {
|
||||
Object.keys(props.item).forEach(key => {
|
||||
console.log(key, form.value[key], props.item[key])
|
||||
if (key in form.value) {
|
||||
form.value[key] = props.item[key]
|
||||
}
|
||||
})
|
||||
emitter('clear_form');
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -285,11 +312,11 @@ onUnmounted(() => {
|
|||
})
|
||||
|
||||
const hasFormatInConfig = computed(() => {
|
||||
if (!ytdlp_cli.value) {
|
||||
if (!form?.value?.value) {
|
||||
return false
|
||||
}
|
||||
|
||||
return /(?<!\S)(-f|--format)(=|\s)(\S+)/.test(ytdlp_cli.value)
|
||||
return /(?<!\S)(-f|--format)(=|\s)(\S+)/.test(form.value.cli)
|
||||
})
|
||||
|
||||
const filter_presets = (flag = true) => config.presets.filter(item => item.default === flag)
|
||||
|
|
|
|||
|
|
@ -43,11 +43,13 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
const props = defineProps({
|
||||
error: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const showStacks = ref(false)
|
||||
|
||||
onMounted(() => console.error(props.error))
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@
|
|||
</p>
|
||||
|
||||
<p class="control" v-if="!config.app.basic_mode">
|
||||
<button v-tooltip.bottom="'Toggle Add Form'" class="button is-primary has-tooltip-bottom"
|
||||
<button v-tooltip.bottom="'Toggle new download form'" class="button is-primary has-tooltip-bottom"
|
||||
@click="config.showForm = !config.showForm">
|
||||
<span class="icon"><i class="fa-solid fa-plus" /></span>
|
||||
</button>
|
||||
|
|
@ -73,9 +73,10 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<NewDownload v-if="config.showForm || config.app.basic_mode" @getInfo="url => get_info = url" />
|
||||
<NewDownload v-if="config.showForm || config.app.basic_mode" @getInfo="url => get_info = url" :item="item_form"
|
||||
@clear_form="item_form = {}" />
|
||||
<Queue @getInfo="url => get_info = url" />
|
||||
<History @getInfo="url => get_info = url" />
|
||||
<History @getInfo="url => get_info = url" @add_new="item => toNewDownload(item)" />
|
||||
<GetInfo v-if="get_info" :link="get_info" @closeModel="get_info = ''" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -94,6 +95,7 @@ const get_info = ref('')
|
|||
const bg_enable = useStorage('random_bg', true)
|
||||
const bg_opacity = useStorage('random_bg_opacity', 0.85)
|
||||
const display_style = useStorage('display_style', 'cards')
|
||||
const item_form = ref({})
|
||||
|
||||
onMounted(() => {
|
||||
if (!config.app.ui_update_title) {
|
||||
|
|
@ -159,4 +161,20 @@ watch(get_info, v => {
|
|||
})
|
||||
|
||||
const changeDisplay = () => display_style.value = display_style.value === 'cards' ? 'list' : 'cards'
|
||||
|
||||
const toNewDownload = async (item) => {
|
||||
if (!item) {
|
||||
return
|
||||
}
|
||||
|
||||
if (config.showForm) {
|
||||
config.showForm = false
|
||||
await nextTick()
|
||||
}
|
||||
|
||||
item_form.value = item
|
||||
|
||||
await nextTick()
|
||||
config.showForm = true
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in a new issue