mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-12-13 13:50:28 +05:30
Implement part of unauthenticated subscription api.
This commit is contained in:
parent
a9295f82b6
commit
02067518b0
@ -15,11 +15,10 @@ import jakarta.persistence.criteria.JoinType;
|
||||
import jakarta.persistence.criteria.Root;
|
||||
import me.kavin.piped.consts.Constants;
|
||||
import me.kavin.piped.ipfs.IPFS;
|
||||
import me.kavin.piped.utils.obj.Channel;
|
||||
import me.kavin.piped.utils.obj.Playlist;
|
||||
import me.kavin.piped.utils.obj.*;
|
||||
import me.kavin.piped.utils.obj.db.PlaylistVideo;
|
||||
import me.kavin.piped.utils.obj.db.PubSub;
|
||||
import me.kavin.piped.utils.obj.db.User;
|
||||
import me.kavin.piped.utils.obj.db.Video;
|
||||
import me.kavin.piped.utils.obj.db.*;
|
||||
import me.kavin.piped.utils.obj.search.SearchChannel;
|
||||
import me.kavin.piped.utils.obj.search.SearchPlaylist;
|
||||
import me.kavin.piped.utils.resp.*;
|
||||
@ -959,6 +958,131 @@ public class ResponseHelper {
|
||||
return mapper.writeValueAsBytes(new AuthenticationFailureResponse());
|
||||
}
|
||||
|
||||
public static byte[] unauthenticatedFeedResponse(String[] channelIds) throws Exception {
|
||||
|
||||
Set<String> filtered = Arrays.stream(channelIds)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.filter(StringUtils::isAlphanumeric)
|
||||
.filter(id -> id.startsWith("UC"))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
if (filtered.isEmpty())
|
||||
return mapper.writeValueAsBytes(mapper.createObjectNode()
|
||||
.put("error", "No valid channel IDs provided"));
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
|
||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||
|
||||
// Get all videos from subscribed channels, with channel info
|
||||
CriteriaQuery<Video> criteria = cb.createQuery(Video.class);
|
||||
var root = criteria.from(Video.class);
|
||||
root.fetch("channel", JoinType.INNER);
|
||||
|
||||
criteria.select(root)
|
||||
.where(cb.and(
|
||||
root.get("channel").in(filtered)
|
||||
))
|
||||
.orderBy(cb.desc(root.get("uploaded")));
|
||||
|
||||
List<StreamItem> feedItems = new ObjectArrayList<>();
|
||||
|
||||
List<Video> videos = s.createQuery(criteria)
|
||||
.setTimeout(20)
|
||||
.setMaxResults(100)
|
||||
.list();
|
||||
|
||||
SyndFeed feed = new SyndFeedImpl();
|
||||
feed.setFeedType("atom_1.0");
|
||||
feed.setTitle("Piped - Feed");
|
||||
feed.setDescription("Piped's RSS unauthenticated subscription feed.");
|
||||
feed.setUri(Constants.FRONTEND_URL + "/feed");
|
||||
feed.setPublishedDate(new Date());
|
||||
|
||||
final List<SyndEntry> entries = new ObjectArrayList<>();
|
||||
|
||||
for (Video video : videos) {
|
||||
var channel = video.getChannel();
|
||||
SyndEntry entry = new SyndEntryImpl();
|
||||
|
||||
SyndPerson person = new SyndPersonImpl();
|
||||
person.setName(channel.getUploader());
|
||||
person.setUri(Constants.FRONTEND_URL + "/channel/" + channel.getUploaderId());
|
||||
|
||||
entry.setAuthors(Collections.singletonList(person));
|
||||
|
||||
entry.setLink(Constants.FRONTEND_URL + "/watch?v=" + video.getId());
|
||||
entry.setUri(Constants.FRONTEND_URL + "/watch?v=" + video.getId());
|
||||
entry.setTitle(video.getTitle());
|
||||
entry.setPublishedDate(new Date(video.getUploaded()));
|
||||
entries.add(entry);
|
||||
}
|
||||
|
||||
feed.setEntries(entries);
|
||||
|
||||
updateSubscribedTime(filtered);
|
||||
|
||||
return new SyndFeedOutput().outputString(feed).getBytes(UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] unauthenticatedFeedResponseRSS(String[] channelIds) throws Exception {
|
||||
|
||||
Set<String> filtered = Arrays.stream(channelIds)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.filter(StringUtils::isAlphanumeric)
|
||||
.filter(id -> id.startsWith("UC"))
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
if (filtered.isEmpty())
|
||||
return mapper.writeValueAsBytes(Collections.EMPTY_LIST);
|
||||
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
|
||||
CriteriaBuilder cb = s.getCriteriaBuilder();
|
||||
|
||||
// Get all videos from subscribed channels, with channel info
|
||||
CriteriaQuery<Video> criteria = cb.createQuery(Video.class);
|
||||
var root = criteria.from(Video.class);
|
||||
root.fetch("channel", JoinType.INNER);
|
||||
|
||||
criteria.select(root)
|
||||
.where(cb.and(
|
||||
root.get("channel").in(filtered)
|
||||
))
|
||||
.orderBy(cb.desc(root.get("uploaded")));
|
||||
|
||||
List<StreamItem> feedItems = new ObjectArrayList<>();
|
||||
|
||||
for (Video video : s.createQuery(criteria).setTimeout(20).list()) {
|
||||
var channel = video.getChannel();
|
||||
|
||||
feedItems.add(new StreamItem("/watch?v=" + video.getId(), video.getTitle(),
|
||||
rewriteURL(video.getThumbnail()), channel.getUploader(), "/channel/" + channel.getUploaderId(),
|
||||
rewriteURL(channel.getUploaderAvatar()), null, null, video.getDuration(), video.getViews(),
|
||||
video.getUploaded(), channel.isVerified()));
|
||||
}
|
||||
|
||||
updateSubscribedTime(filtered);
|
||||
|
||||
return mapper.writeValueAsBytes(feedItems);
|
||||
}
|
||||
}
|
||||
|
||||
private static void updateSubscribedTime(Collection<String> channelIds) {
|
||||
Multithreading.runAsync(() -> {
|
||||
try (StatelessSession s = DatabaseSessionFactory.createStatelessSession()) {
|
||||
var cb = s.getCriteriaBuilder();
|
||||
var cu = cb.createCriteriaUpdate(UnauthenticatedSubscription.class);
|
||||
var root = cu.getRoot();
|
||||
cu.where(root.get("id").in(channelIds)).set(root.get("lastSubscribed"), System.currentTimeMillis());
|
||||
s.createMutationQuery(cu).executeUpdate();
|
||||
} catch (Exception e) {
|
||||
ExceptionHandler.handle(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static byte[] importResponse(String session, String[] channelIds, boolean override) throws IOException {
|
||||
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
package me.kavin.piped.utils.obj.db;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "unauthenticated_subscriptions", indexes = {
|
||||
@Index(columnList = "id", name = "unauthenticated_subscriptions_id_idx"),
|
||||
@Index(columnList = "subscribed_at", name = "unauthenticated_subscriptions_subscribed_at_idx")
|
||||
})
|
||||
public class UnauthenticatedSubscription {
|
||||
|
||||
public UnauthenticatedSubscription() {
|
||||
}
|
||||
|
||||
public UnauthenticatedSubscription(String id, String channelId, long subscribedAt) {
|
||||
this.id = id;
|
||||
this.subscribedAt = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Id
|
||||
@Column(name = "id", unique = true, nullable = false, length = 24)
|
||||
private String id;
|
||||
|
||||
@Column(name = "subscribed_at", nullable = false)
|
||||
private long subscribedAt;
|
||||
|
||||
public long getSubscribedAt() {
|
||||
return subscribedAt;
|
||||
}
|
||||
|
||||
public void setSubscribedAt(long subscribedAt) {
|
||||
this.subscribedAt = subscribedAt;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user