From ed0fa35b923b7eef6fa8d2b9b3239b34f1ffcb73 Mon Sep 17 00:00:00 2001 From: Floens Date: Wed, 27 May 2015 17:42:01 +0200 Subject: [PATCH] Better support for exif tables on /p/ Also move parsers to chan package --- .../{core/loader => chan}/ChanLoader.java | 2 +- .../{core/loader => chan}/ChanParser.java | 61 ++++++++++++++++--- .../java/org/floens/chan/core/model/Post.java | 2 +- .../chan/core/{loader => net}/LoaderPool.java | 3 +- .../chan/core/presenter/ThreadPresenter.java | 4 +- .../floens/chan/core/watch/PinWatcher.java | 4 +- .../org/floens/chan/test/TestActivity.java | 2 +- 7 files changed, 63 insertions(+), 15 deletions(-) rename Clover/app/src/main/java/org/floens/chan/{core/loader => chan}/ChanLoader.java (99%) rename Clover/app/src/main/java/org/floens/chan/{core/loader => chan}/ChanParser.java (87%) rename Clover/app/src/main/java/org/floens/chan/core/{loader => net}/LoaderPool.java (96%) diff --git a/Clover/app/src/main/java/org/floens/chan/core/loader/ChanLoader.java b/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java similarity index 99% rename from Clover/app/src/main/java/org/floens/chan/core/loader/ChanLoader.java rename to Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java index 99f342b7..5bb70a13 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/loader/ChanLoader.java +++ b/Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.floens.chan.core.loader; +package org.floens.chan.chan; import android.text.TextUtils; diff --git a/Clover/app/src/main/java/org/floens/chan/core/loader/ChanParser.java b/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java similarity index 87% rename from Clover/app/src/main/java/org/floens/chan/core/loader/ChanParser.java rename to Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java index d62627d0..8a4e5f67 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/loader/ChanParser.java +++ b/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.floens.chan.core.loader; +package org.floens.chan.chan; import android.content.Context; @@ -29,6 +29,7 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.TypefaceSpan; +import android.text.style.UnderlineSpan; import org.floens.chan.Chan; import org.floens.chan.R; @@ -36,6 +37,7 @@ import org.floens.chan.core.model.Post; import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.utils.AndroidUtils; +import org.floens.chan.utils.Logger; import org.floens.chan.utils.ThemeHelper; import org.jsoup.Jsoup; import org.jsoup.helper.StringUtil; @@ -44,9 +46,11 @@ import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import org.jsoup.nodes.TextNode; import org.jsoup.parser.Parser; +import org.jsoup.select.Elements; import org.jsoup.select.NodeTraversor; import org.jsoup.select.NodeVisitor; +import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.regex.Matcher; @@ -55,6 +59,7 @@ import java.util.regex.Pattern; import static org.floens.chan.utils.AndroidUtils.sp; public class ChanParser { + private static final String TAG = "ChanParser"; private static final Pattern colorPattern = Pattern.compile("color:#([0-9a-fA-F]*)"); private static ChanParser instance = new ChanParser(); @@ -192,15 +197,18 @@ public class ChanParser { Document document = Jsoup.parseBodyFragment(comment); List nodes = document.body().childNodes(); + List texts = new ArrayList<>(nodes.size()); for (Node node : nodes) { CharSequence nodeParsed = parseNode(post, node); if (nodeParsed != null) { - total = TextUtils.concat(total, nodeParsed); + texts.add(nodeParsed); } } + + total = TextUtils.concat(texts.toArray(new CharSequence[texts.size()])); } catch (Exception e) { - e.printStackTrace(); + Logger.e(TAG, "Error parsing comment html", e); } return total; @@ -222,7 +230,7 @@ public class ChanParser { case "span": { Element span = (Element) node; - SpannableString quote = null; + SpannableString quote; Set classes = span.classNames(); if (classes.contains("deadlink")) { @@ -247,7 +255,7 @@ public class ChanParser { if (!TextUtils.isEmpty(group)) { try { hexColor = Integer.parseInt(group, 16); - } catch (NumberFormatException e) { + } catch (NumberFormatException ignored) { } } } @@ -257,6 +265,8 @@ public class ChanParser { quote.setSpan(new StyleSpan(Typeface.BOLD), 0, quote.length(), 0); } } + } else if (classes.contains("abbr")) { + return null; } else { quote = new SpannableString(span.text()); quote.setSpan(new ForegroundColorSpan(ThemeHelper.getInstance().getInlineQuoteColor()), 0, quote.length(), 0); @@ -265,6 +275,43 @@ public class ChanParser { return quote; } + case "table": { + Element table = (Element) node; + + List parts = new ArrayList<>(); + Elements tableRows = table.getElementsByTag("tr"); + for (int i = 0; i < tableRows.size(); i++) { + Element tableRow = tableRows.get(i); + if (tableRow.text().length() > 0) { + Elements tableDatas = tableRow.getElementsByTag("td"); + for (int j = 0; j < tableDatas.size(); j++) { + Element tableData = tableDatas.get(j); + + SpannableString tableDataPart = new SpannableString(tableData.text()); + if (tableData.getElementsByTag("b").size() > 0) { + tableDataPart.setSpan(new StyleSpan(Typeface.BOLD), 0, tableDataPart.length(), 0); + tableDataPart.setSpan(new UnderlineSpan(), 0, tableDataPart.length(), 0); + } + + parts.add(tableDataPart); + + if (j < tableDatas.size() - 1) { + parts.add(": "); + } + } + + if (i < tableRows.size() - 1) { + parts.add("\n"); + } + } + } + + SpannableString tableTotal = new SpannableString(TextUtils.concat(parts.toArray(new CharSequence[parts.size()]))); + tableTotal.setSpan(new ForegroundColorSpan(ThemeHelper.getInstance().getInlineQuoteColor()), 0, tableTotal.length(), 0); + tableTotal.setSpan(new AbsoluteSizeSpan(sp(12f)), 0, tableTotal.length(), 0); + + return tableTotal; + } case "strong": { Element strong = (Element) node; @@ -341,7 +388,7 @@ public class ChanParser { int tId = Integer.parseInt(numsSplitted[0]); int pId = Integer.parseInt(numsSplitted[1]); threadLink = new PostLinkable.ThreadLink(board, tId, pId); - } catch (NumberFormatException e) { + } catch (NumberFormatException ignored) { } } } @@ -359,7 +406,7 @@ public class ChanParser { if (splitted.length == 2) { try { id = Integer.parseInt(splitted[1]); - } catch (NumberFormatException e) { + } catch (NumberFormatException ignored) { } } diff --git a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java index 913bd58a..b6d59a8b 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/model/Post.java +++ b/Clover/app/src/main/java/org/floens/chan/core/model/Post.java @@ -22,7 +22,7 @@ import android.text.TextUtils; import org.floens.chan.Chan; import org.floens.chan.chan.ChanUrls; -import org.floens.chan.core.loader.ChanParser; +import org.floens.chan.chan.ChanParser; import org.jsoup.parser.Parser; import java.util.ArrayList; diff --git a/Clover/app/src/main/java/org/floens/chan/core/loader/LoaderPool.java b/Clover/app/src/main/java/org/floens/chan/core/net/LoaderPool.java similarity index 96% rename from Clover/app/src/main/java/org/floens/chan/core/loader/LoaderPool.java rename to Clover/app/src/main/java/org/floens/chan/core/net/LoaderPool.java index 070d66a0..d41ca9ea 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/loader/LoaderPool.java +++ b/Clover/app/src/main/java/org/floens/chan/core/net/LoaderPool.java @@ -15,8 +15,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.floens.chan.core.loader; +package org.floens.chan.core.net; +import org.floens.chan.chan.ChanLoader; import org.floens.chan.core.model.Loadable; import java.util.HashMap; diff --git a/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java b/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java index 18f7eeeb..ee284abb 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java +++ b/Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java @@ -26,8 +26,8 @@ import org.floens.chan.R; import org.floens.chan.chan.ChanUrls; import org.floens.chan.core.http.DeleteHttpCall; import org.floens.chan.core.http.ReplyManager; -import org.floens.chan.core.loader.ChanLoader; -import org.floens.chan.core.loader.LoaderPool; +import org.floens.chan.chan.ChanLoader; +import org.floens.chan.core.net.LoaderPool; import org.floens.chan.core.manager.WatchManager; import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.Loadable; diff --git a/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java b/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java index 56712a92..6df7e77c 100644 --- a/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java +++ b/Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java @@ -20,8 +20,8 @@ package org.floens.chan.core.watch; import com.android.volley.VolleyError; import org.floens.chan.Chan; -import org.floens.chan.core.loader.ChanLoader; -import org.floens.chan.core.loader.LoaderPool; +import org.floens.chan.chan.ChanLoader; +import org.floens.chan.core.net.LoaderPool; import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.Pin; import org.floens.chan.core.model.Post; diff --git a/Clover/app/src/main/java/org/floens/chan/test/TestActivity.java b/Clover/app/src/main/java/org/floens/chan/test/TestActivity.java index d34ed167..075061ce 100644 --- a/Clover/app/src/main/java/org/floens/chan/test/TestActivity.java +++ b/Clover/app/src/main/java/org/floens/chan/test/TestActivity.java @@ -29,7 +29,7 @@ import com.android.volley.VolleyError; import org.floens.chan.Chan; import org.floens.chan.core.cache.FileCache; -import org.floens.chan.core.loader.ChanLoader; +import org.floens.chan.chan.ChanLoader; import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Post;