mirror of
https://github.com/tubearchivist/tubearchivist-frontend.git
synced 2024-12-22 18:00:17 +00:00
Merge branch 'testing' of https://github.com/bbilly1/tubearchivist into feat/react-frontend
This commit is contained in:
commit
6e4bb5b805
@ -151,7 +151,7 @@ We have come far, nonetheless we are not short of ideas on how to improve and ex
|
||||
- [ ] Implement [Apprise](https://github.com/caronc/apprise) for notifications ([#97](https://github.com/bbilly1/tubearchivist/issues/97))
|
||||
- [ ] Add [SponsorBlock](https://sponsor.ajay.app/) integration
|
||||
- [ ] Add passing browser cookies to yt-dlp ([#199](https://github.com/bbilly1/tubearchivist/issues/199))
|
||||
- [ ] User created playlists ([#108](https://github.com/bbilly1/tubearchivist/issues/108))
|
||||
- [ ] User created playlists, random and repeat controls ([#108](https://github.com/bbilly1/tubearchivist/issues/108), [#220](https://github.com/bbilly1/tubearchivist/issues/220))
|
||||
- [ ] Auto play or play next link
|
||||
- [ ] Show similar videos on video page
|
||||
- [ ] Multi language support
|
||||
|
@ -123,6 +123,9 @@ POST /api/channel/
|
||||
## Channel Item View
|
||||
/api/channel/\<channel_id>/
|
||||
|
||||
## Playlist List View
|
||||
/api/playlist/
|
||||
|
||||
## Playlists Item View
|
||||
/api/playlist/\<playlist_id>/
|
||||
|
||||
|
@ -40,6 +40,8 @@ class SearchProcess:
|
||||
processed = self._process_video(result["_source"])
|
||||
if index == "ta_channel":
|
||||
processed = self._process_channel(result["_source"])
|
||||
if index == "ta_playlist":
|
||||
processed = self._process_playlist(result["_source"])
|
||||
|
||||
return processed
|
||||
|
||||
@ -80,3 +82,19 @@ class SearchProcess:
|
||||
)
|
||||
|
||||
return dict(sorted(video_dict.items()))
|
||||
|
||||
@staticmethod
|
||||
def _process_playlist(playlist_dict):
|
||||
"""run on single playlist dict"""
|
||||
playlist_id = playlist_dict["playlist_id"]
|
||||
playlist_last_refresh = date_praser(
|
||||
playlist_dict["playlist_last_refresh"]
|
||||
)
|
||||
playlist_dict.update(
|
||||
{
|
||||
"playlist_thumbnail": f"/cache/playlists/{playlist_id}.jpg",
|
||||
"playlist_last_refresh": playlist_last_refresh,
|
||||
}
|
||||
)
|
||||
|
||||
return dict(sorted(playlist_dict.items()))
|
||||
|
@ -7,6 +7,7 @@ from api.views import (
|
||||
DownloadApiView,
|
||||
LoginApiView,
|
||||
PingView,
|
||||
PlaylistApiListView,
|
||||
PlaylistApiView,
|
||||
VideoApiListView,
|
||||
VideoApiView,
|
||||
@ -53,6 +54,11 @@ urlpatterns = [
|
||||
PlaylistApiView.as_view(),
|
||||
name="api-playlist",
|
||||
),
|
||||
path(
|
||||
"playlist/",
|
||||
PlaylistApiListView.as_view(),
|
||||
name="api-playlist-list",
|
||||
),
|
||||
path(
|
||||
"download/",
|
||||
DownloadApiListView.as_view(),
|
||||
|
@ -258,6 +258,22 @@ class PlaylistApiView(ApiBaseView):
|
||||
return Response(self.response, status=self.status_code)
|
||||
|
||||
|
||||
class PlaylistApiListView(ApiBaseView):
|
||||
"""resolves to /api/playlist/
|
||||
GET: returns list of indexed playlists
|
||||
"""
|
||||
|
||||
search_base = "ta_playlist/_search/"
|
||||
|
||||
def get(self, request):
|
||||
# pylint: disable=unused-argument
|
||||
"""handle get request"""
|
||||
data = {"query": {"match_all": {}}}
|
||||
self.get_document_list(data)
|
||||
self.get_paginate()
|
||||
return Response(self.response)
|
||||
|
||||
|
||||
class DownloadApiView(ApiBaseView):
|
||||
"""resolves to /api/download/<video_id>/
|
||||
GET: returns metadata dict of an item in the download queue
|
||||
|
@ -200,7 +200,7 @@ class ChannelOverwriteForm(forms.Form):
|
||||
|
||||
SP_CHOICES = [
|
||||
("", "-- change sponsorblock integrations"),
|
||||
("0", "disable sponsorblock integration"),
|
||||
("disable", "disable sponsorblock integration"),
|
||||
("1", "enable sponsorblock integration"),
|
||||
]
|
||||
|
||||
|
@ -351,6 +351,9 @@ class YoutubeChannel(YouTubeItem):
|
||||
for key, value in overwrites.items():
|
||||
if key not in valid_keys:
|
||||
raise ValueError(f"invalid overwrite key: {key}")
|
||||
if value == "disable":
|
||||
to_write[key] = False
|
||||
continue
|
||||
if value in [0, "0"]:
|
||||
del to_write[key]
|
||||
continue
|
||||
|
@ -412,16 +412,18 @@ class YoutubeVideo(YouTubeItem, YoutubeSubtitle):
|
||||
|
||||
def _check_get_sb(self):
|
||||
"""check if need to run sponsor block"""
|
||||
integrate = False
|
||||
if self.config["downloads"]["integrate_sponsorblock"]:
|
||||
return True
|
||||
try:
|
||||
single_overwrite = self.video_overwrites[self.youtube_id]
|
||||
_ = single_overwrite["integrate_sponsorblock"]
|
||||
return True
|
||||
except KeyError:
|
||||
return False
|
||||
integrate = True
|
||||
|
||||
return False
|
||||
if self.video_overwrites:
|
||||
single_overwrite = self.video_overwrites.get(self.youtube_id)
|
||||
if not single_overwrite:
|
||||
return integrate
|
||||
|
||||
integrate = single_overwrite.get("integrate_sponsorblock", False)
|
||||
|
||||
return integrate
|
||||
|
||||
def _process_youtube_meta(self):
|
||||
"""extract relevant fields from youtube"""
|
||||
|
@ -48,7 +48,7 @@
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<p>Current download speed limit in KB/s: <span class="settings-current">{{ config.downloads.limit_speed }}</span></p>
|
||||
<i>Limit download speed. 0 (zero) to deactivate, e.g. 1000 (1MB/s). Speeds are in KB/s.</i><br>
|
||||
<i>Limit download speed. 0 (zero) to deactivate, e.g. 1000 (1MB/s). Speeds are in KB/s. Setting takes effect on new download jobs or application restart.</i><br>
|
||||
{{ app_form.downloads_limit_speed }}
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
|
@ -5,31 +5,11 @@
|
||||
<div class="video-main"></div>
|
||||
<div class="notifications" id="notifications"></div>
|
||||
<div class="sponsorblock" id="sponsorblock">
|
||||
{% if video.channel.channel_overwrites.integrate_sponsorblock %}
|
||||
{% if video.channel.channel_overwrites.integrate_sponsorblock == True %}
|
||||
{% if not video.sponsorblock %}
|
||||
<h4>This video doesn't have any sponsor segments added. To add a segment go to <u><a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">this video on YouTube</a></u> and add a segment using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
{% endif %}
|
||||
{% if video.sponsorblock %}
|
||||
{% for segment in video.sponsorblock %}
|
||||
{% if segment.locked != 1 %}
|
||||
<h4>This video has unlocked sponsor segments. Go to <u><a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">this video on YouTube</a></u> and vote on the segments using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
{{ break }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% elif config.downloads.integrate_sponsorblock %}
|
||||
{% if not video.sponsorblock %}
|
||||
{% if video.sponsorblock.is_enabled %}
|
||||
{% if video.sponsorblock.segments|length == 0 %}
|
||||
<h4>This video doesn't have any sponsor segments added. To add a segment go to <u><a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">this video on YouTube</a></u> and add a segment using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
{% endif %}
|
||||
{% if video.sponsorblock %}
|
||||
{% for segment in video.sponsorblock %}
|
||||
{% if segment.locked != 1 %}
|
||||
<h4>This video has unlocked sponsor segments. Go to <u><a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">this video on YouTube</a></u> and vote on the segments using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
{{ break }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% elif video.sponsorblock.has_unlocked %}
|
||||
<h4>This video has unlocked sponsor segments. Go to <u><a href="https://www.youtube.com/watch?v={{ video.youtube_id }}">this video on YouTube</a></u> and vote on the segments using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
@ -333,24 +333,21 @@ function createPlayer(button) {
|
||||
var videoData = getVideoData(videoId);
|
||||
|
||||
var sponsorBlockElements = '';
|
||||
if (videoData.config.downloads.integrate_sponsorblock && (typeof(videoData.data.channel.channel_overwrites) == "undefined" || typeof(videoData.data.channel.channel_overwrites.integrate_sponsorblock) == "undefined" || videoData.data.channel.channel_overwrites.integrate_sponsorblock == true)) {
|
||||
if (videoData.data.sponsorblock.is_enabled) {
|
||||
sponsorBlock = videoData.data.sponsorblock;
|
||||
if (!sponsorBlock) {
|
||||
if (sponsorBlock.segments.length == 0) {
|
||||
sponsorBlockElements = `
|
||||
<div class="sponsorblock" id="sponsorblock">
|
||||
<h4>This video doesn't have any sponsor segments added. To add a segment go to <u><a href="https://www.youtube.com/watch?v=${videoId}">this video on Youtube</a></u> and add a segment using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
for(let i in sponsorBlock) {
|
||||
if(sponsorBlock[i].locked != 1) {
|
||||
sponsorBlockElements = `
|
||||
<div class="sponsorblock" id="sponsorblock">
|
||||
<h4>This video has unlocked sponsor segments. Go to <u><a href="https://www.youtube.com/watch?v=${videoId}">this video on YouTube</a></u> and vote on the segments using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
</div>
|
||||
`;
|
||||
break;
|
||||
}
|
||||
if (sponsorBlock.has_unlocked) {
|
||||
sponsorBlockElements = `
|
||||
<div class="sponsorblock" id="sponsorblock">
|
||||
<h4>This video has unlocked sponsor segments. Go to <u><a href="https://www.youtube.com/watch?v=${videoId}">this video on YouTube</a></u> and vote on the segments using the <u><a href="https://sponsor.ajay.app/">SponsorBlock</a></u> extension.</h4>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -425,53 +422,6 @@ function createPlayer(button) {
|
||||
divPlayer.innerHTML = markup;
|
||||
}
|
||||
|
||||
// function sendSponsorBlockVote(uuid, vote) {
|
||||
// var videoId = getVideoPlayerVideoId();
|
||||
// postSponsorSegmentVote(videoId, uuid, vote);
|
||||
// }
|
||||
|
||||
// var sponsorBlockTimestamps = [];
|
||||
// function sendSponsorBlockSegment() {
|
||||
// var videoId = getVideoPlayerVideoId();
|
||||
// var currentTime = getVideoPlayerCurrentTime();
|
||||
// var sponsorBlockElement = document.getElementById("sponsorblock");
|
||||
// if (sponsorBlockTimestamps[1]) {
|
||||
// if (sponsorBlockTimestamps[1] > sponsorBlockTimestamps[0]) {
|
||||
// postSponsorSegment(videoId, sponsorBlockTimestamps[0], sponsorBlockTimestamps[1]);
|
||||
// sponsorBlockElement.innerHTML = `
|
||||
// <p>Timestamps sent! (Not really)</p>
|
||||
// `;
|
||||
// setTimeout(function(){
|
||||
// sponsorBlockElement.innerHTML = `
|
||||
// <img src="/static/img/PlayerStartIconSponsorBlocker.svg" class="sponsorblockIcon"><button onclick="sendSponsorBlockSegment()">Start</button>
|
||||
// `;
|
||||
// }, 3000);
|
||||
// } else {
|
||||
// sponsorBlockElement.innerHTML = `
|
||||
// <span class="danger-zone">Invalid Timestamps!</span>
|
||||
// `;
|
||||
// setTimeout(function(){
|
||||
// sponsorBlockElement.innerHTML = `
|
||||
// <img src="/static/img/PlayerStartIconSponsorBlocker.svg" class="sponsorblockIcon"><button onclick="sendSponsorBlockSegment()">Start</button>
|
||||
// `;
|
||||
// }, 3000);
|
||||
// }
|
||||
// sponsorBlockTimestamps = [];
|
||||
// } else if (sponsorBlockTimestamps[0]) {
|
||||
// sponsorBlockTimestamps.push(currentTime);
|
||||
// sponsorBlockElement.innerHTML = `
|
||||
// <img src="/static/img/PlayerStartIconSponsorBlocker.svg" class="sponsorblockIcon" onclick="getVideoPlayer().currentTime = '${sponsorBlockTimestamps[0]}'"><p>${sponsorBlockTimestamps[0].toFixed(1)} s | </p>
|
||||
// <img src="/static/img/PlayerStopIconSponsorBlocker.svg" class="sponsorblockIcon" onclick="getVideoPlayer().currentTime = '${sponsorBlockTimestamps[1]}'"><p>${sponsorBlockTimestamps[1].toFixed(1)} s | </p>
|
||||
// <img src="/static/img/PlayerUploadIconSponsorBlocker.svg" class="sponsorblockIcon"><button onclick="sendSponsorBlockSegment()">Confirm</button>
|
||||
// `;
|
||||
// } else {
|
||||
// sponsorBlockTimestamps.push(currentTime);
|
||||
// sponsorBlockElement.innerHTML = `
|
||||
// <img src="/static/img/PlayerStopIconSponsorBlocker.svg" class="sponsorblockIcon"><button onclick="sendSponsorBlockSegment()">End</button>
|
||||
// `;
|
||||
// }
|
||||
// }
|
||||
|
||||
// Add video tag to video page when passed a video id, function loaded on page load `video.html (115-117)`
|
||||
function insertVideoTag(videoData, videoProgress) {
|
||||
var videoTag = createVideoTag(videoData, videoProgress);
|
||||
@ -563,23 +513,14 @@ function onVideoProgress() {
|
||||
var videoElement = getVideoPlayer();
|
||||
// var sponsorBlockElement = document.getElementById("sponsorblock");
|
||||
var notificationsElement = document.getElementById("notifications");
|
||||
if (sponsorBlock) {
|
||||
for(let i in sponsorBlock) {
|
||||
if(sponsorBlock[i].segment[0] <= currentTime + 0.3 && sponsorBlock[i].segment[0] >= currentTime) {
|
||||
videoElement.currentTime = sponsorBlock[i].segment[1];
|
||||
notificationsElement.innerHTML += `<h3 id="notification-${sponsorBlock[i].UUID}">Skipped sponsor segment from ${formatTime(sponsorBlock[i].segment[0])} to ${formatTime(sponsorBlock[i].segment[1])}.</h3>`;
|
||||
if (sponsorBlock.segments.length > 0) {
|
||||
for(let i in sponsorBlock.segments) {
|
||||
if(sponsorBlock.segments[i].segment[0] <= currentTime + 0.3 && sponsorBlock.segments[i].segment[0] >= currentTime) {
|
||||
videoElement.currentTime = sponsorBlock.segments[i].segment[1];
|
||||
notificationsElement.innerHTML += `<h3 id="notification-${sponsorBlock.segments[i].UUID}">Skipped sponsor segment from ${formatTime(sponsorBlock.segments[i].segment[0])} to ${formatTime(sponsorBlock.segments[i].segment[1])}.</h3>`;
|
||||
}
|
||||
// if(currentTime >= sponsorBlock[i].segment[1] && currentTime <= sponsorBlock[i].segment[1] + 0.2) {
|
||||
// if(sponsorBlock[i].locked != 1) {
|
||||
// sponsorBlockElement.innerHTML += `
|
||||
// <div id="${sponsorBlock[i].UUID}">
|
||||
// <button onclick="sendSponsorBlockVote('${sponsorBlock[i].UUID}', 1)">Up Vote</button>
|
||||
// <button onclick="sendSponsorBlockVote('${sponsorBlock[i].UUID}', -1)">Down Vote</button>
|
||||
// </div>`;
|
||||
// }
|
||||
// }
|
||||
if(currentTime > sponsorBlock[i].segment[1] + 10) {
|
||||
var notificationsElementUUID = document.getElementById("notification-" + sponsorBlock[i].UUID);
|
||||
if(currentTime > sponsorBlock.segments[i].segment[1] + 10) {
|
||||
var notificationsElementUUID = document.getElementById("notification-" + sponsorBlock.segments[i].UUID);
|
||||
if(notificationsElementUUID) {
|
||||
notificationsElementUUID.outerHTML = '';
|
||||
}
|
||||
@ -602,6 +543,12 @@ function onVideoEnded() {
|
||||
if (!getVideoPlayerWatchStatus()) { // Check if video is already marked as watched
|
||||
updateVideoWatchStatus(videoId, "unwatched");
|
||||
}
|
||||
for(let i in sponsorBlock.segments) {
|
||||
var notificationsElementUUID = document.getElementById("notification-" + sponsorBlock.segments[i].UUID);
|
||||
if(notificationsElementUUID) {
|
||||
notificationsElementUUID.outerHTML = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function watchedThreshold(currentTime, duration) {
|
||||
|
Loading…
Reference in New Issue
Block a user