moved socket event pause/resume to api/system/

This commit is contained in:
arabcoders 2025-08-29 19:00:26 +03:00
parent 20cfc00640
commit e2b4a8caa3
9 changed files with 85 additions and 79 deletions

View file

@ -1,11 +1,13 @@
import asyncio
import logging
import time
from aiohttp import web
from aiohttp.web import Request, Response
from aiohttp.web_runner import GracefulExit
from app.library.config import Config
from app.library.DownloadQueue import DownloadQueue
from app.library.encoder import Encoder
from app.library.Events import EventBus, Events
from app.library.router import route
@ -13,10 +15,80 @@ from app.library.router import route
LOG: logging.Logger = logging.getLogger(__name__)
@route("POST", "api/system/pause", "system.pause")
async def downloads_pause(queue: DownloadQueue, encoder: Encoder, notify: EventBus) -> Response:
"""
Pause non-active downloads.
Args:
request (Request): The request object.
queue (DownloadQueue): The download queue instance.
encoder (Encoder): The encoder instance.
notify (EventBus): The event bus instance.
Returns:
Response: The response object.
"""
if queue.is_paused():
return web.json_response(
{"message": "Non-active downloads are already paused."},
status=web.HTTPNotAcceptable.status_code,
dumps=encoder.encode,
)
queue.pause()
msg = "Non-active downloads have been paused."
await notify.emit(
Events.PAUSED,
data={"paused": True, "at": time.time()},
title="Downloads Paused",
message=msg,
)
return web.json_response(data={"message": msg}, status=web.HTTPOk.status_code, dumps=encoder.encode)
@route("POST", "api/system/resume", "system.resume")
async def downloads_resume(queue: DownloadQueue, encoder: Encoder, notify: EventBus) -> Response:
"""
Resume non-active downloads.
Args:
request (Request): The request object.
queue (DownloadQueue): The download queue instance.
encoder (Encoder): The encoder instance.
notify (EventBus): The event bus instance.
Returns:
Response: The response object.
"""
if not queue.is_paused():
return web.json_response(
{"message": "Non-active downloads are not paused."},
status=web.HTTPNotAcceptable.status_code,
dumps=encoder.encode,
)
queue.resume()
msg = "Resumed all downloads."
await notify.emit(
Events.RESUMED,
data={"paused": False, "at": time.time()},
title="Downloads Resumed",
message=msg,
)
return web.json_response(data={"message": msg}, status=web.HTTPOk.status_code, dumps=encoder.encode)
@route("POST", "api/system/shutdown", "system.shutdown")
async def shutdown_system(request: Request, config: Config, encoder: Encoder, notify: EventBus) -> Response:
"""
Get the presets.
Initiate application shutdown.
Args:
request (Request): The request object.

View file

@ -1,38 +1,13 @@
import logging
import time
from app.library.DownloadQueue import DownloadQueue
from app.library.Events import EventBus, Events
from app.library.ItemDTO import Item
from app.library.router import RouteType, route
from app.library.Utils import archive_add, archive_read, get_archive_id
from app.library.YTDLPOpts import YTDLPOpts
LOG: logging.Logger = logging.getLogger(__name__)
@route(RouteType.SOCKET, "pause", "pause_downloads")
async def pause(notify: EventBus, queue: DownloadQueue):
queue.pause()
await notify.emit(
Events.PAUSED,
data={"paused": True, "at": time.time()},
title="Downloads Paused",
message="Non-active downloads have been paused.",
)
@route(RouteType.SOCKET, "resume", "resume_downloads")
async def resume(notify: EventBus, queue: DownloadQueue):
queue.resume()
await notify.emit(
Events.RESUMED,
data={"paused": False, "at": time.time()},
title="Downloads Resumed",
message="Resumed all downloads.",
)
@route(RouteType.SOCKET, "add_url", "add_url")
async def add_url(queue: DownloadQueue, notify: EventBus, sid: str, data: dict):
data = data if isinstance(data, dict) else {}
@ -74,40 +49,6 @@ async def item_delete(queue: DownloadQueue, notify: EventBus, sid: str, data: di
await queue.clear([id], remove_file=bool(data.get("remove_file", False)))
@route(RouteType.SOCKET, "archive_item", "archive_item")
async def archive_item(data: dict):
if not isinstance(data, dict) or "url" not in data:
return
params: YTDLPOpts = YTDLPOpts.get_instance()
if "preset" in data and isinstance(data["preset"], str):
params.preset(name=data["preset"])
if "cli" in data and isinstance(data["cli"], str) and len(data["cli"]) > 1:
params.add_cli(data["cli"], from_user=True)
params = params.get_all()
if not (file := params.get("download_archive")):
return
idDict = get_archive_id(url=data["url"])
if not idDict.get("archive_id"):
LOG.warning(f"URL '{data['url']}' does not have an archive ID.")
return
archive_id: str = idDict.get("archive_id")
if len(archive_read(file, [archive_id])) > 0:
LOG.info(f"URL '{data['url']}' already archived.")
return
archive_add(file, [archive_id])
LOG.info(f"Archiving url '{data['url']}' with id '{archive_id}'.")
@route(RouteType.SOCKET, "item_start", "item_start")
async def item_start(queue: DownloadQueue, notify: EventBus, sid: str, data: list | str) -> None:
if not data:

View file

@ -81,7 +81,7 @@ onMounted(async (): Promise<void> => {
try {
isLoading.value = true
const response = await request(url, { credentials: 'include' })
const response = await request(url)
const body = await response.text()
try {

View file

@ -611,9 +611,6 @@ const deleteSelectedItems = () => {
continue
}
const item = stateStore.get('history', item_id, {} as StoreItem) as StoreItem
if ('finished' === item.status) {
socket.emit('archive_item', item)
}
socket.emit('item_delete', {
id: item._id,
remove_file: config.app.remove_files,
@ -737,10 +734,7 @@ const addArchiveDialog = (item: StoreItem) => {
const archiveItem = async (item: StoreItem, opts = {}) => {
try {
const req = await request(`/api/history/${item._id}/archive`, {
credentials: 'include',
method: 'POST',
})
const req = await request(`/api/history/${item._id}/archive`, { method: 'POST' })
const data = await req.json()
dialog_confirm.value.visible = false
if (!req.ok) {
@ -832,8 +826,7 @@ const downloadSelected = async () => {
try {
const response = await request('/api/file/download', {
method: 'POST',
credentials: 'include',
body: JSON.stringify(files_list),
body: JSON.stringify(files_list)
})
const json = await response.json()
if (!response.ok) {
@ -871,7 +864,7 @@ const removeFromArchiveDialog = (item: StoreItem) => {
const removeFromArchive = async (item: StoreItem, opts?: { re_add?: boolean, remove_history?: boolean }) => {
console.log('Removing from archive:', item, opts)
try {
const req = await request(`/api/history/${item._id}/archive`, { credentials: 'include', method: 'DELETE' })
const req = await request(`/api/history/${item._id}/archive`, { method: 'DELETE' })
const data = await req.json()
if (!req.ok) {
toast.error(data.error)

View file

@ -50,7 +50,7 @@ onMounted(async () => {
try {
isLoading.value = true
const imgRequest = await request(url, { credentials: 'include' })
const imgRequest = await request(url)
if (200 !== imgRequest.status) {
return
}

View file

@ -351,7 +351,6 @@ const addDownload = async () => {
try {
addInProgress.value = true
const response = await request('/api/history', {
credentials: 'include',
method: 'POST',
body: JSON.stringify(request_data),
})

View file

@ -510,7 +510,7 @@ const convert_url = async (url: string): Promise<string> => {
try {
convertInProgress.value = true
const resp = await request('/api/yt-dlp/url/info?' + params.toString(), { credentials: 'include' })
const resp = await request('/api/yt-dlp/url/info?' + params.toString())
const body = await resp.json()
const channel_id = ag(body, 'channel_id', null)
console.log('convert_url', { url, channel_id, body })

View file

@ -170,7 +170,7 @@ const filters = reactive({
const reload = async (): Promise<void> => {
try {
isLoading.value = true
const resp = await request('/api/yt-dlp/options', { credentials: 'include' })
const resp = await request('/api/yt-dlp/options')
if (!resp.ok) {
return
}

View file

@ -29,8 +29,7 @@
<span class="icon"><i class="fas fa-pause" /></span>
<span v-if="!isMobile">Pause</span>
</button>
<button class="button is-danger" @click="socket.emit('resume', {})" v-else
v-tooltip.bottom="'Resume downloading.'">
<button class="button is-danger" @click="resumeDownload" v-else v-tooltip.bottom="'Resume downloading.'">
<span class="icon"><i class="fas fa-play" /></span>
<span v-if="!isMobile">Resume</span>
</button>
@ -174,6 +173,8 @@ watch(() => stateStore.queue, () => {
}, { deep: true })
const resumeDownload = async () => await request('/api/system/resume', { method: 'POST' })
const pauseDownload = () => {
dialog_confirm.value.visible = true
dialog_confirm.value.html_message = `
@ -188,8 +189,8 @@ const pauseDownload = () => {
<li>If you are in middle of adding a playlist/channel, it will break and stop adding more items.</li>
</ul>
</span>`
dialog_confirm.value.confirm = () => {
socket.emit('pause', {})
dialog_confirm.value.confirm = async () => {
await request('/api/system/pause', { method: 'POST' })
dialog_confirm.value.visible = false
}
}