add is_archived to both local info and yt-dlp info

This commit is contained in:
arabcoders 2025-08-28 21:42:02 +03:00
parent f8e3a2f6e6
commit 29b7748b8a
4 changed files with 35 additions and 23 deletions

View file

@ -13,6 +13,8 @@ from app.library.Events import EventBus, Events
from app.library.ItemDTO import Item from app.library.ItemDTO import Item
from app.library.Presets import Preset, Presets from app.library.Presets import Preset, Presets
from app.library.router import route from app.library.router import route
from app.library.Utils import is_downloaded
from app.library.YTDLPOpts import YTDLPOpts
if TYPE_CHECKING: if TYPE_CHECKING:
from library.Download import Download from library.Download import Download
@ -98,8 +100,18 @@ async def item_view(request: Request, queue: DownloadQueue, encoder: Encoder, co
if not item.info: if not item.info:
return web.json_response(data={"error": "item has no info."}, status=web.HTTPNotFound.status_code) return web.json_response(data={"error": "item has no info."}, status=web.HTTPNotFound.status_code)
is_archived = False
params: YTDLPOpts = YTDLPOpts.get_instance().preset(name=item.info.preset)
if item.info.cli:
params.add_cli(item.info.cli, from_user=True)
params = params.get_all()
if archive_file := params.get("download_archive"):
is_archived, _ = is_downloaded(archive_file, item.info.url)
info = { info = {
**item.info.serialize(), **item.info.serialize(),
"is_archived": is_archived,
"ffprobe": {}, "ffprobe": {},
} }

View file

@ -14,7 +14,7 @@ from app.library.cache import Cache
from app.library.config import Config from app.library.config import Config
from app.library.Presets import Presets from app.library.Presets import Presets
from app.library.router import route from app.library.router import route
from app.library.Utils import REMOVE_KEYS, arg_converter, extract_info, validate_url from app.library.Utils import REMOVE_KEYS, arg_converter, extract_info, is_downloaded, validate_url
from app.library.YTDLPOpts import YTDLPOpts from app.library.YTDLPOpts import YTDLPOpts
LOG: logging.Logger = logging.getLogger(__name__) LOG: logging.Logger = logging.getLogger(__name__)
@ -199,6 +199,12 @@ async def get_info(request: Request, cache: Cache, config: Config) -> Response:
"expires": time.time() + 300, "expires": time.time() + 300,
} }
is_archived = False
if user_file := ytdlp_opts.get("download_archive"):
is_archived, _ = is_downloaded(user_file, url)
data["is_archived"] = is_archived
data = OrderedDict(sorted(data.items(), key=lambda item: len(str(item[1])))) data = OrderedDict(sorted(data.items(), key=lambda item: len(str(item[1]))))
cache.set(key=key, value=data, ttl=300) cache.set(key=key, value=data, ttl=300)

View file

@ -139,11 +139,8 @@
</div> </div>
</td> </td>
<td class="is-vcentered has-text-centered is-unselectable"> <td class="is-vcentered has-text-centered is-unselectable">
<span class="icon-text"> <span class="icon" :class="setIconColor(item)"><i :class="[setIcon(item), is_queued(item)]" /></span>
<span class="icon" :class="setIconColor(item)"><i <span>{{ setStatus(item) }}</span>
:class="[setIcon(item), is_queued(item)]" /></span>
<span>{{ setStatus(item) }}</span>
</span>
</td> </td>
<td class="is-vcentered has-text-centered is-unselectable"> <td class="is-vcentered has-text-centered is-unselectable">
<span class="user-hint" :date-datetime="item.datetime" <span class="user-hint" :date-datetime="item.datetime"
@ -285,7 +282,8 @@
<span v-else-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string" <span v-else-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
class="play-overlay"> class="play-overlay">
<div class="play-icon embed-icon"></div> <div class="play-icon embed-icon"></div>
<img @load="e => pImg(e)" :src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" <img @load="e => pImg(e)"
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
v-if="item.extras?.thumbnail" /> v-if="item.extras?.thumbnail" />
<img v-else src="/images/placeholder.png" /> <img v-else src="/images/placeholder.png" />
</span> </span>
@ -299,10 +297,8 @@
<div class="card-content"> <div class="card-content">
<div class="columns is-mobile is-multiline"> <div class="columns is-mobile is-multiline">
<div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable"> <div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable">
<span class="icon-text"> <span class="icon" :class="setIconColor(item)"><i :class="[setIcon(item), is_queued(item)]" /></span>
<span class="icon" :class="setIconColor(item)"><i :class="[setIcon(item), is_queued(item)]" /></span> <span>{{ setStatus(item) }}</span>
<span>{{ setStatus(item) }}</span>
</span>
</div> </div>
<div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable"> <div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable">
<span class="icon"><i class="fa-solid fa-sliders" /></span> <span class="icon"><i class="fa-solid fa-sliders" /></span>

View file

@ -84,7 +84,8 @@
</span> </span>
</div> </div>
<div v-if="showThumbnails && item.extras?.thumbnail"> <div v-if="showThumbnails && item.extras?.thumbnail">
<FloatingImage :image="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" <FloatingImage
:image="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
:title="item.title"> :title="item.title">
<div class="is-text-overflow"> <div class="is-text-overflow">
<NuxtLink target="_blank" :href="item.url">{{ item.title }}</NuxtLink> <NuxtLink target="_blank" :href="item.url">{{ item.title }}</NuxtLink>
@ -98,12 +99,10 @@
</template> </template>
</td> </td>
<td class="has-text-centered is-text-overflow is-unselectable"> <td class="has-text-centered is-text-overflow is-unselectable">
<span class="icon-text"> <span class="icon" :class="setIconColor(item)">
<span class="icon" :class="setIconColor(item)"> <i class="fas fa-solid" :class="setIcon(item)" />
<i class="fas fa-solid" :class="setIcon(item)" />
</span>
<span v-text="setStatus(item)" />
</span> </span>
<span v-text="setStatus(item)" />
</td> </td>
<td> <td>
<div class="progress-bar is-unselectable"> <div class="progress-bar is-unselectable">
@ -206,7 +205,8 @@
<span v-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string" <span v-if="isEmbedable(item.url)" @click="embed_url = getEmbedable(item.url) as string"
class="play-overlay"> class="play-overlay">
<div class="play-icon embed-icon"></div> <div class="play-icon embed-icon"></div>
<img @load="e => pImg(e)" :src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))" <img @load="e => pImg(e)"
:src="uri('/api/thumbnail?id=' + item._id + '&url=' + encodePath(item.extras.thumbnail))"
v-if="item.extras?.thumbnail" /> v-if="item.extras?.thumbnail" />
<img v-else src="/images/placeholder.png" /> <img v-else src="/images/placeholder.png" />
</span> </span>
@ -226,12 +226,10 @@
</div> </div>
</div> </div>
<div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable"> <div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable">
<span class="icon-text"> <span class="icon" :class="setIconColor(item)">
<span class="icon" :class="setIconColor(item)"> <i class="fas fa-solid" :class="setIcon(item)" />
<i class="fas fa-solid" :class="setIcon(item)" />
</span>
<span v-text="setStatus(item)" />
</span> </span>
<span v-text="setStatus(item)" />
</div> </div>
<div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable"> <div class="column is-half-mobile has-text-centered is-text-overflow is-unselectable">
<span class="icon"><i class="fa-solid fa-sliders" /></span> <span class="icon"><i class="fa-solid fa-sliders" /></span>