From 2f682b5e3cfc3fc5f961b60129be7bc90e0d6a03 Mon Sep 17 00:00:00 2001
From: Vitaly Takmazov
Date: Wed, 28 Dec 2016 22:38:21 +0300
Subject: juick-www: now on spring-webmvc
---
.../src/main/java/com/juick/www/Discover.java | 122 ------
juick-www/src/main/java/com/juick/www/Errors.java | 35 --
.../src/main/java/com/juick/www/FacebookLogin.java | 159 -------
juick-www/src/main/java/com/juick/www/Help.java | 85 ----
.../src/main/java/com/juick/www/HelpService.java | 48 +++
juick-www/src/main/java/com/juick/www/Home.java | 171 --------
juick-www/src/main/java/com/juick/www/Login.java | 246 -----------
juick-www/src/main/java/com/juick/www/Main.java | 396 -----------------
.../src/main/java/com/juick/www/NewMessage.java | 425 -------------------
juick-www/src/main/java/com/juick/www/PM.java | 150 -------
.../src/main/java/com/juick/www/PageTemplates.java | 374 ----------------
juick-www/src/main/java/com/juick/www/RSS.java | 63 ---
.../src/main/java/com/juick/www/Settings.java | 293 -------------
juick-www/src/main/java/com/juick/www/SignUp.java | 231 ----------
.../src/main/java/com/juick/www/TwitterAuth.java | 94 -----
juick-www/src/main/java/com/juick/www/User.java | 352 ----------------
.../src/main/java/com/juick/www/UserThread.java | 358 ----------------
juick-www/src/main/java/com/juick/www/Utils.java | 140 +-----
.../main/java/com/juick/www/VKontakteLogin.java | 133 ------
juick-www/src/main/java/com/juick/www/WebApp.java | 154 +++++++
.../src/main/java/com/juick/www/XMPPPost.java | 79 ----
.../www/configuration/WebAppConfiguration.java | 50 +++
.../juick/www/configuration/WwwInitializer.java | 52 +++
.../www/configuration/WwwServletConfiguration.java | 99 +++++
.../java/com/juick/www/controllers/Discover.java | 138 ++++++
.../com/juick/www/controllers/FacebookLogin.java | 153 +++++++
.../main/java/com/juick/www/controllers/Help.java | 74 ++++
.../main/java/com/juick/www/controllers/Home.java | 232 ++++++++++
.../main/java/com/juick/www/controllers/Login.java | 258 ++++++++++++
.../java/com/juick/www/controllers/NewMessage.java | 468 +++++++++++++++++++++
.../main/java/com/juick/www/controllers/PM.java | 163 +++++++
.../com/juick/www/controllers/PageTemplates.java | 381 +++++++++++++++++
.../main/java/com/juick/www/controllers/RSS.java | 66 +++
.../java/com/juick/www/controllers/Settings.java | 287 +++++++++++++
.../java/com/juick/www/controllers/SignUp.java | 170 ++++++++
.../com/juick/www/controllers/TwitterAuth.java | 103 +++++
.../main/java/com/juick/www/controllers/User.java | 368 ++++++++++++++++
.../java/com/juick/www/controllers/UserThread.java | 374 ++++++++++++++++
.../com/juick/www/controllers/VKontakteLogin.java | 130 ++++++
.../java/com/juick/www/controllers/XMPPPost.java | 84 ++++
juick-www/src/main/resources/juick.conf.example | 6 +
juick-www/src/main/resources/layouts/content.html | 27 --
juick-www/src/main/resources/layouts/rss.xml | 38 --
juick-www/src/main/resources/views/404.html | 11 -
juick-www/src/main/resources/views/help.html | 10 -
.../src/main/resources/views/partial/footer.html | 34 --
.../main/resources/views/partial/homecolumn.html | 6 -
.../main/resources/views/partial/navigation.html | 37 --
.../resources/views/partial/settings_tabs.html | 5 -
.../src/main/resources/views/partial/tags.html | 3 -
juick-www/src/main/resources/views/pm_inbox.html | 37 --
juick-www/src/main/resources/views/pm_sent.html | 33 --
.../src/main/resources/views/settings_about.html | 20 -
.../main/resources/views/settings_auth-email.html | 9 -
.../src/main/resources/views/settings_main.html | 156 -------
.../main/resources/views/settings_password.html | 17 -
.../src/main/resources/views/settings_privacy.html | 9 -
.../src/main/resources/views/settings_result.html | 9 -
juick-www/src/main/resources/views/signup.html | 41 --
.../src/main/webapp/WEB-INF/juick.conf.example | 6 -
.../src/main/webapp/WEB-INF/layouts/content.html | 27 ++
juick-www/src/main/webapp/WEB-INF/layouts/rss.xml | 38 ++
juick-www/src/main/webapp/WEB-INF/views/404.html | 11 +
juick-www/src/main/webapp/WEB-INF/views/help.html | 10 +
.../main/webapp/WEB-INF/views/partial/footer.html | 34 ++
.../webapp/WEB-INF/views/partial/homecolumn.html | 6 +
.../webapp/WEB-INF/views/partial/navigation.html | 37 ++
.../WEB-INF/views/partial/settings_tabs.html | 5 +
.../main/webapp/WEB-INF/views/partial/tags.html | 3 +
.../src/main/webapp/WEB-INF/views/pm_inbox.html | 37 ++
.../src/main/webapp/WEB-INF/views/pm_sent.html | 33 ++
.../main/webapp/WEB-INF/views/settings_about.html | 20 +
.../webapp/WEB-INF/views/settings_auth-email.html | 9 +
.../main/webapp/WEB-INF/views/settings_main.html | 156 +++++++
.../webapp/WEB-INF/views/settings_password.html | 17 +
.../webapp/WEB-INF/views/settings_privacy.html | 9 +
.../main/webapp/WEB-INF/views/settings_result.html | 9 +
.../src/main/webapp/WEB-INF/views/signup.html | 41 ++
juick-www/src/main/webapp/WEB-INF/web.xml | 38 --
79 files changed, 4361 insertions(+), 4451 deletions(-)
delete mode 100644 juick-www/src/main/java/com/juick/www/Discover.java
delete mode 100644 juick-www/src/main/java/com/juick/www/Errors.java
delete mode 100644 juick-www/src/main/java/com/juick/www/FacebookLogin.java
delete mode 100644 juick-www/src/main/java/com/juick/www/Help.java
create mode 100644 juick-www/src/main/java/com/juick/www/HelpService.java
delete mode 100644 juick-www/src/main/java/com/juick/www/Home.java
delete mode 100644 juick-www/src/main/java/com/juick/www/Login.java
delete mode 100644 juick-www/src/main/java/com/juick/www/Main.java
delete mode 100644 juick-www/src/main/java/com/juick/www/NewMessage.java
delete mode 100644 juick-www/src/main/java/com/juick/www/PM.java
delete mode 100644 juick-www/src/main/java/com/juick/www/PageTemplates.java
delete mode 100644 juick-www/src/main/java/com/juick/www/RSS.java
delete mode 100644 juick-www/src/main/java/com/juick/www/Settings.java
delete mode 100644 juick-www/src/main/java/com/juick/www/SignUp.java
delete mode 100644 juick-www/src/main/java/com/juick/www/TwitterAuth.java
delete mode 100644 juick-www/src/main/java/com/juick/www/User.java
delete mode 100644 juick-www/src/main/java/com/juick/www/UserThread.java
delete mode 100644 juick-www/src/main/java/com/juick/www/VKontakteLogin.java
create mode 100644 juick-www/src/main/java/com/juick/www/WebApp.java
delete mode 100644 juick-www/src/main/java/com/juick/www/XMPPPost.java
create mode 100644 juick-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java
create mode 100644 juick-www/src/main/java/com/juick/www/configuration/WwwInitializer.java
create mode 100644 juick-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/Discover.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/Help.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/Home.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/Login.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/NewMessage.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/PM.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/RSS.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/Settings.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/SignUp.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/User.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/UserThread.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java
create mode 100644 juick-www/src/main/java/com/juick/www/controllers/XMPPPost.java
create mode 100644 juick-www/src/main/resources/juick.conf.example
delete mode 100644 juick-www/src/main/resources/layouts/content.html
delete mode 100644 juick-www/src/main/resources/layouts/rss.xml
delete mode 100644 juick-www/src/main/resources/views/404.html
delete mode 100644 juick-www/src/main/resources/views/help.html
delete mode 100644 juick-www/src/main/resources/views/partial/footer.html
delete mode 100644 juick-www/src/main/resources/views/partial/homecolumn.html
delete mode 100644 juick-www/src/main/resources/views/partial/navigation.html
delete mode 100644 juick-www/src/main/resources/views/partial/settings_tabs.html
delete mode 100644 juick-www/src/main/resources/views/partial/tags.html
delete mode 100644 juick-www/src/main/resources/views/pm_inbox.html
delete mode 100644 juick-www/src/main/resources/views/pm_sent.html
delete mode 100644 juick-www/src/main/resources/views/settings_about.html
delete mode 100644 juick-www/src/main/resources/views/settings_auth-email.html
delete mode 100644 juick-www/src/main/resources/views/settings_main.html
delete mode 100644 juick-www/src/main/resources/views/settings_password.html
delete mode 100644 juick-www/src/main/resources/views/settings_privacy.html
delete mode 100644 juick-www/src/main/resources/views/settings_result.html
delete mode 100644 juick-www/src/main/resources/views/signup.html
delete mode 100644 juick-www/src/main/webapp/WEB-INF/juick.conf.example
create mode 100644 juick-www/src/main/webapp/WEB-INF/layouts/content.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/layouts/rss.xml
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/404.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/help.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/partial/footer.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/partial/homecolumn.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/partial/navigation.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/partial/settings_tabs.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/partial/tags.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/pm_inbox.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/pm_sent.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/settings_about.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/settings_auth-email.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/settings_main.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/settings_password.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/settings_privacy.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/settings_result.html
create mode 100644 juick-www/src/main/webapp/WEB-INF/views/signup.html
(limited to 'juick-www/src')
diff --git a/juick-www/src/main/java/com/juick/www/Discover.java b/juick-www/src/main/java/com/juick/www/Discover.java
deleted file mode 100644
index af2b6659..00000000
--- a/juick-www/src/main/java/com/juick/www/Discover.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.server.AdsQueries;
-import com.juick.server.MessagesQueries;
-import com.juick.server.TagQueries;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.util.List;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class Discover {
-
- protected void doGet(JdbcTemplate sql, JdbcTemplate sqlSearch, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- String paramTagStr = URLDecoder.decode(request.getRequestURI().substring(5), CharEncoding.UTF_8);
- com.juick.Tag paramTag = TagQueries.getTag(sql, paramTagStr, false);
- if (paramTag == null) {
- Errors.doGet404(sql, request, response);
- return;
- } else if (paramTag.SynonymID > 0 && paramTag.TID != paramTag.SynonymID) {
- com.juick.Tag synTag = TagQueries.getTag(sql, paramTag.SynonymID);
- String url = "/tag/" + URLEncoder.encode(synTag.getName(), CharEncoding.UTF_8);
- if (request.getQueryString() != null) {
- url += "?" + request.getQueryString();
- }
- Utils.sendPermanentRedirect(response, url);
- return;
- } else if (!paramTag.getName().equals(paramTagStr)) {
- String url = "/tag/" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8);
- if (request.getQueryString() != null) {
- url += "?" + request.getQueryString();
- }
- Utils.sendPermanentRedirect(response, url);
- return;
- }
-
- int paramBefore = 0;
- String paramBeforeStr = request.getParameter("before");
- if (paramBeforeStr != null) {
- try {
- paramBefore = Integer.parseInt(paramBeforeStr);
- } catch (NumberFormatException e) {
- }
- }
-
- int visitor_uid = visitor.getUid();
-
- String title = "*" + StringEscapeUtils.escapeHtml4(paramTag.getName());
- List mids = MessagesQueries.getTag(sql, paramTag.TID, visitor_uid, paramBefore, (visitor_uid == 0) ? 40 : 20);
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- String head = StringUtils.EMPTY;
- if (TagQueries.getTagNoIndex(sql, paramTag.TID)) {
- head = " ";
- } else if (paramBefore > 0 || mids.size() < 5) {
- head = " ";
- }
- PageTemplates.pageHead(out, visitor, title, head);
- PageTemplates.pageNavigation(out, visitor, null);
-
- out.println("");
-
- if (mids.size() > 0) {
- int vuid = visitor.getUid();
- int ad_mid = AdsQueries.getAdMID(sql, vuid);
- if (ad_mid > 0 && mids.indexOf(ad_mid) == -1) {
- mids.add(0, ad_mid);
- AdsQueries.logAdMID(sql, vuid, ad_mid);
- } else {
- ad_mid = 0;
- }
-
- PageTemplates.printMessages(out, sql, null, mids, visitor, visitor_uid == 0 ? 2 : 3, ad_mid);
- }
-
- if (mids.size() >= 20) {
- String nextpage = "/tag/" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8) + "?before=" + mids.get(mids.size() - 1);
- out.println("Читать дальше →
");
- }
-
- out.println(" ");
-
- PageTemplates.pageHomeColumn(out, sql, visitor);
-
- PageTemplates.pageFooter(request, out, visitor, true);
-
- PageTemplates.pageEnd(out);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/Errors.java b/juick-www/src/main/java/com/juick/www/Errors.java
deleted file mode 100644
index 75fdddde..00000000
--- a/juick-www/src/main/java/com/juick/www/Errors.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.juick.www;
-
-import com.mitchellbosecke.pebble.error.PebbleException;
-import com.mitchellbosecke.pebble.template.PebbleTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- *
- * @author ugnich
- */
-public class Errors {
-
- public static void doGet404(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- response.setStatus(HttpServletResponse.SC_NOT_FOUND);
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate("views/404.html");
- Map context = new HashMap<>();
- context.put("title", "404 Страница не найдена");
- context.put("visitor", visitor);
- template.evaluate(out, context);
- } catch (PebbleException e) {
- // log("pebble exception", e);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/FacebookLogin.java b/juick-www/src/main/java/com/juick/www/FacebookLogin.java
deleted file mode 100644
index ba7ab29f..00000000
--- a/juick-www/src/main/java/com/juick/www/FacebookLogin.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Juick
- * Copyright (C) 2008-2013, 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.www;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.juick.server.UserQueries;
-import com.juick.www.facebook.Graph;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.util.UUID;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class FacebookLogin {
-
- private static final Logger logger = LoggerFactory.getLogger(FacebookLogin.class);
-
- private final String FACEBOOK_APPID;
- private final String FACEBOOK_SECRET;
- private final String FACEBOOK_REDIRECT = "http://juick.com/_fblogin";
- private final ObjectMapper mapper;
-
- public FacebookLogin(String ApplicationID, String secret) {
- this.FACEBOOK_APPID = ApplicationID;
- this.FACEBOOK_SECRET = secret;
- mapper = new ObjectMapper();
- mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
- mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
- }
-
- protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String fbstate;
-
- String code = request.getParameter("code");
- if (StringUtils.isBlank(code)) {
- fbstate = UUID.randomUUID().toString();
-
- Cookie c = new Cookie("fbstate", fbstate);
- response.addCookie(c);
-
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "https://www.facebook.com/dialog/oauth?scope=publish_stream&client_id=" + FACEBOOK_APPID + "&redirect_uri=" + URLEncoder.encode(FACEBOOK_REDIRECT, CharEncoding.UTF_8) + "&state=" + fbstate);
- return;
- }
-
- fbstate = Utils.getCookie(request, "fbstate");
- if (fbstate == null || fbstate.isEmpty() || !fbstate.equals(request.getParameter("state"))) {
- response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
- return;
- } else {
- Cookie c = new Cookie("fbstate", "-");
- c.setMaxAge(0);
- response.addCookie(c);
- }
-
- String token = Utils.fetchURL("https://graph.facebook.com/oauth/access_token?client_id=" + FACEBOOK_APPID + "&redirect_uri=" + URLEncoder.encode(FACEBOOK_REDIRECT, CharEncoding.UTF_8) + "&client_secret=" + FACEBOOK_SECRET + "&code=" + URLEncoder.encode(code, CharEncoding.UTF_8));
- if (token == null || token.isEmpty() || !token.startsWith("access_token=")) {
- logger.error("FACEBOOK TOKEN ERROR: {}", token);
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
- token = token.substring(13); // access_token=...
- int tokenamp = token.indexOf('&'); // &expires=
- if (tokenamp > 0) {
- token = token.substring(0, tokenamp);
- }
-
- String graph = Utils.fetchURL("https://graph.facebook.com/me?access_token=" + token);
- if (graph == null || graph.isEmpty()) {
- logger.error("FACEBOOK GRAPH ERROR");
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
-
- try {
- Graph fb = mapper.readValue(graph, Graph.class);
-
- long fbID = NumberUtils.toLong(fb.getId(), 0);
- if (fbID == 0 || StringUtils.isBlank(fb.getName()) || StringUtils.isBlank(fb.getLink())) {
- throw new Exception();
- }
-
- int uid = getUIDbyFBID(sql, fbID);
- if (uid > 0) {
- if (!updateDB(sql, fbID, token, fb.getName(), fb.getLink())) {
- throw new Exception();
- }
- Cookie c = new Cookie("hash", UserQueries.getHashByUID(sql, uid));
- c.setMaxAge(50 * 24 * 60 * 60);
- response.addCookie(c);
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "/");
- } else if (fb.getVerified()) {
- String loginhash = UUID.randomUUID().toString();
- if (!insertDB(sql, fbID, loginhash, token, fb.getName(), fb.getLink())) {
- throw new Exception();
- }
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "/signup?type=fb&hash=" + loginhash);
- } else {
- throw new Exception();
- }
- } catch (Exception e) {
- logger.error("fb error", e);
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
- }
-
- private int getUIDbyFBID(JdbcTemplate sql, long fbID) {
- try {
- return sql.queryForObject("SELECT user_id FROM facebook WHERE fb_id=? AND user_id IS NOT NULL",
- Integer.class, fbID);
- } catch (EmptyResultDataAccessException e) {
- return 0;
- }
- }
-
- private boolean insertDB(JdbcTemplate sql, long fbID, String loginhash, String token, String fbName, String fbLink) {
- return sql.update("INSERT INTO facebook(fb_id,loginhash,access_token,fb_name,fb_link) VALUES (?,?,?,?,?)",
- fbID, loginhash, token, fbName, fbLink) > 0;
- }
-
- private boolean updateDB(JdbcTemplate sql, long fbID, String token, String fbName, String fbLink) {
- return sql.update("UPDATE facebook SET access_token=?,fb_name=?,fb_link=? WHERE fb_id=?",
- token, fbName, fbLink, fbID) > 0;
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/Help.java b/juick-www/src/main/java/com/juick/www/Help.java
deleted file mode 100644
index 301d2edc..00000000
--- a/juick-www/src/main/java/com/juick/www/Help.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.www;
-
-import com.mitchellbosecke.pebble.error.PebbleException;
-import com.mitchellbosecke.pebble.template.PebbleTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class Help {
-
- protected void doRedirectToHelpIndex(HttpServletResponse response) throws ServletException, IOException {
- Utils.sendTemporaryRedirect(response, "/help/ru/");
- }
-
- protected void doGetHelp(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, PebbleException, URISyntaxException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- String path[] = request.getRequestURI().split("/");
- String page;
- if (path.length < 3 || path.length > 4 || path[2].length() != 2 || !path[2].matches("^[a-z]+$")) {
- Errors.doGet404(sql, request, response);
- return;
- }
-
- if (path.length == 4) {
- page = path[3];
- if (!page.matches("^[a-zA-Z0-9\\-]*$") || page.equals("navigation") || page.equals("index")) {
- Errors.doGet404(sql, request, response);
- return;
- }
- } else {
- page = "index";
- }
-
- URL f = getClass().getResource("/help/" + path[2] + "/" + page);
- if (f == null) {
- Errors.doGet404(sql, request, response);
- return;
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate("views/help.html");
- Map context = new HashMap<>();
- context.put("title", "Помощь");
- context.put("visitor", visitor);
- context.put("content", new String(Files.readAllBytes(Paths.get(f.toURI()))));
- context.put("navigation", new String(Files.readAllBytes(
- new File(getClass().getResource("/help/" + path[2] + "/navigation").toURI()).toPath())));
- template.evaluate(out, context);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/HelpService.java b/juick-www/src/main/java/com/juick/www/HelpService.java
new file mode 100644
index 00000000..8ece4cfb
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/HelpService.java
@@ -0,0 +1,48 @@
+package com.juick.www;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.cache.annotation.Cacheable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.regex.Pattern;
+
+/**
+ * Created by aalexeev on 12/11/16.
+ */
+public class HelpService {
+ private static final Pattern LANG_PATTERN = Pattern.compile("[a-z]{2}");
+
+ private static final Pattern PAGE_PATTERN = Pattern.compile("[a-zA-Z0-9\\-_]+");
+
+ private final String helpPath;
+
+
+ public HelpService(String helpPath) {
+ this.helpPath = helpPath;
+ }
+
+ @Cacheable("help")
+ public String getHelp(final String page, final String lang) {
+ if (canBePage(page) && canBeLang(lang)) {
+ String path = StringUtils.joinWith("/", helpPath, lang, page);
+
+ try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(path)) {
+ if (is != null)
+ return IOUtils.toString(is, StandardCharsets.UTF_8);
+ } catch (IOException e) {
+ }
+ }
+ return null;
+ }
+
+ public boolean canBePage(final String anything) {
+ return anything != null && PAGE_PATTERN.matcher(anything).matches();
+ }
+
+ public boolean canBeLang(final String anything) {
+ return anything != null && LANG_PATTERN.matcher(anything).matches();
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/Home.java b/juick-www/src/main/java/com/juick/www/Home.java
deleted file mode 100644
index 1d4fd521..00000000
--- a/juick-www/src/main/java/com/juick/www/Home.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.server.AdsQueries;
-import com.juick.server.MessagesQueries;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.net.URLEncoder;
-import java.util.List;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class Home {
-
- protected void doGet(JdbcTemplate sql, JdbcTemplate sqlSearch, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException {
- int paramBefore = NumberUtils.toInt(request.getParameter("before"), 0);
-
- String paramSearch = request.getParameter("search");
- if (paramSearch != null && paramSearch.length() > 64) {
- paramSearch = null;
- }
-
- String title;
- List mids;
-
- String paramShow = request.getParameter("show");
- if (paramSearch != null) {
- title = "Поиск: " + StringEscapeUtils.escapeHtml4(paramSearch);
- mids = MessagesQueries.getSearch(sql, sqlSearch, Utils.encodeSphinx(paramSearch), paramBefore);
- } else if (paramShow == null) {
- if (visitor.getUid() > 0) {
- title = "Популярные";
- mids = MessagesQueries.getPopular(sql, visitor.getUid(), paramBefore);
- } else {
- title = "Микроблоги Juick: популярные записи";
- mids = MessagesQueries.getPopular(sql, 0, paramBefore);
- }
-
- } else if (paramShow.equals("top")) {
- Utils.sendPermanentRedirect(response, "/");
- return;
- } else if (paramShow.equals("my") && visitor != null) {
- title = "Моя лента";
- mids = MessagesQueries.getMyFeed(sql, visitor.getUid(), paramBefore);
- } else if (paramShow.equals("private") && visitor != null) {
- title = "Приватные";
- mids = MessagesQueries.getPrivate(sql, visitor.getUid(), paramBefore);
- } else if (paramShow.equals("discuss") && visitor != null) {
- title = "Обсуждения";
- mids = MessagesQueries.getDiscussions(sql, visitor.getUid(), paramBefore);
- } else if (paramShow.equals("recommended") && visitor != null) {
- title = "Рекомендации";
- mids = MessagesQueries.getRecommended(sql, visitor.getUid(), paramBefore);
- } else if (paramShow.equals("photos")) {
- title = "Фотографии";
- if (visitor != null) {
- mids = MessagesQueries.getPhotos(sql, visitor.getUid(), paramBefore);
- } else {
- mids = MessagesQueries.getPhotos(sql, 0, paramBefore);
- }
- } else if (paramShow.equals("all")) {
- title = "Все сообщения";
- if (visitor != null) {
- mids = MessagesQueries.getAll(sql, visitor.getUid(), paramBefore);
- } else {
- mids = MessagesQueries.getAll(sql, 0, paramBefore);
- }
- } else {
- Errors.doGet404(sql, request, response);
- return;
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- String head = StringUtils.EMPTY;
- if (paramBefore > 0 || paramShow != null) {
- head = " ";
- }
- PageTemplates.pageHead(out, visitor, title, head);
- PageTemplates.pageNavigation(out, visitor, paramSearch);
-
- out.println("");
-
- if (paramShow == null && paramBefore == 0) {
- out.println("");
- }
-
- if (visitor.getUid() > 0) {
- out.println("");
- }
-
- if (mids.size() > 0) {
- int ad_mid = 0;
- if (paramShow == null || paramShow.equals("top") || paramShow.equals("all")) {
- int vuid = visitor.getUid();
- ad_mid = AdsQueries.getAdMID(sql, vuid);
- if (ad_mid > 0 && mids.indexOf(ad_mid) == -1) {
- mids.add(0, ad_mid);
- AdsQueries.logAdMID(sql, vuid, ad_mid);
- } else {
- ad_mid = 0;
- }
- }
-
- PageTemplates.printMessages(out, sql, null, mids, visitor, visitor.getUid() == 0 ? 2 : 3, ad_mid);
- }
-
- if (mids.size() >= 20) {
- String nextpage = "?before=" + mids.get(mids.size() - 1);
- if (paramShow != null) {
- nextpage += "&show=" + paramShow;
- }
- if (paramSearch != null) {
- nextpage += "&search=" + URLEncoder.encode(paramSearch, CharEncoding.UTF_8);
- }
-
- out.println("Читать дальше →
");
- }
-
- if (paramShow == null && paramBefore == 0) {
- out.println("");
- }
-
- out.println(" ");
-
- PageTemplates.pageHomeColumn(out, sql, visitor, paramShow == null && paramBefore == 0 && paramSearch == null && visitor.getUid() == 0);
-
- PageTemplates.pageFooter(request, out, visitor, true);
- PageTemplates.pageEnd(out);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/Login.java b/juick-www/src/main/java/com/juick/www/Login.java
deleted file mode 100644
index 27f34c1c..00000000
--- a/juick-www/src/main/java/com/juick/www/Login.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * 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.www;
-
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class Login {
-
- protected void doGetLoginForm(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0) {
- Utils.sendTemporaryRedirect(response, "/");
- return;
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- out.println("");
- out.println("");
- out.println("");
- out.println("Juick ");
- out.println("");
- out.println("");
- out.println(" ");
- out.println("");
-
- out.println("");
-
- out.println("");
-
- out.println("");
-
- out.println("");
- out.println(" Зарегистрироваться:");
- out.println("
");
- out.println("
");
- out.println("
XMPP ");
- out.println("
");
- out.println("
");
- out.println("
");
- out.println("");
-
- out.println("");
- out.println("");
- }
- }
-
- protected void doGetLogin(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String hash = request.getQueryString();
- if (hash.length() > 32) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- if (com.juick.server.UserQueries.getUIDbyHash(sql, hash) > 0) {
- Cookie c = new Cookie("hash", hash);
- c.setMaxAge(365 * 24 * 60 * 60);
- response.addCookie(c);
- response.sendRedirect("/");
- } else {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
- }
-
- protected void doPostLogin(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String username = request.getParameter("username");
- String password = request.getParameter("password");
- if (username == null || password == null || username.length() > 32 || password.isEmpty()) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- int uid = com.juick.server.UserQueries.checkPassword(sql, username, password);
- if (uid > 0) {
- String hash = com.juick.server.UserQueries.getHashByUID(sql, uid);
- Cookie c = new Cookie("hash", hash);
- c.setMaxAge(365 * 24 * 60 * 60);
- response.addCookie(c);
-
- String referer = request.getHeader("Referer");
- if (referer != null && referer.startsWith("http://juick.com/") && !referer.equals("http://juick.com/login")) {
- response.sendRedirect(referer);
- } else {
- response.sendRedirect("/");
- }
- } else {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
- }
-
- protected void doGetLogout(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0) {
- sql.update("DELETE FROM logins WHERE user_id=?", visitor.getUid());
- }
-
- Cookie c = new Cookie("hash", "-");
- c.setDomain(".juick.com");
- c.setMaxAge(0);
- response.addCookie(c);
-
- Cookie c2 = new Cookie("hash", "-");
- c2.setMaxAge(0);
- response.addCookie(c2);
-
- response.sendRedirect("/");
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/Main.java b/juick-www/src/main/java/com/juick/www/Main.java
deleted file mode 100644
index 4fb13290..00000000
--- a/juick-www/src/main/java/com/juick/www/Main.java
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.Message;
-import com.juick.server.UserQueries;
-import com.mitchellbosecke.pebble.error.PebbleException;
-import org.apache.commons.dbcp2.BasicDataSource;
-import org.apache.commons.lang3.BooleanUtils;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.springframework.jdbc.core.JdbcTemplate;
-import rocks.xmpp.addr.Jid;
-import rocks.xmpp.core.XmppException;
-import rocks.xmpp.core.session.Extension;
-import rocks.xmpp.core.session.XmppSessionConfiguration;
-import rocks.xmpp.core.session.debug.LogbackDebugger;
-import rocks.xmpp.extensions.component.accept.ExternalComponent;
-import ru.sape.Sape;
-
-import javax.servlet.ServletException;
-import javax.servlet.annotation.MultipartConfig;
-import javax.servlet.annotation.WebServlet;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URLEncoder;
-import java.util.Objects;
-import java.util.Properties;
-
-/**
- *
- * @author Ugnich Anton
- */
-@WebServlet(name = "Main", urlPatterns = {"/"})
-@MultipartConfig(fileSizeThreshold = 1024 * 1024, maxRequestSize = 1024 * 1024 * 10)
-public class Main extends HttpServlet {
-
- JdbcTemplate sql;
- JdbcTemplate sqlSearch;
- String sqlSearchConnStr = "jdbc:mysql://127.0.0.1:9306?autoReconnect=true&useUnicode=yes&characterEncoding=utf8&maxAllowedPacket=512000";
- ExternalComponent xmpp;
- Home home = new Home();
- Discover discover = new Discover();
- PM pm = new PM();
- Login login = new Login();
- Help help = new Help();
- User pagesUser = new User();
- UserThread pagesUserThread = new UserThread();
- NewMessage pagesNewMessage;
- XMPPPost xmppPost = new XMPPPost();
- FacebookLogin loginFacebook;
- VKontakteLogin loginVK = new VKontakteLogin();
- TwitterAuth twitterAuth;
- SignUp signup = new SignUp();
- Settings settings;
- RSS rss = new RSS();
-
- @Override
- public void init() throws ServletException {
-
- super.init();
- try {
- Properties conf = new Properties();
- conf.load(getServletContext().getResourceAsStream("/WEB-INF/juick.conf"));
-
- BasicDataSource dataSource = new BasicDataSource();
- dataSource.setDriverClassName(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver"));
- dataSource.setUrl(conf.getProperty("datasource_url"));
- BasicDataSource dataSourceSearch = new BasicDataSource();
- dataSourceSearch.setDriverClassName(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver"));
- dataSourceSearch.setUrl(sqlSearchConnStr);
- sql = new JdbcTemplate(dataSource);
- sqlSearch = new JdbcTemplate(dataSourceSearch);
- boolean isXmppDisabled = BooleanUtils.toBoolean(conf.getProperty("xmpp_disabled"));
- if (!isXmppDisabled) {
- setupXmppComponent(Jid.of(conf.getProperty("www_xmpp_jid", "www.juick.local")),
- conf.getProperty("xmpp_password"), NumberUtils.toInt(conf.getProperty("xmpp_port", StringUtils.EMPTY), 5347));
- }
- twitterAuth = new TwitterAuth(conf.getProperty("twitter_consumer_key"),
- conf.getProperty("twitter_consumer_secret"));
- loginFacebook = new FacebookLogin(conf.getProperty("facebook_appid"), conf.getProperty("facebook_secret"));
- String tmpDir = conf.getProperty("upload_tmp_dir", "/var/www/juick.com/i/tmp/");
- Utils.setTmpDir(tmpDir);
- String imgPath = conf.getProperty("img_path", "/var/www/juick.com/i/");
- pagesNewMessage = new NewMessage(tmpDir, imgPath);
- settings = new Settings(imgPath);
- String sapeUser = conf.getProperty("sape_user", StringUtils.EMPTY);
- if (!Objects.equals(sapeUser, StringUtils.EMPTY)) {
- PageTemplates.sape = new Sape(sapeUser, "juick.com", 2000, 3600);
- } else {
- log("Sape is not initialized");
- }
- } catch (Exception e) {
- log(null, e);
- }
- }
-
- @Override
- public void destroy() {
- try {
- if (xmpp != null)
- xmpp.close();
- log("ExternalComponent on WWW destroyed");
- } catch (Exception e) {
- log("exception on destroy", e);
- }
- }
-
- public void setupXmppComponent(final Jid componentJid, final String password, final int port) {
- XmppSessionConfiguration configuration = XmppSessionConfiguration.builder()
- .extensions(Extension.of(Message.class))
- .debugger(LogbackDebugger.class)
- .build();
- xmpp = ExternalComponent.create(componentJid.toString(), password, configuration, "localhost", port);
- xmpp.addConnectionListener(e -> log(e.toString(), e.getCause()));
- try {
- xmpp.connect();
- } catch (XmppException e) {
- log("xmpp extension", e);
- }
- }
-
- /**
- * Handles the HTTP GET
method.
- * @param request servlet request
- * @param response servlet response
- * @throws ServletException if a servlet-specific error occurs
- * @throws IOException if an I/O error occurs
- */
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- if (request.getCharacterEncoding() == null) {
- request.setCharacterEncoding(CharEncoding.UTF_8);
- }
- String uri = request.getRequestURI();
-
- if (uri.equals("/")) {
- String tag = request.getParameter("tag");
- if (tag != null) {
- Utils.sendPermanentRedirect(response, "/tag/" + URLEncoder.encode(tag, CharEncoding.UTF_8));
- } else {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- home.doGet(sql, sqlSearch, request, response, visitor);
- }
- } else if (uri.equals("/post")) {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0) {
- pagesNewMessage.doGetNewMessage(sql, request, response, visitor);
- } else {
- Utils.sendTemporaryRedirect(response, "/login");
- }
- } else if (uri.equals("/login")) {
- if (request.getQueryString() == null) {
- login.doGetLoginForm(sql, request, response);
- } else {
- login.doGetLogin(sql, request, response);
- }
- } else if (uri.startsWith("/pm/")) {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() == 0) {
- Utils.sendTemporaryRedirect(response, "/login");
- } else {
- switch (uri) {
- case "/pm/inbox":
- try {
- pm.doGetInbox(sql, request, response, visitor);
- } catch (PebbleException e) {
- log("pebble exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- break;
- case "/pm/sent":
- try {
- pm.doGetSent(sql, request, response, visitor);
- } catch (PebbleException e) {
- log("pebble exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- break;
- default:
- Errors.doGet404(sql, request, response);
- break;
- }
- }
- } else if (uri.startsWith("/rss/")) {
- String uname = uri.substring(5);
- int uid = UserQueries.getUIDbyName(sql, uname);
- if (uid > 0) {
- try {
- rss.doGet(sql, response, uid);
- } catch (PebbleException e) {
- log("pebble exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- } else {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- }
- } else if (uri.equals("/logout")) {
- login.doGetLogout(sql, request, response);
- } else if (uri.equals("/settings")) {
- try {
- settings.doGet(sql, request, response);
- } catch (PebbleException e) {
- log("pebble exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- } else if (uri.equals("/_fblogin")) {
- loginFacebook.doGet(sql, request, response);
- } else if (uri.equals("/_vklogin")) {
- loginVK.doGet(sql, request, response);
- } else if (uri.startsWith("/_twitter")) {
- twitterAuth.doGet(sql, request, response);
- } else if (uri.equals("/signup")) {
- try {
- signup.doGet(sql, request, response);
- } catch (PebbleException e) {
- log("pebble exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- } else if (uri.equals("/help") || uri.equals("/help/")) {
- help.doRedirectToHelpIndex(response);
- } else if (uri.startsWith("/help/")) {
- try {
- help.doGetHelp(sql, request, response);
- } catch (PebbleException e) {
- log("pebble exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- } catch (URISyntaxException e) {
- log("help exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- } else if (uri.startsWith("/tag/")) {
- discover.doGet(sql, sqlSearch, request, response);
- } else if (uri.matches("^/\\d+$")) {
- String strID = request.getRequestURI().substring(1);
- int mid = 0;
- try {
- mid = Integer.parseInt(strID);
- } catch (NumberFormatException e) {
- }
- if (mid > 0) {
- com.juick.User author = com.juick.server.MessagesQueries.getMessageAuthor(sql, mid);
- if (author != null) {
- Utils.sendPermanentRedirect(response, "/" + author.getName() + "/" + mid);
- return;
- }
- }
- Errors.doGet404(sql, request, response);
- } else if (uri.matches("^/[^/]+$")) {
- com.juick.User user = com.juick.server.UserQueries.getUserByName(sql, request.getRequestURI().substring(1));
- if (user != null) {
- Utils.sendPermanentRedirect(response, "/" + user.getName() + "/");
- } else {
- Errors.doGet404(sql, request, response);
- }
- } else if (uri.matches("^/.+/.*")) {
- String uriparts[] = uri.split("/");
- com.juick.User user = com.juick.server.UserQueries.getUserByName(sql, uriparts[1]);
- if (user != null && user.getName().equals(uriparts[1]) && !user.isBanned()) {
- if (uriparts.length == 2) { // http://juick.com/username/
- pagesUser.doGetBlog(sql, sqlSearch, request, response, user);
- } else if (uriparts[2].equals("tags")) {
- pagesUser.doGetTags(sql, request, response, user);
- } else if (uriparts[2].equals("friends")) {
- pagesUser.doGetFriends(sql, request, response, user);
- } else if (uriparts[2].equals("readers")) {
- pagesUser.doGetReaders(sql, request, response, user);
- } else {
- int mid = 0;
- try {
- mid = Integer.parseInt(uriparts[2]);
- } catch (NumberFormatException e) {
- }
- if (mid > 0) {
- com.juick.User author = com.juick.server.MessagesQueries.getMessageAuthor(sql, mid);
- if (author != null) {
- if (!author.getName().equals(user.getName())) {
- Utils.sendPermanentRedirect(response, "/" + author.getName() + "/" + mid);
- } else {
- pagesUserThread.doGetThread(sql, request, response, mid);
- }
- } else {
- Errors.doGet404(sql, request, response);
- }
- } else {
- Errors.doGet404(sql, request, response);
- }
- }
- } else if (user != null && !user.isBanned()) {
- Utils.sendPermanentRedirect(response, "/" + user.getName() + "/" + (uriparts.length > 2 ? uriparts[2] : StringUtils.EMPTY));
- } else {
- Errors.doGet404(sql, request, response);
- }
- } else {
- Errors.doGet404(sql, request, response);
- }
- }
-
- /**
- * Handles the HTTP POST
method.
- * @param request servlet request
- * @param response servlet response
- * @throws ServletException if a servlet-specific error occurs
- * @throws IOException if an I/O error occurs
- */
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- if (request.getCharacterEncoding() == null) {
- request.setCharacterEncoding(CharEncoding.UTF_8);
- }
-
- String uri = request.getRequestURI();
- switch (uri) {
- case "/post": {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0 && !visitor.isBanned()) {
- pagesNewMessage.doPostMessage(sql, request, response, xmpp, visitor);
- } else {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
- break;
- }
- case "/comment": {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0 && !visitor.isBanned()) {
- pagesNewMessage.doPostComment(sql, request, response, xmpp, visitor);
- } else {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
- break;
- }
- case "/like": {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0 && !visitor.isBanned()) {
- pagesNewMessage.doPostRecomm(sql, request, response, xmpp, visitor);
- } else {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
- break;
- }
- case "/pm/send": {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0 && !visitor.isBanned()) {
- pm.doPostPM(sql, request, response, xmpp, visitor);
- } else {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
- break;
- }
- case "/login":
- login.doPostLogin(sql, request, response);
- break;
- case "/signup":
- signup.doPost(sql, request, response);
- break;
- case "/settings":
- try {
- settings.doPost(sql, request, response);
- } catch (PebbleException e) {
- log("pebble exception", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- break;
- case "/post2":
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() > 0 && !visitor.isBanned()) {
- xmppPost.doPostMessage(sql, request, response, xmpp, visitor);
- } else {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- }
- break;
- default:
- response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
- break;
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/NewMessage.java b/juick-www/src/main/java/com/juick/www/NewMessage.java
deleted file mode 100644
index 43ea039c..00000000
--- a/juick-www/src/main/java/com/juick/www/NewMessage.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.Tag;
-import com.juick.server.*;
-import com.juick.server.helpers.TagStats;
-import net.coobird.thumbnailator.Thumbnails;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.core.JdbcTemplate;
-import rocks.xmpp.addr.Jid;
-import rocks.xmpp.core.session.XmppSession;
-import rocks.xmpp.core.stanza.model.Message;
-import rocks.xmpp.extensions.nick.model.Nickname;
-import rocks.xmpp.extensions.oob.model.x.OobX;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLEncoder;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.List;
-
-/**
- * @author Ugnich Anton
- */
-public class NewMessage {
-
- private static final Logger logger = LoggerFactory.getLogger(NewMessage.class);
-
- private String tmpDir, imgDir;
-
- public NewMessage(String tmpDir, String imgDir) {
- this.tmpDir = tmpDir;
- this.imgDir = imgDir;
- }
-
- protected void doGetNewMessage(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response,
- com.juick.User visitor) throws ServletException, IOException {
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PageTemplates.pageHead(out, visitor, "Написать", ""
- + ""
- + ""
- + "");
- PageTemplates.pageNavigation(out, visitor, null);
-
- out.println("");
-
- PageTemplates.pageFooter(request, out, visitor, false);
- PageTemplates.pageEnd(out);
- }
- }
-
- void printUserTags(JdbcTemplate sql, PrintWriter out, com.juick.User visitor) {
- List tags = TagQueries.getTagsStats(sql, visitor.getUid());
-
- if (tags.isEmpty()) {
- return;
- }
-
- int min = tags.get(0).getUsageCount();
- int max = tags.get(0).getUsageCount();
- for (int i = 1; i < tags.size(); i++) {
- int usagecnt = tags.get(i).getUsageCount();
- if (usagecnt < min) {
- min = usagecnt;
- }
- if (usagecnt > max) {
- max = usagecnt;
- }
- }
- max -= min;
-
- out.print("");
- for (int i = 0; i < tags.size(); i++) {
- if (i > 0) {
- out.print(" ");
- }
- String taglink = StringUtils.EMPTY;
- try {
- taglink = "" + StringEscapeUtils.escapeHtml4(tags.get(i).getTag().getName()) + " ";
- } catch (UnsupportedEncodingException e) {
- }
- int usagecnt = tags.get(i).getUsageCount();
- if (usagecnt <= max / 5 + min) {
- out.print("" + taglink + " ");
- } else if (usagecnt <= max / 5 * 2 + min) {
- out.print(taglink);
- } else if (usagecnt <= max / 5 * 3 + min) {
- out.print("" + taglink + " ");
- } else if (usagecnt <= max / 5 * 4 + min) {
- out.print("" + taglink + " ");
- } else {
- out.print("" + taglink + " ");
- }
- }
- out.println("
");
- }
-
- public void doPostMessage(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, XmppSession xmpp, com.juick.User visitor) throws ServletException, IOException {
- String body = request.getParameter("body");
- if (body == null || body.length() < 1 || body.length() > 4096) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- body = body.replace("\r", StringUtils.EMPTY);
-
- List tags = Utils.parseTags(sql, request.getParameter("tags"));
-
- String attachmentFName;
- try {
- attachmentFName = Utils.receiveAttachment(request.getPart("attach"), request.getParameter("img"));
- } catch (Exception e) {
- logger.error("MULTIPART ERROR", e);
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- String attachmentType = attachmentFName != null ? attachmentFName.substring(attachmentFName.length() - 3) : null;
- int mid = MessagesQueries.createMessage(sql, visitor.getUid(), body, attachmentType, tags);
- SubscriptionsQueries.subscribeMessage(sql, mid, visitor.getUid());
-
- Message xmsg = new Message();
- xmsg.setFrom(Jid.of("juick@juick.com"));
- xmsg.setType(Message.Type.CHAT);
- xmsg.setThread("juick-" + mid);
- com.juick.Message jmsg = MessagesQueries.getMessage(sql, mid);
- xmsg.addExtension(jmsg);
- xmsg.addExtension(new Nickname("@" + jmsg.getUser().getName()));
-
- if (attachmentFName != null) {
- String fname = mid + "." + attachmentType;
- String attachmentURL = "http://i.juick.com/photos-1024/" + fname;
-
- Path origName = Paths.get(imgDir, "p", fname);
- Files.move(Paths.get(tmpDir, attachmentFName), origName);
- Thumbnails.of(origName.toFile()).size(1024, 1024).outputQuality(0.9)
- .toFile(Paths.get(imgDir, "photos-1024", fname).toFile());
- Thumbnails.of(origName.toFile()).size(512, 512).outputQuality(0.9)
- .toFile(Paths.get(imgDir, "photos-512", fname).toFile());
- Thumbnails.of(origName.toFile()).size(160, 120).outputQuality(0.9)
- .toFile(Paths.get(imgDir, "ps", fname).toFile());
-
- body = attachmentURL + "\n" + body;
- try {
- xmsg.addExtension(new OobX(new URI(attachmentURL)));
- } catch (URISyntaxException e) {
- logger.warn("invalid uri: {} exception {}", attachmentURL, e);
- }
- }
- if (xmpp != null) {
-
- xmsg.setBody("@" + jmsg.getUser().getName() + ":" + jmsg.getTagsString() + "\n" + body + "\n\n#" + mid + " http://juick.com/" + mid);
-
- xmsg.setTo(Jid.of("juick@s2s.juick.com"));
- xmpp.send(xmsg);
-
- xmsg.setTo(Jid.of("juick@ws.juick.com"));
- xmpp.send(xmsg);
-
- xmsg.setTo(Jid.of("juick@push.juick.com"));
- xmpp.send(xmsg);
-
- xmsg.setTo(Jid.of("twitter@crosspost.juick.com"));
- xmpp.send(xmsg);
- xmsg.setTo(Jid.of("fb@crosspost.juick.com"));
- xmpp.send(xmsg);
-
- xmsg.setTo(Jid.of("jubo@nologin.ru"));
- xmpp.send(xmsg);
- } else {
- logger.warn("XMPP unavailable");
- }
-
- //
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PageTemplates.pageHead(out, visitor, "Сообщение опубликовано", null);
- PageTemplates.pageNavigation(out, visitor, null);
-
- String hashtags = StringUtils.EMPTY;
- String tagscomma = StringUtils.EMPTY;
- for (int i = 0; i < jmsg.getTags().size(); i++) {
- if (i > 0) {
- hashtags += " ";
- tagscomma += ",";
- }
- hashtags += "#" + jmsg.getTags().get(i);
- tagscomma += jmsg.getTags().get(i);
- }
-
- String url = URLEncoder.encode("http://juick.com/" + mid, CharEncoding.UTF_8);
- String sharetwi = hashtags + " " + body;
- if (sharetwi.length() > 115) {
- sharetwi = sharetwi.substring(0, 114) + "…";
- }
- sharetwi += " http://juick.com/" + mid;
- String sharelj = URLEncoder.encode(body + "\n", CharEncoding.UTF_8) + url;
-
- out.println("");
- out.println("Сообщение опубликовано ");
- out.println("Поделитесь своим новым постом в социальных сетях:
");
- if (CrosspostQueries.getTwitterTokens(sql, visitor.getUid()).isPresent()) {
- out.println("Отправить в Twitter
");
- }
- out.println("Отправить в LiveJournal
");
- out.println("Отправить в ВКонтакте
");
- if (CrosspostQueries.getFacebookToken(sql, visitor.getUid()).isPresent()) {
- out.println("Отправить в Facebook
");
- }
- out.println("Отправить в Google+
");
- out.println("Ссылка на сообщение: http://juick.com/" + mid + "
");
- out.println(" ");
-
- PageTemplates.pageHomeColumn(out, sql, visitor);
-
- PageTemplates.pageFooter(request, out, visitor, false);
- PageTemplates.pageEnd(out);
- }
- }
-
- public void doPostComment(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, XmppSession xmpp, com.juick.User visitor) throws ServletException, IOException {
- int mid = NumberUtils.toInt(request.getParameter("mid"), 0);
- if (mid == 0) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- com.juick.Message msg = MessagesQueries.getMessage(sql, mid);
- if (msg == null) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
-
- int rid = NumberUtils.toInt(request.getParameter("rid"), 0);
- com.juick.Message reply = null;
- if (rid > 0) {
- reply = MessagesQueries.getReply(sql, mid, rid);
- if (reply == null) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
- }
-
- String body = request.getParameter("body");
- if (body == null || body.length() < 1 || body.length() > 4096) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- body = body.replace("\r", StringUtils.EMPTY);
-
- if ((msg.ReadOnly && msg.getUser().getUid() != visitor.getUid()) || UserQueries.isInBLAny(sql, msg.getUser().getUid(), visitor.getUid()) || (reply != null && UserQueries.isInBLAny(sql, reply.getUser().getUid(), visitor.getUid()))) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
-
- String attachmentFName = null;
- try {
- attachmentFName = Utils.receiveMultiPartFile(request.getPart("attach"));
- } catch (Exception e) {
- logger.error("MULTIPART ERROR", e);
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- String paramImg = request.getParameter("img");
- if (attachmentFName == null && paramImg != null && paramImg.length() > 10) {
- try {
- attachmentFName = Utils.downloadImage(new URL(paramImg));
- } catch (Exception e) {
- logger.error("DOWNLOAD ERROR", e);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
- }
-
- String attachmentType = attachmentFName != null ? attachmentFName.substring(attachmentFName.length() - 3) : null;
- int ridnew = MessagesQueries.createReply(sql, mid, rid, visitor.getUid(), body, attachmentType);
- SubscriptionsQueries.subscribeMessage(sql, mid, visitor.getUid());
-
- Message xmsg = new Message();
- xmsg.setFrom(Jid.of("juick@juick.com"));
- xmsg.setType(Message.Type.CHAT);
- xmsg.setThread("juick-" + mid);
-
- com.juick.Message jmsg = MessagesQueries.getReply(sql, mid, ridnew);
- xmsg.addExtension(jmsg);
-
- String quote = reply != null ? reply.getText() : msg.getText();
- if (quote.length() >= 50) {
- quote = quote.substring(0, 47) + "...";
- }
- xmsg.addExtension(new Nickname("@" + jmsg.getUser().getName()));
-
- if (attachmentFName != null) {
- String fname = mid + "-" + ridnew + "." + attachmentType;
- String attachmentURL = "http://i.juick.com/photos-1024/" + fname;
-
- Path origName = Paths.get(imgDir, "p", fname);
- Files.move(Paths.get(tmpDir, attachmentFName), origName);
- Thumbnails.of(origName.toFile()).size(1024, 1024).outputQuality(0.9)
- .toFile(Paths.get(imgDir, "photos-1024", fname).toFile());
- Thumbnails.of(origName.toFile()).size(512, 512).outputQuality(0.9)
- .toFile(Paths.get(imgDir, "photos-512", fname).toFile());
- Thumbnails.of(origName.toFile()).size(160, 120).outputQuality(0.9)
- .toFile(Paths.get(imgDir, "ps", fname).toFile());
-
- body = attachmentURL + "\n" + body;
- try {
- xmsg.addExtension(new OobX(new URI(attachmentURL)));
- } catch (URISyntaxException e) {
- logger.warn("invalid uri: {}, exception {}", attachmentURL, e);
- }
- }
-
- if (xmpp != null) {
-
- xmsg.setBody("Reply by @" + jmsg.getUser().getName() + ":\n>" + quote + "\n" + body + "\n\n#" +
- mid + "/" + ridnew + " http://juick.com/" + mid + "#" + ridnew);
-
- xmsg.setTo(Jid.of("juick@s2s.juick.com"));
- xmpp.send(xmsg);
-
- xmsg.setTo(Jid.of("juick@ws.juick.com"));
- xmpp.send(xmsg);
-
- xmsg.setTo(Jid.of("juick@push.juick.com"));
- xmpp.send(xmsg);
- } else {
- logger.warn("XMPP unavailable");
- }
-
- Utils.sendTemporaryRedirect(response, "/" + msg.getUser().getName() + "/" + mid + "#" + ridnew);
- }
-
- public void doPostRecomm(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, XmppSession xmpp, com.juick.User visitor) throws ServletException, IOException {
- int mid = NumberUtils.toInt(request.getParameter("mid"), 0);
- if (mid == 0) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- com.juick.Message msg = MessagesQueries.getMessage(sql, mid);
- if (msg == null) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
- if (msg.getUser().getUid() == visitor.getUid()) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
-
- boolean res = MessagesQueries.recommendMessage(sql, mid, visitor.getUid());
-
- if (res) {
- if (xmpp != null) {
- Message xmsg = new Message();
- xmsg.setFrom(Jid.of("juick@juick.com"));
- xmsg.setTo(Jid.of("recomm@s2s.juick.com"));
- com.juick.Message jmsg = new com.juick.Message();
- jmsg.setMid(mid);
- jmsg.setUser(visitor);
- xmsg.addExtension(jmsg);
- xmpp.send(xmsg);
- } else {
- logger.warn("XMPP unavailable");
- }
-
- Utils.replyJSON(request, response, "{\"status\":\"ok\"}");
- } else {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/PM.java b/juick-www/src/main/java/com/juick/www/PM.java
deleted file mode 100644
index d0aa26e9..00000000
--- a/juick-www/src/main/java/com/juick/www/PM.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.server.PMQueries;
-import com.juick.server.TagQueries;
-import com.juick.server.UserQueries;
-import com.juick.util.MessageUtils;
-import com.juick.util.WebUtils;
-import com.mitchellbosecke.pebble.error.PebbleException;
-import com.mitchellbosecke.pebble.template.PebbleTemplate;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.core.JdbcTemplate;
-import rocks.xmpp.addr.Jid;
-import rocks.xmpp.core.session.XmppSession;
-import rocks.xmpp.core.stanza.model.Message;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class PM {
- private static final Logger logger = LoggerFactory.getLogger(PM.class);
-
- protected void doGetInbox(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException, PebbleException {
-
- String title = "PM: Inbox";
- List msgs = PMQueries.getLastPMInbox(sql, visitor.getUid());
- msgs.forEach(m -> m.setText(MessageUtils.formatMessage(m.getText())));
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate("views/pm_inbox.html");
- Map context = new HashMap<>();
- context.put("title", title);
- context.put("visitor", visitor);
- context.put("msgs", msgs);
- context.put("tags", TagQueries.getPopularTags(sql));
- template.evaluate(out, context);
- }
- }
-
- protected void doGetSent(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException, PebbleException {
-
- String title = "PM: Sent";
- List msgs = PMQueries.getLastPMSent(sql, visitor.getUid());
-
- String uname = request.getParameter("uname");
- if (WebUtils.isNotUserName(uname)) {
- uname = StringUtils.EMPTY;
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate("views/pm_sent.html");
- Map context = new HashMap<>();
- context.put("title", title);
- context.put("visitor", visitor);
- context.put("msgs", msgs);
- context.put("tags", TagQueries.getPopularTags(sql));
- context.put("uname", uname);
- template.evaluate(out, context);
- }
- }
-
- public void doPostPM(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, XmppSession xmpp, com.juick.User visitor) throws ServletException, IOException {
- String uname = request.getParameter("uname");
- if (uname.startsWith("@")) {
- uname = uname.substring(1);
- }
- int uid = 0;
- if (WebUtils.isUserName(uname)) {
- uid = UserQueries.getUIDbyName(sql, uname);
- }
-
- String body = request.getParameter("body");
- if (uid == 0 || body == null || body.length() < 1 || body.length() > 10240) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- if (UserQueries.isInBLAny(sql, uid, visitor.getUid())) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
-
- if (PMQueries.createPM(sql, visitor.getUid(), uid, body)) {
- if (xmpp != null) {
- Message msg = new Message();
- msg.setFrom(Jid.of("juick@juick.com"));
- msg.setTo(Jid.of(String.format("%d@push.juick.com", uid)));
- com.juick.Message jmsg = new com.juick.Message();
- jmsg.setUser(visitor);
- jmsg.setText(body);
- msg.addExtension(jmsg);
- xmpp.send(msg);
-
- msg.setTo(Jid.of(String.format("%d@ws.juick.com", uid)));
- xmpp.send(msg);
-
- List jids = UserQueries.getJIDsbyUID(sql, uid);
- for (String jid : jids) {
- Message mm = new Message();
- mm.setTo(Jid.of(jid));
- mm.setType(Message.Type.CHAT);
- if (PMQueries.havePMinRoster(sql, visitor.getUid(), jid)) {
- mm.setFrom(Jid.of(jmsg.getUser().getName(), "juick.com", "Juick"));
- mm.setBody(body);
- } else {
- mm.setFrom(Jid.of("juick", "juick.com", "Juick"));
- mm.setBody("Private message from @" + jmsg.getUser().getName() + ":\n" + body);
- }
- xmpp.send(mm);
- }
- } else {
- logger.warn("XMPP unavailable");
- }
-
- Utils.sendTemporaryRedirect(response, "/pm/sent");
-
- } else {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/PageTemplates.java b/juick-www/src/main/java/com/juick/www/PageTemplates.java
deleted file mode 100644
index 4a625acc..00000000
--- a/juick-www/src/main/java/com/juick/www/PageTemplates.java
+++ /dev/null
@@ -1,374 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.Message;
-import com.juick.server.MessagesQueries;
-import com.juick.server.TagQueries;
-import com.juick.server.UserQueries;
-import com.juick.server.helpers.TagStats;
-import com.juick.util.MessageUtils;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.util.StringUtils;
-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.stream.Collectors;
-
-/**
- * @author Ugnich Anton
- */
-public class PageTemplates {
-
- private static final Logger logger = LoggerFactory.getLogger(PageTemplates.class);
-
- public static Sape sape = null;
- protected 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, com.juick.User visitor, String title, String headers) {
- out.println("");
- out.print("");
- out.print("");
- out.println(" ");
- out.print(" ");
- out.print("");
- if (headers != null) {
- out.print(headers);
- }
- out.print("" + title + " ");
- out.println(" ");
- out.println(" ");
- out.println("");
- out.println("");
- out.flush();
- if (visitor.getUid() > 0) {
- out.println("");
- } else {
- out.println("");
- }
- }
-
- public static void pageNavigation(PrintWriter out, com.juick.User visitor, String search) {
- 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.formatPopularTags(sql, 80);
- }
-
- out.println("");
- }
-
- public static String formatPopularTags(JdbcTemplate sql, int cnt) {
- List popularTags = TagQueries.getPopularTags(sql).stream()
- .map(t -> "" + StringEscapeUtils.escapeHtml4(t) + " ").collect(Collectors.toList());
- return StringUtils.collectionToDelimitedString(popularTags, " ");
- }
-
- public static void pageFooter(HttpServletRequest request, PrintWriter out, com.juick.User visitor, boolean sapeon) {
- out.println("");
-
- out.println("");
- }
-
- public static void pageEnd(PrintWriter out) {
- out.println("");
- }
-
- public static String formatTags(List tags) {
- String ret = org.apache.commons.lang3.StringUtils.EMPTY;
- for (TagStats tag : tags) {
- String tagName = StringEscapeUtils.escapeHtml4(tag.getTag().getName());
- try {
- ret += "" + tagName + " ";
- } 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 = sdfFull.format(fulldate);
- synchronized (sdfSQL) {
- try {
- 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);
- }
- } catch (Exception e) {
- logger.error("PARSE EXCEPTION: {}, exception {}", fulldate, e);
- }
- }
- 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 + " ответов";
- }
- }
-
- 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 (Message msg : msgs) {
-
- List tags = MessagesQueries.getMessageTags(sql, msg.getMid());
- String tagsStr = formatTags(tags);
- if (msg.ReadOnly) {
- tagsStr += "readonly ";
- }
- if (msg.getPrivacy() < 0) {
- tagsStr += "friends ";
- }
- if (msg.getMid() == ad_mid) {
- tagsStr += "реклама ";
- }
-
- String txt;
- if (msg.getTags().stream().anyMatch(t -> t.getName().equals("code"))) {
- txt = MessageUtils.formatMessageCode(msg.getText());
- } else {
- txt = MessageUtils.formatMessage(msg.getText());
- }
-
- out.println("");
- out.println(" ");
-
- if (msg.getAttachmentType() != null) {
- String fname = msg.getMid() + "." + msg.getAttachmentType();
- out.println("
");
- }
- out.println(" " + txt + "
");
- if (msg.getAttachmentType() != null) {
- out.println("
");
- }
- out.print(" ");
- msg.ReadOnly |= blUIDs.contains(msg.getUser().getUid());
- if (visitor.getUid() == 0) {
- out.print("Рекомендовать ");
- } else {
- out.print("Рекомендовать ");
- }
- if (visitor.getUid() == 0 && !msg.ReadOnly) {
- out.print("Комментировать ");
- } else if (visitor.getUid() > 0 && (!msg.ReadOnly || visitor.getUid() == msg.getUser().getUid())) {
- out.print(" ");
- }
- if (visitor.getUid() > 0 && msg.getPrivacy() < 0 && msg.getUser().getUid() == visitor.getUid()) {
- out.print(" Открыть доступ ");
- }
- if (visitor.getUid() > 0 && visitor.getUid() == 3694) {
- out.print(" + ");
- out.print(" - ");
- out.print(" x ");
- }
- out.println(" ");
-
- out.print(" ");
- if (msg.getLikes() > 0) {
- out.print(" " + msg.getLikes() + " ");
- }
- if (msg.getReplies() > 0) {
- out.print(" " + msg.getReplies() + " ");
- }
- out.println(" ");
- out.print(" ");
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/RSS.java b/juick-www/src/main/java/com/juick/www/RSS.java
deleted file mode 100644
index 91ba9380..00000000
--- a/juick-www/src/main/java/com/juick/www/RSS.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Juick
- * Copyright (C) 2008-2013, ugnich
- *
- * 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.www;
-
-import com.juick.Message;
-import com.juick.server.MessagesQueries;
-import com.juick.util.DateFormattersHolder;
-import com.juick.util.MessageUtils;
-import com.mitchellbosecke.pebble.error.PebbleException;
-import com.mitchellbosecke.pebble.template.PebbleTemplate;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- *
- * @author ugnich
- */
-public class RSS {
-
- protected void doGet(JdbcTemplate sql, HttpServletResponse response, int uid) throws ServletException, IOException, PebbleException {
- List mids = MessagesQueries.getUserBlog(sql, uid, 0, 0);
- if (mids.isEmpty()) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND);
- return;
- }
-
- List msgs = MessagesQueries.getMessages(sql, mids);
-
- msgs.forEach(m -> MessageUtils.formatMessage(m.getText()));
-
- response.setContentType("application/rss+xml; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate("layouts/rss.xml");
- Map context = new HashMap<>();
- context.put("user", msgs.stream().findFirst().get().getUser());
- context.put("msgs", msgs);
- context.put("sdfRSS", DateFormattersHolder.getRssFormatterInstance());
- template.evaluate(out, context);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/Settings.java b/juick-www/src/main/java/com/juick/www/Settings.java
deleted file mode 100644
index 1b2a6c8d..00000000
--- a/juick-www/src/main/java/com/juick/www/Settings.java
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Juick
- * Copyright (C) 2008-2013, 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.www;
-
-import com.juick.server.CrosspostQueries;
-import com.juick.server.SubscriptionsQueries;
-import com.juick.server.TagQueries;
-import com.juick.server.UserQueries;
-import com.juick.server.helpers.NotifyOpts;
-import com.juick.server.helpers.UserInfo;
-import com.juick.util.UserUtils;
-import com.mitchellbosecke.pebble.error.PebbleException;
-import com.mitchellbosecke.pebble.template.PebbleTemplate;
-import net.coobird.thumbnailator.Thumbnails;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.mail.Message;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.Transport;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class Settings {
- private static final Logger logger = LoggerFactory.getLogger(Settings.class);
- private final String imgPath;
-
- public Settings(String avatarsPath) {
- this.imgPath = avatarsPath;
- }
-
- protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, PebbleException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() == 0) {
- response.sendRedirect("/login");
- }
- List pages = Arrays.asList("main", "password", "about", "auth-email", "privacy");
- String page = request.getParameter("page");
- if (StringUtils.isEmpty(page) || !pages.contains(page)) {
- page = "main";
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate(String.format("views/settings_%s.html", page));
- Map context = new HashMap<>();
- context.put("title", "Настройки");
- context.put("visitor", visitor);
- context.put("tags", TagQueries.getPopularTags(sql));
- context.put("auths", UserQueries.getAuthCodes(sql, visitor));
- context.put("eopts", UserQueries.getEmailOpts(sql, visitor));
- context.put("ehash", UserQueries.getEmailHash(sql, visitor));
- context.put("emails", UserQueries.getEmails(sql, visitor));
- context.put("jids", UserQueries.getAllJIDs(sql, visitor));
- List hours = IntStream.rangeClosed(0, 23).boxed()
- .map(i -> StringUtils.leftPad(String.format("%d", i), 2, "0")).collect(Collectors.toList());
- context.put("hours", hours);
- context.put("fbstatus", CrosspostQueries.isFBCrossPostEnabled(sql, visitor.getUid()));
- context.put("twitter_name", CrosspostQueries.getTwitterName(sql, visitor.getUid()));
- context.put("telegram_name", CrosspostQueries.getTelegramName(sql, visitor.getUid()));
- context.put("notify_options", SubscriptionsQueries.getNotifyOptions(sql, visitor));
- context.put("userinfo", UserQueries.getUserInfo(sql, visitor));
- if (page.equals("auth-email")) {
- try {
- String account = sql.queryForObject("SELECT account FROM auth WHERE user_id=? AND protocol='email' AND authcode=?",
- String.class, visitor.getUid(), request.getParameter("code"));
- sql.update("INSERT INTO emails(user_id,email) VALUES (?,?)", visitor.getUid(), account);
- sql.update("DELETE FROM auth WHERE user_id=? AND authcode=?", visitor.getUid(), request.getParameter("code"));
- context.put("result", "OK!");
- } catch (EmptyResultDataAccessException e) {
- context.put("result", "Sorry, code unknown.");
- }
- }
- template.evaluate(out, context);
- }
- }
-
- protected void doPost(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, PebbleException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- if (visitor.getUid() == 0) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- List pages = Arrays.asList("main", "password", "about", "email", "email-add", "email-del",
- "email-subscr", "auth-email", "privacy", "jid-del", "twitter-del", "telegram-del", "facebook-disable",
- "facebook-enable", "vk-del");
- String page = request.getParameter("page");
- if (StringUtils.isEmpty(page) || !pages.contains(page)) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- String result = StringUtils.EMPTY;
- switch (page) {
- case "password":
- if (UserQueries.updatePassword(sql, visitor, request.getParameter("password"))) {
- result = "Password has been changed.
";
- String hash = com.juick.server.UserQueries.getHashByUID(sql, visitor.getUid());
- Cookie c = new Cookie("hash", hash);
- c.setMaxAge(365 * 24 * 60 * 60);
- response.addCookie(c);
- }
- break;
- case "main":
- NotifyOpts opts = new NotifyOpts();
- opts.setRepliesEnabled(StringUtils.isNotEmpty(request.getParameter("jnotify")));
- opts.setSubscriptionsEnabled(StringUtils.isNotEmpty(request.getParameter("subscr_notify")));
- opts.setRecommendationsEnabled(StringUtils.isNotEmpty(request.getParameter("recomm")));
- if (SubscriptionsQueries.setNotifyOptions(sql, visitor, opts)) {
- result = "Notification options has been updated
";
- }
- break;
- case "about":
- UserInfo info = new UserInfo();
- info.setFullName(request.getParameter("fullname"));
- info.setCountry(request.getParameter("country"));
- info.setUrl(request.getParameter("url"));
- info.setDescription(request.getParameter("descr"));
- String avatarTmpPath = Utils.receiveMultiPartFile(request.getPart("avatar"));
- if (StringUtils.isNotEmpty(avatarTmpPath)) {
- String originalExtension = FilenameUtils.getExtension(avatarTmpPath);
- String originalName = String.format("%s.%s", visitor.getUid(), originalExtension);
- String targetName = String.format("%s.png", visitor.getUid());
- Path ao = Paths.get(imgPath, "ao", originalName);
- Path a = Paths.get(imgPath, "a", targetName);
- Path as = Paths.get(imgPath, "as", targetName);
- Files.move(Paths.get(Utils.getTmpDir(), avatarTmpPath), ao, StandardCopyOption.REPLACE_EXISTING);
- Thumbnails.of(ao.toFile()).size(96, 96).toFile(a.toFile());
- Thumbnails.of(ao.toFile()).size(32, 32).toFile(as.toFile());
- }
- if (UserQueries.updateUserInfo(sql, visitor, info)) {
- result = String.format("Your info is updated.
Back to blog .
", visitor.getName());
- }
- break;
- case "jid-del":
- String[] params = request.getParameter("delete").split(";", 2);
- int res = -1;
- if (params[0].equals("xmpp")) {
- res = sql.update("DELETE FROM jids WHERE user_id=? AND jid=?", visitor.getUid(), params[1]);
- } else if (params[0].equals("xmpp-unauth")) {
- res = sql.update("DELETE FROM auth WHERE user_id=? AND protocol='xmpp' AND account=?", visitor.getUid(), params[1]);
- }
- if (res == 1) {
- result = "Deleted. Back .
";
- } else {
- result = "Error
";
- }
- break;
- case "email":
- String newHash = UserQueries.updateSecretEmail(sql, visitor);
- if (StringUtils.isNotEmpty(newHash)) {
- result = String.format("New secret email: %s@mail.juick.com
" +
- "Back .
", newHash);
- } else {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
- break;
- case "email-add":
- try {
- sql.queryForObject("SELECT authcode FROM auth WHERE user_id=? AND protocol='email' " +
- "AND account=?", String.class, visitor.getUid(), request.getParameter("account"));
- } catch (EmptyResultDataAccessException e) {
- String authCode = UserUtils.generateHash(8);
- if (sql.update("INSERT INTO auth(user_id,protocol,account,authcode) VALUES (?,'email',?,?)",
- visitor.getUid(), request.getParameter("account"), authCode) > 0) {
- Session session = Session.getDefaultInstance(System.getProperties());
- try {
- MimeMessage message = new MimeMessage(session);
- message.setFrom(new InternetAddress("noreply@mail.juick.com"));
- message.addRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("account")));
- message.setSubject("Juick authorization link");
- message.setText(String.format("Follow link to attach this email to Juick account:\n" +
- "http://juick.com/settings?page=auth-email&code=%s\n\n" +
- "If you don't know, what this mean - just ignore this mail.\n", authCode));
- Transport.send(message);
- result = "Authorization link has been sent to your email. Follow it to proceed.
" +
- "Back
";
-
- } catch (MessagingException ex) {
- logger.error("mail exception", ex);
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
- }
- }
- break;
- case "email-del":
- if (sql.update("DELETE FROM emails WHERE user_id=? AND email=?", visitor.getUid(), request.getParameter("account")) > 0) {
- result = "Deleted. Back .
";
- } else {
- result = "An error occured while deleting.
";
- }
- break;
- case "email-subscr":
- sql.update("UPDATE emails SET subscr_hour=NULL WHERE user_id=?", visitor.getUid());
- String email = request.getParameter("account");
- if (StringUtils.isNotEmpty(email)) {
- sql.update("UPDATE emails SET subscr_hour=? WHERE user_id=? AND email=?",
- request.getParameter("time"), visitor.getUid(), email);
- result = String.format("Saved! Will send to %s at %s:00 GMT ." +
- "
Back
", email, request.getParameter("time"));
- } else {
- result = "Disabled.
Back
";
- }
- break;
- case "twitter-del":
- sql.update("DELETE FROM twitter WHERE user_id=?", visitor.getUid());
- sql.update("DELETE FROM subscr_users WHERE user_id=? AND suser_id=1741", visitor.getUid());
- for (Cookie cookie : request.getCookies()) {
- if (cookie.getName().equals("request_token")) {
- cookie.setMaxAge(0);
- response.addCookie(cookie);
- }
- if (cookie.getName().equals("request_token_secret")) {
- cookie.setMaxAge(0);
- response.addCookie(cookie);
- }
- }
- result = "Back
";
- break;
- case "telegram-del":
- sql.update("DELETE FROM telegram WHERE user_id=?", visitor.getUid());
- result = "Back
";
- break;
- case "facebook-disable":
- sql.update("UPDATE facebook SET crosspost=0 WHERE user_id=?", visitor.getUid());
- sql.update("DELETE FROM subscr_users WHERE user_id=? AND suser_id=5863", visitor.getUid());
- result = "Back
";
- break;
- case "facebook-enable":
- sql.update("UPDATE facebook SET crosspost=1 WHERE user_id=?", visitor.getUid());
- sql.update("INSERT INTO subscr_users(user_id,suser_id,jid,active) VALUES (?,5863,'juick@facebook.juick.com',1)", visitor.getUid());
- result = "Back
";
- break;
- case "vk-del":
- sql.update("DELETE FROM vk WHERE user_id=?", visitor.getUid());
- result = "Back
";
- break;
- default:
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate("views/settings_result.html");
- Map context = new HashMap<>();
- context.put("title", "Настройки");
- context.put("visitor", visitor);
- context.put("result", result);
- template.evaluate(out, context);
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/SignUp.java b/juick-www/src/main/java/com/juick/www/SignUp.java
deleted file mode 100644
index ea40c810..00000000
--- a/juick-www/src/main/java/com/juick/www/SignUp.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Juick
- * Copyright (C) 2008-2013, 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.www;
-
-import com.juick.server.UserQueries;
-import com.mitchellbosecke.pebble.error.PebbleException;
-import com.mitchellbosecke.pebble.template.PebbleTemplate;
-import org.apache.commons.lang3.tuple.Pair;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class SignUp {
-
- protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, PebbleException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- String type = request.getParameter("type");
- String hash = request.getParameter("hash");
- if (type == null || type.isEmpty() || hash == null || hash.isEmpty() || hash.length() > 36 || !type.matches("^[a-zA-Z0-9\\-]+$") || !hash.matches("^[a-zA-Z0-9\\-]+$")) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- String account = null;
- switch (type) {
- case "fb":
- account = getFacebookNameByHash(sql, hash);
- break;
- case "vk":
- account = getVKNameByHash(sql, hash);
- break;
- case "xmpp":
- account = getJIDByHash(sql, hash);
- break;
- case "durov":
- account = getTelegramNameByHash(sql, hash);
- break;
- }
- if (account == null) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- PebbleTemplate template = Utils.getEngine().getTemplate("views/signup.html");
- Map context = new HashMap<>();
- context.put("title", "Новый пользователь");
- context.put("visitor", visitor);
- context.put("account", account);
- context.put("type", type);
- context.put("hash", hash);
- template.evaluate(out, context);
- }
- }
-
- protected void doPost(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
- int uid = 0;
-
- String type = request.getParameter("type");
- String hash = request.getParameter("hash");
- if (type == null || type.isEmpty() || hash == null || hash.isEmpty() || hash.length() > 36 || !type.matches("^[a-zA-Z0-9\\-]+$") || !hash.matches("^[a-zA-Z0-9\\-]+$")) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- String action = request.getParameter("action");
- if (action.charAt(0) == 'l') {
-
- if (visitor.getUid() == 0) {
- String username = request.getParameter("username");
- String password = request.getParameter("password");
- if (username == null || password == null || username.length() > 32 || password.isEmpty()) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- uid = com.juick.server.UserQueries.checkPassword(sql, username, password);
- } else {
- uid = visitor.getUid();
- }
-
- if (uid <= 0) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
-
- if (!(type.charAt(0) == 'f' && setFacebookUser(sql, hash, uid))
- && !(type.charAt(0) == 'v' && setVKUser(sql, hash, uid))
- && !(type.charAt(0) == 'd' && setTelegramUser(sql, hash, uid))
- && !(type.charAt(0) == 'x' && setJIDUser(sql, hash, uid))) {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
-
- } else { // Create new account
- String username = request.getParameter("username");
- String password = request.getParameter("password");
- if (username == null || password == null || username.length() < 2 || username.length() > 16 || !username.matches("^[a-zA-Z0-9\\-]+$") || password.length() < 6 || password.length() > 32) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
-
- // CHECK USERNAME
-
- uid = UserQueries.createUser(sql, username, password);
- if (uid <= 0) {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (!(type.charAt(0) == 'f' && setFacebookUser(sql, hash, uid))
- && !(type.charAt(0) == 'v' && setVKUser(sql, hash, uid))
- && !(type.charAt(0) == 'd' && setTelegramUser(sql, hash, uid))
- && !(type.charAt(0) == 'x' && setJIDUser(sql, hash, uid))) {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
-
- int ref = 0;
- String sRef = Utils.getCookie(request, "ref");
- if (sRef != null) {
- try {
- ref = Integer.parseInt(sRef);
- } catch (Exception e) {
- }
- }
-
- if (ref > 0) {
- setUserRef(sql, uid, ref);
- }
-
- visitor = null;
- }
-
- if (visitor == null) {
- hash = com.juick.server.UserQueries.getHashByUID(sql, uid);
- Cookie c = new Cookie("hash", hash);
- c.setMaxAge(365 * 24 * 60 * 60);
- response.addCookie(c);
- }
-
- response.sendRedirect("/");
- }
-
- private boolean setUserRef(JdbcTemplate sql, int uid, int ref) {
- return sql.update("INSERT INTO users_refs(user_id,ref) VALUES (?,?)", uid, ref) > 0;
- }
-
- private String getFacebookNameByHash(JdbcTemplate sql, String hash) {
- try {
- List> fb = sql.query("SELECT fb_name,fb_link FROM facebook WHERE loginhash=?",
- (rs, num) -> Pair.of(rs.getString(1), rs.getString(2)), hash);
- if (fb.size() > 0) {
- return "" + fb.get(0).getLeft() + " ";
- }
- return null;
- } catch (EmptyResultDataAccessException e) {
- return null;
- }
- }
- private String getTelegramNameByHash(JdbcTemplate sql, String hash) {
- try {
- String name = sql.queryForObject("SELECT tg_name FROM telegram WHERE loginhash=?", String.class, hash);
- return "" + name + " ";
- } catch (EmptyResultDataAccessException e) {
- return null;
- }
- }
-
- private boolean setFacebookUser(JdbcTemplate sql, String hash, int uid) {
- return sql.update("UPDATE facebook SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
- }
-
- private String getVKNameByHash(JdbcTemplate sql, String hash) {
- List> logins = sql.query("SELECT vk_name,vk_link FROM vk WHERE loginhash=?",
- (rs, num) -> Pair.of(rs.getString(1), rs.getString(2)), hash);
- if (logins.size() > 0) {
- return "" + logins.get(0).getLeft() + " ";
- }
- return null;
- }
-
- private boolean setVKUser(JdbcTemplate sql, String hash, int uid) {
- return sql.update("UPDATE vk SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
- }
- private boolean setTelegramUser(JdbcTemplate sql, String hash, int uid) {
- return sql.update("UPDATE telegram SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
- }
-
- private String getJIDByHash(JdbcTemplate sql, String hash) {
- try {
- return sql.queryForObject("SELECT jid FROM jids WHERE loginhash=?", String.class, hash);
- } catch (EmptyResultDataAccessException e) {
- return null;
- }
- }
-
- private boolean setJIDUser(JdbcTemplate sql, String hash, int uid) {
- return sql.update("UPDATE jids SET user_id=?,loginhash=NULL WHERE loginhash=?", uid, hash) > 0;
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/TwitterAuth.java b/juick-www/src/main/java/com/juick/www/TwitterAuth.java
deleted file mode 100644
index 35e00efc..00000000
--- a/juick-www/src/main/java/com/juick/www/TwitterAuth.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package com.juick.www;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.github.scribejava.apis.TwitterApi;
-import com.github.scribejava.core.builder.ServiceBuilder;
-import com.github.scribejava.core.model.OAuth1AccessToken;
-import com.github.scribejava.core.model.OAuth1RequestToken;
-import com.github.scribejava.core.model.OAuthRequest;
-import com.github.scribejava.core.model.Verb;
-import com.github.scribejava.core.oauth.OAuth10aService;
-import com.juick.server.UserQueries;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * Created by vt on 01.12.2015.
- */
-public class TwitterAuth {
-
- private final static String VERIFY_URL = "https://api.twitter.com/1.1/account/verify_credentials.json";
-
- private String consumerKey, consumerSecret;
-
- private final ObjectMapper mapper;
-
- public TwitterAuth(String consumerKey, String consumerSecret) {
- this.consumerKey = consumerKey;
- this.consumerSecret = consumerSecret;
- mapper = new ObjectMapper();
- mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
- mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
- }
-
- protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- String hash = StringUtils.EMPTY, request_token = StringUtils.EMPTY, request_token_secret = StringUtils.EMPTY;
- String verifier = request.getParameter("oauth_verifier");
- Cookie[] cookies = request.getCookies();
- for (Cookie cookie : cookies) {
- if (cookie.getName().equals("hash")) {
- hash = cookie.getValue();
- }
- if (cookie.getName().equals("request_token")) {
- request_token = cookie.getValue();
- }
- if (cookie.getName().equals("request_token_secret")) {
- request_token_secret = cookie.getValue();
- }
- }
- com.juick.User user = UserQueries.getUserByHash(sql, hash);
- if ( user == null || user.getUid() == 0) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
- OAuth10aService oAuthService = new ServiceBuilder()
- .apiKey(consumerKey)
- .apiSecret(consumerSecret)
- .callback("http://juick.com/_twitter")
- .build(TwitterApi.instance());
-
- if (request_token.isEmpty() && request_token_secret.isEmpty()
- && (verifier == null || verifier.isEmpty())) {
- OAuth1RequestToken requestToken = oAuthService.getRequestToken();
- String authUrl = oAuthService.getAuthorizationUrl(requestToken);
- response.addCookie(new Cookie("request_token", requestToken.getToken()));
- response.addCookie(new Cookie("request_token_secret", requestToken.getTokenSecret()));
- response.setStatus(HttpServletResponse.SC_FOUND);
- response.setHeader("Location", authUrl);
- } else {
- if (verifier != null && verifier.length() > 0) {
- OAuth1RequestToken requestToken = new OAuth1RequestToken(request_token, request_token_secret);
- OAuth1AccessToken accessToken = oAuthService.getAccessToken(requestToken, verifier);
- OAuthRequest oAuthRequest = new OAuthRequest(Verb.GET, VERIFY_URL, oAuthService.getConfig());
- oAuthService.signRequest(accessToken, oAuthRequest);
- com.juick.www.twitter.User twitterUser = mapper.readValue(oAuthRequest.send().getBody(), com.juick.www.twitter.User.class);
- if (UserQueries.linkTwitterAccount(sql, user, accessToken.getToken(), accessToken.getTokenSecret(),
- twitterUser.getScreenName())) {
- response.setStatus(HttpServletResponse.SC_FOUND);
- response.setHeader("Location", "http://juick.com/settings");
- } else {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- }
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/User.java b/juick-www/src/main/java/com/juick/www/User.java
deleted file mode 100644
index 926ce3e3..00000000
--- a/juick-www/src/main/java/com/juick/www/User.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.server.MessagesQueries;
-import com.juick.server.TagQueries;
-import com.juick.server.UserQueries;
-import com.juick.server.helpers.TagStats;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringEscapeUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.Comparator;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class User {
-
- protected void doGetBlog(JdbcTemplate sql, JdbcTemplate sqlSearch, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- List mids;
-
- String paramShow = request.getParameter("show");
-
- com.juick.Tag paramTag = null;
- String paramTagStr = request.getParameter("tag");
- if (paramTagStr != null) {
- if (paramTagStr.length() < 64) {
- paramTag = TagQueries.getTag(sql, paramTagStr, false);
- }
- if (paramTag == null) {
- Errors.doGet404(sql, request, response);
- return;
- } else if (!paramTag.getName().equals(paramTagStr)) {
- String url = "/" + user.getName() + "/?tag=" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8);
- Utils.sendPermanentRedirect(response, url);
- return;
- }
- }
-
- int paramBefore = 0;
- String paramBeforeStr = request.getParameter("before");
- if (paramBeforeStr != null) {
- try {
- paramBefore = Integer.parseInt(paramBeforeStr);
- } catch (NumberFormatException e) {
- }
- }
-
- String paramSearch = request.getParameter("search");
- if (paramSearch != null && paramSearch.length() > 64) {
- paramSearch = null;
- }
-
- int privacy = 0;
- if (visitor.getUid() > 0) {
- if (user.getUid() == visitor.getUid() || visitor.getUid() == 1) {
- privacy = -3;
- } else if (UserQueries.isInWL(sql, user.getUid(), visitor.getUid())) {
- privacy = -2;
- }
- }
-
- String title;
- if (paramShow == null) {
- if (paramTag != null) {
- title = "Блог " + user.getName() + ": *" + StringEscapeUtils.escapeHtml4(paramTag.getName());
- mids = MessagesQueries.getUserTag(sql, user.getUid(), paramTag.TID, privacy, paramBefore);
- } else if (paramSearch != null) {
- title = "Блог " + user.getName() + ": " + StringEscapeUtils.escapeHtml4(paramSearch);
- mids = MessagesQueries.getUserSearch(sql, sqlSearch, user.getUid(), Utils.encodeSphinx(paramSearch), privacy, paramBefore);
- } else {
- title = "Блог " + user.getName();
- mids = MessagesQueries.getUserBlog(sql, user.getUid(), privacy, paramBefore);
- }
- } else if (paramShow.equals("recomm")) {
- title = "Рекомендации " + user.getName();
- mids = MessagesQueries.getUserRecommendations(sql, user.getUid(), paramBefore);
- } else if (paramShow.equals("photos")) {
- title = "Фотографии " + user.getName();
- mids = MessagesQueries.getUserPhotos(sql, user.getUid(), privacy, paramBefore);
- } else {
- Errors.doGet404(sql, request, response);
- return;
- }
-
- if (visitor.getUid() == 0) {
- pageUserRefCookie(request, response, user.getUid());
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- String head = " ";
- if (paramTag != null && TagQueries.getTagNoIndex(sql, paramTag.TID)) {
- head += " ";
- } else if (paramBefore > 0 || paramShow != null) {
- head += " ";
- }
- PageTemplates.pageHead(out, visitor, title, head);
- PageTemplates.pageNavigation(out, visitor, null);
- pageUserColumn(out, sql, user, visitor);
-
- if (mids.size() > 0) {
- out.println("");
-
- if (paramTag != null) {
- out.println("← Все записи с тегом " +
- StringEscapeUtils.escapeHtml4(paramTag.getName()) + "
");
- }
-
- PageTemplates.printMessages(out, sql, user, mids, visitor, visitor.getUid() == 0 ? 4 : 5, 0);
-
- if (mids.size() >= 20) {
- String nextpage = "?before=" + mids.get(mids.size() - 1);
- if (paramShow != null) {
- nextpage += "&show=" + paramShow;
- }
- if (paramTag != null) {
- nextpage += "&tag=" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8);
- }
- if (paramSearch != null) {
- nextpage += "&search=" + URLEncoder.encode(paramSearch, CharEncoding.UTF_8);
- }
- out.println("Читать дальше →
");
- }
-
- out.println(" ");
- }
-
- PageTemplates.pageFooter(request, out, visitor, true);
- PageTemplates.pageEnd(out);
- }
- }
-
- protected void doGetTags(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- if (visitor.getUid() == 0) {
- pageUserRefCookie(request, response, user.getUid());
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- String head = " ";
- PageTemplates.pageHead(out, visitor, "Теги " + user.getName(), head);
- PageTemplates.pageNavigation(out, visitor, null);
- pageUserColumn(out, sql, user, visitor);
-
- out.println("");
- out.println("" + pageUserTags(sql, user, visitor, 0) + "
");
- out.println(" ");
-
- PageTemplates.pageFooter(request, out, visitor, false);
- PageTemplates.pageEnd(out);
- }
- }
-
- protected void doGetFriends(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- if (visitor.getUid() == 0) {
- pageUserRefCookie(request, response, user.getUid());
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- String head = " ";
- PageTemplates.pageHead(out, visitor, "Подписки " + user.getName(), head);
- PageTemplates.pageNavigation(out, visitor, null);
- pageUserColumn(out, sql, user, visitor);
-
- out.println("");
- out.println("");
-
- List friends = UserQueries.getUserFriends(sql, user.getUid());
- for (int i = 0; i < friends.size(); i++) {
- if (i % 3 == 0 && i > 0) {
- out.print(" ");
- }
- out.print(" "
- + friends.get(i).getName() + " ");
- }
-
- out.println("
");
- out.println(" ");
-
- PageTemplates.pageFooter(request, out, visitor, false);
- PageTemplates.pageEnd(out);
- }
- }
-
- protected void doGetReaders(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User user) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- if (visitor.getUid() == 0) {
- pageUserRefCookie(request, response, user.getUid());
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- String head = " ";
- PageTemplates.pageHead(out, visitor, "Читатели " + user.getName(), head);
- PageTemplates.pageNavigation(out, visitor, null);
- pageUserColumn(out, sql, user, visitor);
-
- out.println("");
- out.println("");
-
- List readers = UserQueries.getUserReaders(sql, user.getUid());
- for (int i = 0; i < readers.size(); i++) {
- if (i % 3 == 0 && i > 0) {
- out.print(" ");
- }
- out.print(" "
- + readers.get(i).getName() + " ");
- }
-
- out.println("
");
- out.println(" ");
-
- PageTemplates.pageFooter(request, out, visitor, false);
- PageTemplates.pageEnd(out);
- }
- }
-
- public static void pageUserRefCookie(HttpServletRequest request, HttpServletResponse response, int uid) {
- String hReferer = request.getHeader("Referer");
- String ref = Utils.getCookie(request, "ref");
-
- if (ref == null && (hReferer == null || !(hReferer.startsWith("http://juick.com/") || hReferer.startsWith("https://juick.com/")))) {
- Cookie c = new Cookie("ref", Integer.toString(uid));
- c.setMaxAge(7 * 24 * 60 * 60);
- c.setPath("/");
- response.addCookie(c);
- }
- }
-
- public static void pageUserColumn(PrintWriter out, JdbcTemplate sql, com.juick.User user, com.juick.User visitor) {
- out.println("");
- out.println(" ");
- if (visitor.getUid() > 0 && visitor.getUid() != user.getUid()) {
- out.println(" ");
- } else {
- out.println(" ");
- }
- out.println(" ");
- out.println(" ");
- out.println(" ");
- out.println("
");
- out.println(" ");
- out.println(" " + pageUserTags(sql, user, visitor, 20) + "...
");
- out.println(" ");
- out.println(" ");
-
- List
iread = UserQueries.getUserReadLeastPopular(sql, user.getUid(), 8);
- if (!iread.isEmpty()) {
- out.println("");
- for (int i = 0; i < iread.size(); i++) {
- if (i == 4) {
- out.println(" ");
- }
- com.juick.User u = iread.get(i);
- out.println(" ");
- }
- out.println("
");
- }
-
- out.println(" ");
- out.println(" ");
- }
-
- public static String pageUserTags(JdbcTemplate sql, com.juick.User user, com.juick.User visitor, int cnt) {
- List tags = TagQueries.getTagsStats(sql, user.getUid()).stream()
- .sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).collect(Collectors.toList());
- int maxUsageCnt = tags.stream().map(TagStats::getUsageCount).max(Comparator.naturalOrder()).orElse(0);
- String ret = StringUtils.EMPTY;
- int count = cnt > 0 ? Math.min(tags.size(), cnt) : tags.size();
- for (int i = 0; i < count; i++) {
- String tag = StringEscapeUtils.escapeHtml4(tags.get(i).getTag().getName());
- try {
- tag = "" + tag + " ";
- } catch (UnsupportedEncodingException e) {
- }
-
- if (tags.get(i).getUsageCount() > maxUsageCnt / 3 * 2) {
- ret += "" + tag + " ";
- } else if (tags.get(i).getUsageCount() > maxUsageCnt / 3) {
- ret += "" + tag + " ";
- } else {
- ret += tag + " ";
- }
- }
- return ret;
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/UserThread.java b/juick-www/src/main/java/com/juick/www/UserThread.java
deleted file mode 100644
index 79ec42fc..00000000
--- a/juick-www/src/main/java/com/juick/www/UserThread.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * 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.www;
-
-import com.juick.Message;
-import com.juick.server.MessagesQueries;
-import com.juick.server.UserQueries;
-import com.juick.server.helpers.TagStats;
-import com.juick.util.MessageUtils;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Ugnich Anton
- */
-public class UserThread {
-
- protected void doGetThread(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, int MID) throws ServletException, IOException {
- com.juick.User visitor = Utils.getVisitorUser(sql, request, response);
-
- if (!MessagesQueries.canViewThread(sql, MID, visitor.getUid())) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
-
- com.juick.Message msg = MessagesQueries.getMessage(sql, MID);
-
- boolean listview = false;
- String paramView = request.getParameter("view");
- if (paramView != null) {
- if (paramView.equals("list")) {
- listview = true;
- if (visitor.getUid() > 0) {
- UserQueries.setUserOptionInt(sql, visitor.getUid(), "repliesview", 1);
- }
- } else if (paramView.equals("tree") && visitor.getUid() > 0) {
- UserQueries.setUserOptionInt(sql, visitor.getUid(), "repliesview", 0);
- }
- } else if (visitor.getUid() > 0 && UserQueries.getUserOptionInt(sql, visitor.getUid(), "repliesview", 0) == 1) {
- listview = true;
- }
-
- String title = msg.getUser().getName() + ": " + msg.getTagsString();
-
- if (visitor.getUid() > 0) {
- User.pageUserRefCookie(request, response, msg.getUser().getUid());
- }
-
- response.setContentType("text/html; charset=UTF-8");
- try (PrintWriter out = response.getWriter()) {
- String headers = " ";
- if (paramView != null) {
- headers += " ";
- }
- if (msg.Hidden) {
- headers += " ";
- }
- PageTemplates.pageHead(out, visitor, title, headers);
- PageTemplates.pageNavigation(out, visitor, null);
-
- out.println("");
- printMessage(out, sql, msg, visitor);
- printReplies(out, sql, msg, visitor, listview);
- out.println(" ");
-
- PageTemplates.pageFooter(request, out, visitor, false);
-
- PageTemplates.pageEnd(out);
- }
- }
-
- public static com.juick.Message printMessage(PrintWriter out, JdbcTemplate sql, com.juick.Message msg, com.juick.User visitor) {
- msg.VisitorCanComment = visitor.getUid() > 0;
-
- List tags = MessagesQueries.getMessageTags(sql, msg.getMid());
- String tagsStr = PageTemplates.formatTags(tags);
- if (msg.ReadOnly) {
- tagsStr += "readonly ";
- msg.VisitorCanComment = false;
- }
- if (msg.getPrivacy() < 0) {
- tagsStr += "friends ";
- }
-
- String txt;
- if (msg.getTags().stream().anyMatch(t -> t.getName().equals("code"))) {
- txt = MessageUtils.formatMessageCode(msg.getText());
- } else {
- txt = MessageUtils.formatMessage(msg.getText());
- }
-
- if (!tags.isEmpty()) {
- tagsStr = "" + tagsStr + "
";
- }
-
- out.println("");
- out.println(" ");
- out.println(" ");
- out.println(" ");
- out.println("
" + PageTemplates.formatJSLocalTime(msg.getDate()) + "
");
- out.println("
");
- out.println(" ");
- out.println("
" + txt + "
");
-
- if (msg.getAttachmentType() != null) {
- out.println("
");
- }
-
- boolean visitorInBL = false;
- if (visitor.getUid() > 0) {
- if (visitor.getUid() == msg.getUser().getUid()) {
- msg.VisitorCanComment = true;
- } else {
- visitorInBL = UserQueries.isInBL(sql, msg.getUser().getUid(), visitor.getUid());
- if (visitorInBL) {
- msg.VisitorCanComment = false;
- }
- }
- }
-
- if (msg.VisitorCanComment) {
- out.println("
");
- out.println(" ");
- out.println(" ");
- }
-
- List
recomm = MessagesQueries.getMessageRecommendations(sql, msg.getMid());
- if (!recomm.isEmpty()) {
- out.print(" Рекомендовали (" + recomm.size() + "): ");
- for (int i = 0; i < recomm.size(); i++) {
- if (i > 0) {
- out.print(", ");
- }
- out.print("
@" + recomm.get(i) + " ");
- }
- out.println("
");
- }
- out.println(" ");
- out.println(" ");
-
- out.println(" ");
- out.println("
" + msg.getMid() + " ");
- if (visitor.getUid() > 0) {
- if (visitor.getUid() != msg.getUser().getUid()) {
- if (MessagesQueries.isSubscribed(sql, visitor.getUid(), msg.getMid())) {
- out.println("
Подписан ");
- } else {
- out.println("
Подписаться ");
- }
- if (!visitorInBL) {
- out.println("
Рекомендовать ");
- }
- } else {
- out.println("
Удалить ");
- }
- }
- out.println(" ");
- out.println(" ");
-
- return msg;
- }
-
- public static void printReplies(PrintWriter out, JdbcTemplate sql, com.juick.Message msg, com.juick.User visitor, boolean listview) {
- List replies = MessagesQueries.getReplies(sql, msg.getMid());
-
- List blUIDs = new ArrayList();
- for (int i = 0; i < replies.size(); i++) {
- com.juick.Message reply = replies.get(i);
- if (reply.getUser().getUid() != msg.getUser().getUid() && !blUIDs.contains(reply.getUser().getUid())) {
- blUIDs.add(reply.getUser().getUid());
- }
- if (reply.getReplyto() > 0) {
- boolean added = false;
- for (int n = 0; n < replies.size(); n++) {
- if (replies.get(n).getRid() == reply.getReplyto()) {
- replies.get(n).childs.add(reply);
- added = true;
- break;
- }
- }
- if (!added) {
- reply.setReplyto(0);
- }
- }
- }
-
- if (!replies.isEmpty()) {
- if (visitor.getUid() > 0 && msg.getUser().getUid() == visitor.getUid()) {
- for (Message reply : replies) {
- reply.VisitorCanComment = true;
- }
- } else if (visitor.getUid() > 0 && msg.VisitorCanComment) {
- blUIDs = UserQueries.checkBL(sql, visitor.getUid(), blUIDs);
- for (Message reply : replies) {
- reply.VisitorCanComment = reply.getUser().getUid() == visitor.getUid() || !blUIDs.contains(reply.getUser().getUid());
- }
- } else {
- for (Message reply : replies) {
- reply.VisitorCanComment = false;
- }
- }
-
- boolean foldable = false;
- if (replies.size() > 10) {
- for (int i = 0; i < replies.size() - 1; i++) {
- if (replies.get(i).getChildsCount() > 1) {
- foldable = true;
- break;
- }
- }
- }
-
- out.println("");
- out.print("
");
- out.println("
Ответы (" + replies.size() + ") ");
- out.println("
");
-
- out.println("");
- if (listview) {
- printList(out, replies, visitor);
- } else {
- printTree(out, replies, visitor, 0, 0, false);
- }
- out.println(" ");
-
- for (Message reply : replies) {
- reply.cleanupChilds();
- }
- replies.clear();
- }
- }
-
- public static void printTree(PrintWriter out, List replies, com.juick.User visitor, int ReplyTo, int margin, boolean hidden) {
- if (margin > 240) {
- margin = 240;
- }
-
- for (int i = 0; i < replies.size(); i++) {
- com.juick.Message msg = replies.get(i);
- if (msg.getReplyto() == ReplyTo) {
-
- out.print(" 0) {
- out.print("margin-left: " + margin + "px;");
- }
- if (hidden) {
- out.print("display:none;");
- }
- out.println("\">");
- out.println(" ");
- out.println(" ");
- out.println("
" + MessageUtils.formatMessage(msg.getText()) + "
");
- if (msg.getAttachmentType() != null) {
- out.println("
");
- }
- out.print("
/" + msg.getRid());
- if (msg.getReplyto() > 0) {
- out.print(" в ответ на
/" + msg.getReplyto() + " ");
- }
- if (msg.VisitorCanComment) {
- out.println(" ·
");
- out.println(" ");
- } else if (visitor == null) {
- out.println(" ·
Ответить ");
- }
-
- int childs = msg.getChildsCount();
- if (ReplyTo == 0 && childs > 1 && replies.size() > 10) {
- out.println(" ");
- }
- out.println(" ");
- out.println(" ");
-
- if (ReplyTo == 0 && childs > 1 && replies.size() > 10) {
- printTree(out, msg.childs, visitor, msg.getRid(), margin + 20, true);
- } else if (childs > 0) {
- printTree(out, msg.childs, visitor, msg.getRid(), margin + 20, hidden);
- }
- }
- }
- }
-
- public static void printList(PrintWriter out, List replies, com.juick.User visitor) {
- for (Message msg : replies) {
- out.print(" ");
- out.println(" ");
- out.println(" ");
- out.println("
" + MessageUtils.formatMessage(msg.getText()) + "
");
- if (msg.getAttachmentType() != null) {
- out.println("
");
- }
- out.print("
/" + msg.getRid());
- if (msg.getReplyto() > 0) {
- out.print(" в ответ на
/" + msg.getReplyto() + " ");
- }
- if (msg.VisitorCanComment) {
- out.println(" ·
");
- out.println(" ");
- } else if (visitor.getUid() == 0) {
- out.println("
");
- }
- out.println("
");
- out.println(" ");
- }
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/Utils.java b/juick-www/src/main/java/com/juick/www/Utils.java
index ca3535fd..37016ed2 100644
--- a/juick-www/src/main/java/com/juick/www/Utils.java
+++ b/juick-www/src/main/java/com/juick/www/Utils.java
@@ -17,31 +17,21 @@
*/
package com.juick.www;
-import com.juick.Tag;
-import com.juick.User;
-import com.juick.server.TagQueries;
-import com.mitchellbosecke.pebble.PebbleEngine;
-import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.core.JdbcTemplate;
-import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
-import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
-import java.nio.file.Paths;
-import java.util.*;
+import java.util.Arrays;
/**
*
@@ -51,9 +41,6 @@ public class Utils {
private static final Logger logger = LoggerFactory.getLogger(Utils.class);
- private static final PebbleEngine engine = new PebbleEngine.Builder().build();
- private static String tmpDir = "/var/www/juick.com/i/tmp/";
-
public static String getCookie(HttpServletRequest request, String name) {
Cookie cookies[] = request.getCookies();
if (cookies != null) {
@@ -63,40 +50,7 @@ public class Utils {
return null;
}
- public static String receiveMultiPartFile(Part filePart) throws IOException, ServletException {
- String attachmentFName = null;
-
- if (filePart != null) {
- String partname = Utils.getPartFilename(filePart);
- if (partname != null && partname.length() > 0) {
- String attachmentType = partname.substring(partname.length() - 3).toLowerCase();
- if (attachmentType.equals("jpg") || attachmentType.equals("peg") || attachmentType.equals("png")) {
- if (attachmentType.equals("peg")) {
- attachmentType = "jpg";
- }
- attachmentFName = DigestUtils.md5Hex(UUID.randomUUID().toString()) + "." + attachmentType;
- filePart.write(Paths.get(getTmpDir(), attachmentFName).toString());
- } else {
- throw new IOException("Wrong file type");
- }
- }
- }
-
- return attachmentFName;
- }
- public static com.juick.User getVisitorUser(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) {
- String hash = getCookie(request, "hash");
- if (hash != null) {
- com.juick.User visitor = com.juick.server.UserQueries.getUserByHash(sql, hash);
- if (response != null && visitor.getUid() > 0) {
- response.setHeader("X-Username", visitor.getName());
- }
- return visitor;
- } else {
- return new User();
- }
- }
public static void sendTemporaryRedirect(HttpServletResponse response, String location) {
response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
@@ -154,96 +108,4 @@ public class Utils {
return null;
}
}
-
- public static String downloadImage(URL url) throws Exception {
- String attachmentFName = null;
- Exception ex = null;
-
- InputStream is = null;
- FileOutputStream fos = null;
- try {
- URLConnection urlConn = url.openConnection();
- is = urlConn.getInputStream();
- String mime = urlConn.getContentType();
-
- String attachmentType;
- if (mime != null && mime.equals("image/jpeg")) {
- attachmentType = "jpg";
- } else if (mime != null && mime.equals("image/png")) {
- attachmentType = "png";
- } else {
- throw new Exception("Wrong file type");
- }
-
- attachmentFName = DigestUtils.md5Hex(UUID.randomUUID().toString()) + "." + attachmentType;
- fos = new FileOutputStream("/var/www/juick.com/i/tmp/" + attachmentFName);
- byte[] buffer = new byte[10240];
- int len;
- while ((len = is.read(buffer)) > 0) {
- fos.write(buffer, 0, len);
- }
- } catch (Exception e) {
- ex = e;
- attachmentFName = null;
- } finally {
- try {
- if (is != null) {
- is.close();
- }
- } finally {
- if (fos != null) {
- fos.close();
- }
- }
- }
-
- if (ex != null) {
- throw ex;
- } else {
- return attachmentFName;
- }
- }
-
- public static List parseTags(JdbcTemplate sql, String tagsStr) {
- List tags = new ArrayList<>();
- String tagsArr[];
- if (tagsStr != null && !tagsStr.isEmpty()) {
- tagsArr = tagsStr.split("[ \\,]");
- for (int i = 0; i < tagsArr.length; i++) {
- if (tagsArr[i].startsWith("*")) {
- tagsArr[i] = tagsArr[i].substring(1);
- }
- if (tagsArr[i].length() > 64) {
- tagsArr[i] = tagsArr[i].substring(0, 64);
- }
- }
- tags = TagQueries.getTags(sql, tagsArr, true);
- while (tags.size() > 5) {
- tags.remove(5);
- }
- }
- return tags;
- }
-
- public static String receiveAttachment(Part part, String paramImg) throws Exception {
- String attachmentFName = receiveMultiPartFile(part);
-
- if (attachmentFName == null && paramImg != null && paramImg.length() > 10) {
- URL imgUrl = new URL(paramImg);
- attachmentFName = downloadImage(imgUrl);
- }
- return attachmentFName;
- }
-
- public static PebbleEngine getEngine() {
- return engine;
- }
-
- public static String getTmpDir() {
- return tmpDir;
- }
-
- public static void setTmpDir(String tmpDir) {
- Utils.tmpDir = tmpDir;
- }
}
diff --git a/juick-www/src/main/java/com/juick/www/VKontakteLogin.java b/juick-www/src/main/java/com/juick/www/VKontakteLogin.java
deleted file mode 100644
index 2184fc9a..00000000
--- a/juick-www/src/main/java/com/juick/www/VKontakteLogin.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Juick
- * Copyright (C) 2008-2013, 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.www;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.juick.server.UserQueries;
-import com.juick.www.vk.Token;
-import com.juick.www.vk.UsersResponse;
-import org.apache.commons.lang3.CharEncoding;
-import org.apache.commons.lang3.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.dao.EmptyResultDataAccessException;
-import org.springframework.jdbc.core.JdbcTemplate;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.net.URLEncoder;
-import java.util.UUID;
-
-/**
- * @author Ugnich Anton
- */
-public class VKontakteLogin {
- private static final Logger logger = LoggerFactory.getLogger(VKontakteLogin.class);
- private static final String VK_APPID = "3544101";
- private static final String VK_SECRET = "z2afNI8jA5lIpZ2jsTm1";
- private static final String VK_REDIRECT = "http://juick.com/_vklogin";
-
- public VKontakteLogin() {
- mapper = new ObjectMapper();
- mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
- mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
- mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
- }
-
- private final ObjectMapper mapper;
-
- protected void doGet(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String code = request.getParameter("code");
- if (StringUtils.isBlank(code)) {
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "https://oauth.vk.com/authorize?client_id=" + VK_APPID + "&redirect_uri=" + URLEncoder.encode(VK_REDIRECT, CharEncoding.UTF_8) + "&scope=friends,wall,offline&response_type=code");
- return;
- }
-
-
- String tokenjson = Utils.fetchURL("https://oauth.vk.com/access_token?client_id=" + VK_APPID + "&redirect_uri=" + URLEncoder.encode(VK_REDIRECT, CharEncoding.UTF_8) + "&client_secret=" + VK_SECRET + "&code=" + URLEncoder.encode(code, CharEncoding.UTF_8));
- if (tokenjson == null || tokenjson.isEmpty()) {
- logger.error("VK TOKEN EMPTY");
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
- String token = null;
- long vkID = 0;
- Token json = mapper.readValue(tokenjson, Token.class);
- token = json.getAccessToken();
- vkID = json.getUserId();
- if (token == null || vkID == 0) {
- logger.error("VK TOKEN EMPTY: {}", tokenjson);
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
-
- String graph = Utils.fetchURL("https://api.vk.com/method/users.get?uids=" + vkID + "&fields=screen_name&access_token=" + token);
- if (graph == null || graph.isEmpty()) {
- logger.error("VK GRAPH ERROR");
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- return;
- }
-
- try {
- com.juick.www.vk.User jsonUser = mapper.readValue(graph, UsersResponse.class).getUsers().get(0);
- String vkName = jsonUser.getFirstName() + " " + jsonUser.getLastName();
- String vkLink = jsonUser.getScreenName();
-
- if (vkName == null || vkLink == null || vkName.isEmpty() || vkName.length() == 1 || vkLink.isEmpty()) {
- throw new Exception();
- }
-
- int uid = getUIDbyVKID(sql, vkID);
- if (uid > 0) {
- Cookie c = new Cookie("hash", UserQueries.getHashByUID(sql, uid));
- c.setMaxAge(50 * 24 * 60 * 60);
- response.addCookie(c);
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "/");
- } else {
- String loginhash = UUID.randomUUID().toString();
- if (!insertDB(sql, vkID, loginhash, token, vkName, vkLink)) {
- throw new Exception();
- }
- response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
- response.setHeader("Location", "/signup?type=vk&hash=" + loginhash);
- }
- } catch (Exception e) {
- logger.error("JSON ERROR", e);
- response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- }
-
- private int getUIDbyVKID(JdbcTemplate sql, long vkID) {
- try {
- return sql.queryForObject("SELECT user_id FROM vk WHERE vk_id=? AND user_id IS NOT NULL", Integer.class, vkID);
- } catch (EmptyResultDataAccessException e) {
- return 0;
- }
- }
-
- private boolean insertDB(JdbcTemplate sql, long vkID, String loginhash, String token, String vkName, String vkLink) {
- return sql.update("INSERT INTO vk(vk_id,loginhash,access_token,vk_name,vk_link) VALUES (?,?,?,?,?)",
- vkID, loginhash, token, vkName, vkLink) > 0;
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/WebApp.java b/juick-www/src/main/java/com/juick/www/WebApp.java
new file mode 100644
index 00000000..85ae64d4
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/WebApp.java
@@ -0,0 +1,154 @@
+/*
+ * 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.www;
+
+import com.juick.Message;
+import com.juick.Tag;
+import com.juick.User;
+import com.juick.service.TagService;
+import com.juick.service.UserService;
+import com.juick.www.controllers.PageTemplates;
+import org.apache.commons.lang3.BooleanUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+import rocks.xmpp.addr.Jid;
+import rocks.xmpp.core.XmppException;
+import rocks.xmpp.core.session.Extension;
+import rocks.xmpp.core.session.XmppSessionConfiguration;
+import rocks.xmpp.core.session.debug.LogbackDebugger;
+import rocks.xmpp.extensions.component.accept.ExternalComponent;
+import ru.sape.Sape;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+public class WebApp implements AutoCloseable {
+ private static Logger logger = LoggerFactory.getLogger(WebApp.class);
+
+ private ExternalComponent xmpp;
+
+ Environment env;
+ PageTemplates templates;
+ UserService userService;
+ TagService tagService;
+
+ private String imgDir;
+ private String tmpDir;
+
+ public WebApp(Environment env, PageTemplates templates, UserService userService, TagService tagService) {
+ this.env = env;
+ this.templates = templates;
+ this.userService = userService;
+ this.tagService = tagService;
+ tmpDir = env.getProperty("upload_tmp_dir", "/var/www/juick.com/i/tmp/");
+ imgDir = env.getProperty("img_path", "/var/www/juick.com/i/");
+ boolean isXmppDisabled = BooleanUtils.toBoolean(env.getProperty("xmpp_disabled"));
+ if (!isXmppDisabled) {
+ setupXmppComponent(Jid.of(env.getProperty("www_xmpp_jid", "www.juick.local")),
+ env.getProperty("xmpp_password"), NumberUtils.toInt(env.getProperty("xmpp_port", StringUtils.EMPTY), 5347));
+ }
+ String sapeUser = env.getProperty("sape_user", StringUtils.EMPTY);
+ if (!Objects.equals(sapeUser, StringUtils.EMPTY)) {
+ templates.sape = new Sape(sapeUser, "juick.com", 2000, 3600);
+ } else {
+ logger.error("Sape is not initialized");
+ }
+ }
+
+ @Override
+ public void close() {
+ try {
+ if (xmpp != null)
+ xmpp.close();
+ logger.error("ExternalComponent on WWW destroyed");
+ } catch (Exception e) {
+ logger.error("exception on destroy", e);
+ }
+ }
+
+ public void setupXmppComponent(final Jid componentJid, final String password, final int port) {
+ XmppSessionConfiguration configuration = XmppSessionConfiguration.builder()
+ .extensions(Extension.of(Message.class))
+ .debugger(LogbackDebugger.class)
+ .build();
+ xmpp = ExternalComponent.create(componentJid.toString(), password, configuration, "localhost", port);
+ xmpp.addConnectionListener(e -> logger.error(e.toString(), e.getCause()));
+ try {
+ xmpp.connect();
+ } catch (XmppException e) {
+ logger.error("xmpp extension", e);
+ }
+ }
+
+ public ExternalComponent getXmpp() {
+ return xmpp;
+ }
+
+
+ public com.juick.User getVisitorUser(HttpServletRequest request, HttpServletResponse response) {
+ String hash = Utils.getCookie(request, "hash");
+ if (hash != null) {
+ com.juick.User visitor = userService.getUserByHash(hash);
+ if (response != null && visitor.getUid() > 0) {
+ response.setHeader("X-Username", visitor.getName());
+ }
+ return visitor;
+ } else {
+ return new User();
+ }
+ }
+
+ public String getImgDir() {
+ return imgDir;
+ }
+
+ public String getTmpDir() {
+ return tmpDir;
+ }
+
+ public List parseTags(String tagsStr) {
+ List tags = new ArrayList<>();
+ String tagsArr[];
+ if (tagsStr != null && !tagsStr.isEmpty()) {
+ tagsArr = tagsStr.split("[ \\,]");
+ for (int i = 0; i < tagsArr.length; i++) {
+ if (tagsArr[i].startsWith("*")) {
+ tagsArr[i] = tagsArr[i].substring(1);
+ }
+ if (tagsArr[i].length() > 64) {
+ tagsArr[i] = tagsArr[i].substring(0, 64);
+ }
+ }
+ tags = tagService.getTags(tagsArr, true);
+ while (tags.size() > 5) {
+ tags.remove(5);
+ }
+ }
+ return tags;
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/XMPPPost.java b/juick-www/src/main/java/com/juick/www/XMPPPost.java
deleted file mode 100644
index c2ec42d7..00000000
--- a/juick-www/src/main/java/com/juick/www/XMPPPost.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package com.juick.www;
-
-import com.juick.Tag;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.math.NumberUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.jdbc.core.JdbcTemplate;
-import rocks.xmpp.addr.Jid;
-import rocks.xmpp.core.session.XmppSession;
-import rocks.xmpp.core.stanza.model.Message;
-import rocks.xmpp.extensions.oob.model.x.OobX;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Created by vitalyster on 08.12.2016.
- */
-public class XMPPPost {
- private final static Logger logger = LoggerFactory.getLogger(XMPPPost.class);
-
- public void doPostMessage(JdbcTemplate sql, HttpServletRequest request,
- HttpServletResponse response, XmppSession xmpp, com.juick.User visitor)
- throws ServletException, IOException {
- if (visitor.getUid() == 0) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN);
- return;
- }
- String body = request.getParameter("body").replace("\r", StringUtils.EMPTY);
- int mid = NumberUtils.toInt(request.getParameter("mid"), 0);
- int rid = NumberUtils.toInt(request.getParameter("rid"), 0);
- if (mid > 0 && rid > 0) {
- body = String.format("#%d/%d %s", mid, rid, body);
- } else if (mid > 0) {
- body = String.format("#%d %s", mid, body);
- } else {
- // is a post
- List tags = Utils.parseTags(sql, request.getParameter("tags"));
- body = String.format("%s %s", tags.stream()
- .map(t -> "*" + t.getName()).collect(Collectors.joining(" ")), body);
- }
- String attachmentFName;
- try {
- attachmentFName = Utils.receiveAttachment(request.getPart("attach"), request.getParameter("img"));
- } catch (Exception e) {
- logger.error("MULTIPART ERROR", e);
- response.sendError(HttpServletResponse.SC_BAD_REQUEST);
- return;
- }
- Message msg = new Message();
- msg.setType(Message.Type.CHAT);
- msg.setFrom(Jid.of(String.valueOf(visitor.getUid()), "uid.juick.com", "perl"));
- msg.setTo(Jid.of("juick@juick.com/Juick"));
- msg.setBody(body);
- try {
- if (attachmentFName != null) {
- String attachmentUrl = String.format("juick://%s", attachmentFName);
- msg.addExtension(new OobX(new URI(attachmentUrl), "!!!!Juick!!"));
- }
- xmpp.sendMessage(msg);
- } catch (URISyntaxException e1) {
- logger.warn("attachment error", e1);
- }
- String referer = request.getHeader("referer");
- if (StringUtils.isBlank(referer) || referer.substring(0, 21).equals("http://juick.com/post")
- || referer.substring(0, 22).equals("https://juick.com/post")) {
- response.sendRedirect("/?show=my");
- return;
- }
- response.sendRedirect(referer);
- }
-}
diff --git a/juick-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java b/juick-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java
new file mode 100644
index 00000000..cd681190
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/configuration/WebAppConfiguration.java
@@ -0,0 +1,50 @@
+package com.juick.www.configuration;
+
+import com.juick.service.TagService;
+import com.juick.service.UserService;
+import com.juick.www.HelpService;
+import com.juick.www.controllers.PageTemplates;
+import com.juick.www.WebApp;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.guava.GuavaCacheManager;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+
+/**
+ * Created by aalexeev on 11/22/16.
+ */
+@Configuration
+@PropertySource("classpath:juick.conf")
+@EnableCaching
+public class WebAppConfiguration {
+ @Resource
+ private Environment env;
+ @Inject
+ private UserService userService;
+ @Inject
+ private TagService tagService;
+
+ @Bean
+ public WebApp webApp() {
+ return new WebApp(env, templates(), userService, tagService);
+ }
+ @Bean
+ public PageTemplates templates() {
+ return new PageTemplates();
+ }
+ @Bean
+ public GuavaCacheManager cacheManager() {
+ return new GuavaCacheManager("help");
+ }
+
+ @Bean
+ public HelpService helpService() {
+ return new HelpService("help");
+ }
+
+}
diff --git a/juick-www/src/main/java/com/juick/www/configuration/WwwInitializer.java b/juick-www/src/main/java/com/juick/www/configuration/WwwInitializer.java
new file mode 100644
index 00000000..cd5429c2
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/configuration/WwwInitializer.java
@@ -0,0 +1,52 @@
+package com.juick.www.configuration;
+
+import com.juick.configuration.DataConfiguration;
+import com.juick.configuration.SearchConfiguration;
+import org.apache.commons.lang3.CharEncoding;
+import org.springframework.web.filter.CharacterEncodingFilter;
+import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
+
+import javax.servlet.FilterRegistration;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * Created by aalexeev on 11/20/16.
+ */
+public class WwwInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
+
+ @Override
+ protected Class>[] getRootConfigClasses() {
+ return new Class>[]{
+ WebAppConfiguration.class,
+ DataConfiguration.class,
+ SearchConfiguration.class
+ };
+ }
+
+ @Override
+ protected Class>[] getServletConfigClasses() {
+ return new Class>[]{WwwServletConfiguration.class};
+ }
+
+ @Override
+ protected String[] getServletMappings() {
+ return new String[]{"/"};
+ }
+
+ @Override
+ protected String getServletName() {
+ return "WWW-spring dispatcher servlet";
+ }
+
+ @Override
+ public void onStartup(ServletContext servletContext) throws ServletException {
+ super.onStartup(servletContext);
+
+ FilterRegistration.Dynamic registration = servletContext.addFilter(
+ "encodingFilter", new CharacterEncodingFilter(CharEncoding.UTF_8, true));
+
+ registration.addMappingForUrlPatterns(null, true, "/*");
+ }
+}
+
diff --git a/juick-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java b/juick-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java
new file mode 100644
index 00000000..c4e6c07c
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/configuration/WwwServletConfiguration.java
@@ -0,0 +1,99 @@
+package com.juick.www.configuration;
+
+import com.mitchellbosecke.pebble.PebbleEngine;
+import com.mitchellbosecke.pebble.loader.Loader;
+import com.mitchellbosecke.pebble.loader.ServletLoader;
+import com.mitchellbosecke.pebble.spring4.PebbleViewResolver;
+import com.mitchellbosecke.pebble.spring4.extension.SpringExtension;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.env.Environment;
+import org.springframework.http.CacheControl;
+import org.springframework.web.multipart.MultipartResolver;
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
+import org.springframework.web.servlet.ViewResolver;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+import org.springframework.web.servlet.resource.PathResourceResolver;
+
+import javax.inject.Inject;
+import javax.servlet.ServletContext;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Created by vitalyster on 28.06.2016.
+ */
+@Configuration
+@ComponentScan(basePackages = {"com.juick.www.controllers"})
+@PropertySource("classpath:juick.conf")
+public class WwwServletConfiguration extends WebMvcConfigurationSupport {
+ @Inject
+ private Environment env;
+
+ @Override
+ protected void addResourceHandlers(ResourceHandlerRegistry registry) {
+ registry.setOrder(0);
+ registry.addResourceHandler(
+ "/scripts.js*",
+ "/style.css*",
+ "/*.png",
+ "/favicon.ico")
+ .addResourceLocations("/")
+ .setCacheControl(CacheControl.maxAge(30, TimeUnit.DAYS))
+ .resourceChain(true)
+ .addResolver(new PathResourceResolver());
+
+ registry.addResourceHandler("/static/**")
+ .addResourceLocations("/static/")
+ .setCacheControl(CacheControl.maxAge(30, TimeUnit.DAYS));
+ }
+
+ @Override
+ public RequestMappingHandlerMapping requestMappingHandlerMapping() {
+ RequestMappingHandlerMapping result = super.requestMappingHandlerMapping();
+
+ result.setOrder(1);
+
+ return result;
+ }
+
+ @Bean
+ public MultipartResolver multipartResolver() {
+ CommonsMultipartResolver resolver = new CommonsMultipartResolver();
+ resolver.setMaxUploadSize(10000000);
+ return resolver;
+ }
+
+ @Inject
+ private ServletContext servletContext;
+
+ @Bean
+ public Loader templateLoader(){
+ return new ServletLoader(servletContext);
+ }
+
+ @Bean
+ public SpringExtension springExtension() {
+ return new SpringExtension();
+ }
+
+ @Bean
+ public PebbleEngine pebbleEngine() {
+ return new PebbleEngine.Builder()
+ .loader(this.templateLoader())
+ .extension(springExtension())
+ .build();
+ }
+
+ @Bean
+ public ViewResolver viewResolver() {
+ PebbleViewResolver viewResolver = new PebbleViewResolver();
+ viewResolver.setPrefix("/WEB-INF/");
+ viewResolver.setSuffix(".html");
+ viewResolver.setPebbleEngine(pebbleEngine());
+ return viewResolver;
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Discover.java b/juick-www/src/main/java/com/juick/www/controllers/Discover.java
new file mode 100644
index 00000000..e5d17501
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/Discover.java
@@ -0,0 +1,138 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.service.AdsService;
+import com.juick.service.MessagesService;
+import com.juick.service.TagService;
+import com.juick.www.Utils;
+import com.juick.www.WebApp;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.List;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class Discover {
+ @Inject
+ WebApp webApp;
+ @Inject
+ MessagesService messagesService;
+ @Inject
+ TagService tagService;
+ @Inject
+ AdsService adsService;
+ @Inject
+ PageTemplates templates;
+
+ @RequestMapping(value = "/tag/{tagName}", method = RequestMethod.GET)
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+
+ String paramTagStr = URLDecoder.decode(request.getRequestURI().substring(5), CharEncoding.UTF_8);
+ com.juick.Tag paramTag = tagService.getTag(paramTagStr, false);
+ if (paramTag == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ } else if (paramTag.SynonymID > 0 && paramTag.TID != paramTag.SynonymID) {
+ com.juick.Tag synTag = tagService.getTag(paramTag.SynonymID);
+ String url = "/tag/" + URLEncoder.encode(synTag.getName(), CharEncoding.UTF_8);
+ if (request.getQueryString() != null) {
+ url += "?" + request.getQueryString();
+ }
+ Utils.sendPermanentRedirect(response, url);
+ return;
+ } else if (!paramTag.getName().equals(paramTagStr)) {
+ String url = "/tag/" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8);
+ if (request.getQueryString() != null) {
+ url += "?" + request.getQueryString();
+ }
+ Utils.sendPermanentRedirect(response, url);
+ return;
+ }
+
+ int paramBefore = 0;
+ String paramBeforeStr = request.getParameter("before");
+ if (paramBeforeStr != null) {
+ try {
+ paramBefore = Integer.parseInt(paramBeforeStr);
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ int visitor_uid = visitor.getUid();
+
+ String title = "*" + StringEscapeUtils.escapeHtml4(paramTag.getName());
+ List mids = messagesService.getTag(paramTag.TID, visitor_uid, paramBefore, (visitor_uid == 0) ? 40 : 20);
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ String head = StringUtils.EMPTY;
+ if (tagService.getTagNoIndex(paramTag.TID)) {
+ head = " ";
+ } else if (paramBefore > 0 || mids.size() < 5) {
+ head = " ";
+ }
+ templates.pageHead(out, visitor, title, head);
+ templates.pageNavigation(out, visitor, null);
+
+ out.println("");
+
+ if (mids.size() > 0) {
+ int vuid = visitor.getUid();
+ int ad_mid = adsService.getAdMid(vuid);
+ if (ad_mid > 0 && mids.indexOf(ad_mid) == -1) {
+ mids.add(0, ad_mid);
+ adsService.logAdMid(vuid, ad_mid);
+ } else {
+ ad_mid = 0;
+ }
+
+ templates.printMessages(out, null, mids, visitor, visitor_uid == 0 ? 2 : 3, ad_mid);
+ }
+
+ if (mids.size() >= 20) {
+ String nextpage = "/tag/" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8) + "?before=" + mids.get(mids.size() - 1);
+ out.println("Читать дальше →
");
+ }
+
+ out.println(" ");
+
+ templates.pageHomeColumn(out, visitor);
+
+ templates.pageFooter(request, out, visitor, true);
+
+ templates.pageEnd(out);
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java b/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java
new file mode 100644
index 00000000..cc11f99a
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/FacebookLogin.java
@@ -0,0 +1,153 @@
+/*
+ * Juick
+ * Copyright (C) 2008-2013, 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.www.controllers;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.juick.service.CrosspostService;
+import com.juick.service.UserService;
+import com.juick.www.Utils;
+import com.juick.www.facebook.Graph;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.UUID;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class FacebookLogin {
+
+ private static final Logger logger = LoggerFactory.getLogger(FacebookLogin.class);
+
+ private final String FACEBOOK_APPID;
+ private final String FACEBOOK_SECRET;
+ private final String FACEBOOK_REDIRECT = "http://juick.com/_fblogin";
+ private final ObjectMapper mapper;
+
+ @Inject
+ CrosspostService crosspostService;
+ @Inject
+ UserService userService;
+
+ @Inject
+ public FacebookLogin(Environment env) {
+ FACEBOOK_APPID = env.getProperty("facebook_appid");
+ FACEBOOK_SECRET = env.getProperty("facebook_secret");
+
+ mapper = new ObjectMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
+ }
+
+ @RequestMapping(value = "/_fblogin", method = RequestMethod.GET)
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
+ String fbstate;
+
+ String code = request.getParameter("code");
+ if (StringUtils.isBlank(code)) {
+ fbstate = UUID.randomUUID().toString();
+
+ Cookie c = new Cookie("fbstate", fbstate);
+ response.addCookie(c);
+
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "https://www.facebook.com/dialog/oauth?scope=publish_stream&client_id=" + FACEBOOK_APPID + "&redirect_uri=" + URLEncoder.encode(FACEBOOK_REDIRECT, CharEncoding.UTF_8) + "&state=" + fbstate);
+ return;
+ }
+
+ fbstate = Utils.getCookie(request, "fbstate");
+ if (fbstate == null || fbstate.isEmpty() || !fbstate.equals(request.getParameter("state"))) {
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ } else {
+ Cookie c = new Cookie("fbstate", "-");
+ c.setMaxAge(0);
+ response.addCookie(c);
+ }
+
+ String token = Utils.fetchURL("https://graph.facebook.com/oauth/access_token?client_id=" + FACEBOOK_APPID + "&redirect_uri=" + URLEncoder.encode(FACEBOOK_REDIRECT, CharEncoding.UTF_8) + "&client_secret=" + FACEBOOK_SECRET + "&code=" + URLEncoder.encode(code, CharEncoding.UTF_8));
+ if (token == null || token.isEmpty() || !token.startsWith("access_token=")) {
+ logger.error("FACEBOOK TOKEN ERROR: {}", token);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+ token = token.substring(13); // access_token=...
+ int tokenamp = token.indexOf('&'); // &expires=
+ if (tokenamp > 0) {
+ token = token.substring(0, tokenamp);
+ }
+
+ String graph = Utils.fetchURL("https://graph.facebook.com/me?access_token=" + token);
+ if (graph == null || graph.isEmpty()) {
+ logger.error("FACEBOOK GRAPH ERROR");
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ try {
+ Graph fb = mapper.readValue(graph, Graph.class);
+
+ long fbID = NumberUtils.toLong(fb.getId(), 0);
+ if (fbID == 0 || StringUtils.isBlank(fb.getName()) || StringUtils.isBlank(fb.getLink())) {
+ throw new Exception();
+ }
+
+ int uid = crosspostService.getUIDbyFBID(fbID);
+ if (uid > 0) {
+ if (!crosspostService.updateFacebookUser(fbID, token, fb.getName(), fb.getLink())) {
+ throw new Exception();
+ }
+ Cookie c = new Cookie("hash", userService.getHashByUID(uid));
+ c.setMaxAge(50 * 24 * 60 * 60);
+ response.addCookie(c);
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "/");
+ } else if (fb.getVerified()) {
+ String loginhash = UUID.randomUUID().toString();
+ if (!crosspostService.createFacebookUser(fbID, loginhash, token, fb.getName(), fb.getLink())) {
+ throw new Exception();
+ }
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "/signup?type=fb&hash=" + loginhash);
+ } else {
+ throw new Exception();
+ }
+ } catch (Exception e) {
+ logger.error("fb error", e);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Help.java b/juick-www/src/main/java/com/juick/www/controllers/Help.java
new file mode 100644
index 00000000..58949827
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/Help.java
@@ -0,0 +1,74 @@
+package com.juick.www.controllers;
+
+import com.juick.server.util.HttpNotFoundException;
+import com.juick.www.HelpService;
+import com.juick.www.WebApp;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Created by aalexeev on 11/21/16.
+ */
+@Controller
+public class Help {
+ @Inject
+ private HelpService helpService;
+ @Inject
+ private WebApp webApp;
+
+ @RequestMapping({"/help/", "/help", "/help/{langOrPage}", "/help/{lang}/{page}"})
+ public String showHelp(
+ HttpServletRequest request,
+ HttpServletResponse response,
+ Locale locale,
+ @PathVariable("lang") Optional langParam,
+ @PathVariable("page") Optional pageParam,
+ @PathVariable("langOrPage") Optional langOrPageParam,
+ Model model) throws IOException, URISyntaxException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ String page = pageParam.orElse("index");
+ String lang = langParam.orElse(locale.getLanguage());
+
+ String navigation = null;
+
+ if (langOrPageParam.isPresent()) {
+ String langOrPage = langOrPageParam.get();
+
+ if (helpService.canBeLang(langOrPage)) {
+ navigation = helpService.getHelp("navigation", langOrPage);
+ if (navigation != null)
+ lang = langOrPage;
+ }
+
+ if (navigation == null && helpService.canBePage(langOrPage))
+ page = langOrPage;
+ }
+
+ String content = helpService.getHelp(page, lang);
+ if (content == null && !Objects.equals("index", page))
+ content = helpService.getHelp("index", lang);
+
+ if (navigation == null)
+ navigation = helpService.getHelp("navigation", lang);
+
+ if (content == null || navigation == null)
+ throw new HttpNotFoundException();
+
+ model.addAttribute("navigation", navigation);
+ model.addAttribute("content", content);
+ model.addAttribute("visitor", visitor);
+
+ return "views/help";
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Home.java b/juick-www/src/main/java/com/juick/www/controllers/Home.java
new file mode 100644
index 00000000..2f9dc903
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/Home.java
@@ -0,0 +1,232 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.service.AdsService;
+import com.juick.service.MessagesService;
+import com.juick.service.UserService;
+import com.juick.util.WebUtils;
+import com.juick.www.Utils;
+import com.juick.www.WebApp;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.URLEncoder;
+import java.util.List;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class Home {
+ @Inject
+ UserService userService;
+ @Inject
+ MessagesService messagesService;
+ @Inject
+ AdsService adsService;
+ @Inject
+ PageTemplates templates;
+ @Inject
+ WebApp webApp;
+
+ @RequestMapping(value = "/{anything}/**", method = RequestMethod.GET)
+ protected void parseAnyThing(HttpServletResponse response, @PathVariable String anything,
+ @RequestParam(required = false, defaultValue = "0") int before) throws IOException {
+ if (before == 0) {
+ boolean isPostNumber = WebUtils.isPostNumber(anything);
+ int messageId = isPostNumber ?
+ NumberUtils.toInt(anything) : 0;
+
+ if (isPostNumber && anything.equals(Integer.toString(messageId))) {
+ if (messageId > 0) {
+ com.juick.User author = messagesService.getMessageAuthor(messageId);
+
+ if (author != null) {
+ Utils.sendPermanentRedirect(response, "/" + author.getName() + "/" + anything);
+ return;
+ }
+ }
+ }
+ com.juick.User user = userService.getUserByName(anything);
+ if (user.getUid() > 0) {
+ Utils.sendPermanentRedirect(response, "/" + user.getName() + "/");
+ return;
+ }
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+ com.juick.User user = userService.getUserByName(anything);
+ if (user.getUid() > 0) {
+ Utils.sendPermanentRedirect(response, "/" + user.getName() + "/?before=" + before);
+ return;
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+ }
+
+ @RequestMapping(value = "/", method = RequestMethod.GET)
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String tag = request.getParameter("tag");
+ if (tag != null) {
+ Utils.sendPermanentRedirect(response, "/tag/" + URLEncoder.encode(tag, CharEncoding.UTF_8));
+ }
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ int paramBefore = NumberUtils.toInt(request.getParameter("before"), 0);
+
+ String paramSearch = request.getParameter("search");
+ if (paramSearch != null && paramSearch.length() > 64) {
+ paramSearch = null;
+ }
+
+ String title;
+ List mids;
+
+ String paramShow = request.getParameter("show");
+ if (paramSearch != null) {
+ title = "Поиск: " + StringEscapeUtils.escapeHtml4(paramSearch);
+ mids = messagesService.getSearch(Utils.encodeSphinx(paramSearch), paramBefore);
+ } else if (paramShow == null) {
+ if (visitor.getUid() > 0) {
+ title = "Популярные";
+ mids = messagesService.getPopular(visitor.getUid(), paramBefore);
+ } else {
+ title = "Микроблоги Juick: популярные записи";
+ mids = messagesService.getPopular(0, paramBefore);
+ }
+
+ } else if (paramShow.equals("top")) {
+ Utils.sendPermanentRedirect(response, "/");
+ return;
+ } else if (paramShow.equals("my") && visitor != null) {
+ title = "Моя лента";
+ mids = messagesService.getMyFeed(visitor.getUid(), paramBefore);
+ } else if (paramShow.equals("private") && visitor != null) {
+ title = "Приватные";
+ mids = messagesService.getPrivate(visitor.getUid(), paramBefore);
+ } else if (paramShow.equals("discuss") && visitor != null) {
+ title = "Обсуждения";
+ mids = messagesService.getDiscussions(visitor.getUid(), paramBefore);
+ } else if (paramShow.equals("recommended") && visitor != null) {
+ title = "Рекомендации";
+ mids = messagesService.getRecommended(visitor.getUid(), paramBefore);
+ } else if (paramShow.equals("photos")) {
+ title = "Фотографии";
+ if (visitor != null) {
+ mids = messagesService.getPhotos(visitor.getUid(), paramBefore);
+ } else {
+ mids = messagesService.getPhotos(0, paramBefore);
+ }
+ } else if (paramShow.equals("all")) {
+ title = "Все сообщения";
+ if (visitor != null) {
+ mids = messagesService.getAll(visitor.getUid(), paramBefore);
+ } else {
+ mids = messagesService.getAll(0, paramBefore);
+ }
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ String head = StringUtils.EMPTY;
+ if (paramBefore > 0 || paramShow != null) {
+ head = " ";
+ }
+ templates.pageHead(out, visitor, title, head);
+ templates.pageNavigation(out, visitor, paramSearch);
+
+ out.println("");
+
+ if (paramShow == null && paramBefore == 0) {
+ out.println("");
+ }
+
+ if (visitor.getUid() > 0) {
+ out.println("");
+ out.println("");
+ out.println(" ");
+ out.println(" ");
+ out.println(" ");
+ out.println(" ");
+ }
+
+ if (mids.size() > 0) {
+ int ad_mid = 0;
+ if (paramShow == null || paramShow.equals("top") || paramShow.equals("all")) {
+ int vuid = visitor.getUid();
+ ad_mid = adsService.getAdMid(vuid);
+ if (ad_mid > 0 && mids.indexOf(ad_mid) == -1) {
+ mids.add(0, ad_mid);
+ adsService.logAdMid(vuid, ad_mid);
+ } else {
+ ad_mid = 0;
+ }
+ }
+
+ templates.printMessages(out, null, mids, visitor, visitor.getUid() == 0 ? 2 : 3, ad_mid);
+ }
+
+ if (mids.size() >= 20) {
+ String nextpage = "?before=" + mids.get(mids.size() - 1);
+ if (paramShow != null) {
+ nextpage += "&show=" + paramShow;
+ }
+ if (paramSearch != null) {
+ nextpage += "&search=" + URLEncoder.encode(paramSearch, CharEncoding.UTF_8);
+ }
+
+ out.println("Читать дальше →
");
+ }
+
+ if (paramShow == null && paramBefore == 0) {
+ out.println("");
+ }
+
+ out.println(" ");
+
+ templates.pageHomeColumn(out, visitor, paramShow == null && paramBefore == 0 && paramSearch == null && visitor.getUid() == 0);
+
+ templates.pageFooter(request, out, visitor, true);
+ templates.pageEnd(out);
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Login.java b/juick-www/src/main/java/com/juick/www/controllers/Login.java
new file mode 100644
index 00000000..bce3e000
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/Login.java
@@ -0,0 +1,258 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.service.UserService;
+import com.juick.www.Utils;
+import com.juick.www.WebApp;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class Login {
+ @Inject
+ UserService userService;
+ @Inject
+ WebApp webApp;
+
+ @RequestMapping(value = "/login", method = RequestMethod.GET)
+ protected void doGetLoginForm(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String hash = request.getQueryString();
+ if (hash != null) {
+ if (hash.length() > 32) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ if (userService.getUIDbyHash(hash) > 0) {
+ Cookie c = new Cookie("hash", hash);
+ c.setMaxAge(365 * 24 * 60 * 60);
+ response.addCookie(c);
+ response.sendRedirect("/");
+ } else {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ }
+ }
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() > 0) {
+ Utils.sendTemporaryRedirect(response, "/");
+ return;
+ }
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ out.println("");
+ out.println("");
+ out.println("");
+ out.println("Juick ");
+ out.println("");
+ out.println("");
+ out.println(" ");
+ out.println("");
+
+ out.println("");
+
+ out.println("");
+
+ out.println("");
+
+ out.println("");
+ out.println(" Зарегистрироваться:");
+ out.println("
");
+ out.println("
");
+ out.println("
XMPP ");
+ out.println("
");
+ out.println("
");
+ out.println("
");
+ out.println("");
+
+ out.println("");
+ out.println("");
+ }
+ }
+
+ @RequestMapping(value = "/login", method = RequestMethod.POST)
+ protected void doPostLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+ if (username == null || password == null || username.length() > 32 || password.isEmpty()) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ int uid = userService.checkPassword(username, password);
+ if (uid > 0) {
+ String hash = userService.getHashByUID(uid);
+ Cookie c = new Cookie("hash", hash);
+ c.setMaxAge(365 * 24 * 60 * 60);
+ response.addCookie(c);
+
+ String referer = request.getHeader("Referer");
+ if (referer != null && referer.startsWith("http://juick.com/") && !referer.equals("http://juick.com/login")) {
+ response.sendRedirect(referer);
+ } else {
+ response.sendRedirect("/");
+ }
+ } else {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ }
+ }
+
+ @RequestMapping(value = "/logout", method = RequestMethod.GET)
+ protected void doGetLogout(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() > 0) {
+ userService.logout(visitor.getUid());
+ }
+
+ Cookie c = new Cookie("hash", "-");
+ c.setDomain(".juick.com");
+ c.setMaxAge(0);
+ response.addCookie(c);
+
+ Cookie c2 = new Cookie("hash", "-");
+ c2.setMaxAge(0);
+ response.addCookie(c2);
+
+ response.sendRedirect("/");
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/NewMessage.java b/juick-www/src/main/java/com/juick/www/controllers/NewMessage.java
new file mode 100644
index 00000000..dacd54a3
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/NewMessage.java
@@ -0,0 +1,468 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.Tag;
+import com.juick.server.helpers.TagStats;
+import com.juick.server.util.HttpBadRequestException;
+import com.juick.server.util.HttpUtils;
+import com.juick.service.*;
+import com.juick.www.Utils;
+import com.juick.www.WebApp;
+import net.coobird.thumbnailator.Thumbnails;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import rocks.xmpp.addr.Jid;
+import rocks.xmpp.core.stanza.model.Message;
+import rocks.xmpp.extensions.nick.model.Nickname;
+import rocks.xmpp.extensions.oob.model.x.OobX;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.List;
+
+/**
+ * @author Ugnich Anton
+ */
+@Controller
+public class NewMessage {
+
+ @Inject
+ Environment env;
+ @Inject
+ TagService tagService;
+ @Inject
+ MessagesService messagesService;
+ @Inject
+ UserService userService;
+ @Inject
+ SubscriptionService subscriptionService;
+ @Inject
+ CrosspostService crosspostService;
+ @Inject
+ WebApp webApp;
+ @Inject
+ PageTemplates templates;
+
+ private static final Logger logger = LoggerFactory.getLogger(NewMessage.class);
+
+ @RequestMapping(value = "/post", method = RequestMethod.GET)
+ protected void doGetNewMessage(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ Utils.sendTemporaryRedirect(response, "/login");
+ return;
+ }
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ templates.pageHead(out, visitor, "Написать", ""
+ + ""
+ + ""
+ + "");
+ templates.pageNavigation(out, visitor, null);
+
+ out.println("");
+
+ templates.pageFooter(request, out, visitor, false);
+ templates.pageEnd(out);
+ }
+ }
+
+ void printUserTags(PrintWriter out, com.juick.User visitor) {
+ List tags = tagService.getUserTagStats(visitor.getUid());
+
+ if (tags.isEmpty()) {
+ return;
+ }
+
+ int min = tags.get(0).getUsageCount();
+ int max = tags.get(0).getUsageCount();
+ for (int i = 1; i < tags.size(); i++) {
+ int usagecnt = tags.get(i).getUsageCount();
+ if (usagecnt < min) {
+ min = usagecnt;
+ }
+ if (usagecnt > max) {
+ max = usagecnt;
+ }
+ }
+ max -= min;
+
+ out.print("");
+ for (int i = 0; i < tags.size(); i++) {
+ if (i > 0) {
+ out.print(" ");
+ }
+ String taglink = StringUtils.EMPTY;
+ try {
+ taglink = "" + StringEscapeUtils.escapeHtml4(tags.get(i).getTag().getName()) + " ";
+ } catch (UnsupportedEncodingException e) {
+ }
+ int usagecnt = tags.get(i).getUsageCount();
+ if (usagecnt <= max / 5 + min) {
+ out.print("" + taglink + " ");
+ } else if (usagecnt <= max / 5 * 2 + min) {
+ out.print(taglink);
+ } else if (usagecnt <= max / 5 * 3 + min) {
+ out.print("" + taglink + " ");
+ } else if (usagecnt <= max / 5 * 4 + min) {
+ out.print("" + taglink + " ");
+ } else {
+ out.print("" + taglink + " ");
+ }
+ }
+ out.println("
");
+ }
+
+ @RequestMapping(value = "/post", method = RequestMethod.POST)
+ public void doPostMessage(HttpServletRequest request, HttpServletResponse response,
+ @RequestParam(required = false) String img,
+ @RequestParam(required = false) MultipartFile attach) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ String body = request.getParameter("body");
+ if (body == null || body.length() < 1 || body.length() > 4096) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ body = body.replace("\r", StringUtils.EMPTY);
+
+ List tags = webApp.parseTags(request.getParameter("tags"));
+
+ String attachmentFName = HttpUtils.receiveMultiPartFile(attach, webApp.getTmpDir());
+
+ if (StringUtils.isBlank(attachmentFName) && img != null && img.length() > 10) {
+ try {
+ URL imgUrl = new URL(img);
+ attachmentFName = HttpUtils.downloadImage(imgUrl);
+ } catch (Exception e) {
+ logger.error("DOWNLOAD ERROR", e);
+ throw new HttpBadRequestException();
+ }
+ }
+
+ String attachmentType = StringUtils.isNotEmpty(attachmentFName) ? attachmentFName.substring(attachmentFName.length() - 3) : null;
+ int mid = messagesService.createMessage(visitor.getUid(), body, attachmentType, tags);
+ subscriptionService.subscribeMessage(mid, visitor.getUid());
+
+ Message xmsg = new Message();
+ xmsg.setFrom(Jid.of("juick@juick.com"));
+ xmsg.setType(Message.Type.CHAT);
+ xmsg.setThread("juick-" + mid);
+ com.juick.Message jmsg = messagesService.getMessage(mid);
+ xmsg.addExtension(jmsg);
+ xmsg.addExtension(new Nickname("@" + jmsg.getUser().getName()));
+
+ if (StringUtils.isNotEmpty(attachmentFName)) {
+ String fname = mid + "." + attachmentType;
+ String attachmentURL = "http://i.juick.com/photos-1024/" + fname;
+
+ Path origName = Paths.get(webApp.getImgDir(), "p", fname);
+ Files.move(Paths.get(webApp.getTmpDir(), attachmentFName), origName);
+ Thumbnails.of(origName.toFile()).size(1024, 1024).outputQuality(0.9)
+ .toFile(Paths.get(webApp.getImgDir(), "photos-1024", fname).toFile());
+ Thumbnails.of(origName.toFile()).size(512, 512).outputQuality(0.9)
+ .toFile(Paths.get(webApp.getImgDir(), "photos-512", fname).toFile());
+ Thumbnails.of(origName.toFile()).size(160, 120).outputQuality(0.9)
+ .toFile(Paths.get(webApp.getImgDir(), "ps", fname).toFile());
+
+ body = attachmentURL + "\n" + body;
+ try {
+ xmsg.addExtension(new OobX(new URI(attachmentURL)));
+ } catch (URISyntaxException e) {
+ logger.warn("invalid uri: {} exception {}", attachmentURL, e);
+ }
+ }
+ if (webApp.getXmpp() != null) {
+
+ xmsg.setBody("@" + jmsg.getUser().getName() + ":" + jmsg.getTagsString() + "\n" + body + "\n\n#" + mid + " http://juick.com/" + mid);
+
+ xmsg.setTo(Jid.of("juick@s2s.juick.com"));
+ webApp.getXmpp().send(xmsg);
+
+ xmsg.setTo(Jid.of("juick@ws.juick.com"));
+ webApp.getXmpp().send(xmsg);
+
+ xmsg.setTo(Jid.of("juick@push.juick.com"));
+ webApp.getXmpp().send(xmsg);
+
+ xmsg.setTo(Jid.of("twitter@crosspost.juick.com"));
+ webApp.getXmpp().send(xmsg);
+ xmsg.setTo(Jid.of("fb@crosspost.juick.com"));
+ webApp.getXmpp().send(xmsg);
+
+ xmsg.setTo(Jid.of("jubo@nologin.ru"));
+ webApp.getXmpp().send(xmsg);
+ } else {
+ logger.warn("XMPP unavailable");
+ }
+
+ //
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ templates.pageHead(out, visitor, "Сообщение опубликовано", null);
+ templates.pageNavigation(out, visitor, null);
+
+ String hashtags = StringUtils.EMPTY;
+ String tagscomma = StringUtils.EMPTY;
+ for (int i = 0; i < jmsg.getTags().size(); i++) {
+ if (i > 0) {
+ hashtags += " ";
+ tagscomma += ",";
+ }
+ hashtags += "#" + jmsg.getTags().get(i);
+ tagscomma += jmsg.getTags().get(i);
+ }
+
+ String url = URLEncoder.encode("http://juick.com/" + mid, CharEncoding.UTF_8);
+ String sharetwi = hashtags + " " + body;
+ if (sharetwi.length() > 115) {
+ sharetwi = sharetwi.substring(0, 114) + "…";
+ }
+ sharetwi += " http://juick.com/" + mid;
+ String sharelj = URLEncoder.encode(body + "\n", CharEncoding.UTF_8) + url;
+
+ out.println("");
+ out.println("Сообщение опубликовано ");
+ out.println("Поделитесь своим новым постом в социальных сетях:
");
+ if (crosspostService.getTwitterTokens(visitor.getUid()).isPresent()) {
+ out.println("Отправить в Twitter
");
+ }
+ out.println("Отправить в LiveJournal
");
+ out.println("Отправить в ВКонтакте
");
+ if (crosspostService.getFacebookToken(visitor.getUid()).isPresent()) {
+ out.println("Отправить в Facebook
");
+ }
+ out.println("Отправить в Google+
");
+ out.println("Ссылка на сообщение: http://juick.com/" + mid + "
");
+ out.println(" ");
+
+ templates.pageHomeColumn(out, visitor);
+
+ templates.pageFooter(request, out, visitor, false);
+ templates.pageEnd(out);
+ }
+ }
+
+ @RequestMapping(value = "/comment", method = RequestMethod.POST)
+ public void doPostComment(HttpServletRequest request, HttpServletResponse response,
+ @RequestParam(required = false) String img,
+ @RequestParam(required = false) MultipartFile attach) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ int mid = NumberUtils.toInt(request.getParameter("mid"), 0);
+ if (mid == 0) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ com.juick.Message msg = messagesService.getMessage(mid);
+ if (msg == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ int rid = NumberUtils.toInt(request.getParameter("rid"), 0);
+ com.juick.Message reply = null;
+ if (rid > 0) {
+ reply = messagesService.getReply(mid, rid);
+ if (reply == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+ }
+
+ String body = request.getParameter("body");
+ if (body == null || body.length() < 1 || body.length() > 4096) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ body = body.replace("\r", StringUtils.EMPTY);
+
+ if ((msg.ReadOnly && msg.getUser().getUid() != visitor.getUid())
+ || userService.isInBLAny(msg.getUser().getUid(), visitor.getUid())
+ || (reply != null && userService.isInBLAny(reply.getUser().getUid(), visitor.getUid()))) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ String attachmentFName = HttpUtils.receiveMultiPartFile(attach, webApp.getTmpDir());
+
+ if (StringUtils.isBlank(attachmentFName) && img != null && img.length() > 10) {
+ try {
+ URL imgUrl = new URL(img);
+ attachmentFName = HttpUtils.downloadImage(imgUrl);
+ } catch (Exception e) {
+ logger.error("DOWNLOAD ERROR", e);
+ throw new HttpBadRequestException();
+ }
+ }
+
+ String attachmentType = StringUtils.isNotEmpty(attachmentFName) ? attachmentFName.substring(attachmentFName.length() - 3) : null;
+ int ridnew = messagesService.createReply(mid, rid, visitor.getUid(), body, attachmentType);
+ subscriptionService.subscribeMessage(mid, visitor.getUid());
+
+ Message xmsg = new Message();
+ xmsg.setFrom(Jid.of("juick@juick.com"));
+ xmsg.setType(Message.Type.CHAT);
+ xmsg.setThread("juick-" + mid);
+
+ com.juick.Message jmsg = messagesService.getReply(mid, ridnew);
+ xmsg.addExtension(jmsg);
+
+ String quote = reply != null ? reply.getText() : msg.getText();
+ if (quote.length() >= 50) {
+ quote = quote.substring(0, 47) + "...";
+ }
+ xmsg.addExtension(new Nickname("@" + jmsg.getUser().getName()));
+
+ if (StringUtils.isNotEmpty(attachmentFName)) {
+ String fname = mid + "-" + ridnew + "." + attachmentType;
+ String attachmentURL = "http://i.juick.com/photos-1024/" + fname;
+
+ Path origName = Paths.get(webApp.getImgDir(), "p", fname);
+ Files.move(Paths.get(webApp.getTmpDir(), attachmentFName), origName);
+ Thumbnails.of(origName.toFile()).size(1024, 1024).outputQuality(0.9)
+ .toFile(Paths.get(webApp.getImgDir(), "photos-1024", fname).toFile());
+ Thumbnails.of(origName.toFile()).size(512, 512).outputQuality(0.9)
+ .toFile(Paths.get(webApp.getImgDir(), "photos-512", fname).toFile());
+ Thumbnails.of(origName.toFile()).size(160, 120).outputQuality(0.9)
+ .toFile(Paths.get(webApp.getImgDir(), "ps", fname).toFile());
+
+ body = attachmentURL + "\n" + body;
+ try {
+ xmsg.addExtension(new OobX(new URI(attachmentURL)));
+ } catch (URISyntaxException e) {
+ logger.warn("invalid uri: {}, exception {}", attachmentURL, e);
+ }
+ }
+
+ if (webApp.getXmpp() != null) {
+
+ xmsg.setBody("Reply by @" + jmsg.getUser().getName() + ":\n>" + quote + "\n" + body + "\n\n#" +
+ mid + "/" + ridnew + " http://juick.com/" + mid + "#" + ridnew);
+
+ xmsg.setTo(Jid.of("juick@s2s.juick.com"));
+ webApp.getXmpp().send(xmsg);
+
+ xmsg.setTo(Jid.of("juick@ws.juick.com"));
+ webApp.getXmpp().send(xmsg);
+
+ xmsg.setTo(Jid.of("juick@push.juick.com"));
+ webApp.getXmpp().send(xmsg);
+ } else {
+ logger.warn("XMPP unavailable");
+ }
+
+ Utils.sendTemporaryRedirect(response, "/" + msg.getUser().getName() + "/" + mid + "#" + ridnew);
+ }
+
+ @RequestMapping(value = "/like", method = RequestMethod.POST)
+ public void doPostRecomm(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ int mid = NumberUtils.toInt(request.getParameter("mid"), 0);
+ if (mid == 0) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+ com.juick.Message msg = messagesService.getMessage(mid);
+ if (msg == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+ if (msg.getUser().getUid() == visitor.getUid()) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ boolean res = messagesService.recommendMessage(mid, visitor.getUid());
+
+ if (res) {
+ if (webApp.getXmpp() != null) {
+ Message xmsg = new Message();
+ xmsg.setFrom(Jid.of("juick@juick.com"));
+ xmsg.setTo(Jid.of("recomm@s2s.juick.com"));
+ com.juick.Message jmsg = new com.juick.Message();
+ jmsg.setMid(mid);
+ jmsg.setUser(visitor);
+ xmsg.addExtension(jmsg);
+ webApp.getXmpp().send(xmsg);
+ } else {
+ logger.warn("XMPP unavailable");
+ }
+
+ Utils.replyJSON(request, response, "{\"status\":\"ok\"}");
+ } else {
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/PM.java b/juick-www/src/main/java/com/juick/www/controllers/PM.java
new file mode 100644
index 00000000..56b688cf
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/PM.java
@@ -0,0 +1,163 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.service.PMQueriesService;
+import com.juick.service.TagService;
+import com.juick.service.UserService;
+import com.juick.util.MessageUtils;
+import com.juick.util.WebUtils;
+import com.juick.www.Utils;
+import com.juick.www.WebApp;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import rocks.xmpp.addr.Jid;
+import rocks.xmpp.core.stanza.model.Message;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class PM {
+ private static final Logger logger = LoggerFactory.getLogger(PM.class);
+
+ @Inject
+ PMQueriesService pmQueriesService;
+ @Inject
+ TagService tagService;
+ @Inject
+ UserService userService;
+ @Inject
+ WebApp webApp;
+
+ @RequestMapping(value = "/pm/inbox", method = RequestMethod.GET)
+ protected String doGetInbox(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ Utils.sendTemporaryRedirect(response, "/login");
+ }
+ String title = "PM: Inbox";
+ List msgs = pmQueriesService.getLastPMInbox(visitor.getUid());
+ msgs.forEach(m -> m.setText(MessageUtils.formatMessage(m.getText())));
+ model.addAttribute("title", title);
+ model.addAttribute("visitor", visitor);
+ model.addAttribute("msgs", msgs);
+ model.addAttribute("tags", tagService.getPopularTags());
+ return "views/pm_inbox";
+ }
+
+ @RequestMapping(value = "/pm/sent", method = RequestMethod.GET)
+ protected String doGetSent(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ Utils.sendTemporaryRedirect(response, "/login");
+ }
+ String title = "PM: Sent";
+ List msgs = pmQueriesService.getLastPMSent(visitor.getUid());
+
+ String uname = request.getParameter("uname");
+ if (WebUtils.isNotUserName(uname)) {
+ uname = StringUtils.EMPTY;
+ }
+
+ model.addAttribute("title", title);
+ model.addAttribute("visitor", visitor);
+ model.addAttribute("msgs", msgs);
+ model.addAttribute("tags", tagService.getPopularTags());
+ model.addAttribute("uname", uname);
+ return "views/pm_sent";
+ }
+
+ @RequestMapping(value = "/pm/send", method = RequestMethod.POST)
+ public void doPostPM(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0 || visitor.isBanned()) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ String uname = request.getParameter("uname");
+ if (uname.startsWith("@")) {
+ uname = uname.substring(1);
+ }
+ int uid = 0;
+ if (WebUtils.isUserName(uname)) {
+ uid = userService.getUIDbyName(uname);
+ }
+
+ String body = request.getParameter("body");
+ if (uid == 0 || body == null || body.length() < 1 || body.length() > 10240) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ if (userService.isInBLAny(uid, visitor.getUid())) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ if (pmQueriesService.createPM(visitor.getUid(), uid, body)) {
+ if (webApp.getXmpp() != null) {
+ Message msg = new Message();
+ msg.setFrom(Jid.of("juick@juick.com"));
+ msg.setTo(Jid.of(String.format("%d@push.juick.com", uid)));
+ com.juick.Message jmsg = new com.juick.Message();
+ jmsg.setUser(visitor);
+ jmsg.setText(body);
+ msg.addExtension(jmsg);
+ webApp.getXmpp().send(msg);
+
+ msg.setTo(Jid.of(String.format("%d@ws.juick.com", uid)));
+ webApp.getXmpp().send(msg);
+
+ List jids = userService.getJIDsbyUID(uid);
+ for (String jid : jids) {
+ Message mm = new Message();
+ mm.setTo(Jid.of(jid));
+ mm.setType(Message.Type.CHAT);
+ if (pmQueriesService.havePMinRoster(visitor.getUid(), jid)) {
+ mm.setFrom(Jid.of(jmsg.getUser().getName(), "juick.com", "Juick"));
+ mm.setBody(body);
+ } else {
+ mm.setFrom(Jid.of("juick", "juick.com", "Juick"));
+ mm.setBody("Private message from @" + jmsg.getUser().getName() + ":\n" + body);
+ }
+ webApp.getXmpp().send(mm);
+ }
+ } else {
+ logger.warn("XMPP unavailable");
+ }
+
+ Utils.sendTemporaryRedirect(response, "/pm/sent");
+
+ } else {
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java b/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java
new file mode 100644
index 00000000..3152d5fc
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java
@@ -0,0 +1,381 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.Message;
+import com.juick.server.helpers.TagStats;
+import com.juick.service.MessagesService;
+import com.juick.service.TagService;
+import com.juick.service.UserService;
+import com.juick.util.MessageUtils;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+import ru.sape.Sape;
+
+import javax.inject.Inject;
+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.stream.Collectors;
+
+/**
+ * @author Ugnich Anton
+ */
+public class PageTemplates {
+
+ private static final Logger logger = LoggerFactory.getLogger(PageTemplates.class);
+
+ public Sape sape = null;
+ protected 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;
+
+ @Inject
+ TagService tagService;
+ @Inject
+ MessagesService messagesService;
+ @Inject
+ UserService userService;
+
+ public void pageHead(PrintWriter out, com.juick.User visitor, String title, String headers) {
+ out.println("");
+ out.print("");
+ out.print("");
+ out.println(" ");
+ out.print(" ");
+ out.print("");
+ if (headers != null) {
+ out.print(headers);
+ }
+ out.print("" + title + " ");
+ out.println(" ");
+ out.println(" ");
+ out.println("");
+ out.println("");
+ out.flush();
+ if (visitor.getUid() > 0) {
+ out.println("");
+ } else {
+ out.println("");
+ }
+ }
+
+ public void pageNavigation(PrintWriter out, com.juick.User visitor, String search) {
+ out.println("");
+ }
+
+ public void pageHomeColumn(PrintWriter out, com.juick.User visitor) {
+ pageHomeColumn(out, visitor, false);
+ }
+
+ public void pageHomeColumn(PrintWriter out, com.juick.User visitor, boolean showAdv) {
+ if (tagsHTML == null) {
+ tagsHTML = formatPopularTags(80);
+ }
+
+ out.println("");
+ }
+
+ public String formatPopularTags(int cnt) {
+ List popularTags = tagService.getPopularTags().stream()
+ .map(t -> "" + StringEscapeUtils.escapeHtml4(t) + " ").collect(Collectors.toList());
+ return StringUtils.collectionToDelimitedString(popularTags, " ");
+ }
+
+ public void pageFooter(HttpServletRequest request, PrintWriter out, com.juick.User visitor, boolean sapeon) {
+ out.println("");
+
+ out.println("");
+ }
+
+ public void pageEnd(PrintWriter out) {
+ out.println("");
+ }
+
+ public String formatTags(List tags) {
+ String ret = org.apache.commons.lang3.StringUtils.EMPTY;
+ for (TagStats tag : tags) {
+ String tagName = StringEscapeUtils.escapeHtml4(tag.getTag().getName());
+ try {
+ ret += "" + tagName + " ";
+ } catch (UnsupportedEncodingException e) {
+ }
+ }
+
+ return ret;
+ }
+
+ public 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 = sdfFull.format(fulldate);
+ synchronized (sdfSQL) {
+ try {
+ 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);
+ }
+ } catch (Exception e) {
+ logger.error("PARSE EXCEPTION: {}, exception {}", fulldate, e);
+ }
+ }
+ return ret;
+ }
+ }
+
+ public String formatJSLocalTime(Date ts) {
+ return "";
+ }
+
+ public 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 + " ответов";
+ }
+ }
+
+ public void printMessages(PrintWriter out, com.juick.User user, List mids, com.juick.User visitor, int YandexID, int ad_mid) {
+ List msgs = messagesService.getMessages(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 = userService.checkBL(visitor.getUid(), blUIDs);
+ }
+
+ for (Message msg : msgs) {
+
+ List tags = tagService.getMessageTags(msg.getMid());
+ String tagsStr = formatTags(tags);
+ if (msg.ReadOnly) {
+ tagsStr += "readonly ";
+ }
+ if (msg.getPrivacy() < 0) {
+ tagsStr += "friends ";
+ }
+ if (msg.getMid() == ad_mid) {
+ tagsStr += "реклама ";
+ }
+
+ String txt;
+ if (msg.getTags().stream().anyMatch(t -> t.getName().equals("code"))) {
+ txt = MessageUtils.formatMessageCode(msg.getText());
+ } else {
+ txt = MessageUtils.formatMessage(msg.getText());
+ }
+
+ out.println("");
+ out.println(" ");
+
+ if (msg.getAttachmentType() != null) {
+ String fname = msg.getMid() + "." + msg.getAttachmentType();
+ out.println("
");
+ }
+ out.println(" " + txt + "
");
+ if (msg.getAttachmentType() != null) {
+ out.println("
");
+ }
+ out.print(" ");
+ msg.ReadOnly |= blUIDs.contains(msg.getUser().getUid());
+ if (visitor.getUid() == 0) {
+ out.print("Рекомендовать ");
+ } else {
+ out.print("Рекомендовать ");
+ }
+ if (visitor.getUid() == 0 && !msg.ReadOnly) {
+ out.print("Комментировать ");
+ } else if (visitor.getUid() > 0 && (!msg.ReadOnly || visitor.getUid() == msg.getUser().getUid())) {
+ out.print(" ");
+ }
+ if (visitor.getUid() > 0 && msg.getPrivacy() < 0 && msg.getUser().getUid() == visitor.getUid()) {
+ out.print(" Открыть доступ ");
+ }
+ if (visitor.getUid() > 0 && visitor.getUid() == 3694) {
+ out.print(" + ");
+ out.print(" - ");
+ out.print(" x ");
+ }
+ out.println(" ");
+
+ out.print(" ");
+ if (msg.getLikes() > 0) {
+ out.print(" " + msg.getLikes() + " ");
+ }
+ if (msg.getReplies() > 0) {
+ out.print(" " + msg.getReplies() + " ");
+ }
+ out.println(" ");
+ out.print(" ");
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/RSS.java b/juick-www/src/main/java/com/juick/www/controllers/RSS.java
new file mode 100644
index 00000000..79fd8e67
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/RSS.java
@@ -0,0 +1,66 @@
+/*
+ * Juick
+ * Copyright (C) 2008-2013, ugnich
+ *
+ * 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.www.controllers;
+
+import com.juick.Message;
+import com.juick.server.util.HttpNotFoundException;
+import com.juick.service.MessagesService;
+import com.juick.service.UserService;
+import com.juick.util.DateFormattersHolder;
+import com.juick.util.MessageUtils;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ *
+ * @author ugnich
+ */
+@Controller
+public class RSS {
+ @Inject
+ UserService userService;
+ @Inject
+ MessagesService messagesService;
+
+ @RequestMapping(value = "/rss/{uname}", method = RequestMethod.GET)
+ protected String doGet(JdbcTemplate sql, HttpServletResponse response,
+ @PathVariable String uname, ModelMap model) {
+ int uid = userService.getUIDbyName(uname);
+ List mids = messagesService.getUserBlog(uid, 0, 0);
+ if (mids.isEmpty()) {
+ throw new HttpNotFoundException();
+ }
+
+ List msgs = messagesService.getMessages(mids);
+
+ msgs.forEach(m -> MessageUtils.formatMessage(m.getText()));
+
+ model.addAttribute("user", msgs.stream().findFirst().get().getUser());
+ model.addAttribute("msgs", msgs);
+ model.addAttribute("sdfRSS", DateFormattersHolder.getRssFormatterInstance());
+ return "webapp/WEB-INF/layouts/rss";
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/Settings.java b/juick-www/src/main/java/com/juick/www/controllers/Settings.java
new file mode 100644
index 00000000..63cf99e6
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/Settings.java
@@ -0,0 +1,287 @@
+/*
+ * Juick
+ * Copyright (C) 2008-2013, 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.www.controllers;
+
+import com.juick.server.helpers.NotifyOpts;
+import com.juick.server.helpers.UserInfo;
+import com.juick.server.util.HttpBadRequestException;
+import com.juick.server.util.HttpUtils;
+import com.juick.service.*;
+import com.juick.util.UserUtils;
+import com.juick.www.WebApp;
+import net.coobird.thumbnailator.Thumbnails;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.inject.Inject;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class Settings {
+ private static final Logger logger = LoggerFactory.getLogger(Settings.class);
+
+ @Inject
+ WebApp webApp;
+ @Inject
+ TagService tagService;
+ @Inject
+ UserService userService;
+ @Inject
+ CrosspostService crosspostService;
+ @Inject
+ SubscriptionService subscriptionService;
+ @Inject
+ EmailService emailService;
+ @Inject
+ TelegramService telegramService;
+
+ @RequestMapping(value = "/settings", method = RequestMethod.GET)
+ protected String doGet(HttpServletRequest request, HttpServletResponse response, ModelMap model) throws IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ response.sendRedirect("/login");
+ }
+ List pages = Arrays.asList("main", "password", "about", "auth-email", "privacy");
+ String page = request.getParameter("page");
+ if (StringUtils.isEmpty(page) || !pages.contains(page)) {
+ page = "main";
+ }
+
+ model.addAttribute("title", "Настройки");
+ model.addAttribute("visitor", visitor);
+ model.addAttribute("tags", tagService.getPopularTags());
+ model.addAttribute("auths", userService.getAuthCodes(visitor));
+ model.addAttribute("eopts", userService.getEmailOpts(visitor));
+ model.addAttribute("ehash", userService.getEmailHash(visitor));
+ model.addAttribute("emails", userService.getEmails(visitor));
+ model.addAttribute("jids", userService.getAllJIDs(visitor));
+ List hours = IntStream.rangeClosed(0, 23).boxed()
+ .map(i -> StringUtils.leftPad(String.format("%d", i), 2, "0")).collect(Collectors.toList());
+ model.addAttribute("hours", hours);
+ model.addAttribute("fbstatus", crosspostService.getFbCrossPostStatus(visitor.getUid()).isCrosspostEnabled());
+ model.addAttribute("twitter_name", crosspostService.getTwitterName(visitor.getUid()));
+ model.addAttribute("telegram_name", crosspostService.getTelegramName(visitor.getUid()));
+ model.addAttribute("notify_options", subscriptionService.getNotifyOptions(visitor));
+ model.addAttribute("userinfo", userService.getUserInfo(visitor));
+ if (page.equals("auth-email")) {
+ if (emailService.verifyAddressByCode(visitor.getUid(), request.getParameter("code"))) {
+ ;
+ model.addAttribute("result", "OK!");
+ } else {
+ model.addAttribute("result", "Sorry, code unknown.");
+ }
+ }
+ return String.format("views/settings_%s", page);
+ }
+
+ @RequestMapping(value = "/settings", method = RequestMethod.POST)
+ protected String doPost(HttpServletRequest request, HttpServletResponse response,
+ @RequestParam(required = false) MultipartFile avatar,
+ ModelMap model)
+ throws IOException, ServletException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0) {
+ throw new HttpBadRequestException();
+ }
+ List pages = Arrays.asList("main", "password", "about", "email", "email-add", "email-del",
+ "email-subscr", "auth-email", "privacy", "jid-del", "twitter-del", "telegram-del", "facebook-disable",
+ "facebook-enable", "vk-del");
+ String page = request.getParameter("page");
+ if (StringUtils.isEmpty(page) || !pages.contains(page)) {
+ throw new HttpBadRequestException();
+ }
+ String result = StringUtils.EMPTY;
+ switch (page) {
+ case "password":
+ if (userService.updatePassword(visitor, request.getParameter("password"))) {
+ result = "Password has been changed.
";
+ String hash = userService.getHashByUID(visitor.getUid());
+ Cookie c = new Cookie("hash", hash);
+ c.setMaxAge(365 * 24 * 60 * 60);
+ response.addCookie(c);
+ }
+ break;
+ case "main":
+ NotifyOpts opts = new NotifyOpts();
+ opts.setRepliesEnabled(StringUtils.isNotEmpty(request.getParameter("jnotify")));
+ opts.setSubscriptionsEnabled(StringUtils.isNotEmpty(request.getParameter("subscr_notify")));
+ opts.setRecommendationsEnabled(StringUtils.isNotEmpty(request.getParameter("recomm")));
+ if (subscriptionService.setNotifyOptions(visitor, opts)) {
+ result = "Notification options has been updated
";
+ }
+ break;
+ case "about":
+ UserInfo info = new UserInfo();
+ info.setFullName(request.getParameter("fullname"));
+ info.setCountry(request.getParameter("country"));
+ info.setUrl(request.getParameter("url"));
+ info.setDescription(request.getParameter("descr"));
+ String avatarTmpPath = HttpUtils.receiveMultiPartFile(avatar, webApp.getTmpDir());
+ if (StringUtils.isNotEmpty(avatarTmpPath)) {
+ String originalExtension = FilenameUtils.getExtension(avatarTmpPath);
+ String originalName = String.format("%s.%s", visitor.getUid(), originalExtension);
+ String targetName = String.format("%s.png", visitor.getUid());
+ Path ao = Paths.get(webApp.getImgDir(), "ao", originalName);
+ Path a = Paths.get(webApp.getImgDir(), "a", targetName);
+ Path as = Paths.get(webApp.getImgDir(), "as", targetName);
+ Files.move(Paths.get(webApp.getTmpDir(), avatarTmpPath), ao, StandardCopyOption.REPLACE_EXISTING);
+ Thumbnails.of(ao.toFile()).size(96, 96).toFile(a.toFile());
+ Thumbnails.of(ao.toFile()).size(32, 32).toFile(as.toFile());
+ }
+ if (userService.updateUserInfo(visitor, info)) {
+ result = String.format("Your info is updated.
Back to blog .
", visitor.getName());
+ }
+ break;
+ case "jid-del":
+ // FIXME: stop using ugnich-csv in parameters
+ String[] params = request.getParameter("delete").split(";", 2);
+ boolean res = false;
+ if (params[0].equals("xmpp")) {
+ res = userService.deleteJID(visitor.getUid(), params[1]);
+ } else if (params[0].equals("xmpp-unauth")) {
+ res = userService.unauthJID(visitor.getUid(), params[1]);
+ }
+ if (res) {
+ result = "Deleted. Back .
";
+ } else {
+ result = "Error
";
+ }
+ break;
+ case "email":
+ String newHash = userService.updateSecretEmail(visitor);
+ if (StringUtils.isNotEmpty(newHash)) {
+ result = String.format("New secret email: %s@mail.juick.com
" +
+ "Back .
", newHash);
+ } else {
+ throw new HttpBadRequestException();
+ }
+ break;
+ case "email-add":
+ try {
+ emailService.verifyAddressByCode(visitor.getUid(), request.getParameter("account"));
+ } catch (EmptyResultDataAccessException e) {
+ String authCode = UserUtils.generateHash(8);
+ if (emailService.addVerificationCode(visitor.getUid(), request.getParameter("account"), authCode)) {
+ Session session = Session.getDefaultInstance(System.getProperties());
+ try {
+ MimeMessage message = new MimeMessage(session);
+ message.setFrom(new InternetAddress("noreply@mail.juick.com"));
+ message.addRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("account")));
+ message.setSubject("Juick authorization link");
+ message.setText(String.format("Follow link to attach this email to Juick account:\n" +
+ "http://juick.com/settings?page=auth-email&code=%s\n\n" +
+ "If you don't know, what this mean - just ignore this mail.\n", authCode));
+ Transport.send(message);
+ result = "Authorization link has been sent to your email. Follow it to proceed.
" +
+ "Back
";
+
+ } catch (MessagingException ex) {
+ logger.error("mail exception", ex);
+ throw new HttpBadRequestException();
+ }
+ }
+ }
+ break;
+ case "email-del":
+ if (emailService.deleteEmail(visitor.getUid(), request.getParameter("account"))) {
+ result = "Deleted. Back .
";
+ } else {
+ result = "An error occured while deleting.
";
+ }
+ break;
+ case "email-subscr":
+ if (emailService.setSubscriptionHour(visitor.getUid(), request.getParameter("account"),
+ request.getParameter("time"))) {
+ result = String.format("Saved! Will send to %s at %s:00 GMT ." +
+ "
Back
", request.getParameter("account"),
+ request.getParameter("time"));
+ } else {
+ result = "Disabled.
Back
";
+ }
+ break;
+ case "twitter-del":
+ crosspostService.deleteTwitterToken(visitor.getUid());
+ for (Cookie cookie : request.getCookies()) {
+ if (cookie.getName().equals("request_token")) {
+ cookie.setMaxAge(0);
+ response.addCookie(cookie);
+ }
+ if (cookie.getName().equals("request_token_secret")) {
+ cookie.setMaxAge(0);
+ response.addCookie(cookie);
+ }
+ }
+ result = "Back
";
+ break;
+ case "telegram-del":
+ telegramService.deleteTelegramUser(visitor.getUid());
+ result = "Back
";
+ break;
+ case "facebook-disable":
+ crosspostService.disableFBCrosspost(visitor.getUid());
+ result = "Back
";
+ break;
+ case "facebook-enable":
+ crosspostService.enableFBCrosspost(visitor.getUid());
+ result = "Back
";
+ break;
+ case "vk-del":
+ crosspostService.deleteVKUser(visitor.getUid());
+ result = "Back
";
+ break;
+ default:
+ throw new HttpBadRequestException();
+ }
+
+ model.addAttribute("title", "Настройки");
+ model.addAttribute("visitor", visitor);
+ model.addAttribute("result", result);
+ return "views/settings_result";
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/SignUp.java b/juick-www/src/main/java/com/juick/www/controllers/SignUp.java
new file mode 100644
index 00000000..937a3242
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/SignUp.java
@@ -0,0 +1,170 @@
+/*
+ * Juick
+ * Copyright (C) 2008-2013, 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.www.controllers;
+
+import com.juick.server.util.HttpBadRequestException;
+import com.juick.server.util.HttpForbiddenException;
+import com.juick.service.CrosspostService;
+import com.juick.service.UserService;
+import com.juick.www.Utils;
+import com.juick.www.WebApp;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class SignUp {
+
+ @Inject
+ WebApp webApp;
+ @Inject
+ UserService userService;
+ @Inject
+ CrosspostService crosspostService;
+
+
+ @RequestMapping(value = "/signup", method = RequestMethod.GET)
+ protected String doGet(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+
+ String type = request.getParameter("type");
+ String hash = request.getParameter("hash");
+ if (type == null || type.isEmpty() || hash == null || hash.isEmpty() || hash.length() > 36
+ || !type.matches("^[a-zA-Z0-9\\-]+$") || !hash.matches("^[a-zA-Z0-9\\-]+$")) {
+ throw new HttpBadRequestException();
+ }
+
+ String account = null;
+ switch (type) {
+ case "fb":
+ account = crosspostService.getFacebookNameByHash(hash);
+ break;
+ case "vk":
+ account = crosspostService.getVKNameByHash(hash);
+ break;
+ case "xmpp":
+ account = crosspostService.getJIDByHash(hash);
+ break;
+ case "durov":
+ account = crosspostService.getTelegramNameByHash(hash);
+ break;
+ }
+ if (account == null) {
+ throw new HttpBadRequestException();
+ }
+
+ model.addAttribute("title", "Новый пользователь");
+ model.addAttribute("visitor", visitor);
+ model.addAttribute("account", account);
+ model.addAttribute("type", type);
+ model.addAttribute("hash", hash);
+ return "views/signup";
+ }
+
+ @RequestMapping(value = "/signup", method = RequestMethod.POST)
+ protected String doPost(HttpServletRequest request, HttpServletResponse response) {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ int uid = 0;
+
+ String type = request.getParameter("type");
+ String hash = request.getParameter("hash");
+ if (type == null || type.isEmpty() || hash == null || hash.isEmpty() || hash.length() > 36 || !type.matches("^[a-zA-Z0-9\\-]+$") || !hash.matches("^[a-zA-Z0-9\\-]+$")) {
+ throw new HttpBadRequestException();
+ }
+
+ String action = request.getParameter("action");
+ if (action.charAt(0) == 'l') {
+
+ if (visitor.getUid() == 0) {
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+ if (username == null || password == null || username.length() > 32 || password.isEmpty()) {
+ throw new HttpBadRequestException();
+ }
+ uid = userService.checkPassword(username, password);
+ } else {
+ uid = visitor.getUid();
+ }
+
+ if (uid <= 0) {
+ throw new HttpForbiddenException();
+ }
+
+ if (!(type.charAt(0) == 'f' && crosspostService.setFacebookUser(hash, uid))
+ && !(type.charAt(0) == 'v' && crosspostService.setVKUser(hash, uid))
+ && !(type.charAt(0) == 'd' && crosspostService.setTelegramUser(hash, uid))
+ && !(type.charAt(0) == 'x' && crosspostService.setJIDUser(hash, uid))) {
+ throw new HttpBadRequestException();
+ }
+
+ } else { // Create new account
+ String username = request.getParameter("username");
+ String password = request.getParameter("password");
+ if (username == null || password == null || username.length() < 2 || username.length() > 16 || !username.matches("^[a-zA-Z0-9\\-]+$") || password.length() < 6 || password.length() > 32) {
+ throw new HttpBadRequestException();
+ }
+
+ // CHECK USERNAME
+
+ uid = userService.createUser(username, password);
+ if (uid <= 0) {
+ throw new HttpBadRequestException();
+ }
+
+ if (!(type.charAt(0) == 'f' && crosspostService.setFacebookUser(hash, uid))
+ && !(type.charAt(0) == 'v' && crosspostService.setVKUser(hash, uid))
+ && !(type.charAt(0) == 'd' && crosspostService.setTelegramUser(hash, uid))
+ && !(type.charAt(0) == 'x' && crosspostService.setJIDUser(hash, uid))) {
+ throw new HttpBadRequestException();
+ }
+
+ int ref = 0;
+ String sRef = Utils.getCookie(request, "ref");
+ if (sRef != null) {
+ try {
+ ref = Integer.parseInt(sRef);
+ } catch (Exception e) {
+ }
+ }
+
+ if (ref > 0) {
+ crosspostService.setUserRef(uid, ref);
+ }
+
+ visitor = null;
+ }
+
+ if (visitor == null) {
+ hash = userService.getHashByUID(uid);
+ Cookie c = new Cookie("hash", hash);
+ c.setMaxAge(365 * 24 * 60 * 60);
+ response.addCookie(c);
+ }
+ return "redirect:/";
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java b/juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java
new file mode 100644
index 00000000..901a8362
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/TwitterAuth.java
@@ -0,0 +1,103 @@
+package com.juick.www.controllers;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.github.scribejava.apis.TwitterApi;
+import com.github.scribejava.core.builder.ServiceBuilder;
+import com.github.scribejava.core.model.OAuth1AccessToken;
+import com.github.scribejava.core.model.OAuth1RequestToken;
+import com.github.scribejava.core.model.OAuthRequest;
+import com.github.scribejava.core.model.Verb;
+import com.github.scribejava.core.oauth.OAuth10aService;
+import com.juick.service.UserService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Created by vt on 01.12.2015.
+ */
+@Controller
+public class TwitterAuth {
+
+ private final static String VERIFY_URL = "https://api.twitter.com/1.1/account/verify_credentials.json";
+
+ private String consumerKey, consumerSecret;
+
+ private final ObjectMapper mapper;
+
+ @Inject
+ UserService userService;
+
+ @Inject
+ public TwitterAuth(Environment env) {
+ this.consumerKey = env.getProperty("twitter_consumer_key");
+ this.consumerSecret = env.getProperty("twitter_consumer_secret");
+ mapper = new ObjectMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
+ }
+
+ @RequestMapping(value = "/_twitter", method = RequestMethod.GET)
+ protected void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ String hash = StringUtils.EMPTY, request_token = StringUtils.EMPTY, request_token_secret = StringUtils.EMPTY;
+ String verifier = request.getParameter("oauth_verifier");
+ Cookie[] cookies = request.getCookies();
+ for (Cookie cookie : cookies) {
+ if (cookie.getName().equals("hash")) {
+ hash = cookie.getValue();
+ }
+ if (cookie.getName().equals("request_token")) {
+ request_token = cookie.getValue();
+ }
+ if (cookie.getName().equals("request_token_secret")) {
+ request_token_secret = cookie.getValue();
+ }
+ }
+ com.juick.User user = userService.getUserByHash(hash);
+ if ( user == null || user.getUid() == 0) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ OAuth10aService oAuthService = new ServiceBuilder()
+ .apiKey(consumerKey)
+ .apiSecret(consumerSecret)
+ .callback("http://juick.com/_twitter")
+ .build(TwitterApi.instance());
+
+ if (request_token.isEmpty() && request_token_secret.isEmpty()
+ && (verifier == null || verifier.isEmpty())) {
+ OAuth1RequestToken requestToken = oAuthService.getRequestToken();
+ String authUrl = oAuthService.getAuthorizationUrl(requestToken);
+ response.addCookie(new Cookie("request_token", requestToken.getToken()));
+ response.addCookie(new Cookie("request_token_secret", requestToken.getTokenSecret()));
+ response.setStatus(HttpServletResponse.SC_FOUND);
+ response.setHeader("Location", authUrl);
+ } else {
+ if (verifier != null && verifier.length() > 0) {
+ OAuth1RequestToken requestToken = new OAuth1RequestToken(request_token, request_token_secret);
+ OAuth1AccessToken accessToken = oAuthService.getAccessToken(requestToken, verifier);
+ OAuthRequest oAuthRequest = new OAuthRequest(Verb.GET, VERIFY_URL, oAuthService.getConfig());
+ oAuthService.signRequest(accessToken, oAuthRequest);
+ com.juick.www.twitter.User twitterUser = mapper.readValue(oAuthRequest.send().getBody(), com.juick.www.twitter.User.class);
+ if (userService.linkTwitterAccount(user, accessToken.getToken(), accessToken.getTokenSecret(),
+ twitterUser.getScreenName())) {
+ response.setStatus(HttpServletResponse.SC_FOUND);
+ response.setHeader("Location", "http://juick.com/settings");
+ } else {
+ response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/User.java b/juick-www/src/main/java/com/juick/www/controllers/User.java
new file mode 100644
index 00000000..d3406f4e
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/User.java
@@ -0,0 +1,368 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.server.helpers.TagStats;
+import com.juick.service.MessagesService;
+import com.juick.service.TagService;
+import com.juick.service.UserService;
+import com.juick.www.Utils;
+import com.juick.www.WebApp;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class User {
+ @Inject
+ WebApp webApp;
+ @Inject
+ UserService userService;
+ @Inject
+ TagService tagService;
+ @Inject
+ MessagesService messagesService;
+ @Inject
+ PageTemplates templates;
+
+ @RequestMapping("/{uname}/")
+ protected void doGetBlog(HttpServletRequest request, HttpServletResponse response,
+ @PathVariable String uname) throws IOException {
+ com.juick.User user = userService.getUserByName(uname);
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.isBanned()) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ List mids;
+
+ String paramShow = request.getParameter("show");
+
+ com.juick.Tag paramTag = null;
+ String paramTagStr = request.getParameter("tag");
+ if (paramTagStr != null) {
+ if (paramTagStr.length() < 64) {
+ paramTag = tagService.getTag(paramTagStr, false);
+ }
+ if (paramTag == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ } else if (!paramTag.getName().equals(paramTagStr)) {
+ String url = "/" + user.getName() + "/?tag=" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8);
+ Utils.sendPermanentRedirect(response, url);
+ return;
+ }
+ }
+
+ int paramBefore = 0;
+ String paramBeforeStr = request.getParameter("before");
+ if (paramBeforeStr != null) {
+ try {
+ paramBefore = Integer.parseInt(paramBeforeStr);
+ } catch (NumberFormatException e) {
+ }
+ }
+
+ String paramSearch = request.getParameter("search");
+ if (paramSearch != null && paramSearch.length() > 64) {
+ paramSearch = null;
+ }
+
+ int privacy = 0;
+ if (visitor.getUid() > 0) {
+ if (user.getUid() == visitor.getUid() || visitor.getUid() == 1) {
+ privacy = -3;
+ } else if (userService.isInWL(user.getUid(), visitor.getUid())) {
+ privacy = -2;
+ }
+ }
+
+ String title;
+ if (paramShow == null) {
+ if (paramTag != null) {
+ title = "Блог " + user.getName() + ": *" + StringEscapeUtils.escapeHtml4(paramTag.getName());
+ mids = messagesService.getUserTag(user.getUid(), paramTag.TID, privacy, paramBefore);
+ } else if (paramSearch != null) {
+ title = "Блог " + user.getName() + ": " + StringEscapeUtils.escapeHtml4(paramSearch);
+ mids = messagesService.getUserSearch(user.getUid(), Utils.encodeSphinx(paramSearch), privacy, paramBefore);
+ } else {
+ title = "Блог " + user.getName();
+ mids = messagesService.getUserBlog(user.getUid(), privacy, paramBefore);
+ }
+ } else if (paramShow.equals("recomm")) {
+ title = "Рекомендации " + user.getName();
+ mids = messagesService.getUserRecommendations(user.getUid(), paramBefore);
+ } else if (paramShow.equals("photos")) {
+ title = "Фотографии " + user.getName();
+ mids = messagesService.getUserPhotos(user.getUid(), privacy, paramBefore);
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ String head = " ";
+ if (paramTag != null && tagService.getTagNoIndex(paramTag.TID)) {
+ head += " ";
+ } else if (paramBefore > 0 || paramShow != null) {
+ head += " ";
+ }
+ templates.pageHead(out, visitor, title, head);
+ templates.pageNavigation(out, visitor, null);
+ pageUserColumn(out, user, visitor);
+
+ if (mids.size() > 0) {
+ out.println("");
+
+ if (paramTag != null) {
+ out.println("← Все записи с тегом " +
+ StringEscapeUtils.escapeHtml4(paramTag.getName()) + "
");
+ }
+
+ templates.printMessages(out, user, mids, visitor, visitor.getUid() == 0 ? 4 : 5, 0);
+
+ if (mids.size() >= 20) {
+ String nextpage = "?before=" + mids.get(mids.size() - 1);
+ if (paramShow != null) {
+ nextpage += "&show=" + paramShow;
+ }
+ if (paramTag != null) {
+ nextpage += "&tag=" + URLEncoder.encode(paramTag.getName(), CharEncoding.UTF_8);
+ }
+ if (paramSearch != null) {
+ nextpage += "&search=" + URLEncoder.encode(paramSearch, CharEncoding.UTF_8);
+ }
+ out.println("Читать дальше →
");
+ }
+
+ out.println(" ");
+ }
+
+ templates.pageFooter(request, out, visitor, true);
+ templates.pageEnd(out);
+ }
+ }
+
+ @RequestMapping(value = "/{uname}/tags", method = RequestMethod.GET)
+ protected void doGetTags(HttpServletRequest request, HttpServletResponse response,
+ @PathVariable String uname) throws IOException {
+ com.juick.User user = userService.getUserByName(uname);
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.isBanned()) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ String head = " ";
+ templates.pageHead(out, visitor, "Теги " + user.getName(), head);
+ templates.pageNavigation(out, visitor, null);
+ pageUserColumn(out, user, visitor);
+
+ out.println("");
+ out.println("" + pageUserTags(user, visitor, 0) + "
");
+ out.println(" ");
+
+ templates.pageFooter(request, out, visitor, false);
+ templates.pageEnd(out);
+ }
+ }
+
+ @RequestMapping(value = "/{uname}/friends", method = RequestMethod.GET)
+ protected void doGetFriends(HttpServletRequest request, HttpServletResponse response,
+ @PathVariable String uname) throws ServletException, IOException {
+ com.juick.User user = userService.getUserByName(uname);
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.isBanned()) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ String head = " ";
+ templates.pageHead(out, visitor, "Подписки " + user.getName(), head);
+ templates.pageNavigation(out, visitor, null);
+ pageUserColumn(out, user, visitor);
+
+ out.println("");
+ out.println("");
+
+ List friends = userService.getUserFriends(user.getUid());
+ for (int i = 0; i < friends.size(); i++) {
+ if (i % 3 == 0 && i > 0) {
+ out.print(" ");
+ }
+ out.print(" "
+ + friends.get(i).getName() + " ");
+ }
+
+ out.println("
");
+ out.println(" ");
+
+ templates.pageFooter(request, out, visitor, false);
+ templates.pageEnd(out);
+ }
+ }
+
+ @RequestMapping(value = "/{uname}/readers", method = RequestMethod.GET)
+ protected void doGetReaders(HttpServletRequest request, HttpServletResponse response,
+ @PathVariable String uname) throws ServletException, IOException {
+ com.juick.User user = userService.getUserByName(uname);
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.isBanned()) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ String head = " ";
+ templates.pageHead(out, visitor, "Читатели " + user.getName(), head);
+ templates.pageNavigation(out, visitor, null);
+ pageUserColumn(out, user, visitor);
+
+ out.println("");
+ out.println("");
+
+ List readers = userService.getUserReaders(user.getUid());
+ for (int i = 0; i < readers.size(); i++) {
+ if (i % 3 == 0 && i > 0) {
+ out.print(" ");
+ }
+ out.print(" "
+ + readers.get(i).getName() + " ");
+ }
+
+ out.println("
");
+ out.println(" ");
+
+ templates.pageFooter(request, out, visitor, false);
+ templates.pageEnd(out);
+ }
+ }
+
+ public void pageUserColumn(PrintWriter out, com.juick.User user, com.juick.User visitor) {
+ out.println("");
+ out.println(" ");
+ if (visitor.getUid() > 0 && visitor.getUid() != user.getUid()) {
+ out.println(" ");
+ } else {
+ out.println(" ");
+ }
+ out.println(" ");
+ out.println(" ");
+ out.println(" ");
+ out.println("
");
+ out.println(" ");
+ out.println(" " + pageUserTags(user, visitor, 20) + "...
");
+ out.println(" ");
+ out.println(" ");
+
+ List
iread = userService.getUserReadLeastPopular(user.getUid(), 8);
+ if (!iread.isEmpty()) {
+ out.println("");
+ for (int i = 0; i < iread.size(); i++) {
+ if (i == 4) {
+ out.println(" ");
+ }
+ com.juick.User u = iread.get(i);
+ out.println(" ");
+ }
+ out.println("
");
+ }
+
+ out.println(" ");
+ out.println(" ");
+ }
+
+ public String pageUserTags(com.juick.User user, com.juick.User visitor, int cnt) {
+ List tags = tagService.getUserTagStats(user.getUid()).stream()
+ .sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).collect(Collectors.toList());
+ int maxUsageCnt = tags.stream().map(TagStats::getUsageCount).max(Comparator.naturalOrder()).orElse(0);
+ String ret = StringUtils.EMPTY;
+ int count = cnt > 0 ? Math.min(tags.size(), cnt) : tags.size();
+ for (int i = 0; i < count; i++) {
+ String tag = StringEscapeUtils.escapeHtml4(tags.get(i).getTag().getName());
+ try {
+ tag = "" + tag + " ";
+ } catch (UnsupportedEncodingException e) {
+ }
+
+ if (tags.get(i).getUsageCount() > maxUsageCnt / 3 * 2) {
+ ret += "" + tag + " ";
+ } else if (tags.get(i).getUsageCount() > maxUsageCnt / 3) {
+ ret += "" + tag + " ";
+ } else {
+ ret += tag + " ";
+ }
+ }
+ return ret;
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/UserThread.java b/juick-www/src/main/java/com/juick/www/controllers/UserThread.java
new file mode 100644
index 00000000..4020e149
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/UserThread.java
@@ -0,0 +1,374 @@
+/*
+ * 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.www.controllers;
+
+import com.juick.Message;
+import com.juick.server.helpers.TagStats;
+import com.juick.service.MessagesService;
+import com.juick.service.TagService;
+import com.juick.service.UserService;
+import com.juick.util.MessageUtils;
+import com.juick.www.WebApp;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Ugnich Anton
+ */
+@Controller
+public class UserThread {
+
+ @Inject
+ WebApp webApp;
+ @Inject
+ MessagesService messagesService;
+ @Inject
+ UserService userService;
+ @Inject
+ TagService tagService;
+ @Inject
+ PageTemplates templates;
+
+ @RequestMapping(value = "/{uname}/{mid}", method = RequestMethod.GET)
+ protected void doGetThread(HttpServletRequest request, HttpServletResponse response,
+ @PathVariable int mid) throws ServletException, IOException {
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+
+ if (!messagesService.canViewThread(mid, visitor.getUid())) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+
+ com.juick.Message msg = messagesService.getMessage(mid);
+
+ boolean listview = false;
+ String paramView = request.getParameter("view");
+ if (paramView != null) {
+ if (paramView.equals("list")) {
+ listview = true;
+ if (visitor.getUid() > 0) {
+ userService.setUserOptionInt(visitor.getUid(), "repliesview", 1);
+ }
+ } else if (paramView.equals("tree") && visitor.getUid() > 0) {
+ userService.setUserOptionInt(visitor.getUid(), "repliesview", 0);
+ }
+ } else if (visitor.getUid() > 0 && userService.getUserOptionInt(visitor.getUid(), "repliesview", 0) == 1) {
+ listview = true;
+ }
+
+ String title = msg.getUser().getName() + ": " + msg.getTagsString();
+
+ response.setContentType("text/html; charset=UTF-8");
+ try (PrintWriter out = response.getWriter()) {
+ String headers = " ";
+ if (paramView != null) {
+ headers += " ";
+ }
+ if (msg.Hidden) {
+ headers += " ";
+ }
+ templates.pageHead(out, visitor, title, headers);
+ templates.pageNavigation(out, visitor, null);
+
+ out.println("");
+ printMessage(out, msg, visitor);
+ printReplies(out, msg, visitor, listview);
+ out.println(" ");
+
+ templates.pageFooter(request, out, visitor, false);
+
+ templates.pageEnd(out);
+ }
+ }
+
+ public com.juick.Message printMessage(PrintWriter out, com.juick.Message msg, com.juick.User visitor) {
+ msg.VisitorCanComment = visitor.getUid() > 0;
+
+ List tags = tagService.getMessageTags(msg.getMid());
+ String tagsStr = templates.formatTags(tags);
+ if (msg.ReadOnly) {
+ tagsStr += "readonly ";
+ msg.VisitorCanComment = false;
+ }
+ if (msg.getPrivacy() < 0) {
+ tagsStr += "friends ";
+ }
+
+ String txt;
+ if (msg.getTags().stream().anyMatch(t -> t.getName().equals("code"))) {
+ txt = MessageUtils.formatMessageCode(msg.getText());
+ } else {
+ txt = MessageUtils.formatMessage(msg.getText());
+ }
+
+ if (!tags.isEmpty()) {
+ tagsStr = "" + tagsStr + "
";
+ }
+
+ out.println("");
+ out.println(" ");
+ out.println(" ");
+ out.println(" ");
+ out.println("
" + templates.formatJSLocalTime(msg.getDate()) + "
");
+ out.println("
");
+ out.println(" ");
+ out.println("
" + txt + "
");
+
+ if (msg.getAttachmentType() != null) {
+ out.println("
");
+ }
+
+ boolean visitorInBL = false;
+ if (visitor.getUid() > 0) {
+ if (visitor.getUid() == msg.getUser().getUid()) {
+ msg.VisitorCanComment = true;
+ } else {
+ visitorInBL = userService.isInBL(msg.getUser().getUid(), visitor.getUid());
+ if (visitorInBL) {
+ msg.VisitorCanComment = false;
+ }
+ }
+ }
+
+ if (msg.VisitorCanComment) {
+ out.println("
");
+ out.println(" ");
+ out.println(" ");
+ }
+
+ List
recomm = messagesService.getMessageRecommendations(msg.getMid());
+ if (!recomm.isEmpty()) {
+ out.print(" Рекомендовали (" + recomm.size() + "): ");
+ for (int i = 0; i < recomm.size(); i++) {
+ if (i > 0) {
+ out.print(", ");
+ }
+ out.print("
@" + recomm.get(i) + " ");
+ }
+ out.println("
");
+ }
+ out.println(" ");
+ out.println(" ");
+
+ out.println(" ");
+ out.println("
" + msg.getMid() + " ");
+ if (visitor.getUid() > 0) {
+ if (visitor.getUid() != msg.getUser().getUid()) {
+ if (messagesService.isSubscribed(visitor.getUid(), msg.getMid())) {
+ out.println("
Подписан ");
+ } else {
+ out.println("
Подписаться ");
+ }
+ if (!visitorInBL) {
+ out.println("
Рекомендовать ");
+ }
+ } else {
+ out.println("
Удалить ");
+ }
+ }
+ out.println(" ");
+ out.println(" ");
+
+ return msg;
+ }
+
+ public void printReplies(PrintWriter out, com.juick.Message msg, com.juick.User visitor, boolean listview) {
+ List replies = messagesService.getReplies(msg.getMid());
+
+ List blUIDs = new ArrayList();
+ for (int i = 0; i < replies.size(); i++) {
+ com.juick.Message reply = replies.get(i);
+ if (reply.getUser().getUid() != msg.getUser().getUid() && !blUIDs.contains(reply.getUser().getUid())) {
+ blUIDs.add(reply.getUser().getUid());
+ }
+ if (reply.getReplyto() > 0) {
+ boolean added = false;
+ for (int n = 0; n < replies.size(); n++) {
+ if (replies.get(n).getRid() == reply.getReplyto()) {
+ replies.get(n).childs.add(reply);
+ added = true;
+ break;
+ }
+ }
+ if (!added) {
+ reply.setReplyto(0);
+ }
+ }
+ }
+
+ if (!replies.isEmpty()) {
+ if (visitor.getUid() > 0 && msg.getUser().getUid() == visitor.getUid()) {
+ for (Message reply : replies) {
+ reply.VisitorCanComment = true;
+ }
+ } else if (visitor.getUid() > 0 && msg.VisitorCanComment) {
+ blUIDs = userService.checkBL(visitor.getUid(), blUIDs);
+ for (Message reply : replies) {
+ reply.VisitorCanComment = reply.getUser().getUid() == visitor.getUid() || !blUIDs.contains(reply.getUser().getUid());
+ }
+ } else {
+ for (Message reply : replies) {
+ reply.VisitorCanComment = false;
+ }
+ }
+
+ boolean foldable = false;
+ if (replies.size() > 10) {
+ for (int i = 0; i < replies.size() - 1; i++) {
+ if (replies.get(i).getChildsCount() > 1) {
+ foldable = true;
+ break;
+ }
+ }
+ }
+
+ out.println("");
+ out.print("
");
+ out.println("
Ответы (" + replies.size() + ") ");
+ out.println("
");
+
+ out.println("");
+ if (listview) {
+ printList(out, replies, visitor);
+ } else {
+ printTree(out, replies, visitor, 0, 0, false);
+ }
+ out.println(" ");
+
+ for (Message reply : replies) {
+ reply.cleanupChilds();
+ }
+ replies.clear();
+ }
+ }
+
+ public void printTree(PrintWriter out, List replies, com.juick.User visitor, int ReplyTo, int margin, boolean hidden) {
+ if (margin > 240) {
+ margin = 240;
+ }
+
+ for (int i = 0; i < replies.size(); i++) {
+ com.juick.Message msg = replies.get(i);
+ if (msg.getReplyto() == ReplyTo) {
+
+ out.print(" 0) {
+ out.print("margin-left: " + margin + "px;");
+ }
+ if (hidden) {
+ out.print("display:none;");
+ }
+ out.println("\">");
+ out.println(" ");
+ out.println(" ");
+ out.println("
" + MessageUtils.formatMessage(msg.getText()) + "
");
+ if (msg.getAttachmentType() != null) {
+ out.println("
");
+ }
+ out.print("
/" + msg.getRid());
+ if (msg.getReplyto() > 0) {
+ out.print(" в ответ на
/" + msg.getReplyto() + " ");
+ }
+ if (msg.VisitorCanComment) {
+ out.println(" ·
");
+ out.println(" ");
+ } else if (visitor == null) {
+ out.println(" ·
Ответить ");
+ }
+
+ int childs = msg.getChildsCount();
+ if (ReplyTo == 0 && childs > 1 && replies.size() > 10) {
+ out.println(" ");
+ }
+ out.println(" ");
+ out.println(" ");
+
+ if (ReplyTo == 0 && childs > 1 && replies.size() > 10) {
+ printTree(out, msg.childs, visitor, msg.getRid(), margin + 20, true);
+ } else if (childs > 0) {
+ printTree(out, msg.childs, visitor, msg.getRid(), margin + 20, hidden);
+ }
+ }
+ }
+ }
+
+ public void printList(PrintWriter out, List replies, com.juick.User visitor) {
+ for (Message msg : replies) {
+ out.print(" ");
+ out.println(" ");
+ out.println(" ");
+ out.println("
" + MessageUtils.formatMessage(msg.getText()) + "
");
+ if (msg.getAttachmentType() != null) {
+ out.println("
");
+ }
+ out.print("
/" + msg.getRid());
+ if (msg.getReplyto() > 0) {
+ out.print(" в ответ на
/" + msg.getReplyto() + " ");
+ }
+ if (msg.VisitorCanComment) {
+ out.println(" ·
");
+ out.println(" ");
+ } else if (visitor.getUid() == 0) {
+ out.println("
");
+ }
+ out.println("
");
+ out.println(" ");
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java b/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java
new file mode 100644
index 00000000..d860a7bc
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/VKontakteLogin.java
@@ -0,0 +1,130 @@
+/*
+ * Juick
+ * Copyright (C) 2008-2013, 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.www.controllers;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.juick.service.CrosspostService;
+import com.juick.service.UserService;
+import com.juick.www.Utils;
+import com.juick.www.vk.Token;
+import com.juick.www.vk.UsersResponse;
+import org.apache.commons.lang3.CharEncoding;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+import javax.inject.Inject;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.UUID;
+
+/**
+ * @author Ugnich Anton
+ */
+@Controller
+public class VKontakteLogin {
+ private static final Logger logger = LoggerFactory.getLogger(VKontakteLogin.class);
+ private static final String VK_APPID = "3544101";
+ private static final String VK_SECRET = "z2afNI8jA5lIpZ2jsTm1";
+ private static final String VK_REDIRECT = "http://juick.com/_vklogin";
+
+ @Inject
+ CrosspostService crosspostService;
+ @Inject
+ UserService userService;
+
+ public VKontakteLogin() {
+ mapper = new ObjectMapper();
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+ mapper.setSerializationInclusion(JsonInclude.Include.NON_DEFAULT);
+ }
+
+ private final ObjectMapper mapper;
+
+ @RequestMapping(value = "/_vklogin", method = RequestMethod.GET)
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ String code = request.getParameter("code");
+ if (StringUtils.isBlank(code)) {
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "https://oauth.vk.com/authorize?client_id=" + VK_APPID + "&redirect_uri=" + URLEncoder.encode(VK_REDIRECT, CharEncoding.UTF_8) + "&scope=friends,wall,offline&response_type=code");
+ return;
+ }
+
+
+ String tokenjson = Utils.fetchURL("https://oauth.vk.com/access_token?client_id=" + VK_APPID + "&redirect_uri=" + URLEncoder.encode(VK_REDIRECT, CharEncoding.UTF_8) + "&client_secret=" + VK_SECRET + "&code=" + URLEncoder.encode(code, CharEncoding.UTF_8));
+ if (tokenjson == null || tokenjson.isEmpty()) {
+ logger.error("VK TOKEN EMPTY");
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+ String token = null;
+ long vkID = 0;
+ Token json = mapper.readValue(tokenjson, Token.class);
+ token = json.getAccessToken();
+ vkID = json.getUserId();
+ if (token == null || vkID == 0) {
+ logger.error("VK TOKEN EMPTY: {}", tokenjson);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ String graph = Utils.fetchURL("https://api.vk.com/method/users.get?uids=" + vkID + "&fields=screen_name&access_token=" + token);
+ if (graph == null || graph.isEmpty()) {
+ logger.error("VK GRAPH ERROR");
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ return;
+ }
+
+ try {
+ com.juick.www.vk.User jsonUser = mapper.readValue(graph, UsersResponse.class).getUsers().get(0);
+ String vkName = jsonUser.getFirstName() + " " + jsonUser.getLastName();
+ String vkLink = jsonUser.getScreenName();
+
+ if (vkName == null || vkLink == null || vkName.isEmpty() || vkName.length() == 1 || vkLink.isEmpty()) {
+ throw new Exception();
+ }
+
+ int uid = crosspostService.getUIDbyVKID(vkID);
+ if (uid > 0) {
+ Cookie c = new Cookie("hash", userService.getHashByUID(uid));
+ c.setMaxAge(50 * 24 * 60 * 60);
+ response.addCookie(c);
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "/");
+ } else {
+ String loginhash = UUID.randomUUID().toString();
+ if (!crosspostService.createVKUser(vkID, loginhash, token, vkName, vkLink)) {
+ throw new Exception();
+ }
+ response.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
+ response.setHeader("Location", "/signup?type=vk&hash=" + loginhash);
+ }
+ } catch (Exception e) {
+ logger.error("JSON ERROR", e);
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ }
+ }
+}
diff --git a/juick-www/src/main/java/com/juick/www/controllers/XMPPPost.java b/juick-www/src/main/java/com/juick/www/controllers/XMPPPost.java
new file mode 100644
index 00000000..f64907b2
--- /dev/null
+++ b/juick-www/src/main/java/com/juick/www/controllers/XMPPPost.java
@@ -0,0 +1,84 @@
+package com.juick.www.controllers;
+
+import com.juick.server.util.HttpBadRequestException;
+import com.juick.server.util.HttpUtils;
+import com.juick.service.TagService;
+import com.juick.www.WebApp;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import rocks.xmpp.addr.Jid;
+import rocks.xmpp.core.stanza.model.Message;
+import rocks.xmpp.extensions.oob.model.x.OobX;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+/**
+ * Created by vitalyster on 08.12.2016.
+ */
+@Controller
+public class XMPPPost {
+ private final static Logger logger = LoggerFactory.getLogger(XMPPPost.class);
+
+ @Inject
+ WebApp webApp;
+ @Inject
+ TagService tagService;
+
+ @RequestMapping(value = "/post2", method = RequestMethod.POST)
+ public void doPostMessage(HttpServletRequest request, HttpServletResponse response,
+ @RequestParam(required = false) String img,
+ @RequestParam(required = false) MultipartFile attach) throws IOException {
+
+ com.juick.User visitor = webApp.getVisitorUser(request, response);
+ if (visitor.getUid() == 0 || visitor.isBanned()) {
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ return;
+ }
+ String body = request.getParameter("body").replace("\r", StringUtils.EMPTY);
+
+ String attachmentFName = HttpUtils.receiveMultiPartFile(attach, webApp.getTmpDir());
+
+ if (StringUtils.isBlank(attachmentFName) && img != null && img.length() > 10) {
+ try {
+ URL imgUrl = new URL(img);
+ attachmentFName = HttpUtils.downloadImage(imgUrl);
+ } catch (Exception e) {
+ logger.error("DOWNLOAD ERROR", e);
+ throw new HttpBadRequestException();
+ }
+ }
+ Message msg = new Message();
+ msg.setType(Message.Type.CHAT);
+ msg.setFrom(Jid.of(String.valueOf(visitor.getUid()), "uid.juick.com", "perl"));
+ msg.setTo(Jid.of("juick@juick.com/Juick"));
+ msg.setBody(body);
+ try {
+ if (StringUtils.isNotEmpty(attachmentFName)) {
+ String attachmentUrl = String.format("juick://%s", attachmentFName);
+ msg.addExtension(new OobX(new URI(attachmentUrl), "!!!!Juick!!"));
+ }
+ webApp.getXmpp().sendMessage(msg);
+ } catch (URISyntaxException e1) {
+ logger.warn("attachment error", e1);
+ }
+ String referer = request.getHeader("referer");
+ if (StringUtils.isBlank(referer) || referer.substring(0, 21).equals("http://juick.com/post")
+ || referer.substring(0, 22).equals("https://juick.com/post")) {
+ response.sendRedirect("/?show=my");
+ return;
+ }
+ response.sendRedirect(referer);
+ }
+}
diff --git a/juick-www/src/main/resources/juick.conf.example b/juick-www/src/main/resources/juick.conf.example
new file mode 100644
index 00000000..bbe2a9e5
--- /dev/null
+++ b/juick-www/src/main/resources/juick.conf.example
@@ -0,0 +1,6 @@
+mysql_username=username
+xmpp_password=secret
+sape_user=usertoken
+wns_application_sip=ms-app://x-1-11-1-1111111111-...
+wns_client_secret=secret
+xmpp_disabled=false
\ No newline at end of file
diff --git a/juick-www/src/main/resources/layouts/content.html b/juick-www/src/main/resources/layouts/content.html
deleted file mode 100644
index ef12382c..00000000
--- a/juick-www/src/main/resources/layouts/content.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
- {% block headers %}
- {{ headers | raw }}
- {% endblock %}
- {{ title }}
-
-
-
-
- {% include "views/partial/navigation.html" %}
-
- {% block content %}
- {% endblock %}
-
-
- {% block column %}
- {% endblock %}
-
- {% include "views/partial/footer.html" %}
-
-
\ No newline at end of file
diff --git a/juick-www/src/main/resources/layouts/rss.xml b/juick-www/src/main/resources/layouts/rss.xml
deleted file mode 100644
index 23866c8a..00000000
--- a/juick-www/src/main/resources/layouts/rss.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
- {{ user.getName() }} - Juick
- http://juick.com/{{ user.getName() }}/
- The latest messages by @{{ user.getName() }} at Juick
-
- http://i.juick.com/a/{{ user.getUid() }}.png
- {{ user.getName() }} - Juick
- http://juick.com/{{ user.getName() }}/
-
- {% for msg in msgs %}
- -
-
http://juick.com/{{ msg.getUser().getName() }}/{{ msg.getMid() }}
- http://juick.com/{{ msg.getUser().getName() }}/{{ msg.getMid() }}
-
-
- {{ sdfRSS.format(msg.getDate()) }}
- http://juick.com/{{ msg.getUser().getName() }}/{{ msg.getMid() }}
- {% for tag in msg.getTags() %}
- {{ tag }}
- {% endfor %}
- {% if msg.getAttachmentType() is not empty %}
- {% if msg.getAttachmentType() == "jpg" %}
-
-
- {% elseif msg.getAttachmentType() == "png" %}
-
-
- {% endif %}
- {% endif %}
-
-
- {% endfor %}
-
-
diff --git a/juick-www/src/main/resources/views/404.html b/juick-www/src/main/resources/views/404.html
deleted file mode 100644
index c993df4b..00000000
--- a/juick-www/src/main/resources/views/404.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
- Страница не найдена
- Сожалеем, но страницу с этим адресом удалил её автор, либо её никогда не существовало.
-
-{% endblock %}
-
-{% block "column" %}
-{% include "views/partial/homecolumn.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/help.html b/juick-www/src/main/resources/views/help.html
deleted file mode 100644
index 3d9960d1..00000000
--- a/juick-www/src/main/resources/views/help.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
- {{ content | raw }}
-
-{% endblock %}
-
-{% block "column" %}
-{{ navigation | raw }}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/partial/footer.html b/juick-www/src/main/resources/views/partial/footer.html
deleted file mode 100644
index 6978a2c0..00000000
--- a/juick-www/src/main/resources/views/partial/footer.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/partial/homecolumn.html b/juick-www/src/main/resources/views/partial/homecolumn.html
deleted file mode 100644
index 5293918d..00000000
--- a/juick-www/src/main/resources/views/partial/homecolumn.html
+++ /dev/null
@@ -1,6 +0,0 @@
-
- {% include "views/partial/tags.html" %}
- {% if showAdv %}
- конструктор сайтов
- {% endif %}
-
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/partial/navigation.html b/juick-www/src/main/resources/views/partial/navigation.html
deleted file mode 100644
index 2863d0c3..00000000
--- a/juick-www/src/main/resources/views/partial/navigation.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
diff --git a/juick-www/src/main/resources/views/partial/settings_tabs.html b/juick-www/src/main/resources/views/partial/settings_tabs.html
deleted file mode 100644
index d7901d5e..00000000
--- a/juick-www/src/main/resources/views/partial/settings_tabs.html
+++ /dev/null
@@ -1,5 +0,0 @@
-
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/partial/tags.html b/juick-www/src/main/resources/views/partial/tags.html
deleted file mode 100644
index 4d05b7fb..00000000
--- a/juick-www/src/main/resources/views/partial/tags.html
+++ /dev/null
@@ -1,3 +0,0 @@
-{% for tag in tags %}
- {{ tag }}
-{% endfor %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/pm_inbox.html b/juick-www/src/main/resources/views/pm_inbox.html
deleted file mode 100644
index 36b3e511..00000000
--- a/juick-www/src/main/resources/views/pm_inbox.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-{% if not msgs.isEmpty() %}
-
- {% for msg in msgs %}
-
-
-
-
-
{{ msg.getText() | raw }}
-
-
-
-
-
-
-
-
- {% endfor %}
-
-{% endif %}
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/homecolumn.html" %}
-{% endblock %}
diff --git a/juick-www/src/main/resources/views/pm_sent.html b/juick-www/src/main/resources/views/pm_sent.html
deleted file mode 100644
index 7c6fb686..00000000
--- a/juick-www/src/main/resources/views/pm_sent.html
+++ /dev/null
@@ -1,33 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
-
-
-{% if not msgs.isEmpty() %}
-
- {% for msg in msgs %}
-
-
-
-
{{ msg.getText() | raw }}
-
-
- {% endfor %}
-
-{% endif %}
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/homecolumn.html" %}
-{% endblock %}
diff --git a/juick-www/src/main/resources/views/settings_about.html b/juick-www/src/main/resources/views/settings_about.html
deleted file mode 100644
index 0252af35..00000000
--- a/juick-www/src/main/resources/views/settings_about.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
-
- Full name:
- Country:
- URL:
- Please, start with "http://"
- About:
-
- Max. 255 symbols
- Avatar:
- Recommendations: PNG, 96x96, <50Kb. Also, JPG and GIF supported.
-
-
-
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/settings_tabs.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/settings_auth-email.html b/juick-www/src/main/resources/views/settings_auth-email.html
deleted file mode 100644
index 79691083..00000000
--- a/juick-www/src/main/resources/views/settings_auth-email.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
- {{ result }}
Settings .
-
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/settings_tabs.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/settings_main.html b/juick-www/src/main/resources/views/settings_main.html
deleted file mode 100644
index f4630be2..00000000
--- a/juick-www/src/main/resources/views/settings_main.html
+++ /dev/null
@@ -1,156 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
- Настройки
-
-
- Notification options
- Reply notifications ("Message posted")
- Subscriptions notifications ("@user subscribed...")
- Posts recommendations ("Recommended by @user")
-
-
-
-
-
- Telegram
- {% if telegram_name is not empty %}
-
- Telegram: {{ telegram_name }} —
-
-
-
-
- {% else %}
- To connect Telegram account: send any text message to @Juick_bot
-
- {% endif %}
-
-
-
-
- XMPP accounts
-
- Your accounts:
-
- {% for jid in jids %}
- {{ jid }}
- {% endfor %}
- {% for auth in auths %}
- {{ auth.getAccount() }}
- — Confirm
- {% endfor %}
-
- {% if jids is not empty %}
-
- {% endif %}
- To add new jabber account: send any text message to juick@juick.com
-
-
-
-
-
- E-mail
-
-
- Add account:
-
-
-
-
-
-
- Your accounts:
-
- {% for email in emails %}
- {{ email }}
- {% endfor %}
- {% if emails is empty %}
- -
- {% else %}
-
-
- {% endif %}
-
- {% if emails is not empty %}
-
- You can receive all your subscriptions by email:
- Sent to
- Disabled
- {% for email in emails %}
-
- {{ email }}
-
- {% endfor %}
- every day at
- {% for hour in hours %}
-
- {{ hour }}:00 GMT
-
- {% endfor %}
-
-
-
-
- {% endif %}
-
- You can post to Juick via e-mail. Send your plain text
- messages to special secret e-mail. You can attach one photo or video file.
- Secret email: {% if ehash is not empty %} {{ ehash }} {% else %}-{% endif %}
-
-
-
-
-
-
- Facebook
-
- {% if fbstatus.isConnected() %}
- {% if fbstatus.isCrosspostEnabled() %}
-
-
- Facebook: Enabled —
-
-
-
-
- {% else %}
-
-
- Facebook: Disabled —
-
-
-
-
- {% endif %}
- {% else %}
- Cross-posting to Facebook:
- {% endif %}
-
-
-
- Twitter
- {% if twitter_name is not empty %}
-
- Twitter: {{ twitter_name }} —
-
-
-
-
- {% else %}
- Cross-posting to Twitter:
- {% endif %}
-
-
-
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/settings_tabs.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/settings_password.html b/juick-www/src/main/resources/views/settings_password.html
deleted file mode 100644
index e9c2dce0..00000000
--- a/juick-www/src/main/resources/views/settings_password.html
+++ /dev/null
@@ -1,17 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
-
- Changing your password
-
-
- Change password:
- (max. length - 16 symbols)
-
-
-
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/settings_tabs.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/settings_privacy.html b/juick-www/src/main/resources/views/settings_privacy.html
deleted file mode 100644
index 48756d8e..00000000
--- a/juick-www/src/main/resources/views/settings_privacy.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
- Privacy
-
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/settings_tabs.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/settings_result.html b/juick-www/src/main/resources/views/settings_result.html
deleted file mode 100644
index 3f5482d4..00000000
--- a/juick-www/src/main/resources/views/settings_result.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
- {{ result | raw }}
-
-{% endblock %}
-{% block "column" %}
-{% include "views/partial/settings_tabs.html" %}
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/resources/views/signup.html b/juick-www/src/main/resources/views/signup.html
deleted file mode 100644
index 724ad961..00000000
--- a/juick-www/src/main/resources/views/signup.html
+++ /dev/null
@@ -1,41 +0,0 @@
-{% extends "layouts/content.html" %}
-{% block content %}
-
- {% if type | slice(0, 1) == 'f' %}
-
- {% elseif type | slice(0, 1) == 'v' %}
-
- {% elseif type | slice(0, 1) == 'x' %}
-
- {% elseif type | slice(0, 1) == 'd' %}
-
- {% endif %}
- {{ account | raw }}
-
-Связать с существующим аккаунтом Juick
-
-
-
-
- {% if visitor.getUID() > 0 %}
-
- {% else %}
- Имя пользователя:
- Пароль:
-
- {% endif %}
-
-
-
-
-Создать новый аккаунт Juick
-
-
-
-
- Имя пользователя: (От 2-х до 16-и латинских символов
- и/или цифр, дефис)
- Пароль: (от 6-и до 32-х символов)
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/juick.conf.example b/juick-www/src/main/webapp/WEB-INF/juick.conf.example
deleted file mode 100644
index bbe2a9e5..00000000
--- a/juick-www/src/main/webapp/WEB-INF/juick.conf.example
+++ /dev/null
@@ -1,6 +0,0 @@
-mysql_username=username
-xmpp_password=secret
-sape_user=usertoken
-wns_application_sip=ms-app://x-1-11-1-1111111111-...
-wns_client_secret=secret
-xmpp_disabled=false
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/layouts/content.html b/juick-www/src/main/webapp/WEB-INF/layouts/content.html
new file mode 100644
index 00000000..6a564034
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/layouts/content.html
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ {% block headers %}
+ {{ headers | raw }}
+ {% endblock %}
+ {{ title }}
+
+
+
+
+ {% include "views/partial/navigation" %}
+
+ {% block content %}
+ {% endblock %}
+
+
+ {% block column %}
+ {% endblock %}
+
+ {% include "views/partial/footer" %}
+
+
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/layouts/rss.xml b/juick-www/src/main/webapp/WEB-INF/layouts/rss.xml
new file mode 100644
index 00000000..23866c8a
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/layouts/rss.xml
@@ -0,0 +1,38 @@
+
+
+
+
+ {{ user.getName() }} - Juick
+ http://juick.com/{{ user.getName() }}/
+ The latest messages by @{{ user.getName() }} at Juick
+
+ http://i.juick.com/a/{{ user.getUid() }}.png
+ {{ user.getName() }} - Juick
+ http://juick.com/{{ user.getName() }}/
+
+ {% for msg in msgs %}
+ -
+
http://juick.com/{{ msg.getUser().getName() }}/{{ msg.getMid() }}
+ http://juick.com/{{ msg.getUser().getName() }}/{{ msg.getMid() }}
+
+
+ {{ sdfRSS.format(msg.getDate()) }}
+ http://juick.com/{{ msg.getUser().getName() }}/{{ msg.getMid() }}
+ {% for tag in msg.getTags() %}
+ {{ tag }}
+ {% endfor %}
+ {% if msg.getAttachmentType() is not empty %}
+ {% if msg.getAttachmentType() == "jpg" %}
+
+
+ {% elseif msg.getAttachmentType() == "png" %}
+
+
+ {% endif %}
+ {% endif %}
+
+
+ {% endfor %}
+
+
diff --git a/juick-www/src/main/webapp/WEB-INF/views/404.html b/juick-www/src/main/webapp/WEB-INF/views/404.html
new file mode 100644
index 00000000..21f42d75
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/404.html
@@ -0,0 +1,11 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+ Страница не найдена
+ Сожалеем, но страницу с этим адресом удалил её автор, либо её никогда не существовало.
+
+{% endblock %}
+
+{% block "column" %}
+{% include "views/partial/homecolumn" %}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/help.html b/juick-www/src/main/webapp/WEB-INF/views/help.html
new file mode 100644
index 00000000..a4b76676
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/help.html
@@ -0,0 +1,10 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+ {{ content | raw }}
+
+{% endblock %}
+
+{% block "column" %}
+{{ navigation | raw }}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/footer.html b/juick-www/src/main/webapp/WEB-INF/views/partial/footer.html
new file mode 100644
index 00000000..6978a2c0
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/partial/footer.html
@@ -0,0 +1,34 @@
+
+
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/homecolumn.html b/juick-www/src/main/webapp/WEB-INF/views/partial/homecolumn.html
new file mode 100644
index 00000000..28a73662
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/partial/homecolumn.html
@@ -0,0 +1,6 @@
+
+ {% include "views/partial/tags" %}
+ {% if showAdv %}
+ конструктор сайтов
+ {% endif %}
+
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/navigation.html b/juick-www/src/main/webapp/WEB-INF/views/partial/navigation.html
new file mode 100644
index 00000000..2863d0c3
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/partial/navigation.html
@@ -0,0 +1,37 @@
+
diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/settings_tabs.html b/juick-www/src/main/webapp/WEB-INF/views/partial/settings_tabs.html
new file mode 100644
index 00000000..d7901d5e
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/partial/settings_tabs.html
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/tags.html b/juick-www/src/main/webapp/WEB-INF/views/partial/tags.html
new file mode 100644
index 00000000..4d05b7fb
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/partial/tags.html
@@ -0,0 +1,3 @@
+{% for tag in tags %}
+ {{ tag }}
+{% endfor %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/pm_inbox.html b/juick-www/src/main/webapp/WEB-INF/views/pm_inbox.html
new file mode 100644
index 00000000..cb55582a
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/pm_inbox.html
@@ -0,0 +1,37 @@
+{% extends "layouts/content" %}
+{% block content %}
+{% if not msgs.isEmpty() %}
+
+ {% for msg in msgs %}
+
+
+
+
+
{{ msg.getText() | raw }}
+
+
+
+
+
+
+
+
+ {% endfor %}
+
+{% endif %}
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/homecolumn" %}
+{% endblock %}
diff --git a/juick-www/src/main/webapp/WEB-INF/views/pm_sent.html b/juick-www/src/main/webapp/WEB-INF/views/pm_sent.html
new file mode 100644
index 00000000..41f3814b
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/pm_sent.html
@@ -0,0 +1,33 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+
+
+{% if not msgs.isEmpty() %}
+
+ {% for msg in msgs %}
+
+
+
+
{{ msg.getText() | raw }}
+
+
+ {% endfor %}
+
+{% endif %}
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/homecolumn" %}
+{% endblock %}
diff --git a/juick-www/src/main/webapp/WEB-INF/views/settings_about.html b/juick-www/src/main/webapp/WEB-INF/views/settings_about.html
new file mode 100644
index 00000000..a11a1609
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/settings_about.html
@@ -0,0 +1,20 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+
+ Full name:
+ Country:
+ URL:
+ Please, start with "http://"
+ About:
+
+ Max. 255 symbols
+ Avatar:
+ Recommendations: PNG, 96x96, <50Kb. Also, JPG and GIF supported.
+
+
+
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/settings_tabs" %}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/settings_auth-email.html b/juick-www/src/main/webapp/WEB-INF/views/settings_auth-email.html
new file mode 100644
index 00000000..e7ed985a
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/settings_auth-email.html
@@ -0,0 +1,9 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+ {{ result }}
Settings .
+
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/settings_tabs" %}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/settings_main.html b/juick-www/src/main/webapp/WEB-INF/views/settings_main.html
new file mode 100644
index 00000000..39c6d875
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/settings_main.html
@@ -0,0 +1,156 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+ Настройки
+
+
+ Notification options
+ Reply notifications ("Message posted")
+ Subscriptions notifications ("@user subscribed...")
+ Posts recommendations ("Recommended by @user")
+
+
+
+
+
+ Telegram
+ {% if telegram_name is not empty %}
+
+ Telegram: {{ telegram_name }} —
+
+
+
+
+ {% else %}
+ To connect Telegram account: send any text message to @Juick_bot
+
+ {% endif %}
+
+
+
+
+ XMPP accounts
+
+ Your accounts:
+
+ {% for jid in jids %}
+ {{ jid }}
+ {% endfor %}
+ {% for auth in auths %}
+ {{ auth.getAccount() }}
+ — Confirm
+ {% endfor %}
+
+ {% if jids is not empty %}
+
+ {% endif %}
+ To add new jabber account: send any text message to juick@juick.com
+
+
+
+
+
+ E-mail
+
+
+ Add account:
+
+
+
+
+
+
+ Your accounts:
+
+ {% for email in emails %}
+ {{ email }}
+ {% endfor %}
+ {% if emails is empty %}
+ -
+ {% else %}
+
+
+ {% endif %}
+
+ {% if emails is not empty %}
+
+ You can receive all your subscriptions by email:
+ Sent to
+ Disabled
+ {% for email in emails %}
+
+ {{ email }}
+
+ {% endfor %}
+ every day at
+ {% for hour in hours %}
+
+ {{ hour }}:00 GMT
+
+ {% endfor %}
+
+
+
+
+ {% endif %}
+
+ You can post to Juick via e-mail. Send your plain text
+ messages to special secret e-mail. You can attach one photo or video file.
+ Secret email: {% if ehash is not empty %} {{ ehash }} {% else %}-{% endif %}
+
+
+
+
+
+
+ Facebook
+
+ {% if fbstatus.isConnected() %}
+ {% if fbstatus.isCrosspostEnabled() %}
+
+
+ Facebook: Enabled —
+
+
+
+
+ {% else %}
+
+
+ Facebook: Disabled —
+
+
+
+
+ {% endif %}
+ {% else %}
+ Cross-posting to Facebook:
+ {% endif %}
+
+
+
+ Twitter
+ {% if twitter_name is not empty %}
+
+ Twitter: {{ twitter_name }} —
+
+
+
+
+ {% else %}
+ Cross-posting to Twitter:
+ {% endif %}
+
+
+
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/settings_tabs" %}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/settings_password.html b/juick-www/src/main/webapp/WEB-INF/views/settings_password.html
new file mode 100644
index 00000000..d7883546
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/settings_password.html
@@ -0,0 +1,17 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+
+ Changing your password
+
+
+ Change password:
+ (max. length - 16 symbols)
+
+
+
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/settings_tabs" %}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/settings_privacy.html b/juick-www/src/main/webapp/WEB-INF/views/settings_privacy.html
new file mode 100644
index 00000000..29ed5e95
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/settings_privacy.html
@@ -0,0 +1,9 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+ Privacy
+
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/settings_tabs" %}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/settings_result.html b/juick-www/src/main/webapp/WEB-INF/views/settings_result.html
new file mode 100644
index 00000000..88a52938
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/settings_result.html
@@ -0,0 +1,9 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+ {{ result | raw }}
+
+{% endblock %}
+{% block "column" %}
+{% include "views/partial/settings_tabs" %}
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/views/signup.html b/juick-www/src/main/webapp/WEB-INF/views/signup.html
new file mode 100644
index 00000000..e454f7dd
--- /dev/null
+++ b/juick-www/src/main/webapp/WEB-INF/views/signup.html
@@ -0,0 +1,41 @@
+{% extends "layouts/content" %}
+{% block content %}
+
+ {% if type | slice(0, 1) == 'f' %}
+
+ {% elseif type | slice(0, 1) == 'v' %}
+
+ {% elseif type | slice(0, 1) == 'x' %}
+
+ {% elseif type | slice(0, 1) == 'd' %}
+
+ {% endif %}
+ {{ account | raw }}
+
+Связать с существующим аккаунтом Juick
+
+
+
+
+ {% if visitor.getUID() > 0 %}
+
+ {% else %}
+ Имя пользователя:
+ Пароль:
+
+ {% endif %}
+
+
+
+
+Создать новый аккаунт Juick
+
+
+
+
+ Имя пользователя: (От 2-х до 16-и латинских символов
+ и/или цифр, дефис)
+ Пароль: (от 6-и до 32-х символов)
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/juick-www/src/main/webapp/WEB-INF/web.xml b/juick-www/src/main/webapp/WEB-INF/web.xml
index ed9e8e62..a31c71d0 100644
--- a/juick-www/src/main/webapp/WEB-INF/web.xml
+++ b/juick-www/src/main/webapp/WEB-INF/web.xml
@@ -2,42 +2,4 @@
-
- Main
- com.juick.www.Main
- 1
-
-
- Main
- /
-
-
- default
- /scripts.js
-
-
- default
- /style.css
-
-
- default
- /scripts.js.map
-
-
- default
- /style.css.map
-
-
- js
- application/javascript;charset=UTF-8
-
-
- css
- text/css;charset=UTF-8
-
-
-
- 30
-
-
--
cgit v1.2.3