From f3963f0b12055ba6710b9b28ddc93a5b5fe91d67 Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 22 Sep 2017 16:39:00 +0300 Subject: Initial getNotifications query * using Java 8 DateTime API where possible --- build.gradle | 1 + juick-core/build.gradle | 2 ++ juick-core/src/main/java/com/juick/Message.java | 16 +++++++---- .../com/juick/formatters/PlainTextFormatter.java | 3 +- .../main/java/com/juick/util/DateFormatter.java | 15 +++++----- .../com/juick/xml/adapters/SimpleDateAdapter.java | 8 +++--- .../src/test/java/com/juick/FormatterTest.java | 17 +++++------ .../test/java/com/juick/test/util/MockUtils.java | 4 +-- .../src/main/java/com/juick/rss/MessagesView.java | 3 +- juick-server-core/build.gradle | 1 + .../java/com/juick/service/MessagesService.java | 3 ++ juick-server-jdbc/build.gradle | 1 + .../com/juick/service/MessagesServiceImpl.java | 33 ++++++++++++++++++++-- .../com/juick/service/PMQueriesServiceImpl.java | 6 ++-- .../java/com/juick/service/MessageServiceTest.java | 22 +++++++++++++-- .../pebble/extension/FormatterExtension.java | 6 ++-- .../pebble/extension/filters/PrettyTimeFilter.java | 5 ++-- .../pebble/extension/filters/TimestampFilter.java | 23 +++++++++++++++ .../src/main/webapp/WEB-INF/views/macros/tree.html | 6 ++-- .../main/webapp/WEB-INF/views/partial/message.html | 6 ++-- .../webapp/WEB-INF/views/partial/thread_list.html | 6 ++-- .../src/main/webapp/WEB-INF/views/pm_inbox.html | 2 +- .../src/main/webapp/WEB-INF/views/pm_sent.html | 2 +- .../src/main/webapp/WEB-INF/views/thread.html | 6 ++-- src/test/java/com/juick/rss/LegacyRSS.java | 4 +-- src/test/java/com/juick/tests/ApiTests.java | 3 -- src/test/java/com/juick/tests/MessageTests.java | 10 +++++-- 27 files changed, 149 insertions(+), 65 deletions(-) create mode 100644 juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/TimestampFilter.java diff --git a/build.gradle b/build.gradle index 73b9099a..c1188e89 100644 --- a/build.gradle +++ b/build.gradle @@ -54,6 +54,7 @@ dependencies { testCompile "org.json:json:20170516" testCompile "com.fasterxml.jackson.core:jackson-core:${jacksonVersion}" testCompile "com.fasterxml.jackson.core:jackson-databind:${jacksonVersion}" + testCompile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${rootProject.jacksonVersion}" testCompile "org.springframework:spring-jdbc:${springFrameworkVersion}" testCompile "org.springframework:spring-test:${springFrameworkVersion}" testCompile "ch.vorburger.mariaDB4j:mariaDB4j:2.2.3" diff --git a/juick-core/build.gradle b/juick-core/build.gradle index 27fe03ba..b392fb24 100644 --- a/juick-core/build.gradle +++ b/juick-core/build.gradle @@ -11,6 +11,8 @@ dependencies { testCompile "com.fasterxml.jackson.core:jackson-core:${rootProject.jacksonVersion}" testCompile "com.fasterxml.jackson.core:jackson-databind:${rootProject.jacksonVersion}" + testCompile "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${rootProject.jacksonVersion}" + testCompile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${rootProject.jacksonVersion}" testCompile "junit:junit:${rootProject.junitVersion}" testCompile "org.hamcrest:hamcrest-all:${rootProject.hamcrestVersion}" testCompile "rocks.xmpp:xmpp-core-client:0.7.4" diff --git a/juick-core/src/main/java/com/juick/Message.java b/juick-core/src/main/java/com/juick/Message.java index 72f60c82..25463c46 100644 --- a/juick-core/src/main/java/com/juick/Message.java +++ b/juick-core/src/main/java/com/juick/Message.java @@ -26,7 +26,11 @@ import org.apache.commons.lang3.builder.ToStringBuilder; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.util.*; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.TreeSet; /** * @author Ugnich Anton @@ -40,7 +44,7 @@ public class Message implements Comparable { private String text = null; private User user = null; private final List tags; - private Date date; + private Instant ts; @XmlTransient @JsonIgnore public int TimeAgo = 0; @@ -239,12 +243,12 @@ public class Message implements Comparable { @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC") @XmlAttribute(name = "ts") @XmlJavaTypeAdapter(SimpleDateAdapter.class) - public Date getDate() { - return date; + public Instant getTimestamp() { + return ts; } - public void setDate(Date date) { - this.date = date; + public void setTimestamp(Instant timestamp) { + this.ts = timestamp; } public com.juick.PM getPM() { diff --git a/juick-core/src/main/java/com/juick/formatters/PlainTextFormatter.java b/juick-core/src/main/java/com/juick/formatters/PlainTextFormatter.java index 8f9378a8..c62e0134 100644 --- a/juick-core/src/main/java/com/juick/formatters/PlainTextFormatter.java +++ b/juick-core/src/main/java/com/juick/formatters/PlainTextFormatter.java @@ -22,6 +22,7 @@ import com.juick.util.MessageUtils; import org.apache.commons.lang3.StringUtils; import org.ocpsoft.prettytime.PrettyTime; +import java.util.Date; import java.util.Locale; /** @@ -45,7 +46,7 @@ public class PlainTextFormatter { public static String formatPostSummary(Message m) { int cropLength = 384; - String timeAgo = pt.format(m.getDate()); + String timeAgo = pt.format(Date.from(m.getTimestamp())); String repliesCount = m.getReplies() == 1 ? "; 1 reply" : m.getReplies() == 0 ? "" : String.format("; %d replies", m.getReplies()); String txt = m.getText().length() >= cropLength ? diff --git a/juick-core/src/main/java/com/juick/util/DateFormatter.java b/juick-core/src/main/java/com/juick/util/DateFormatter.java index d7cf16bf..f9e23a91 100644 --- a/juick-core/src/main/java/com/juick/util/DateFormatter.java +++ b/juick-core/src/main/java/com/juick/util/DateFormatter.java @@ -19,10 +19,11 @@ package com.juick.util; import org.apache.commons.lang3.StringUtils; +import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; -import java.util.Date; +import java.util.Locale; /** * Created by aalexeev on 12/7/16. @@ -31,25 +32,25 @@ public class DateFormatter { private final DateTimeFormatter formatter; public DateFormatter(String pattern) { - formatter = DateTimeFormatter.ofPattern(pattern); + formatter = DateTimeFormatter.ofPattern(pattern, Locale.ENGLISH); } - public String format(final Date date) { - if (date == null) + public String format(final Instant ts) { + if (ts == null) return null; - LocalDateTime ldt = LocalDateTime.ofInstant(date.toInstant(), ZoneOffset.UTC); + LocalDateTime ldt = LocalDateTime.ofInstant(ts, ZoneOffset.UTC); return ldt.format(formatter); } - public Date parse(final String v) { + public Instant parse(final String v) { if (StringUtils.isBlank(v)) return null; LocalDateTime ldt = LocalDateTime.parse(v, formatter); - return Date.from(ldt.toInstant(ZoneOffset.UTC)); + return ldt.toInstant(ZoneOffset.UTC); } } diff --git a/juick-core/src/main/java/com/juick/xml/adapters/SimpleDateAdapter.java b/juick-core/src/main/java/com/juick/xml/adapters/SimpleDateAdapter.java index 9a6061cf..6dd40582 100644 --- a/juick-core/src/main/java/com/juick/xml/adapters/SimpleDateAdapter.java +++ b/juick-core/src/main/java/com/juick/xml/adapters/SimpleDateAdapter.java @@ -20,21 +20,21 @@ package com.juick.xml.adapters; import com.juick.util.DateFormattersHolder; import javax.xml.bind.annotation.adapters.XmlAdapter; -import java.util.Date; +import java.time.Instant; /** * Created by vitalyster on 15.11.2016. */ -public class SimpleDateAdapter extends XmlAdapter { +public class SimpleDateAdapter extends XmlAdapter { @Override - public String marshal(Date v) throws Exception { + public String marshal(Instant v) throws Exception { return DateFormattersHolder.getMessageFormatterInstance().format(v); } @Override - public Date unmarshal(String v) throws Exception { + public Instant unmarshal(String v) throws Exception { return DateFormattersHolder.getMessageFormatterInstance().parse(v); } } diff --git a/juick-core/src/test/java/com/juick/FormatterTest.java b/juick-core/src/test/java/com/juick/FormatterTest.java index d9324b8e..397c4b6c 100644 --- a/juick-core/src/test/java/com/juick/FormatterTest.java +++ b/juick-core/src/test/java/com/juick/FormatterTest.java @@ -21,6 +21,7 @@ import com.juick.util.DateFormattersHolder; import org.apache.commons.lang3.RandomUtils; import org.junit.Test; +import java.time.Instant; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; @@ -36,15 +37,15 @@ public class FormatterTest { @Test public void forAnyDateFormatterShouldReturnNotEmptyString() throws Exception { - Date date = new Date(); + Instant ts = Instant.now(); - assertThat(DateFormattersHolder.getMessageFormatterInstance().format(date), not(isEmptyOrNullString())); - assertThat(DateFormattersHolder.getRssFormatterInstance().format(date), not(isEmptyOrNullString())); + assertThat(DateFormattersHolder.getMessageFormatterInstance().format(ts), not(isEmptyOrNullString())); + assertThat(DateFormattersHolder.getRssFormatterInstance().format(ts), not(isEmptyOrNullString())); - date = new Date(RandomUtils.nextLong(1, Long.MAX_VALUE / 10000)); + ts = Instant.ofEpochMilli(RandomUtils.nextLong(1, Long.MAX_VALUE / 10000)); - assertThat(DateFormattersHolder.getMessageFormatterInstance().format(date), not(isEmptyOrNullString())); - assertThat(DateFormattersHolder.getRssFormatterInstance().format(date), not(isEmptyOrNullString())); + assertThat(DateFormattersHolder.getMessageFormatterInstance().format(ts), not(isEmptyOrNullString())); + assertThat(DateFormattersHolder.getRssFormatterInstance().format(ts), not(isEmptyOrNullString())); } @Test @@ -56,7 +57,7 @@ public class FormatterTest { Date date = calendar.getTime(); - assertThat(DateFormattersHolder.getMessageFormatterInstance().format(date), equalTo("2012-01-01 00:00:00")); - assertThat(DateFormattersHolder.getRssFormatterInstance().format(date), equalTo("Sun, 1 Jan 2012 00:00:00")); + assertThat(DateFormattersHolder.getMessageFormatterInstance().format(date.toInstant()), equalTo("2012-01-01 00:00:00")); + assertThat(DateFormattersHolder.getRssFormatterInstance().format(date.toInstant()), equalTo("Sun, 1 Jan 2012 00:00:00")); } } diff --git a/juick-core/src/test/java/com/juick/test/util/MockUtils.java b/juick-core/src/test/java/com/juick/test/util/MockUtils.java index 8426cde8..017af4d1 100644 --- a/juick-core/src/test/java/com/juick/test/util/MockUtils.java +++ b/juick-core/src/test/java/com/juick/test/util/MockUtils.java @@ -21,7 +21,7 @@ import com.juick.Message; import com.juick.User; import org.apache.commons.text.RandomStringGenerator; -import java.util.Date; +import java.time.Instant; /** * Created by vitalyster on 12.01.2017. @@ -34,7 +34,7 @@ public class MockUtils { msg.setMid(mid); msg.setUser(user); msg.setText(messageText == null ? generator.generate(24) : messageText); - msg.setDate(new Date()); + msg.setTimestamp(Instant.now()); return msg; } diff --git a/juick-rss/src/main/java/com/juick/rss/MessagesView.java b/juick-rss/src/main/java/com/juick/rss/MessagesView.java index b98e1d93..146641c5 100644 --- a/juick-rss/src/main/java/com/juick/rss/MessagesView.java +++ b/juick-rss/src/main/java/com/juick/rss/MessagesView.java @@ -43,6 +43,7 @@ import javax.servlet.http.HttpServletResponse; import java.net.URI; import java.net.URISyntaxException; import java.util.Collections; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -110,7 +111,7 @@ public class MessagesView extends AbstractRssFeedView { description.setType("text/html"); description.setValue(messageDescription); item.setDescription(description); - item.setPubDate(msg.getDate()); + item.setPubDate(Date.from(msg.getTimestamp())); item.setComments(messageUrl); msg.getTags().stream().map(t -> { Category category = new Category(); diff --git a/juick-server-core/build.gradle b/juick-server-core/build.gradle index d231ab40..83a02452 100644 --- a/juick-server-core/build.gradle +++ b/juick-server-core/build.gradle @@ -11,6 +11,7 @@ dependencies { compile "com.fasterxml.jackson.core:jackson-databind:${rootProject.jacksonVersion}" compile "com.fasterxml.jackson.core:jackson-annotations:${rootProject.jacksonVersion}" compile "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${rootProject.jacksonVersion}" + compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${rootProject.jacksonVersion}" compile "rocks.xmpp:xmpp-core-client:0.7.4" compile "rocks.xmpp:xmpp-extensions-client:0.7.4" diff --git a/juick-server-core/src/main/java/com/juick/service/MessagesService.java b/juick-server-core/src/main/java/com/juick/service/MessagesService.java index 0644dd99..870a7249 100644 --- a/juick-server-core/src/main/java/com/juick/service/MessagesService.java +++ b/juick-server-core/src/main/java/com/juick/service/MessagesService.java @@ -20,6 +20,7 @@ package com.juick.service; import com.juick.User; import com.juick.server.helpers.ResponseReply; +import java.time.LocalDateTime; import java.util.Collection; import java.util.List; @@ -100,4 +101,6 @@ public interface MessagesService { List getLastMessages(int hours); List getLastReplies(int hours); + + List getNotifications(User user, LocalDateTime before); } diff --git a/juick-server-jdbc/build.gradle b/juick-server-jdbc/build.gradle index 9b19bcb4..a9da3dff 100644 --- a/juick-server-jdbc/build.gradle +++ b/juick-server-jdbc/build.gradle @@ -10,6 +10,7 @@ dependencies { compile "com.fasterxml.jackson.core:jackson-databind:${rootProject.jacksonVersion}" compile "com.fasterxml.jackson.core:jackson-annotations:${rootProject.jacksonVersion}" compile "com.fasterxml.jackson.datatype:jackson-datatype-jdk8:${rootProject.jacksonVersion}" + compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:${rootProject.jacksonVersion}" providedCompile "ch.qos.logback:logback-classic:${rootProject.logbackVersion}" providedCompile "ch.qos.logback:logback-core:${rootProject.logbackVersion}" diff --git a/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java index 3533d701..c23b04e4 100644 --- a/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java +++ b/juick-server-jdbc/src/main/java/com/juick/service/MessagesServiceImpl.java @@ -40,7 +40,11 @@ import org.springframework.util.Assert; import javax.inject.Inject; import java.sql.*; -import java.util.*; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; /** * Created by aalexeev on 11/13/16. @@ -74,7 +78,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ user.setBanned(rs.getBoolean(6)); msg.setUser(user); msg.TimeAgo = rs.getInt(7); - msg.setDate(rs.getTimestamp(8)); + msg.setTimestamp(rs.getTimestamp(8).toInstant()); msg.ReadOnly = rs.getBoolean(9); msg.setPrivacy(rs.getInt(10)); msg.FriendsOnly = msg.getPrivacy() < 0; @@ -322,7 +326,7 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ msg.getUser().setUid(rs.getInt(1)); msg.getUser().setName(rs.getString(2)); msg.setReplyto(rs.getInt(3)); - msg.setDate(rs.getTimestamp(4)); + msg.setTimestamp(rs.getTimestamp(4).toInstant()); msg.setAttachmentType(rs.getString(5)); msg.setText(rs.getString(6)); String quote = rs.getString(7); @@ -834,4 +838,27 @@ public class MessagesServiceImpl extends BaseJdbcService implements MessagesServ return reply; }, -hours); } + + @Transactional(readOnly = true) + @Override + public List getNotifications(User user, LocalDateTime before) { + return getNamedParameterJdbcTemplate().query("SELECT replies.message_id as mid, replies.reply_id, replies.replyto, " + + "replies.user_id, users.nick, users.banned, " + + "TIMESTAMPDIFF(MINUTE, replies.ts, NOW()), replies.ts, " + + "0 as readonly, 0 as privacy, 0 as replies, " + + "replies.attach, 0 as place_id, 0 as lat, " + + "0 as lon, 0 as likes, 0 as hidden, " + + "NULL as tags, NULL as repliesby, replies.txt, " + + "IFNULL(qw.txt, t.txt) as q FROM replies INNER JOIN users " + + "ON replies.user_id = users.id " + + "LEFT JOIN replies qw ON replies.message_id = qw.message_id and replies.replyto = qw.reply_id " + + "LEFT JOIN messages_txt t on replies.message_id = t.message_id " + + "WHERE EXISTS (SELECT 1 FROM subscr_messages WHERE suser_id=:uid " + + "AND replies.message_id=message_id) " + + (before != null ? "AND replies.ts < :before " : StringUtils.EMPTY) + + "ORDER BY ts DESC LIMIT 20", new MapSqlParameterSource() + .addValue("uid", user.getUid()) + .addValue("before", before), + new MessageMapper()); + } } diff --git a/juick-server-jdbc/src/main/java/com/juick/service/PMQueriesServiceImpl.java b/juick-server-jdbc/src/main/java/com/juick/service/PMQueriesServiceImpl.java index 6b13f7bc..80be200b 100644 --- a/juick-server-jdbc/src/main/java/com/juick/service/PMQueriesServiceImpl.java +++ b/juick-server-jdbc/src/main/java/com/juick/service/PMQueriesServiceImpl.java @@ -125,7 +125,7 @@ public class PMQueriesServiceImpl extends BaseJdbcService implements PMQueriesSe msg.setUser(new User()); msg.getUser().setUid(uuid); msg.setText(rs.getString(2)); - msg.setDate(rs.getTimestamp(3)); + msg.setTimestamp(rs.getTimestamp(3).toInstant()); return msg; }); @@ -149,7 +149,7 @@ public class PMQueriesServiceImpl extends BaseJdbcService implements PMQueriesSe msg.getUser().setName(rs.getString(2)); msg.setText(rs.getString(3)); msg.TimeAgo = rs.getInt(4); - msg.setDate(rs.getTimestamp(5)); + msg.setTimestamp(rs.getTimestamp(5).toInstant()); return msg; }, uid); @@ -169,7 +169,7 @@ public class PMQueriesServiceImpl extends BaseJdbcService implements PMQueriesSe msg.getUser().setName(rs.getString(2)); msg.setText(rs.getString(3)); msg.TimeAgo = rs.getInt(4); - msg.setDate(rs.getTimestamp(5)); + msg.setTimestamp(rs.getTimestamp(5).toInstant()); return msg; }, uid); diff --git a/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java b/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java index 64de9424..738a1250 100644 --- a/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java +++ b/juick-server-jdbc/src/test/java/com/juick/service/MessageServiceTest.java @@ -17,17 +17,22 @@ package com.juick.service; +import com.juick.Message; +import com.juick.User; import com.juick.configuration.RepositoryConfiguration; import com.juick.server.helpers.AnonymousUser; +import org.junit.Before; import org.junit.Test; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import javax.inject.Inject; +import java.time.ZoneId; import java.util.List; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; /** * Created by aalexeev on 11/25/16. @@ -43,10 +48,14 @@ public class MessageServiceTest extends AbstractJUnit4SpringContextTests { int ugnichId, freefdId, mid; - @Test - public void getMyFeed() { + @Before + public void createUgniches() { ugnichId = userService.createUser("ugnich", "secret"); freefdId = userService.createUser("freefd", "secret"); + } + + @Test + public void getMyFeed() { mid = messagesService.createMessage(ugnichId, "test", null, null); int mid2 = messagesService.createMessage(ugnichId, "test2", null, null); subscriptionService.subscribeUser(userService.getUserByUID(freefdId).orElse(AnonymousUser.INSTANCE), @@ -65,5 +74,14 @@ public class MessageServiceTest extends AbstractJUnit4SpringContextTests { assertThat(messagesService.recommendMessage(mid, ugnichId), equalTo(false)); assertThat(messagesService.getMessage(mid).getLikes(), equalTo(0)); assertThat(messagesService.getAll(ugnichId, 0).size(), equalTo(3)); + + User ugnich = userService.getUserByUID(ugnichId).orElse(AnonymousUser.INSTANCE); + User freefd = userService.getUserByUID(freefdId).orElse(AnonymousUser.INSTANCE); + int mid = messagesService.createMessage(ugnichId, "yo", null, null); + subscriptionService.subscribeMessage(mid, freefdId); + int rid = messagesService.createReply(mid, 0, ugnichId, "yo", null); + Message reply = messagesService.getReply(mid, rid); + assertThat(messagesService.getNotifications(freefd, null).size(), is(1)); + assertThat(messagesService.getNotifications(freefd, reply.getTimestamp().atZone(ZoneId.systemDefault()).toLocalDateTime()).size(), is(0)); } } diff --git a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java index 7702a316..c8244df4 100644 --- a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java +++ b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/FormatterExtension.java @@ -17,10 +17,7 @@ package com.mitchellbosecke.pebble.extension; -import com.mitchellbosecke.pebble.extension.filters.FormatMessageFilter; -import com.mitchellbosecke.pebble.extension.filters.FormatRepliesFilter; -import com.mitchellbosecke.pebble.extension.filters.PrettyTimeFilter; -import com.mitchellbosecke.pebble.extension.filters.TagsListFilter; +import com.mitchellbosecke.pebble.extension.filters.*; import java.util.HashMap; import java.util.Map; @@ -35,6 +32,7 @@ public class FormatterExtension extends AbstractExtension { filters.put("formatMessage", new FormatMessageFilter()); filters.put("formatReplies", new FormatRepliesFilter()); filters.put("prettyTime", new PrettyTimeFilter()); + filters.put("timestamp", new TimestampFilter()); filters.put("tagsList", new TagsListFilter()); return filters; } diff --git a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/PrettyTimeFilter.java b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/PrettyTimeFilter.java index 08e657c8..1d58ce79 100644 --- a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/PrettyTimeFilter.java +++ b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/PrettyTimeFilter.java @@ -21,6 +21,7 @@ import com.juick.util.PrettyTimeFormatter; import com.mitchellbosecke.pebble.extension.Filter; import com.mitchellbosecke.pebble.template.EvaluationContext; +import java.time.Instant; import java.util.Date; import java.util.List; import java.util.Locale; @@ -35,10 +36,10 @@ public class PrettyTimeFilter implements Filter { @Override public Object apply(Object input, Map args) { - if (input instanceof Date) { + if (input instanceof Instant) { EvaluationContext context = (EvaluationContext) args.get("_context"); Locale locale = context.getLocale(); - return formatter.format(locale, (Date)input); + return formatter.format(locale, Date.from((Instant)input)); } throw new IllegalArgumentException("invalid input"); } diff --git a/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/TimestampFilter.java b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/TimestampFilter.java new file mode 100644 index 00000000..35efb314 --- /dev/null +++ b/juick-www/src/main/java/com/mitchellbosecke/pebble/extension/filters/TimestampFilter.java @@ -0,0 +1,23 @@ +package com.mitchellbosecke.pebble.extension.filters; + +import com.mitchellbosecke.pebble.extension.Filter; + +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class TimestampFilter implements Filter { + @Override + public Object apply(Object input, Map args) { + if (input instanceof Instant) { + return Date.from((Instant)input); + } + throw new IllegalArgumentException("invalid input"); + } + + @Override + public List getArgumentNames() { + return null; + } +} diff --git a/juick-www/src/main/webapp/WEB-INF/views/macros/tree.html b/juick-www/src/main/webapp/WEB-INF/views/macros/tree.html index 09ba5365..f0c283e9 100644 --- a/juick-www/src/main/webapp/WEB-INF/views/macros/tree.html +++ b/juick-www/src/main/webapp/WEB-INF/views/macros/tree.html @@ -20,9 +20,9 @@ diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/message.html b/juick-www/src/main/webapp/WEB-INF/views/partial/message.html index b3ff86cd..f3a42ff2 100644 --- a/juick-www/src/main/webapp/WEB-INF/views/partial/message.html +++ b/juick-www/src/main/webapp/WEB-INF/views/partial/message.html @@ -7,9 +7,9 @@
diff --git a/juick-www/src/main/webapp/WEB-INF/views/partial/thread_list.html b/juick-www/src/main/webapp/WEB-INF/views/partial/thread_list.html index 275ffeaf..918c4fb0 100644 --- a/juick-www/src/main/webapp/WEB-INF/views/partial/thread_list.html +++ b/juick-www/src/main/webapp/WEB-INF/views/partial/thread_list.html @@ -18,9 +18,9 @@ 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 index a8a8a1e9..156877c0 100644 --- a/juick-www/src/main/webapp/WEB-INF/views/pm_inbox.html +++ b/juick-www/src/main/webapp/WEB-INF/views/pm_inbox.html @@ -12,7 +12,7 @@ {{ msg.user.name }} -
{{ msg.date }}
+
{{ msg.timestamp | prettyTime }}
{{ msg | formatMessage }}
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 index 48aaa7e1..08b9585a 100644 --- a/juick-www/src/main/webapp/WEB-INF/views/pm_sent.html +++ b/juick-www/src/main/webapp/WEB-INF/views/pm_sent.html @@ -19,7 +19,7 @@ {{ msg.user.name }} -
{{ msg.date }}
+
{{ msg.timestamp | prettyTime }}
{{ msg | formatMessage }}
diff --git a/juick-www/src/main/webapp/WEB-INF/views/thread.html b/juick-www/src/main/webapp/WEB-INF/views/thread.html index 5f1cb148..57d7e0a1 100644 --- a/juick-www/src/main/webapp/WEB-INF/views/thread.html +++ b/juick-www/src/main/webapp/WEB-INF/views/thread.html @@ -6,9 +6,9 @@
diff --git a/src/test/java/com/juick/rss/LegacyRSS.java b/src/test/java/com/juick/rss/LegacyRSS.java index 2ad276c7..3038e2d2 100644 --- a/src/test/java/com/juick/rss/LegacyRSS.java +++ b/src/test/java/com/juick/rss/LegacyRSS.java @@ -119,7 +119,7 @@ public class LegacyRSS { out.println("]]>"); out.println(""); - out.println("" + DateFormattersHolder.getRssFormatterInstance().format(msg.getDate()) + ""); + out.println("" + DateFormattersHolder.getRssFormatterInstance().format(msg.getTimestamp()) + ""); out.println("http://juick.com/" + msg.getUser().getName() + "/" + msg.getMid() + ""); if (!msg.getTags().isEmpty()) { @@ -190,7 +190,7 @@ public class LegacyRSS { out.println("http://juick.com/" + r.uname + "/"); out.println("@" + r.uname + ":"); out.println(""); - out.println("" + DateFormattersHolder.getRssFormatterInstance().format(r.pubDate) + ""); + out.println("" + DateFormattersHolder.getRssFormatterInstance().format(r.pubDate.toInstant()) + ""); String attachment = r.attachmentType; if (attachment != null && !attachment.isEmpty()) { if (attachment.equals("jpg")) { diff --git a/src/test/java/com/juick/tests/ApiTests.java b/src/test/java/com/juick/tests/ApiTests.java index 7001d3f0..51641c1d 100644 --- a/src/test/java/com/juick/tests/ApiTests.java +++ b/src/test/java/com/juick/tests/ApiTests.java @@ -168,9 +168,6 @@ public class ApiTests { int mid = messagesService.createMessage(user_id, "yo", null, new ArrayList<>()); Message msg = messagesService.getMessage(mid); assertEquals("yo", msg.getText()); - Calendar calendar = Calendar.getInstance(); - calendar.setTime(msg.getDate()); - assertEquals(2017, calendar.get(Calendar.YEAR)); User me = msg.getUser(); assertEquals("mmmme", me.getName()); assertEquals("mmmme", messagesService.getMessageAuthor(mid).getName()); diff --git a/src/test/java/com/juick/tests/MessageTests.java b/src/test/java/com/juick/tests/MessageTests.java index 25a5115e..2cc8fed2 100644 --- a/src/test/java/com/juick/tests/MessageTests.java +++ b/src/test/java/com/juick/tests/MessageTests.java @@ -18,6 +18,8 @@ package com.juick.tests; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.juick.Message; import com.juick.util.DateFormattersHolder; import org.apache.commons.codec.CharEncoding; @@ -38,7 +40,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringWriter; import java.text.ParseException; -import java.util.Date; +import java.time.Instant; import static org.junit.Assert.assertEquals; @@ -51,9 +53,11 @@ public class MessageTests { assertEquals("First tag must be", "test", msg.getTags().get(0).getName()); assertEquals("Third tag must be", "test3", msg.getTags().get(2).getName()); assertEquals("Count of tags must be", 3, msg.getTags().size()); - Date currentDate = new Date(); - msg.setDate(currentDate); + Instant currentDate = Instant.now(); + msg.setTimestamp(currentDate); ObjectMapper serializer = new ObjectMapper(); + serializer.registerModule(new Jdk8Module()); + serializer.registerModule(new JavaTimeModule()); String jsonMessage = serializer.writeValueAsString(msg); JSONObject jsonObject = new JSONObject(jsonMessage); assertEquals("date should be in timestamp field", DateFormattersHolder.getMessageFormatterInstance().format(currentDate), -- cgit v1.2.3