package org.softeg.slartus.forpdaapi;
import android.net.Uri;
import android.text.Html;
import android.text.TextUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.softeg.slartus.forpdaapi.search.SearchApi;
import org.softeg.slartus.forpdacommon.Functions;
import org.softeg.slartus.forpdacommon.HttpHelper;
import org.softeg.slartus.forpdacommon.NotReportException;
import org.softeg.slartus.forpdacommon.PatternExtensions;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* Created by slinkin on 20.02.14.
*/
public class TopicsApi {
final static Pattern countPattern = PatternExtensions.compile("<a href=\"/forum/index.php\\?act=[^\"]*?st=(\\d+)\">»</a>");
final static Pattern mainPattern = PatternExtensions.compile("cat_name[\\s\\S]*?</div>([\\s\\S]*<br />)<div class=\"forum_mod_funcs\">");
final static Pattern topicsPattern = PatternExtensions.compile("(<div data-item-fid[\\s\\S]*?</script></div></div>)");
final static Pattern topicPattern = PatternExtensions.compile("<div data-item-fid=\"(\\d*)\" data-item-track=\"(\\w*)\" data-item-pin=\"(\\d)\"[\\s\\S]*?<a href=\"([^\"]*?)\"[^>]*>(<strong>|)([\\s\\S]*?)(<\\/strong>|)<\\/a>[\\s\\S]*?<span class=\"topic_desc\">([\\s\\S]*?)(<[\\s\\S]*?showforum=(\\d*?)\"[\\s\\S]*?)<a href=\"[^\"]*view=getlastpost[^\"]*\">Послед.:<\\/a>\\s*<a href=\"[^\"]*?\\/forum\\/index.php\\?showuser=\\d+\">(.*?)<\\/a>(.*?)<");
public static ArrayList<FavTopic> getFavTopics(IHttpClient client,
ListInfo listInfo) throws ParseException, IOException, URISyntaxException {
return getFavTopics(client, null, null, null, null, false, false, listInfo);
}
public static ArrayList<FavTopic> getFavTopics(IHttpClient client,
String sortKey,
String sortBy,
String pruneDay,
String topicFilter,
Boolean unreadInTop,
Boolean fullPagesList,
ListInfo listInfo) throws ParseException, IOException, URISyntaxException {
List<NameValuePair> qparams = new ArrayList<NameValuePair>();
qparams.add(new BasicNameValuePair("act", "fav"));
qparams.add(new BasicNameValuePair("type", "topics"));
if (sortKey != null)
qparams.add(new BasicNameValuePair("sort_key", sortKey));
if (sortBy != null)
qparams.add(new BasicNameValuePair("sort_by", sortBy));
if (pruneDay != null)
qparams.add(new BasicNameValuePair("prune_day", pruneDay));
if (topicFilter != null)
qparams.add(new BasicNameValuePair("topicfilter", topicFilter));
qparams.add(new BasicNameValuePair("st", Integer.toString(listInfo.getFrom())));
URI uri = URIUtils.createURI("http", "4pda.ru", -1, "/forum/index.php",
URLEncodedUtils.format(qparams, "UTF-8"), null);
String pageBody = client.performGet(uri.toString());
Matcher m = countPattern.matcher(pageBody);
if (m.find()) {
listInfo.setOutCount(Integer.parseInt(m.group(1)) + 1);
}
ArrayList<FavTopic> res = new ArrayList<>();
String today = Functions.getToday();
String yesterday = Functions.getYesterToday();
int sortOrder = 1000 + listInfo.getFrom() + 1;
m = mainPattern.matcher(pageBody);
Matcher tmp;
if (m.find()) {
m = topicsPattern.matcher(m.group(1));
while (m.find()) {
tmp = topicPattern.matcher(m.group(1));
if (tmp.find()) {
String tId = tmp.group(1);
String trackType = tmp.group(2);
Boolean pinned = "1".equals(tmp.group(3));
Uri ur = Uri.parse(tmp.group(4));
if (TextUtils.isEmpty(ur.getQueryParameter("showtopic"))) {
FavTopic topic = new FavTopic(null, tmp.group(6));
topic.setTid(tId);
topic.setPinned(pinned);
topic.setTrackType(trackType);
topic.setDescription("Форум");
topic.setSortOrder(Integer.toString(sortOrder++));
res.add(topic);
continue;
}
String id = ur.getQueryParameter("showtopic");
String title = tmp.group(6);
FavTopic topic = new FavTopic(id, title);
topic.setTid(tId);
topic.setPinned(pinned);
topic.setTrackType(trackType);
if (TextUtils.isEmpty(tmp.group(8)))
topic.setDescription(tmp.group(9).replaceFirst("<span class=\"topic_desc\"[\\s\\S]*$", "").replaceAll("<a[^>]*?>([\\s\\S]*?)</a>", "$1"));
else
topic.setDescription(tmp.group(8));
topic.setIsNew(tmp.group(9).contains("view=getnewpost"));
topic.setForumId(tmp.group(10));
topic.setLastMessageAuthor(tmp.group(11));
topic.setLastMessageDate(Functions.parseForumDateTime(tmp.group(12), today, yesterday));
topic.setSortOrder(Integer.toString(sortOrder++));
res.add(topic);
}
}
}
if (fullPagesList) {
while (true) {
if (listInfo.getOutCount() <= res.size())
break;
listInfo.setFrom(res.size());
ArrayList<FavTopic> nextPageTopics = getFavTopics(client, sortKey, sortBy, pruneDay, topicFilter, false, false, listInfo);
if (nextPageTopics.size() == 0)
break;
res.addAll(nextPageTopics);
}
}
if (unreadInTop) {
final int asc = -1;// новые вверху
Collections.sort(res, new Comparator<Topic>() {
@Override
public int compare(Topic topic, Topic topic2) {
if (topic.getState() == topic2.getState())
return 0;
return (topic.getState() == Topic.FLAG_NEW) ? asc : (-asc);
}
});
}
if (res.size() == 0) {
m = PatternExtensions.compile("<div class=\"errorwrap\">([\\s\\S]*?)</div>")
.matcher(pageBody);
if (m.find()) {
throw new NotReportException(Html.fromHtml(m.group(1)).toString(), new Exception(Html.fromHtml(m.group(1)).toString()));
}
}
return res;
}
public static ArrayList<Topic> getForumTopics(IHttpClient client,
String url,
String forumId,
Boolean unreadInTop,
ListInfo listInfo) throws ParseException, IOException, URISyntaxException {
String pageBody = client.performGet(url);
ArrayList<Topic> res = new ArrayList<Topic>();
if ((HttpHelper.getRedirectUri() != null && HttpHelper.getRedirectUri().toString().toLowerCase().contains("act=search"))
|| url.toLowerCase().contains("act=search")) {
res = SearchApi.parse(pageBody, listInfo);
} else {
int start = listInfo.getFrom();
Pattern lastPageStartPattern = Pattern.compile("<a href=\"(http://4pda.ru)?/forum/index.php\\?showforum=\\d+&[^\"]*?st=(\\d+)\">",
Pattern.CASE_INSENSITIVE);
Pattern themesPattern = Pattern.compile("<div class=\"topic_title\">.*?<a href=\"[^\"]*?/forum/index.php\\?showtopic=(\\d+)\">([^<]*)</a>.*?</div><div class=\"topic_body\">(?:<span class=\"topic_desc\">([^<]*)<br /></span>|)<span class=\"topic_desc\">автор: <a href=\"[^\"]*?/forum/index.php\\?showuser=\\d+\">[^<]*</a></span><br />(<a href=\"[^\"]*?/forum/index.php\\?showtopic=\\d+&view=getnewpost\">Новые</a>)?\\s*<a href=\"[^\"]*?/forum/index.php\\?showtopic=\\d+&view=getlastpost\">Послед.:</a> <a href=\"[^\"]*?/forum/index.php\\?showuser=(\\d+)\">([^<]*)</a>(.*?)<.*?/div>", Pattern.CASE_INSENSITIVE);
String today = Functions.getToday();
String yesterday = Functions.getYesterToday();
Pattern idPattern = Pattern.compile("showtopic=(\\d+)", Pattern.CASE_INSENSITIVE);
Pattern forumIdPattern = Pattern.compile("showforum=(\\d+)", Pattern.CASE_INSENSITIVE);
Document doc = Jsoup.parse(pageBody);
Elements trElements = doc.select("table:has(th:contains(Название темы)) tr");
for (Element trElement : trElements) {
if (trElement.children().size() < 3)
continue;
Element tdElement = trElement.child(2);
Element el = tdElement.select("a[href~=showtopic]").last();
if (el == null)
continue;
Matcher m = idPattern.matcher(el.attr("href"));
if (!m.find())
continue;
Topic theme = new Topic(m.group(1), el.text());
el = tdElement.select("span.desc").first();
if (el != null)
theme.setDescription(el.text());
theme.setIsNew(tdElement.select("a[href*=view=getnewpost]").first() != null);
tdElement = trElement.child(3);
el = tdElement.select("a[href~=showforum=\\d+]").first();
if (el != null) {
m = forumIdPattern.matcher(el.attr("href"));
if (m.find())
theme.setForumId(m.group(1));
}
tdElement = trElement.child(7);
el = tdElement.select("span.desc]").first();
if (el != null) {
theme.setLastMessageDate(Functions.parseForumDateTime(el.ownText(), today, yesterday));
}
el = tdElement.select("span.desc>b>a[href~=showuser=\\D+]").first();
if (el != null) {
theme.setLastMessageAuthor(el.text());
}
}
Matcher m = themesPattern.matcher(pageBody);
int sortOrder = 1000 + start + 1;
while (m.find()) {
Topic theme = new Topic(m.group(1), m.group(2));
theme.setDescription(m.group(3) == null ? "" : m.group(3));
// theme.setLastMessageAuthorId(m.group(5));
theme.setLastMessageAuthor(m.group(6));
theme.setIsNew(m.group(4) != null);
theme.setLastMessageDate(Functions.parseForumDateTime(m.group(7), today, yesterday));
theme.setForumId(forumId);
theme.setSortOrder(Integer.toString(sortOrder++));
res.add(theme);
}
m = lastPageStartPattern.matcher(pageBody);
while (m.find()) {
listInfo.setOutCount(Math.max(Integer.parseInt(m.group(2)), listInfo.getFrom()));
}
}
if (unreadInTop) {
final int asc = -1;// новые вверху
Collections.sort(res, new Comparator<Topic>() {
@Override
public int compare(Topic topic, Topic topic2) {
if (topic.getState() == topic2.getState())
return 0;
return (topic.getState() == Topic.FLAG_NEW) ? asc : (-asc);
}
});
}
if (res.size() == 0) {
Matcher m = PatternExtensions.compile("<div class=\"errorwrap\">([\\s\\S]*?)</div>")
.matcher(pageBody);
if (m.find()) {
throw new NotReportException(Html.fromHtml(m.group(1)).toString(), new Exception(Html.fromHtml(m.group(1)).toString()));
}
}
return res;
}
}