Better support for exif tables on /p/

Also move parsers to chan package
filtering
Floens 10 years ago
parent 43fa4fba26
commit ed0fa35b92
  1. 2
      Clover/app/src/main/java/org/floens/chan/chan/ChanLoader.java
  2. 61
      Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java
  3. 2
      Clover/app/src/main/java/org/floens/chan/core/model/Post.java
  4. 3
      Clover/app/src/main/java/org/floens/chan/core/net/LoaderPool.java
  5. 4
      Clover/app/src/main/java/org/floens/chan/core/presenter/ThreadPresenter.java
  6. 4
      Clover/app/src/main/java/org/floens/chan/core/watch/PinWatcher.java
  7. 2
      Clover/app/src/main/java/org/floens/chan/test/TestActivity.java

@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.floens.chan.core.loader; package org.floens.chan.chan;
import android.text.TextUtils; import android.text.TextUtils;

@ -15,7 +15,7 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package org.floens.chan.core.loader; package org.floens.chan.chan;
import android.content.Context; import android.content.Context;
@ -29,6 +29,7 @@ import android.text.style.ForegroundColorSpan;
import android.text.style.StrikethroughSpan; import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan; import android.text.style.TypefaceSpan;
import android.text.style.UnderlineSpan;
import org.floens.chan.Chan; import org.floens.chan.Chan;
import org.floens.chan.R; 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.model.PostLinkable;
import org.floens.chan.core.settings.ChanSettings; import org.floens.chan.core.settings.ChanSettings;
import org.floens.chan.utils.AndroidUtils; import org.floens.chan.utils.AndroidUtils;
import org.floens.chan.utils.Logger;
import org.floens.chan.utils.ThemeHelper; import org.floens.chan.utils.ThemeHelper;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil; import org.jsoup.helper.StringUtil;
@ -44,9 +46,11 @@ import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node; import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode; import org.jsoup.nodes.TextNode;
import org.jsoup.parser.Parser; import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.jsoup.select.NodeTraversor; import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor; import org.jsoup.select.NodeVisitor;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -55,6 +59,7 @@ import java.util.regex.Pattern;
import static org.floens.chan.utils.AndroidUtils.sp; import static org.floens.chan.utils.AndroidUtils.sp;
public class ChanParser { public class ChanParser {
private static final String TAG = "ChanParser";
private static final Pattern colorPattern = Pattern.compile("color:#([0-9a-fA-F]*)"); private static final Pattern colorPattern = Pattern.compile("color:#([0-9a-fA-F]*)");
private static ChanParser instance = new ChanParser(); private static ChanParser instance = new ChanParser();
@ -192,15 +197,18 @@ public class ChanParser {
Document document = Jsoup.parseBodyFragment(comment); Document document = Jsoup.parseBodyFragment(comment);
List<Node> nodes = document.body().childNodes(); List<Node> nodes = document.body().childNodes();
List<CharSequence> texts = new ArrayList<>(nodes.size());
for (Node node : nodes) { for (Node node : nodes) {
CharSequence nodeParsed = parseNode(post, node); CharSequence nodeParsed = parseNode(post, node);
if (nodeParsed != null) { if (nodeParsed != null) {
total = TextUtils.concat(total, nodeParsed); texts.add(nodeParsed);
} }
} }
total = TextUtils.concat(texts.toArray(new CharSequence[texts.size()]));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); Logger.e(TAG, "Error parsing comment html", e);
} }
return total; return total;
@ -222,7 +230,7 @@ public class ChanParser {
case "span": { case "span": {
Element span = (Element) node; Element span = (Element) node;
SpannableString quote = null; SpannableString quote;
Set<String> classes = span.classNames(); Set<String> classes = span.classNames();
if (classes.contains("deadlink")) { if (classes.contains("deadlink")) {
@ -247,7 +255,7 @@ public class ChanParser {
if (!TextUtils.isEmpty(group)) { if (!TextUtils.isEmpty(group)) {
try { try {
hexColor = Integer.parseInt(group, 16); 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); quote.setSpan(new StyleSpan(Typeface.BOLD), 0, quote.length(), 0);
} }
} }
} else if (classes.contains("abbr")) {
return null;
} else { } else {
quote = new SpannableString(span.text()); quote = new SpannableString(span.text());
quote.setSpan(new ForegroundColorSpan(ThemeHelper.getInstance().getInlineQuoteColor()), 0, quote.length(), 0); quote.setSpan(new ForegroundColorSpan(ThemeHelper.getInstance().getInlineQuoteColor()), 0, quote.length(), 0);
@ -265,6 +275,43 @@ public class ChanParser {
return quote; return quote;
} }
case "table": {
Element table = (Element) node;
List<CharSequence> 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": { case "strong": {
Element strong = (Element) node; Element strong = (Element) node;
@ -341,7 +388,7 @@ public class ChanParser {
int tId = Integer.parseInt(numsSplitted[0]); int tId = Integer.parseInt(numsSplitted[0]);
int pId = Integer.parseInt(numsSplitted[1]); int pId = Integer.parseInt(numsSplitted[1]);
threadLink = new PostLinkable.ThreadLink(board, tId, pId); threadLink = new PostLinkable.ThreadLink(board, tId, pId);
} catch (NumberFormatException e) { } catch (NumberFormatException ignored) {
} }
} }
} }
@ -359,7 +406,7 @@ public class ChanParser {
if (splitted.length == 2) { if (splitted.length == 2) {
try { try {
id = Integer.parseInt(splitted[1]); id = Integer.parseInt(splitted[1]);
} catch (NumberFormatException e) { } catch (NumberFormatException ignored) {
} }
} }

@ -22,7 +22,7 @@ import android.text.TextUtils;
import org.floens.chan.Chan; import org.floens.chan.Chan;
import org.floens.chan.chan.ChanUrls; 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 org.jsoup.parser.Parser;
import java.util.ArrayList; import java.util.ArrayList;

@ -15,8 +15,9 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
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 org.floens.chan.core.model.Loadable;
import java.util.HashMap; import java.util.HashMap;

@ -26,8 +26,8 @@ import org.floens.chan.R;
import org.floens.chan.chan.ChanUrls; import org.floens.chan.chan.ChanUrls;
import org.floens.chan.core.http.DeleteHttpCall; import org.floens.chan.core.http.DeleteHttpCall;
import org.floens.chan.core.http.ReplyManager; import org.floens.chan.core.http.ReplyManager;
import org.floens.chan.core.loader.ChanLoader; import org.floens.chan.chan.ChanLoader;
import org.floens.chan.core.loader.LoaderPool; import org.floens.chan.core.net.LoaderPool;
import org.floens.chan.core.manager.WatchManager; import org.floens.chan.core.manager.WatchManager;
import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Loadable;

@ -20,8 +20,8 @@ package org.floens.chan.core.watch;
import com.android.volley.VolleyError; import com.android.volley.VolleyError;
import org.floens.chan.Chan; import org.floens.chan.Chan;
import org.floens.chan.core.loader.ChanLoader; import org.floens.chan.chan.ChanLoader;
import org.floens.chan.core.loader.LoaderPool; import org.floens.chan.core.net.LoaderPool;
import org.floens.chan.core.model.ChanThread; import org.floens.chan.core.model.ChanThread;
import org.floens.chan.core.model.Pin; import org.floens.chan.core.model.Pin;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;

@ -29,7 +29,7 @@ import com.android.volley.VolleyError;
import org.floens.chan.Chan; import org.floens.chan.Chan;
import org.floens.chan.core.cache.FileCache; 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.ChanThread;
import org.floens.chan.core.model.Loadable; import org.floens.chan.core.model.Loadable;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;

Loading…
Cancel
Save