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