/* * 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.server.MessagesQueries; import com.juick.server.UserQueries; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import ru.sape.Sape; /** * * @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.print(""); out.print(""); out.print(""); if (headers != null) { out.print(headers); } out.print("" + title + ""); out.print(""); out.println(""); out.println(""); out.println(""); out.flush(); out.println(""); } public static void pageNavigation(PrintWriter out, com.juick.User visitor, String search) { out.println("
"); out.println(" "); out.print(" "); out.print("
"); out.println("
"); if (visitor != null) { out.print(" "); out.print(" "); } else { out.println("

Чтобы добавлять сообщения и комментарии, представьтесь.

"); } out.println("
"); out.println("
"); } public static void pageYandexAd728(PrintWriter out, int YandexID) { out.println("
"); out.println(""); } public static void pageHomeColumn(PrintWriter out, Connection sql, com.juick.User visitor) { if (tagsHTML == null) { tagsHTML = PageTemplates.getPopularTags(sql, 80); } out.println(""); } public static String getPopularTags(Connection sql, int cnt) { String ret = ""; com.juick.Tag tags[] = new com.juick.Tag[cnt]; int maxUsageCnt = 0; PreparedStatement stmt = null; ResultSet rs = null; try { stmt = sql.prepareStatement("SELECT tags.name AS name,COUNT(DISTINCT messages.user_id) AS cnt FROM (messages INNER JOIN messages_tags ON (messages.ts>TIMESTAMPADD(MONTH,-1,NOW()) AND messages.message_id=messages_tags.message_id)) INNER JOIN tags ON messages_tags.tag_id=tags.tag_id WHERE tags.tag_id NOT IN (SELECT tag_id FROM tags_ignore) GROUP BY tags.tag_id ORDER BY cnt DESC LIMIT ?"); stmt.setInt(1, cnt); rs = stmt.executeQuery(); rs.beforeFirst(); cnt = 0; while (rs.next()) { tags[cnt] = new com.juick.Tag(); tags[cnt].Name = rs.getString(1); tags[cnt].UsageCnt = rs.getInt(2); if (tags[cnt].UsageCnt > maxUsageCnt) { maxUsageCnt = tags[cnt].UsageCnt; } cnt++; } } catch (SQLException e) { System.err.println(e); } finally { Utils.finishSQL(rs, stmt); } Arrays.sort(tags, 0, cnt); for (int i = 0; i < cnt; i++) { String tag = Utils.encodeHTML(tags[i].Name); try { tag = "" + tag + ""; } catch (UnsupportedEncodingException e) { } if (tags[i].UsageCnt > maxUsageCnt / 3 * 2) { ret += "" + tag + " "; } else if (tags[i].UsageCnt > maxUsageCnt / 3) { ret += "" + tag + " "; } else { ret += tag + " "; } } return ret; } public static void printContestRating(PrintWriter out, Connection sql) { out.println("
"); out.println(""); out.println("

Кто выиграет iPod?

"); out.println(""); int i = 0; PreparedStatement stmt = null; ResultSet rs = null; try { stmt = sql.prepareStatement("SELECT users.id,users.nick,COUNT(users_refs.user_id) AS cnt FROM users INNER JOIN users_refs ON users.id=users_refs.ref WHERE users.id>2 GROUP BY users_refs.ref ORDER BY cnt DESC LIMIT 10"); rs = stmt.executeQuery(); rs.beforeFirst(); while (rs.next()) { String uname = rs.getString(2); if (i == 0) { out.println(" "); } else { out.println(" "); } i++; } } catch (SQLException e) { System.err.println(e); } finally { Utils.finishSQL(rs, stmt); } out.println("
" + uname + "" + rs.getInt(3) + "
" + uname + "" + rs.getInt(3) + "
"); out.println(""); } public static void pageFooter(HttpServletRequest request, PrintWriter out, com.juick.User visitor, boolean sapeon) { out.println("
"); out.println(" "); out.print("
"); out.print("Twitter"); out.print("ВКонтакте"); out.print("Facebook"); out.println("
"); out.print("
juick.com © 2008-2014"); if (sapeon && sape != null && (visitor == null || visitor.UID == 1) && request.getQueryString() == null) { String links = sape.getPageLinks(request.getRequestURI(), request.getCookies()).render(); if (links != null && !links.isEmpty()) { out.print("
Спонсоры: " + links); } } out.println("
"); out.println("
"); if (visitor != null) { out.println(""); } out.println(""); } public static void pageEnd(PrintWriter out) { out.println(""); } public static String formatTags(ArrayList tags, com.juick.User user) { String ret = ""; for (int i = 0; i < tags.size(); i++) { String tag = tags.get(i); tag = tag.replaceAll("<", "<"); tag = tag.replaceAll(">", ">"); try { ret += " *" + tag + ""; } catch (UnsupportedEncodingException e) { } } return ret; } public static String formatDate(int minutes, String 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 = fulldate; synchronized (sdfSQL) { try { Date pDate = sdfSQL.parse(fulldate); Calendar c = Calendar.getInstance(); int curyear = c.get(Calendar.YEAR); c.setTime(pDate); if (c.get(Calendar.YEAR) == curyear) { ret = sdfSimple.format(pDate); } else { ret = sdfFull.format(pDate); } } catch (Exception e) { System.err.println("PARSE EXCEPTION: " + fulldate); } } return ret; } } public static String formatJSLocalTime(String ts) { String ret = ""; synchronized (sdfSQL) { try { Date date = sdfSQL.parse(ts); ret = ""; } catch (Exception e) { System.err.println("PARSE EXCEPTION: " + ts); } } return ret; } 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, Connection sql, com.juick.User user, ArrayList mids, com.juick.User visitor, int YandexID, int ad_mid) { ArrayList msgs = MessagesQueries.getMessages(sql, mids); for (int i = 0; i < msgs.size(); i++) { com.juick.Message msg = msgs.get(i); if (msg.MID == ad_mid) { msgs.remove(i); msgs.add(0, msg); break; } } ArrayList blUIDs = new ArrayList(20); if (visitor != null) { for (int i = 0; i < msgs.size(); i++) { blUIDs.add(msgs.get(i).User.UID); } blUIDs = UserQueries.checkBL(sql, visitor.UID, 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); String tags; if (user == null) { tags = msg.Tags.isEmpty() ? "" : formatTags(msg.Tags, null); } else { tags = msg.Tags.isEmpty() ? "" : formatTags(msg.Tags, msg.User); } if (msg.ReadOnly) { tags += " *readonly"; } if (msg.Privacy < 0) { tags += " *friends"; } if (msg.MID == ad_mid) { tags += " *реклама"; } String txt; if (!msg.Tags.isEmpty() && msg.Tags.contains("code")) { txt = formatMessageCode(msg.Text); } else { txt = formatMessage(msg.Text); } out.println("
"); out.println(" "); out.println("
@" + msg.User.UName + ":" + tags + "
"); out.println("
"); if (msg.AttachmentType != null) { String fname = msg.MID + "." + msg.AttachmentType; out.println("

\"\"/

"); } out.println("

" + txt + "

"); if (msg.AttachmentType != null) { out.println("
"); } out.print(" "); out.print(" "); out.println("
"); } } }