aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPinapelz <donaldshan1@outlook.com>2023-04-16 12:34:40 -0700
committerPinapelz <donaldshan1@outlook.com>2023-04-16 12:34:40 -0700
commit9c13697880b7dcb35c5ecf541e639998925380eb (patch)
tree20685c91be753e3f882c44e677b3950fd9121502 /src
parent01fa51f3fde9063b1a78c48ca32e9e121c61da2f (diff)
Change package path to domain url1.1
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/pinapelz/Holodex.java257
-rw-r--r--src/main/java/com/pinapelz/HolodexException.java25
-rw-r--r--src/main/java/com/pinapelz/HolodexService.java212
-rw-r--r--src/main/java/com/pinapelz/datatypes/Channel.java21
-rw-r--r--src/main/java/com/pinapelz/datatypes/Comment.java10
-rw-r--r--src/main/java/com/pinapelz/datatypes/CommentSearchResult.java11
-rw-r--r--src/main/java/com/pinapelz/datatypes/Paginated.java15
-rw-r--r--src/main/java/com/pinapelz/datatypes/SimpleChannel.java16
-rw-r--r--src/main/java/com/pinapelz/datatypes/SimpleCommentVideo.java21
-rw-r--r--src/main/java/com/pinapelz/datatypes/SimpleVideo.java26
-rw-r--r--src/main/java/com/pinapelz/datatypes/Video.java24
-rw-r--r--src/main/java/com/pinapelz/datatypes/VideoSearchResult.java11
-rw-r--r--src/main/java/com/pinapelz/factory/VideoSearchResultConverterFactory.java51
-rw-r--r--src/main/java/com/pinapelz/query/ChannelQueryBuilder.java79
-rw-r--r--src/main/java/com/pinapelz/query/CommentSearchQueryBuilder.java134
-rw-r--r--src/main/java/com/pinapelz/query/VideoByVideoIdQueryBuilder.java39
-rw-r--r--src/main/java/com/pinapelz/query/VideoQueryBuilder.java157
-rw-r--r--src/main/java/com/pinapelz/query/VideoSearchQueryBuilder.java134
-rw-r--r--src/main/java/com/pinapelz/query/VideosByChannelIDQueryBuilder.java78
19 files changed, 1321 insertions, 0 deletions
diff --git a/src/main/java/com/pinapelz/Holodex.java b/src/main/java/com/pinapelz/Holodex.java
new file mode 100644
index 0000000..70020c2
--- /dev/null
+++ b/src/main/java/com/pinapelz/Holodex.java
@@ -0,0 +1,257 @@
+package com.pinapelz;
+
+import com.google.gson.Gson;
+import com.pinapelz.datatypes.*;
+import com.pinapelz.query.*;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import retrofit2.Call;
+import retrofit2.Response;
+import retrofit2.Retrofit;
+import retrofit2.converter.jackson.JacksonConverterFactory;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.lang.reflect.Field;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * The class for interacting with the Holodex API
+ */
+public class Holodex {
+ private HolodexService service;
+ private int readTimeout = 35;
+ private int writeTimeout = 35;
+
+ /**
+ * Instantiates a new Holodex with the default base url
+ *
+ * @param apiKey the api key
+ */
+ public Holodex(String apiKey) {
+ initializeHolodexService(apiKey, "https://holodex.net");
+ }
+
+ /**
+ * Instantiates a new Holodex with a custom base url
+ *
+ * @param apiKey the api key
+ * @param baseUrl the base url
+ */
+ public Holodex(String apiKey, String baseUrl) {
+ initializeHolodexService(apiKey, baseUrl);
+ }
+
+ private void initializeHolodexService(String apiKey, String baseUrl){
+ OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
+ .writeTimeout(writeTimeout, TimeUnit.SECONDS)
+ .readTimeout(readTimeout, TimeUnit.SECONDS);
+ httpClient.addInterceptor(chain -> {
+ Request original = chain.request();
+ Request request = original.newBuilder()
+ .header("X-APIKEY", apiKey)
+ .method(original.method(), original.body())
+ .build();
+ return chain.proceed(request);
+ });
+ Retrofit retrofit = new Retrofit.Builder()
+ .baseUrl(baseUrl)
+ .addConverterFactory(JacksonConverterFactory.create())
+ .client(httpClient.build())
+ .build();
+ service = retrofit.create(HolodexService.class);
+ }
+
+ private Holodex setReadTimeout(int readTimeout) {
+ this.readTimeout = readTimeout;
+ return this;
+ }
+
+ private Holodex setWriteTimeout(int writeTimeout) {
+ this.writeTimeout = writeTimeout;
+ return this;
+ }
+
+ /**
+ * Gets a list of upcoming and/or live SimpleVideos matching the VideoQueryBuilder attributes
+ *
+ * @param queryBuilder the query builder
+ * @return A list of upcoming and/or live SimpleVideos
+ * @throws HolodexException the holodex exception
+ */
+ public List<SimpleVideo> getLiveAndUpcomingVideos(VideoQueryBuilder queryBuilder) throws HolodexException {
+ Call<List<SimpleVideo>> call = service.getLiveVideos(queryBuilder.getChannelId(), queryBuilder.getId(),
+ queryBuilder.getInclude(), queryBuilder.getLang(),
+ queryBuilder.getLimit(), queryBuilder.getMaxUpcomingHours(),
+ queryBuilder.getMentionedChannelId(), queryBuilder.getOffset(),
+ queryBuilder.getOrder(), queryBuilder.getOrg(),
+ queryBuilder.getPaginated(), queryBuilder.getSort(),
+ queryBuilder.getStatus(), queryBuilder.getTopic(),
+ queryBuilder.getType());
+ return executeCall(call);
+ }
+
+ /**
+ * Gets a list of videos matching the VideoQueryBuilder attributes
+ *
+ * @param queryBuilder the query builder
+ * @return list of videos
+ * @throws HolodexException the holodex exception
+ */
+ public List<Video> getVideos(VideoQueryBuilder queryBuilder) throws HolodexException {
+ Call<List<Video>> call = service.getVideos(queryBuilder.getChannelId(), queryBuilder.getId(),
+ queryBuilder.getInclude(), queryBuilder.getLang(),
+ queryBuilder.getLimit(), queryBuilder.getMaxUpcomingHours(),
+ queryBuilder.getMentionedChannelId(), queryBuilder.getOffset(),
+ queryBuilder.getOrder(), queryBuilder.getOrg(),
+ queryBuilder.getPaginated(), queryBuilder.getSort(),
+ queryBuilder.getStatus(), queryBuilder.getTopic(),
+ queryBuilder.getType());
+ return executeCall(call);
+ }
+
+ /**
+ * Gets information about a channel when given a channel id
+ *
+ * @param channelId the channel id
+ * @return the Channel
+ * @throws HolodexException the holodex exception
+ */
+ public Channel getChannel(String channelId) throws HolodexException {
+ Call<Channel> call = service.getChannel(channelId);
+ return executeCall(call);
+ }
+
+ /**
+ * Gets a list of Videos matching the VideoByVideoIdQueryBuilder attributes for a specific channel
+ * Used for when the channel id is known
+ *
+ * @param query the query
+ * @return List of videos matching the query
+ * @throws HolodexException the holodex exception
+ */
+ public List<Video> getVideosByChannelId(VideosByChannelIDQueryBuilder query) throws HolodexException {
+ Call<List<Video>> call = service.getVideosByChannelId(query.getChannelId(), query.getType(), query.getInclude(),
+ query.getLang(), query.getLimit(), query.getOffset(), query.getPaginated());
+ return executeCall(call);
+
+ }
+
+ /**
+ * Gets upcoming and live videos from an array of channel ids
+ * Response will contain videos from all channels together
+ * This should be used when there is a set of channels that need to be queried
+ *
+ * @param channels the channel ids to get videos from
+ * @return List of live and/or upcoming videos where the channel id is the author
+ * @throws HolodexException the holodex exception
+ */
+ public List<Video> getVideosFromChannels(String[] channels) throws HolodexException{
+ String channelsString = String.join(",", channels);
+ Call<List<Video>> call = service.getVideosFromChannels(channelsString);
+ return executeCall(call);
+ }
+
+ /**
+ * Gets the video matching the VideoByVideoIdQueryBuilder attributes
+ *
+ * @param query the query
+ * @return Video matching the query
+ * @throws HolodexException holodex exception
+ */
+ public Video getVideo(VideoByVideoIdQueryBuilder query) throws HolodexException {
+ Call<Video> call = service.getVideo(query.getVideoId(), query.getLang(), query.getC());
+ return executeCall(call);
+ }
+
+ /**
+ * Gets a list of channels the match the ChannelQueryBuilder attributes
+ *
+ * @param query the query
+ * @return List of channels matching the query
+ * @throws HolodexException the holodex exception
+ */
+ public List<Channel> getChannels(ChannelQueryBuilder query) throws HolodexException{
+ Call<List<Channel>> call = service.getChannels(query.getLimit(), query.getOffset(), query.getType(),
+ query.getLang(), query.getOrder(), query.getOrg(), query.getSort()
+ );
+ return executeCall(call);
+ }
+
+ /**
+ * Sends a POST request to search for videos matching the VideoSearchQueryBuilder attributes
+ * If the query is paginated, the response will be a VideoSearchResult object
+ * If the query is not paginated, the response will be a list of SimpleVideo objects
+ * @param query
+ * @return
+ * @throws HolodexException
+ */
+
+ public Object searchVideo(VideoSearchQueryBuilder query) throws HolodexException {
+ Map<String, Object> payload = toMap(query);
+ RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
+ new Gson().toJson(payload));
+ if(query.isPaginated()) {
+ Call<VideoSearchResult> call = service.postPaginatedVideoSearch(body);
+ return executeCall(call);
+ }
+ Call<List<SimpleVideo>> call = service.postVideoSearch(body);
+ return executeCall(call);
+
+ }
+
+ /**
+ * Sends a POST request to search for comments matching the CommentSearchQueryBuilder attributes
+ * If the query is paginated, the response will be a CommentSearchResult object
+ * If the query is not paginated, the response will be a list of SimpleCommentVideo objects
+ * @param query
+ * @return
+ * @throws HolodexException
+ */
+ public Object searchComment(CommentSearchQueryBuilder query) throws HolodexException{
+ Map<String, Object> payload = toMap(query);
+ RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
+ new Gson().toJson(payload));
+ if(query.isPaginated()) {
+ Call<CommentSearchResult> call = service.postPaginatedCommentSearch(body);
+ return executeCall(call);
+ }
+ Call<List<SimpleCommentVideo>> call = service.postCommentSearch(body);
+ return executeCall(call);
+ }
+
+ private static Map<String, Object> toMap(Object obj) throws HolodexException {
+ Map<String, Object> map = new HashMap<>();
+ Field[] fields = obj.getClass().getDeclaredFields();
+ for (Field field : fields) {
+ field.setAccessible(true);
+ try {
+ Object value = field.get(obj);
+ map.put(field.getName(), value);
+ } catch (IllegalAccessException e) {
+ throw new HolodexException("Failed to execute API call", e);
+ }
+ }
+ return map;
+ }
+
+
+ private <T> T executeCall(Call<T> call) throws HolodexException {
+ try {
+ Response<T> response = call.execute();
+ if (response.isSuccessful()) {
+ return response.body();
+ } else {
+ throw new HolodexException("API returned error: " + response.code());
+ }
+ } catch (IOException e) {
+ System.out.println(e);
+ throw new HolodexException("Failed to execute API call", e);
+ }
+ }
+
+}
diff --git a/src/main/java/com/pinapelz/HolodexException.java b/src/main/java/com/pinapelz/HolodexException.java
new file mode 100644
index 0000000..d9914f8
--- /dev/null
+++ b/src/main/java/com/pinapelz/HolodexException.java
@@ -0,0 +1,25 @@
+package com.pinapelz;
+
+/**
+ * Class for Holodex related exceptions
+ */
+public class HolodexException extends Exception{
+ /**
+ * Instantiates a new Holodex exception.
+ *
+ * @param message the message
+ */
+ public HolodexException(String message) {
+ super(message);
+ }
+
+ /**
+ * Instantiates a new Holodex exception.
+ *
+ * @param message the message
+ * @param cause the cause
+ */
+ public HolodexException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/src/main/java/com/pinapelz/HolodexService.java b/src/main/java/com/pinapelz/HolodexService.java
new file mode 100644
index 0000000..a705025
--- /dev/null
+++ b/src/main/java/com/pinapelz/HolodexService.java
@@ -0,0 +1,212 @@
+package com.pinapelz;
+
+import com.pinapelz.datatypes.*;
+import okhttp3.RequestBody;
+import retrofit2.Call;
+import retrofit2.http.*;
+
+import java.util.List;
+
+/**
+ * The interface Holodex service.
+ */
+public interface HolodexService {
+ /**
+ * /api/v2/live endpoint
+ *
+ * @param channel_id the YouTube channel id
+ * @param id the YouTube video id
+ * @param include the include parameters
+ * @param lang a comma separated String of languages (e.g "en,ja")
+ * @param limit the limit for the number of results
+ * @param maxUpcomingHours number of maximum hours to show upcoming videos
+ * @param mentioned_channel_id the mentioned channel id of a different channel (for collabs)
+ * @param offset the offset for the number of results
+ * @param order the order (asc, desc)
+ * @param org the organization of which to get videos for (e.g. "Hololive")
+ * @param paginated paginated field
+ * @param sort sort by returned field (e.g "start_scheduled")
+ * @param status filter by video status (e.g. "upcoming")
+ * @param topic filter by type of video (e.g "stream")
+ * @param type the type
+ * @return a list of SimpleVideo objects
+ */
+ @GET("/api/v2/live")
+ Call<List<SimpleVideo>> getLiveVideos(
+ @Query("channel_id") String channel_id,
+ @Query("id") String id,
+ @Query("include") String include,
+ @Query("lang") String lang,
+ @Query("limit") Integer limit,
+ @Query("maxUpcomingHours") Integer maxUpcomingHours,
+ @Query("mentioned_channel_id") String mentioned_channel_id,
+ @Query("offset") Integer offset,
+ @Query("order") String order,
+ @Query("org") String org,
+ @Query("paginated") String paginated,
+ @Query("sort") String sort,
+ @Query("status") String status,
+ @Query("topic") String topic,
+ @Query("type") String type
+ );
+
+ /**
+ * /api/v2/video endpoint
+ *
+ * @param channel_id the YouTube channel id
+ * @param id the YouTube video id
+ * @param include the include parameters comma seperated
+ * @param lang a comma separated String of languages (e.g "en,ja")
+ * @param limit the limit for the number of results
+ * @param max_upcoming_hours number of maximum hours to show upcoming videos
+ * @param mentioned_channel_id the mentioned channel id of a different channel (for collabs)
+ * @param offset the offset for the number of results
+ * @param order the order (asc, desc)
+ * @param org the organization of which to get videos for (e.g. "Hololive")
+ * @param paginated paginated field
+ * @param sort sort by returned field (e.g "start_scheduled")
+ * @param status filter by video status (e.g. "upcoming")
+ * @param topic filter by type of video (e.g "stream")
+ * @param type the type
+ * @return a list of Video objects
+ */
+ @GET("/api/v2/videos")
+ Call<List<Video>> getVideos(
+ @Query("channel_id") String channel_id,
+ @Query("id") String id,
+ @Query("include") String include,
+ @Query("lang") String lang,
+ @Query("limit") Integer limit,
+ @Query("max_upcoming_hours") Integer max_upcoming_hours,
+ @Query("mentioned_channel_id") String mentioned_channel_id,
+ @Query("offset") Integer offset,
+ @Query("order") String order,
+ @Query("org") String org,
+ @Query("paginated") String paginated,
+ @Query("sort") String sort,
+ @Query("status") String status,
+ @Query("topic") String topic,
+ @Query("type") String type
+ );
+
+ /**
+ * /api/v2/channels endpoint
+ *
+ * @param channelID the channel id
+ * @return the channel
+ */
+ @GET("/api/v2/channels/{channelID}")
+ Call<Channel> getChannel(
+ @Path("channelID") String channelID
+ );
+
+ /**
+ * /api/v2/channels/{channelID}/{type} endpoint
+ *
+ * @param channelID the YouTube channel id
+ * @param type the type of video resource ("clips", "videos", "collabs")
+ * @param include the include parameters comma seperated
+ * @param lang a comma separated String of languages (e.g "en,ja")
+ * @param limit the limit for the number of results
+ * @param offset the offset for the number of results
+ * @param paginated paginated field
+ * @return list of Videos by channel id
+ */
+ @GET("/api/v2/channels/{channelID}/{type}")
+ Call<List<Video>> getVideosByChannelId(
+ @Path("channelID") String channelID,
+ @Path("type") String type,
+ @Query("include") String include,
+ @Query("lang") String lang,
+ @Query("limit") Integer limit,
+ @Query("offset") Integer offset,
+ @Query("paginated") String paginated
+ );
+
+ /**
+ * /api/v2/users/live endpoint
+ *
+ * @param channels the channel ids in a comma separated String
+ * @return the videos from channels
+ */
+ @GET("/api/v2/users/live")
+ Call<List<Video>> getVideosFromChannels(
+ @Query("channels") String channels
+ );
+
+ /**
+ * /api/v2/videos/{videoID} endpoint
+ *
+ * @param videoID the YouTube video id
+ * @param lang a comma separated String of languages (e.g "en,ja")
+ * @param c 1 will return timestamp comments for the video, 0 will not
+ * @return the video
+ */
+ @GET("/api/v2/videos/{videoID}")
+ Call<Video> getVideo(
+ @Path("videoID") String videoID,
+ @Query("lang") String lang,
+ @Query("c") String c
+ );
+
+ /**
+ * /api/v2/channels endpoint
+ *
+ * @param limit the limit for the number of results
+ * @param offset the offset for the number of results
+ * @param type the type of channel (e.g "vtuber")
+ * @param lang a comma separated String of languages (e.g "en,ja")
+ * @param order ascending or descending order (e.g "asc")
+ * @param org filter by organization (e.g "Hololive")
+ * @param sort column in which data should be sorted (default is org)
+ * @return the channels
+ */
+ @GET("/api/v2/channels")
+ Call<List<Channel>> getChannels(
+ @Query("limit") Integer limit,
+ @Query("offset") Integer offset,
+ @Query("type") String type,
+ @Query("lang") String lang,
+ @Query("order") String order,
+ @Query("org") String org,
+ @Query("sort") String sort
+ );
+
+ /**
+ * /api/v2/search/videoSearch endpoint
+ * @param videoSearchResult
+ * @return
+ */
+ @POST("/api/v2/search/videoSearch")
+ @Paginated(false)
+ Call<List<SimpleVideo>> postVideoSearch(
+ @Body RequestBody videoSearchResult
+ );
+
+ @POST("/api/v2/search/videoSearch")
+ @Paginated(true)
+ Call<VideoSearchResult> postPaginatedVideoSearch(
+ @Body RequestBody videoSearchResult
+ );
+
+ /**
+ * /api/v2/search/channelSearch endpoint
+ * @param commentSearchResult
+ * @return
+ */
+ @POST("/api/v2/search/commentSearch")
+ @Paginated(false)
+ Call<List<SimpleCommentVideo>> postCommentSearch(
+ @Body RequestBody commentSearchResult
+ );
+
+ @POST("/api/v2/search/commentSearch")
+ @Paginated(true)
+ Call<CommentSearchResult> postPaginatedCommentSearch(
+ @Body RequestBody commentSearchResult
+ );
+
+
+
+}
+
diff --git a/src/main/java/com/pinapelz/datatypes/Channel.java b/src/main/java/com/pinapelz/datatypes/Channel.java
new file mode 100644
index 0000000..e7b5332
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/Channel.java
@@ -0,0 +1,21 @@
+package com.pinapelz.datatypes;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+/**
+ * Channel object
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Channel extends SimpleChannel{
+ public String suborg;
+ public String banner;
+ public String twitter;
+ public String video_count;
+ public String subscriber_count;
+ public String view_count;
+ public String clip_count;
+ public String lang;
+ public String published_at;
+ public boolean inactive;
+ public String description;
+}
diff --git a/src/main/java/com/pinapelz/datatypes/Comment.java b/src/main/java/com/pinapelz/datatypes/Comment.java
new file mode 100644
index 0000000..729dfba
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/Comment.java
@@ -0,0 +1,10 @@
+package com.pinapelz.datatypes;
+
+/**
+ * Comment object
+ */
+public class Comment {
+ public String comment_key;
+ public String video_id;
+ public String message;
+}
diff --git a/src/main/java/com/pinapelz/datatypes/CommentSearchResult.java b/src/main/java/com/pinapelz/datatypes/CommentSearchResult.java
new file mode 100644
index 0000000..a519bcd
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/CommentSearchResult.java
@@ -0,0 +1,11 @@
+package com.pinapelz.datatypes;
+
+import java.util.List;
+
+/**
+ * Result object for a paginated comment search
+ */
+public class CommentSearchResult {
+ public int total;
+ public List<SimpleCommentVideo> items;
+}
diff --git a/src/main/java/com/pinapelz/datatypes/Paginated.java b/src/main/java/com/pinapelz/datatypes/Paginated.java
new file mode 100644
index 0000000..3da558e
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/Paginated.java
@@ -0,0 +1,15 @@
+package com.pinapelz.datatypes;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for paginated queries
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Paginated {
+ boolean value() default true;
+}
diff --git a/src/main/java/com/pinapelz/datatypes/SimpleChannel.java b/src/main/java/com/pinapelz/datatypes/SimpleChannel.java
new file mode 100644
index 0000000..2f78d8e
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/SimpleChannel.java
@@ -0,0 +1,16 @@
+package com.pinapelz.datatypes;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+/**
+ * Simple channel object
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class SimpleChannel {
+ public String id;
+ public String name;
+ public String english_name;
+ public String type;
+ public String photo;
+ public String org;
+}
diff --git a/src/main/java/com/pinapelz/datatypes/SimpleCommentVideo.java b/src/main/java/com/pinapelz/datatypes/SimpleCommentVideo.java
new file mode 100644
index 0000000..d313a30
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/SimpleCommentVideo.java
@@ -0,0 +1,21 @@
+package com.pinapelz.datatypes;
+
+import java.util.List;
+
+/**
+ * The same as SimpleVideo, but with comments
+ * @see SimpleVideo
+ *
+ */
+public class SimpleCommentVideo {
+ public String id;
+ public String title;
+ public String type;
+ public String published_at;
+ public String available_at;
+ public int duration;
+ public String status;
+ public int songcount;
+ public SimpleChannel channel;
+ public List<Comment> comments;
+}
diff --git a/src/main/java/com/pinapelz/datatypes/SimpleVideo.java b/src/main/java/com/pinapelz/datatypes/SimpleVideo.java
new file mode 100644
index 0000000..7e2fd44
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/SimpleVideo.java
@@ -0,0 +1,26 @@
+package com.pinapelz.datatypes;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+/**
+ * Simple video object
+ */
+@JsonIgnoreProperties (ignoreUnknown = true)
+public class SimpleVideo {
+ public String id;
+ public String title;
+ public String type;
+ public String topic_id;
+ public String published_at;
+ public String available_at;
+ public int duration;
+ public String status;
+ public String start_scheduled;
+ public String start_actual;
+ public String end_actual;
+ public int live_viewers;
+ public String description;
+ public int songcount;
+ public String channel_id;
+ public Channel channel;
+}
diff --git a/src/main/java/com/pinapelz/datatypes/Video.java b/src/main/java/com/pinapelz/datatypes/Video.java
new file mode 100644
index 0000000..fb01ac4
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/Video.java
@@ -0,0 +1,24 @@
+package com.pinapelz.datatypes;
+
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+
+import java.util.List;
+
+/**
+ * Video object
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class Video extends SimpleVideo {
+ public List<Video> clips;
+ public List<Video> sources;
+ public List<Video> refers;
+ public List<Video> simulcasts;
+ public List<SimpleChannel> mentions;
+ public String thumbnail;
+ public List<Video> reccomendations;
+ public List<Comment> comments;
+}
+
+
+
diff --git a/src/main/java/com/pinapelz/datatypes/VideoSearchResult.java b/src/main/java/com/pinapelz/datatypes/VideoSearchResult.java
new file mode 100644
index 0000000..36251a1
--- /dev/null
+++ b/src/main/java/com/pinapelz/datatypes/VideoSearchResult.java
@@ -0,0 +1,11 @@
+package com.pinapelz.datatypes;
+
+import java.util.List;
+
+/**
+ * Result object for a paginated video search
+ */
+public class VideoSearchResult {
+ public int total;
+ public List<SimpleVideo> items;
+}
diff --git a/src/main/java/com/pinapelz/factory/VideoSearchResultConverterFactory.java b/src/main/java/com/pinapelz/factory/VideoSearchResultConverterFactory.java
new file mode 100644
index 0000000..0ab27c4
--- /dev/null
+++ b/src/main/java/com/pinapelz/factory/VideoSearchResultConverterFactory.java
@@ -0,0 +1,51 @@
+package com.pinapelz.factory;
+
+import com.pinapelz.datatypes.Paginated;
+import com.pinapelz.datatypes.SimpleVideo;
+import com.pinapelz.datatypes.VideoSearchResult;
+import okhttp3.ResponseBody;
+import retrofit2.Converter;
+import retrofit2.Retrofit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+
+public class VideoSearchResultConverterFactory extends Converter.Factory {
+
+ public static VideoSearchResultConverterFactory create() {
+ return new VideoSearchResultConverterFactory();
+ }
+
+ @Override
+ public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
+ boolean isPaginated = false;
+ for (Annotation annotation : annotations) {
+ if (annotation instanceof Paginated) {
+ isPaginated = ((Paginated) annotation).value();
+ }
+ }
+ if (isPaginated) {
+ Type listType = new ParameterizedType() {
+ @Override
+ public Type[] getActualTypeArguments() {
+ return new Type[]{VideoSearchResult.class};
+ }
+
+ @Override
+ public Type getRawType() {
+ return List.class;
+ }
+
+ @Override
+ public Type getOwnerType() {
+ return null;
+ }
+ };
+ return retrofit.nextResponseBodyConverter(this, listType, annotations);
+ } else {
+ return retrofit.nextResponseBodyConverter(this, SimpleVideo.class, annotations);
+ }
+ }
+}
diff --git a/src/main/java/com/pinapelz/query/ChannelQueryBuilder.java b/src/main/java/com/pinapelz/query/ChannelQueryBuilder.java
new file mode 100644
index 0000000..24d3c91
--- /dev/null
+++ b/src/main/java/com/pinapelz/query/ChannelQueryBuilder.java
@@ -0,0 +1,79 @@
+package com.pinapelz.query;
+
+/**
+ * Query builder for getting a list of Channels matching the given parameters
+ */
+public class ChannelQueryBuilder {
+ private Integer limit;
+ private Integer offset;
+ private String type;
+ private String lang;
+ private String order;
+ private String org;
+ private String sort;
+
+ public Integer getLimit() {
+ return limit;
+ }
+
+ public ChannelQueryBuilder setLimit(Integer limit) {
+ this.limit = limit;
+ return this;
+ }
+
+ public Integer getOffset() {
+ return offset;
+ }
+
+ public ChannelQueryBuilder setOffset(Integer offset) {
+ this.offset = offset;
+ return this;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public ChannelQueryBuilder setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getLang() {
+ return lang;
+ }
+
+ public ChannelQueryBuilder setLang(String lang) {
+ this.lang = lang;
+ return this;
+ }
+
+ public String getOrder() {
+ return order;
+ }
+
+ public ChannelQueryBuilder setOrder(String order) {
+ this.order = order;
+ return this;
+ }
+
+ public String getOrg() {
+ return org;
+ }
+
+ public ChannelQueryBuilder setOrg(String org) {
+ this.org = org;
+ return this;
+ }
+
+ public String getSort() {
+ return sort;
+ }
+
+ public ChannelQueryBuilder setSort(String sort) {
+ this.sort = sort;
+ return this;
+ }
+
+
+}
diff --git a/src/main/java/com/pinapelz/query/CommentSearchQueryBuilder.java b/src/main/java/com/pinapelz/query/CommentSearchQueryBuilder.java
new file mode 100644
index 0000000..eeb83d5
--- /dev/null
+++ b/src/main/java/com/pinapelz/query/CommentSearchQueryBuilder.java
@@ -0,0 +1,134 @@
+package com.pinapelz.query;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Builder for a comment search query
+ * Default values set in constructor
+ */
+public class CommentSearchQueryBuilder {
+ private String sort;
+ private List<String> lang;
+ private List<String> target;
+ private List<String> conditions;
+ private List<String> topic;
+ private List<String> vch;
+ private List<String> org;
+ private List<String> comment;
+ private boolean paginated;
+ private int offset;
+ private int limit;
+
+ public CommentSearchQueryBuilder(){
+ this.sort = "newest";
+ this.paginated = true;
+ this.offset = 0;
+ this.limit = 10;
+ this.topic = new ArrayList<String>();
+ this.comment = new ArrayList<String>();
+ this.org = List.of("Nijisanji");
+ this.vch = new ArrayList<String>();
+ this.conditions = new ArrayList<String>();
+ this.lang = List.of("en");
+ }
+
+ public String getSort() {
+ return sort;
+ }
+
+ public CommentSearchQueryBuilder setSort(String sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public List<String> getLang() {
+ return lang;
+ }
+
+ public CommentSearchQueryBuilder setLang(List<String> lang) {
+ this.lang = lang;
+ return this;
+ }
+
+ public List<String> getTarget() {
+ return target;
+ }
+
+ public CommentSearchQueryBuilder setTarget(List<String> target) {
+ this.target = target;
+ return this;
+ }
+
+ public List<String> getConditions() {
+ return conditions;
+ }
+
+ public CommentSearchQueryBuilder setConditions(List<String> conditions) {
+ this.conditions = conditions;
+ return this;
+ }
+
+ public List<String> getTopic() {
+ return topic;
+ }
+
+ public CommentSearchQueryBuilder setTopic(List<String> topic) {
+ this.topic = topic;
+ return this;
+ }
+
+ public List<String> getVch() {
+ return vch;
+ }
+
+ public CommentSearchQueryBuilder setVch(List<String> vch) {
+ this.vch = vch;
+ return this;
+ }
+
+ public List<String> getOrg() {
+ return org;
+ }
+
+ public CommentSearchQueryBuilder setOrg(List<String> org) {
+ this.org = org;
+ return this;
+ }
+
+ public List<String> getComment() {
+ return comment;
+ }
+
+ public CommentSearchQueryBuilder setComment(List<String> comment) {
+ this.comment = comment;
+ return this;
+ }
+
+ public boolean isPaginated() {
+ return paginated;
+ }
+
+ public CommentSearchQueryBuilder setPaginated(boolean paginated) {
+ this.paginated = paginated;
+ return this;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public CommentSearchQueryBuilder setOffset(int offset) {
+ this.offset = offset;
+ return this;
+ }
+
+ public int getLimit() {
+ return limit;
+ }
+
+ public CommentSearchQueryBuilder setLimit(int limit) {
+ this.limit = limit;
+ return this;
+ }
+}
diff --git a/src/main/java/com/pinapelz/query/VideoByVideoIdQueryBuilder.java b/src/main/java/com/pinapelz/query/VideoByVideoIdQueryBuilder.java
new file mode 100644
index 0000000..7348683
--- /dev/null
+++ b/src/main/java/com/pinapelz/query/VideoByVideoIdQueryBuilder.java
@@ -0,0 +1,39 @@
+package com.pinapelz.query;
+
+/**
+ * Query builder for getting a video by video id
+ */
+public class VideoByVideoIdQueryBuilder {
+ private String videoId;
+ private String lang;
+ private String c;
+
+ public String getVideoId() {
+ return videoId;
+ }
+
+ public VideoByVideoIdQueryBuilder setVideoId(String videoId) {
+ this.videoId = videoId;
+ return this;
+ }
+
+ public String getLang() {
+ return lang;
+ }
+
+ public VideoByVideoIdQueryBuilder setLang(String lang) {
+ this.lang = lang;
+ return this;
+ }
+
+ public String getC() {
+ return c;
+ }
+
+ public VideoByVideoIdQueryBuilder setC(String c) {
+ this.c = c;
+ return this;
+ }
+
+
+}
diff --git a/src/main/java/com/pinapelz/query/VideoQueryBuilder.java b/src/main/java/com/pinapelz/query/VideoQueryBuilder.java
new file mode 100644
index 0000000..b7072fc
--- /dev/null
+++ b/src/main/java/com/pinapelz/query/VideoQueryBuilder.java
@@ -0,0 +1,157 @@
+package com.pinapelz.query;
+
+/**
+ * Query builder for getting a set of videos matching the given parameters
+ */
+public class VideoQueryBuilder {
+ private String channelId;
+ private String id;
+ private String include;
+ private String lang;
+ private Integer limit;
+ private Integer maxUpcomingHours;
+ private String mentionedChannelId;
+ private Integer offset;
+ private String order;
+ private String org;
+ private String paginated;
+ private String sort;
+ private String status;
+ private String topic;
+ private String type;
+
+ public VideoQueryBuilder setChannelId(String channelId) {
+ this.channelId = channelId;
+ return this;
+ }
+
+ public VideoQueryBuilder setId(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public VideoQueryBuilder setInclude(String include) {
+ this.include = include;
+ return this;
+ }
+
+ public VideoQueryBuilder setLang(String lang) {
+ this.lang = lang;
+ return this;
+ }
+
+ public VideoQueryBuilder setLimit(Integer limit) {
+ this.limit = limit;
+ return this;
+ }
+
+ public VideoQueryBuilder setMaxUpcomingHours(Integer maxUpcomingHours) {
+ this.maxUpcomingHours = maxUpcomingHours;
+ return this;
+ }
+
+ public VideoQueryBuilder setMentionedChannelId(String mentionedChannelId) {
+ this.mentionedChannelId = mentionedChannelId;
+ return this;
+ }
+
+ public VideoQueryBuilder setOffset(Integer offset) {
+ this.offset = offset;
+ return this;
+ }
+
+ public VideoQueryBuilder setOrder(String order) {
+ this.order = order;
+ return this;
+ }
+
+ public VideoQueryBuilder setOrg(String org) {
+ this.org = org;
+ return this;
+ }
+
+ public VideoQueryBuilder setPaginated(String paginated) {
+ this.paginated = paginated;
+ return this;
+ }
+
+ public VideoQueryBuilder setSort(String sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public VideoQueryBuilder setStatus(String status) {
+ this.status = status;
+ return this;
+ }
+
+ public VideoQueryBuilder setTopic(String topic) {
+ this.topic = topic;
+ return this;
+ }
+
+ public VideoQueryBuilder setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getChannelId() {
+ return channelId;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getInclude() {
+ return include;
+ }
+
+ public String getLang() {
+ return lang;
+ }
+
+ public Integer getLimit() {
+ return limit;
+ }
+
+ public Integer getMaxUpcomingHours() {
+ return maxUpcomingHours;
+ }
+
+ public String getMentionedChannelId() {
+ return mentionedChannelId;
+ }
+
+ public Integer getOffset() {
+ return offset;
+ }
+
+ public String getOrder() {
+ return order;
+ }
+
+ public String getOrg() {
+ return org;
+ }
+
+ public String getPaginated() {
+ return paginated;
+ }
+
+ public String getSort() {
+ return sort;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public String getTopic() {
+ return topic;
+ }
+
+ public String getType() {
+ return type;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/com/pinapelz/query/VideoSearchQueryBuilder.java b/src/main/java/com/pinapelz/query/VideoSearchQueryBuilder.java
new file mode 100644
index 0000000..5147d97
--- /dev/null
+++ b/src/main/java/com/pinapelz/query/VideoSearchQueryBuilder.java
@@ -0,0 +1,134 @@
+package com.pinapelz.query;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Builder for a video search query
+ * Default values set in constructor
+ */
+public class VideoSearchQueryBuilder {
+ private String sort;
+ private List<String> lang;
+ private List<String> target;
+ private List<String> conditions;
+ private List<String> topic;
+ private List<String> vch;
+ private List<String> org;
+ private List<String> comment;
+ private boolean paginated;
+ private int offset;
+ private int limit;
+
+ public VideoSearchQueryBuilder() {
+ this.sort = "newest";
+ this.paginated = true;
+ this.offset = 0;
+ this.limit = 10;
+ this.topic = new ArrayList<String>();
+ this.comment = new ArrayList<String>();
+ this.org = List.of("Nijisanji");
+ this.vch = new ArrayList<String>();
+ this.conditions = new ArrayList<String>();
+ this.lang = List.of("en");
+ }
+
+ public String getSort() {
+ return sort;
+ }
+
+ public VideoSearchQueryBuilder setSort(String sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public List<String> getLang() {
+ return lang;
+ }
+
+ public VideoSearchQueryBuilder setLang(List<String> lang) {
+ this.lang = lang;
+ return this;
+ }
+
+ public List<String> getTarget() {
+ return target;
+ }
+
+ public VideoSearchQueryBuilder setTarget(List<String> target) {
+ this.target = target;
+ return this;
+ }
+
+ public List<String> getConditions() {
+ return conditions;
+ }
+
+ public VideoSearchQueryBuilder setConditions(List<String> conditions) {
+ this.conditions = conditions;
+ return this;
+ }
+
+ public List<String> getTopic() {
+ return topic;
+ }
+
+ public VideoSearchQueryBuilder setTopic(List<String> topic) {
+ this.topic = topic;
+ return this;
+ }
+
+ public List<String> getVch() {
+ return vch;
+ }
+
+ public VideoSearchQueryBuilder setVch(List<String> vch) {
+ this.vch = vch;
+ return this;
+ }
+
+ public List<String> getOrg() {
+ return org;
+ }
+
+ public VideoSearchQueryBuilder setOrg(List<String> org) {
+ this.org = org;
+ return this;
+ }
+
+ public List<String> getComment() {
+ return comment;
+ }
+
+ public VideoSearchQueryBuilder setComment(List<String> comment) {
+ this.comment = comment;
+ return this;
+ }
+
+ public boolean isPaginated() {
+ return paginated;
+ }
+
+ public VideoSearchQueryBuilder setPaginated(boolean paginated) {
+ this.paginated = paginated;
+ return this;
+ }
+
+ public int getOffset() {
+ return offset;
+ }
+
+ public VideoSearchQueryBuilder setOffset(int offset) {
+ this.offset = offset;
+ return this;
+ }
+
+ public int getLimit() {
+ return limit;
+ }
+
+ public VideoSearchQueryBuilder setLimit(int limit) {
+ this.limit = limit;
+ return this;
+ }
+}
diff --git a/src/main/java/com/pinapelz/query/VideosByChannelIDQueryBuilder.java b/src/main/java/com/pinapelz/query/VideosByChannelIDQueryBuilder.java
new file mode 100644
index 0000000..821df24
--- /dev/null
+++ b/src/main/java/com/pinapelz/query/VideosByChannelIDQueryBuilder.java
@@ -0,0 +1,78 @@
+package com.pinapelz.query;
+
+/**
+ * Query builder for getting videos by a given channel id
+ */
+public class VideosByChannelIDQueryBuilder {
+ private String channelId;
+ private String type;
+ private String include;
+ private String lang;
+ private Integer limit;
+ private Integer offset;
+ private String paginated;
+
+ public VideosByChannelIDQueryBuilder setChannelId(String channelId) {
+ this.channelId = channelId;
+ return this;
+ }
+
+ public VideosByChannelIDQueryBuilder setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public VideosByChannelIDQueryBuilder setInclude(String include) {
+ this.include = include;
+ return this;
+ }
+
+ public VideosByChannelIDQueryBuilder setLang(String lang) {
+ this.lang = lang;
+ return this;
+ }
+
+ public VideosByChannelIDQueryBuilder setLimit(Integer limit) {
+ this.limit = limit;
+ return this;
+ }
+
+ public VideosByChannelIDQueryBuilder setOffset(Integer offset) {
+ this.offset = offset;
+ return this;
+ }
+
+ public VideosByChannelIDQueryBuilder setPaginated(String paginated) {
+ this.paginated = paginated;
+ return this;
+ }
+
+ public String getChannelId() {
+ return channelId;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getInclude() {
+ return include;
+ }
+
+ public String getLang() {
+ return lang;
+ }
+
+ public Integer getLimit() {
+ return limit;
+ }
+
+ public Integer getOffset() {
+ return offset;
+ }
+
+ public String getPaginated() {
+ return paginated;
+ }
+
+}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage