package ml.docilealligator.infinityforreddit.post;
import android.net.Uri;
import android.os.Handler;
import android.text.Html;
import android.text.TextUtils;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import ml.docilealligator.infinityforreddit.postfilter.PostFilter;
import ml.docilealligator.infinityforreddit.readpost.ReadPostsListInterface;
import ml.docilealligator.infinityforreddit.thing.MediaMetadata;
import ml.docilealligator.infinityforreddit.utils.JSONUtils;
import ml.docilealligator.infinityforreddit.utils.Utils;
/**
* Created by alex on 3/21/18.
*/
public class ParsePost {
@WorkerThread
public static LinkedHashSet<Post> parsePostsSync(String response, int nPosts, PostFilter postFilter, @Nullable ReadPostsListInterface readPostsList) {
LinkedHashSet<Post> newPosts = new LinkedHashSet<>();
try {
JSONObject jsonResponse = new JSONObject(response);
JSONArray allPostsData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
//Posts listing
int numberOfPosts = (nPosts < 0 || nPosts > allPostsData.length()) ?
allPostsData.length() : nPosts;
ArrayList<String> newPostsIds = new ArrayList<>();
for (int i = 0; i < numberOfPosts; i++) {
try {
if (!allPostsData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) {
continue;
}
JSONObject data = allPostsData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY);
Post post = parseBasicData(data);
if (PostFilter.isPostAllowed(post, postFilter)) {
newPosts.add(post);
newPostsIds.add(post.getId());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Set<String> readPostsIds = readPostsList.getReadPostsIdsByIds(newPostsIds);
for (Post post: newPosts) {
if (readPostsIds.contains(post.getId())) {
post.markAsRead();
}
}
return newPosts;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
public static String getLastItem(String response) {
try {
JSONObject object = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY);
return object.isNull(JSONUtils.AFTER_KEY) ? null : object.getString(JSONUtils.AFTER_KEY);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
public static void parsePost(Executor executor, Handler handler, String response, ParsePostListener parsePostListener) {
executor.execute(() -> {
try {
JSONArray allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
if (allData.length() == 0) {
handler.post(parsePostListener::onParsePostFail);
return;
}
JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY);
Post post = parseBasicData(data);
handler.post(() -> parsePostListener.onParsePostSuccess(post));
} catch (JSONException e) {
e.printStackTrace();
handler.post(parsePostListener::onParsePostFail);
}
});
}
@WorkerThread
@Nullable
public static Post parsePostSync(String response) {
try {
JSONArray allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
if (allData.length() == 0) {
return null;
}
JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY);
return parseBasicData(data);
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
public static void parseRandomPost(Executor executor, Handler handler, String response, boolean isNSFW,
ParseRandomPostListener parseRandomPostListener) {
executor.execute(() -> {
try {
JSONArray postsArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY);
if (postsArray.length() == 0) {
handler.post(parseRandomPostListener::onParseRandomPostFailed);
} else {
JSONObject post = postsArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY);
String subredditName = post.getString(JSONUtils.SUBREDDIT_KEY);
String postId;
if (isNSFW) {
postId = post.getString(JSONUtils.ID_KEY);
} else {
postId = post.getString(JSONUtils.LINK_ID_KEY).substring("t3_".length());
}
handler.post(() -> parseRandomPostListener.onParseRandomPostSuccess(postId, subredditName));
}
} catch (JSONException e) {
e.printStackTrace();
handler.post(parseRandomPostListener::onParseRandomPostFailed);
}
});
}
@WorkerThread
public static Post parseBasicData(JSONObject data) throws JSONException {
String id = data.getString(JSONUtils.ID_KEY);
String fullName = data.getString(JSONUtils.NAME_KEY);
String subredditName = data.getString(JSONUtils.SUBREDDIT_KEY);
String subredditNamePrefixed = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY);
String author = data.getString(JSONUtils.AUTHOR_KEY);
StringBuilder authorFlairHTMLBuilder = new StringBuilder();
if (data.has(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY)) {
JSONArray flairArray = data.getJSONArray(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY);
for (int i = 0; i < flairArray.length(); i++) {
JSONObject flairObject = flairArray.getJSONObject(i);
String e = flairObject.getString(JSONUtils.E_KEY);
if (e.equals("text")) {
authorFlairHTMLBuilder.append(flairObject.getString(JSONUtils.T_KEY));
} else if (e.equals("emoji")) {
authorFlairHTMLBuilder.append("<img src=\"").append(Html.escapeHtml(flairObject.getString(JSONUtils.U_KEY))).append("\">");
}
}
}
String authorFlair = data.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) ? "" : data.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY);
String distinguished = data.getString(JSONUtils.DISTINGUISHED_KEY);
String suggestedSort = data.has(JSONUtils.SUGGESTED_SORT_KEY) ? data.getString(JSONUtils.SUGGESTED_SORT_KEY) : null;
long postTime = data.getLong(JSONUtils.CREATED_UTC_KEY) * 1000;
String title = data.getString(JSONUtils.TITLE_KEY);
int score = data.getInt(JSONUtils.SCORE_KEY);
int voteType;
int nComments = data.getInt(JSONUtils.NUM_COMMENTS_KEY);
int upvoteRatio = (int) (data.getDouble(JSONUtils.UPVOTE_RATIO_KEY) * 100);
boolean hidden = data.getBoolean(JSONUtils.HIDDEN_KEY);
boolean spoiler = data.getBoolean(JSONUtils.SPOILER_KEY);
boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY);
boolean stickied = data.getBoolean(JSONUtils.STICKIED_KEY);
boolean archived = data.getBoolean(JSONUtils.ARCHIVED_KEY);
boolean locked = data.getBoolean(JSONUtils.LOCKED_KEY);
boolean saved = data.getBoolean(JSONUtils.SAVED_KEY);
boolean deleted = !data.isNull(JSONUtils.REMOVED_BY_CATEGORY_KEY) && data.getString(JSONUtils.REMOVED_BY_CATEGORY_KEY).equals("deleted");
boolean removed = !data.isNull(JSONUtils.REMOVED_BY_CATEGORY_KEY) && data.getString(JSONUtils.REMOVED_BY_CATEGORY_KEY).equals("moderator");
StringBuilder postFlairHTMLBuilder = new StringBuilder();
String flair = "";
if (data.has(JSONUtils.LINK_FLAIR_RICHTEXT_KEY)) {
JSONArray flairArray = data.getJSONArray(JSONUtils.LINK_FLAIR_RICHTEXT_KEY);
for (int i = 0; i < flairArray.length(); i++) {
JSONObject flairObject = flairArray.getJSONObject(i);
String e = flairObject.getString(JSONUtils.E_KEY);
if (e.equals("text")) {
postFlairHTMLBuilder.append(Html.escapeHtml(flairObject.getString(JSONUtils.T_KEY)));
} else if (e.equals("emoji")) {
postFlairHTMLBuilder.append("<img src=\"").append(Html.escapeHtml(flairObject.getString(JSONUtils.U_KEY))).append("\">");
}
}
flair = postFlairHTMLBuilder.toString();
}
if (flair.equals("") && data.has(JSONUtils.LINK_FLAIR_TEXT_KEY) && !data.isNull(JSONUtils.LINK_FLAIR_TEXT_KEY)) {
flair = data.getString(JSONUtils.LINK_FLAIR_TEXT_KEY);
}
if (data.isNull(JSONUtils.LIKES_KEY)) {
voteType = 0;
} else {
voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1;
score -= voteType;
}
String permalink = Html.fromHtml(data.getString(JSONUtils.PERMALINK_KEY)).toString();
ArrayList<Post.Preview> previews = new ArrayList<>();
if (data.has(JSONUtils.PREVIEW_KEY)) {
JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0);
String previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
int previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY);
int previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY);
previews.add(new Post.Preview(previewUrl, previewWidth, previewHeight, "", ""));
JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY);
for (int i = 0; i < thumbnailPreviews.length(); i++) {
JSONObject thumbnailPreview = thumbnailPreviews.getJSONObject(i);
String thumbnailPreviewUrl = thumbnailPreview.getString(JSONUtils.URL_KEY);
int thumbnailPreviewWidth = thumbnailPreview.getInt(JSONUtils.WIDTH_KEY);
int thumbnailPreviewHeight = thumbnailPreview.getInt(JSONUtils.HEIGHT_KEY);
previews.add(new Post.Preview(thumbnailPreviewUrl, thumbnailPreviewWidth, thumbnailPreviewHeight, "", ""));
}
}
Map<String, MediaMetadata> mediaMetadataMap = JSONUtils.parseMediaMetadata(data);
if (data.has(JSONUtils.CROSSPOST_PARENT_LIST)) {
//Cross post
//data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0) out of bounds????????????
data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0);
Post crosspostParent = parseBasicData(data);
Post post = parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed,
author, authorFlair, authorFlairHTMLBuilder.toString(),
postTime, title, previews, mediaMetadataMap,
score, voteType, nComments, upvoteRatio, flair, hidden,
spoiler, nsfw, stickied, archived, locked, saved, deleted, removed, true,
distinguished, suggestedSort);
post.setCrosspostParentId(crosspostParent.getId());
return post;
} else {
return parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed,
author, authorFlair, authorFlairHTMLBuilder.toString(),
postTime, title, previews, mediaMetadataMap,
score, voteType, nComments, upvoteRatio, flair, hidden,
spoiler, nsfw, stickied, archived, locked, saved, deleted, removed, false,
distinguished, suggestedSort);
}
}
private static Post parseData(JSONObject data, String permalink, String id, String fullName,
String subredditName, String subredditNamePrefixed, String author,
String authorFlair, String authorFlairHTML, long postTimeMillis, String title,
ArrayList<Post.Preview> previews, Map<String, MediaMetadata> mediaMetadataMap,
int score, int voteType, int nComments, int upvoteRatio, String flair,
boolean hidden, boolean spoiler, boolean nsfw,
boolean stickied, boolean archived, boolean locked, boolean saved,
boolean deleted, boolean removed, boolean isCrosspost,
String distinguished, String suggestedSort) throws JSONException {
Post post;
boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY);
String url = Html.fromHtml(data.getString(JSONUtils.URL_KEY)).toString();
Uri uri = Uri.parse(url);
String path = uri.getPath();
if (!data.has(JSONUtils.PREVIEW_KEY) && previews.isEmpty()) {
if (url.contains(permalink)) {
//Text post
int postType = Post.TEXT_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, permalink, score, postType,
voteType, nComments, upvoteRatio, flair, hidden, spoiler, nsfw,
stickied, archived, locked, saved, isCrosspost, distinguished, suggestedSort);
} else {
if (path.endsWith(".jpg") || path.endsWith(".png") || path.endsWith(".jpeg")) {
//Image post
int postType = Post.IMAGE_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair, hidden,
spoiler, nsfw, stickied, archived, locked, saved, isCrosspost, distinguished, suggestedSort);
if (previews.isEmpty()) {
if ("i.redgifs.com".equals(uri.getAuthority())) {
//No preview link (Not able to load redgifs image)
post.setPostType(Post.NO_PREVIEW_LINK_TYPE);
} else {
previews.add(new Post.Preview(url, 0, 0, "", ""));
}
} else if ("i.redgifs.com".equals(uri.getAuthority())) {
post.setUrl(previews.get(previews.size() - 1).getPreviewUrl());
}
post.setPreviews(previews);
} else {
if (isVideo) {
//No preview video post
JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY);
int postType = Post.VIDEO_TYPE;
String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString();
String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY);
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair,
authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType,
nComments, upvoteRatio, flair, hidden, spoiler, nsfw, stickied,
archived, locked, saved, isCrosspost, distinguished, suggestedSort);
post.setVideoUrl(videoUrl);
post.setVideoDownloadUrl(videoDownloadUrl);
} else {
//No preview link post
int postType = Post.NO_PREVIEW_LINK_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair, hidden,
spoiler, nsfw, stickied, archived, locked, saved, isCrosspost, distinguished, suggestedSort);
if (data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText("");
} else {
post.setSelfText(Utils.parseRedditImagesBlock(Utils.modifyMarkdown(Utils.trimTrailingWhitespace(data.getString(JSONUtils.SELFTEXT_KEY))), mediaMetadataMap));
}
String authority = uri.getAuthority();
if (authority != null) {
if (authority.contains("redgifs.com")) {
String redgifsId = url.substring(url.lastIndexOf("/") + 1).toLowerCase();
post.setPostType(Post.VIDEO_TYPE);
post.setIsRedgifs(true);
post.setVideoUrl(url);
post.setRedgifsId(redgifsId);
} else if (authority.equals("streamable.com")) {
String shortCode = url.substring(url.lastIndexOf("/") + 1);
post.setPostType(Post.VIDEO_TYPE);
post.setIsStreamable(true);
post.setVideoUrl(url);
post.setStreamableShortCode(shortCode);
}
}
}
}
}
} else {
if (previews.isEmpty()) {
if (data.has(JSONUtils.PREVIEW_KEY)) {
JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0);
String previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
int previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY);
int previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY);
previews.add(new Post.Preview(previewUrl, previewWidth, previewHeight, "", ""));
JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY);
for (int i = 0; i < thumbnailPreviews.length(); i++) {
JSONObject thumbnailPreview = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY).getJSONObject(i);
String thumbnailPreviewUrl = thumbnailPreview.getString(JSONUtils.URL_KEY);
int thumbnailPreviewWidth = thumbnailPreview.getInt(JSONUtils.WIDTH_KEY);
int thumbnailPreviewHeight = thumbnailPreview.getInt(JSONUtils.HEIGHT_KEY);
previews.add(new Post.Preview(thumbnailPreviewUrl, thumbnailPreviewWidth, thumbnailPreviewHeight, "", ""));
}
}
}
if (isVideo) {
//Video post
JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY);
int postType = Post.VIDEO_TYPE;
String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString();
String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY);
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair,
authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType,
nComments, upvoteRatio, flair, hidden, spoiler, nsfw, stickied,
archived, locked, saved, isCrosspost, distinguished, suggestedSort);
post.setPreviews(previews);
post.setVideoUrl(videoUrl);
post.setVideoDownloadUrl(videoDownloadUrl);
} else if (data.has(JSONUtils.PREVIEW_KEY)) {
if (data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) {
int postType = Post.VIDEO_TYPE;
String authority = uri.getAuthority();
// The hls stream inside REDDIT_VIDEO_PREVIEW_KEY can sometimes lack an audio track
if (authority.contains("imgur.com") && (path.endsWith(".gifv") || path.endsWith(".mp4"))) {
if (path.endsWith(".gifv")) {
url = url.substring(0, url.length() - 5) + ".mp4";
}
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair,
authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType,
nComments, upvoteRatio, flair, hidden, spoiler, nsfw, stickied,
archived, locked, saved, isCrosspost, distinguished, suggestedSort);
post.setPreviews(previews);
post.setVideoUrl(url);
post.setVideoDownloadUrl(url);
post.setIsImgur(true);
} else {
//Gif video post (HLS) and maybe Redgifs
String videoUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.HLS_URL_KEY)).toString();
String videoDownloadUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.FALLBACK_URL_KEY);
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, authorFlair,
authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType,
nComments, upvoteRatio, flair, hidden, spoiler, nsfw, stickied,
archived, locked, saved, isCrosspost, distinguished, suggestedSort);
post.setPreviews(previews);
post.setVideoUrl(videoUrl);
post.setVideoDownloadUrl(videoDownloadUrl);
}
post.setVideoFallBackDirectUrl(Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.FALLBACK_URL_KEY)).toString());
} else {
if (path.endsWith(".jpg") || path.endsWith(".png") || path.endsWith(".jpeg")) {
//Image post
int postType = Post.IMAGE_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair,
hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost,
distinguished, suggestedSort);
if (previews.isEmpty()) {
if ("i.redgifs.com".equals(uri.getAuthority())) {
//No preview link (Not able to load redgifs image)
post.setPostType(Post.NO_PREVIEW_LINK_TYPE);
} else {
previews.add(new Post.Preview(url, 0, 0, "", ""));
}
} else if ("i.redgifs.com".equals(uri.getAuthority())) {
post.setUrl(previews.get(previews.size() - 1).getPreviewUrl());
}
post.setPreviews(previews);
} else if (path.endsWith(".gif")) {
//Gif post
int postType = Post.GIF_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair,
hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost,
distinguished, suggestedSort);
post.setPreviews(previews);
post.setVideoUrl(url);
try {
String mp4Variant = data.getJSONObject(JSONUtils.PREVIEW_KEY)
.getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0)
.getJSONObject(JSONUtils.VARIANTS_KEY).getJSONObject(JSONUtils.MP4_KEY)
.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY);
if (!mp4Variant.isEmpty()) {
post.setMp4Variant(mp4Variant);
}
} catch (Exception ignore) {}
} else if (uri.getAuthority().contains("imgur.com") && (path.endsWith(".gifv") || path.endsWith(".mp4"))) {
// Imgur gifv/mp4
int postType = Post.VIDEO_TYPE;
if (url.endsWith("gifv")) {
url = url.substring(0, url.length() - 5) + ".mp4";
}
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair,
hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost,
distinguished, suggestedSort);
post.setPreviews(previews);
post.setVideoUrl(url);
post.setVideoDownloadUrl(url);
post.setIsImgur(true);
} else if (path.endsWith(".mp4")) {
//Video post
int postType = Post.VIDEO_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair,
hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost,
distinguished, suggestedSort);
post.setPreviews(previews);
post.setVideoUrl(url);
post.setVideoDownloadUrl(url);
} else {
if (url.contains(permalink)) {
//Text post but with a preview
int postType = Post.TEXT_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, permalink, score,
postType, voteType, nComments, upvoteRatio, flair,
hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost,
distinguished, suggestedSort);
//Need attention
post.setPreviews(previews);
} else {
//Link post
int postType = Post.LINK_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair,
hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost,
distinguished, suggestedSort);
if (data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText("");
} else {
post.setSelfText(Utils.parseRedditImagesBlock(Utils.modifyMarkdown(Utils.trimTrailingWhitespace(data.getString(JSONUtils.SELFTEXT_KEY))), mediaMetadataMap));
}
post.setPreviews(previews);
String authority = uri.getAuthority();
if (authority != null) {
if (authority.contains("redgifs.com")) {
String redgifsId = url.substring(url.lastIndexOf("/") + 1).toLowerCase();
post.setPostType(Post.VIDEO_TYPE);
post.setIsRedgifs(true);
post.setVideoUrl(url);
post.setRedgifsId(redgifsId);
} else if (authority.equals("streamable.com")) {
String shortCode = url.substring(url.lastIndexOf("/") + 1);
post.setPostType(Post.VIDEO_TYPE);
post.setIsStreamable(true);
post.setVideoUrl(url);
post.setStreamableShortCode(shortCode);
}
}
}
}
}
} else {
if (path.endsWith(".jpg") || path.endsWith(".png") || path.endsWith(".jpeg")) {
//Image post
int postType = Post.IMAGE_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair, hidden,
spoiler, nsfw, stickied, archived, locked, saved, isCrosspost, distinguished, suggestedSort);
if (previews.isEmpty()) {
if ("i.redgifs.com".equals(uri.getAuthority())) {
//No preview link (Not able to load redgifs image)
post.setPostType(Post.NO_PREVIEW_LINK_TYPE);
} else {
previews.add(new Post.Preview(url, 0, 0, "", ""));
}
} else if ("i.redgifs.com".equals(uri.getAuthority())) {
post.setUrl(previews.get(previews.size() - 1).getPreviewUrl());
}
post.setPreviews(previews);
} else if (path.endsWith(".mp4")) {
//Video post
int postType = Post.VIDEO_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair, hidden,
spoiler, nsfw, stickied, archived, locked, saved, isCrosspost, distinguished, suggestedSort);
post.setPreviews(previews);
post.setVideoUrl(url);
post.setVideoDownloadUrl(url);
} else {
//CP No Preview Link post
int postType = Post.NO_PREVIEW_LINK_TYPE;
post = new Post(id, fullName, subredditName, subredditNamePrefixed, author,
authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score,
postType, voteType, nComments, upvoteRatio, flair, hidden,
spoiler, nsfw, stickied, archived, locked, saved, isCrosspost, distinguished, suggestedSort);
//Need attention
if (data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText("");
} else {
post.setSelfText(Utils.parseRedditImagesBlock(Utils.modifyMarkdown(Utils.trimTrailingWhitespace(data.getString(JSONUtils.SELFTEXT_KEY))), mediaMetadataMap));
}
String authority = uri.getAuthority();
if (authority != null) {
if (authority.contains("redgifs.com")) {
String redgifsId = url.substring(url.lastIndexOf("/") + 1).toLowerCase();
post.setPostType(Post.VIDEO_TYPE);
post.setIsRedgifs(true);
post.setVideoUrl(url);
post.setRedgifsId(redgifsId);
} else if (authority.equals("streamable.com")) {
String shortCode = url.substring(url.lastIndexOf("/") + 1);
post.setPostType(Post.VIDEO_TYPE);
post.setIsStreamable(true);
post.setVideoUrl(url);
post.setStreamableShortCode(shortCode);
}
}
}
}
}
if (post.getPostType() == Post.VIDEO_TYPE) {
try {
String authority = uri.getAuthority();
if (authority != null) {
if (authority.contains("redgifs.com")) {
String redgifsId = url.substring(url.lastIndexOf("/") + 1);
if (redgifsId.contains("-")) {
redgifsId = redgifsId.substring(0, redgifsId.indexOf('-'));
}
post.setIsRedgifs(true);
post.setVideoUrl(url);
post.setRedgifsId(redgifsId.toLowerCase());
} else if (authority.equals("streamable.com")) {
String shortCode = url.substring(url.lastIndexOf("/") + 1);
post.setPostType(Post.VIDEO_TYPE);
post.setIsStreamable(true);
post.setVideoUrl(url);
post.setStreamableShortCode(shortCode);
}
}
} catch (IllegalArgumentException ignore) { }
} else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) {
if (!data.isNull(JSONUtils.GALLERY_DATA_KEY)) {
JSONArray galleryIdsArray = data.getJSONObject(JSONUtils.GALLERY_DATA_KEY).getJSONArray(JSONUtils.ITEMS_KEY);
JSONObject galleryObject = data.getJSONObject(JSONUtils.MEDIA_METADATA_KEY);
ArrayList<Post.Gallery> gallery = new ArrayList<>();
for (int i = 0; i < galleryIdsArray.length(); i++) {
String galleryId = galleryIdsArray.getJSONObject(i).getString(JSONUtils.MEDIA_ID_KEY);
JSONObject singleGalleryObject = galleryObject.getJSONObject(galleryId);
String mimeType = singleGalleryObject.getString(JSONUtils.M_KEY);
String galleryItemUrl;
if (mimeType.contains("jpg") || mimeType.contains("png")) {
galleryItemUrl = singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getString(JSONUtils.U_KEY);
} else {
JSONObject sourceObject = singleGalleryObject.getJSONObject(JSONUtils.S_KEY);
if (mimeType.contains("gif")) {
galleryItemUrl = sourceObject.getString(JSONUtils.GIF_KEY);
} else {
galleryItemUrl = sourceObject.getString(JSONUtils.MP4_KEY);
}
}
JSONObject galleryItem = galleryIdsArray.getJSONObject(i);
String galleryItemCaption = "";
String galleryItemCaptionUrl = "";
if (galleryItem.has(JSONUtils.CAPTION_KEY)) {
galleryItemCaption = galleryItem.getString(JSONUtils.CAPTION_KEY).trim();
}
if (galleryItem.has(JSONUtils.CAPTION_URL_KEY)) {
galleryItemCaptionUrl = galleryItem.getString(JSONUtils.CAPTION_URL_KEY).trim();
}
if (previews.isEmpty() && (mimeType.contains("jpg") || mimeType.contains("png"))) {
previews.add(new Post.Preview(galleryItemUrl, singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getInt(JSONUtils.X_KEY),
singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getInt(JSONUtils.Y_KEY), galleryItemCaption, galleryItemCaptionUrl));
}
Post.Gallery postGalleryItem = new Post.Gallery(mimeType, galleryItemUrl, "", subredditName + "-" + galleryId + "." + mimeType.substring(mimeType.lastIndexOf("/") + 1), galleryItemCaption, galleryItemCaptionUrl);
// For issue #558
// Construct a fallback image url
if (!TextUtils.isEmpty(galleryItemUrl) && !TextUtils.isEmpty(mimeType) && (mimeType.contains("jpg") || mimeType.contains("png"))) {
postGalleryItem.setFallbackUrl("https://i.redd.it/" + galleryId + "." + mimeType.substring(mimeType.lastIndexOf("/") + 1));
postGalleryItem.setHasFallback(true);
}
gallery.add(postGalleryItem);
}
if (!gallery.isEmpty()) {
post.setPostType(Post.GALLERY_TYPE);
post.setGallery(gallery);
post.setPreviews(previews);
}
} else if (post.getPostType() == Post.LINK_TYPE) {
String authority = uri.getAuthority();
if (authority != null) {
if (authority.contains("redgifs.com")) {
String redgifsId = url.substring(url.lastIndexOf("/") + 1).toLowerCase();
post.setPostType(Post.VIDEO_TYPE);
post.setIsRedgifs(true);
post.setVideoUrl(url);
post.setRedgifsId(redgifsId);
} else if (authority.equals("streamable.com")) {
String shortCode = url.substring(url.lastIndexOf("/") + 1);
post.setPostType(Post.VIDEO_TYPE);
post.setIsStreamable(true);
post.setVideoUrl(url);
post.setStreamableShortCode(shortCode);
}
}
}
}
if (post.getPostType() != Post.LINK_TYPE && post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) {
if (data.isNull(JSONUtils.SELFTEXT_KEY)) {
post.setSelfText("");
} else {
String selfText = Utils.parseRedditImagesBlock(Utils.modifyMarkdown(Utils.trimTrailingWhitespace(data.getString(JSONUtils.SELFTEXT_KEY))), mediaMetadataMap);
post.setSelfText(selfText);
if (data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) {
post.setSelfTextPlainTrimmed("");
} else {
String selfTextPlain = Utils.trimTrailingWhitespace(
Html.fromHtml(data.getString(JSONUtils.SELFTEXT_HTML_KEY))).toString();
post.setSelfTextPlain(selfTextPlain);
if (selfTextPlain.length() > 250) {
selfTextPlain = selfTextPlain.substring(0, 250);
}
if (!selfText.equals("")) {
Pattern p = Pattern.compile(">!.+!<");
Matcher m = p.matcher(selfText.substring(0, Math.min(selfText.length(), 400)));
if (m.find()) {
post.setSelfTextPlainTrimmed("");
} else {
post.setSelfTextPlainTrimmed(selfTextPlain);
}
} else {
post.setSelfTextPlainTrimmed(selfTextPlain);
}
}
}
}
post.setMediaMetadataMap(mediaMetadataMap);
return post;
}
public interface ParsePostsListingListener {
void onParsePostsListingSuccess(LinkedHashSet<Post> newPostData, String lastItem);
void onParsePostsListingFail();
}
public interface ParsePostListener {
void onParsePostSuccess(Post post);
void onParsePostFail();
}
public interface ParseRandomPostListener {
void onParseRandomPostSuccess(String postId, String subredditName);
void onParseRandomPostFailed();
}
}