/*******************************************************************************
* This file is part of RedReader.
*
* RedReader is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RedReader is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RedReader. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package org.quantumbadger.redreader.reddit.url;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import org.quantumbadger.redreader.common.Constants;
import org.quantumbadger.redreader.common.General;
import java.util.ArrayList;
import java.util.List;
public class PostCommentListingURL extends CommentListingURL {
public final String after;
public final String postId;
public final String commentId;
public final Integer context;
public final Integer limit;
public final Sort order;
public static PostCommentListingURL forPostId(String postId) {
return new PostCommentListingURL(null, postId, null, null, null, null);
}
public PostCommentListingURL(
final String after,
String postId,
String commentId,
final Integer context,
final Integer limit,
final Sort order) {
if(postId != null && postId.startsWith("t3_")) {
postId = postId.substring(3);
}
if(commentId != null && commentId.startsWith("t1_")) {
commentId = commentId.substring(3);
}
this.after = after;
this.postId = postId;
this.commentId = commentId;
this.context = context;
this.limit = limit;
this.order = order;
}
@Override
public PostCommentListingURL after(String after) {
return new PostCommentListingURL(after, postId, commentId, context, limit, order);
}
@Override
public PostCommentListingURL limit(Integer limit) {
return new PostCommentListingURL(after, postId, commentId, context, limit, order);
}
public PostCommentListingURL context(Integer context) {
return new PostCommentListingURL(after, postId, commentId, context, limit, order);
}
public PostCommentListingURL order(Sort order) {
return new PostCommentListingURL(after, postId, commentId, context, limit, order);
}
public PostCommentListingURL commentId(String commentId) {
if(commentId != null && commentId.startsWith("t1_")) {
commentId = commentId.substring(3);
}
return new PostCommentListingURL(after, postId, commentId, context, limit, order);
}
@Override
public Uri generateJsonUri() {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(Constants.Reddit.getScheme()).authority(Constants.Reddit.getDomain());
internalGenerateCommon(builder);
builder.appendEncodedPath(".json");
return builder.build();
}
public Uri generateNonJsonUri() {
final Uri.Builder builder = new Uri.Builder();
builder.scheme(Constants.Reddit.getScheme()).authority(Constants.Reddit.getHumanReadableDomain());
internalGenerateCommon(builder);
return builder.build();
}
private void internalGenerateCommon(@NonNull final Uri.Builder builder) {
builder.encodedPath("/comments");
builder.appendPath(postId);
if(commentId != null) {
builder.appendEncodedPath("comment");
builder.appendPath(commentId);
if(context != null) {
builder.appendQueryParameter("context", context.toString());
}
}
if(after != null) {
builder.appendQueryParameter("after", after);
}
if(limit != null) {
builder.appendQueryParameter("limit", limit.toString());
}
if(order != null) {
builder.appendQueryParameter("sort", order.key);
}
}
public static PostCommentListingURL parse(final Uri uri) {
final String[] pathSegments;
{
final List<String> pathSegmentsList = uri.getPathSegments();
final ArrayList<String> pathSegmentsFiltered = new ArrayList<>(pathSegmentsList.size());
for(String segment : pathSegmentsList) {
while(General.asciiLowercase(segment).endsWith(".json") || General.asciiLowercase(segment).endsWith(".xml")) {
segment = segment.substring(0, segment.lastIndexOf('.'));
}
pathSegmentsFiltered.add(segment);
}
pathSegments = pathSegmentsFiltered.toArray(new String[pathSegmentsFiltered.size()]);
}
if(pathSegments.length == 1 && uri.getHost().equals("redd.it")) {
return new PostCommentListingURL(null, pathSegments[0], null, null, null, null);
}
if(pathSegments.length < 2) {
return null;
}
int offset = 0;
if(pathSegments[0].equalsIgnoreCase("r")) {
offset = 2;
if(pathSegments.length - offset < 2) {
return null;
}
}
if(!pathSegments[offset].equalsIgnoreCase("comments")) {
return null;
}
final String postId;
String commentId = null;
postId = pathSegments[offset + 1];
offset += 2;
if(pathSegments.length - offset >= 2) {
commentId = pathSegments[offset + 1];
}
String after = null;
Integer limit = null;
Integer context = null;
Sort order = null;
for(final String parameterKey : General.getUriQueryParameterNames(uri)) {
if(parameterKey.equalsIgnoreCase("after")) {
after = uri.getQueryParameter(parameterKey);
} else if(parameterKey.equalsIgnoreCase("limit")) {
try {
limit = Integer.parseInt(uri.getQueryParameter(parameterKey));
} catch(Throwable ignored) {}
} else if(parameterKey.equalsIgnoreCase("context")) {
try {
context = Integer.parseInt(uri.getQueryParameter(parameterKey));
} catch(Throwable ignored) {
}
} else if(parameterKey.equalsIgnoreCase("sort")) {
order = Sort.lookup(uri.getQueryParameter(parameterKey));
}
}
return new PostCommentListingURL(after, postId, commentId, context, limit, order);
}
@Override
public @RedditURLParser.PathType int pathType() {
return RedditURLParser.POST_COMMENT_LISTING_URL;
}
@Override
public String humanReadableName(final Context context, final boolean shorter) {
return super.humanReadableName(context, shorter);
}
public enum Sort {
BEST("confidence"),
HOT("hot"),
NEW("new"),
OLD("old"),
TOP("top"),
CONTROVERSIAL("controversial"),
QA("qa");
public final String key;
private Sort(final String key) {
this.key = key;
}
public static Sort lookup(String name) {
name = General.asciiUppercase(name);
if(name.equals("CONFIDENCE")) {
return BEST; // oh, reddit...
}
try {
return Sort.valueOf(name);
} catch(IllegalArgumentException e) {
return null;
}
}
}
}