package net.krautchan.data;
/*
* Copyright (C) 2011 Johannes Jander (johannes@jandermail.de)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringEscapeUtils;
public class KCPosting extends KrautObject implements Comparable<KCPosting>{
private static final long serialVersionUID = 2343973223217952495L;
private static final SimpleDateFormat df = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
// we get the date as: EEE, dd MMM yyyy HH:mm:ss z"
// we need to write it as: 2008-07-17T09:24:17Z
private static SimpleDateFormat dfShort = new SimpleDateFormat ("dd.MM. HH:mm");
private static SimpleDateFormat dfOut = new SimpleDateFormat ("yyyy-MM-dd'T'HH:mm:ss");
//private static final Pattern imgPat = Pattern.compile("href=\"/download/(\\d+\\..+?)/(.+?)\"");
private static final Pattern imgPat = Pattern.compile("a\\s+href=\"/files/(\\d+\\..+?)\".+?src=\"?/thumbnails/(\\d+\\..+?)\\s\"?", Pattern.DOTALL);
private static final Pattern linkPat = Pattern.compile("https?://w?w?w?\\.?(.+?)/(.+?)([\"\\s<>\\(\\)])");
private static final Pattern kcLinkPat = Pattern.compile("<a href=\".+\">>>(\\d+)</a>");
private static final Pattern uriPat = Pattern.compile("href=\"(.+?)\"");
private static final Pattern spoilerPat = Pattern.compile("<span class=\"spoiler\">(.+?)</span>", Pattern.DOTALL);
private static final Pattern quotePat = Pattern.compile("<span class=\"quote\">(.+?)</span>", Pattern.DOTALL);
public Long kcNummer;
public Long threadId;
public Long threadKcNummer;
public Long created;
public String title;
public String creationDate;
public String creationShortDate;
public String content;
public String originalContent;
public String user;
public String tripCode;
public boolean sage;
//<img style="display: block" id='thumbnail_93878459' src=/thumbnails/1314213328002.jpg" ...
public String[] thumbs = new String[4];
//<a href="/download/1314213328002.jpg/DSC00030.JPG"
public String[] imgs = new String[4];
public static enum Fields {
KC_NUM,
TITLE,
USER,
DATE,
URI,
IMAGES,
CONTENT
}
public void sanitizeContent () {
String locContent = content;
locContent = StringEscapeUtils.unescapeHtml4(locContent);
locContent = locContent.replaceAll("<p>", "");
locContent = locContent.replaceAll("</p>", " ");
originalContent = locContent;
locContent = locContent.replaceAll("onclick=\"highlightPost\\(\\'\\d+\\'\\);\"", "");
locContent = locContent.replaceAll(">>>(\\d+)</a>", " onclick='quoteClick(this); return false;' class=\"kclink\">>> $1</a>");
locContent = locContent.replaceAll("<a href=\"/resolve(/.+?)\"\\s*>.+?</a>", "<a href=\"/resolve$1\" class=\"kclink\" onclick=\"Android.openKcLink('$1');return false;\">>> $1</a>");
Matcher m = linkPat.matcher(locContent);
//CharBuffer buf = CharBuffer.allocate(locContent.length()+1000);
StringBuffer buf = new StringBuffer(locContent.length()+1000);
int end = 0;
while (m.find()) {
int gc = m.groupCount();
if (gc > 0) {
buf.append(locContent.substring(end, m.start()));
end = m.end();
String host = m.group(1);
String name = host;
String styleClass="extlink";
String androidFunction = "openExternalLink";
String url = m.group(1)+"/"+m.group(2);
if ((host.contains("youtube")) || (host.contains("youtu.be"))) {
styleClass="ytlink";
name = "YouTube";
androidFunction = "openYouTubeVideo";
} else if (host.contains("krautchan.net")){
styleClass="kclink";
name = ">>";
host = "";
androidFunction = "openKcLink";
}
buf.append("<a href=\"http://"+m.group(1)+"/"+m.group(2)+"\" class=\""+styleClass+"\" onclick=\"Android."+androidFunction+"('"+url+"');return false;\">"+name+"</a>"+m.group(3));
}
}
buf.append(locContent.substring(end, locContent.length()));
content = "<p><span>"+buf.toString().trim()+"</span></p>";
}
public String asHtml (boolean showImages) {
String innerHtml = "<div class=\"posthead\">" +
"<p class=\"headline\"><b>"+kcNummer+"</b><time class='timeago' datetime='"+creationDate+"'>"+creationDate+"</time></p>";
if (null != title) {
innerHtml += "<p class=\"topic\">"+title+"</p>";
}
innerHtml += "</div>";
innerHtml += content;
if (showImages && imgs.length > 0) {
innerHtml += "<div class=\"image-container\">";
for (int i = 0; i < imgs.length; i++) {
if (null != imgs[i]) {
innerHtml += "<a class=\"kcimglink\" href=\"/files/"+imgs[i]+"\" onclick=\"Android.openImage('"+imgs[i]+"');return false;\"><img src=\"/thumbnails/"+thumbs[i]+"\"></a>";
}
}
innerHtml += "</div>";
}
return "<div id='"+kcNummer+"'>"+innerHtml+"</div>";
}
public String getKcStyledContent() {
String kcStyledContent = originalContent.replaceAll("<br>", "\n>");
Matcher kcMatcher = kcLinkPat.matcher(kcStyledContent);
while (kcMatcher.find()) {
kcStyledContent = kcMatcher.replaceAll(">>"+kcMatcher.group(1));
}
Matcher spoilerMatcher = spoilerPat.matcher(kcStyledContent);
while (spoilerMatcher.find()) {
kcStyledContent = ">>"+spoilerMatcher.replaceAll("[spoiler]"+spoilerMatcher.group(1)+"[/spoiler]");
}
Matcher quoteMatcher = quotePat.matcher(kcStyledContent);
while (quoteMatcher.find()) {
kcStyledContent = quoteMatcher.replaceFirst(quoteMatcher.group(1));
quoteMatcher = quotePat.matcher(kcStyledContent);
}
kcStyledContent = ">"+kcStyledContent;
return kcStyledContent.trim();
}
public void setField(Fields fields, String arg) throws ParseException {
switch (fields) {
case KC_NUM: {
if (null != arg) {
kcNummer = Long.parseLong(arg);
}
break;
}
case TITLE: {
title = StringEscapeUtils.unescapeHtml4(arg);
break;
}
case USER: {
user = arg;
break;
}
case DATE: {
int pos = arg.lastIndexOf('.');
Date cDate = df.parse(arg.substring(0, pos));
created = cDate.getTime();
creationShortDate = dfShort.format(cDate);
creationDate = dfOut.format(cDate);
break;
}
case URI: {
Matcher m = uriPat.matcher(arg);
if (m.find()) {
uri = m.group(1);
dbId = (long)uri.hashCode();
}
break;
}
case IMAGES: {
Matcher m = imgPat.matcher(arg);
int i = 0;
while (m.find() && i < imgs.length) {
imgs[i] = m.group(1);
thumbs[i] = m.group(2);
i++;
}
break;
}
case CONTENT: {
content = arg.replaceFirst(kcNummer+"\">\\s*", "");
sanitizeContent();
break;
}
default:
throw new IllegalStateException ("Illegal State in KCPosting:setField");
}
}
public String toString() {
return "Post: "+kcNummer+" - "+content.substring(0, 40);
}
@Override
public int compareTo(KCPosting arg0) {
return kcNummer.compareTo(arg0.kcNummer);
}
}