/*
* Juick
* Copyright (C) 2008-2011, Ugnich Anton
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package com.juick.http.www;
import com.juick.Message;
import com.juick.Tag;
import com.juick.server.Endpoints;
import com.juick.server.MessagesQueries;
import com.juick.server.UserQueries;
import org.springframework.jdbc.core.JdbcTemplate;
import ru.sape.Sape;
import javax.servlet.http.HttpServletRequest;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
*
* @author Ugnich Anton
*/
public class PageTemplates {
public static Sape sape = null;
private static final SimpleDateFormat sdfSQL = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private static SimpleDateFormat sdfSimple = new SimpleDateFormat("d MMM");
private static SimpleDateFormat sdfFull = new SimpleDateFormat("d MMM yyyy");
private static String tagsHTML = null;
public static void pageHead(PrintWriter out, String title, String headers) {
out.println("");
out.print("");
out.print("
");
out.println(" ");
out.print(" ");
out.print("");
out.print("");
if (headers != null) {
out.print(headers);
}
out.print("" + title + " ");
out.println(" ");
out.println(" ");
out.println("");
out.println("");
out.flush();
out.println("");
}
public static void pageNavigation(PrintWriter out, com.juick.User visitor, String search) {
out.println("");
}
public static void pageYandexAd728(PrintWriter out, int YandexID) {
/*
out.println("
");
out.println("");
*/
out.println("");
out.println(" ");
out.println("");
}
public static void pageHomeColumn(PrintWriter out, JdbcTemplate sql, com.juick.User visitor) {
pageHomeColumn(out, sql, visitor, false);
}
public static void pageHomeColumn(PrintWriter out, JdbcTemplate sql, com.juick.User visitor, boolean showAdv) {
if (tagsHTML == null) {
tagsHTML = PageTemplates.getPopularTags(sql, 80);
}
out.println("");
}
public static String getPopularTags(JdbcTemplate sql, int cnt) {
List tags = sql.queryForList("SELECT name FROM tags WHERE top=1 ORDER BY name ASC", String.class);
if (!tags.isEmpty()) {
return tags.stream().map(tag -> "" + Utils.encodeHTML(tag) + " ")
.collect(Collectors.joining(" "));
}
return "";
}
public static void pageFooter(HttpServletRequest request, PrintWriter out, com.juick.User visitor, boolean sapeon) {
out.println("");
if (visitor != null) {
out.println("");
}
out.println("");
}
public static void pageEnd(PrintWriter out) {
out.println("");
}
public static String formatTags(List tags) {
String ret = "";
for (Tag tag : tags) {
String tagName = tag.Name.replaceAll("<", "<").replaceAll(">", ">");
try {
ret += " *" + tagName + " ";
} catch (UnsupportedEncodingException e) {
}
}
return ret;
}
public static String formatTags(List tags, com.juick.User user) {
String ret = "";
for (String tag : tags) {
tag = tag.replaceAll("<", "<");
tag = tag.replaceAll(">", ">");
try {
ret += " *" + tag + " ";
} catch (UnsupportedEncodingException e) {
}
}
return ret;
}
public static String formatDate(int minutes, Date fulldate) {
if (minutes < 1) {
return "сейчас";
} else if (minutes < 60) {
String unit;
int ld = minutes % 10;
if ((minutes < 10 || minutes > 20) && ld == 1) {
unit = "минуту";
} else if ((minutes < 10 || minutes > 20) && ld > 1 && ld < 5) {
unit = "минуты";
} else {
unit = "минут";
}
return minutes + " " + unit + " назад";
} else if (minutes < 1440) {
int hours = (minutes / 60);
String unit;
int ld = hours % 10;
if ((hours < 10 || hours > 20) && ld == 1) {
unit = "час";
} else if ((hours < 10 || hours > 20) && ld > 1 && ld < 5) {
unit = "часа";
} else {
unit = "часов";
}
return hours + " " + unit + " назад";
} else if (minutes < 20160) {
int days = (minutes / 1440);
String unit;
int ld = days % 10;
if ((days < 10 || days > 20) && ld == 1) {
unit = "день";
} else if ((days < 10 || days > 20) && ld > 1 && ld < 5) {
unit = "дня";
} else {
unit = "дней";
}
return days + " " + unit + " назад";
} else {
String ret;
Calendar c = Calendar.getInstance();
int curyear = c.get(Calendar.YEAR);
c.setTime(fulldate);
if (c.get(Calendar.YEAR) == curyear) {
ret = sdfSimple.format(fulldate);
} else {
ret = sdfFull.format(fulldate);
}
return ret;
}
}
public static String formatJSLocalTime(Date ts) {
return "";
}
public static String formatReplies(int replies) {
int ld = replies % 10;
int lh = replies % 100;
if ((lh < 10 || lh > 20) && ld == 1) {
return replies + " ответ";
} else if ((lh < 10 || lh > 20) && ld > 1 && ld < 5) {
return replies + " ответа";
} else {
return replies + " ответов";
}
}
private static Pattern regexLinks2 = Pattern.compile("((?<=\\s)|(?<=\\A))([\\[\\{]|<)((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\\"\\)\\!]+)/?(?:[^\\]\\}](?", ">");
// http://juick.com/last?page=2
// http://juick.com/last?page=2
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\n\\\"]+)/?[^\\s\\n\\\"]*)", "$1$2 ");
// (http://juick.com/last?page=2)
// (http://juick.com/last?page=2 )
Matcher m = regexLinks2.matcher(msg);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String url = m.group(3).replace(" ", "%20").replaceAll("\\s+", "");
m.appendReplacement(sb, "$1$2" + url + " $5");
}
m.appendTail(sb);
msg = sb.toString();
return "" + msg + " ";
}
public static String formatMessage(String msg) {
msg = msg.replaceAll("&", "&");
msg = msg.replaceAll("<", "<");
msg = msg.replaceAll(">", ">");
// --
// —
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))\\-\\-?((?=\\s)|(?=\\Z))", "$1—$2");
// http://juick.com/last?page=2
// juick.com
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\n\\\"]+)/?[^\\s\\n\\\"]*)", "$1$3 ");
// [link text][http://juick.com/last?page=2]
// link text
msg = msg.replaceAll("\\[([^\\]]+)\\]\\[((?:ht|f)tps?://[^\\]]+)\\]", "$1 ");
msg = msg.replaceAll("\\[([^\\]]+)\\]\\(((?:ht|f)tps?://[^\\)]+)\\)", "$1 ");
// #12345
// #12345
msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))#(\\d+)((?=\\s)|(?=\\Z)|(?=\\))|(?=\\.)|(?=\\,))", "$1#$2 $3");
// #12345/65
// #12345/65
msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))#(\\d+)/(\\d+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1#$2/$3 $4");
// *bold*
// bold
msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))\\*([^\\*\\n<>]+)\\*((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1$2 $3");
// /italic/
// italic
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))/([^\\/\\n<>]+)/((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1$2 $3");
// _underline_
// underline
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))_([^\\_\\n<>]+)_((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1$2 $3");
// /12
// /12
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))\\/(\\d+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1/$2 $3");
// @username@jabber.org
// @username@jabber.org
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))@([\\w\\-\\.]+@[\\w\\-\\.]+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1@$2 $3");
// @username
// @username
msg = msg.replaceAll("((?<=\\s)|(?<=\\A))@([\\w\\-]{2,16})((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1@$2 $3");
// (http://juick.com/last?page=2)
// (juick.com )
Matcher m = regexLinks2.matcher(msg);
StringBuffer sb = new StringBuffer();
while (m.find()) {
String url = m.group(3).replace(" ", "%20").replaceAll("\\s+", "");
m.appendReplacement(sb, "$1$2$4 $5");
}
m.appendTail(sb);
msg = sb.toString();
// > citate
msg = msg.replaceAll("(?:(?<=\\n)|(?<=\\A))> *(.*)?(\\n|(?=\\Z))", "$1 ");
msg = msg.replaceAll("", "\n");
msg = msg.replaceAll("\n", " \n");
return msg;
}
public static void printMessages(PrintWriter out, JdbcTemplate sql, com.juick.User user,
List mids, com.juick.User visitor, int YandexID, int ad_mid) {
List msgs = MessagesQueries.getMessages(sql, mids);
for (int i = 0; i < msgs.size(); i++) {
com.juick.Message msg = msgs.get(i);
if (msg.getMID() == ad_mid) {
msgs.remove(i);
msgs.add(0, msg);
break;
}
}
List blUIDs = new ArrayList<>(20);
if (visitor != null) {
for (Message msg : msgs) {
blUIDs.add(msg.getUser().getUID());
}
blUIDs = UserQueries.checkBL(sql, visitor.getUID(), blUIDs);
}
for (int i = 0; i < msgs.size(); i++) {
if (i == 0 && YandexID > 0 && ad_mid == 0) {
pageYandexAd728(out, YandexID);
}
com.juick.Message msg = msgs.get(i);
List tags = MessagesQueries.getMessageTags(sql, msg.getMID());
String tagsStr = formatTags(tags);
if (msg.ReadOnly) {
tagsStr += " *readonly";
}
if (msg.Privacy < 0) {
tagsStr += " *friends";
}
if (msg.getMID() == ad_mid) {
tagsStr += " *реклама";
}
String txt;
if (!msg.Tags.isEmpty() && msg.Tags.contains("code")) {
txt = formatMessageCode(msg.getText());
} else {
txt = formatMessage(msg.getText());
}
out.println("");
out.println(" ");
out.println(" ");
out.println(" ");
if (msg.AttachmentType != null) {
String fname = msg.getMID() + "." + msg.AttachmentType;
out.println("
");
}
out.println(" " + txt + "
");
if (msg.AttachmentType != null) {
out.println("
");
}
out.print(" ");
msg.ReadOnly |= blUIDs.contains(msg.getUser().getUID());
if (visitor == null && !msg.ReadOnly) {
out.print("Комментировать ");
} else if (visitor != null && (!msg.ReadOnly || visitor.getUID() == msg.getUser().getUID())) {
out.print("Комментировать ");
}
out.print("Мне нравится ");
if (visitor != null && msg.Privacy < 0 && msg.getUser().getUID() == visitor.getUID()) {
out.print(" Открыть доступ ");
}
if (visitor != null && visitor.getUID() == 3694) {
out.print(" + ");
out.print(" - ");
out.print(" x ");
}
out.println(" ");
out.print(" ");
if (msg.Likes > 0) {
out.print("" + msg.Likes + " ");
}
if (msg.Replies > 0) {
out.print("" + msg.Replies + " ");
}
out.println(" ");
out.print(" ");
}
}
}