Changeset 5762
- Timestamp:
- Nov 28, 2019, 1:52:09 PM (3 years ago)
- Location:
- extensions/net.sf.basedb.reggie/trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/net.sf.basedb.reggie/trunk/config/reggie-config.xml
r5737 r5762 23 23 <!-- Max age (in days) of entries to display (even if the max number hasn't been reached) --> 24 24 <max-age-in-days>14</max-age-in-days> 25 <quote-of-the-day> 26 <!-- URL to quote-of-the-day endpoint (optional, set an empty URL to disable this feature) --> 27 <url>https://quotes.rest/qod.json</url> 28 <!-- Default is 12 hours; do not set to less than 3600 since the external API has a limit --> 29 <max-age-in-seconds>43200</max-age-in-seconds> 30 </quote-of-the-day> 25 31 </activity-log> 26 32 -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/activity/ActivityLog.java
r5761 r5762 1 1 package net.sf.basedb.reggie.activity; 2 2 3 import java.io.InputStream; 4 import java.io.InputStreamReader; 5 import java.io.StringWriter; 6 import java.net.URL; 7 import java.net.URLConnection; 3 8 import java.nio.charset.Charset; 9 import java.nio.charset.StandardCharsets; 4 10 import java.text.SimpleDateFormat; 5 11 import java.time.LocalDateTime; … … 21 27 import org.jdom2.output.Format; 22 28 import org.jdom2.output.XMLOutputter; 29 import org.json.simple.JSONArray; 30 import org.json.simple.JSONObject; 31 import org.json.simple.parser.JSONParser; 23 32 import org.slf4j.Logger; 24 33 import org.slf4j.LoggerFactory; 25 34 26 35 import net.sf.basedb.clients.web.extensions.ExtensionsControl; 36 import net.sf.basedb.core.AbsoluteProgressReporter; 27 37 import net.sf.basedb.core.Application; 28 38 import net.sf.basedb.reggie.Reggie; 29 39 import net.sf.basedb.reggie.XmlConfig; 40 import net.sf.basedb.util.FileUtil; 30 41 import net.sf.basedb.util.Values; 31 42 … … 106 117 private int maxAgeInDays = 14; 107 118 private int maxEntries = 35; 119 private int maxQuoteAgeInSeconds = 3600 * 12; // 12 hours is the default 120 private URL quoteUrl; 108 121 109 122 private volatile byte[] rssFeed; … … 187 200 maxAgeInDays = Values.getInt(cfg.getConfig("activity-log/max-age-in-days"), 14); 188 201 maxEntries = Values.getInt(cfg.getConfig("activity-log/max-entries"), 35); 202 maxQuoteAgeInSeconds = Values.getInt(cfg.getConfig("activity-log/quote-of-the-day/max-age-in-seconds"), 12*3600); 203 try 204 { 205 quoteUrl = new URL(cfg.getConfig("activity-log/quote-of-the-day/url")); 206 } 207 catch (Exception ex) 208 { 209 quoteUrl = null; 210 } 189 211 } 190 212 191 213 public QuoteOfTheDay getQuoteOfTheDay() 192 214 { 193 if (quoteOfTheDay == null) 194 { 195 QuoteOfTheDay tmp = new QuoteOfTheDay(); 196 tmp.setAuthor("Indiana Jones - Raiders of the Lost Ark"); 197 tmp.setQuote("There's a big snake in the plane, Jock!"); 198 quoteOfTheDay = tmp; 199 } 200 return quoteOfTheDay; 215 if (quoteUrl == null) return null; // Disabled 216 217 if (quoteOfTheDay == null || quoteOfTheDay.getAgeInSeconds() > maxQuoteAgeInSeconds) 218 { 219 synchronized (quoteUrl) 220 { 221 if (quoteOfTheDay == null || quoteOfTheDay.getAgeInSeconds() > maxQuoteAgeInSeconds) 222 { 223 InputStream in = null; 224 QuoteOfTheDay tmp = new QuoteOfTheDay(); 225 try 226 { 227 // Read data from the URL, if external we have a fixed limit 228 AbsoluteProgressReporter maxDataFilter = quoteUrl.getProtocol().startsWith("http") ? new MaxDownloadFilter(5000) : null; 229 logger.debug("Loading quote from " + quoteUrl); 230 URLConnection conn = quoteUrl.openConnection(); 231 conn.setConnectTimeout(3000); 232 conn.setReadTimeout(3000); 233 in = conn.getInputStream(); 234 StringWriter sout = new StringWriter(); 235 FileUtil.copy(new InputStreamReader(in, StandardCharsets.UTF_8), sout, maxDataFilter); 236 logger.debug("A quote was loaded from " + quoteUrl + "; bytes="+sout.getBuffer().length()); 237 238 // Parse as JSON { "contents": { "quotes": [ {"quote": "...", "author": "..." }, {...} ] }} 239 JSONObject json = (JSONObject)new JSONParser().parse(sout.toString()); 240 json = (JSONObject)json.get("contents"); 241 JSONArray jsonQuotes = (JSONArray)json.get("quotes"); 242 243 int index = (int)Math.floor(Math.random()*jsonQuotes.size()); 244 JSONObject jsonQuote = (JSONObject)jsonQuotes.get(index); 245 String quote = (String)jsonQuote.get("quote"); 246 String author = (String)jsonQuote.get("author"); 247 248 // Check that we have values of acceptable lengths 249 if (quote != null && author != null && quote.length() < 160 && author.length() < 40) 250 { 251 tmp.setAuthor(author); 252 tmp.setQuote(quote); 253 logger.debug("A quote was successfully loaded from "+ quoteUrl); 254 } 255 } 256 catch (Exception ex) 257 { 258 logger.warn("Could not load quote-of-the-day", ex); 259 } 260 finally 261 { 262 FileUtil.close(in); 263 quoteOfTheDay = tmp; 264 } 265 } 266 } 267 } 268 else if (logger.isDebugEnabled() || true) 269 { 270 logger.debug("Using existing quote; age="+quoteOfTheDay.getAgeInSeconds()); 271 } 272 return quoteOfTheDay == null || quoteOfTheDay.getQuote() == null ? null : quoteOfTheDay; 201 273 } 202 274 … … 441 513 } 442 514 515 /** 516 To prevent external data overflow. 517 */ 518 static class MaxDownloadFilter 519 implements AbsoluteProgressReporter 520 { 521 522 private final long maxBytes; 523 524 public MaxDownloadFilter(long maxBytes) 525 { 526 this.maxBytes = maxBytes; 527 } 528 529 @Override 530 public void display(int percent, String message) 531 {} 532 533 @Override 534 public void append(String message) 535 {} 536 537 @Override 538 public void displayAbsolute(long completed, String message) 539 { 540 if (completed > maxBytes) 541 { 542 throw new RuntimeException("Too much data: " + completed + "; max allowed: " + maxBytes); 543 } 544 } 545 546 } 443 547 } -
extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/activity/QuoteOfTheDay.java
r5761 r5762 7 7 public class QuoteOfTheDay 8 8 { 9 private final long created; 9 10 private String quote; 10 11 private String author; 11 12 12 13 public QuoteOfTheDay() 13 {} 14 { 15 this.created = System.currentTimeMillis(); 16 } 14 17 15 18 /** … … 39 42 } 40 43 44 /** 45 Get the age of the quote in seconds. 46 */ 47 public int getAgeInSeconds() 48 { 49 return (int)((System.currentTimeMillis() - created) / 1000); 50 } 51 41 52 }
Note: See TracChangeset
for help on using the changeset viewer.