/*******************************************************************************
* 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 org.quantumbadger.redreader.common.Constants;
import org.quantumbadger.redreader.common.General;
import org.quantumbadger.redreader.reddit.PostSort;
import java.util.ArrayList;
import java.util.List;
public class SearchPostListURL extends PostListingURL {
public final String subreddit, query;
public final PostSort order;
public final Integer limit;
public final String before, after;
SearchPostListURL(String subreddit, String query, PostSort order, Integer limit, String before, String after) {
this.subreddit = subreddit;
this.query = query;
this.order = order;
this.limit = limit;
this.before = before;
this.after = after;
}
SearchPostListURL(String subreddit, String query, Integer limit, String before, String after) {
this(subreddit, query, PostSort.RELEVANCE, limit, before, after);
}
public static SearchPostListURL build(String subreddit, String query) {
if(subreddit != null) {
while(subreddit.startsWith("/")) subreddit = subreddit.substring(1);
while(subreddit.startsWith("r/")) subreddit = subreddit.substring(2);
}
return new SearchPostListURL(subreddit, query, null, null, null);
}
@Override
public PostListingURL after(String after) {
return new SearchPostListURL(subreddit, query, order, limit, before, after);
}
@Override
public PostListingURL limit(Integer limit) {
return new SearchPostListURL(subreddit, query, order, limit, before, after);
}
public SearchPostListURL sort(PostSort newOrder) {
return new SearchPostListURL(subreddit, query, newOrder, limit, before, after);
}
@Override
public Uri generateJsonUri() {
Uri.Builder builder = new Uri.Builder();
builder.scheme(Constants.Reddit.getScheme()).authority(Constants.Reddit.getDomain());
if(subreddit != null) {
builder.encodedPath("/r/");
builder.appendPath(subreddit);
builder.appendQueryParameter("restrict_sr", "on");
} else {
builder.encodedPath("/");
}
builder.appendEncodedPath("search");
if(query != null) {
builder.appendQueryParameter("q", query);
}
if(order != null) {
switch(order) {
case RELEVANCE:
case NEW:
case HOT:
case TOP:
case COMMENTS:
builder.appendQueryParameter("sort", General.asciiLowercase(order.name()));
break;
}
}
if(before != null) {
builder.appendQueryParameter("before", before);
}
if(after != null) {
builder.appendQueryParameter("after", after);
}
if(limit != null) {
builder.appendQueryParameter("limit", String.valueOf(limit));
}
builder.appendEncodedPath(".json");
return builder.build();
}
@Override
public @RedditURLParser.PathType int pathType() {
return RedditURLParser.SEARCH_POST_LISTING_URL;
}
public static SearchPostListURL parse(final Uri uri) {
boolean restrict_sr = false;
String query = "";
PostSort order = null;
Integer limit = null;
String before = null, after = null;
for(final String parameterKey : General.getUriQueryParameterNames(uri)) {
if(parameterKey.equalsIgnoreCase("after")) {
after = uri.getQueryParameter(parameterKey);
} else if(parameterKey.equalsIgnoreCase("before")) {
before = uri.getQueryParameter(parameterKey);
} else if(parameterKey.equalsIgnoreCase("limit")) {
try {
limit = Integer.parseInt(uri.getQueryParameter(parameterKey));
} catch(Throwable ignored) {}
} else if(parameterKey.equalsIgnoreCase("sort")) {
order = PostSort.valueOfOrNull(uri.getQueryParameter(parameterKey));
} else if(parameterKey.equalsIgnoreCase("q")) {
query = uri.getQueryParameter(parameterKey);
} else if(parameterKey.equalsIgnoreCase("restrict_sr")) {
restrict_sr = "on".equalsIgnoreCase(uri.getQueryParameter(parameterKey));
}
}
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('.'));
}
if(segment.length() > 0) {
pathSegmentsFiltered.add(segment);
}
}
pathSegments = pathSegmentsFiltered.toArray(new String[pathSegmentsFiltered.size()]);
}
if(pathSegments.length != 1 && pathSegments.length != 3) return null;
if(!pathSegments[pathSegments.length - 1].equalsIgnoreCase("search")) return null;
switch(pathSegments.length) {
case 1: {
return new SearchPostListURL(null, query, order, limit, before, after);
}
case 3: {
if(!pathSegments[0].equals("r")) return null;
final String subreddit = pathSegments[1];
return new SearchPostListURL(restrict_sr ? subreddit : null, query, order, limit, before, after);
}
default:
return null;
}
}
@Override
public String humanReadableName(Context context, boolean shorter) {
if(shorter) return "Search Results";
// TODO strings
final StringBuilder builder = new StringBuilder("Search");
if(query != null) {
builder.append(" for \"").append(query).append("\"");
}
if(subreddit != null) {
builder.append(" on /r/").append(subreddit);
}
return builder.toString();
}
@Override
public String humanReadablePath() {
final StringBuilder builder = new StringBuilder(super.humanReadablePath());
if(query != null) {
builder.append("?q=").append(query);
}
return builder.toString();
}
}