Merge remote-tracking branch 'origin/master' into add-back-hsqldb

This commit is contained in:
Kavin 2023-10-26 16:18:55 +01:00
commit e45c7088dc
No known key found for this signature in database
GPG Key ID: 6E4598CA5C92C41F
23 changed files with 73 additions and 66 deletions

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
java: [ 17 ] java: [ 21 ]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -19,7 +19,7 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: ${{ matrix.java }} java-version: ${{ matrix.java }}
distribution: temurin distribution: zulu
cache: "gradle" cache: "gradle"
- name: Run Build - name: Run Build
run: ./gradlew build run: ./gradlew build

View File

@ -25,7 +25,7 @@ jobs:
dockerfile: dockerfile:
- Dockerfile.ci - Dockerfile.ci
- Dockerfile.azul.ci - Dockerfile.azul.ci
- Dockerfile.openj9.ci #- Dockerfile.openj9.ci
- Dockerfile.graalvm-jvm.ci - Dockerfile.graalvm-jvm.ci
include: include:
- sleep: 20 - sleep: 20

View File

@ -17,8 +17,8 @@ jobs:
strategy: strategy:
matrix: matrix:
include: include:
- image: 1337kavin/piped:openj9 # - image: 1337kavin/piped:openj9
dockerfile: ./Dockerfile.openj9.ci # dockerfile: ./Dockerfile.openj9.ci
- image: 1337kavin/piped:hotspot - image: 1337kavin/piped:hotspot
dockerfile: ./Dockerfile.ci dockerfile: ./Dockerfile.ci
- image: 1337kavin/piped:latest,1337kavin/piped:azul-zulu - image: 1337kavin/piped:latest,1337kavin/piped:azul-zulu

View File

@ -15,11 +15,11 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
ref: ${{ github.event.pull_request.base.sha }} ref: ${{ github.event.pull_request.base.sha }}
- name: set up JDK 17 - name: set up JDK 21
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 17 java-version: 21
distribution: temurin distribution: zulu
cache: "gradle" cache: "gradle"
- name: Run Build - name: Run Build
run: ./gradlew shadowJar run: ./gradlew shadowJar
@ -39,7 +39,7 @@ jobs:
- testing/docker-compose.cockroachdb.yml - testing/docker-compose.cockroachdb.yml
- testing/docker-compose.yugabytedb.yml - testing/docker-compose.yugabytedb.yml
dockerfile: dockerfile:
- Dockerfile.ci - Dockerfile.azul.ci
include: include:
- sleep: 20 - sleep: 20
- docker-compose-file: testing/docker-compose.cockroachdb.yml - docker-compose-file: testing/docker-compose.cockroachdb.yml

View File

@ -9,11 +9,11 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: set up JDK 17 - name: set up JDK 21
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 17 java-version: 21
distribution: temurin distribution: zulu
cache: "gradle" cache: "gradle"
- name: Run Build - name: Run Build
run: ./gradlew shadowJar run: ./gradlew shadowJar

View File

@ -1,4 +1,4 @@
FROM eclipse-temurin:17-jdk AS build FROM eclipse-temurin:21-jdk AS build
WORKDIR /app/ WORKDIR /app/
@ -7,7 +7,7 @@ COPY . /app/
RUN --mount=type=cache,target=/root/.gradle/caches/ \ RUN --mount=type=cache,target=/root/.gradle/caches/ \
./gradlew shadowJar ./gradlew shadowJar
FROM eclipse-temurin:17-jre FROM eclipse-temurin:21-jre
RUN --mount=type=cache,target=/var/cache/apt/ \ RUN --mount=type=cache,target=/var/cache/apt/ \
apt-get update && \ apt-get update && \

View File

@ -1,4 +1,4 @@
FROM eclipse-temurin:17-jre FROM eclipse-temurin:21-jre
RUN --mount=type=cache,target=/var/cache/apt/ \ RUN --mount=type=cache,target=/var/cache/apt/ \
apt-get update && \ apt-get update && \

View File

@ -1,4 +1,4 @@
FROM ghcr.io/graalvm/native-image:latest as build FROM container-registry.oracle.com/graalvm/native-image:latest as build
WORKDIR /app/ WORKDIR /app/

