home
·
contact
·
privacy
projects
/
ytplom
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
a3d9084
)
Enable marking queued downloads for playlist insertion once ready.
master
author
Plom Heller
<plom@plomlompom.com>
Wed, 18 Mar 2026 03:12:33 +0000
(
04:12
+0100)
committer
Plom Heller
<plom@plomlompom.com>
Wed, 18 Mar 2026 03:12:33 +0000
(
04:12
+0100)
src/templates/_base.js
patch
|
blob
|
history
src/templates/downloads.js
patch
|
blob
|
history
src/templates/file.js
patch
|
blob
|
history
src/ytplom/http.py
patch
|
blob
|
history
src/ytplom/misc.py
patch
|
blob
|
history
diff --git
a/src/templates/_base.js
b/src/templates/_base.js
index d83b0da72485265f714bbc945942fa4bde1927e5..4692e19430d1b50875d5568f5b76a46322014dcd 100644
(file)
--- a/
src/templates/_base.js
+++ b/
src/templates/_base.js
@@
-23,7
+23,7
@@
eslint
"function-paren-newline": "off",
"max-lines": [
"error",
"function-paren-newline": "off",
"max-lines": [
"error",
- {"max": 4
50
, "skipBlankLines": true, "skipComments": true}
+ {"max": 4
63
, "skipBlankLines": true, "skipComments": true}
],
"max-lines-per-function": [
"error",
],
"max-lines-per-function": [
"error",
@@
-89,10
+89,10
@@
export const
],
CMD_ADD_NEXT = "inject",
CMD_ADD_PLAY = "injectplay",
],
CMD_ADD_NEXT = "inject",
CMD_ADD_PLAY = "injectplay",
+ CMD_NEXT = "next",
CMD_PAUSE = "pause",
CMD_PLAY = "play",
CMD_PREV = "prev",
CMD_PAUSE = "pause",
CMD_PLAY = "play",
CMD_PREV = "prev",
- CMD_NEXT = "next",
CMD_RM = "rm",
IDX_PATH_ID = 2,
IDX_START = 0,
CMD_RM = "rm",
IDX_PATH_ID = 2,
IDX_START = 0,
@@
-179,6
+179,20
@@
export const addChildTo = (
return el;
};
return el;
};
+export const addCheckboxTo = (
+ parent,
+ checked,
+ onclick
+) => addChildTo(
+ "input",
+ parent,
+ {
+ checked,
+ onclick,
+ "type": "checkbox"
+ }
+);
+
export const addATo = (
parent,
textContent,
export const addATo = (
parent,
textContent,
@@
-364,11
+378,11
@@
eventHandlers.player = (
playerDiv.innerHTML = "";
addPlayerBtnToDiv(
CMD_PREV,
playerDiv.innerHTML = "";
addPlayerBtnToDiv(
CMD_PREV,
- CMD_PREV
,
+ CMD_PREV
);
addPlayerBtnToDiv(
CMD_NEXT,
);
addPlayerBtnToDiv(
CMD_NEXT,
- CMD_NEXT
,
+ CMD_NEXT
);
addPlayerBtnToDiv(
data.is_playing ? CMD_PAUSE : CMD_PLAY,
);
addPlayerBtnToDiv(
data.is_playing ? CMD_PAUSE : CMD_PLAY,
diff --git
a/src/templates/downloads.js
b/src/templates/downloads.js
index 7a1d7ab39c238aef4bb57bb0d68628c1d2e279d9..d59dd7c6087ec9caa9166e8214bdf2b9db9fd658 100644
(file)
--- a/
src/templates/downloads.js
+++ b/
src/templates/downloads.js
@@
-10,7
+10,7
@@
eslint
],
"max-lines-per-function": [
"error",
],
"max-lines-per-function": [
"error",
- 1
12
+ 1
46
],
"max-params": [
"error",
],
"max-params": [
"error",
@@
-50,6
+50,8
@@
import {
SYMBOL_UP,
addATdTo,
addButtonTo,
SYMBOL_UP,
addATdTo,
addButtonTo,
+ addChildTo,
+ addCheckboxTo,
addPlayerBtnTo,
addTdTo,
drawTable,
addPlayerBtnTo,
addTdTo,
drawTable,
@@
-80,6
+82,17
@@
eventHandlers.downloads = (data) => {
command
)
),
command
)
),
+ addInjectionCheckbox = (
+ td,
+ item
+ ) => addCheckboxTo(
+ td,
+ item.to_inject,
+ () => wrappedCommand(
+ PATH_DOWNLOADS_JSON,
+ `${item.to_inject ? "un" : "in"}ject_${item.yt_id}`
+ )
+ ),
drawDownloadTable = (
items,
populateRow,
drawDownloadTable = (
items,
populateRow,
@@
-127,6
+140,10
@@
eventHandlers.downloads = (data) => {
downloading
) => {
const tdEntryControl = addTdTo(tr); // col 1
downloading
) => {
const tdEntryControl = addTdTo(tr); // col 1
+ addInjectionCheckbox(
+ tdEntryControl,
+ data.downloading
+ );
addCommandButtonTo(
tdEntryControl,
SYMBOL_RM,
addCommandButtonTo(
tdEntryControl,
SYMBOL_RM,
@@
-160,6
+177,10
@@
eventHandlers.downloads = (data) => {
`${CMD_RM}_${idx}`
);
const tdEntryControl = addTdTo(tr); // col 2
`${CMD_RM}_${idx}`
);
const tdEntryControl = addTdTo(tr); // col 2
+ addInjectionCheckbox(
+ tdEntryControl,
+ toDownload
+ );
for (
const [
symbol,
for (
const [
symbol,
diff --git
a/src/templates/file.js
b/src/templates/file.js
index 75e1773122014921dac775facf23e46404f69364..37654c23b173b824e695cf966c7fd86cf194fd5a 100644
(file)
--- a/
src/templates/file.js
+++ b/
src/templates/file.js
@@
-32,6
+32,7
@@
import {
PATH_PREFIX_FILE_JSON,
PREFIX_CLICKABLE,
addATo,
PATH_PREFIX_FILE_JSON,
PREFIX_CLICKABLE,
addATo,
+ addCheckboxTo,
addChildTo,
addPlayerBtnTo,
addTdTo,
addChildTo,
addPlayerBtnTo,
addTdTo,
@@
-90,15
+91,11
@@
const updateFileData = async () => { // eslint-disable-line one-var
if (allowEdit) {
const tdCheckbox = addTdTo(tr);
tdCheckbox.classList.add(CLS_TAG_CHECKBOX);
if (allowEdit) {
const tdCheckbox = addTdTo(tr);
tdCheckbox.classList.add(CLS_TAG_CHECKBOX);
- addChildTo(
- "input",
+ addCheckboxTo(
tdCheckbox,
tdCheckbox,
- {
- "checked": true,
- /* eslint-disable-next-line no-use-before-define */
- "onclick": sendUpdate,
- "type": "checkbox"
- }
+ true,
+ /* eslint-disable-next-line no-use-before-define */
+ sendUpdate
);
}
addATo(
);
}
addATo(
diff --git
a/src/ytplom/http.py
b/src/ytplom/http.py
index 28041766d623ce4174d8cc9bab36047b8c732293..eefcfc72ec88bef5316f292c57ac099fcb1a4c98 100644
(file)
--- a/
src/ytplom/http.py
+++ b/
src/ytplom/http.py
@@
-41,7
+41,7
@@
class Server(ThreadingMixIn, PlomHttpServer):
_TaskHandler, *args, **kwargs)
self.config = config
self.player = Player()
_TaskHandler, *args, **kwargs)
self.config = config
self.player = Player()
- self.downloads = DownloadsManager()
+ self.downloads = DownloadsManager(
playlist_inject=self.player.inject
)
self.downloads.clean_unfinished()
self.downloads.start_thread()
VideoFile.call_forget\
self.downloads.clean_unfinished()
self.downloads.start_thread()
VideoFile.call_forget\
diff --git
a/src/ytplom/misc.py
b/src/ytplom/misc.py
index efd389a9dfb7a1e0e400f1153918e74225fdacb8..c068b5075b6a2fc9b38121d8da558bf0c1bec578 100644
(file)
--- a/
src/ytplom/misc.py
+++ b/
src/ytplom/misc.py
@@
-844,7
+844,9
@@
class Player:
class DownloadsManager:
"""Manages downloading and downloads access."""
class DownloadsManager:
"""Manages downloading and downloads access."""
- def __init__(self) -> None:
+ def __init__(self, playlist_inject: Callable[[VideoFile], None]) -> None:
+ self._playlist_inject = playlist_inject
+ self._to_inject: set[str] = set()
self._inherited: list[YoutubeId] = []
self._downloaded: list[YoutubeId] = []
self._downloading: Optional[YoutubeId] = None
self._inherited: list[YoutubeId] = []
self._downloaded: list[YoutubeId] = []
self._downloading: Optional[YoutubeId] = None
@@
-900,9
+902,11
@@
class DownloadsManager:
def overview(
self, conn: DbConn
def overview(
self, conn: DbConn
- ) -> dict[str, list[dict[str, str]] | Optional[dict[str, str]]]:
+ ) -> dict[str,
+ list[dict[str, str | bool]]
+ | Optional[dict[str, str | bool]]]:
'What has been, what will be, and what currently is being downloaded.'
'What has been, what will be, and what currently is being downloaded.'
- downloaded: list[dict[str, str]] = []
+ downloaded: list[dict[str, str
| bool
]] = []
yt_id: Optional[YoutubeId]
for yt_id in self._downloaded:
try:
yt_id: Optional[YoutubeId]
for yt_id in self._downloaded:
try:
@@
-912,7
+916,7
@@
class DownloadsManager:
downloaded += [{'yt_id': yt_id,
'path': str(file.rel_path),
'digest': file.digest.b64}] # + title?
downloaded += [{'yt_id': yt_id,
'path': str(file.rel_path),
'digest': file.digest.b64}] # + title?
- to_download: list[dict[str, str]] = []
+ to_download: list[dict[str, str
| bool
]] = []
for idx, yt_id in enumerate(self._to_download):
try:
yt_video = YoutubeVideo.get_one(conn, yt_id)
for idx, yt_id in enumerate(self._to_download):
try:
yt_video = YoutubeVideo.get_one(conn, yt_id)
@@
-920,8
+924,9
@@
class DownloadsManager:
continue
to_download += [{'yt_id': yt_id,
'title': yt_video.title,
continue
to_download += [{'yt_id': yt_id,
'title': yt_video.title,
- 'idx': str(idx)}]
- downloading: Optional[dict[str, str]] = None
+ 'idx': str(idx),
+ 'to_inject': yt_id in self._to_inject}]
+ downloading: Optional[dict[str, str | bool]] = None
if (yt_id := self._downloading):
try:
yt_video = YoutubeVideo.get_one(conn, yt_id)
if (yt_id := self._downloading):
try:
yt_video = YoutubeVideo.get_one(conn, yt_id)
@@
-930,7
+935,8
@@
class DownloadsManager:
else:
downloading = {'yt_id': yt_id,
'title': yt_video.title,
else:
downloading = {'yt_id': yt_id,
'title': yt_video.title,
- 'status': self._status}
+ 'status': self._status,
+ 'to_inject': yt_id in self._to_inject}
return {'downloaded': downloaded,
'downloading': downloading,
'to_download': to_download}
return {'downloaded': downloaded,
'downloading': downloading,
'to_download': to_download}
@@
-948,6
+954,7
@@
class DownloadsManager:
def _queue_download(self, yt_id: YoutubeId) -> None:
if yt_id == self._downloading or yt_id in self._downloaded:
return
def _queue_download(self, yt_id: YoutubeId) -> None:
if yt_id == self._downloading or yt_id in self._downloaded:
return
+ self._to_inject.add(yt_id)
self._to_download += [yt_id]
if not self._downloading:
self.q.put('download_next')
self._to_download += [yt_id]
if not self._downloading:
self.q.put('download_next')
@@
-983,6
+990,9
@@
class DownloadsManager:
with DbConn() as conn:
file.save(conn)
conn.commit()
with DbConn() as conn:
file.save(conn)
conn.commit()
+ if yt_id in self._to_inject:
+ self._playlist_inject(file)
+ self._to_inject.remove(yt_id)
self._downloaded += [yt_id]
self._downloading = None
return yt_id
self._downloaded += [yt_id]
self._downloading = None
return yt_id
@@
-1081,6
+1091,10
@@
class DownloadsManager:
self._queue_download(yt_id)
elif command == 'forget':
self._forget_file(yt_id)
self._queue_download(yt_id)
elif command == 'forget':
self._forget_file(yt_id)
+ elif command == 'inject':
+ self._to_inject.add(yt_id)
+ elif command == 'unject' and yt_id in self._to_inject:
+ self._to_inject.remove(yt_id)
self._update_timestamp(yt_id)
Thread(target=loop, daemon=False).start()
self._update_timestamp(yt_id)
Thread(target=loop, daemon=False).start()