package org.softeg.slartus.forpdaplus;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManager;
import com.afollestad.materialdialogs.MaterialDialog;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.cookie.Cookie;
import org.softeg.slartus.forpdaapi.ForumsApi;
import org.softeg.slartus.forpdaapi.IHttpClient;
import org.softeg.slartus.forpdaapi.LoginResult;
import org.softeg.slartus.forpdaapi.NewsApi;
import org.softeg.slartus.forpdaapi.OnProgressChangedListener;
import org.softeg.slartus.forpdaapi.ProfileApi;
import org.softeg.slartus.forpdaapi.ProgressState;
import org.softeg.slartus.forpdaapi.ReputationsApi;
import org.softeg.slartus.forpdaapi.TopicApi;
import org.softeg.slartus.forpdaapi.TopicReadingUsers;
import org.softeg.slartus.forpdaapi.post.PostApi;
import org.softeg.slartus.forpdaapi.qms.QmsApi;
import org.softeg.slartus.forpdaapi.users.Users;
import org.softeg.slartus.forpdacommon.NotReportException;
import org.softeg.slartus.forpdacommon.Observer;
import org.softeg.slartus.forpdacommon.PatternExtensions;
import org.softeg.slartus.forpdacommon.SimpleCookie;
import org.softeg.slartus.forpdaplus.classes.DownloadTask;
import org.softeg.slartus.forpdaplus.classes.DownloadTasks;
import org.softeg.slartus.forpdaplus.classes.Forum;
import org.softeg.slartus.forpdaplus.classes.TopicBodyBuilder;
import org.softeg.slartus.forpdaplus.classes.common.Functions;
import org.softeg.slartus.forpdaplus.classes.forum.ExtTopic;
import org.softeg.slartus.forpdaplus.common.AppLog;
import org.softeg.slartus.forpdaplus.db.ForumsTableOld;
import org.softeg.slartus.forpdaplus.download.DownloadReceiver;
import org.softeg.slartus.forpdaplus.download.DownloadsService;
import org.softeg.slartus.forpdaplus.fragments.topic.ForPdaWebInterface;
import org.softeg.slartus.forpdaplus.utils.LogUtil;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by IntelliJ IDEA.
* User: Admin
* Date: 16.09.11
* Time: 18:40
* To change this template use File | Settings | File Templates.
*/
public class Client implements IHttpClient {
public static final String SITE = "4pda.ru";
public String UserId = "0";
private String m_User = App.getContext().getString(R.string.guest);
private String m_K = "";
private Client() {
}
public String getAuthKey() {
return m_K;
}
public static final Client INSTANCE = new Client();
public URI getRedirectUri() {
return HttpHelper.getRedirectUri();
}
public String getLastUrl() {
return HttpHelper.getLastUri();
}
public void deletePost(String forumId, String themeId, String postId, CharSequence authKey) throws IOException {
PostApi.delete(this, forumId, themeId, postId, authKey);
}
public String getEditPostPlus(String forumId, String themeId, String postId, String authKey,
Map<String, String> outParams) throws Throwable {
if (TextUtils.isEmpty(forumId) || TextUtils.isEmpty(authKey)) {
ExtTopic topic = new ExtTopic(themeId, "");
setThemeForumAndAuthKey(topic);
forumId = topic.getForumId();
authKey = topic.getAuthKey();
outParams.put("forumId", forumId);
outParams.put("authKey", authKey);
}
String res = PostApi.getEditPage(this, forumId, themeId, postId, authKey);
String error = PostApi.checkEditPage(res);
if (!TextUtils.isEmpty(error))
throw new NotReportException(error);
return res;
}
public String editPost(String forumId, String themeId, String authKey, String postId, Boolean enablesig,
Boolean enableEmo, String post, String addedFileList, String post_edit_reason) throws IOException {
return PostApi.applyEdit(this, forumId, themeId, authKey, postId, enablesig,
enableEmo, post, addedFileList, post_edit_reason);
}
public String attachFilePost(String forumId, String themeId, String authKey, String attachPostKey, String postId, Boolean enablesig, Boolean enableEmo,
String post, String filePath, String addedFileList, ProgressState progress
, String post_edit_reason) throws Exception {
return PostApi.attachFile(this, forumId, themeId, authKey, attachPostKey, postId, enablesig, enableEmo,
post, filePath, addedFileList, progress, post_edit_reason);
}
public String deleteAttachFilePost(String forumId, String themeId, String authKey, String postId,
Boolean enablesig, Boolean enableemo,
String post, String attachToDeleteId, String fileList
, String post_edit_reason) throws Exception {
return PostApi.deleteAttachedFile(this, forumId, themeId, authKey, postId,
enablesig, enableemo,
post, attachToDeleteId, fileList, post_edit_reason);
}
public Boolean changeReputation(String postId, String userId, String type, String message, Map<String, String> outParams) throws IOException {
return ReputationsApi.changeReputation(this, postId, userId, type, message, outParams);
}
public String claim(String themeId, String postId, String message) throws IOException {
String error = PostApi.claim(this, themeId, postId, message);
if (!TextUtils.isEmpty(error))
return error;
return App.getContext().getString(R.string.complaint_sent);
}
public Boolean hasLoginCookies() {
Boolean session = false;
Boolean pass_hash = false;
Boolean member = false;
HttpHelper httpHelper = null;
try {
try {
httpHelper = new HttpHelper();
} catch (IOException e) {
AppLog.e(null, e);
return false;
}
List<Cookie> cookies = httpHelper.getCookies();
for (Cookie cookie : cookies) {
if (!session && cookie.getName().equals("session_id"))
session = true;
else if (!pass_hash && cookie.getName().equals("pass_hash"))
pass_hash = true;
else if (!member && cookie.getName().equals("member_id"))
member = true;
}
} finally {
if (httpHelper != null)
httpHelper.close();
}
return session && pass_hash && member;
}
public String performGetWithCheckLogin(String url, OnProgressChangedListener beforeGetPage, OnProgressChangedListener afterGetPage) throws IOException {
if (beforeGetPage != null)
beforeGetPage.onProgressChanged(App.getContext().getString(R.string.receiving_data));
String body = performGet(url);
if (beforeGetPage != null)
afterGetPage.onProgressChanged(App.getContext().getString(R.string.receiving_data));
/*Matcher headerMatcher = PatternExtensions.compile("<body>([\\s\\S]*?)globalmess").matcher(body);
if (headerMatcher.find()) {
checkLogin(headerMatcher.group(1));
checkMails(headerMatcher.group(1));
} else {
checkLogin(body);
checkMails(body);
}*/
return body;
}
/**
* Загрузка тестовой страницы, проверка логина, проверка писем
*/
public void loadTestPage() throws IOException {
String body = performGet("http://4pda.ru/forum/index.php?showforum=200");
checkLogin(body);
checkMails(body);
}
public String performGetFullVersion(String s) throws IOException {
HttpHelper httpHelper = new HttpHelper(HttpHelper.FULL_USER_AGENT);
//HttpHelper httpHelper = new HttpHelper();
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = httpHelper.performGet(s);
} finally {
httpHelper.close();
}
if (TextUtils.isEmpty(res))
throw new NotReportException(App.getContext().getString(R.string.server_return_empty_page));
// m_HttpHelper.close();
return res;
}
public String performGet(String s) throws IOException {
return performGet(s, true, true);
}
public String performGet(String s, Boolean checkEmptyResult, Boolean checkLoginAndMails) throws IOException {
HttpHelper httpHelper = new HttpHelper();
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = httpHelper.performGet(s);
} finally {
httpHelper.close();
}
if (checkEmptyResult && TextUtils.isEmpty(res))
throw new NotReportException(App.getContext().getString(R.string.server_return_empty_page));
else if (checkLoginAndMails) {
checkLogin(res);
if (!s.contains("xhr"))
checkMails(res);
}
// m_HttpHelper.close();
return res;
}
public String performPost(String s, Map<String, String> additionalHeaders) throws IOException {
HttpHelper httpHelper = new HttpHelper();
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = httpHelper.performPost(s, additionalHeaders);
// m_HttpHelper.close();
} finally {
httpHelper.close();
}
return res;
}
public String uploadFile(String url, String filePath, Map<String, String> additionalHeaders
, ProgressState progress) throws Exception {
HttpHelper httpHelper = new HttpHelper();
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = httpHelper.uploadFile(url, filePath, additionalHeaders, progress);
// m_HttpHelper.close();
} finally {
httpHelper.close();
}
return res;
}
@Override
public CookieStore getCookieStore() throws IOException {
HttpHelper httpHelper = new HttpHelper();
try {
return httpHelper.getCookieStore();
} finally {
httpHelper.close();
}
}
public String performPost(String s, Map<String, String> additionalHeaders, String encoding) throws IOException {
HttpHelper httpHelper = new HttpHelper();
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = httpHelper.performPost(s, additionalHeaders, encoding);
// m_HttpHelper.close();
} finally {
httpHelper.close();
}
return res;
}
@Override
public String performPost(String s, List<NameValuePair> additionalHeaders) throws IOException {
HttpHelper httpHelper = new HttpHelper();
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = httpHelper.performPost(s, additionalHeaders);
// m_HttpHelper.close();
} finally {
httpHelper.close();
}
return res;
}
public List<Cookie> getCookies() throws IOException {
HttpHelper httpHelper = new HttpHelper();
try {
return httpHelper.getCookies();
} finally {
httpHelper.close();
}
}
public Users getTopicWritersUsers(String topicId) throws IOException {
return org.softeg.slartus.forpdaapi.TopicApi.getWriters(this, topicId);
}
public static Client getInstance() {
return INSTANCE; //To change body of created methods use File | Settings | File Templates.
}
public Boolean likeNews(String postId) throws IOException {
return NewsApi.like(this, postId);
}
public Boolean likeComment(final String id, final String comment) throws IOException {
return NewsApi.likeComment(this, id, comment);
}
public interface OnUserChangedListener {
void onUserChanged(String user, Boolean success);
}
public void doOnUserChangedListener(String user, Boolean success) {
for (OnUserChangedListener listener : m_OnUserChangeListeners.getListeners()) {
listener.onUserChanged(user, success);
}
}
private Observer<OnUserChangedListener> m_OnUserChangeListeners = new Observer<OnUserChangedListener>();
public void addOnUserChangedListener(OnUserChangedListener p) {
m_OnUserChangeListeners.addStrongListener(p);
}
public interface OnMailListener {
void onMail(int count);
}
public void doOnMailListener() {
for (OnMailListener listener : m_OnMailListeners.getListeners()) {
listener.onMail(0);
}
}
private Observer<OnMailListener> m_OnMailListeners = new Observer<OnMailListener>();
public void addOnMailListener(OnMailListener p) {
m_OnMailListeners.addStrongListener(p);
}
public interface OnProgressPositionChangedListener {
void onProgressChanged(Context context, DownloadTask downloadTask, Exception ex);
}
public void doOnOnProgressChanged(OnProgressChangedListener listener, String state) {
if (listener != null) {
listener.onProgressChanged(state);
}
}
public void showLoginForm(Context mContext, final OnUserChangedListener onUserChangedListener) {
try {
final LoginDialog loginDialog = new LoginDialog(mContext);
MaterialDialog dialog = new MaterialDialog.Builder(mContext)
.title(R.string.login)
.customView(loginDialog.getView(), true)
.positiveText(R.string.login)
.negativeText(R.string.cancel)
.callback(new MaterialDialog.ButtonCallback() {
@Override
public void onPositive(MaterialDialog dialog) {
loginDialog.connect(onUserChangedListener);
}
})
.build();
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
dialog.show();
} catch (Exception ex) {
AppLog.e(mContext, ex);
}
}
public String getUser() {
return m_User;
}
private Boolean m_Logined = false;
public Boolean getLogined() {
return m_Logined;
}
private String m_LoginFailedReason;
public String getLoginFailedReason() {
return m_LoginFailedReason;
}
public String reply(String forumId, String themeId, String authKey, String post,
Boolean enablesig, Boolean enableemo, Boolean quick, String addedFileList) throws IOException {
return reply(forumId, themeId, authKey, null, post,
enablesig, enableemo, quick, addedFileList);
}
public String reply(String forumId, String themeId, String authKey, String attachPostKey, String post,
Boolean enablesig, Boolean enableemo, Boolean quick, String addedFileList) throws IOException {
return PostApi.reply(this, forumId, themeId, authKey, attachPostKey, post,
enablesig, enableemo, addedFileList, quick);
}
public Boolean login(String login, String password, Boolean privacy,
String capVal, String capTime, String capSig, String session) throws Exception {
HttpHelper httpHelper = new HttpHelper();
try {
// httpHelper.clearCookies();
// httpHelper.writeExternalCookies();
final HttpHelper finalHttpHelper = httpHelper;
LoginResult loginResult = ProfileApi.login(new IHttpClient() {
public String performGetWithCheckLogin(String s, OnProgressChangedListener beforeGetPage, OnProgressChangedListener afterGetPage) throws IOException {
return null;
}
public String performGet(String s, Boolean b, Boolean bb) throws IOException {
return null;
}
public String performGet(String s) throws IOException {
return null;
}
@Override
public String performGetFullVersion(String s) throws IOException {
return null;
}
public String performPost(String s, Map<String, String> additionalHeaders) throws IOException {
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = finalHttpHelper.performPost(s, additionalHeaders);
checkLogin(res);
finalHttpHelper.writeExternalCookies();
} catch (Exception ignored) {
} finally {
finalHttpHelper.close();
}
return res;
}
public String performPost(String s, List<NameValuePair> additionalHeaders) throws IOException {
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = finalHttpHelper.performPost(s, additionalHeaders);
checkLogin(res);
finalHttpHelper.writeExternalCookies();
} catch (Exception ignored) {
} finally {
finalHttpHelper.close();
}
return res;
}
public String performPost(String s, Map<String, String> additionalHeaders, String encoding) throws IOException {
String res = null;
try {
// s="http://4pda.ru/2009/12/28/18506/#comment-363525";
res = finalHttpHelper.performPost(s, additionalHeaders, encoding);
checkLogin(res);
finalHttpHelper.writeExternalCookies();
} catch (Exception ignored) {
} finally {
finalHttpHelper.close();
}
return res;
}
@Override
public String uploadFile(String url, String filePath, Map<String, String> additionalHeaders, ProgressState progress) throws Exception {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public CookieStore getCookieStore() throws IOException {
try {
return finalHttpHelper.getCookieStore();
} finally {
finalHttpHelper.close();
}
}
}, login, password, privacy, capVal, capTime, capSig, session);
m_Logined = loginResult.isSuccess();
m_LoginFailedReason = m_Logined ? null : loginResult.getLoginError().toString();
// m_SessionId = outParams.get("SessionId");
m_User = loginResult.getUserLogin().toString();
m_K = loginResult.getK().toString();
httpHelper.getCookieStore().addCookie(new SimpleCookie("4pda.UserId", loginResult.getUserId().toString()));
httpHelper.getCookieStore().addCookie(new SimpleCookie("4pda.User", m_User));
httpHelper.getCookieStore().addCookie(new SimpleCookie("4pda.K", m_K));
httpHelper.writeExternalCookies();
} finally {
httpHelper.close();
}
return m_Logined;
}
private final Pattern checkLoginPattern = PatternExtensions.compile("<a href=\"(http://4pda.ru)?/forum/index.php\\?showuser=(\\d+)\">(.*?)</a></b> \\( <a href=\"(http://4pda.ru)?/forum/index.php\\?act=Login&CODE=03&k=([a-z0-9]{32})\">Выход</a>");
public void checkLoginByCookies() {
try {
HttpHelper httpHelper = null;
try {
httpHelper = new HttpHelper();
if (checkLogin(httpHelper.getCookieStore())) {
m_Logined = true;
}
} finally {
if (httpHelper != null)
httpHelper.finalize();
}
} catch (Throwable ignored) {
} finally {
doOnUserChangedListener(m_User, m_Logined);
}
}
public Boolean checkLogin(CookieStore cookies) {
if (cookies == null)
return false;
m_User = "";
m_K = "";
Cookie memberIdCookie = null;
for (Cookie cookie : cookies.getCookies()) {
if ("4pda.UserId".equals(cookie.getName())) {
UserId = cookie.getValue();
} else if ("4pda.User".equals(cookie.getName())) {
m_User = cookie.getValue();
} else if ("4pda.K".equals(cookie.getName())) {
m_K = cookie.getValue();
} else if ("member_id".equals(cookie.getName())) {
memberIdCookie = cookie;
}
}
return !TextUtils.isEmpty(m_User) && !TextUtils.isEmpty(UserId) && !TextUtils.isEmpty(m_K) && memberIdCookie != null && UserId.equals(memberIdCookie.getValue());
}
public void checkLogin(String pageBody) {
try {
HttpHelper httpHelper = null;
try {
httpHelper = new HttpHelper();
if (checkLogin(httpHelper.getCookieStore())) {
m_Logined = true;
return;
}
if (!TextUtils.isEmpty(m_User) && !TextUtils.isEmpty(UserId)
&& !TextUtils.isEmpty(m_K)) {
List<Cookie> cookies = httpHelper.getLastCookies();
for (Cookie cookie : cookies) {
if ("member_id".equals(cookie.getName())) {
if (UserId.equals(cookie.getValue())) {
m_Logined = true;
return;
}
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (httpHelper != null)
httpHelper.close();
}
Matcher m = checkLoginPattern.matcher(pageBody);
if (m.find()) {
UserId = m.group(2);
m_User = m.group(3);
m_K = m.group(5);
m_Logined = true;
} else {
m_Logined = false;
m_User = "гость";
m_K = "";
UserId = "";
}
} finally {
doOnUserChangedListener(m_User, m_Logined);
}
}
private int m_QmsCount = 0;
public int getQmsCount() {
return m_QmsCount;
}
public void setQmsCount(int count) {
m_QmsCount = count;
}
public void checkMails(String pageBody) {
m_QmsCount = QmsApi.getNewQmsCount(pageBody);
doOnMailListener();
}
public Boolean logout() throws Throwable {
String res = ProfileApi.logout(this, m_K);
HttpHelper httpHelper = new HttpHelper();
try {
httpHelper.clearCookies();
httpHelper.writeExternalCookies();
} finally {
httpHelper.close();
}
checkLogin(res);
if (m_Logined)
m_LoginFailedReason = App.getContext().getString(R.string.bad_logout);
return !m_Logined;
}
public Forum loadForums() throws Exception {
return ForumsTableOld.loadForumsTree();
}
public String loadPageAndCheckLogin(String url, OnProgressChangedListener progressChangedListener) throws IOException {
doOnOnProgressChanged(progressChangedListener, App.getContext().getString(R.string.receiving_data));
String body = performGet(url);
doOnOnProgressChanged(progressChangedListener, App.getContext().getString(R.string.processing_data));
/*Matcher headerMatcher = PatternExtensions.compile("<body>([\\s\\S]*?)globalmess").matcher(body);
if (headerMatcher.find()) {
checkLogin(headerMatcher.group(1));
checkMails(headerMatcher.group(1));
} else {
checkLogin(body);
checkMails(body);
}*/
return body;
}
//loadTopic
private final static Pattern pollFormPattern = Pattern.compile("<form[^>]*action=\"[^\"]*addpoll=1[^\"]*\"[^>]*>([\\s\\S]*?)</form>", Pattern.CASE_INSENSITIVE);
private final static Pattern pollTitlePattern = Pattern.compile("<b>(.*?)</b>");
private final static Pattern pollQuestionsPattern = Pattern.compile("strong>(.*?)</strong[\\s\\S]*?table[^>]*?>([\\s\\S]*?)</table>");
private final static Pattern pollVotedPattern = Pattern.compile("(<input[^>]*?>) <b>([^>]*)</b>");
private final static Pattern pollNotVotedPattern = Pattern.compile("<td[^>]*>([^<]*?)</td><td[^\\[]*\\[ <b>(.*?)</b>[^\\[]*\\[([^\\]]*)");
private final static Pattern pollBottomPattern = Pattern.compile("<td class=\"row1\" colspan=\"3\" align=\"center\"><b>([^<]*?)</b>[\\s\\S]*?class=\"formbuttonrow\">([\\s\\S]*?)</td");
private final static Pattern beforePostsPattern = PatternExtensions.compile("^([\\s\\S]*?)<div data-post");
//1 - id поста
//2 - дата
//3 - номер поста
//4 - ник
//5 - урл аватарки
//6 - куратор или нет, если нет, то null
//7 - группа
//8 - online|offline
//9 - id юзера
//10 - репа
//11 - + - репы, действия
//12 - класс тела
//13 - тело
//Да простит меня господь за это. Действие во благо не счетается грехом, ведь верно?
//А разве может быть иначе?
private final static Pattern postsPattern = Pattern.compile("<div data-post=\"(\\d+)\"[^>]*>[\\s\\S]*?post_date[^>]*?>(.*?) [^#]*#(\\d+)[\\s\\S]*?font color=\"([^\"]*?)\"[\\s\\S]*?data-av=\"([^\"]*)\"[^>]*?>([^>]*?)<[\\s\\S]*?<a href=\"[^\"]*?showuser=(\\d+)\"[\\s\\S]*?<span[^>]*?post_user_info[^>]*?>(<strong[\\s\\S]*?<\\/strong>(?:<br[^>]*?>))?(?:<span[^<]*?color:[^;']*[^>]*?>)?([\\s\\S]*?)(?:<\\/span>|)(?: \\| [^<]*?)?<\\/span>([\\s\\S]*?<span[^>]*?ajaxrep[^>]*?>([^<]*?)<\\/span>[\\s\\S]*?)<div class=\"post_body([^\"]*?)\"[^>]*?>([\\s\\S]*?)<\\/div><\\/div>(?=<div data-post=\"\\d+\"[^>]*>|<!-- TABLE FOOTER -->|<div class=\"topic_foot_nav\">)",
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
String np = "<div data-post=\"(\\d+)\"[^>]*>[\\s\\S]*?post_date[^>]*?>(.*?) [^#]*#(\\d+)[\\s\\S]*?font color=\"([^\"]*?)\"[\\s\\S]*?\\[B\\](.*?),\\[\\/B\\]\\s*'\\)\"\\s*data-av=\"([^\"]*)\">[\\s\\S]*?<a href=\"[^\"]*?showuser=(\\d+)\"[\\s\\S]*?<span class=\"post_user_info[^\"]*\"[^>]*>(<strong[\\s\\S]*?<\\/strong><br[^>]*>)?(<span[^>]*?>[^<]*?<\\/span>)[\\s\\S]*?<br[^>]*?>([\\s\\S]*?<span[^>]*?ajaxrep[^>]*?>(\\d+)<\\/span>[\\s\\S]*?)<div class=\"post_body([^\"]*?)\"[^>]*?>([\\s\\S]*?)<\\/div><\\/div>(?=<div data-post=\"\\d+\"[^>]*>|<!-- TABLE FOOTER -->)";
private final static Pattern editPattern = PatternExtensions.compile("do=edit_post[^\"]*\"");
private final static Pattern deletePattern = PatternExtensions.compile("onclick=\"[^\"]*seMODdel");
//createTopic
private final static Pattern navStripPattern = PatternExtensions.compile("<div id=\"navstrip\">(.*?)</div>");
private final static Pattern userPattern =
PatternExtensions.compile("act=login&CODE=03&k=([a-z0-9]{32})");
private final static Pattern titlePattern = PatternExtensions.compile("<title>(.*?) - 4PDA</title>");
private final static Pattern descriptionPattern = PatternExtensions.compile("<div class=\"topic_title_post\">([^<]*)<");
private final static Pattern moderatorTitlePattern = PatternExtensions.compile("onclick=\"return setpidchecks\\(this.checked\\);\".*?> (.*?)<");
private final static Pattern pagesCountPattern = PatternExtensions.compile("var pages = parseInt\\((\\d+)\\);");
private final static Pattern lastPageStartPattern = PatternExtensions.compile("<a href=\"([^\"]*?4pda.ru)?\\/forum\\/index.php\\?showtopic=\\d+&st=(\\d+)\"");
private final static Pattern currentPagePattern = PatternExtensions.compile("<span class=\"pagecurrent\">(\\d+)</span>");
public TopicBodyBuilder parseTopic(String topicPageBody,
Context context, String themeUrl, Boolean spoilFirstPost) throws IOException {
Log.d("kek", "redirected final theme url = " + themeUrl);
checkLogin(topicPageBody);
Pattern pattern = PatternExtensions.compile("showtopic=(\\d+)(&(.*))?");
Matcher m = pattern.matcher(themeUrl);
String topicId = null;
String urlParams = null;
if (m.find()) {
topicId = m.group(1);
urlParams = m.group(3);
}
return loadTopic(context, topicId, topicPageBody, spoilFirstPost, m_Logined,
urlParams);
}
public static ExtTopic createTopic(String id, String page) {
String title = "";
Matcher m = titlePattern.matcher(page);
if (m.find()) {
title = m.group(1);
}
ExtTopic topic = new ExtTopic(id, title);
m = descriptionPattern.matcher(page);
if (m.find()) {
topic.setDescription(m.group(1).replace(title + ", ", ""));
} else {
m = moderatorTitlePattern.matcher(page);
if (m.find())
topic.setDescription(m.group(1).replace(title + ", ", ""));
}
m = navStripPattern.matcher(page);
if (m.find()) {
final Pattern forumPatter = PatternExtensions.compile("<a href=\"([^\"]*?4pda.ru)?\\/forum\\/index.php\\?.*?showforum=(\\d+).*?\">(.*?)<\\/a>");
Matcher forumMatcher = forumPatter.matcher(m.group(1));
while (forumMatcher.find()) {
if (forumMatcher.group(2).equals("10"))
topic.setPostVote(false);
topic.setForumId(forumMatcher.group(2));
topic.setForumTitle(forumMatcher.group(3));
}
}
if (Client.getInstance().getAuthKey() != null && !Client.getInstance().getAuthKey().isEmpty())
topic.setAuthKey(Client.getInstance().getAuthKey());
m = pagesCountPattern.matcher(page);
if (m.find()) {
topic.setPagesCount(m.group(1));
}
m = lastPageStartPattern.matcher(page);
while (m.find()) {
topic.setLastPageStartCount(m.group(2));
}
m = currentPagePattern.matcher(page);
if (m.find()) {
topic.setCurrentPage(m.group(1));
} else
topic.setCurrentPage("1");
return topic;
}
private TopicBodyBuilder loadTopic(Context context,
String id, String topicBody, Boolean spoilFirstPost,
Boolean logined, String urlParams) throws IOException {
Matcher mainMatcher = beforePostsPattern.matcher(topicBody);
if (!mainMatcher.find()) {
Matcher errorMatcher = Pattern.compile("<div class=\"wr va-m text\">([\\s\\S]*?)</div>", Pattern.CASE_INSENSITIVE)
.matcher(topicBody);
if (errorMatcher.find()) {
throw new NotReportException(errorMatcher.group(1));
}
Pattern errorPattern = PatternExtensions.compile("<div class=\"errorwrap\">([\\s\\S]*?)</div>");
errorMatcher = errorPattern.matcher(topicBody);
if (errorMatcher.find()) {
final Pattern errorReasonPattern = PatternExtensions.compile("<p>(.*?)</p>");
Matcher errorReasonMatcher = errorReasonPattern.matcher(errorMatcher.group(1));
if (errorReasonMatcher.find()) {
throw new NotReportException(errorReasonMatcher.group(1));
}
}
if (TextUtils.isEmpty(topicBody))
throw new NotReportException(context.getString(R.string.server_return_empty_page));
if (topicBody.startsWith("<h1>"))
throw new NotReportException(context.getString(R.string.site_response) + Html.fromHtml(topicBody).toString());
throw new IOException(context.getString(R.string.error_parsing_page) + " id=" + id);
}
Boolean isWebviewAllowJavascriptInterface = Functions.isWebviewAllowJavascriptInterface(context);
ExtTopic topic = createTopic(id, mainMatcher.group(1));
topicBody = topicBody.replace("^[\\s\\S]*?<div data-post", "<div data-post").replace("<div class=\"topic_foot_nav\">[\\s\\S]*", "<div class=\"topic_foot_nav\">");
TopicBodyBuilder topicBodyBuilder = new TopicBodyBuilder(context, logined, topic, urlParams,
isWebviewAllowJavascriptInterface);
//Boolean browserStyle = prefs.getBoolean("theme.BrowserStylePreRemove", false);
topicBodyBuilder.beginTopic();
//>>ОПРОС
Matcher pollMatcher = pollFormPattern.matcher(mainMatcher.group(1));
if (pollMatcher.find()) {
String pollSource = pollMatcher.group(1);
StringBuilder pollBuilder = new StringBuilder();
String percent;
Matcher temp;
pollBuilder.append("<form action=\"modules.php\" method=\"get\">");
pollMatcher = pollTitlePattern.matcher(pollSource);
if (pollMatcher.find()) {
if (!pollMatcher.group(1).equals("-"))
pollBuilder.append("<div class=\"poll_title\"><span>").append(pollMatcher.group(1)).append("</span></div>");
}
pollBuilder.append("<div class=\"poll_body\">");
boolean voted = false;
pollMatcher = pollQuestionsPattern.matcher(pollSource);
while (pollMatcher.find()) {
if (!pollMatcher.group(2).contains("input"))
voted = true;
pollBuilder.append("<div class=\"poll_theme\">");
pollBuilder.append("<div class=\"theme_title\"><span>").append(pollMatcher.group(1)).append("</span></div>");
pollBuilder.append("<div class=\"items").append(voted ? " voted" : "").append("\">");
if (voted) {
temp = pollNotVotedPattern.matcher(pollMatcher.group(2));
while (temp.find()) {
pollBuilder.append("<div class=\"item\">");
pollBuilder.append("<span class=\"name\"><span>").append(temp.group(1)).append("</span></span>");
pollBuilder.append("<span class=\"num_votes\"><span>").append(temp.group(2)).append("</span></span>");
pollBuilder.append("<div class=\"range\">");
percent = temp.group(3).replace(",", ".");
pollBuilder.append("<div class=\"range_bar\" style=\"width:").append(percent).append(";\"></div>");
pollBuilder.append("<span class=\"value\"><span>").append(percent).append("</span></span>");
pollBuilder.append("</div>");
pollBuilder.append("</div>");
}
} else {
temp = pollVotedPattern.matcher(pollMatcher.group(2));
while (temp.find()) {
pollBuilder.append("<label class=\"item\">");
pollBuilder.append(temp.group(1));
pollBuilder.append("<span class=\"icon\"></span>");
pollBuilder.append("<span class=\"item_body\"><span class=\"name\">").append(temp.group(2)).append("</span></span>");
pollBuilder.append("</label>");
}
}
pollBuilder.append("</div>");
pollBuilder.append("</div>");
}
pollBuilder.append("</div>");
pollMatcher = pollBottomPattern.matcher(pollSource);
if (pollMatcher.find()) {
pollBuilder.append("<div class=\"votes_info\"><span>").append(pollMatcher.group(1)).append("</span></div>");
if (logined) {
pollBuilder.append("<div class=\"buttons\">").append(pollMatcher.group(2)).append("</div>");
}
}
pollBuilder.append("<input type=\"hidden\" name=\"addpoll\" value=\"1\" /></form>");
topicBodyBuilder.addPoll(
pollBuilder.toString()
.replace("go_gadget_show()", ForPdaWebInterface.NAME + ".go_gadget_show()")
.replace("go_gadget_vote()", ForPdaWebInterface.NAME + ".go_gadget_vote()"),
urlParams != null && urlParams.contains("poll_open=true"));
}
//<<опрос
topicBodyBuilder.openPostsList();
mainMatcher = postsPattern.matcher(topicBody);
//String today = Functions.getToday();
//String yesterday = Functions.getYesterToday();
org.softeg.slartus.forpdaplus.classes.Post post = null;
Boolean spoil = spoilFirstPost;
String str;
Matcher m;
while (mainMatcher.find()) {
post = new org.softeg.slartus.forpdaplus.classes.Post(mainMatcher.group(1), mainMatcher.group(2), mainMatcher.group(3));
post.setUserState(mainMatcher.group(4));
post.setAvatarFileName(mainMatcher.group(5));
post.setAuthor(mainMatcher.group(6));
post.setUserId(mainMatcher.group(7));
if (mainMatcher.group(8) != null) {
post.setCurator();
}
post.setUserGroup(mainMatcher.group(9));
str = mainMatcher.group(10);
if (str.contains("win_minus")) {
post.setCanMinusRep(true);
}
if (str.contains("win_add")) {
post.setCanPlusRep(true);
}
m = editPattern.matcher(str);
if (m.find()) {
post.setCanEdit(true);
}
m = deletePattern.matcher(str);
if (m.find()) {
post.setCanDelete(true);
// если автор поста не совпадает с текущим пользователем и есть возможность удалить-значит, модератор
if (post.getUserId() != null && !post.getUserId().equals(Client.getInstance().UserId)) {
topicBodyBuilder.setMMod(true);
}
}
post.setUserReputation(mainMatcher.group(11));
post.setBody("<div class=\"post_body " + mainMatcher.group(12) + "\">" + mainMatcher.group(13) + "</div>");
topicBodyBuilder.addPost(post, spoil);
spoil = false;
}
topicBodyBuilder.endTopic();
return topicBodyBuilder;
}
public TopicReadingUsers getTopicReadingUsers(String topicId) throws IOException {
return TopicApi.getReadingUsers(this, topicId);
}
public void markAllForumAsRead() throws Throwable {
ForumsApi.markAllAsRead(this);
}
public String getThemeForumId(CharSequence themeId) throws IOException {
String res = performGet("http://4pda.ru/forum/lofiversion/index.php?t" + themeId + ".html");
return parseForumId(res);
}
private String parseForumId(String pageBody) {
Pattern pattern = Pattern.compile("<div class='ipbnav'>.*<a href='http://4pda.ru/forum/lofiversion/index.php\\?f(\\d+).html'>.*?</a></div>",
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(pageBody);
if (m.find()) {
return m.group(1);
} else {
return null;
}
}
private void setThemeForumAndAuthKey(ExtTopic topic) throws IOException {
String res = performGet("http://4pda.ru/forum/lofiversion/index.php?t" + topic.getId() + ".html");
if (TextUtils.isEmpty(topic.getForumId())) {
String forumId = parseForumId(res);
if (forumId != null) {
topic.setForumId(forumId);
LogUtil.E("BOOM DOOM", "forum id " + forumId);
}
}
if (TextUtils.isEmpty(topic.getAuthKey())) {
Pattern pattern = Pattern.compile("name=\"auth_key\" value=\"(.*)\"",
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);
Matcher m = pattern.matcher(res);
if (m.find()) {
topic.setAuthKey(m.group(1));
LogUtil.E("BOOM DOOM", "key " + m.group(1));
}
}
}
public DownloadTask downloadFile(Context context, String url, int notificationId, String tempFilePath) {
DownloadTask downloadTask = m_DownloadTasks.add(url, notificationId, null);
Intent intent = new Intent(context, DownloadsService.class);
intent.putExtra(DownloadsService.DOWNLOAD_FILE_ID_KEY, notificationId);
intent.putExtra(DownloadsService.DOWNLOAD_FILE_TEMP_NAME_KEY, tempFilePath);
intent.putExtra("receiver", new DownloadReceiver(new Handler(), context));
context.startService(intent);
return downloadTask;
}
private DownloadTasks m_DownloadTasks = new DownloadTasks();
public DownloadTasks getDownloadTasks() {
return m_DownloadTasks;
}
}