package org.softeg.slartus.forpdaapi.appsgamescatalog;/*
* Created by slinkin on 17.03.14.
*/
import android.net.Uri;
import android.text.Html;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.softeg.slartus.forpdaapi.IHttpClient;
import org.softeg.slartus.forpdaapi.Topic;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AppsGamesCatalogApi {
private static final String APPS_PAGE_ID = "112220";
private static final String GAMES_PAGE_ID = "117270";
private static final String APPS_CATALOG_URL = "http://4pda.ru/forum/index.php?showtopic=" + APPS_PAGE_ID;
private static final String GAMES_CATALOG_URL = "http://4pda.ru/forum/index.php?showtopic=" + GAMES_PAGE_ID;
public static ArrayList<AppGameCatalog> getCatalog(IHttpClient client, AppGameCatalog parent) throws IOException {
ArrayList<AppGameCatalog> res = new ArrayList<>();
AppGameCatalog appCatalog = new AppGameCatalog(APPS_PAGE_ID, "Программы")
.setLevel(AppGameCatalog.LEVEL_TYPE);
appCatalog.setParent(parent);
Apps.loadCatalog(client, appCatalog, res);
res.add(appCatalog);
AppGameCatalog gameCatalog = new AppGameCatalog(GAMES_PAGE_ID, "Игры")
.setLevel(AppGameCatalog.LEVEL_TYPE);
Games.loadCatalog(client, gameCatalog, res);
gameCatalog.setParent(parent);
res.add(gameCatalog);
return res;
}
public static ArrayList<Topic> loadTopics(IHttpClient client, AppGameCatalog catalog) throws IOException {
ArrayList<Topic> res = catalog.getType() == AppGameCatalog.TYPE_APPLICATIONS ?
Apps.loadTopics(client, catalog) : Games.loadTopics(client, catalog);
sort(res);
return res;
}
private static void sort(ArrayList<Topic> apps) {
Collections.sort(apps, new Comparator<Topic>() {
public int compare(Topic topic, Topic topic1) {
return topic.getTitle().toUpperCase().compareTo(topic1.getTitle().toUpperCase());
}
});
}
public static class Apps {
private static void loadCatalog(IHttpClient client, AppGameCatalog catalog, ArrayList<AppGameCatalog> res) throws IOException {
String pageBody = client.performGet(APPS_CATALOG_URL);
Matcher contentMatcher = Pattern.compile("<div class=\"[^\"]*post_body[^\"]*\"[^>]*?>([\\s\\S]*?)<a name=\"entry\\d+\"></a>",
Pattern.CASE_INSENSITIVE).matcher(pageBody);
if (!contentMatcher.find()) {
throw new IOException("Не найден пост с содержанием каталога приложений");
}
Document doc = Jsoup.parse(contentMatcher.group(1));
for (Element categoryElement : doc.select("ol[type=1]>li")) {
Elements elements = categoryElement.select("a");
if (elements.size() == 0) continue;
Element element = elements.get(0);
Uri uri = Uri.parse(element.attr("href"));
String title = element.text();
AppGameCatalog category = new AppGameCatalog(uri.getQueryParameter("p"), title)
.setLevel(AppGameCatalog.LEVEL_CATEGORY);
category.setParent(catalog);
res.add(category);
AppGameCatalog subCategory = new AppGameCatalog(category.getId().toString(), category.getTitle() + " @ темы")
.setLevel(AppGameCatalog.LEVEL_CATEGORY);
subCategory.setParent(category);
res.add(subCategory);
for (Element subCategoryElement : categoryElement.select("ul>li>a")) {
uri = Uri.parse(subCategoryElement.attr("href"));
title = subCategoryElement.text();
AppGameCatalog subcategory = new AppGameCatalog(uri.getQueryParameter("anchor"), title)
.setLevel(AppGameCatalog.LEVEL_SUBCATEGORY);
subcategory.setParent(category);
res.add(subcategory);
}
}
}
public static ArrayList<Topic> loadTopics(IHttpClient client, AppGameCatalog catalog) throws IOException {
if (catalog.getLevel() == AppGameCatalog.LEVEL_CATEGORY || (catalog.getParent().getId().equals(catalog.getId()))) {
return loadCategoryThemes(client, catalog.getId().toString());
} else if (catalog.getLevel() == AppGameCatalog.LEVEL_SUBCATEGORY) {
return loadSubCategoryThemes(client, catalog.getParent().getId(), catalog.getId());
}
return new ArrayList<>();
}
public static ArrayList<Topic> loadCategoryThemes(IHttpClient client, String catalogId) throws IOException {
String pageBody = client.performGet(APPS_CATALOG_URL);
ArrayList<Topic> res = new ArrayList<>();
Pattern pattern = Pattern.compile("<a name=\"entry" + catalogId + "\">([\\s\\S]*?)</div>(?:<!--Begin Msg Number|<!-- TABLE FOOTER)", Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(pageBody);
if (!m.find()) return res;
Document doc = Jsoup.parse(m.group(1));
Elements subCategoryElements = doc.select("ol[type=1]");
for (Element subCategoryElement : subCategoryElements) {
String subCategoryTitle = "";
Elements elements = subCategoryElement.select("span");
if (elements.size() > 0) {
subCategoryTitle = elements.first().text();
}
Elements topicElements = subCategoryElement.select("li");
for (Element topicElement : topicElements) {
elements = topicElement.select("a");
if (elements.size() == 0) continue;
Element element = elements.get(0);
Uri uri = Uri.parse(element.attr("href"));
Topic topic = new Topic(uri.getQueryParameter("showtopic"), element.text());
m = Pattern.compile("</a>(?:\\s*</b>\\s*-\\s*)(.*)?(?:<br\\s*/>|$)", Pattern.CASE_INSENSITIVE).matcher(topicElement.html());
if (m.find())
topic.setDescription(m.group(1));
topic.setForumTitle(subCategoryTitle);
res.add(topic);
}
}
return res;
}
private static ArrayList<Topic> loadSubCategoryThemes(IHttpClient client, CharSequence categoryId, CharSequence subCategoryId) throws IOException {
String pageBody = client.performGet(APPS_CATALOG_URL);
ArrayList<Topic> res = new ArrayList<>();
Pattern pattern = Pattern.compile("<a name=\"entry" + categoryId + "\">([\\s\\S]*?)</div>(?:<!--Begin Msg Number|<!-- TABLE FOOTER)", Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(pageBody);
if (!m.find()) return res;
Document doc = Jsoup.parse(m.group(1));
Elements subCategoryElements = doc.select("ol[type=1]");
for (Element subCategoryElement : subCategoryElements) {
Elements elements = subCategoryElement.select(String.format("a[name=%s]", subCategoryId));
if (elements.size() == 0) continue;
String subCategoryTitle = "";
elements = subCategoryElement.select("span");
if (elements.size() > 0) {
subCategoryTitle = elements.first().text();
}
Elements topicElements = subCategoryElement.select("li");
for (Element topicElement : topicElements) {
elements = topicElement.select("a");
if (elements.size() == 0) continue;
Element element = elements.get(0);
Uri uri = Uri.parse(element.attr("href"));
Topic topic = new Topic(uri.getQueryParameter("showtopic"), element.text());
m = Pattern.compile("</a>(?:\\s*</b>\\s*-\\s*)(.*)?(?:<br\\s*/>|$)", Pattern.CASE_INSENSITIVE).matcher(topicElement.html());
if (m.find())
topic.setDescription(m.group(1));
topic.setForumTitle(subCategoryTitle);
res.add(topic);
}
break;
}
return res;
}
}
public static class Games {
private static void loadCatalog(IHttpClient client, AppGameCatalog catalog, ArrayList<AppGameCatalog> res) throws IOException {
String pageBody = client.performGet(GAMES_CATALOG_URL);
Pattern pattern = Pattern.compile("<div class=\"[^\"]*post_body[^\"]*\">(.*?)(?:<!--Begin Msg Number|<!-- TABLE FOOTER)",
Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(pageBody);
if (!m.find()) return;
Document doc = Jsoup.parse(m.group(1));
for (Element categoryElement : doc.select("ol[type=1]>li")) {
Elements elements = categoryElement.select("a");
if (elements.size() == 0) continue;
Element element = elements.get(0);
Uri uri = Uri.parse(element.attr("href"));
String title = element.text();
AppGameCatalog category = new AppGameCatalog(uri.getQueryParameter("p"), title)
.setLevel(AppGameCatalog.LEVEL_CATEGORY).setGames();
category.setParent(catalog);
res.add(category);
}
}
public static ArrayList<Topic> loadTopics(IHttpClient client, AppGameCatalog catalog) throws IOException {
if (catalog.getLevel() == AppGameCatalog.LEVEL_CATEGORY || (catalog.getParent().getId().equals(catalog.getId()))) {
return loadCategoryThemes(client, catalog.getId().toString());
} else if (catalog.getLevel() == AppGameCatalog.LEVEL_SUBCATEGORY) {
return loadSubCategoryThemes(client, catalog.getParent().getId().toString(), catalog);
}
return new ArrayList<>();
}
public static ArrayList<Topic> loadCategoryThemes(IHttpClient client, String catalogId) throws IOException {
String pageBody = client.performGet(GAMES_CATALOG_URL);
ArrayList<Topic> res = new ArrayList<>();
Pattern pattern = Pattern.compile("<a name=\"entry" + catalogId + "\">([\\s\\S]*?)</div>(?:<!--Begin Msg Number|<!-- TABLE FOOTER)", Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(pageBody);
if (!m.find())
return res;
Document doc = Jsoup.parse(m.group(1));
Elements subCategoryElements = doc.select("ol[type=1]>li");
for (Element topicElement : subCategoryElements) {
Elements elements = topicElement.select("a");
if (elements.size() == 0) continue;
Element element = elements.get(0);
Uri uri = Uri.parse(element.attr("href"));
Topic topic = new Topic(uri.getQueryParameter("showtopic"), element.text());
m = Pattern.compile("</a>(?:\\s*</b>\\s*-\\s*)(.*)?(?:<br\\s*/>|$)", Pattern.CASE_INSENSITIVE).matcher(topicElement.html());
if (m.find())
topic.setDescription(m.group(1));
res.add(topic);
}
return res;
}
private static ArrayList<Topic> loadSubCategoryThemes(IHttpClient client, String catalogId, AppGameCatalog subCategory) throws IOException {
String pageBody = client.performGet(GAMES_CATALOG_URL);
ArrayList<Topic> res = new ArrayList<>();
Pattern pattern = Pattern.compile("<div class=\"post_body(?:\\s|\\w)*?\">(<div align=.center.>)?(?:<!--coloro:coral-->)?<span style=.color:coral.>(?:<!--/coloro-->)?<b>(<div align=.center.>)?" + catalogId + "\\..*?</div>(.*?)</div>");
Matcher m = pattern.matcher(pageBody);
Pattern subCategoryPattern = Pattern.compile("(?<!<div align='center'>)<span style=\"color:coral\"><b>" + Pattern.quote(subCategory.getHtmlTitle()) + "<(.*?)(?:<ol type=.1.>|</div>)");
Pattern themesPattern = Pattern.compile("<li><b><a href=\"http://4pda.ru/forum/index.php\\?showtopic=(\\d+)[^\"]*\" target=\"_blank\">(.*?)</a>(.*?)</li>");
if (m.find()) {
Matcher m1 = subCategoryPattern.matcher(m.group(3) + "</div>");
if (m1.find()) {
Matcher m2 = themesPattern.matcher(m1.group(1));
while (m2.find()) {
Topic topic = new Topic(m2.group(1), m2.group(2));
topic.setDescription(Html.fromHtml(m2.group(3)).toString());
topic.setForumTitle(subCategory.getTitle().toString());
res.add(topic);
}
}
}
return res;
}
}
}