Piped-Backend/src/main/java/me/kavin/piped/Main.java

160 lines
6.5 KiB
Java

package me.kavin.piped;
import io.activej.inject.Injector;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import me.kavin.piped.consts.Constants;
import me.kavin.piped.utils.*;
import me.kavin.piped.utils.obj.db.*;
import org.hibernate.Session;
import org.hibernate.StatelessSession;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.localization.Localization;
import org.schabi.newpipe.extractor.services.youtube.YoutubeThrottlingDecrypter;
import org.schabi.newpipe.extractor.services.youtube.extractors.YoutubeStreamExtractor;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class Main {
public static void main(String[] args) throws Exception {
NewPipe.init(new DownloaderImpl(), new Localization("en", "US"));
YoutubeStreamExtractor.forceFetchAndroidClient(true);
YoutubeStreamExtractor.forceFetchIosClient(true);
Injector.useSpecializer();
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
System.out.printf("ThrottlingCache: %o entries%n", YoutubeThrottlingDecrypter.getCacheSize());
YoutubeThrottlingDecrypter.clearCache();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0, TimeUnit.MINUTES.toMillis(60));
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);
}
if (Constants.DISABLE_TIMERS)
return;
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
CriteriaBuilder cb = s.getCriteriaBuilder();
CriteriaQuery<PubSub> criteria = cb.createQuery(PubSub.class);
var root = criteria.from(PubSub.class);
var userSq = criteria.subquery(User.class);
var userRoot = userSq.from(User.class);
userSq.select(userRoot.get("subscribed_ids"));
var subquery = criteria.subquery(UnauthenticatedSubscription.class);
var subRoot = subquery.from(UnauthenticatedSubscription.class);
subquery.select(subRoot.get("id"))
.where(cb.gt(subRoot.get("subscribedAt"), System.currentTimeMillis() - TimeUnit.DAYS.toMillis(Constants.SUBSCRIPTIONS_EXPIRY)));
criteria.select(root)
.where(cb.and(
cb.lessThan(root.get("subbedAt"), System.currentTimeMillis() - TimeUnit.DAYS.toMillis(4)),
cb.or(
root.get("id").in(userSq),
root.get("id").in(subquery)
)
)
);
List<PubSub> pubSubList = s.createQuery(criteria).list();
Collections.shuffle(pubSubList);
pubSubList.stream().parallel()
.forEach(pubSub -> {
if (pubSub != null)
Multithreading.runAsyncLimitedPubSub(() -> {
try {
ResponseHelper.subscribePubSub(pubSub.getId());
} catch (IOException e) {
ExceptionHandler.handle(e);
}
});
});
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0, TimeUnit.MINUTES.toMillis(90));
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
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)));
var tr = s.beginTransaction();
var query = s.createMutationQuery(cd);
System.out.printf("Cleanup: Removed %o old videos%n", query.executeUpdate());
tr.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
}, 0, TimeUnit.MINUTES.toMillis(60));
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);
subQuery.select(subRoot.join("videos").get("id"));
pvQuery.where(cb.not(pvRoot.get("id").in(subQuery)));
var tr = s.beginTransaction();
s.createMutationQuery(pvQuery).executeUpdate();
tr.commit();
}
}
}, 0, TimeUnit.MINUTES.toMillis(60));
}
}