Merge pull request #107 from arabcoders/dev
Added option to archive failing download from WebUI
This commit is contained in:
commit
7d34eeb3a9
4 changed files with 67 additions and 24 deletions
21
app/main.py
21
app/main.py
|
|
@ -9,7 +9,7 @@ import selectors
|
|||
import time
|
||||
from Config import Config
|
||||
from DownloadQueue import DownloadQueue
|
||||
from Utils import ObjectSerializer, Notifier, load_file
|
||||
from Utils import ObjectSerializer, Notifier, isDownloaded, load_file
|
||||
from aiohttp import web, client
|
||||
from aiohttp.web import Request, Response
|
||||
from Webhooks import Webhooks
|
||||
|
|
@ -550,6 +550,25 @@ class Main:
|
|||
})
|
||||
await self.sio.emit('cli_close', {'exitcode': -1})
|
||||
|
||||
@self.sio.event()
|
||||
async def archive_item(sid, data):
|
||||
if not isinstance(data, dict) or 'url' not in data or not self.config.keep_archive:
|
||||
return
|
||||
|
||||
file: str = self.config.ytdl_options.get('download_archive', None)
|
||||
|
||||
if not file:
|
||||
return
|
||||
|
||||
exists, idDict = isDownloaded(file, data['url'])
|
||||
if exists or 'archive_id' not in idDict or idDict['archive_id'] is None:
|
||||
return
|
||||
|
||||
with open(file, 'a') as f:
|
||||
f.write(f"{idDict['archive_id']}\n")
|
||||
|
||||
LOG.info(f'Archiving item: {data["url"]=}')
|
||||
|
||||
@self.sio.event()
|
||||
async def connect(sid, environ):
|
||||
await self.connect(sid, environ)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<pageTasks v-if="showTasks" :tasks="config.tasks" />
|
||||
<DownloadingList :config="config" :queue="downloading" @deleteItem="deleteItem" />
|
||||
<PageCompleted :config="config" :completed="completed" @deleteItem="deleteItem" @addItem="addItem"
|
||||
@playItem="playItem" />
|
||||
@playItem="playItem" @archiveItem="archiveItem" />
|
||||
</template>
|
||||
|
||||
<div class="modal is-active" v-if="video_link">
|
||||
|
|
@ -64,6 +64,18 @@ const runCommand = (args) => {
|
|||
socket.value.emit('cli_post', args);
|
||||
}
|
||||
|
||||
const sendData = (type, data, stringify = false) => {
|
||||
if (!socket.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (true === Boolean(stringify)) {
|
||||
data = JSON.stringify(data);
|
||||
}
|
||||
|
||||
socket.value.emit(type, data);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
socket.value = io(process.env.VUE_APP_BASE_URL, {
|
||||
path: document.location.pathname + 'socket.io',
|
||||
|
|
@ -141,12 +153,17 @@ onMounted(() => {
|
|||
});
|
||||
|
||||
socket.value.on('cli_close', () => cli_isLoading.value = false);
|
||||
socket.value.on('cli_output', stream => {
|
||||
cli_output.value.push(stream)
|
||||
console.log(stream);
|
||||
});
|
||||
socket.value.on('cli_output', s => cli_output.value.push(s));
|
||||
});
|
||||
|
||||
const archiveItem = (type, item) => {
|
||||
if (!confirm(`Archive '${item.title ?? item.id ?? item.url ?? '??'}'?`)){
|
||||
return
|
||||
}
|
||||
sendData('archive_item', item);
|
||||
deleteItem(type, item._id);
|
||||
}
|
||||
|
||||
const deleteItem = (type, item) => {
|
||||
const items = []
|
||||
|
||||
|
|
@ -234,5 +251,4 @@ bus.on((event, data) => {
|
|||
setTimeout(() => bus.emit('task_edit', data), 500);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -77,15 +77,22 @@
|
|||
|
||||
<div class="columns is-multiline">
|
||||
<LazyLoader :unrender="true" :min-height="210" class="column is-6" v-for="item in sortCompleted" :key="item._id">
|
||||
<div class="card" :class="{ 'is-bordered-danger': item.status === 'error', 'is-bordered-info': item.live_in || item.is_live }">
|
||||
<header class="card-header has-tooltip" v-tooltip="item.title">
|
||||
<div class="card-header-title has-text-centered is-text-overflow is-block">
|
||||
<div class="card"
|
||||
:class="{ 'is-bordered-danger': item.status === 'error', 'is-bordered-info': item.live_in || item.is_live }">
|
||||
<header class="card-header has-tooltip">
|
||||
<div class="card-header-title is-text-overflow is-block" v-tooltip="item.title">
|
||||
<a v-if="item.filename" referrerpolicy="no-referrer" :href="makeDownload(config, item, 'm3u8')"
|
||||
@click.prevent="$emit('playItem', item)">
|
||||
{{ item.title }}
|
||||
</a>
|
||||
<span v-else>{{ item.title }}</span>
|
||||
</div>
|
||||
<div class="card-header-icon" v-if="item.filename">
|
||||
<a :href="makeDownload(config, item)" :download="item.filename?.split('/').reverse()[0]" class="has-text-primary"
|
||||
v-tooltip="'Download item.'">
|
||||
<span class="icon"><font-awesome-icon icon="fa-solid fa-download" /></span>
|
||||
</a>
|
||||
</div>
|
||||
</header>
|
||||
<div class="card-content">
|
||||
<div class="columns is-mobile is-multiline">
|
||||
|
|
@ -154,17 +161,6 @@
|
|||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="column is-half-mobile" v-if="item.filename">
|
||||
<a class="button is-fullwidth is-primary" :href="makeDownload(config, item)"
|
||||
:download="item.filename?.split('/').reverse()[0]">
|
||||
<span class="icon-text is-block">
|
||||
<span class="icon">
|
||||
<font-awesome-icon icon="fa-solid fa-download" />
|
||||
</span>
|
||||
<span>Download</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="column is-half-mobile">
|
||||
<a class="button is-danger is-fullwidth" @click="$emit('deleteItem', 'completed', item._id)">
|
||||
<span class="icon-text is-block">
|
||||
|
|
@ -175,6 +171,17 @@
|
|||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="column is-half-mobile" v-if="config.app?.keep_archive && item.status != 'finished'">
|
||||
<a class="button is-danger is-light is-fullwidth" v-tooltip="'Add link to archive.'"
|
||||
@click="$emit('archiveItem', 'completed', item)">
|
||||
<span class="icon-text is-block">
|
||||
<span class="icon">
|
||||
<font-awesome-icon icon="fa-solid fa-box-archive" />
|
||||
</span>
|
||||
<span>Archive</span>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="column is-half-mobile">
|
||||
<a referrerpolicy="no-referrer" class="button is-link is-fullwidth" target="_blank" :href="item.url">
|
||||
<span class="icon-text is-block">
|
||||
|
|
@ -218,7 +225,7 @@ import moment from "moment";
|
|||
import { useStorage } from '@vueuse/core'
|
||||
import LazyLoader from './Lazy-Loader'
|
||||
|
||||
const emits = defineEmits(['deleteItem', 'addItem', 'playItem']);
|
||||
const emits = defineEmits(['deleteItem', 'addItem', 'playItem', 'archiveItem']);
|
||||
|
||||
const props = defineProps({
|
||||
completed: {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import {
|
|||
faBroom,
|
||||
faServer,
|
||||
faPowerOff,
|
||||
faPaperPlane
|
||||
faPaperPlane,
|
||||
faBoxArchive
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
import { faSquare, faSquareCheck } from '@fortawesome/free-regular-svg-icons'
|
||||
|
|
@ -24,7 +25,7 @@ import 'floating-vue/dist/style.css'
|
|||
library.add(faCog, faTrash, faLink, faPlus, faTrashCan, faCircleXmark, faCircleCheck, faRotateRight, faDownload,
|
||||
faUpRightFromSquare, faSquare, faSquareCheck, faSpinner, faArrowUp, faArrowDown, faTasks, faCalendar, faArrowUpAZ,
|
||||
faArrowDownAZ, faEject, faGlobe, faMoon, faSun, faTerminal, faBroom, faServer, faPowerOff, faBroom, faServer,
|
||||
faPowerOff, faPaperPlane)
|
||||
faPowerOff, faPaperPlane, faBoxArchive)
|
||||
const app = createApp(App);
|
||||
|
||||
app.config.globalProperties.capitalize = s => s && s[0].toUpperCase() + s.slice(1);
|
||||
|
|
|
|||
Loading…
Reference in a new issue