Replace utils’ Digits and custom time constants by Java’s TimeUnit.
[Sone.git] / src / main / java / net / pterodactylus / sone / web / ajax / GetTimesAjaxPage.java
1 /*
2  * Sone - GetTimesAjaxPage.java - Copyright © 2010–2013 David Roden
3  *
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
7  * version.
8  *
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
12  * details.
13  *
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/>.
16  */
17
18 package net.pterodactylus.sone.web.ajax;
19
20 import java.text.DateFormat;
21 import java.text.SimpleDateFormat;
22 import java.util.Date;
23 import java.util.concurrent.TimeUnit;
24
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;
30
31 /**
32  * Ajax page that returns a formatted, relative timestamp for replies or posts.
33  *
34  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
35  */
36 public class GetTimesAjaxPage extends JsonPage {
37
38         /** Formatter for tooltips. */
39         private static final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy, HH:mm:ss");
40
41         /**
42          * Creates a new get times AJAX page.
43          *
44          * @param webInterface
45          *            The Sone web interface
46          */
47         public GetTimesAjaxPage(WebInterface webInterface) {
48                 super("getTimes.ajax", webInterface);
49         }
50
51         /**
52          * {@inheritDoc}
53          */
54         @Override
55         protected JsonObject createJsonObject(FreenetRequest request) {
56                 String allIds = request.getHttpRequest().getParam("posts");
57                 JsonObject postTimes = new JsonObject();
58                 if (allIds.length() > 0) {
59                         String[] ids = allIds.split(",");
60                         for (String id : ids) {
61                                 Post post = webInterface.getCore().getPost(id, false);
62                                 if (post == null) {
63                                         continue;
64                                 }
65                                 JsonObject postTime = new JsonObject();
66                                 Time time = getTime(post.getTime());
67                                 postTime.put("timeText", time.getText());
68                                 postTime.put("refreshTime", TimeUnit.MILLISECONDS.toSeconds(time.getRefresh()));
69                                 synchronized (dateFormat) {
70                                         postTime.put("tooltip", dateFormat.format(new Date(post.getTime())));
71                                 }
72                                 postTimes.put(id, postTime);
73                         }
74                 }
75                 JsonObject replyTimes = new JsonObject();
76                 allIds = request.getHttpRequest().getParam("replies");
77                 if (allIds.length() > 0) {
78                         String[] ids = allIds.split(",");
79                         for (String id : ids) {
80                                 PostReply reply = webInterface.getCore().getPostReply(id, false);
81                                 if (reply == null) {
82                                         continue;
83                                 }
84                                 JsonObject replyTime = new JsonObject();
85                                 Time time = getTime(reply.getTime());
86                                 replyTime.put("timeText", time.getText());
87                                 replyTime.put("refreshTime", TimeUnit.MILLISECONDS.toSeconds(time.getRefresh()));
88                                 synchronized (dateFormat) {
89                                         replyTime.put("tooltip", dateFormat.format(new Date(reply.getTime())));
90                                 }
91                                 replyTimes.put(id, replyTime);
92                         }
93                 }
94                 return createSuccessJsonObject().put("postTimes", postTimes).put("replyTimes", replyTimes);
95         }
96
97         /**
98          * {@inheritDoc}
99          */
100         @Override
101         protected boolean needsFormPassword() {
102                 return false;
103         }
104
105         /**
106          * {@inheritDoc}
107          */
108         @Override
109         protected boolean requiresLogin() {
110                 return false;
111         }
112
113         //
114         // PRIVATE METHODS
115         //
116
117         /**
118          * Returns the formatted relative time for a given time.
119          *
120          * @param time
121          *            The time to format the difference from (in milliseconds)
122          * @return The formatted age
123          */
124         private Time getTime(long time) {
125                 return getTime(webInterface, time);
126         }
127
128         //
129         // STATIC METHODS
130         //
131
132         /**
133          * Returns the formatted relative time for a given time.
134          *
135          * @param webInterface
136          *            The Sone web interface (for l10n access)
137          * @param time
138          *            The time to format the difference from (in milliseconds)
139          * @return The formatted age
140          */
141         public static Time getTime(WebInterface webInterface, long time) {
142                 if (time == 0) {
143                         return new Time(webInterface.getL10n().getString("View.Sone.Text.UnknownDate"), TimeUnit.HOURS.toMillis(12));
144                 }
145                 long age = System.currentTimeMillis() - time;
146                 String text;
147                 long refresh;
148                 if (age < 0) {
149                         text = webInterface.getL10n().getDefaultString("View.Time.InTheFuture");
150                         refresh = TimeUnit.MINUTES.toMillis(5);
151                 } else if (age < TimeUnit.SECONDS.toMillis(20)) {
152                         text = webInterface.getL10n().getDefaultString("View.Time.AFewSecondsAgo");
153                         refresh = TimeUnit.SECONDS.toMillis(10);
154                 } else if (age < TimeUnit.SECONDS.toMillis(45)) {
155                         text = webInterface.getL10n().getString("View.Time.HalfAMinuteAgo");
156                         refresh = TimeUnit.SECONDS.toMillis(20);
157                 } else if (age < TimeUnit.SECONDS.toMillis(90)) {
158                         text = webInterface.getL10n().getString("View.Time.AMinuteAgo");
159                         refresh = TimeUnit.MINUTES.toMillis(1);
160                 } else if (age < TimeUnit.MINUTES.toMillis(30)) {
161                         text = webInterface.getL10n().getString("View.Time.XMinutesAgo", "min", String.valueOf(TimeUnit.MILLISECONDS.toMinutes(age + TimeUnit.SECONDS.toMillis(30))));
162                         refresh = TimeUnit.MINUTES.toMillis(1);
163                 } else if (age < TimeUnit.MINUTES.toMillis(45)) {
164                         text = webInterface.getL10n().getString("View.Time.HalfAnHourAgo");
165                         refresh = TimeUnit.MINUTES.toMillis(10);
166                 } else if (age < TimeUnit.MINUTES.toMillis(90)) {
167                         text = webInterface.getL10n().getString("View.Time.AnHourAgo");
168                         refresh = TimeUnit.HOURS.toMillis(1);
169                 } else if (age < TimeUnit.HOURS.toMillis(21)) {
170                         text = webInterface.getL10n().getString("View.Time.XHoursAgo", "hour", String.valueOf(TimeUnit.MILLISECONDS.toHours(age + TimeUnit.MINUTES.toMillis(30))));
171                         refresh = TimeUnit.HOURS.toMillis(1);
172                 } else if (age < TimeUnit.HOURS.toMillis(42)) {
173                         text = webInterface.getL10n().getString("View.Time.ADayAgo");
174                         refresh = TimeUnit.DAYS.toMillis(1);
175                 } else if (age < TimeUnit.DAYS.toMillis(6)) {
176                         text = webInterface.getL10n().getString("View.Time.XDaysAgo", "day", String.valueOf(TimeUnit.MILLISECONDS.toDays(age + TimeUnit.HOURS.toMillis(12))));
177                         refresh = TimeUnit.DAYS.toMillis(1);
178                 } else if (age < TimeUnit.DAYS.toMillis(11)) {
179                         text = webInterface.getL10n().getString("View.Time.AWeekAgo");
180                         refresh = TimeUnit.DAYS.toMillis(1);
181                 } else if (age < TimeUnit.DAYS.toMillis(28)) {
182                         text = webInterface.getL10n().getString("View.Time.XWeeksAgo", "week", String.valueOf((TimeUnit.MILLISECONDS.toHours(age) + 84) / 24));
183                         refresh = TimeUnit.DAYS.toMillis(1);
184                 } else if (age < TimeUnit.DAYS.toMillis(42)) {
185                         text = webInterface.getL10n().getString("View.Time.AMonthAgo");
186                         refresh = TimeUnit.DAYS.toMillis(1);
187                 } else if (age < TimeUnit.DAYS.toMillis(330)) {
188                         text = webInterface.getL10n().getString("View.Time.XMonthsAgo", "month", String.valueOf((TimeUnit.MILLISECONDS.toDays(age) + 15) / 30));
189                         refresh = TimeUnit.DAYS.toMillis(1);
190                 } else if (age < TimeUnit.DAYS.toMillis(540)) {
191                         text = webInterface.getL10n().getString("View.Time.AYearAgo");
192                         refresh = TimeUnit.DAYS.toMillis(7);
193                 } else {
194                         text = webInterface.getL10n().getString("View.Time.XYearsAgo", "year", String.valueOf((long) ((TimeUnit.MILLISECONDS.toDays(age) + 182.64) / 365.28)));
195                         refresh = TimeUnit.DAYS.toMillis(7);
196                 }
197                 return new Time(text, refresh);
198         }
199
200         /**
201          * Container for a formatted time.
202          *
203          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
204          */
205         public static class Time {
206
207                 /** The formatted time. */
208                 private final String text;
209
210                 /** The time after which to refresh the time. */
211                 private final long refresh;
212
213                 /**
214                  * Creates a new formatted time container.
215                  *
216                  * @param text
217                  *            The formatted time
218                  * @param refresh
219                  *            The time after which to refresh the time (in milliseconds)
220                  */
221                 public Time(String text, long refresh) {
222                         this.text = text;
223                         this.refresh = refresh;
224                 }
225
226                 /**
227                  * Returns the formatted time.
228                  *
229                  * @return The formatted time
230                  */
231                 public String getText() {
232                         return text;
233                 }
234
235                 /**
236                  * Returns the time after which to refresh the time.
237                  *
238                  * @return The time after which to refresh the time (in milliseconds)
239                  */
240                 public long getRefresh() {
241                         return refresh;
242                 }
243
244                 /**
245                  * {@inheritDoc}
246                  */
247                 @Override
248                 public String toString() {
249                         return text;
250                 }
251
252         }
253
254 }