/** * Подписка на ответы в топике * * @param forumId - id форума (можно получить из TopicApi.getForumId) * @param authKey - ключ, возвращаемый при логине в параметре K_KEY * @param topicId - id топика * @param emailtype - способ уведомления (смотри константы TopicApi.SUBSCRIBE_EMAIL_TYPE_) */ public static ResultInfo subscribe( IHttpClient client, CharSequence forumId, CharSequence authKey, CharSequence topicId, String emailtype) throws IOException { Map<String, String> additionalHeaders = new HashMap<String, String>(); additionalHeaders.put("act", "usercp"); additionalHeaders.put("CODE", "end_subs"); additionalHeaders.put("method", "topic"); additionalHeaders.put("auth_key", authKey.toString()); additionalHeaders.put("tid", topicId.toString()); additionalHeaders.put("fid", forumId.toString()); additionalHeaders.put("st", "0"); additionalHeaders.put("emailtype", emailtype); String res = client.performPost("http://4pda.ru/forum/index.php", additionalHeaders); Pattern p = Pattern.compile( "<div class=\"errorwrap\">\n" + "\\s*<h4>Причина:</h4>\n" + "\\s*\n" + "\\s*<p>(.*)</p>", Pattern.MULTILINE); Matcher m = p.matcher(res); if (m.find()) { return new ResultInfo(false, "Ошибка подписки: " + m.group(1)); } return new ResultInfo(true, ""); }
/** * Добавить топик в Избранное * * @param forumId - id форума (можно получить из TopicApi.getForumId) * @param topicId - id топика * @return * @throws IOException */ public static ResultInfo addToFavorites( IHttpClient httpClient, CharSequence forumId, CharSequence topicId) throws IOException { String res = httpClient.performGet( "http://4pda.ru/forum/index.php?autocom=favtopics&CODE=03&f=" + forumId + "&t=" + topicId + "&st=0"); Pattern pattern = Pattern.compile("\\s*<div class=\"tablepad\">\\s*(.*)\\s*<ul>", Pattern.MULTILINE); Matcher m = pattern.matcher(res); if (m.find()) { return new ResultInfo(true, m.group(1)); } else { pattern = Pattern.compile("\\s*<h4>Причина:</h4>\\s*<p>(.*?)</p>", Pattern.MULTILINE); m = pattern.matcher(res); if (m.find()) { return new ResultInfo(false, m.group(1)); } } return new ResultInfo(false, "Результат неизвестен. Сообщите разработчику"); }
/** * Возвращает сервисный id для топика из подписок * * @param httpClient * @param topicId * @return null - нет в подписках топика */ private static CharSequence getTopicSubscribedId(IHttpClient httpClient, CharSequence topicId) throws IOException { String body = httpClient.performGet("http://4pda.ru/forum/index.php?act=UserCP&CODE=26"); Pattern pattern = Pattern.compile( "(?:<td colspan=\"6\" class=\"row1\"><b>.*?</b></td>)?\n" + "\\s*</tr><tr>\n" + "\\s*<td class=\"row2\" align=\"center\" width=\"5%\">(?:<font color='.*?'>)?.*?(?:</font>)?</td>\n" + "\\s*<td class=\"row2\">\n" + "\\s*<a href=\"http://4pda.ru/forum/index.php\\?showtopic=" + topicId + "\">.*?</a> \n" + "\\s*\\(\\s*<a href=\"http://4pda.ru/forum/index.php\\?showtopic=" + topicId + "\" target=\"_blank\">В новом окне</a> \\)\n" + "\\s*<div class=\"desc\">(?:.*?<br />)?.*?\n" + "\\s*<br />\n" + "\\s*Тип: .*?\n" + "\\s*</div>\n" + "\\s*</td>\n" + "\\s*<td class=\"row2\" align=\"center\"><a href=\"javascript:who_posted\\(\\d+\\);\">\\d+</a></td>\n" + "\\s*<td class=\"row2\" align=\"center\">\\d+</td>\n" + "\\s*<td class=\"row2\">.*?<br />автор: <a href='http://4pda.ru/forum/index.php\\?showuser=\\d+'>.*?</a></td>\n" + "\\s*<td class=\"row1\" align=\"center\" style='padding: 1px;'><input class='checkbox' type=\"checkbox\" name=\"id-(\\d+)\" value=\"yes\" /></td>"); Matcher m = pattern.matcher(body); if (m.find()) return m.group(1); return null; }
/** * Получение топика * * @param client - клиент * @param topicUrl - ссылка на топик * @return * @throws IOException */ public static TopicResult getTopic(IHttpClient client, CharSequence topicUrl) throws IOException { TopicResult topicResult = new TopicResult(); String topicBody = client.performGet(normalizeTopicUrl(topicUrl).toString()); topicResult.parseUrl(client.getRedirectUrl()); Matcher mainMatcher = Pattern.compile( "([\\s\\S]*?)(<div class=\"pagination\">.[\\s\\S]*?<div class=\"pagination\">.*?</div>)") .matcher(topicBody); checkTopicResult(topicUrl, topicResult.getTopicId(), topicBody, mainMatcher); topicResult.parseHeader(mainMatcher.group(1)); topicBody = mainMatcher.group(2); topicResult.setBody(topicBody); return topicResult; }
/** * Удалить тему из избранного * * @param forumId - id форума (можно получить из TopicApi.getForumId) * @param topicId - id топика * @return * @throws IOException */ public static ResultInfo removeFromFavorites( IHttpClient httpClient, CharSequence forumId, CharSequence topicId) throws IOException { String query = "http://4pda.ru/forum/index.php?autocom=favtopics&CODE=02&selectedtids=" + topicId + "&cb=1&t=" + topicId + "&st=0"; if (!TextUtils.isEmpty(forumId)) query += "&f=" + forumId; httpClient.performGet(query); return new ResultInfo(true, null); }
/** * Отписка от темы * * @throws IOException */ public static ResultInfo unSubscribe(IHttpClient httpClient, CharSequence topicId) throws IOException { CharSequence subscribesId = getTopicSubscribedId(httpClient, topicId); if (subscribesId != null) { Map<String, String> additionalHeaders = new HashMap<String, String>(); additionalHeaders.put("act", "UserCP"); additionalHeaders.put("CODE", "27"); additionalHeaders.put("id-" + subscribesId, "yes"); additionalHeaders.put("trackchoice", "unsubscribe"); httpClient.performPost("http://4pda.ru/forum/index.php", additionalHeaders); return new ResultInfo(true, null); } return new ResultInfo(false, "Тема в подписках не найдена"); }
/** * Возвращает ID форума для топика * * @return null - в случае провала * @throws IOException */ public CharSequence getForumId(IHttpClient client, CharSequence topicId) throws IOException { String res = client.performGet("http://4pda.ru/forum/lofiversion/index.php?t" + topicId + ".html"); Pattern pattern = Pattern.compile( "<div class='ipbnav'>.*<a href='http://4pda.ru/forum/lofiversion/index.php\\?f(\\d+).html'>.*?</a></div>", Pattern.MULTILINE); Matcher m = pattern.matcher(res); if (m.find()) { return m.group(1); } else { return null; } }
public static ArrayList<News> getNews(IHttpClient httpClient, String url, ListInfo listInfo) throws IOException, ParseException { // http://4pda.ru/2013/page/7/ // http://4pda.ru/2013/2/page/7/ // http://4pda.ru/2013/2/2/page/7/ // http://4pda.ru/tag/programs-for-ios/page/3 // http://4pda.ru/page/5/ // http://4pda.ru/page/5/?s=ios - поиск // http://4pda.ru/?s=%EF%EB%E0%ED%F8%E5%F2 // http://4pda.ru/page/6/?s=%EF%EB%E0%ED%F8%E5%F2 final int NEWS_PER_PAGE = 30; // 30 новостей на страницу выводит форум int pageNum = 1; String justUrl = url; // урл без страницы и параметров String params = ""; // параметры, например, s=%EF%EB%E0%ED%F8%E5%F2 // сначала проверим на поисковой урл Matcher m = Pattern.compile("(.*?)(?:page/+(\\d+)/+)?\\?(.*?)$", Pattern.CASE_INSENSITIVE).matcher(url); if (m.find()) { justUrl = m.group(1); if (!TextUtils.isEmpty(m.group(2))) pageNum = Integer.parseInt(m.group(2)); if (!TextUtils.isEmpty(m.group(3))) params = m.group(3); } else { m = Pattern.compile("(.*?)(?:page/+(\\d+)/+)?$", Pattern.CASE_INSENSITIVE).matcher(url); if (m.find()) { justUrl = m.group(1); if (!TextUtils.isEmpty(m.group(2))) pageNum = Integer.parseInt(m.group(2)); } } pageNum = (int) Math.ceil(listInfo.getFrom() / NEWS_PER_PAGE) + pageNum; String requestUrl = justUrl + "/page/" + pageNum + "/" + params; String dailyNewsPage = httpClient.performGet(requestUrl); Matcher postsMatcher = Pattern.compile( "<div class=\"post\" id=\"post-\\d+\">([\\s\\S]*?)<span id=\"ka_\\d+_0_n\"></span></div><br /></div></div>") .matcher(dailyNewsPage); SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yy"); Pattern mPattern = Pattern.compile( "<a href=\"(/\\d+/\\d+/\\d+/(\\d+))/\" rel=\"bookmark\" title=\"(.*?)\" alt=\"\">.*?</a></h2>"); Pattern textPattern = Pattern.compile( "<div class=\"entry\" id=\"[^\"]*\">" + "(?:<a href=\"([^\"]*)\" class=\"oprj ([^\"]*)\"><div>(.*?)</div>)?" + "([\\s\\S]*?)" + "(?:<noindex><span class=\"mb_source\">Источник: <a href=\"([^\"]*)\" target=\"[^\"]*\">(.*?)</a></span></noindex>)?" + "<br /><br /></div><div class=\"postmetadata\" id=\"ka_meta_\\d+_0\"><span id=\"ka_\\d+_0\"></span> \\| " + "<strong>(.*?)</strong> \\|\\s*(\\d+\\.\\d+\\.\\d+)\\s*\\|\\s*" + "<a href=\"/\\d+/\\d+/\\d+/\\d+/#comments\" title=\"[^\"]*\"><b class=\"spr pc\"></b>\\s*(\\d+)\\s*</a>"); Pattern imagePattern = Pattern.compile("<center><img[^>]*?src=\"(.*?)\""); ArrayList<News> res = new ArrayList<News>(); while (postsMatcher.find()) { String postData = postsMatcher.group(1); m = mPattern.matcher(postData); if (m.find()) { String id = m.group(1); News news = new News(id, Html.fromHtml(m.group(3)).toString()); Matcher textMatcher = textPattern.matcher(postData); if (textMatcher.find()) { if (textMatcher.group(1) != null) { news.setTagLink(textMatcher.group(1)); news.setTagName(textMatcher.group(2)); news.setTagTitle(textMatcher.group(3)); } if (textMatcher.group(5) != null) { news.setSourceUrl(textMatcher.group(5)); news.setSourceTitle(textMatcher.group(6)); } news.setDescription(getDescription(textMatcher.group(4))); news.setAuthor(Html.fromHtml(textMatcher.group(7))); Date _pubDate = dateFormat.parse(textMatcher.group(8)); news.setNewsDate(DateTimeExternals.getDateString(_pubDate)); news.setCommentsCount(Integer.parseInt(textMatcher.group(9))); } Matcher imageMatcher = imagePattern.matcher(postData); if (imageMatcher.find()) { news.setImgUrl(imageMatcher.group(1)); } res.add(news); } } int lastPageNum = lastPageNum(dailyNewsPage); listInfo.setOutCount(res.size() * lastPageNum); return res; }