View File

@ -1,4 +1,4 @@
FROM ghcr.io/graalvm/native-image:latest as build FROM container-registry.oracle.com/graalvm/native-image:latest as build
RUN jlink \ RUN jlink \
--add-modules java.base,java.logging,java.sql,java.management,java.xml,java.naming,java.desktop,jdk.crypto.ec \ --add-modules java.base,java.logging,java.sql,java.management,java.xml,java.naming,java.desktop,jdk.crypto.ec \

View File

@ -1,7 +1,6 @@
plugins { plugins {
id "com.github.johnrengelman.shadow" version "8.1.1" id "com.github.johnrengelman.shadow" version "8.1.1"
id "java" id "java"
id "io.freefair.lombok" version "8.3"
id "eclipse" id "eclipse"
} }
@ -13,11 +12,11 @@ repositories {
dependencies { dependencies {
implementation 'org.apache.commons:commons-lang3:3.13.0' implementation 'org.apache.commons:commons-lang3:3.13.0'
implementation 'org.apache.commons:commons-text:1.10.0' implementation 'org.apache.commons:commons-text:1.10.0'
implementation 'commons-io:commons-io:2.13.0' implementation 'commons-io:commons-io:2.14.0'
implementation 'it.unimi.dsi:fastutil-core:8.5.12' implementation 'it.unimi.dsi:fastutil-core:8.5.12'
implementation 'commons-codec:commons-codec:1.16.0' implementation 'commons-codec:commons-codec:1.16.0'
implementation 'org.bouncycastle:bcprov-jdk15on:1.70' implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'com.github.FireMasterK.NewPipeExtractor:NewPipeExtractor:5518112dce594bb4cd07d8ed3391bcc5e688f829' implementation 'com.github.FireMasterK.NewPipeExtractor:NewPipeExtractor:8cf9a4aef0919df2ef1baafd30ab5bfefefc0844'
implementation 'com.github.FireMasterK:nanojson:9f4af3b739cc13f3d0d9d4b758bbe2b2ae7119d7' implementation 'com.github.FireMasterK:nanojson:9f4af3b739cc13f3d0d9d4b758bbe2b2ae7119d7'
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2' implementation 'com.fasterxml.jackson.core:jackson-core:2.15.2'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2' implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.2'
@ -42,9 +41,11 @@ dependencies {
implementation(platform("com.squareup.okhttp3:okhttp-bom:4.11.0")) implementation(platform("com.squareup.okhttp3:okhttp-bom:4.11.0"))
implementation 'com.squareup.okhttp3:okhttp' implementation 'com.squareup.okhttp3:okhttp'
implementation 'com.squareup.okhttp3:okhttp-brotli' implementation 'com.squareup.okhttp3:okhttp-brotli'
implementation 'io.sentry:sentry:6.28.0' implementation 'io.sentry:sentry:6.30.0'
implementation 'rocks.kavin:reqwest4j:1.0.12' implementation 'rocks.kavin:reqwest4j:1.0.12'
implementation 'io.minio:minio:8.5.6' implementation 'io.minio:minio:8.5.6'
compileOnly 'org.projectlombok:lombok:1.18.30'
annotationProcessor 'org.projectlombok:lombok:1.18.30'
} }
shadowJar { shadowJar {
@ -61,5 +62,5 @@ jar {
group = 'me.kavin.piped' group = 'me.kavin.piped'
version = '1.0' version = '1.0'
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_21

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://downloads.gradle.org/distributions/gradle-8.3-bin.zip distributionUrl=https\://downloads.gradle.org/distributions/gradle-8.4-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

14
gradlew vendored
View File

@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #( case $MAX_FD in #(
max*) max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) || MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit" warn "Could not query maximum file descriptor limit"
esac esac
@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #( '' | soft) :;; #(
*) *)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045 # shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" || ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD" warn "Could not set maximum file descriptor limit to $MAX_FD"
esac esac
@ -202,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command; # Collect all arguments for the java command:
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# shell script including quotes and variable substitutions, so put them in # and any embedded shellness will be escaped.
# double quotes to make sure that they get re-expanded; and # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# * put everything else in single quotes, so that it's not re-expanded. # treated as '${Hostname}' itself on the command line.
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \

View File

@ -18,7 +18,7 @@ import org.hibernate.StatelessSession;
import org.schabi.newpipe.extractor.NewPipe; import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.localization.ContentCountry; import org.schabi.newpipe.extractor.localization.ContentCountry;
import org.schabi.newpipe.extractor.localization.Localization; import org.schabi.newpipe.extractor.localization.Localization;
import org.schabi.newpipe.extractor.services.youtube.YoutubeThrottlingDecrypter; import org.schabi.newpipe.extractor.services.youtube.YoutubeJavaScriptPlayerManager;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor; import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor;
import java.util.*; import java.util.*;
@ -53,17 +53,17 @@ public class Main {
System.exit(1); System.exit(1);
} }
Multithreading.runAsync(() -> new Thread(new SyncRunner( Multithreading.runAsync(() -> Thread.ofVirtual().start(new SyncRunner(
new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build(), new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build(),
MATRIX_SERVER, MATRIX_SERVER,
MatrixHelper.MATRIX_TOKEN) MatrixHelper.MATRIX_TOKEN)
).start()); ));
new Timer().scheduleAtFixedRate(new TimerTask() { new Timer().scheduleAtFixedRate(new TimerTask() {
@Override @Override
public void run() { public void run() {
System.out.printf("ThrottlingCache: %o entries%n", YoutubeThrottlingDecrypter.getCacheSize()); System.out.printf("ThrottlingCache: %o entries%n", YoutubeJavaScriptPlayerManager.getThrottlingParametersCacheSize());
YoutubeThrottlingDecrypter.clearCache(); YoutubeJavaScriptPlayerManager.clearThrottlingParametersCache();
} }
}, 0, TimeUnit.MINUTES.toMillis(60)); }, 0, TimeUnit.MINUTES.toMillis(60));

