2 * Sone - GetTimesAjaxPage.java - Copyright © 2010–2013 David Roden
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation, either version 3 of the License, or (at your option) any later
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.web.ajax;
20 import java.text.DateFormat;
21 import java.text.SimpleDateFormat;
22 import java.util.Date;
23 import java.util.concurrent.TimeUnit;
25 import net.pterodactylus.sone.data.Post;
26 import net.pterodactylus.sone.data.PostReply;
27 import net.pterodactylus.sone.web.WebInterface;
28 import net.pterodactylus.sone.web.page.FreenetRequest;
29 import net.pterodactylus.util.json.JsonObject;
31 import com.google.common.base.Optional;
34 * Ajax page that returns a formatted, relative timestamp for replies or posts.
36 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
38 public class GetTimesAjaxPage extends JsonPage {
40 /** Formatter for tooltips. */
41 private static final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy, HH:mm:ss");
44 * Creates a new get times AJAX page.
47 * The Sone web interface
49 public GetTimesAjaxPage(WebInterface webInterface) {
50 super("getTimes.ajax", webInterface);
57 protected JsonObject createJsonObject(FreenetRequest request) {
58 String allIds = request.getHttpRequest().getParam("posts");
59 JsonObject postTimes = new JsonObject();
60 if (allIds.length() > 0) {
61 String[] ids = allIds.split(",");
62 for (String id : ids) {
63 Optional<Post> post = webInterface.getCore().getPost(id);
64 if (!post.isPresent()) {
67 JsonObject postTime = new JsonObject();
68 Time time = getTime(post.get().getTime());
69 postTime.put("timeText", time.getText());
70 postTime.put("refreshTime", TimeUnit.MILLISECONDS.toSeconds(time.getRefresh()));
71 synchronized (dateFormat) {
72 postTime.put("tooltip", dateFormat.format(new Date(post.get().getTime())));
74 postTimes.put(id, postTime);
77 JsonObject replyTimes = new JsonObject();
78 allIds = request.getHttpRequest().getParam("replies");
79 if (allIds.length() > 0) {
80 String[] ids = allIds.split(",");
81 for (String id : ids) {
82 Optional<PostReply> reply = webInterface.getCore().getPostReply(id);
83 if (!reply.isPresent()) {
86 JsonObject replyTime = new JsonObject();
87 Time time = getTime(reply.get().getTime());
88 replyTime.put("timeText", time.getText());
89 replyTime.put("refreshTime", TimeUnit.MILLISECONDS.toSeconds(time.getRefresh()));
90 synchronized (dateFormat) {
91 replyTime.put("tooltip", dateFormat.format(new Date(reply.get().getTime())));
93 replyTimes.put(id, replyTime);
96 return createSuccessJsonObject().put("postTimes", postTimes).put("replyTimes", replyTimes);
103 protected boolean needsFormPassword() {
111 protected boolean requiresLogin() {
120 * Returns the formatted relative time for a given time.
123 * The time to format the difference from (in milliseconds)
124 * @return The formatted age
126 private Time getTime(long time) {
127 return getTime(webInterface, time);
135 * Returns the formatted relative time for a given time.
137 * @param webInterface
138 * The Sone web interface (for l10n access)
140 * The time to format the difference from (in milliseconds)
141 * @return The formatted age
143 public static Time getTime(WebInterface webInterface, long time) {
145 return new Time(webInterface.getL10n().getString("View.Sone.Text.UnknownDate"), TimeUnit.HOURS.toMillis(12));
147 long age = System.currentTimeMillis() - time;
151 text = webInterface.getL10n().getDefaultString("View.Time.InTheFuture");
152 refresh = TimeUnit.MINUTES.toMillis(5);
153 } else if (age < TimeUnit.SECONDS.toMillis(20)) {
154 text = webInterface.getL10n().getDefaultString("View.Time.AFewSecondsAgo");
155 refresh = TimeUnit.SECONDS.toMillis(10);
156 } else if (age < TimeUnit.SECONDS.toMillis(45)) {
157 text = webInterface.getL10n().getString("View.Time.HalfAMinuteAgo");
158 refresh = TimeUnit.SECONDS.toMillis(20);
159 } else if (age < TimeUnit.SECONDS.toMillis(90)) {
160 text = webInterface.getL10n().getString("View.Time.AMinuteAgo");
161 refresh = TimeUnit.MINUTES.toMillis(1);
162 } else if (age < TimeUnit.MINUTES.toMillis(30)) {
163 text = webInterface.getL10n().getString("View.Time.XMinutesAgo", "min", String.valueOf(TimeUnit.MILLISECONDS.toMinutes(age + TimeUnit.SECONDS.toMillis(30))));
164 refresh = TimeUnit.MINUTES.toMillis(1);
165 } else if (age < TimeUnit.MINUTES.toMillis(45)) {
166 text = webInterface.getL10n().getString("View.Time.HalfAnHourAgo");
167 refresh = TimeUnit.MINUTES.toMillis(10);
168 } else if (age < TimeUnit.MINUTES.toMillis(90)) {
169 text = webInterface.getL10n().getString("View.Time.AnHourAgo");
170 refresh = TimeUnit.HOURS.toMillis(1);
171 } else if (age < TimeUnit.HOURS.toMillis(21)) {
172 text = webInterface.getL10n().getString("View.Time.XHoursAgo", "hour", String.valueOf(TimeUnit.MILLISECONDS.toHours(age + TimeUnit.MINUTES.toMillis(30))));
173 refresh = TimeUnit.HOURS.toMillis(1);
174 } else if (age < TimeUnit.HOURS.toMillis(42)) {
175 text = webInterface.getL10n().getString("View.Time.ADayAgo");
176 refresh = TimeUnit.DAYS.toMillis(1);
177 } else if (age < TimeUnit.DAYS.toMillis(6)) {
178 text = webInterface.getL10n().getString("View.Time.XDaysAgo", "day", String.valueOf(TimeUnit.MILLISECONDS.toDays(age + TimeUnit.HOURS.toMillis(12))));
179 refresh = TimeUnit.DAYS.toMillis(1);
180 } else if (age < TimeUnit.DAYS.toMillis(11)) {
181 text = webInterface.getL10n().getString("View.Time.AWeekAgo");
182 refresh = TimeUnit.DAYS.toMillis(1);
183 } else if (age < TimeUnit.DAYS.toMillis(28)) {
184 text = webInterface.getL10n().getString("View.Time.XWeeksAgo", "week", String.valueOf((TimeUnit.MILLISECONDS.toHours(age) + 84) / (7 * 24)));
185 refresh = TimeUnit.DAYS.toMillis(1);
186 } else if (age < TimeUnit.DAYS.toMillis(42)) {
187 text = webInterface.getL10n().getString("View.Time.AMonthAgo");
188 refresh = TimeUnit.DAYS.toMillis(1);
189 } else if (age < TimeUnit.DAYS.toMillis(330)) {
190 text = webInterface.getL10n().getString("View.Time.XMonthsAgo", "month", String.valueOf((TimeUnit.MILLISECONDS.toDays(age) + 15) / 30));
191 refresh = TimeUnit.DAYS.toMillis(1);
192 } else if (age < TimeUnit.DAYS.toMillis(540)) {
193 text = webInterface.getL10n().getString("View.Time.AYearAgo");
194 refresh = TimeUnit.DAYS.toMillis(7);
196 text = webInterface.getL10n().getString("View.Time.XYearsAgo", "year", String.valueOf((long) ((TimeUnit.MILLISECONDS.toDays(age) + 182.64) / 365.28)));
197 refresh = TimeUnit.DAYS.toMillis(7);
199 return new Time(text, refresh);
203 * Container for a formatted time.
205 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
207 public static class Time {
209 /** The formatted time. */
210 private final String text;
212 /** The time after which to refresh the time. */
213 private final long refresh;
216 * Creates a new formatted time container.
221 * The time after which to refresh the time (in milliseconds)
223 public Time(String text, long refresh) {
225 this.refresh = refresh;
229 * Returns the formatted time.
231 * @return The formatted time
233 public String getText() {
238 * Returns the time after which to refresh the time.
240 * @return The time after which to refresh the time (in milliseconds)
242 public long getRefresh() {
250 public String toString() {