From c52cf467ac24e92cd1846b9ee10fb6acc2fdabfb Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Thu, 30 Apr 2020 21:33:51 +0800 Subject: Probably fix duplicate posts issues. Move classes related to Post to Package Post. --- .../Activity/ViewPostDetailActivity.java | 6 +- .../infinityforreddit/FetchPost.java | 54 --- .../infinityforreddit/HidePost.java | 62 --- .../infinityforreddit/ParsePost.java | 488 --------------------- .../infinityforreddit/Post/FetchPost.java | 54 +++ .../infinityforreddit/Post/HidePost.java | 63 +++ .../infinityforreddit/Post/ParsePost.java | 487 ++++++++++++++++++++ .../infinityforreddit/Post/Post.java | 10 + .../infinityforreddit/Post/PostDataSource.java | 104 +++-- .../infinityforreddit/Post/SubmitPost.java | 464 ++++++++++++++++++++ .../Service/SubmitPostService.java | 2 +- .../infinityforreddit/SubmitPost.java | 464 -------------------- 12 files changed, 1160 insertions(+), 1098 deletions(-) delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/FetchPost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/HidePost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java (limited to 'app/src/main') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java index 92d04927..9d8ea8a9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java @@ -64,14 +64,14 @@ import ml.docilealligator.infinityforreddit.Event.PostUpdateEventToDetailActivit import ml.docilealligator.infinityforreddit.Event.PostUpdateEventToPostList; import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.FetchComment; -import ml.docilealligator.infinityforreddit.FetchPost; +import ml.docilealligator.infinityforreddit.Post.FetchPost; import ml.docilealligator.infinityforreddit.Flair; import ml.docilealligator.infinityforreddit.Fragment.FlairBottomSheetFragment; import ml.docilealligator.infinityforreddit.Fragment.PostCommentSortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.HidePost; +import ml.docilealligator.infinityforreddit.Post.HidePost; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.ParseComment; -import ml.docilealligator.infinityforreddit.ParsePost; +import ml.docilealligator.infinityforreddit.Post.ParsePost; import ml.docilealligator.infinityforreddit.Post.Post; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.ReadMessage; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPost.java deleted file mode 100644 index 9f0c93ba..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPost.java +++ /dev/null @@ -1,54 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import androidx.annotation.NonNull; - -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Utils.RedditUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchPost { - public static void fetchPost(Retrofit retrofit, String id, String accessToken, Locale locale, FetchPostListener fetchPostListener) { - Call postCall; - if (accessToken == null) { - postCall = retrofit.create(RedditAPI.class).getPost(id); - } else { - postCall = retrofit.create(RedditAPI.class).getPostOauth(id, RedditUtils.getOAuthHeader(accessToken)); - } - postCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { - @Override - public void onParsePostSuccess(Post post) { - fetchPostListener.fetchPostSuccess(post); - } - - @Override - public void onParsePostFail() { - fetchPostListener.fetchPostFailed(); - } - }); - } else { - fetchPostListener.fetchPostFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchPostListener.fetchPostFailed(); - } - }); - } - - public interface FetchPostListener { - void fetchPostSuccess(Post post); - - void fetchPostFailed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/HidePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/HidePost.java deleted file mode 100644 index 39f6a2fb..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/HidePost.java +++ /dev/null @@ -1,62 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.Utils.RedditUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class HidePost { - public static void hidePost(Retrofit oauthRetrofit, String accessToken, String fullname, - HidePostListener hidePostListener) { - Map params = new HashMap<>(); - params.put(RedditUtils.ID_KEY, fullname); - oauthRetrofit.create(RedditAPI.class).hide(RedditUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - hidePostListener.success(); - } else { - hidePostListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - hidePostListener.failed(); - } - }); - } - - public static void unhidePost(Retrofit oauthRetrofit, String accessToken, String fullname, - HidePostListener hidePostListener) { - Map params = new HashMap<>(); - params.put(RedditUtils.ID_KEY, fullname); - oauthRetrofit.create(RedditAPI.class).unhide(RedditUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - hidePostListener.success(); - } else { - hidePostListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - hidePostListener.failed(); - } - }); - } - - public interface HidePostListener { - void success(); - - void failed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java deleted file mode 100644 index 3a4845e1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParsePost.java +++ /dev/null @@ -1,488 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.os.AsyncTask; -import android.text.Html; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -/** - * Created by alex on 3/21/18. - */ - -public class ParsePost { - public static void parsePosts(String response, Locale locale, int nPosts, int filter, boolean nsfw, - ParsePostsListingListener parsePostsListingListener) { - new ParsePostDataAsyncTask(response, locale, nPosts, filter, nsfw, parsePostsListingListener).execute(); - } - - public static void parsePost(String response, Locale locale, ParsePostListener parsePostListener) { - new ParsePostDataAsyncTask(response, locale, true, parsePostListener).execute(); - } - - private static Post parseBasicData(JSONObject data, Locale locale) 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(""); - } - } - } - String authorFlair = data.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) ? "" : data.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY); - 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); - 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.LOCKEC_KEY); - boolean saved = data.getBoolean(JSONUtils.SAVED_KEY); - StringBuilder postFlairHTMLBuilder = new StringBuilder(); - 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(""); - } - } - } - String flair = postFlairHTMLBuilder.toString(); - StringBuilder awardingsBuilder = new StringBuilder(); - JSONArray awardingsArray = data.getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); - int nAwards = 0; - for (int i = 0; i < awardingsArray.length(); i++) { - JSONObject award = awardingsArray.getJSONObject(i); - int count = award.getInt(JSONUtils.COUNT_KEY); - nAwards += count; - JSONArray icons = award.getJSONArray(JSONUtils.RESIZED_ICONS_KEY); - if (icons.length() > 4) { - String iconUrl = icons.getJSONObject(3).getString(JSONUtils.URL_KEY); - awardingsBuilder.append(" ").append("x").append(count).append(" "); - } else if (icons.length() > 0) { - String iconUrl = icons.getJSONObject(icons.length() - 1).getString(JSONUtils.URL_KEY); - awardingsBuilder.append(" ").append("x").append(count).append(" "); - } - } - - if (data.isNull(JSONUtils.LIKES_KEY)) { - voteType = 0; - } else { - voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; - score -= voteType; - } - - Calendar postTimeCalendar = Calendar.getInstance(); - postTimeCalendar.setTimeInMillis(postTime); - String formattedPostTime = new SimpleDateFormat("MMM d, yyyy, HH:mm", - locale).format(postTimeCalendar.getTime()); - String permalink = Html.fromHtml(data.getString(JSONUtils.PERMALINK_KEY)).toString(); - - String previewUrl = ""; - String thumbnailPreviewUrl = ""; - int previewWidth = -1; - int previewHeight = -1; - if (data.has(JSONUtils.PREVIEW_KEY)) { - JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); - previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); - JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY); - int thumbnailPreviewsLength = thumbnailPreviews.length(); - if (thumbnailPreviewsLength > 0) { - if (thumbnailPreviewsLength >= 3) { - thumbnailPreviewUrl = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY).getJSONObject(2).getString(JSONUtils.URL_KEY); - } else { - thumbnailPreviewUrl = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY).getJSONObject(0).getString(JSONUtils.URL_KEY); - } - } - previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); - previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); - } - if (data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { - //Cross post - data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); - Post crosspostParent = parseBasicData(data, locale); - Post post = parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, - author, authorFlair, authorFlairHTMLBuilder.toString(), formattedPostTime, - postTime, title, previewUrl, thumbnailPreviewUrl, previewWidth, previewHeight, - score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, - spoiler, nsfw, stickied, archived, locked, saved, true); - post.setCrosspostParentId(crosspostParent.getId()); - return post; - } else { - return parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, - author, authorFlair, authorFlairHTMLBuilder.toString(), formattedPostTime, - postTime, title, previewUrl, thumbnailPreviewUrl, previewWidth, previewHeight, - score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, - spoiler, nsfw, stickied, archived, locked, saved, false); - } - } - - private static Post parseData(JSONObject data, String permalink, String id, String fullName, - String subredditName, String subredditNamePrefixed, String author, - String authorFlair, String authorFlairHTML, String formattedPostTime, - long postTimeMillis, String title, String previewUrl, - String thumbnailPreviewUrl, int previewWidth, int previewHeight, - int score, int voteType, int nComments, String flair, - String awards, int nAwards, boolean hidden, boolean spoiler, - boolean nsfw, boolean stickied, boolean archived, boolean locked, - boolean saved, boolean isCrosspost) throws JSONException { - Post post; - - boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); - String url = Html.fromHtml(data.getString(JSONUtils.URL_KEY)).toString(); - - if (!data.has(JSONUtils.PREVIEW_KEY) && previewUrl.equals("")) { - if (url.contains(permalink)) { - //Text post - int postType = Post.TEXT_TYPE; - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, - title, permalink, score, postType, voteType, nComments, flair, awards, nAwards, - hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost); - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - 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); - } - post.setSelfTextPlainTrimmed(selfTextPlain); - } - } - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - int postType = Post.IMAGE_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, title, - url, thumbnailPreviewUrl, url, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, - locked, saved, isCrosspost); - - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - } else { - //No preview link post - int postType = Post.NO_PREVIEW_LINK_TYPE; - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, - title, previewUrl, thumbnailPreviewUrl, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, - archived, locked, saved, isCrosspost); - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - } - } - } - } else { - if (previewUrl.equals("")) { - previewUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) - .getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY)).toString(); - } - - 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, formattedPostTime, postTimeMillis, title, - previewUrl, thumbnailPreviewUrl, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, - saved, isCrosspost); - - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - 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)) { - //Gif video post (HLS) - int postType = Post.VIDEO_TYPE; - 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, formattedPostTime, postTimeMillis, title, - previewUrl, thumbnailPreviewUrl, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, - locked, saved, isCrosspost); - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - post.setVideoUrl(videoUrl); - post.setVideoDownloadUrl(videoDownloadUrl); - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - int postType = Post.IMAGE_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, - title, url, thumbnailPreviewUrl, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, - stickied, archived, locked, saved, isCrosspost); - - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - } else if (url.endsWith("gif")){ - //Gif post - int postType = Post.GIF_TYPE; - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, - title, previewUrl, thumbnailPreviewUrl, url, permalink, score, - postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, - nsfw, stickied, archived, locked, saved, isCrosspost); - - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - post.setVideoUrl(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, formattedPostTime, postTimeMillis, - title, permalink, score, postType, voteType, nComments, flair, - awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, - saved, isCrosspost); - - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - 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); - } - post.setSelfTextPlainTrimmed(selfTextPlain); - } - } - } else { - //Link post - int postType = Post.LINK_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, - title, previewUrl, thumbnailPreviewUrl, url, permalink, score, - postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, - nsfw, stickied, archived, locked, saved, isCrosspost); - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - } - - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - } - } - } - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - int postType = Post.IMAGE_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, title, - previewUrl, thumbnailPreviewUrl, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, - archived, locked, saved, isCrosspost); - post.setPreviewWidth(previewWidth); - post.setPreviewHeight(previewHeight); - } else { - //CP No Preview Link post - int postType = Post.NO_PREVIEW_LINK_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, title, - url, thumbnailPreviewUrl, url, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, - locked, saved, isCrosspost); - } - } - } - - return post; - } - - public interface ParsePostsListingListener { - void onParsePostsListingSuccess(ArrayList newPostData, String lastItem); - - void onParsePostsListingFail(); - } - - public interface ParsePostListener { - void onParsePostSuccess(Post post); - - void onParsePostFail(); - } - - private static class ParsePostDataAsyncTask extends AsyncTask { - private JSONArray allData; - private Locale locale; - private int nPosts; - private int filter; - private boolean nsfw; - private ParsePostsListingListener parsePostsListingListener; - private ParsePostListener parsePostListener; - private ArrayList newPosts; - private Post post; - private String lastItem; - private boolean parseFailed; - - ParsePostDataAsyncTask(String response, Locale locale, int nPosts, int filter, boolean nsfw, - ParsePostsListingListener parsePostsListingListener) { - this.parsePostsListingListener = parsePostsListingListener; - try { - JSONObject jsonResponse = new JSONObject(response); - allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); - this.locale = locale; - this.nPosts = nPosts; - this.filter = filter; - this.nsfw = nsfw; - newPosts = new ArrayList<>(); - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - ParsePostDataAsyncTask(String response, Locale locale, boolean nsfw, - ParsePostListener parsePostListener) { - this.parsePostListener = parsePostListener; - try { - allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - this.locale = locale; - this.nsfw = nsfw; - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - @Override - protected Void doInBackground(Void... voids) { - if (parseFailed) { - return null; - } - - if (newPosts == null) { - //Only one post - if (allData.length() == 0) { - parseFailed = true; - return null; - } - - try { - JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); - post = parseBasicData(data, locale); - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } else { - //Posts listing - int size; - if (nPosts < 0 || nPosts > allData.length()) { - size = allData.length(); - } else { - size = nPosts; - } - - for (int i = 0; i < size; i++) { - try { - if (allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { - JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - Post post = parseBasicData(data, locale); - if (!(!nsfw && post.isNSFW())) { - if (filter == PostFragment.EXTRA_NO_FILTER) { - newPosts.add(post); - } else if (filter == post.getPostType()) { - newPosts.add(post); - } else if (filter == Post.LINK_TYPE && post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { - newPosts.add(post); - } else if (filter == Post.NSFW_TYPE && post.isNSFW()) { - newPosts.add(post); - } - } - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - if (newPosts != null) { - parsePostsListingListener.onParsePostsListingSuccess(newPosts, lastItem); - } else { - parsePostListener.onParsePostSuccess(post); - } - } else { - if (parsePostsListingListener != null) { - parsePostsListingListener.onParsePostsListingFail(); - } else { - parsePostListener.onParsePostFail(); - } - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java new file mode 100644 index 00000000..ccbec648 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java @@ -0,0 +1,54 @@ +package ml.docilealligator.infinityforreddit.Post; + +import androidx.annotation.NonNull; + +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.RedditAPI; +import ml.docilealligator.infinityforreddit.Utils.RedditUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchPost { + public static void fetchPost(Retrofit retrofit, String id, String accessToken, Locale locale, FetchPostListener fetchPostListener) { + Call postCall; + if (accessToken == null) { + postCall = retrofit.create(RedditAPI.class).getPost(id); + } else { + postCall = retrofit.create(RedditAPI.class).getPostOauth(id, RedditUtils.getOAuthHeader(accessToken)); + } + postCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(Post post) { + fetchPostListener.fetchPostSuccess(post); + } + + @Override + public void onParsePostFail() { + fetchPostListener.fetchPostFailed(); + } + }); + } else { + fetchPostListener.fetchPostFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchPostListener.fetchPostFailed(); + } + }); + } + + public interface FetchPostListener { + void fetchPostSuccess(Post post); + + void fetchPostFailed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java new file mode 100644 index 00000000..ab031fa5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java @@ -0,0 +1,63 @@ +package ml.docilealligator.infinityforreddit.Post; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.RedditAPI; +import ml.docilealligator.infinityforreddit.Utils.RedditUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class HidePost { + public static void hidePost(Retrofit oauthRetrofit, String accessToken, String fullname, + HidePostListener hidePostListener) { + Map params = new HashMap<>(); + params.put(RedditUtils.ID_KEY, fullname); + oauthRetrofit.create(RedditAPI.class).hide(RedditUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + hidePostListener.success(); + } else { + hidePostListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + hidePostListener.failed(); + } + }); + } + + public static void unhidePost(Retrofit oauthRetrofit, String accessToken, String fullname, + HidePostListener hidePostListener) { + Map params = new HashMap<>(); + params.put(RedditUtils.ID_KEY, fullname); + oauthRetrofit.create(RedditAPI.class).unhide(RedditUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + hidePostListener.success(); + } else { + hidePostListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + hidePostListener.failed(); + } + }); + } + + public interface HidePostListener { + void success(); + + void failed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java new file mode 100644 index 00000000..ba59f855 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java @@ -0,0 +1,487 @@ +package ml.docilealligator.infinityforreddit.Post; + +import android.os.AsyncTask; +import android.text.Html; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.LinkedHashSet; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.Fragment.PostFragment; +import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import ml.docilealligator.infinityforreddit.Utils.Utils; + +/** + * Created by alex on 3/21/18. + */ + +public class ParsePost { + public static void parsePosts(String response, Locale locale, int nPosts, int filter, boolean nsfw, + ParsePostsListingListener parsePostsListingListener) { + new ParsePostDataAsyncTask(response, locale, nPosts, filter, nsfw, parsePostsListingListener).execute(); + } + + public static void parsePost(String response, Locale locale, ParsePostListener parsePostListener) { + new ParsePostDataAsyncTask(response, locale, true, parsePostListener).execute(); + } + + private static Post parseBasicData(JSONObject data, Locale locale) 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(""); + } + } + } + String authorFlair = data.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) ? "" : data.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY); + 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); + 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.LOCKEC_KEY); + boolean saved = data.getBoolean(JSONUtils.SAVED_KEY); + StringBuilder postFlairHTMLBuilder = new StringBuilder(); + 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(""); + } + } + } + String flair = postFlairHTMLBuilder.toString(); + StringBuilder awardingsBuilder = new StringBuilder(); + JSONArray awardingsArray = data.getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); + int nAwards = 0; + for (int i = 0; i < awardingsArray.length(); i++) { + JSONObject award = awardingsArray.getJSONObject(i); + int count = award.getInt(JSONUtils.COUNT_KEY); + nAwards += count; + JSONArray icons = award.getJSONArray(JSONUtils.RESIZED_ICONS_KEY); + if (icons.length() > 4) { + String iconUrl = icons.getJSONObject(3).getString(JSONUtils.URL_KEY); + awardingsBuilder.append(" ").append("x").append(count).append(" "); + } else if (icons.length() > 0) { + String iconUrl = icons.getJSONObject(icons.length() - 1).getString(JSONUtils.URL_KEY); + awardingsBuilder.append(" ").append("x").append(count).append(" "); + } + } + + if (data.isNull(JSONUtils.LIKES_KEY)) { + voteType = 0; + } else { + voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; + score -= voteType; + } + + Calendar postTimeCalendar = Calendar.getInstance(); + postTimeCalendar.setTimeInMillis(postTime); + String formattedPostTime = new SimpleDateFormat("MMM d, yyyy, HH:mm", + locale).format(postTimeCalendar.getTime()); + String permalink = Html.fromHtml(data.getString(JSONUtils.PERMALINK_KEY)).toString(); + + String previewUrl = ""; + String thumbnailPreviewUrl = ""; + int previewWidth = -1; + int previewHeight = -1; + if (data.has(JSONUtils.PREVIEW_KEY)) { + JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); + previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); + JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY); + int thumbnailPreviewsLength = thumbnailPreviews.length(); + if (thumbnailPreviewsLength > 0) { + if (thumbnailPreviewsLength >= 3) { + thumbnailPreviewUrl = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY).getJSONObject(2).getString(JSONUtils.URL_KEY); + } else { + thumbnailPreviewUrl = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY).getJSONObject(0).getString(JSONUtils.URL_KEY); + } + } + previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); + previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); + } + if (data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { + //Cross post + data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); + Post crosspostParent = parseBasicData(data, locale); + Post post = parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, + author, authorFlair, authorFlairHTMLBuilder.toString(), formattedPostTime, + postTime, title, previewUrl, thumbnailPreviewUrl, previewWidth, previewHeight, + score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, + spoiler, nsfw, stickied, archived, locked, saved, true); + post.setCrosspostParentId(crosspostParent.getId()); + return post; + } else { + return parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, + author, authorFlair, authorFlairHTMLBuilder.toString(), formattedPostTime, + postTime, title, previewUrl, thumbnailPreviewUrl, previewWidth, previewHeight, + score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, + spoiler, nsfw, stickied, archived, locked, saved, false); + } + } + + private static Post parseData(JSONObject data, String permalink, String id, String fullName, + String subredditName, String subredditNamePrefixed, String author, + String authorFlair, String authorFlairHTML, String formattedPostTime, + long postTimeMillis, String title, String previewUrl, + String thumbnailPreviewUrl, int previewWidth, int previewHeight, + int score, int voteType, int nComments, String flair, + String awards, int nAwards, boolean hidden, boolean spoiler, + boolean nsfw, boolean stickied, boolean archived, boolean locked, + boolean saved, boolean isCrosspost) throws JSONException { + Post post; + + boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); + String url = Html.fromHtml(data.getString(JSONUtils.URL_KEY)).toString(); + + if (!data.has(JSONUtils.PREVIEW_KEY) && previewUrl.equals("")) { + if (url.contains(permalink)) { + //Text post + int postType = Post.TEXT_TYPE; + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, + title, permalink, score, postType, voteType, nComments, flair, awards, nAwards, + hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost); + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + 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); + } + post.setSelfTextPlainTrimmed(selfTextPlain); + } + } + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //Image post + int postType = Post.IMAGE_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, title, + url, thumbnailPreviewUrl, url, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, + locked, saved, isCrosspost); + + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + } else { + //No preview link post + int postType = Post.NO_PREVIEW_LINK_TYPE; + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, + title, previewUrl, thumbnailPreviewUrl, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, + archived, locked, saved, isCrosspost); + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + } + } + } + } else { + if (previewUrl.equals("")) { + previewUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0) + .getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY)).toString(); + } + + 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, formattedPostTime, postTimeMillis, title, + previewUrl, thumbnailPreviewUrl, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, + saved, isCrosspost); + + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + 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)) { + //Gif video post (HLS) + int postType = Post.VIDEO_TYPE; + 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, formattedPostTime, postTimeMillis, title, + previewUrl, thumbnailPreviewUrl, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, + locked, saved, isCrosspost); + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + post.setVideoUrl(videoUrl); + post.setVideoDownloadUrl(videoDownloadUrl); + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //Image post + int postType = Post.IMAGE_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, + title, url, thumbnailPreviewUrl, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, + stickied, archived, locked, saved, isCrosspost); + + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + } else if (url.endsWith("gif")){ + //Gif post + int postType = Post.GIF_TYPE; + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, + title, previewUrl, thumbnailPreviewUrl, url, permalink, score, + postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, + nsfw, stickied, archived, locked, saved, isCrosspost); + + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + post.setVideoUrl(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, formattedPostTime, postTimeMillis, + title, permalink, score, postType, voteType, nComments, flair, + awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, + saved, isCrosspost); + + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + 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); + } + post.setSelfTextPlainTrimmed(selfTextPlain); + } + } + } else { + //Link post + int postType = Post.LINK_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, + title, previewUrl, thumbnailPreviewUrl, url, permalink, score, + postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, + nsfw, stickied, archived, locked, saved, isCrosspost); + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + } + + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + } + } + } + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //Image post + int postType = Post.IMAGE_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, title, + previewUrl, thumbnailPreviewUrl, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, + archived, locked, saved, isCrosspost); + post.setPreviewWidth(previewWidth); + post.setPreviewHeight(previewHeight); + } else { + //CP No Preview Link post + int postType = Post.NO_PREVIEW_LINK_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, formattedPostTime, postTimeMillis, title, + url, thumbnailPreviewUrl, url, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, + locked, saved, isCrosspost); + } + } + } + + return post; + } + + public interface ParsePostsListingListener { + void onParsePostsListingSuccess(LinkedHashSet newPostData, String lastItem); + + void onParsePostsListingFail(); + } + + public interface ParsePostListener { + void onParsePostSuccess(Post post); + + void onParsePostFail(); + } + + private static class ParsePostDataAsyncTask extends AsyncTask { + private JSONArray allData; + private Locale locale; + private int nPosts; + private int filter; + private boolean nsfw; + private ParsePostsListingListener parsePostsListingListener; + private ParsePostListener parsePostListener; + private LinkedHashSet newPosts; + private Post post; + private String lastItem; + private boolean parseFailed; + + ParsePostDataAsyncTask(String response, Locale locale, int nPosts, int filter, boolean nsfw, + ParsePostsListingListener parsePostsListingListener) { + this.parsePostsListingListener = parsePostsListingListener; + try { + JSONObject jsonResponse = new JSONObject(response); + allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + this.locale = locale; + this.nPosts = nPosts; + this.filter = filter; + this.nsfw = nsfw; + newPosts = new LinkedHashSet<>(); + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + ParsePostDataAsyncTask(String response, Locale locale, boolean nsfw, + ParsePostListener parsePostListener) { + this.parsePostListener = parsePostListener; + try { + allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + this.locale = locale; + this.nsfw = nsfw; + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + @Override + protected Void doInBackground(Void... voids) { + if (parseFailed) { + return null; + } + + if (newPosts == null) { + //Only one post + if (allData.length() == 0) { + parseFailed = true; + return null; + } + + try { + JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); + post = parseBasicData(data, locale); + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } else { + //Posts listing + int size; + if (nPosts < 0 || nPosts > allData.length()) { + size = allData.length(); + } else { + size = nPosts; + } + + for (int i = 0; i < size; i++) { + try { + if (allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { + JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + Post post = parseBasicData(data, locale); + if (!(!nsfw && post.isNSFW())) { + if (filter == PostFragment.EXTRA_NO_FILTER) { + newPosts.add(post); + } else if (filter == post.getPostType()) { + newPosts.add(post); + } else if (filter == Post.LINK_TYPE && post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + newPosts.add(post); + } else if (filter == Post.NSFW_TYPE && post.isNSFW()) { + newPosts.add(post); + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!parseFailed) { + if (newPosts != null) { + parsePostsListingListener.onParsePostsListingSuccess(newPosts, lastItem); + } else { + parsePostListener.onParsePostSuccess(post); + } + } else { + if (parsePostsListingListener != null) { + parsePostsListingListener.onParsePostsListingFail(); + } else { + parsePostListener.onParsePostFail(); + } + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java index d8b98ad8..eccc4388 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java @@ -3,6 +3,8 @@ package ml.docilealligator.infinityforreddit.Post; import android.os.Parcel; import android.os.Parcelable; +import androidx.annotation.Nullable; + import ml.docilealligator.infinityforreddit.Utils.RedditUtils; /** @@ -506,4 +508,12 @@ public class Post implements Parcelable { parcel.writeByte((byte) (isCrosspost ? 1 : 0)); parcel.writeString(crosspostParentId); } + + @Override + public boolean equals(@Nullable Object obj) { + if (!(obj instanceof Post)) { + return false; + } + return ((Post) obj).getFullName().equals(fullName); + } } \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java index 19536c47..e8e865b1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java @@ -5,10 +5,11 @@ import androidx.lifecycle.MutableLiveData; import androidx.paging.PageKeyedDataSource; import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; import java.util.Locale; import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.ParsePost; import ml.docilealligator.infinityforreddit.RedditAPI; import ml.docilealligator.infinityforreddit.SortType; import ml.docilealligator.infinityforreddit.Utils.RedditUtils; @@ -42,6 +43,7 @@ public class PostDataSource extends PageKeyedDataSource { private int filter; private String userWhere; private String multiRedditPath; + private LinkedHashSet postLinkedHashSet; private MutableLiveData paginationNetworkStateLiveData; private MutableLiveData initialLoadStateLiveData; @@ -62,6 +64,7 @@ public class PostDataSource extends PageKeyedDataSource { this.sortType = sortType == null ? new SortType(SortType.Type.BEST) : sortType; this.filter = filter; this.nsfw = nsfw; + postLinkedHashSet = new LinkedHashSet<>(); } PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String path, int postType, @@ -97,6 +100,7 @@ public class PostDataSource extends PageKeyedDataSource { } this.filter = filter; this.nsfw = nsfw; + postLinkedHashSet = new LinkedHashSet<>(); } PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditOrUserName, int postType, @@ -113,6 +117,7 @@ public class PostDataSource extends PageKeyedDataSource { userWhere = where; this.filter = filter; this.nsfw = nsfw; + postLinkedHashSet = new LinkedHashSet<>(); } PostDataSource(Retrofit retrofit, String accessToken, Locale locale, String subredditOrUserName, String query, @@ -129,6 +134,7 @@ public class PostDataSource extends PageKeyedDataSource { this.sortType = sortType == null ? new SortType(SortType.Type.RELEVANCE) : sortType; this.filter = filter; this.nsfw = nsfw; + postLinkedHashSet = new LinkedHashSet<>(); } MutableLiveData getPaginationNetworkStateLiveData() { @@ -234,7 +240,7 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { String nextPageKey; if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { nextPageKey = null; @@ -242,14 +248,17 @@ public class PostDataSource extends PageKeyedDataSource { nextPageKey = lastItem; } + int currentPostsSize = postLinkedHashSet.size(); if (newPosts.size() != 0) { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(true); } else if (nextPageKey != null) { loadBestPostsInitial(callback, nextPageKey); return; } else { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(false); } @@ -296,11 +305,18 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { loadBestPostsAfter(params, callback, lastItem); } else { - callback.onResult(newPosts, lastItem); + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } } @@ -366,7 +382,7 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { String nextPageKey; if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { nextPageKey = null; @@ -375,13 +391,15 @@ public class PostDataSource extends PageKeyedDataSource { } if (newPosts.size() != 0) { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(true); } else if (nextPageKey != null) { loadSubredditPostsInitial(callback, nextPageKey); return; } else { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(false); } @@ -439,11 +457,18 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { loadSubredditPostsAfter(params, callback, lastItem); } else { - callback.onResult(newPosts, lastItem); + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } } @@ -493,7 +518,7 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { String nextPageKey; if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { nextPageKey = null; @@ -502,13 +527,15 @@ public class PostDataSource extends PageKeyedDataSource { } if (newPosts.size() != 0) { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(true); } else if (nextPageKey != null) { loadUserPostsInitial(callback, nextPageKey); return; } else { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(false); } @@ -562,11 +589,18 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { loadUserPostsAfter(params, callback, lastItem); } else { - callback.onResult(newPosts, lastItem); + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } } @@ -638,7 +672,7 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { String nextPageKey; if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { nextPageKey = null; @@ -647,13 +681,15 @@ public class PostDataSource extends PageKeyedDataSource { } if (newPosts.size() != 0) { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(true); } else if (nextPageKey != null) { loadSearchPostsInitial(callback, nextPageKey); return; } else { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(false); } @@ -727,11 +763,18 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { loadSearchPostsAfter(params, callback, lastItem); } else { - callback.onResult(newPosts, lastItem); + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } } @@ -780,7 +823,7 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { String nextPageKey; if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { nextPageKey = null; @@ -789,13 +832,15 @@ public class PostDataSource extends PageKeyedDataSource { } if (newPosts.size() != 0) { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(true); } else if (nextPageKey != null) { loadMultiRedditPostsInitial(callback, nextPageKey); return; } else { - callback.onResult(newPosts, null, nextPageKey); + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); hasPostLiveData.postValue(false); } @@ -849,11 +894,18 @@ public class PostDataSource extends PageKeyedDataSource { ParsePost.parsePosts(response.body(), locale, -1, filter, nsfw, new ParsePost.ParsePostsListingListener() { @Override - public void onParsePostsListingSuccess(ArrayList newPosts, String lastItem) { + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { loadMultiRedditPostsAfter(params, callback, lastItem); } else { - callback.onResult(newPosts, lastItem); + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } paginationNetworkStateLiveData.postValue(NetworkState.LOADED); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java new file mode 100644 index 00000000..e7479e36 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java @@ -0,0 +1,464 @@ +package ml.docilealligator.infinityforreddit.Post; + +import android.graphics.Bitmap; +import android.os.AsyncTask; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.RedditAPI; +import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import ml.docilealligator.infinityforreddit.Utils.RedditUtils; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class SubmitPost { + public static void submitTextOrLinkPost(Retrofit oauthRetrofit, String accessToken, + Locale locale, String subredditName, String title, String content, + String flair, boolean isSpoiler, boolean isNSFW, String kind, + SubmitPostListener submitPostListener) { + submitPost(oauthRetrofit, accessToken, locale, subredditName, title, content, + flair, isSpoiler, isNSFW, kind, null, submitPostListener); + } + + public static void submitImagePost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + String accessToken, Locale locale, + String subredditName, String title, Bitmap image, String flair, + boolean isSpoiler, boolean isNSFW, SubmitPostListener submitPostListener) { + uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, image, + new UploadImageListener() { + @Override + public void uploaded(String imageUrl) { + submitPost(oauthRetrofit, accessToken, locale, + subredditName, title, imageUrl, flair, isSpoiler, isNSFW, + RedditUtils.KIND_IMAGE, null, submitPostListener); + } + + @Override + public void uploadFailed(@Nullable String errorMessage) { + submitPostListener.submitFailed(errorMessage); + } + }); + } + + public static void submitVideoPost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + Retrofit uploadVideoRetrofit, String accessToken, + Locale locale, String subredditName, String title, byte[] buffer, String mimeType, + Bitmap posterBitmap, String flair, boolean isSpoiler, boolean isNSFW, + SubmitPostListener submitPostListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + String fileType = mimeType.substring(mimeType.indexOf("/") + 1); + + Map uploadImageParams = new HashMap<>(); + uploadImageParams.put(RedditUtils.FILEPATH_KEY, "post_video." + fileType); + uploadImageParams.put(RedditUtils.MIMETYPE_KEY, mimeType); + + Call uploadImageCall = api.uploadImage(RedditUtils.getOAuthHeader(accessToken), uploadImageParams); + uploadImageCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { + @Override + public void parseSuccessful(Map nameValuePairsMap) { + RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), buffer); + MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_video." + fileType, fileBody); + + RedditAPI uploadVideoToAWSApi; + if (fileType.equals("gif")) { + uploadVideoToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); + } else { + uploadVideoToAWSApi = uploadVideoRetrofit.create(RedditAPI.class); + } + Call uploadMediaToAWS = uploadVideoToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); + + uploadMediaToAWS.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { + @Override + public void parseSuccessful(String url) { + uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, + posterBitmap, new UploadImageListener() { + @Override + public void uploaded(String imageUrl) { + if (fileType.equals("gif")) { + submitPost(oauthRetrofit, accessToken, locale, + subredditName, title, url, flair, isSpoiler, isNSFW, + RedditUtils.KIND_VIDEOGIF, imageUrl, submitPostListener); + } else { + submitPost(oauthRetrofit, accessToken, locale, + subredditName, title, url, flair, isSpoiler, isNSFW, + RedditUtils.KIND_VIDEO, imageUrl, submitPostListener); + } + } + + @Override + public void uploadFailed(@Nullable String errorMessage) { + submitPostListener.submitFailed(errorMessage); + } + }); + } + + @Override + public void parseFailed() { + submitPostListener.submitFailed(null); + } + }).execute(); + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } + + @Override + public void parseFailed() { + submitPostListener.submitFailed(null); + } + }).execute(); + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } + + private static void submitPost(Retrofit oauthRetrofit, String accessToken, + Locale locale, String subredditName, String title, String content, + String flair, boolean isSpoiler, boolean isNSFW, String kind, + @Nullable String posterUrl, SubmitPostListener submitPostListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Map params = new HashMap<>(); + params.put(RedditUtils.API_TYPE_KEY, RedditUtils.API_TYPE_JSON); + params.put(RedditUtils.SR_KEY, subredditName); + params.put(RedditUtils.TITLE_KEY, title); + params.put(RedditUtils.KIND_KEY, kind); + switch (kind) { + case RedditUtils.KIND_SELF: + params.put(RedditUtils.TEXT_KEY, content); + break; + case RedditUtils.KIND_LINK: + case RedditUtils.KIND_IMAGE: + params.put(RedditUtils.URL_KEY, content); + break; + case RedditUtils.KIND_VIDEOGIF: + params.put(RedditUtils.KIND_KEY, RedditUtils.KIND_IMAGE); + params.put(RedditUtils.URL_KEY, content); + params.put(RedditUtils.VIDEO_POSTER_URL_KEY, posterUrl); + break; + case RedditUtils.KIND_VIDEO: + params.put(RedditUtils.URL_KEY, content); + params.put(RedditUtils.VIDEO_POSTER_URL_KEY, posterUrl); + break; + } + + if (flair != null) { + params.put(RedditUtils.FLAIR_TEXT_KEY, flair); + } + params.put(RedditUtils.SPOILER_KEY, Boolean.toString(isSpoiler)); + params.put(RedditUtils.NSFW_KEY, Boolean.toString(isNSFW)); + + Call submitPostCall = api.submit(RedditUtils.getOAuthHeader(accessToken), params); + submitPostCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + try { + getSubmittedPost(response.body(), kind, oauthRetrofit, accessToken, + locale, submitPostListener); + } catch (JSONException e) { + e.printStackTrace(); + submitPostListener.submitFailed(null); + } + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } + + private static void uploadImage(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + String accessToken, Bitmap image, + UploadImageListener uploadImageListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Map uploadImageParams = new HashMap<>(); + uploadImageParams.put(RedditUtils.FILEPATH_KEY, "post_image.jpg"); + uploadImageParams.put(RedditUtils.MIMETYPE_KEY, "image/jpeg"); + + Call uploadImageCall = api.uploadImage(RedditUtils.getOAuthHeader(accessToken), uploadImageParams); + uploadImageCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { + @Override + public void parseSuccessful(Map nameValuePairsMap) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + image.compress(Bitmap.CompressFormat.JPEG, 100, stream); + byte[] byteArray = stream.toByteArray(); + + RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), byteArray); + MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_image.jpg", fileBody); + + RedditAPI uploadMediaToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); + Call uploadMediaToAWS = uploadMediaToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); + + uploadMediaToAWS.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { + @Override + public void parseSuccessful(String url) { + uploadImageListener.uploaded(url); + } + + @Override + public void parseFailed() { + uploadImageListener.uploadFailed(null); + } + }).execute(); + } else { + uploadImageListener.uploadFailed("Error: " + response.code()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + uploadImageListener.uploadFailed(t.getMessage()); + } + }); + } + + @Override + public void parseFailed() { + uploadImageListener.uploadFailed(null); + } + }).execute(); + } else { + uploadImageListener.uploadFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + uploadImageListener.uploadFailed(t.getMessage()); + } + }); + } + + private static void getSubmittedPost(String response, String kind, Retrofit oauthRetrofit, + String accessToken, Locale locale, + SubmitPostListener submitPostListener) throws JSONException { + JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); + if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) + .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); + if (error.length() != 0) { + String errorString; + if (error.length() >= 2) { + errorString = error.getString(1); + } else { + errorString = error.getString(0); + } + submitPostListener.submitFailed(errorString); + } else { + submitPostListener.submitFailed(null); + } + + return; + } + + if (!kind.equals(RedditUtils.KIND_IMAGE) && !kind.equals(RedditUtils.KIND_VIDEO) && !kind.equals(RedditUtils.KIND_VIDEOGIF)) { + String postId = responseObject.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ID_KEY); + + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Call getPostCall = api.getPostOauth(postId, RedditUtils.getOAuthHeader(accessToken)); + getPostCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(Post post) { + submitPostListener.submitSuccessful(post); + } + + @Override + public void onParsePostFail() { + submitPostListener.submitFailed(null); + } + }); + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } else { + submitPostListener.submitSuccessful(null); + } + } + + public interface SubmitPostListener { + void submitSuccessful(Post post); + + void submitFailed(@Nullable String errorMessage); + } + + private interface UploadImageListener { + void uploaded(String imageUrl); + + void uploadFailed(@Nullable String errorMessage); + } + + private static class ParseJSONResponseFromAWSAsyncTask extends AsyncTask { + private String response; + private ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener; + private Map nameValuePairsMap; + private boolean successful; + ParseJSONResponseFromAWSAsyncTask(String response, ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener) { + this.response = response; + this.parseJSONResponseFromAWSListener = parseJSONResponseFromAWSListener; + nameValuePairsMap = new HashMap<>(); + successful = false; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject responseObject = new JSONObject(response); + JSONArray nameValuePairs = responseObject.getJSONObject(JSONUtils.ARGS_KEY).getJSONArray(JSONUtils.FIELDS_KEY); + + nameValuePairsMap = new HashMap<>(); + for (int i = 0; i < nameValuePairs.length(); i++) { + nameValuePairsMap.put(nameValuePairs.getJSONObject(i).getString(JSONUtils.NAME_KEY), + RedditUtils.getRequestBody(nameValuePairs.getJSONObject(i).getString(JSONUtils.VALUE_KEY))); + } + + successful = true; + } catch (JSONException e) { + e.printStackTrace(); + successful = false; + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (successful) { + parseJSONResponseFromAWSListener.parseSuccessful(nameValuePairsMap); + } else { + parseJSONResponseFromAWSListener.parseFailed(); + } + } + + interface ParseJSONResponseFromAWSListener { + void parseSuccessful(Map nameValuePairsMap); + + void parseFailed(); + } + } + + private static class ParseXMLReponseFromAWSAsyncTask extends AsyncTask { + private String response; + private ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener; + private String imageUrl; + private boolean successful; + ParseXMLReponseFromAWSAsyncTask(String response, ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener) { + this.response = response; + this.parseXMLResponseFromAWSListener = parseXMLResponseFromAWSListener; + successful = false; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); + xmlPullParser.setInput(new StringReader(response)); + + boolean isLocationTag = false; + int eventType = xmlPullParser.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + if (xmlPullParser.getName().equals("Location")) { + isLocationTag = true; + } + } else if (eventType == XmlPullParser.TEXT) { + if (isLocationTag) { + imageUrl = xmlPullParser.getText(); + successful = true; + return null; + } + } + eventType = xmlPullParser.next(); + } + } catch (XmlPullParserException | IOException e) { + e.printStackTrace(); + successful = false; + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (successful) { + parseXMLResponseFromAWSListener.parseSuccessful(imageUrl); + } else { + parseXMLResponseFromAWSListener.parseFailed(); + } + } + + interface ParseXMLResponseFromAWSListener { + void parseSuccessful(String url); + + void parseFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java index cfce40c8..cedf9730 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java @@ -39,7 +39,7 @@ import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.NotificationUtils; import ml.docilealligator.infinityforreddit.Post.Post; import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SubmitPost; +import ml.docilealligator.infinityforreddit.Post.SubmitPost; import retrofit2.Retrofit; public class SubmitPostService extends Service { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java deleted file mode 100644 index 6a93edf1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubmitPost.java +++ /dev/null @@ -1,464 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.graphics.Bitmap; -import android.os.AsyncTask; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.StringReader; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.RedditUtils; -import okhttp3.MediaType; -import okhttp3.MultipartBody; -import okhttp3.RequestBody; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class SubmitPost { - public static void submitTextOrLinkPost(Retrofit oauthRetrofit, String accessToken, - Locale locale, String subredditName, String title, String content, - String flair, boolean isSpoiler, boolean isNSFW, String kind, - SubmitPostListener submitPostListener) { - submitPost(oauthRetrofit, accessToken, locale, subredditName, title, content, - flair, isSpoiler, isNSFW, kind, null, submitPostListener); - } - - public static void submitImagePost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, - String accessToken, Locale locale, - String subredditName, String title, Bitmap image, String flair, - boolean isSpoiler, boolean isNSFW, SubmitPostListener submitPostListener) { - uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, image, - new UploadImageListener() { - @Override - public void uploaded(String imageUrl) { - submitPost(oauthRetrofit, accessToken, locale, - subredditName, title, imageUrl, flair, isSpoiler, isNSFW, - RedditUtils.KIND_IMAGE, null, submitPostListener); - } - - @Override - public void uploadFailed(@Nullable String errorMessage) { - submitPostListener.submitFailed(errorMessage); - } - }); - } - - public static void submitVideoPost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, - Retrofit uploadVideoRetrofit, String accessToken, - Locale locale, String subredditName, String title, byte[] buffer, String mimeType, - Bitmap posterBitmap, String flair, boolean isSpoiler, boolean isNSFW, - SubmitPostListener submitPostListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - String fileType = mimeType.substring(mimeType.indexOf("/") + 1); - - Map uploadImageParams = new HashMap<>(); - uploadImageParams.put(RedditUtils.FILEPATH_KEY, "post_video." + fileType); - uploadImageParams.put(RedditUtils.MIMETYPE_KEY, mimeType); - - Call uploadImageCall = api.uploadImage(RedditUtils.getOAuthHeader(accessToken), uploadImageParams); - uploadImageCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { - @Override - public void parseSuccessful(Map nameValuePairsMap) { - RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), buffer); - MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_video." + fileType, fileBody); - - RedditAPI uploadVideoToAWSApi; - if (fileType.equals("gif")) { - uploadVideoToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); - } else { - uploadVideoToAWSApi = uploadVideoRetrofit.create(RedditAPI.class); - } - Call uploadMediaToAWS = uploadVideoToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); - - uploadMediaToAWS.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { - @Override - public void parseSuccessful(String url) { - uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, - posterBitmap, new UploadImageListener() { - @Override - public void uploaded(String imageUrl) { - if (fileType.equals("gif")) { - submitPost(oauthRetrofit, accessToken, locale, - subredditName, title, url, flair, isSpoiler, isNSFW, - RedditUtils.KIND_VIDEOGIF, imageUrl, submitPostListener); - } else { - submitPost(oauthRetrofit, accessToken, locale, - subredditName, title, url, flair, isSpoiler, isNSFW, - RedditUtils.KIND_VIDEO, imageUrl, submitPostListener); - } - } - - @Override - public void uploadFailed(@Nullable String errorMessage) { - submitPostListener.submitFailed(errorMessage); - } - }); - } - - @Override - public void parseFailed() { - submitPostListener.submitFailed(null); - } - }).execute(); - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } - - @Override - public void parseFailed() { - submitPostListener.submitFailed(null); - } - }).execute(); - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } - - private static void submitPost(Retrofit oauthRetrofit, String accessToken, - Locale locale, String subredditName, String title, String content, - String flair, boolean isSpoiler, boolean isNSFW, String kind, - @Nullable String posterUrl, SubmitPostListener submitPostListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Map params = new HashMap<>(); - params.put(RedditUtils.API_TYPE_KEY, RedditUtils.API_TYPE_JSON); - params.put(RedditUtils.SR_KEY, subredditName); - params.put(RedditUtils.TITLE_KEY, title); - params.put(RedditUtils.KIND_KEY, kind); - switch (kind) { - case RedditUtils.KIND_SELF: - params.put(RedditUtils.TEXT_KEY, content); - break; - case RedditUtils.KIND_LINK: - case RedditUtils.KIND_IMAGE: - params.put(RedditUtils.URL_KEY, content); - break; - case RedditUtils.KIND_VIDEOGIF: - params.put(RedditUtils.KIND_KEY, RedditUtils.KIND_IMAGE); - params.put(RedditUtils.URL_KEY, content); - params.put(RedditUtils.VIDEO_POSTER_URL_KEY, posterUrl); - break; - case RedditUtils.KIND_VIDEO: - params.put(RedditUtils.URL_KEY, content); - params.put(RedditUtils.VIDEO_POSTER_URL_KEY, posterUrl); - break; - } - - if (flair != null) { - params.put(RedditUtils.FLAIR_TEXT_KEY, flair); - } - params.put(RedditUtils.SPOILER_KEY, Boolean.toString(isSpoiler)); - params.put(RedditUtils.NSFW_KEY, Boolean.toString(isNSFW)); - - Call submitPostCall = api.submit(RedditUtils.getOAuthHeader(accessToken), params); - submitPostCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - try { - getSubmittedPost(response.body(), kind, oauthRetrofit, accessToken, - locale, submitPostListener); - } catch (JSONException e) { - e.printStackTrace(); - submitPostListener.submitFailed(null); - } - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } - - private static void uploadImage(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, - String accessToken, Bitmap image, - UploadImageListener uploadImageListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Map uploadImageParams = new HashMap<>(); - uploadImageParams.put(RedditUtils.FILEPATH_KEY, "post_image.jpg"); - uploadImageParams.put(RedditUtils.MIMETYPE_KEY, "image/jpeg"); - - Call uploadImageCall = api.uploadImage(RedditUtils.getOAuthHeader(accessToken), uploadImageParams); - uploadImageCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { - @Override - public void parseSuccessful(Map nameValuePairsMap) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - image.compress(Bitmap.CompressFormat.JPEG, 100, stream); - byte[] byteArray = stream.toByteArray(); - - RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), byteArray); - MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_image.jpg", fileBody); - - RedditAPI uploadMediaToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); - Call uploadMediaToAWS = uploadMediaToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); - - uploadMediaToAWS.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { - @Override - public void parseSuccessful(String url) { - uploadImageListener.uploaded(url); - } - - @Override - public void parseFailed() { - uploadImageListener.uploadFailed(null); - } - }).execute(); - } else { - uploadImageListener.uploadFailed("Error: " + response.code()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - uploadImageListener.uploadFailed(t.getMessage()); - } - }); - } - - @Override - public void parseFailed() { - uploadImageListener.uploadFailed(null); - } - }).execute(); - } else { - uploadImageListener.uploadFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - uploadImageListener.uploadFailed(t.getMessage()); - } - }); - } - - private static void getSubmittedPost(String response, String kind, Retrofit oauthRetrofit, - String accessToken, Locale locale, - SubmitPostListener submitPostListener) throws JSONException { - JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); - if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { - JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) - .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); - if (error.length() != 0) { - String errorString; - if (error.length() >= 2) { - errorString = error.getString(1); - } else { - errorString = error.getString(0); - } - submitPostListener.submitFailed(errorString); - } else { - submitPostListener.submitFailed(null); - } - - return; - } - - if (!kind.equals(RedditUtils.KIND_IMAGE) && !kind.equals(RedditUtils.KIND_VIDEO) && !kind.equals(RedditUtils.KIND_VIDEOGIF)) { - String postId = responseObject.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ID_KEY); - - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Call getPostCall = api.getPostOauth(postId, RedditUtils.getOAuthHeader(accessToken)); - getPostCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), locale, new ParsePost.ParsePostListener() { - @Override - public void onParsePostSuccess(Post post) { - submitPostListener.submitSuccessful(post); - } - - @Override - public void onParsePostFail() { - submitPostListener.submitFailed(null); - } - }); - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } else { - submitPostListener.submitSuccessful(null); - } - } - - public interface SubmitPostListener { - void submitSuccessful(Post post); - - void submitFailed(@Nullable String errorMessage); - } - - private interface UploadImageListener { - void uploaded(String imageUrl); - - void uploadFailed(@Nullable String errorMessage); - } - - private static class ParseJSONResponseFromAWSAsyncTask extends AsyncTask { - private String response; - private ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener; - private Map nameValuePairsMap; - private boolean successful; - ParseJSONResponseFromAWSAsyncTask(String response, ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener) { - this.response = response; - this.parseJSONResponseFromAWSListener = parseJSONResponseFromAWSListener; - nameValuePairsMap = new HashMap<>(); - successful = false; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject responseObject = new JSONObject(response); - JSONArray nameValuePairs = responseObject.getJSONObject(JSONUtils.ARGS_KEY).getJSONArray(JSONUtils.FIELDS_KEY); - - nameValuePairsMap = new HashMap<>(); - for (int i = 0; i < nameValuePairs.length(); i++) { - nameValuePairsMap.put(nameValuePairs.getJSONObject(i).getString(JSONUtils.NAME_KEY), - RedditUtils.getRequestBody(nameValuePairs.getJSONObject(i).getString(JSONUtils.VALUE_KEY))); - } - - successful = true; - } catch (JSONException e) { - e.printStackTrace(); - successful = false; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (successful) { - parseJSONResponseFromAWSListener.parseSuccessful(nameValuePairsMap); - } else { - parseJSONResponseFromAWSListener.parseFailed(); - } - } - - interface ParseJSONResponseFromAWSListener { - void parseSuccessful(Map nameValuePairsMap); - - void parseFailed(); - } - } - - private static class ParseXMLReponseFromAWSAsyncTask extends AsyncTask { - private String response; - private ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener; - private String imageUrl; - private boolean successful; - ParseXMLReponseFromAWSAsyncTask(String response, ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener) { - this.response = response; - this.parseXMLResponseFromAWSListener = parseXMLResponseFromAWSListener; - successful = false; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); - xmlPullParser.setInput(new StringReader(response)); - - boolean isLocationTag = false; - int eventType = xmlPullParser.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - if (xmlPullParser.getName().equals("Location")) { - isLocationTag = true; - } - } else if (eventType == XmlPullParser.TEXT) { - if (isLocationTag) { - imageUrl = xmlPullParser.getText(); - successful = true; - return null; - } - } - eventType = xmlPullParser.next(); - } - } catch (XmlPullParserException | IOException e) { - e.printStackTrace(); - successful = false; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (successful) { - parseXMLResponseFromAWSListener.parseSuccessful(imageUrl); - } else { - parseXMLResponseFromAWSListener.parseFailed(); - } - } - - interface ParseXMLResponseFromAWSListener { - void parseSuccessful(String url); - - void parseFailed(); - } - } -} -- cgit v1.2.3