001/* 002 * $Id: TunesAjaxRestListener.java 185 2020-09-07 02:43:14Z tgutwin $ 003 * $HeadURL: svn://svn.webarts.bc.ca/closed/trunk/www/tunes/WEB-INF/src/ca/bc/webarts/servlet/TunesAjaxRestListener.java $ 004 * $Revision: 185 $ 005 * $LastChangedDate: 2020-09-06 19:43:14 -0700 (Sun, 06 Sep 2020) $ 006 * $LastChangedBy: tgutwin $ 007 * Copyright (c) 2014-2020 Tom B. Gutwin P.Eng. North Vancouver BC Canada 008 * 009 * This program is free software; you can redistribute it and/or 010 * modify it under the terms of the GNU General Public License 011 * as published by the Free Software Foundation; either version 3 012 * of the License, or any later version. 013 * 014 * This program is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * along with this program; If not, see <http://www.gnu.org/licenses/>. 021 */ 022package ca.bc.webarts.servlet; 023 024import ca.bc.webarts.tools.Log; 025import ca.bc.webarts.widgets.Util; 026import ca.bc.webarts.tools.sockets.*; 027import ca.bc.webarts.widgets.ResultSetConverter; 028import ca.bc.webarts.widgets.tunes.TunesHelper; 029 030import com.oreilly.servlet.ParameterParser; 031import com.oreilly.servlet.ParameterNotFoundException; 032import com.oreilly.servlet.ServletUtils; 033 034import java.text.DecimalFormat; 035import java.io.BufferedReader; 036import java.io.File; 037import java.io.FileNotFoundException; 038import java.io.FileOutputStream; 039import java.io.FileReader; 040import java.io.FileWriter; 041import java.io.FileInputStream; 042import java.io.IOException; 043import java.io.InputStream; 044import java.io.OutputStream; 045import java.io.BufferedReader; 046import java.io.InputStreamReader; 047import java.io.IOException; 048import java.net.Socket; 049import java.net.UnknownHostException; 050import java.net.InetAddress; 051import java.net.MalformedURLException; 052import java.net.URL; 053import java.net.UnknownHostException; 054import java.util.Calendar; 055import java.util.Date; 056import java.util.Enumeration; 057import java.util.TimeZone; 058import java.util.Vector; 059import java.util.zip.ZipEntry; 060import java.util.zip.ZipOutputStream; 061import java.text.DateFormat; 062import java.text.SimpleDateFormat; 063import java.time.Duration; 064import java.time.LocalDateTime; 065import java.time.ZonedDateTime; 066import java.time.format.DateTimeFormatter; 067 068import javax.servlet.http.HttpServlet; 069import javax.servlet.http.HttpServletRequest; 070import javax.servlet.*; 071import javax.servlet.http.*; 072 073//import javax.json.Json; 074 075/** 076 * This class is a generic listener, implemented as a servlet, for responding to AJAX and/or Rest style requests.<br /> 077 * 078 * @author tgutwin 079 * @created April 25, 2016 080 */ 081public class TunesAjaxRestListener extends javax.servlet.http.HttpServlet 082{ 083 // implements SingleThreadModel 084 085 /** Class constant. **/ 086 protected static final String className_ = "TunesAjaxRestListener"; 087 private final static String SYSTEM_FILE_SEPERATOR = File.separator; 088 /** Version String. */ 089 private final static String SERVLET_VERSION = Util.spacesToCapsInString("0.99.RC.6_[$Rev: 185 $]"); 090 091 public static final String CLIENT_SETTING_NAME_VIEWPORTWIDTH = "clientSetting.viewPortWidth"; 092 public static final String CLIENT_SETTING_NAME_VIEWPORTHEIGHT = "clientSetting.viewPortHeight"; 093 public static final String CLIENT_SETTING_NAME_BROWSER_NAME = "clientSetting.browserName"; 094 public static final String CLIENT_SETTING_NAME_BROWSER_VERSION = "clientSetting.browserVersion"; 095 public static final String CLIENT_SETTING_NAME_DEVICE_TYPE = "clientSetting.deviceType"; 096 097 public static final String CLIENT_SETTING_NAME_LASTFM_SESSION_KEY = "clientSetting.lastFmSession"; 098 public static final String CLIENT_SETTING_NAME_LASTFM_USERID = "clientSetting.lastFmUserID"; 099 public static final String CLIENT_SETTING_NAME_LASTFM_USER_RECENT = "clientSetting.lastFmUserRecent"; 100 public static final String CLIENT_SETTING_NAME_LASTFM_PLAY_TRACK_NUM = "clientSetting.lastFmPlayTrackNum"; 101 public static final String CLIENT_SETTING_NAME_LASTFM_PLAY_TRACK = "clientSetting.lastFmPlayTrack"; 102 public static final String CLIENT_SETTING_NAME_LASTFM_PLAY_ALBUM = "clientSetting.lastFmPlayAlbum"; 103 public static final String CLIENT_SETTING_NAME_LASTFM_PLAY_ARTIST = "clientSetting.lastFmPlayArtist"; 104 public static final String CLIENT_SETTING_NAME_LASTFM_PLAY_ALBUM_ARTIST = "clientSetting.lastFmPlayAlbumArtist"; 105 public static final String CLIENT_SETTING_NAME_LASTFM_PLAY_TIME = "clientSetting.lastFmPlayTime"; 106 public static final String CLIENT_SETTING_NAME_LASTFM_PLAY_DURATION = "clientSetting.lastFmPlayDuration"; 107 public static final String CLIENT_SETTING_NAME_LASTFM_SCROBBLE_TRACK = "clientSetting.lastFmScrobbleTrack"; 108 public static final String CLIENT_SETTING_NAME_LASTFM_SCROBBLE_ARTIST = "clientSetting.lastFmScrobbleArtist"; 109 public static final String CLIENT_SETTING_NAME_LASTFM_SCROBBLE_ALBUM = "clientSetting.lastFmScrobbleAlbum"; 110 public static final String CLIENT_SETTING_NAME_LASTFM_SCROBBLE_ALBUM_ARTIST= "clientSetting.lastFmScrobbleAlbumArtist"; 111 public static final String CLIENT_SETTING_NAME_LASTFM_LOVE_TRACK = "clientSetting.lastFmLoveTrack"; 112 public static final String CLIENT_SETTING_NAME_LASTFM_LIST_LOVE_TRACK = "clientSetting.lastFmListLovedTracks"; 113 114 /** DEFAULT Last.FM username to use: admin .**/ 115 protected static final String LASTFM_DEFAULT_USERNAME = "tgutwin"; //"${lastfm.user}"; 116 /** DEFAULT Last.FM password to use: admin .**/ 117 protected static final String LASTFM_DEFAULT_PASSWORD = "~19AcrobatiC19~~~"; //"${lastfm.pass}"; 118 119 /** DEFAULT WebSocket PORT on pi. **/ 120 public static final String PIWEBSOCKET_DEFAULT_SERVER = "pi2.webarts.bc.ca"; 121 /** DEFAULT WebSocket PORT on pi. **/ 122 public static final int PIWEBSOCKET_DEFAULT_PORT = 44448; 123 /** Build String. (yymmddhhss) */ 124 private final static String BUILD_TAG = "160425183718"; 125 126 /** The webServer hostname this servlet is alive on. **/ 127 private static String webServerHostName_ = "fred.webarts.bc.ca"; 128 129 private boolean debugOut_ = true; 130 protected static Log log_= Log.getInstance(); 131 132 private int viewPortWidth_ = 0; 133 private int viewPortHeight_ = 0; 134 private String someParamYouWannaSet_ = ""; 135 136 /** Control for rest response format XML(default) or JSON. **/ 137 private boolean xmlResponse_ = false; 138 139 /** AJAX param - **/ 140 private String debugOut = ""; 141 private String dataType = ""; 142 private int viewPortWidth = 0; 143 private int viewPortHeight = 0; 144 private String browserName = ""; 145 private String browserVersion = ""; 146 private String lastFmSessionKey = ""; 147 private String lastFmUserRecent = ""; 148 private String lastFmPlayTrack = ""; 149 private int lastFmPlayTrackNum = 0; 150 private String lastFmPlayAlbum = ""; 151 private String lastFmPlayArtist = ""; 152 private String lastFmPlayAlbumArtist = ""; 153 private int lastFmPlayTime = 0; 154 private int lastFmPlayDuration = 0; 155 private String lastFmScrobbleTrack = ""; 156 private String lastFmPreviousScrobbleTrack = ""; 157 private String lastFmScrobbleArtist = ""; 158 private String lastFmScrobbleAlbum = ""; 159 private String lastFmScrobbleAlbumArtist = ""; 160 private String lastFmLoveTrack = ""; 161 private String lastFmListLovedTracks = ""; 162 private boolean xmlResponse = xmlResponse_; 163 private TunesHelper tunesHelper = null; 164 private String lastFmLogin = ""; 165 private String lastFmUserID_ = LASTFM_DEFAULT_USERNAME; 166 private String lastFmPassword_ = LASTFM_DEFAULT_PASSWORD; 167 private boolean lastFMInit_ = false; 168 private java.util.Vector <de.umass.lastfm.Track> lastFmRecentTracks_ = null; 169 private String [] ajaxCommands_ = { "lastFmPlayTrack", 170 "lastFmLogin", 171 "lastFmScrobbleTrack", 172 "lastFmLoveTrack", 173 "lastFmListLovedTracks", 174 "lastFmUserRecent"}; 175 private String [] restCommands_ = { "test", 176 "lastFmListLovedTracks", 177 "playOnPi"}; 178 /** true if using TCP Socket listener running on pi2 false if using ssh access or (the NEW recommended) WebSocket. **/ 179 private boolean piWebSocketAccess_ = false; 180 private String piWebSocketServer_ = PIWEBSOCKET_DEFAULT_SERVER; 181 private int piWebSocketPort_ = PIWEBSOCKET_DEFAULT_PORT; 182 private org.eclipse.jetty.websocket.client.WebSocketClient piWebSocket_ = new org.eclipse.jetty.websocket.client.WebSocketClient(); 183 184 /** true if using TCP Socket listener running on pi2 false if using ssh access or (the NEW recommended) WebSocket. **/ 185 private boolean piSocketAccess_ = true; 186 private String piTunesTCPSocketServer_ = "pi2.webarts.bc.ca"; 187 private int piTunesTCPSocket_ = TCPSocketServer.DEFAULT_PORT; 188 189 /** 190 * Gets the ServletInfo attribute of the TunesAjaxRestListener object 191 * 192 * @return The ServletInfo value 193 */ 194 public String getServletInfo() 195 { 196 final String methodName = "getServletInfo"; 197 return "WebARTS Design TunesAjaxRestListener servlet. Version:" + SERVLET_VERSION + 198 " Build:" + BUILD_TAG; 199 } 200 201 202 /** 203 * The one time servlet init stuff goes here. It sets the derbyDBDir based on the following prioritized varables: 204 * <ol><li>context init param: derbyDBDir</li><li>servlet init param (from web.xml): derbyDBDir</li> 205 * <li>default hardcoded variable: derbyDBDir</li></ol>If defined in multiple places, the higher priority item will 206 * be used. 207 **/ 208 public void init() 209 { 210 System.out.println("\n~~~~~~~~\n~~~~~~~~\nInitializing ca.bc.webarts.servlet.TunesAjaxRestListener\n~~~~~~~~\n~~~~~~~~"); 211 212 boolean notFoundInit = true; 213 boolean notFoundContext = true; 214 java.util.Enumeration <String> initEnum = getInitParameterNames(); 215 for (; notFoundInit && initEnum.hasMoreElements();) 216 { 217 if(initEnum.nextElement().equals("someParamYouWannaSet")) 218 { 219 notFoundInit = false; 220 /* Do something with the init param */ 221 someParamYouWannaSet_ = getInitParameter("someParamYouWannaSet"); 222 System.out.println("\n~~~~~~~~\n INIT ServletParam: someParamYouWannaSet="+someParamYouWannaSet_); 223 } 224 } 225 226 //also check context 227 initEnum = getServletConfig().getServletContext().getInitParameterNames(); 228 for (; notFoundContext && initEnum.hasMoreElements();) 229 { 230 if(initEnum.nextElement().equals("someParamYouWannaSet")) 231 { 232 notFoundContext = false; 233 /* Do something with the init param */ 234 someParamYouWannaSet_ = getServletConfig().getServletContext().getInitParameter("derbyDBDir"); 235 System.out.println("\n~~~~~~~~\n INIT ContextParam: someParamYouWannaSet="+someParamYouWannaSet_); 236 } 237 } 238 239 if(notFoundInit && notFoundContext ) 240 { 241 /* Set the default values */ 242 //eagleDBDir_ = pEye_.getDerbyDBDir(); 243 } 244 245 try 246 { 247 webServerHostName_ = InetAddress.getLocalHost().getHostName(); 248 } 249 catch (UnknownHostException ex) 250 { 251 webServerHostName_ = "fred.webarts.bc.ca"; 252 } 253 } 254 255 256 /** Override to close Things **/ 257 public void destroy() 258 { 259 super.destroy(); 260 } 261 262 263 /** 264 * Returns the value of viewPortWidth_. 265 */ 266 public int getViewPortWidth() { 267 return viewPortWidth_; 268 } 269 270 271 /** 272 * Sets the value of viewPortWidth_. 273 * @param viewPortWidth The value to assign viewPortWidth_. 274 */ 275 public void setViewPortWidth(int viewPortWidth) { 276 this.viewPortWidth_ = viewPortWidth; 277 } 278 279 280 /** 281 * Returns the value of viewPortHeight_. 282 */ 283 public int getViewPortHeight() { 284 return viewPortHeight_; 285 } 286 287 288 /** 289 * Sets the value of viewPortHeight_. 290 * @param viewPortWidth The value to assign viewPortWidth_. 291 */ 292 public void setViewPortHeight(int viewPortHeight) { 293 this.viewPortHeight_ = viewPortHeight; 294 } 295 296 297 /** 298 * Returns the value of debugOut_. 299 */ 300 public boolean getDebugOut() 301 { 302 return debugOut_; 303 } 304 305 306 /** 307 * Sets the value of debugOut_. 308 * @param debugOut The value to assign debugOut_. 309 */ 310 public void setDebugOut(boolean debugOut) 311 { 312 this.debugOut_ = debugOut; 313 log_.setLogLevel((debugOut_?log_.DEBUG:log_.MINOR)); 314 } 315 316 317 /** 318 * Get Method for class field 'xmlResponse'. 319 * 320 * @return boolean - The value the class field 'xmlResponse' XML (true) or JSON (false). 321 * 322 **/ 323 public boolean getXmlResponse() 324 { 325 return xmlResponse_; 326 } // getXmlResponse Method 327 328 329 /** 330 * Set Method for class field 'xmlResponse' that controls if teh rest response is in XML (true) or JSON (false). 331 * 332 * @param xmlResponse is the value to set this class field to XML (true) or JSON (false). 333 * 334 **/ 335 public void setXmlResponse(boolean xmlResponse) 336 { 337 this.xmlResponse_ = xmlResponse; 338 } // setXmlResponse Method 339 340 341 /** 342 * streams to a zipped out stream (without creating a file). 343 * from: http://www.coderanch.com/t/276892/java-io/java/Stream-data-ZipOutputStream 344 * @param servletOutput is the stream to zip into 345 * @param dataName are the pseudo fileName that will get created in the zip (pseudo file) stream 346 * @param dataStream the data to zip 347 **/ 348 private void streamZIP(OutputStream servletOut, String dataName, InputStream dataStream) 349 { 350 String[] dataNames = {dataName}; 351 InputStream[] dataStreams = {dataStream}; 352 streamZIP(servletOut, dataNames,dataStreams); 353 } 354 355 356 /** 357 * streams to a zipped out stream (without creating a file). 358 * from: http://www.coderanch.com/t/276892/java-io/java/Stream-data-ZipOutputStream 359 * 360 * Sample servlet doGet...<br /> 361 * public void doGet(HttpServletRequest request, 362 HttpServletResponse response) throws IOException{ 363 response.setContentType("text/plain"); 364 response.setHeader("Content-Disposition", 365 "attachment;filename=downloadname.txt"); 366 String[] dataNames = {dataName}; 367 InputStream[] dataStreams = {dataStream}; 368 OutputStream os = response.getOutputStream(); 369 streamZIP(servletOut, dataNames,dataStreams); 370 } 371 * 372 * 373 * @param servletOutput is the stream to zip into 374 * @param dataNames are the pseudo fileNames that will get created in the zip (pseudo file) stream 375 * @param dataStreams the data to zip 376 **/ 377 private void streamZIP(OutputStream servletOut, 378 String[] dataNames, 379 InputStream[] dataStreams) 380 { 381 ZipOutputStream zos = new ZipOutputStream(servletOut); 382 final int DATA_BLOCK_SIZE = 2048; 383 int byteCount; 384 byte[] data; 385 386 try 387 { 388 for(int i = 0; i < dataNames.length; i++) 389 { 390 ZipEntry ze = new ZipEntry(dataNames[i]); 391 zos.putNextEntry(ze); 392 data = new byte[DATA_BLOCK_SIZE]; 393 394 while((byteCount = dataStreams[i].read(data, 0, DATA_BLOCK_SIZE)) != -1) 395 { 396 zos.write(data, 0, byteCount); 397 } 398 399 zos.flush(); 400 zos.closeEntry(); 401 dataStreams[i].close(); 402 } 403 zos.close(); 404 } 405 catch(Exception e) 406 { 407 System.err.println("Problem streaming zip data " + e.toString()); 408 } 409 } 410 411 412 /** Parses any defined servlet params into the defined class vars. **/ 413 private void parseParams(HttpServletRequest req) 414 { 415 ParameterParser parser = new ParameterParser(req); 416 if(debugOut_) 417 { 418 System.out.println("\nRequest Params:"); 419 Enumeration<String> parmNames = req.getParameterNames(); 420 for (; parmNames.hasMoreElements();) 421 { 422 String currParamName = (String) parmNames.nextElement(); 423 System.out.println(" "+currParamName+"="+req.getParameter(currParamName)); 424 } 425 } 426 427 /* parse out the request params into class vars */ 428 debugOut = parser.getStringParameter("debugOut", ""); 429 viewPortWidth = parser.getIntParameter("viewPortWidth",0); 430 viewPortHeight = parser.getIntParameter("viewPortHeight",0); 431 browserName = parser.getStringParameter("clientBrowser",""); 432 browserVersion = parser.getStringParameter("clientBrowserVersion",""); 433 dataType = parser.getStringParameter("dataType","json"); 434 435 lastFmLogin = parser.getStringParameter("lastFmLogin",""); // Ajax Request 436 lastFmUserID_ = parser.getStringParameter("lastFmUserID",LASTFM_DEFAULT_USERNAME); 437 lastFmPassword_ = parser.getStringParameter("lastFmPassword",LASTFM_DEFAULT_PASSWORD); 438 lastFmSessionKey = parser.getStringParameter("lastFmSessionKey",""); 439 lastFmUserRecent = parser.getStringParameter("lastFmUserRecent",""); // Ajax Request 440 441 lastFmPlayTrackNum = parser.getIntParameter("lastFmPlayTrackNum",0); 442 lastFmPlayTrack = parser.getStringParameter("lastFmPlayTrack","").replace("_"," ").trim(); // Ajax Request 443 lastFmPlayAlbum = parser.getStringParameter("lastFmPlayAlbum","").replace("_"," ").trim(); 444 lastFmPlayArtist = parser.getStringParameter("lastFmPlayArtist","").replace("_"," ").trim(); 445 lastFmPlayAlbumArtist = parser.getStringParameter("lastFmPlayAlbumArtist","").replace("_"," ").trim(); 446 lastFmPlayTime = parser.getIntParameter("lastFmPlayTime",0); 447 lastFmPlayDuration = parser.getIntParameter("lastFmPlayDuration",0); 448 449 lastFmScrobbleTrack = parser.getStringParameter("lastFmScrobbleTrack","").replace("_"," ").trim(); // Ajax Request 450 lastFmScrobbleAlbum = parser.getStringParameter("lastFmScrobbleAlbum","").replace("_"," ").trim(); 451 lastFmScrobbleArtist = parser.getStringParameter("lastFmScrobbleArtist","").replace("_"," ").trim(); 452 lastFmScrobbleAlbumArtist = parser.getStringParameter("lastFmScrobbleAlbumArtist","").replace("_"," ").trim(); 453 lastFmLoveTrack = parser.getStringParameter("lastFmLoveTrack","").replace("_"," ").trim(); // Ajax Request 454 lastFmListLovedTracks = parser.getStringParameter("lastFmListLovedTracks","").replace("_"," ").trim(); // Ajax Request 455 xmlResponse = parser.getBooleanParameter("xmlResponse",xmlResponse_); 456 457 if(debugOut_) { System.out.println(" PlayTrack="+lastFmPlayTrack+" lastFmPlayArtist="+lastFmPlayArtist +" lastFmPlayAlbumArtist="+lastFmPlayAlbumArtist );} 458 if(debugOut_) { System.out.println(" ScrobbleTrack="+lastFmScrobbleTrack+" lastFmScrobbleAlbum="+lastFmScrobbleAlbum+ 459 " lastFmScrobbleAlbumArtist="+lastFmScrobbleAlbumArtist+" lastFmScrobbleArtist="+lastFmScrobbleArtist );} 460 461 } 462 463 464 /** Convert a well-formed (but not necessarily valid) XML string into a JSON String. **/ 465 private String xmlToJson(String xml) 466 { 467 String jsonStr = ""; 468 org.json.JSONObject jsonObj = null; 469 if (xml== null || xml.length()<2) xml = ""; 470 try 471 { 472 jsonObj = org.json.XML.toJSONObject(xml.replaceAll(";", ";").replaceAll("&", "&").replaceAll("%", "%")); 473 } 474 catch (org.json.JSONException jsonEx) 475 { 476 System.out.println("!!!JSON xml Parse ERROR: " + jsonEx.getMessage()); 477 System.out.println(xml); 478 System.out.println("\n!!! JSON xml Parse ERROR: " + jsonEx.getMessage()); 479 jsonStr = ""; 480 } 481 if(jsonObj!= null) jsonStr = jsonObj.toString(2); 482 return jsonStr; 483 } 484 485 486 /** 487 * This method handles the "GET" submission - it is used for Ajax calls to set webApp parameters using JQuery. 488 * 489 * @param req Description of the Parameter 490 * @param res Description of the Parameter 491 * @exception ServletException Description of the Exception 492 * @exception IOException Description of the Exception 493 */ 494 public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException 495 { 496 parseParams(req); 497 498 ServletOutputStream out = res.getOutputStream(); 499 String conPath = req.getContextPath(); 500 String restPath = req.getPathInfo(); // basically anything added to the end of the URL is considered a RESt request 501 502 if(debugOut_) 503 { 504 System.out.println("\n~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 505 System.out.println("Tunes TunesAjaxRestListener.doGet "+ " debugOut="+debugOut_); 506 System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~"); 507 } 508 509 boolean ajaxCall = false; 510 boolean restRequest = false; 511 String ajaxResponse = ""; 512 String restResponse = null; 513 514 res.setStatus(HttpServletResponse.SC_OK); // default ids OK,, set again lower downif NOT 515 516 ajaxResponse = checkForAjaxRequest(req); 517 if (!ajaxResponse.equals("")) ajaxCall=true; 518 519 if(!ajaxCall) restResponse = checkForRestRequest(req); 520 if (restResponse!=null && !restResponse.equals("")) restRequest=true; 521 522 if(debugOut_) { System.out.println("ajaxCall="+ajaxCall+" restRequest="+restRequest );} 523 /* * * * * * * * * * * EMPTY * * * * * * * * * * */ 524 /* *********************************************** */ 525 if( !ajaxCall && !restRequest) // EMPTY query and NO parms... it was *NOT* a JQuery Ajax call or a REST call, so just present some status back to user 526 { 527 sendServletAdminPage(req, res); 528 } 529 530 if(ajaxCall) 531 { 532 res.setContentType("text/plain"); 533 // https://stackoverflow.com/questions/5750696/how-to-get-a-cross-origin-resource-sharing-cors-post-request-working 534 res.setHeader("Access-Control-Allow-Origin", "*"); 535 if(out!=null ) 536 { 537 if (debugOut_) 538 System.out.println("AJAX REPLY("+ajaxResponse.length()+")="+ajaxResponse); 539 out.print(ajaxResponse); 540 } 541 else 542 System.out.println("HttpServletResponse.ServletOutputStream is NOT ready"); 543 } 544 else if(restRequest) 545 { 546 if (xmlResponse_) res.setContentType("text/xml"); 547 else res.setContentType("application/json"); 548 if(restResponse!=null && !restResponse.equals("")) 549 { 550 res.setStatus(HttpServletResponse.SC_OK); 551 } 552 else 553 { 554 res.setStatus(HttpServletResponse.SC_NOT_FOUND); 555 restResponse = "<RestResponse succeeded=\"false\"><status>404</status></RestResponse>"; 556 } 557 if(out!=null ) 558 { 559 if (debugOut_) 560 System.out.println("XML REPLY("+restResponse.length()+")="+restResponse); 561 if (!xmlResponse_) restResponse = xmlToJson(restResponse); 562 if (debugOut_) 563 System.out.println("REST REPLY("+restResponse.length()+")="+restResponse); 564 out.print(restResponse); 565 } 566 else 567 System.out.println("HttpServletResponse.ServletOutputStream is NOT ready"); 568 } 569 out.flush(); 570 res.flushBuffer(); 571 } 572 573 574 /** 575 * This method handles the "POST" submissions. 576 * 577 * @param req Description of Parameter 578 * @param res Description of Parameter 579 * @exception ServletException Description of Exception 580 * @exception IOException Description of Exception 581 */ 582 public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException 583 { 584 //parseParams(req); 585 586 StringBuffer postBody = new StringBuffer(""); 587 String line = null; 588 // try 589 // { 590 BufferedReader reader = req.getReader(); 591 while ((line = reader.readLine()) != null) 592 postBody.append(line+"\n"); 593 594 String postReply = ""; 595 596 // Do something with the posted message 597 // send it to a helper class if desired 598 /*String postReply = pEye_.newMessage(postBody.toString()); */ 599 600 // send back an empty reply 601 if ((postReply==null || postReply.equals(""))) 602 { 603 // send back a 200 with an empty body 604 res.setStatus(HttpServletResponse.SC_OK); 605 res.setContentLength(0); 606 postReply = ""; 607 if (debugOut_) System.out.println("TunesAjaxRestListener.doPost: emptyreply from newMessage"); 608 } 609 /* 610 else if(!sendFastPoll_) 611 { 612 // send back the pEyeReply as the body 613 res.setStatus(HttpServletResponse.SC_OK); 614 res.setContentLength(pEyeReply.length()); 615 if (debugOut_) System.out.println("TunesAjaxRestListener.doPost: SLOW Poll & newMessage reply existed"); 616 } 617 else // if(sendFastPoll_) 618 { 619 MessageCommand mc = new MessageCommand(pEye_.getMeterMacId()); 620 pEyeReply = mc.getSetFastPollCommandStr(fastPollFreq_,fastPollDur_); 621 622 res.setContentLength(0); // send back the setFastPollCommand string as the body 623 //if (debugOut_) System.out.println(" *!*!*!*! TunesAjaxRestListener.doPost: Send FAST Poll to:"+pEye_.getMeterMacId() ); 624 625 // now reset fastPoll for next message 626 sendFastPoll_ = false; 627 } 628 */ 629 630 postReply = "\n"+postReply; 631 res.setContentType("application/xml"); 632 res.setStatus(HttpServletResponse.SC_OK); 633 res.setContentLength(postReply.length()); 634 635 ServletOutputStream out = res.getOutputStream(); 636 if(out!=null ) 637 { 638 if (debugOut_) System.out.println("Attempting to HttpServletResponse REPLY("+postReply.length()+")="+postReply); 639 out.print(postReply); 640 out.flush(); 641 } 642 else 643 System.out.println("HttpServletResponse.ServletOutputStream is NOT ready"); 644 645 res.flushBuffer(); 646 647 /* 648 } 649 catch (Exception e) 650 { 651 //report an error 652 e.printStackTrace(); 653 } 654 */ 655 } 656 657 658 /** Parses the REST command string and prepares the response in XML format. 659 * @param restPath is the rest command part of the rest URL 660 * @return a string holding the XML rest response OR null if not a REST Request 661 **/ 662 private String checkForRestRequest(HttpServletRequest req) throws ServletException, IOException 663 { 664 String restResponse = null; 665 String servletPath = req.getServletPath(); 666 String restPath = req.getPathInfo(); // basically anything added to the end of the URL is considered a RESt request 667 String pre = "/"; 668 boolean returnXml = xmlResponse_; // false means JSON 669 670 if (servletPath.equals("/rest") && restPath!=null && !restPath.equals("") ) 671 { 672 673 DecimalFormat dfp = new DecimalFormat( "##0" ); 674 DecimalFormat dfe = new DecimalFormat( "###0.000" ); 675 if(restPath.equals(pre+"test")) 676 { 677 StringBuilder sb = new StringBuilder("<RestResponse succeeded=\"true\">"); 678 /* Add In the response content */ 679 sb.append("<testNode className=\""); 680 sb.append(className_); 681 sb.append("\">"); 682 sb.append("Hello"); 683 sb.append("</testNode>"); 684 sb.append("</RestResponse>"); 685 restResponse = sb.toString(); 686 } 687 // 688 // REST Commands 689 // ------------------------ 690 // REST Request - lastFmListLovedTracks 691 else if(restPath.equals(pre+"lastFmListLovedTracks")) 692 { 693 StringBuilder sb = new StringBuilder("<RestResponse succeeded=\"true\">"); 694 /* Add In the response content */ 695 sb.append(" <lastFmLovedTrack index=\""); 696 sb.append("1"); 697 sb.append("\">"); 698 sb.append(" NOT Implemented YET"); 699 sb.append(" </lastFmLovedTrack>"); 700 sb.append("</RestResponse>"); 701 restResponse = sb.toString(); 702 } 703 // ------------------------ 704 // REST Request - playOnPi 705 else if(restPath.startsWith(pre+"playOnPi") && restPath.length() > (pre+"playOnPi").length() ) 706 { 707 System.out.println("TunesAjaxRestListener runOnPi2 - restPath="+restPath); 708 String pi2Cmd = "/bin/runOnPi2"; 709 int tuneFileIndex = -1; 710 String currentTuneFile = ""; 711 String pi2TunePath = ""; 712 java.util.Vector<String> cmdResults = new java.util.Vector<String>(); 713 714 /* check for a 2nd '/' to index where the tuneFileIndex starts */ 715 if(restPath.substring((pre+"playOnPi/").length()).indexOf("/") > -1) 716 { 717 tuneFileIndex = restPath.substring((pre+"playOnPi/").length()).indexOf("/") + (pre+"playOnPi/").length(); 718 System.out.println("TunesAjaxRestListener runOnPi2 - tuneFileIndex="+tuneFileIndex); 719 720 currentTuneFile = restPath.substring(tuneFileIndex+1); 721 System.out.println("TunesAjaxRestListener runOnPi2 - currentTuneFile="+currentTuneFile); 722 723 pi2TunePath = currentTuneFile.replace("tunes/",""); // "/mnt/nas/snd/ogg/"); // let piListener handle the re-mangling of the final pathon the pi 724 String [] cmdParms2 = {"/usr/bin/ogg123","-q", pi2TunePath ,"&"}; 725 System.out.println("\nTune Path="+pi2TunePath); 726 727 /* send msg to TCPsocket */ 728 if(piSocketAccess_) 729 { 730 pi2Cmd = restPath.substring((pre+"playOnPi/").length(), tuneFileIndex); 731 System.out.println("TunesAjaxRestListener runOnPi2Socket - pi2Cmd="+pi2Cmd); 732 if(!pi2Cmd.equalsIgnoreCase("artistList") &&!pi2Cmd.equalsIgnoreCase("artistAlbumsList")) 733 { 734 cmdResults = sendPiSocketMessage(pi2Cmd, pi2TunePath); 735 } 736 else // process on server 737 { 738 //TBD... list the Artists dirs and/or the recursed Artist/Album dirs 739 if(tunesHelper == null) tunesHelper = new TunesHelper(); 740 tunesHelper.parseTunesDir(); 741 Vector <ca.bc.webarts.widgets.tunes.Artist> artists = tunesHelper.getArtists(); 742 String currResult = ""; 743 System.out.println("\n Tunes Dirpath="+ tunesHelper.getTunesDirPath()+"\n Num Artists="+artists.size()); 744 745 for (ca.bc.webarts.widgets.tunes.Artist currArtist: artists) 746 { 747 748 currResult = "\n <artist name=\""+currArtist.artistName()+"\" artistDirName=\""+currArtist.name(true)+"\" numAlbums="+currArtist.getNumberOfAlbums()+">"; 749 for (ca.bc.webarts.widgets.tunes.Album currAlbum: currArtist.getAlbums()) 750 { 751 currResult += "\n <album name=\""+currAlbum.albumTitle()+"\" albumDirName=\""+currAlbum.name(true)+"\">"+"</album>"; //.replaceAll("<", "<").replaceAll(">", ">") 752 } 753 currResult += " </artist>\n"; 754 cmdResults.add(currResult); 755 } 756 } 757 758 } 759 else // deprecated 760 { 761 // Execute the ssh to pi2 762 // a bash script is available called 'runOnPi2' that does this... /bin/su -s /bin/sh tgutwin -c "uname -a" 763 //String [] cmdParms = {"uname","-a"}; 764 String [] cmdParms = {"/home/pi/.local/bin/killer","ogg123"}; 765 //cmdResults = Util.executeNativeApp(pi2Cmd, cmdParms, false); 766 Util.executeNativeApp(pi2Cmd, cmdParms, false); 767 System.out.println("\n ***** Now Play a new Tune ***"); 768 769 //cmdResults = Util.executeNativeApp(pi2Cmd, cmdParms2, false); 770 Util.executeNativeApp(pi2Cmd, cmdParms2, false); 771 772 } 773 774 StringBuilder sb = new StringBuilder("<RestResponse succeeded=\"true\""); 775 /* Add In the response content */ 776 sb.append(" request=\"playOnPi\""); 777 sb.append(" pi2Cmd=\""); 778 sb.append(pi2Cmd); 779 sb.append("\""); 780 sb.append(" cmdParm=\""); 781 sb.append(pi2TunePath); 782 sb.append("\""); 783 sb.append(" piSocketAccess=\""); 784 sb.append(piSocketAccess_); 785 sb.append("\""); 786 if(!piSocketAccess_) 787 { 788 sb.append(" cmdParms2=\""); 789 sb.append(java.util.Arrays.toString(cmdParms2)); 790 sb.append("\""); 791 } 792 sb.append(">"); 793 sb.append(" <cmdResults numResults=\""+cmdResults.size()+"\">"); 794 for( String s: cmdResults) sb.append("\n <cmdResult>"+s+"</cmdResult>"); 795 sb.append(" </cmdResults>"); 796 sb.append("</RestResponse>"); 797 xmlResponse_=false; 798 restResponse = sb.toString(); // this gets convertedto JSON before sending back 799 } 800 else if(PirateTunesClientThread.getCommandWithNoOptionsList().contains( restPath.substring((pre+"playOnPi/").length()) )) 801 { 802 pi2TunePath = ""; 803 StringBuilder sb = new StringBuilder("<RestResponse succeeded="); //\"false\""); 804 String suc = "\"true\""; 805 suc = "\"true\""; 806 pi2Cmd = restPath.substring((pre+"playOnPi/").length()); 807 System.out.println("TunesAjaxRestListener runOnPi2 - pi2Cmd="+pi2Cmd); 808 cmdResults = sendPiSocketMessage(pi2Cmd); 809 /* Add In the response content */ 810 sb.append(suc); 811 sb.append(" request=\"playOnPi\""); 812 sb.append(" pi2Cmd=\""); 813 sb.append(pi2Cmd); 814 sb.append("\""); 815 sb.append(" filename=\""); 816 sb.append(pi2TunePath); 817 sb.append("\""); 818 sb.append(" piSocketAccess=\""); 819 sb.append(piSocketAccess_); 820 sb.append("\""); 821 sb.append(">"); 822 sb.append(" <cmdResults numResults=\""+cmdResults.size()+"\">"); 823 for( String s: cmdResults) sb.append("<cmdResult>"+s+" </cmdResult>"); 824 sb.append(" </cmdResults>"); 825 sb.append("</RestResponse>"); 826 xmlResponse_=false; 827 restResponse = sb.toString(); // this gets convertedto JSON before sending back 828 } 829 else 830 { 831 StringBuilder sb = new StringBuilder("<RestResponse succeeded="); //\"false\""); 832 String suc = "\"false\""; 833 /* Add In the response content */ 834 sb.append(suc); 835 sb.append(" request=\"playOnPi\""); 836 sb.append(" pi2Cmd=\""); 837 sb.append(pi2Cmd); 838 sb.append("\""); 839 sb.append(" cmdParm=\""); 840 sb.append(pi2TunePath); 841 sb.append("\""); 842 sb.append(" piSocketAccess=\""); 843 sb.append(piSocketAccess_); 844 sb.append("\""); 845 sb.append(">"); 846 sb.append(" <cmdResults numResults=\""+cmdResults.size()+"\">"); 847 for( String s: cmdResults) sb.append("<cmdResult>"+s+"</cmdResult>"); 848 sb.append(" </cmdResults>"); 849 sb.append("</RestResponse>"); 850 xmlResponse_=false; 851 restResponse = sb.toString(); // this gets convertedto JSON before sending back 852 853 } 854 } 855 } 856 857 return restResponse; 858 } 859 860 861 /** Checks if this Request is an AJAX request and prepares the response in XML format. 862 * @param req the servlet request 863 * @return a string holding the response value to be returned OR null if not an expected/Valid AJAX Request 864 **/ 865 private String checkForAjaxRequest(HttpServletRequest req) throws ServletException, IOException 866 { 867 String ajaxResponse = ""; 868 // was it a JQuery Ajax call for info... (such as eagleDBDir_) 869 if (debugOut!=null &&!debugOut.equals("") ) 870 { 871 debugOut_ = Boolean.parseBoolean(debugOut); 872 setDebugOut(debugOut_); 873 //pEye_.setDebugOut(debugOut_); 874 System.out.println("TunesAjaxRestListener.checkForAjaxRequest - debugOut_="+debugOut_); 875 ajaxResponse = ""+debugOut_; 876 } 877 else if (viewPortWidth!=0 ) 878 { 879 // do something with the passed parms 880 viewPortWidth_=viewPortWidth; 881 req.getSession().setAttribute(CLIENT_SETTING_NAME_VIEWPORTWIDTH, viewPortWidth); 882 ajaxResponse = ""+viewPortWidth_; 883 } 884 else if (viewPortHeight!=0 ) 885 { 886 // do something with the passed parms 887 viewPortHeight_=viewPortHeight; 888 req.getSession().setAttribute(CLIENT_SETTING_NAME_VIEWPORTHEIGHT, viewPortHeight); 889 ajaxResponse = ""+viewPortHeight_; 890 } 891 else if (browserName!=null &&!browserName.equals("") ) 892 { 893 req.getSession().setAttribute(CLIENT_SETTING_NAME_BROWSER_NAME, browserName); 894 ajaxResponse = ""+browserName; 895 } 896 else if (browserVersion!=null &&!browserVersion.equals("") ) 897 { 898 req.getSession().setAttribute(CLIENT_SETTING_NAME_BROWSER_VERSION, browserVersion); 899 ajaxResponse = ""+browserVersion; 900 } 901 // 902 // AJAX Calls 903 // Ajax Call - lastFmPlayTrack 904 else if (lastFmPlayTrack!=null && !lastFmPlayTrack.equals("") ) 905 { 906 boolean useFullData = true; 907 System.out.println("Ajax Call - lastFmPlayTrack="+lastFmPlayTrack.trim()); 908 HttpSession session = req.getSession(true); 909 System.out.println(" ajaxParam Found: lastFmPlayTrack="+lastFmPlayTrack +" lastFmPlayArtist="+lastFmPlayArtist.trim()+" lastFmPlayAlbumArtist="+lastFmPlayAlbumArtist.trim()); 910 System.out.println(" TunesAjaxRestListener JSessionID: "+session.getId() ); 911 912 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_PLAY_TRACK, lastFmPlayTrack); 913 if (lastFmPlayArtist!=null && !lastFmPlayArtist.equals("") ) 914 { 915 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_PLAY_ARTIST, lastFmPlayArtist.trim()); 916 } else useFullData = false; 917 if (lastFmPlayAlbumArtist!=null && !lastFmPlayAlbumArtist.equals("") ) 918 { 919 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_PLAY_ALBUM_ARTIST, lastFmPlayAlbumArtist.trim()); 920 } else useFullData = false; 921 if (lastFmPlayAlbum!=null && !lastFmPlayAlbum.equals("") ) 922 { 923 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_PLAY_ALBUM, lastFmPlayAlbum.trim()); 924 } else useFullData = false; 925 // Threaded call to send a play notification to last.fm 926 loginLastFM(); 927 //HttpSession session = request.getSession(); 928 session.setAttribute("TunesAjaxRestListener.tunesHelper", tunesHelper); 929 930 if ( lastFMInit_) 931 { 932 if(useFullData) 933 { 934 tunesHelper.nowPlaying(lastFmPlayArtist.trim(), lastFmPlayTrack.trim(), 935 lastFmPlayTime, lastFmPlayDuration, 936 lastFmPlayAlbum.trim(), lastFmPlayAlbumArtist.trim(), 937 lastFmPlayTrackNum); 938 } 939 else 940 { 941 tunesHelper.nowPlaying(lastFmPlayArtist.trim(), lastFmPlayTrack.trim()); 942 } 943 ajaxResponse = ""+lastFmPlayAlbumArtist.trim()+"/"+lastFmPlayTrack.trim(); 944 } 945 else 946 { 947 ajaxResponse = "null/null"; 948 } 949 } 950 // Ajax Call - lastFmLogin 951 else if (!lastFmLogin.equals("")) 952 { 953 System.out.println("\n\n !*!*!*!*!*!*!*!*!*\nAjax Call - lastFmLogin="+lastFmLogin+"\n !*!*!*!*!*!*!*!*!*"); 954 HttpSession session = req.getSession(true); 955 System.out.println(" TunesAjaxRestListener SessionID: "+session.getId() ); 956 if (lastFmScrobbleAlbum !=null &&!lastFmScrobbleAlbum.equals("") ) 957 { 958 System.out.println(" ajaxParam Found: lastFmUserID="+lastFmUserID_.trim() +" lastFmPassword_="+lastFmPassword_.trim()); 959 req.getSession().setAttribute(CLIENT_SETTING_NAME_LASTFM_USERID, lastFmUserID_.trim()); 960 } 961 // Threaded call to send a scrobble notification to last.fm 962 loginLastFM(); 963 if ( lastFMInit_ ) 964 { 965 ajaxResponse = "SuccessfullLogin/"+lastFmUserID_.trim()+"/"+lastFmPassword_.trim(); 966 } 967 else 968 { 969 ajaxResponse = "null/null"; 970 } 971 //HttpSession session = request.getSession(); 972 session.setAttribute("TunesAjaxRestListener.tunesHelper", tunesHelper); 973 } 974 // Ajax Call - lastFmScrobbleTrack 975 else if (lastFmScrobbleTrack!=null &&!lastFmScrobbleTrack.equals("") && (lastFmLoveTrack==null || lastFmLoveTrack.equals(""))) 976 { 977 System.out.println("Ajax Call - lastFmScrobbleTrack="+lastFmScrobbleTrack.trim()); 978 HttpSession session = req.getSession(true); 979 System.out.println(" ajaxParam Found: lastFmScrobbleTrack="+lastFmScrobbleTrack.trim() +" lastFmScrobbleArtist="+lastFmScrobbleArtist.trim()); 980 System.out.println(" TunesAjaxRestListener SessionID: "+session.getId() ); 981 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_SCROBBLE_TRACK, lastFmScrobbleTrack); 982 if (lastFmScrobbleAlbum !=null && !lastFmScrobbleAlbum.equals("") ) 983 { 984 System.out.println(" ajaxParam Found: lastFmScrobbleAlbum="+lastFmScrobbleAlbum ); 985 req.getSession().setAttribute(CLIENT_SETTING_NAME_LASTFM_SCROBBLE_ALBUM, lastFmScrobbleAlbum.trim()); 986 } 987 if (lastFmScrobbleAlbumArtist !=null && !lastFmScrobbleAlbumArtist.equals("") ) 988 { 989 System.out.println(" ajaxParam Found: lastFmScrobbleAlbumArtist="+lastFmScrobbleAlbumArtist ); 990 req.getSession().setAttribute(CLIENT_SETTING_NAME_LASTFM_SCROBBLE_ALBUM_ARTIST, lastFmScrobbleAlbumArtist.trim()); 991 } 992 if (lastFmScrobbleArtist!=null && !lastFmScrobbleArtist.equals("") ) 993 { 994 req.getSession().setAttribute(CLIENT_SETTING_NAME_LASTFM_SCROBBLE_ARTIST, lastFmScrobbleArtist.trim()); 995 } 996 // Threaded call to send a scrobble notification to last.fm 997 loginLastFM(); 998 //HttpSession session = request.getSession(); 999 session.setAttribute("TunesAjaxRestListener.tunesHelper", tunesHelper); 1000 1001 if ( lastFMInit_ && !lastFmScrobbleTrack.trim().equals(lastFmPreviousScrobbleTrack)) 1002 { 1003 lastFmPreviousScrobbleTrack = lastFmScrobbleTrack.trim(); 1004 tunesHelper.scrobble(lastFmScrobbleArtist.trim(), lastFmScrobbleAlbumArtist.trim(), lastFmScrobbleAlbum.trim(), lastFmScrobbleTrack.trim()); 1005 ajaxResponse = ""+lastFmScrobbleArtist.trim()+"/"+lastFmScrobbleAlbumArtist.trim()+"/"+lastFmScrobbleAlbum.trim()+"/"+lastFmScrobbleTrack.trim(); 1006 } 1007 else 1008 { 1009 ajaxResponse = "null/null"; 1010 } 1011 } 1012 // Ajax Call - lastFmLoveTrack 1013 else if (lastFmLoveTrack!=null && !lastFmLoveTrack.equals("") && lastFmScrobbleTrack!=null && !lastFmScrobbleTrack.equals("") ) 1014 { 1015 System.out.println("Ajax Call - lastFmLoveTrack="+lastFmLoveTrack.trim()); 1016 HttpSession session = req.getSession(true); 1017 if (lastFmScrobbleArtist!=null &&!lastFmScrobbleArtist.equals("") ) 1018 { 1019 req.getSession().setAttribute(CLIENT_SETTING_NAME_LASTFM_SCROBBLE_ARTIST, lastFmScrobbleArtist.trim()); 1020 } 1021 System.out.println(" ajaxParam Found: lastFmLoveTrack="+lastFmLoveTrack.trim()+ 1022 "lastFmScrobbleTrack="+lastFmScrobbleTrack.trim() + 1023 " lastFmScrobbleArtist="+lastFmScrobbleArtist.trim()); 1024 System.out.println(" TunesAjaxRestListener SessionID: "+session.getId() ); 1025 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_LOVE_TRACK, lastFmLoveTrack.trim()); 1026 // Threaded call to send a love notification to last.fm 1027 loginLastFM(); 1028 //HttpSession session = request.getSession(); 1029 session.setAttribute("TunesAjaxRestListener.tunesHelper", tunesHelper); 1030 1031 if ( lastFMInit_) 1032 { 1033 //http://10.0.0.253/tunes/ajax/?lastFmLoveTrack=1&lastFmScrobbleTrack=18TillIDie&lastFmScrobbleArtist=BryanAdams 1034 ajaxResponse = tunesHelper.loveTrack(lastFmScrobbleArtist.trim(), lastFmScrobbleTrack.trim()); 1035 //ajaxResponse = ""+lastFmScrobbleArtist+"/"+lastFmScrobbleTrack; 1036 } 1037 else 1038 { 1039 ajaxResponse = "null/null"; 1040 } 1041 } 1042 // Ajax Call - lastFmListLovedTracks 1043 else if (lastFmListLovedTracks!=null && !lastFmListLovedTracks.equals("") ) 1044 { 1045 System.out.println("Ajax Call - lastFmListLovedTracks="+lastFmListLovedTracks.trim()); 1046 HttpSession session = req.getSession(true); 1047 System.out.println(" TunesAjaxRestListener SessionID: "+session.getId() ); 1048 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_LIST_LOVE_TRACK, lastFmListLovedTracks.trim()); 1049 // Threaded call to send a love notification to last.fm 1050 loginLastFM(); 1051 //HttpSession session = request.getSession(); 1052 session.setAttribute("TunesAjaxRestListener.tunesHelper", tunesHelper); 1053 1054 if ( lastFMInit_) 1055 { 1056 Vector<String> lTks = tunesHelper.retrieveLastFmLovedTrackNames(); 1057 ajaxResponse = "["; 1058 int counter = 0; int tot = lTks.size(); 1059 for (String currT : lTks) 1060 { 1061 ajaxResponse += "\""+currT+"\""; 1062 if (counter++<(tot-1)) ajaxResponse += "," ; 1063 } 1064 ajaxResponse += "]"; 1065 1066 //String [] ltArray = new String[lTks.size()]; 1067 //ltArray = (String []) lTks.toArray(ltArray); 1068 //ajaxResponse = java.util.Arrays.toString(ltArray); 1069 } 1070 else 1071 { 1072 ajaxResponse = "null/null"; 1073 } 1074 } 1075 // Ajax Call - lastFmUserRecent 1076 else if (lastFmUserRecent!=null && !lastFmUserRecent.equals("") ) 1077 { 1078 int numberRecentsReturned = 15; 1079 ajaxResponse = "null/null"; 1080 boolean returnHtml = true; 1081 if (dataType!=null && dataType.equalsIgnoreCase("json") ) returnHtml = false; 1082 if (dataType!=null && dataType.equalsIgnoreCase("html") ) returnHtml = true; 1083 String htmlResponse = ""; 1084 String jsonResponse = "{"; 1085 System.out.println("Ajax Call - lastFmUserRecent="+lastFmUserRecent.trim()); 1086 HttpSession session = req.getSession(true); 1087 System.out.println(" TunesAjaxRestListener SessionID: "+session.getId() ); 1088 session.setAttribute(CLIENT_SETTING_NAME_LASTFM_USER_RECENT, lastFmUserRecent.trim()); 1089 // Threaded call to send a play notification to last.fm 1090 loginLastFM(); 1091 //HttpSession session = request.getSession(); 1092 session.setAttribute("TunesAjaxRestListener.tunesHelper", tunesHelper); 1093 1094 if ( lastFMInit_) 1095 { 1096 //http://10.0.0.253/tunes/ajax/?lastFmLoveTrack=1&lastFmScrobbleTrack=18TillIDie&lastFmScrobbleArtist=BryanAdams 1097 de.umass.lastfm.Track [] recentTracks = tunesHelper.retrieveLastFmRecentSongs(lastFmUserRecent.trim()); 1098 java.util.Vector<String> lovedTrackNames = tunesHelper.getLastFmLovedTrackNames(); 1099 1100 // return html 1101 if(recentTracks!=null) 1102 { 1103 int [] trackPlayCount = new int[recentTracks.length]; 1104 1105 Date pt = null; 1106 Calendar pc = null; 1107 //java.util.Date nowTime = new java.util.Date(); 1108 //String currTime = DateFormat.getDateInstance().format(nowTime); 1109 DateFormat dParser = new SimpleDateFormat("EEE MMM d HH:mm:ss z YYYY"); //Sat May 19 22:03:59 PDT 2018 1110 DateTimeFormatter dtParser = DateTimeFormatter.ofPattern("EEE MMM d HH:mm:ss zzz YYYY");//Sat May 19 22:03:59 PDT 2018 1111 //Date convertedDate = null; 1112 //String output = ""; 1113 ZonedDateTime zNow = ZonedDateTime.now(); 1114 LocalDateTime lNow = LocalDateTime.now(); 1115 LocalDateTime playedLDate = null;; 1116 ZonedDateTime playedZDate = null; 1117 Duration timeSincePlayed = null; 1118 String timeSincePlayedSTR = ""; 1119 boolean shade = true; 1120 1121 //ajaxResponse = ""+recentTracks.length+" recent tracks"; 1122 htmlResponse += "<img src=\"images/lastfm_SquareLogo.png\" height=\"32\" width=\"32\" style=\"margin-top: 2px; margin-bottom: 2px; margin-left: 9px; margin-right: 20px; float: left;\">"+ 1123 " Recent Tracks: " + 1124 tunesHelper.retrieveLastFmSessionUsername() + " <img src=\""+tunesHelper.retrieveLastFmUserImageURL()+"\" height=\"32\" width=\"32\">" ; 1125 jsonResponse += " \"LastFmUsername\": \""+tunesHelper.retrieveLastFmSessionUsername()+"\",\n"; 1126 jsonResponse += " \"LastFmUserImageURL\": \""+tunesHelper.retrieveLastFmUserImageURL()+"\",\n"; 1127 jsonResponse += " \"numberRecentsReturned\": "+numberRecentsReturned+",\n"; 1128 jsonResponse += " \"recentTracks\": [\n"; 1129 htmlResponse += "<div id=\"recentTracksTableDiv\"><table class=\"w3-left-align\">"; 1130 for (int i=0; i<numberRecentsReturned ; i++) 1131 { 1132 trackPlayCount[i] = tunesHelper.retrieveLastfmTrackPlayCount(recentTracks[i]); 1133 jsonResponse += " {"+"\n"; 1134 if(!recentTracks[i].isNowPlaying() || i==0) 1135 { 1136 jsonResponse += " \"recentNum\": "+(i+1)+",\n"; 1137 jsonResponse += " \"isNowPlaying\": "+recentTracks[i].isNowPlaying()+",\n"; 1138 jsonResponse += " \"PlayCount\": "+trackPlayCount[i]+",\n"; 1139 pt = recentTracks[i].getPlayedWhen(); //Sat May 19 22:03:59 PDT 2018 1140 //System.out.println( recentTracks[i].getName()+" last played: " + pt); 1141 pc = toCalendar(pt); 1142 //System.out.println( recentTracks[i].getName()+" last calendar: " + pc); 1143 //convertedDate = dParser.parse(playTime); 1144 //timeOutput = formatter.format(convertedDate); 1145 //of(int year, int month, int dayOfMonth, int hour, int minute, int second) 1146 playedLDate = 1147 LocalDateTime.of(pc.get(Calendar.YEAR) , 1148 pc.get(Calendar.MONTH)+1 , 1149 pc.get(Calendar.DAY_OF_MONTH) , 1150 pc.get(Calendar.HOUR_OF_DAY) , 1151 pc.get(Calendar.MINUTE) , 1152 pc.get(Calendar.SECOND)); 1153 1154 //playedLDate = LocalDateTime.parse(playTimeStr, dtParser); 1155 playedZDate = ZonedDateTime.of(playedLDate, zNow.getZone()); 1156 //System.out.println( recentTracks[i].getName()+" last playedZDate: " + playedZDate); 1157 timeSincePlayed = Duration.between(playedZDate, zNow); 1158 //System.out.println( recentTracks[i].getName()+" Minutes since played: " + timeSincePlayed.toMinutes()); 1159 timeSincePlayedSTR = ""+timeSincePlayed.toMinutes()+" mins"; 1160 if(timeSincePlayed.toMinutes()<1) timeSincePlayedSTR = " seconds ago"; 1161 else if(timeSincePlayed.toMinutes()>=120) timeSincePlayedSTR = ""+timeSincePlayed.toHours()+" hrs"; 1162 else if(timeSincePlayed.toMinutes()>=1440) timeSincePlayedSTR = ""+timeSincePlayed.toDays()+" days"; 1163 1164 String animSpeaker = 1165 "\n <span class=\"si-icon si-icon-volume\" data-icon-name=\"volume\"><svg height=\"64\" version=\"1.1\" width=\"64\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\">\n"+ 1166 " <desc>Created with Snap</desc><defs></defs>\n"+ 1167 " <g>\n"+ 1168 " <path style=\"opacity: 1;\" fill=\"#fff\" d=\"m 37.991813,22.751636 -3.083782,3.083783 c 1.588254,1.572528 2.571897,3.753462 2.571897,6.164853 0,2.410848 -0.983643,4.592324 -2.571897,6.16431 l 3.083782,3.083782 c 2.364757,-2.368011 3.82775,-5.637242 3.82775,-9.248093 0,-3.611392 -1.462993,-6.880083 -3.82775,-9.248636 z\" transform=\"matrix(0,0,0,0,22,32)\"></path>\n"+ 1169 " <path style=\"opacity: 1;\" fill=\"#fff\" d=\"m 50.496123,32 c 0,-6.005432 -2.440672,-11.440956 -6.383379,-15.369023 L 41.05987,19.68385 c 3.149937,3.15319 5.097703,7.506925 5.097703,12.31615 0,4.808682 -1.948309,9.162417 -5.097703,12.31615 l 3.052874,3.052873 C 48.055451,43.440956 50.496123,38.005431 50.496123,32 z\" transform=\"matrix(0,0,0,0,22,32)\"></path>\n"+ 1170 " <path style=\"opacity: 1;\" fill=\"#fff\" d=\"m 59.173768,32.000271 c 0,-8.402181 -3.412386,-16.006711 -8.925453,-21.505137 l -3.068057,3.068056 c 4.72843,4.713247 7.654417,11.233274 7.654417,18.437081 0,7.203264 -2.925987,13.723833 -7.654417,18.436538 l 3.068057,3.068057 c 5.513067,-5.497884 8.925453,-13.102957 8.925453,-21.504595 z\" transform=\"matrix(0,0,0,0,22,32)\"></path>\n"+ 1171 " <polygon fill=\"#fff\" points=\"21.085,66 44,87.208 44,12.791 21.517,34 0,34 0,66 \" transform=\"matrix(0.57539192,0,0,0.57539192,3.3431808,3.2306919)\"></polygon>\n"+ 1172 " </g>\n"+ 1173 " </svg></span>\n"; 1174 animSpeaker = ""; 1175 1176 if(recentTracks[i].isNowPlaying()) 1177 { 1178 jsonResponse += " \"TimeSincePlayed\": \"Now Playing\",\n"; 1179 timeSincePlayedSTR = "<div>"+ 1180 "<img src=\"images/equalizerBars_anim.gif\" width=46 height=46 style=\"vertical-align:middle;margin-left: 12px;argin-bottom: 1px;margin-right: 5px;\"> " 1181 +animSpeaker+"<!--span style=\"\"><Playing now</span-->"+ 1182 "</div>"; 1183 } 1184 else 1185 jsonResponse += " \"TimeSincePlayed\": \""+timeSincePlayedSTR+"\",\n"; 1186 1187 jsonResponse += " \"LastPlayedWhen\": \""+playedZDate+"\",\n"; 1188 jsonResponse += " \"Artist\": \""+recentTracks[i].getArtist()+"\",\n"; 1189 jsonResponse += " \"Album\": \""+recentTracks[i].getAlbum()+"\",\n"; 1190 jsonResponse += " \"SongName\": \""+recentTracks[i].getName()+"\",\n"; 1191 jsonResponse += " \"SongURL\": \""+recentTracks[i].getUrl()+"\",\n"; 1192 jsonResponse += " \"Loved\": \""+lovedTrackNames.contains(recentTracks[i].getName().trim())+"\",\n"; 1193 1194 if(recentTracks[i].isNowPlaying()) 1195 htmlResponse += "<tr style=\""+"background-color: #88e;"+"\">"; 1196 else 1197 htmlResponse += "<tr style=\""+(shade?"background-color: #ccf;":"background-color: #ddf;")+"\">"; 1198 htmlResponse += "<td style=\"width: 48px;height: 48px;text-align: center;vertical-align: middle;\"><img src=\""+recentTracks[i].getImageURL(de.umass.lastfm.ImageSize.SMALL)+"\"></td>"; 1199 htmlResponse += "<td style=\"height: 48px;\"><b>"+recentTracks[i].getArtist()+"</b>, "+recentTracks[i].getAlbum()+"<br>"; 1200 htmlResponse += "<a href=\""+recentTracks[i].getUrl()+"\" target=\"_blank\">"+recentTracks[i].getName()+"</a>"; 1201 htmlResponse += "</td>"; 1202 htmlResponse += "<td id=\"trackPlayCount\" align=\"right\" style=\"padding: 15px;color: #002266;width: 140px;height: 48px;\">"+trackPlayCount[i]; 1203 htmlResponse += (trackPlayCount[i]>1?" plays</td>":" play</td>"); 1204 htmlResponse += "<td style=\""+(recentTracks[i].isNowPlaying()?"":"padding: 15px;")+"width: 160px;height: 48px;\">"+timeSincePlayedSTR+"</td>"; 1205 htmlResponse += "</tr>"; 1206 shade = !shade; 1207 jsonResponse += " \"AlbumCoverImageURL\": \""+recentTracks[i].getImageURL(de.umass.lastfm.ImageSize.SMALL)+"\"\n"; 1208 } 1209 jsonResponse += " }"; 1210 if (i<(numberRecentsReturned-1)) jsonResponse += ","; 1211 jsonResponse += "\n"; 1212 } 1213 1214 htmlResponse += "</table></div>"; 1215 jsonResponse += " ]\n"; 1216 } 1217 1218 //ajaxResponse = ""+lastFmScrobbleArtist+"/"+lastFmScrobbleTrack; 1219 } 1220 jsonResponse += "}"; 1221 ajaxResponse = (returnHtml?htmlResponse:jsonResponse); 1222 } 1223 1224 return ajaxResponse; 1225 } 1226 1227 1228 private static Calendar toCalendar(Date date) 1229 { 1230 Calendar cal = Calendar.getInstance(); 1231 if(date!=null) cal.setTime(date); 1232 return cal; 1233 } 1234 1235 1236 private java.util.Vector<String> sendPiSocketMessage(String msg) { return sendPiSocketMessage(msg,""); } 1237 private java.util.Vector<String> sendPiSocketMessage(String msg, String cmdParm) 1238 { 1239 java.util.Vector<String> retVal = new java.util.Vector<String>(); retVal.add("NOT_Sent: "+msg); 1240 TCPSocketClient socketClient = new TCPSocketClient( piTunesTCPSocketServer_, piTunesTCPSocket_); 1241 Vector<String> availCommands = ca.bc.webarts.tools.sockets.PirateTunesClientThread.getCommandList(); 1242 try 1243 { 1244 1245 /* Read From The Commandline */ 1246 BufferedReader inputLine = null; 1247 inputLine = new BufferedReader(new InputStreamReader(System.in)); 1248 String req = ""; 1249 1250 if (availCommands.contains(msg.trim())) 1251 { 1252 try 1253 { 1254 if ( //instance.isListening() && 1255 !msg.trim().equals("")) 1256 { 1257 //req = inputLine.readLine().trim(); 1258 req = (msg + " "+cmdParm).trim(); 1259 System.out.print("Request: "+req); 1260 socketClient.initSocket(); 1261 if (socketClient.isInit()) 1262 { 1263 System.out.println(" being SENT... "); 1264 socketClient.sendAndWait(req, 2500);// Sends and starts it listening here 1265 //socketClient.send(req); // same as sendAndWait(req, 0) 1266 retVal = new java.util.Vector<String>(); //"Sent: "+req; 1267 socketClient.closeSocket(); 1268 java.util.Vector<String> responseList = socketClient.getResponseList(); 1269 for (String r: responseList) 1270 { 1271 1272 if ( !( r.startsWith(TCPSocketServer.END) 1273 || r.startsWith(TCPSocketServer.ERROR) 1274 || r.startsWith(TCPSocketServer.SUCCESS) 1275 ) 1276 ) 1277 { 1278 retVal.add(r); 1279 } 1280 } 1281 } 1282 else 1283 System.err.println(" Socket NOT init"); 1284 } 1285 } 1286 catch (IOException e) 1287 { 1288 System.err.println("IOException: " + e); 1289 e.printStackTrace(); 1290 } 1291 } 1292 else 1293 { 1294 System.err.println("playOnPi Rest command ERROR: non-standard command"); 1295 retVal = new java.util.Vector<String>(); 1296 retVal.add("NOT_Sent: "+msg); 1297 retVal.add(" >non-standard command"); 1298 } 1299 } 1300 catch (Exception ioEx) 1301 { 1302 ioEx.printStackTrace(); 1303 } 1304 1305 return retVal; 1306 } 1307 1308 1309 /** 1310 * Logs into the last.fm session with the already provided user/pass. 1311 * this method uses TunesHelper to do this. 1312 * 1313 * @return success or not 1314 **/ 1315 private boolean loginLastFM() 1316 { 1317 if(tunesHelper == null) tunesHelper = new TunesHelper(); 1318 /* should probably also use the lastFM user pass sent by some AJAX call. */ 1319 System.out.println("\n TunesAjaxRestListener.loginLastFM() lastFmUserID_="+lastFmUserID_+" lastFmPassword_="+lastFmPassword_); 1320 tunesHelper.setLastFmUserID(lastFmUserID_); 1321 tunesHelper.setLastFmPassword(lastFmPassword_); 1322 1323 if (tunesHelper!=null) 1324 { 1325 if (!lastFmSessionKey.equals("") ) 1326 { 1327 if (tunesHelper.restoreLastFmUserSession(lastFmSessionKey)) 1328 { 1329 lastFMInit_ = true; 1330 } 1331 else 1332 { 1333 System.out.println("\n******** Ajax Login LastFM CANT Restre... re-Initing "); 1334 lastFMInit_ = tunesHelper.initLastFmUserSession(true, lastFmUserID_, lastFmPassword_); 1335 } 1336 } 1337 } 1338 if (!lastFMInit_)System.out.println("\n *************\n -> TunesAjaxRestListener Login ERROR - Last.fm *************\n"); 1339 return lastFMInit_; 1340 } 1341 1342 1343 /** Prepares and returns basic info page about the servlet and server. **/ 1344 private void sendServletAdminPage(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException 1345 { 1346 ServletOutputStream out = res.getOutputStream(); 1347 ServletContext context = getServletContext(); 1348 java.util.Properties sysProps = System.getProperties(); 1349 TimeZone localTz = Calendar.getInstance().getTimeZone(); 1350 int offset = localTz.getRawOffset(); 1351 // shift Daylight savings hour if needed 1352 Date dateNow = new Date(); 1353 boolean dst = localTz.inDaylightTime(dateNow); 1354 int dstOffset = localTz.getDSTSavings(); 1355 //if(dst) offset = offset + dstOffset; 1356 1357 String prop = ""; 1358 1359 // Send Back a response to be presented to the users browser 1360 res.setContentType("text/html"); 1361 out.println("<html>\n"); 1362 out.println("<head>\n"); 1363 out.println("<title>Ajax / REST Listener - Servlet Console</title>\n"); 1364 out.println("<meta charset=\"UTF-8\">"); 1365 out.println("<link rel=\"icon\""); 1366 out.println(" type=\"image/png\""); 1367 out.println(" href=\"images/2blueeighthnotes-16x16.png\" />"); 1368 out.println("<style>"); 1369 out.println("H1 { font-weight: bolder; background-color: #000033; color: #ffffbb; font-size: 200%;padding-top: 20px;padding-bottom:20px}"); 1370 out.println("H2 { font-weight: bolder; color: #ffff99; font-size: 160%; text-decoration: underline}"); 1371 out.println("H3 { font-weight: bolder; color: #ffff44; font-size: 140%}"); 1372 out.println("H4, H5 { color: #ffffff }"); 1373 out.println("A { color: #ffaadd }"); 1374 out.println("DT { font-weight: bolder }"); 1375 out.println("LI { line-height: 125% }"); 1376 out.println("BODY { background-color: #101066; color: #ffff44; font-size: 100%; line-height: 110% }"); 1377 out.println(".val { color: #ffffff; font: \"Lucida Console\", Monaco, monospace }"); 1378 out.println(""); 1379 out.println(""); 1380 out.println(""); 1381 out.println("</style>"); 1382 1383 //out.println("<META HTTP-EQUIV=\"refresh\" content=\"2;URL=\"javascript:history.go(-2);\">\n"); 1384 out.println("</head>\n"); 1385 out.println("<body>"); 1386 out.println("<h1>Web<i>ARTS</i> Ajax / REST Listener</h1><h2>Servlet Console</h2>"); 1387 out.println(" <ul>"); 1388 String info = getServletInfo(); 1389 out.println(" <li>"); 1390 out.println(ca.bc.webarts.widgets.Util.left(info, info.indexOf(".") ).trim()); 1391 out.println(" </li>"); 1392 out.println(" <li>"); 1393 out.println(info.substring(info.indexOf(".")+1 ).trim()); 1394 out.println(" </li>"); 1395 out.println(" </ul>"); 1396 out.println(" <h3>Servlet Parameters</h3>"); 1397 out.println(" <ul>"); 1398 out.println(" <li>debug = <span class=\"val\">"+debugOut_+"</span></li>"); 1399 out.println("<br />"); 1400 out.println(" <li>Servlet Init Params:"); 1401 out.println(" <ul>"); 1402 1403 java.util.Enumeration <String> initEnum = getInitParameterNames(); 1404 String currParamName = ""; 1405 for (; initEnum.hasMoreElements();) 1406 { 1407 currParamName = initEnum.nextElement(); 1408 out.print(" <li>"); 1409 out.print(currParamName+" = <span class=\"val\">"+getInitParameter(currParamName)); 1410 out.println("</span></li>"); 1411 } 1412 out.println(" </ul>"); 1413 out.println(" </li>"); // servlet init params 1414 1415 out.println("<br />"); 1416 out.println(" <li>Context Params for "+context.getServletContextName()+":"); 1417 out.println(" <ul>"); 1418 out.print(" <li>"); 1419 out.print("ContextPath"+" = <span class=\"val\">"+context.getContextPath()); 1420 out.println("</span></li>"); 1421 out.print(" <li>"); 1422 out.print("Real Path For Context Root"+" = <span class=\"val\">"+context.getRealPath("/")); 1423 out.println("</span></li>"); 1424 out.println(" </ul>"); 1425 out.println(" </li>"); // CONTEXT params 1426 1427 out.println("<br />"); 1428 out.println(" <li>Context <b>Init</b> Params:"); 1429 out.println(" <ul>"); 1430 initEnum = context.getInitParameterNames(); 1431 currParamName = ""; 1432 for (; initEnum.hasMoreElements();) 1433 { 1434 currParamName = initEnum.nextElement(); 1435 out.print(" <li>"); 1436 out.print(currParamName+" = <span class=\"val\">"+context.getInitParameter(currParamName)); 1437 out.println("</span></li>"); 1438 } 1439 out.println(" </ul>"); 1440 out.println(" </li>"); // context init params 1441 1442 out.println(" </ul>"); 1443 1444 out.println("<br /><br />"); 1445 out.println("<h3>Available Rest request commands</h3>"); 1446 out.println(" <ul>"); 1447 for (int i=0; i<restCommands_.length; i++) 1448 { 1449 out.println(" <li><span class=\"val\">"+restCommands_[i]+"</span></li>"); 1450 } 1451 out.println(" </ul>"); 1452 1453 out.println("<br /><br />"); 1454 out.println("<h3>Available AJAX commands</h3>"); 1455 out.println(" <ul>"); 1456 for (int i=0; i<ajaxCommands_.length; i++) 1457 { 1458 out.println(" <li><span class=\"val\">"+ajaxCommands_[i]+"</span></li>"); 1459 } 1460 out.println(" </ul>"); 1461 1462 out.println("<br /><br />"); 1463 out.println("<h3>Server Status</h3>"); 1464 out.println(" <ul>"); 1465 out.println(" <li>Server name = <span class=\"val\">"+req.getServerName()+" ("+req.getLocalAddr()+")</span></li>"); 1466 out.println(" <li>Server port = <span class=\"val\">"+req.getServerPort()+"</span></li>"); 1467 out.println(" <li>WebApp Engine = <span class=\"val\">"+context.getServerInfo()+"</span></li>"); 1468 out.println(" <li>Supported Servlet Version = <span class=\"val\">"+context.getMajorVersion()+"."+context.getMinorVersion()+"</span></li>"); 1469 1470 if(context.getMajorVersion()>2 && context.getMinorVersion()>-1) 1471 out.println(" <ul><li>Effective Version = <span class=\"val\">"+ 1472 context.getEffectiveMajorVersion()+"."+context.getEffectiveMinorVersion()+"</span></li></ul>"); 1473 out.println(" </li>"); 1474 if(context.getMajorVersion()>2 && context.getMinorVersion()>0) 1475 { 1476 try { 1477 out.println(" <li>Logical Hostname = <span class=\"val\">"+context.getVirtualServerName()+"</span></li>"); 1478 } catch (Exception ex) {} 1479 } 1480 1481 out.println(" <li>System Properties\n <ul>"); 1482 prop = "java.vendor"; 1483 out.println(" <li>"+prop+" = <span class=\"val\">"+sysProps.getProperty(prop)+"</span></li>"); 1484 prop = "java.runtime.version"; 1485 out.println(" <li>"+prop+" = <span class=\"val\">"+sysProps.getProperty(prop)+"</span></li>"); 1486 prop = "java.version"; 1487 out.println(" <li>"+prop+" = <span class=\"val\">"+sysProps.getProperty(prop)+"</span></li>"); 1488 prop = "os.arch"; 1489 out.println(" <li>"+prop+" = <span class=\"val\">"+sysProps.getProperty(prop)+"</span></li>"); 1490 prop = "os.name"; 1491 out.println(" <li>"+prop+" = <span class=\"val\">"+sysProps.getProperty(prop)+"</span></li>"); 1492 prop = "os.version"; 1493 out.println(" <li>"+prop+" = <span class=\"val\">"+sysProps.getProperty(prop)+"</span></li>"); 1494 1495 out.println(" </ul>\n </li>"); 1496 out.println(" </ul> <!-- Server Status -->"); 1497 1498 out.println("<br /><br />"); 1499 out.println("<h3>Client Request</h3>"); 1500 out.println(" <ul>"); 1501 out.println(" <li>Client/proxy Host = <span class=\"val\">"+req.getRemoteHost()+" ("+req.getRemoteAddr()+")</span></li>"); 1502 out.println(" <li>Client/proxy port = <span class=\"val\">"+req.getRemotePort()+"</span></li>"); 1503 out.println(" <li>Protocol = <span class=\"val\">"+req.getProtocol()+"</span></li>"); 1504 out.println(" <li>reqest.PathInfo= <span class=\"val\">"+req.getPathInfo()+"</span></li>"); 1505 out.println(" </ul>"); 1506 1507 out.println("<br /><br />"); 1508 out.println("<h3>Client Parms Status</h3>"); 1509 out.println(" <ul>"); 1510 out.println(" <li>Browser = <span class=\"val\">"+req.getSession().getAttribute(CLIENT_SETTING_NAME_BROWSER_NAME)+" v"+ 1511 req.getSession().getAttribute(CLIENT_SETTING_NAME_BROWSER_VERSION)+"</span></li>"); 1512 out.println(" <li>Device Type = <span class=\"val\">"+req.getSession().getAttribute(CLIENT_SETTING_NAME_DEVICE_TYPE)+"</span></li>"); 1513 out.println(" <li>viewport.width = <span class=\"val\">"+req.getSession().getAttribute(CLIENT_SETTING_NAME_VIEWPORTWIDTH)+"</span></li>"); 1514 out.println(" <li>viewport.height= <span class=\"val\">"+req.getSession().getAttribute(CLIENT_SETTING_NAME_VIEWPORTHEIGHT)+"</span></li>"); 1515 1516 Enumeration<String> parmNames = req.getParameterNames(); 1517 out.println(" <li><b>Request Parameters</b>\n <ul>"); 1518 for (; parmNames.hasMoreElements();) 1519 { 1520 currParamName = (String) parmNames.nextElement(); 1521 out.println(" <li>"+currParamName+"= <span class=\"val\">"+req.getParameter(currParamName)+"</span></li>"); 1522 } 1523 out.println(" </ul>\n </li>"); 1524 out.println(" </ul>"); 1525 1526 out.println("<br /><br />"); 1527 out.println("\n</body>\n</html>"); 1528 } 1529}