2020-11-12 21:19:45 +00:00
|
|
|
package me.kavin.piped;
|
|
|
|
|
2021-03-29 13:59:10 +00:00
|
|
|
import io.activej.inject.Injector;
|
2022-10-30 19:56:04 +00:00
|
|
|
import io.sentry.Sentry;
|
2022-06-17 15:37:10 +00:00
|
|
|
import jakarta.persistence.criteria.CriteriaBuilder;
|
2022-01-31 04:17:16 +00:00
|
|
|
import me.kavin.piped.consts.Constants;
|
2022-10-29 21:00:55 +00:00
|
|
|
import me.kavin.piped.server.ServerLauncher;
|
2022-07-02 17:13:58 +00:00
|
|
|
import me.kavin.piped.utils.*;
|
2022-11-13 00:12:55 +00:00
|
|
|
import me.kavin.piped.utils.matrix.SyncRunner;
|
|
|
|
import me.kavin.piped.utils.obj.MatrixHelper;
|
2022-09-17 14:59:26 +00:00
|
|
|
import me.kavin.piped.utils.obj.db.PlaylistVideo;
|
|
|
|
import me.kavin.piped.utils.obj.db.Video;
|
2022-11-13 00:12:55 +00:00
|
|
|
import okhttp3.OkHttpClient;
|
2022-07-19 08:20:42 +00:00
|
|
|
import org.hibernate.Session;
|
2022-07-04 05:42:01 +00:00
|
|
|
import org.hibernate.StatelessSession;
|
2022-01-31 04:17:16 +00:00
|
|
|
import org.schabi.newpipe.extractor.NewPipe;
|
2022-09-10 20:05:10 +00:00
|
|
|
import org.schabi.newpipe.extractor.localization.ContentCountry;
|
2022-01-31 04:17:16 +00:00
|
|
|
import org.schabi.newpipe.extractor.localization.Localization;
|
2022-03-14 14:54:47 +00:00
|
|
|
import org.schabi.newpipe.extractor.services.youtube.YoutubeThrottlingDecrypter;
|
2022-04-24 17:01:00 +00:00
|
|
|
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor;
|
2022-01-31 04:17:16 +00:00
|
|
|
|
2022-09-10 20:05:10 +00:00
|
|
|
import java.util.*;
|
2022-01-31 04:17:16 +00:00
|
|
|
import java.util.concurrent.TimeUnit;
|
2022-09-17 14:59:26 +00:00
|
|
|
import java.util.stream.Collectors;
|
2020-11-12 21:19:45 +00:00
|
|
|
|
2022-11-13 00:12:55 +00:00
|
|
|
import static me.kavin.piped.consts.Constants.MATRIX_SERVER;
|
|
|
|
|
2020-11-12 21:19:45 +00:00
|
|
|
public class Main {
|
|
|
|
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
|
|
2022-09-10 20:05:10 +00:00
|
|
|
NewPipe.init(new DownloaderImpl(), new Localization("en", "US"), ContentCountry.DEFAULT, Multithreading.getCachedExecutor());
|
2022-09-07 07:29:11 +00:00
|
|
|
YoutubeStreamExtractor.forceFetchAndroidClient(true);
|
2022-04-24 17:01:00 +00:00
|
|
|
YoutubeStreamExtractor.forceFetchIosClient(true);
|
2020-11-12 21:19:45 +00:00
|
|
|
|
2022-10-30 22:26:20 +00:00
|
|
|
Sentry.init(options -> {
|
|
|
|
options.setDsn(Constants.SENTRY_DSN);
|
|
|
|
options.setRelease(Constants.VERSION);
|
|
|
|
options.addIgnoredExceptionForType(ErrorResponse.class);
|
|
|
|
options.setTracesSampleRate(0.1);
|
|
|
|
});
|
2022-10-30 19:56:04 +00:00
|
|
|
|
2021-03-29 13:59:10 +00:00
|
|
|
Injector.useSpecializer();
|
2021-02-24 09:52:29 +00:00
|
|
|
|
2022-11-15 01:41:15 +00:00
|
|
|
Multithreading.runAsync(() -> new Thread(new SyncRunner(
|
2022-11-13 00:12:55 +00:00
|
|
|
new OkHttpClient.Builder().readTimeout(60, TimeUnit.SECONDS).build(),
|
|
|
|
MATRIX_SERVER,
|
|
|
|
MatrixHelper.MATRIX_TOKEN)
|
2022-11-15 01:41:15 +00:00
|
|
|
).start());
|
2022-11-13 00:12:55 +00:00
|
|
|
|
2022-06-25 09:19:06 +00:00
|
|
|
new Timer().scheduleAtFixedRate(new TimerTask() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2022-10-30 19:56:04 +00:00
|
|
|
System.out.printf("ThrottlingCache: %o entries%n", YoutubeThrottlingDecrypter.getCacheSize());
|
|
|
|
YoutubeThrottlingDecrypter.clearCache();
|
2022-06-25 09:19:06 +00:00
|
|
|
}
|
|
|
|
}, 0, TimeUnit.MINUTES.toMillis(60));
|
|
|
|
|
2022-07-19 08:20:42 +00:00
|
|
|
if (!Constants.DISABLE_SERVER)
|
|
|
|
new Thread(() -> {
|
|
|
|
try {
|
|
|
|
new ServerLauncher().launch(args);
|
|
|
|
} catch (Exception e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}).start();
|
|
|
|
|
|
|
|
try (Session ignored = DatabaseSessionFactory.createSession()) {
|
|
|
|
System.out.println("Database connection is ready!");
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
System.exit(1);
|
|
|
|
}
|
2022-06-25 09:19:06 +00:00
|
|
|
|
|
|
|
if (Constants.DISABLE_TIMERS)
|
|
|
|
return;
|
|
|
|
|
2021-07-16 22:40:46 +00:00
|
|
|
new Timer().scheduleAtFixedRate(new TimerTask() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2022-07-04 05:42:01 +00:00
|
|
|
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
2021-07-16 22:40:46 +00:00
|
|
|
|
2022-09-17 14:59:26 +00:00
|
|
|
final Random random = new Random();
|
|
|
|
|
|
|
|
s.createNativeQuery("SELECT id FROM pubsub WHERE subbed_at < :subbedTime AND id IN (" +
|
|
|
|
"SELECT DISTINCT channel FROM users_subscribed" +
|
|
|
|
" UNION " +
|
|
|
|
"SELECT id FROM unauthenticated_subscriptions WHERE subscribed_at > :unauthSubbed" +
|
|
|
|
")", String.class)
|
|
|
|
.setParameter("subbedTime", System.currentTimeMillis() - TimeUnit.DAYS.toMillis(4))
|
|
|
|
.setParameter("unauthSubbed", System.currentTimeMillis() - TimeUnit.DAYS.toMillis(Constants.SUBSCRIPTIONS_EXPIRY))
|
|
|
|
.stream()
|
|
|
|
.filter(Objects::nonNull)
|
|
|
|
.collect(Collectors.toUnmodifiableSet())
|
|
|
|
.stream()
|
|
|
|
.sorted(Comparator.comparingInt(o -> random.nextInt()))
|
|
|
|
.parallel()
|
|
|
|
.forEach(id -> Multithreading.runAsyncLimitedPubSub(() -> {
|
|
|
|
try {
|
2022-10-29 21:00:55 +00:00
|
|
|
PubSubHelper.subscribePubSub(id);
|
2022-12-10 04:56:31 +00:00
|
|
|
} catch (Exception e) {
|
2022-09-17 14:59:26 +00:00
|
|
|
ExceptionHandler.handle(e);
|
|
|
|
}
|
|
|
|
}));
|
2021-07-16 22:40:46 +00:00
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 0, TimeUnit.MINUTES.toMillis(90));
|
|
|
|
|
|
|
|
new Timer().scheduleAtFixedRate(new TimerTask() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2022-07-05 13:18:33 +00:00
|
|
|
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
2021-07-16 22:40:46 +00:00
|
|
|
|
2022-07-04 06:09:20 +00:00
|
|
|
var cb = s.getCriteriaBuilder();
|
|
|
|
var cd = cb.createCriteriaDelete(Video.class);
|
|
|
|
var root = cd.from(Video.class);
|
|
|
|
cd.where(cb.lessThan(root.get("uploaded"), System.currentTimeMillis() - TimeUnit.DAYS.toMillis(Constants.FEED_RETENTION)));
|
|
|
|
|
2022-07-04 17:44:16 +00:00
|
|
|
var tr = s.beginTransaction();
|
2021-07-16 22:40:46 +00:00
|
|
|
|
2022-07-04 06:09:20 +00:00
|
|
|
var query = s.createMutationQuery(cd);
|
2021-07-16 22:40:46 +00:00
|
|
|
|
2022-07-05 13:18:33 +00:00
|
|
|
System.out.printf("Cleanup: Removed %o old videos%n", query.executeUpdate());
|
2021-07-16 22:40:46 +00:00
|
|
|
|
|
|
|
tr.commit();
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 0, TimeUnit.MINUTES.toMillis(60));
|
|
|
|
|
2022-07-07 23:06:39 +00:00
|
|
|
new Timer().scheduleAtFixedRate(new TimerTask() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
|
|
|
|
|
|
|
CriteriaBuilder cb = s.getCriteriaBuilder();
|
|
|
|
|
|
|
|
var pvQuery = cb.createCriteriaDelete(PlaylistVideo.class);
|
|
|
|
var pvRoot = pvQuery.from(PlaylistVideo.class);
|
|
|
|
|
|
|
|
var subQuery = pvQuery.subquery(me.kavin.piped.utils.obj.db.Playlist.class);
|
|
|
|
var subRoot = subQuery.from(me.kavin.piped.utils.obj.db.Playlist.class);
|
|
|
|
|
2022-11-13 00:12:55 +00:00
|
|
|
subQuery.select(subRoot.join("videos").get("id")).distinct(true);
|
2022-07-07 23:06:39 +00:00
|
|
|
|
|
|
|
pvQuery.where(cb.not(pvRoot.get("id").in(subQuery)));
|
|
|
|
|
|
|
|
var tr = s.beginTransaction();
|
|
|
|
s.createMutationQuery(pvQuery).executeUpdate();
|
|
|
|
tr.commit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, 0, TimeUnit.MINUTES.toMillis(60));
|
|
|
|
|
2021-02-24 10:26:26 +00:00
|
|
|
}
|
2020-11-12 21:19:45 +00:00
|
|
|
}
|