Make post reply returned by provider optional.
[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 import com.google.common.base.Optional;
32
33 /**
34  * Ajax page that returns a formatted, relative timestamp for replies or posts.
35  *
36  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
37  */
38 public class GetTimesAjaxPage extends JsonPage {
39
40         /** Formatter for tooltips. */
41         private static final DateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy, HH:mm:ss");
42
43         /**
44          * Creates a new get times AJAX page.
45          *
46          * @param webInterface
47          *            The Sone web interface
48          */
49         public GetTimesAjaxPage(WebInterface webInterface) {
50                 super("getTimes.ajax", webInterface);
51         }
52
53         /**
54          * {@inheritDoc}
55          */
56         @Override
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                                 Post post = webInterface.getCore().getPost(id);
64                                 if (post == null) {
65                                         continue;
66                                 }
67                                 JsonObject postTime = new JsonObject();
68                                 Time time = getTime(post.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.getTime())));
73                                 }
74                                 postTimes.put(id, postTime);
75                         }
76                 }
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()) {
84                                         continue;
85                                 }
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())));
92                                 }
93                                 replyTimes.put(id, replyTime);
94                         }
95                 }
96                 return createSuccessJsonObject().put("postTimes", postTimes).put("replyTimes", replyTimes);
97         }
98
99         /**
100          * {@inheritDoc}
101          */
102         @Override
103         protected boolean needsFormPassword() {
104                 return false;
105         }
106
107         /**
108          * {@inheritDoc}
109          */
110         @Override
111         protected boolean requiresLogin() {
112                 return false;
113         }
114
115         //
116         // PRIVATE METHODS
117         //
118
119         /**
120          * Returns the formatted relative time for a given time.
121          *
122          * @param time
123          *            The time to format the difference from (in milliseconds)
124          * @return The formatted age
125          */
126         private Time getTime(long time) {
127                 return getTime(webInterface, time);
128         }
129
130         //
131         // STATIC METHODS
132         //
133
134         /**
135          * Returns the formatted relative time for a given time.
136          *
137          * @param webInterface
138          *            The Sone web interface (for l10n access)
139          * @param time
140          *            The time to format the difference from (in milliseconds)
141          * @return The formatted age
142          */
143         public static Time getTime(WebInterface webInterface, long time) {
144                 if (time == 0) {
145                         return new Time(webInterface.getL10n().getString("View.Sone.Text.UnknownDate"), TimeUnit.HOURS.toMillis(12));
146                 }
147                 long age = System.currentTimeMillis() - time;
148                 String text;
149                 long refresh;
150                 if (age < 0) {
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) / 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);
195                 } else {
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);
198                 }
199                 return new Time(text, refresh);
200         }
201
202         /**
203          * Container for a formatted time.
204          *
205          * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
206          */
207         public static class Time {
208
209                 /** The formatted time. */
210                 private final String text;
211
212                 /** The time after which to refresh the time. */
213                 private final long refresh;
214
215                 /**
216                  * Creates a new formatted time container.
217                  *
218                  * @param text
219                  *            The formatted time
220                  * @param refresh
221                  *            The time after which to refresh the time (in milliseconds)
222                  */
223                 public Time(String text, long refresh) {
224                         this.text = text;
225                         this.refresh = refresh;
226                 }
227
228                 /**
229                  * Returns the formatted time.
230                  *
231                  * @return The formatted time
232                  */
233                 public String getText() {
234                         return text;
235                 }
236
237                 /**
238                  * Returns the time after which to refresh the time.
239                  *
240                  * @return The time after which to refresh the time (in milliseconds)
241                  */
242                 public long getRefresh() {
243                         return refresh;
244                 }
245
246                 /**
247                  * {@inheritDoc}
248                  */
249                 @Override
250                 public String toString() {
251                         return text;
252                 }
253
254         }
255
256 }