View File

@ -32,7 +32,7 @@ import static me.kavin.piped.consts.Constants.YOUTUBE_SERVICE;
import static me.kavin.piped.consts.Constants.mapper; import static me.kavin.piped.consts.Constants.mapper;
import static me.kavin.piped.utils.CollectionUtils.collectPreloadedTabs; import static me.kavin.piped.utils.CollectionUtils.collectPreloadedTabs;
import static me.kavin.piped.utils.CollectionUtils.collectRelatedItems; import static me.kavin.piped.utils.CollectionUtils.collectRelatedItems;
import static me.kavin.piped.utils.URLUtils.rewriteURL; import static me.kavin.piped.utils.URLUtils.getLastThumbnail;
public class ChannelHandlers { public class ChannelHandlers {
public static byte[] channelResponse(String channelPath) throws Exception { public static byte[] channelResponse(String channelPath) throws Exception {
@ -77,7 +77,7 @@ public class ChannelHandlers {
Multithreading.runAsync(() -> { Multithreading.runAsync(() -> {
try { try {
MatrixHelper.sendEvent("video.piped.channel.info", new FederatedChannelInfo( MatrixHelper.sendEvent("video.piped.channel.info", new FederatedChannelInfo(
info.getId(), StringUtils.abbreviate(info.getName(), 100), info.getAvatarUrl(), info.isVerified()) info.getId(), StringUtils.abbreviate(info.getName(), 100), info.getAvatars().isEmpty() ? null : info.getAvatars().getLast().getUrl(), info.isVerified())
); );
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
@ -93,7 +93,7 @@ public class ChannelHandlers {
if (channel != null) { if (channel != null) {
ChannelHelpers.updateChannel(s, channel, StringUtils.abbreviate(info.getName(), 100), info.getAvatarUrl(), info.isVerified()); ChannelHelpers.updateChannel(s, channel, StringUtils.abbreviate(info.getName(), 100), info.getAvatars().isEmpty() ? null : info.getAvatars().getLast().getUrl(), info.isVerified());
Set<String> ids = tabInfo.getRelatedItems() Set<String> ids = tabInfo.getRelatedItems()
.stream() .stream()
@ -159,8 +159,8 @@ public class ChannelHandlers {
} }
}).toList(); }).toList();
final Channel channel = new Channel(info.getId(), info.getName(), rewriteURL(info.getAvatarUrl()), final Channel channel = new Channel(info.getId(), info.getName(), getLastThumbnail(info.getAvatars()),
rewriteURL(info.getBannerUrl()), info.getDescription(), info.getSubscriberCount(), info.isVerified(), getLastThumbnail(info.getBanners()), info.getDescription(), info.getSubscriberCount(), info.isVerified(),
nextpage, relatedStreams, tabs); nextpage, relatedStreams, tabs);
return mapper.writeValueAsBytes(channel); return mapper.writeValueAsBytes(channel);

View File

@ -30,8 +30,7 @@ import static java.nio.charset.StandardCharsets.UTF_8;
import static me.kavin.piped.consts.Constants.YOUTUBE_SERVICE; import static me.kavin.piped.consts.Constants.YOUTUBE_SERVICE;
import static me.kavin.piped.consts.Constants.mapper; import static me.kavin.piped.consts.Constants.mapper;
import static me.kavin.piped.utils.CollectionUtils.collectRelatedItems; import static me.kavin.piped.utils.CollectionUtils.collectRelatedItems;
import static me.kavin.piped.utils.URLUtils.rewriteURL; import static me.kavin.piped.utils.URLUtils.*;
import static me.kavin.piped.utils.URLUtils.substringYouTube;
public class PlaylistHandlers { public class PlaylistHandlers {
public static byte[] playlistResponse(String playlistId) throws Exception { public static byte[] playlistResponse(String playlistId) throws Exception {
@ -60,10 +59,10 @@ public class PlaylistHandlers {
nextpage = mapper.writeValueAsString(page); nextpage = mapper.writeValueAsString(page);
} }
final Playlist playlist = new Playlist(info.getName(), rewriteURL(info.getThumbnailUrl()), final Playlist playlist = new Playlist(info.getName(), getLastThumbnail(info.getThumbnails()),
info.getDescription().getContent(), rewriteURL(info.getBannerUrl()), nextpage, info.getDescription().getContent(), getLastThumbnail(info.getBanners()), nextpage,
info.getUploaderName().isEmpty() ? null : info.getUploaderName(), info.getUploaderName().isEmpty() ? null : info.getUploaderName(),
substringYouTube(info.getUploaderUrl()), rewriteURL(info.getUploaderAvatarUrl()), substringYouTube(info.getUploaderUrl()), getLastThumbnail(info.getUploaderAvatars()),
(int) info.getStreamCount(), relatedStreams); (int) info.getStreamCount(), relatedStreams);
return mapper.writeValueAsBytes(playlist); return mapper.writeValueAsBytes(playlist);

View File

@ -36,8 +36,7 @@ import java.util.concurrent.TimeoutException;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static me.kavin.piped.consts.Constants.YOUTUBE_SERVICE; import static me.kavin.piped.consts.Constants.YOUTUBE_SERVICE;
import static me.kavin.piped.consts.Constants.mapper; import static me.kavin.piped.consts.Constants.mapper;
import static me.kavin.piped.utils.URLUtils.rewriteURL; import static me.kavin.piped.utils.URLUtils.*;
import static me.kavin.piped.utils.URLUtils.substringYouTube;
import static org.schabi.newpipe.extractor.NewPipe.getPreferredContentCountry; import static org.schabi.newpipe.extractor.NewPipe.getPreferredContentCountry;
import static org.schabi.newpipe.extractor.NewPipe.getPreferredLocalization; import static org.schabi.newpipe.extractor.NewPipe.getPreferredLocalization;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonPostResponse; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonPostResponse;
@ -342,10 +341,10 @@ public class StreamHandlers {
if (comment.getReplies() != null) if (comment.getReplies() != null)
repliespage = mapper.writeValueAsString(comment.getReplies()); repliespage = mapper.writeValueAsString(comment.getReplies());
comments.add(new Comment(comment.getUploaderName(), rewriteURL(comment.getUploaderAvatarUrl()), comments.add(new Comment(comment.getUploaderName(), getLastThumbnail(comment.getUploaderAvatars()),
comment.getCommentId(), Optional.ofNullable(comment.getCommentText()).map(Description::getContent).orElse(null), comment.getTextualUploadDate(), comment.getCommentId(), Optional.ofNullable(comment.getCommentText()).map(Description::getContent).orElse(null), comment.getTextualUploadDate(),
substringYouTube(comment.getUploaderUrl()), repliespage, comment.getLikeCount(), comment.getReplyCount(), substringYouTube(comment.getUploaderUrl()), repliespage, comment.getLikeCount(), comment.getReplyCount(),
comment.isHeartedByUploader(), comment.isPinned(), comment.isUploaderVerified())); comment.isHeartedByUploader(), comment.isPinned(), comment.isUploaderVerified(), comment.hasCreatorReply(), comment.isChannelOwner()));
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
ExceptionHandler.handle(e); ExceptionHandler.handle(e);
} }
@ -380,10 +379,10 @@ public class StreamHandlers {
if (comment.getReplies() != null) if (comment.getReplies() != null)
repliespage = mapper.writeValueAsString(comment.getReplies()); repliespage = mapper.writeValueAsString(comment.getReplies());
comments.add(new Comment(comment.getUploaderName(), rewriteURL(comment.getUploaderAvatarUrl()), comments.add(new Comment(comment.getUploaderName(), getLastThumbnail(comment.getUploaderAvatars()),
comment.getCommentId(), Optional.ofNullable(comment.getCommentText()).map(Description::getContent).orElse(null), comment.getTextualUploadDate(), comment.getCommentId(), Optional.ofNullable(comment.getCommentText()).map(Description::getContent).orElse(null), comment.getTextualUploadDate(),
substringYouTube(comment.getUploaderUrl()), repliespage, comment.getLikeCount(), comment.getReplyCount(), substringYouTube(comment.getUploaderUrl()), repliespage, comment.getLikeCount(), comment.getReplyCount(),
comment.isHeartedByUploader(), comment.isPinned(), comment.isUploaderVerified())); comment.isHeartedByUploader(), comment.isPinned(), comment.isUploaderVerified(), comment.hasCreatorReply(), comment.isChannelOwner()));
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
ExceptionHandler.handle(e); ExceptionHandler.handle(e);
} }

View File

@ -268,7 +268,7 @@ public class AuthPlaylistHandlers {
channel = DatabaseHelper.saveChannel(channelId); channel = DatabaseHelper.saveChannel(channelId);
} }
video = new PlaylistVideo(videoId, info.getName(), info.getThumbnailUrl(), info.getDuration(), channel); video = new PlaylistVideo(videoId, info.getName(), info.getThumbnails().getLast().getUrl(), info.getDuration(), channel);
var tr = s.beginTransaction(); var tr = s.beginTransaction();
try { try {
@ -402,7 +402,7 @@ public class AuthPlaylistHandlers {
PlaylistInfo info = PlaylistInfo.getInfo(url); PlaylistInfo info = PlaylistInfo.getInfo(url);
var playlist = new me.kavin.piped.utils.obj.db.Playlist(info.getName(), user, info.getThumbnailUrl()); var playlist = new me.kavin.piped.utils.obj.db.Playlist(info.getName(), user, info.getThumbnails().getLast().getUrl());
List<StreamInfoItem> videos = new ObjectArrayList<>(info.getRelatedItems()); List<StreamInfoItem> videos = new ObjectArrayList<>(info.getRelatedItems());
@ -451,7 +451,7 @@ public class AuthPlaylistHandlers {
var channel = channelMap.get(channelId); var channel = channelMap.get(channelId);
playlist.getVideos().add(videoMap.computeIfAbsent(videoId, (key) -> new PlaylistVideo(videoId, video.getName(), video.getThumbnailUrl(), video.getDuration(), channel))); playlist.getVideos().add(videoMap.computeIfAbsent(videoId, (key) -> new PlaylistVideo(videoId, video.getName(), video.getThumbnails().getLast().getUrl(), video.getDuration(), channel)));
}); });
var tr = s.beginTransaction(); var tr = s.beginTransaction();

View File

@ -71,7 +71,7 @@ public class CollectionUtils {
return new Streams(info.getName(), info.getDescription().getContent(), return new Streams(info.getName(), info.getDescription().getContent(),
info.getTextualUploadDate(), info.getUploaderName(), substringYouTube(info.getUploaderUrl()), info.getTextualUploadDate(), info.getUploaderName(), substringYouTube(info.getUploaderUrl()),
rewriteURL(info.getUploaderAvatarUrl()), rewriteURL(info.getThumbnailUrl()), info.getDuration(), getLastThumbnail(info.getUploaderAvatars()), getLastThumbnail(info.getThumbnails()), info.getDuration(),
info.getViewCount(), info.getLikeCount(), info.getDislikeCount(), info.getUploaderSubscriberCount(), info.isUploaderVerified(), info.getViewCount(), info.getLikeCount(), info.getDislikeCount(), info.getUploaderSubscriberCount(), info.isUploaderVerified(),
audioStreams, videoStreams, relatedStreams, subtitles, livestream, rewriteVideoURL(info.getHlsUrl()), audioStreams, videoStreams, relatedStreams, subtitles, livestream, rewriteVideoURL(info.getHlsUrl()),
rewriteVideoURL(info.getDashMpdUrl()), null, info.getCategory(), info.getLicence(), rewriteVideoURL(info.getDashMpdUrl()), null, info.getCategory(), info.getLicence(),
@ -101,9 +101,9 @@ public class CollectionUtils {
StreamInfoItem item = (StreamInfoItem) o; StreamInfoItem item = (StreamInfoItem) o;
return new StreamItem(substringYouTube(item.getUrl()), item.getName(), return new StreamItem(substringYouTube(item.getUrl()), item.getName(),
rewriteURL(item.getThumbnailUrl()), getLastThumbnail(item.getThumbnails()),
item.getUploaderName(), substringYouTube(item.getUploaderUrl()), item.getUploaderName(), substringYouTube(item.getUploaderUrl()),
rewriteURL(item.getUploaderAvatarUrl()), item.getTextualUploadDate(), getLastThumbnail(item.getUploaderAvatars()), item.getTextualUploadDate(),
item.getShortDescription(), item.getDuration(), item.getShortDescription(), item.getDuration(),
item.getViewCount(), item.getUploadDate() != null ? item.getViewCount(), item.getUploadDate() != null ?
item.getUploadDate().offsetDateTime().toInstant().toEpochMilli() : -1, item.getUploadDate().offsetDateTime().toInstant().toEpochMilli() : -1,
@ -115,7 +115,7 @@ public class CollectionUtils {
PlaylistInfoItem item = (PlaylistInfoItem) o; PlaylistInfoItem item = (PlaylistInfoItem) o;
return new PlaylistItem(substringYouTube(item.getUrl()), item.getName(), return new PlaylistItem(substringYouTube(item.getUrl()), item.getName(),
rewriteURL(item.getThumbnailUrl()), getLastThumbnail(item.getThumbnails()),
item.getUploaderName(), substringYouTube(item.getUploaderUrl()), item.getUploaderName(), substringYouTube(item.getUploaderUrl()),
item.isUploaderVerified(), item.isUploaderVerified(),
item.getPlaylistType().name(), item.getStreamCount()); item.getPlaylistType().name(), item.getStreamCount());
@ -126,7 +126,7 @@ public class CollectionUtils {
ChannelInfoItem item = (ChannelInfoItem) o; ChannelInfoItem item = (ChannelInfoItem) o;
return new ChannelItem(substringYouTube(item.getUrl()), item.getName(), return new ChannelItem(substringYouTube(item.getUrl()), item.getName(),
rewriteURL(item.getThumbnailUrl()), getLastThumbnail(item.getThumbnails()),
item.getDescription(), item.getSubscriberCount(), item.getStreamCount(), item.getDescription(), item.getSubscriberCount(), item.getStreamCount(),
item.isVerified()); item.isVerified());
} }

View File

@ -192,7 +192,7 @@ public class DatabaseHelper {
} }
var channel = new Channel(channelId, StringUtils.abbreviate(info.getName(), 100), var channel = new Channel(channelId, StringUtils.abbreviate(info.getName(), 100),
info.getAvatarUrl(), info.isVerified()); info.getAvatars().isEmpty() ? null : info.getAvatars().getLast().getUrl(), info.isVerified());
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) { try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
var tr = s.beginTransaction(); var tr = s.beginTransaction();

View File

@ -5,7 +5,7 @@ import java.util.function.Supplier;
public class Multithreading { public class Multithreading {
private static final ExecutorService es = Executors.newCachedThreadPool(); private static final ExecutorService es = Executors.newVirtualThreadPerTaskExecutor();
private static final ExecutorService esLimited = Executors private static final ExecutorService esLimited = Executors
.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 8); .newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 8);
private static final ExecutorService esLimitedPubSub = Executors private static final ExecutorService esLimitedPubSub = Executors

View File

@ -2,12 +2,14 @@ package me.kavin.piped.utils;
import me.kavin.piped.consts.Constants; import me.kavin.piped.consts.Constants;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.schabi.newpipe.extractor.Image;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.List;
public class URLUtils { public class URLUtils {
@ -37,6 +39,10 @@ public class URLUtils {
return rewriteURL(old, Constants.IMAGE_PROXY_PART); return rewriteURL(old, Constants.IMAGE_PROXY_PART);
} }
public static String getLastThumbnail(final List<Image> thumbnails) {
return thumbnails.isEmpty() ? null : rewriteURL(thumbnails.getLast().getUrl());
}
public static String rewriteVideoURL(final String old) { public static String rewriteVideoURL(final String old) {
return rewriteURL(old, Constants.PROXY_PART); return rewriteURL(old, Constants.PROXY_PART);
} }

View File

@ -50,7 +50,7 @@ public class VideoHelpers {
if (!DatabaseHelper.doesVideoExist(s, info.getId())) { if (!DatabaseHelper.doesVideoExist(s, info.getId())) {
Video video = new Video(info.getId(), info.getName(), info.getViewCount(), info.getDuration(), Video video = new Video(info.getId(), info.getName(), info.getViewCount(), info.getDuration(),
Math.max(infoTime, time), info.getThumbnailUrl(), info.isShortFormContent(), channel); Math.max(infoTime, time), info.getThumbnails().getLast().getUrl(), info.isShortFormContent(), channel);
insertVideo(video); insertVideo(video);
return; return;
@ -81,7 +81,7 @@ public class VideoHelpers {
boolean isShort = extractor.isShortFormContent() || isShort(extractor.getId()); boolean isShort = extractor.isShortFormContent() || isShort(extractor.getId());
Video video = new Video(extractor.getId(), extractor.getName(), extractor.getViewCount(), extractor.getLength(), Video video = new Video(extractor.getId(), extractor.getName(), extractor.getViewCount(), extractor.getLength(),
Math.max(infoTime, time), extractor.getThumbnailUrl(), isShort, channel); Math.max(infoTime, time), extractor.getThumbnails().getLast().getUrl(), isShort, channel);
insertVideo(video); insertVideo(video);

View File

@ -4,10 +4,10 @@ public class Comment {
public String author, thumbnail, commentId, commentText, commentedTime, commentorUrl, repliesPage; public String author, thumbnail, commentId, commentText, commentedTime, commentorUrl, repliesPage;
public int likeCount, replyCount; public int likeCount, replyCount;
public boolean hearted, pinned, verified; public boolean hearted, pinned, verified, creatorReplied, channelOwner;
public Comment(String author, String thumbnail, String commentId, String commentText, String commentedTime, public Comment(String author, String thumbnail, String commentId, String commentText, String commentedTime,
String commentorUrl, String repliesPage, int likeCount, int replyCount, boolean hearted, boolean pinned, boolean verified) { String commentorUrl, String repliesPage, int likeCount, int replyCount, boolean hearted, boolean pinned, boolean verified, boolean creatorReplied, boolean channelOwner) {
this.author = author; this.author = author;
this.thumbnail = thumbnail; this.thumbnail = thumbnail;
this.commentId = commentId; this.commentId = commentId;
@ -20,5 +20,7 @@ public class Comment {
this.hearted = hearted; this.hearted = hearted;
this.pinned = pinned; this.pinned = pinned;
this.verified = verified; this.verified = verified;
this.creatorReplied = creatorReplied;
this.channelOwner = channelOwner;
} }
} }