001/* 002 * 003 * $Revision: 1313 $ 004 * $Date: 2020-03-19 09:10:10 -0700 (Thu, 19 Mar 2020) $ 005 * $URL: svn://fred.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/widgets/tunes/Song.java $ 006 * 007 * Written by Tom Gutwin - WebARTS Design. 008 * http://www.webarts.bc.ca 009 * Copyright (C) 2016-2019 WebARTS Design, North Vancouver Canada 010 * This program is free software; you can redistribute it and/or modify 011 * it under the terms of the GNU General Public License as published by 012 * the Free Software Foundation; either version 2 of the License, or 013 * (at your option) any later version. 014 * 015 * This program is distributed in the hope that it will be useful, 016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 018 * GNU General Public License for more details. 019 * 020 * You should have received a copy of the GNU General Public License 021 * along with this program; if not, write to the Free Software 022 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 023 */ 024 025package ca.bc.webarts.widgets.tunes; 026 027import ca.bc.webarts.widgets.Util; 028import java.io.File; 029import java.util.Vector; 030 031 032import org.apache.commons.codec.DecoderException; 033import org.apache.commons.codec.binary.Hex; 034 035/** Class to hold a Song as a java object. **/ 036 public class Song implements java.lang.Comparable<Song> 037 { 038 /** A holder for this clients System File Separator. */ 039 public final static String SYSTEM_FILE_SEPERATOR = java.io.File.separator; 040 041 /** A holder for this clients System line termination separator. */ 042 public final static String SYSTEM_LINE_SEPERATOR = 043 System.getProperty("line.separator"); 044 private String name_ = ""; 045 private String artistName_ = ""; 046 private String albumArtistName_ = ""; 047 private String artistDir_ = ""; 048 private File albumDirFile_ = null; 049 private String htmlLinkStart_ = ""; 050 private String htmlLinkEnd_ = ""; 051 /** The songs track number within its {@link Album Album}. **/ 052 private int number_ = 0; 053 private int cdNumber_ = 1; 054 private File songFile_ = null; 055 private boolean lastFmLoved_ = false; 056 private static String tunesSubPath_ = TunesHelper.getTunesSubPath() ; 057 /** The optional absolute index for this Song in the users overall Library of songs. It can be used by a user 058 * to assign a unique key/index that this song has in a users entire Artist/Album library of songs. **/ 059 private int libraryIndex_=-1; 060 061 /** The 2 digit HEX char/byte Reference KEY for this Song .<br> 062 * Example: 0 a <br> 063 * Each song should have a unique key, <b>WITHIN ITS OWN ALBUM</b>, based on the parsing of the tunes root 064 * directory. It is created each time the root directory is parsed. 065 * It is based on the song/track number as it inits album 066 **/ 067 private char[] refKEY_ = {'0','0'}; 068 private char[] albumRefKEY_ = {'0','0'}; 069 private char[] artistRefKEY_ = {'0','0','0','0'}; 070 071 072 /** Minimal Constructor for Song. 073 * 074 * @param songFileDirPath the full path to the songFile. 075 * @throws Exception if the artist file dir does not exist of can't read as a dir. 076 **/ 077 public Song(String songFileDirPath) throws Exception 078 { 079 this(songFileDirPath, "", "", null); 080 } //Constructor 081 082 083 /** Constructor for Song with specied html start/end. 084 * 085 * @param songFileDirPath the full path to the songFile. 086 * @param htmlLinkStart used in the creation of the html toString method. 087 * @param htmlLinkEnd used in the creation of the html toString method. 088 * @throws Exception if the artist file dir does not exist of can't read as a dir. 089 **/ 090 public Song(String songFileDirPath, String htmlLinkStart, String htmlLinkEnd) throws Exception 091 { 092 this(songFileDirPath, htmlLinkStart, htmlLinkEnd, null); 093 } 094 095 096 /** Constructor for Song allowing fully defined metadata. 097 * 098 * @param songFileDirPath the full path to the songFile. 099 * @param htmlLinkStart used in the creation of the html toString method. 100 * @param htmlLinkEnd used in the creation of the html toString method. 101 * @param albumRefKEY see {@link #refKEY_ refKEY_}. 102 * @throws Exception if the artist file dire does not exist of can't read as a dir. 103 **/ 104 public Song(String songFileDirPath, String htmlLinkStart, String htmlLinkEnd, char[] albumRefKEY) throws Exception 105 { 106 if(albumRefKEY!=null && albumRefKEY_.length==2) albumRefKEY_ = albumRefKEY; 107 File songFile = new File(songFileDirPath); 108 String songFilePath = songFile.getAbsolutePath(); 109 if(songFile!=null && !songFile.isDirectory() && songFile.canRead() && 110 (songFilePath.endsWith(".ogg") || songFilePath.endsWith(".oga") || 111 songFilePath.endsWith(".mp3") || songFilePath.endsWith(".flac"))) 112 { 113 this.songFile_ = songFile; 114 String number = "00"; 115 String cdNumber = "01"; 116 String sng = ""; 117 try 118 { 119 sng = songFile_.getAbsolutePath().substring(songFile_.getAbsolutePath().lastIndexOf("/")+1).trim(); 120 121 if(sng.indexOf("_")>0) 122 //number = right(sng.substring(sng.indexOf("_")+1, sng.indexOf("-")),2); 123 //number = sng.substring(sng.indexOf("_")+1, sng.indexOf("-")); 124 number = sng.substring(sng.indexOf("_")+1, sng.indexOf("-", sng.indexOf("_")+1)); 125 else if(sng.indexOf("-")>0) 126 number = sng.substring(sng.indexOf("-")-2, sng.indexOf("-")); 127 if(number.length()>2) 128 { 129 // it includes a disc number 130 cdNumber = left(number,2); 131 number = right(number,2); 132 //System.out.print(" ++++++ "+sng.indexOf("_")+"} " +sng); 133 //System.out.println(" +++++++ Multi-CD: "+cdNumber+"["+number+"]"); 134 } 135 } 136 catch(Exception ex) 137 { 138 ex.printStackTrace(); 139 if(sng!=null && !"".equals(sng)) 140 { 141 System.out.println(" ++++++ "+sng.indexOf("_")+"} " +sng); 142 System.out.println(" ++++++ "+sng.substring(sng.indexOf("_")+1, sng.indexOf("-", sng.indexOf("_")+1))); 143 } 144 number = "00"; 145 } 146 try 147 { 148 this.number_=Integer.parseInt(number); 149 this.cdNumber_=Integer.parseInt(cdNumber); 150 } 151 catch(Exception ex) 152 { 153 this.number_ = 0; 154 } 155 if( ! ( this.number_ < (16*16)) || this.number_ <0 ) this.number_=0; 156 refKEY_ = Util.toHEXChars(this.number_, refKEY_.length); 157 158 } 159 else 160 throw new java.lang.Exception("Error with Song File Path or song type (ogg, mp3, .flac): "+songFileDirPath); 161 162 setHtmlLinkStart( htmlLinkStart); 163 setHtmlLinkEnd( htmlLinkEnd); 164 } // -- Constructor 165 166 167 /** SongName part of the filename including extension with spaces in name . **/ 168 public String name(){return name(false);} 169 /** SongName part of the filename including extension with or without thw spaces in name . **/ 170 public String name(boolean removeSpaces) 171 { 172 String retVal = songFile_.getAbsolutePath().substring(songFile_.getAbsolutePath().lastIndexOf("/")+1); 173 if (!removeSpaces) retVal = Util.capsToSpacesInString(retVal); 174 return retVal.trim(); 175 } 176 177 public String getSongFilePath() { return songFile_.getAbsolutePath(); } 178 179 public File getSongFile() { return songFile_; } 180 181 182 /** The actual fully expanded, cleaned of underscores and explicits / usable Song Title. **/ 183 public String songTitle(){return songTitle(false);} 184 /** The actual (optionally removed spaces), cleaned of underscores and explicits / usable Song Title. **/ 185 public String songTitle(boolean removeSpaces) 186 { 187 String file = name(); //.substring(name(true).lastIndexOf("-")+1); 188 String title = file.substring(file.indexOf("-")+1,file.lastIndexOf(".")); 189 if(file.indexOf("_")>0) 190 try 191 { 192 title = file.substring(file.indexOf("-", 193 file.indexOf("_")+1 194 )+1, 195 file.lastIndexOf(".")); 196 } 197 catch (java.lang.StringIndexOutOfBoundsException strEx) 198 { 199 title = file.substring(file.indexOf("-")+1,file.lastIndexOf(".")); 200 } 201 202 if (!removeSpaces) title = Util.capsToSpacesInString(title); 203 title = removeExplicit(title); 204 title = Util.tokenReplace(title," "," "); 205 title = Util.tokenReplace(title,"_"," "); 206 title = Util.tokenReplace(title," "," "); 207 title = Util.tokenReplace(title,"( ","("); 208 title = Util.tokenReplace(title,"He- Man","He-Man"); 209 title = Util.tokenReplace(title,"Liveat Live Aid","Live At Live Aid"); 210 title = Util.tokenReplace(title,",13th July1985",", 13th July 1985"); 211 title = Util.tokenReplace(title,"Livefromthe North Sea Jazz Festival","Live From The North Sea Jazz Festival"); 212 title = Util.tokenReplace(title,"Inthe","In The"); 213 title = Util.tokenReplace(title,"andthe"," And The"); 214 title = Util.tokenReplace(title," "," "); 215 216 return title.trim(); 217 } 218 219 220 /** 221 * Set Method for class field 'tunesSubPath_'. 222 * 223 * @param tunesSubPath is the value to set this class field to. 224 * 225 **/ 226 public static void setTunesSubPath(String tunesSubPath) 227 { 228 tunesSubPath_ = tunesSubPath; 229 } // setTunesSubPath Method 230 231 232 /** 233 * Get Method for class field 'tunesSubPath_'. 234 * 235 * @return String - The value the class field 'tunesSubPath_'. 236 * 237 **/ 238 public static String getTunesSubPath() 239 { 240 return tunesSubPath_; 241 } // getTunesSubPath Method 242 243 /** 244 * Set Method for class field 'cdNumber_'. 245 * 246 * @param cdNumber is the value to set this class field to. 247 * 248 **/ 249 public void setCdNumber(int cdNumber) 250 { 251 this.cdNumber_ = cdNumber; 252 } // setCdNumber Method 253 254 255 /** 256 * Get Method for class field 'cdNumber_'. 257 * 258 * @return int - The value the class field 'cdNumber_'. 259 * 260 **/ 261 public int getCdNumber() 262 { 263 return cdNumber_; 264 } // getCdNumber_ Method 265 266 267 268 /** 269 * Set Method for class field 'htmlLinkStart_'. 270 * 271 * @param htmlLinkStart is the value to set this class field to. 272 * 273 **/ 274 public void setHtmlLinkStart(String htmlLinkStart) 275 { 276 this.htmlLinkStart_ = htmlLinkStart; 277 } // setHtmlLinkStart Method 278 279 280 /** 281 * Get Method for class field 'htmlLinkStart_'. 282 * 283 * @return String - The value the class field 'htmlLinkStart_'. 284 * 285 **/ 286 public String getHtmlLinkStart() 287 { 288 return htmlLinkStart_; 289 } // getHtmlLinkStart Method 290 291 292 /** 293 * Set Method for class field 'htmlLinkEnd_'. 294 * 295 * @param htmlLinkEnd is the value to set this class field to. 296 * 297 **/ 298 public void setHtmlLinkEnd(String htmlLinkEnd) 299 { 300 this.htmlLinkEnd_ = htmlLinkEnd; 301 } // setHtmlLinkEnd Method 302 303 304 /** 305 * Get Method for class field 'htmlLinkEnd_'. 306 * 307 * @return String - The value the class field 'htmlLinkEnd_'. 308 * 309 **/ 310 public String getHtmlLinkEnd() 311 { 312 return htmlLinkEnd_; 313 } // getHtmlLinkEnd Method 314 315 316 /** 317 * Set this song as 'lastFmLoved_'. 318 * 319 **/ 320 public void setLastFmLoved(){setLastFmLoved(true);} 321 322 /** 323 * Set Method for class field 'lastFmLoved_'. 324 * 325 * @param lastFmLoved is the value to set this class field to. 326 * 327 **/ 328 public void setLastFmLoved(boolean lastFmLoved) 329 { 330 this.lastFmLoved_ = lastFmLoved; 331 } // setLastFmLoved Method 332 333 334 /** 335 * Get Method for class field 'lastFmLoved_'. 336 * 337 * @return boolean - The value the class field 'lastFmLoved_'. 338 * 339 **/ 340 public boolean getLastFmLoved() 341 { 342 return lastFmLoved_; 343 } // getLastFmLoved Method 344 345 346 public String albumName() 347 { 348 String albumPath = songFile_.getAbsolutePath().substring(0,songFile_.getAbsolutePath().lastIndexOf("/")); 349 //String artistPath = albumPath.substring(0, albumPath.lastIndexOf("/")); 350 String albumName = removeExplicit(albumPath.substring(albumPath.lastIndexOf("/")+1)); 351 //String artistName = artistPath.getAbsolutePath().substring(artistPath.getAbsolutePath().lastIndexOf("/")+1); 352 return albumName; 353 } // getHtmlLinkEnd Method 354 355 356 /** The actual fully expanded, cleaned of underscores and explicits / usable Album Title. **/ 357 public String albumTitle() 358 { 359 return albumTitle(false); 360 } 361 362 363 /** The actual cleaned of underscores and explicits / usable Album Title. **/ 364 public String albumTitle(boolean removeSpaces) 365 { 366 String title = albumName(); 367 title = Song.removeExplicit(title); 368 title = Util.capsToSpacesInString(title); 369 title = Util.tokenReplace(title," <","<"); 370 title = Util.tokenReplace(title," "," "); 371 title = Util.tokenReplace(title,"+"," +"); 372 title = Util.tokenReplace(title,"++","+"); 373 title = Util.tokenReplace(title,"_"," "); 374 title = Util.tokenReplace(title,"x &y","x&y"); 375 title = Util.tokenReplace(title,"x & y","x&y"); 376 title = Util.tokenReplace(title,"X &Y","X&Y"); 377 title = Util.tokenReplace(title,"X & Y","X&Y"); 378 title = Util.tokenReplace(title,"%2f","/"); 379 title = Util.tokenReplace(title,"%2F","/"); 380 title = Util.tokenReplace(title,"A & M","A&M"); 381 title = Util.tokenReplace(title,"a & m","A&M"); 382 title = Util.tokenReplace(title,"A& M","A&M"); 383 title = Util.tokenReplace(title,"A &M","A&M"); 384 if (removeSpaces) title=Util.spacesToCapsInString(title); 385 return title.trim(); 386 } 387 388 389 390 /** the artist dirname for this song. It parses it from the full pathed filename: artist/album/songs.<br> 391 * <b>NOTE:</b> this can be a problem if the top dir is various or variousArtists. In this case it will parse the artist from the actual filename 392 * it shouold follow my naming convention: Artist_XX-Songname.ogg <br> where XX is the track number. 393 * 394 * @return String artist dirname for this song 395 **/ 396 public String artistDir() 397 { 398 String albumPath = songFile_.getAbsolutePath().substring(0,songFile_.getAbsolutePath().lastIndexOf("/")); 399 //if(albumTitle().contains("Wembley"))System.out.println(" DEBUG: Song.artistDir albumPath="+albumPath); 400 String artistDir = albumPath.substring(0, albumPath.lastIndexOf("/")); 401 //if(albumTitle().contains("Wembley"))System.out.println(" DEBUG: Song.artistDir artistDir="+artistDir); 402 artistDir = artistDir.substring( artistDir.lastIndexOf("/")+1); 403 //if(albumTitle().contains("Wembley"))System.out.println(" DEBUG: Song.artistDir artistDir="+artistDir); 404 405 return artistDir; 406 } // artistDir Method 407 408 409 /** the artist name for this song. It parses it from the full pathed filename: artist/album/songs.<br> 410 * <b>NOTE:</b> this can be a problem if the top dir is various or variousArtists. In this case it will parse the artist from the actual filename 411 * it shouold follow my naming convention: Artist_XX-Songname.ogg <br> where XX is the track number. 412 * 413 * @return String artist name for this song 414 **/ 415 public String artistName() 416 { 417 String albumPath = songFile_.getAbsolutePath().substring(0,songFile_.getAbsolutePath().lastIndexOf("/")); 418 String artistPath = albumPath.substring(0, albumPath.lastIndexOf("/")); 419 //String albumName = albumPath.getAbsolutePath().substring(albumPath.getAbsolutePath().lastIndexOf("/")+1); 420 String albumArtistName_ = artistPath.substring(artistPath.lastIndexOf("/")+1); 421 if( 422 albumArtistName_.equalsIgnoreCase("various") 423 || albumArtistName_.equalsIgnoreCase("variousArtists") 424 || albumArtistName_.equalsIgnoreCase("randyBachman&BurtonCummings") 425 ) 426 { 427 try 428 { 429 String file = name(true); //.substring(name(true).lastIndexOf("-")+1); 430 String art = "";; 431 if(file.indexOf("-")>0) art = file.substring(0,file.indexOf("-")); 432 if(art.indexOf("_")>0) 433 art = art.substring(0,file.indexOf("_")); 434 else 435 art = art.substring(0,art.length()-2); 436 artistName_ = art; 437 } 438 catch(Exception ex) 439 { 440 System.out.println("Json parsing choked on artistName for "+ name(true)); 441 } 442 } 443 else 444 artistName_=albumArtistName_; 445 return artistName_; 446 } // getHtmlLinkEnd Method 447 448 449 /** 450 * Set Method for class field 'number_'. 451 * 452 * @param number is the value to set this class field to. 453 * 454 **/ 455 public void setNumber(int number) 456 { 457 this.number_ = number; 458 } // setNumber Method 459 460 461 /** 462 * Get Method for class field 'number_'. 463 * 464 * @return int - The value the class field 'number_'. 465 * 466 **/ 467 public int getNumber() 468 { 469 return number_; 470 } // getNumber Method 471 472 473 /** 474 * Set Method for class field {@link #libraryIndex_ 'libraryIndex_'}. 475 * 476 * @param libraryIndex is the value to set this class field to. 477 * 478 **/ 479 public void setLibraryIndex(int libraryIndex) 480 { 481 this.libraryIndex_ = libraryIndex; 482 } // setLibraryIndex Method 483 484 485 /** 486 * Get Method for class field {@link #libraryIndex_ 'libraryIndex_'}. 487 * 488 * @return int - The value the class field 'libraryIndex_'. 489 * 490 **/ 491 public int getLibraryIndex() 492 { 493 return libraryIndex_; 494 } // getLibraryIndex Method 495 496 497 /** 498 * Gets rid (removes) the word EXPLICIT from the title. 499 * 500 * @param title is the string to parse 501 * @return String is the replaced resultant String. 502 * 503 **/ 504 public static String removeExplicit(String title) 505 { 506 title = Util.tokenReplace(title,"(explicit)",""); 507 title = Util.tokenReplace(title,"explicit",""); 508 title = Util.tokenReplace(title,"(Explicit)",""); 509 title = Util.tokenReplace(title,"Explicit",""); 510 title = Util.tokenReplace(title,"(EXPLICIT)",""); 511 title = Util.tokenReplace(title,"EXPLICIT",""); 512 return title; 513 } 514 515 516 public String getRefKeyString() 517 { 518 String retVal = ""; 519 520 //System.out.println("getRefKeyString() refKEY_="+java.util.Arrays.toString(refKEY_)); 521 try 522 { 523 //System.out.println("getRefKeyString() Hex.decodeHex(refKEY_)="+Hex.decodeHex(refKEY_)); 524 //System.out.println("getRefKeyString() Hex.encodeHexString(refKEY_)="+Hex.encodeHexString(Hex.decodeHex(refKEY_))); 525 retVal = Hex.encodeHexString(Hex.decodeHex(refKEY_)); //only takes EVENnumber of chars 526 } 527 catch (DecoderException dEx) 528 { 529 //send back an empty String 530 System.out.println("getRefKeyString() Crapped Out: "+dEx.getMessage()); 531 } 532 return retVal; 533 } 534 535 536 /** 537 * Set Method for class field 'artistRefKEY_'. 538 * 539 * @param artistRefKEY is the value to set this class field to. 540 * 541 **/ 542 public void setArtistRefKEY(char[] artistRefKEY) 543 { 544 this.artistRefKEY_ = artistRefKEY; 545 } // setArtistRefKEY_ Method 546 547 548 /** 549 * Get Method for class field 'artistRefKEY_'. 550 * 551 * @return char[] - The value the class field 'artistRefKEY_'. 552 * 553 **/ 554 public char[] getArtistRefKEY() 555 { 556 return artistRefKEY_; 557 } // getArtistRefKEY_ Method 558 559 560 public String getAlbumRefKeyString() 561 { 562 String retVal = ""; 563 try 564 { 565 retVal = Hex.encodeHexString(Hex.decodeHex(albumRefKEY_)); //only takes EVENnumber of chars 566 } 567 catch (DecoderException dEx) 568 { 569 //send back an empty String 570 System.out.println("getAlbumRefKeyString() Crapped Out: "+dEx.getMessage()); 571 } 572 return retVal; 573 } 574 575 576 public String getArtistRefKeyString() 577 { 578 String retVal = ""; 579 try 580 { 581 retVal = Hex.encodeHexString(Hex.decodeHex(artistRefKEY_)); //only takes EVENnumber of chars 582 } 583 catch (DecoderException dEx) 584 { 585 //send back an empty String 586 System.out.println("getArtistRefKeyString() Crapped Out: "+dEx.getMessage()); 587 } 588 return retVal; 589 } 590 591 592 /** 593 * Returns the song metadata as a JSON String. 594 * <pre> 595 * { 596 * url : "https://red.webarts.bc.ca:9443/static/tunes/38Special/TheVeryBestOfTheA&lMYears(1977-1988)/38Special_13-Teacher,Teacher.ogg", 597 * file : "38Special_13-Teacher,Teacher.ogg", 598 * title : "Teacher, Teacher", 599 * number : "13" 600 * } 601 * </pre> 602 * @param songIndex is the int to use as this songs overall library index number to use in its metadata tags. 603 * @return the json String 604 **/ 605 public String toJsonString(int songIndex) 606 { 607 setHtmlLinkStart("<a class=\"Song"+songIndex+"\" id=\"Song"+songIndex+"\" name=\"Song"+songIndex+"\" href=\"#\" >"); 608 setLibraryIndex(songIndex); 609 //setHtmlLinkEnd("</a>"); 610 611 boolean spacedOut = false; 612 StringBuilder retVal = new StringBuilder(" {"); 613 try 614 { 615 String file = name(true); //.substring(name(true).lastIndexOf("-")+1); 616 617 String number = "00"; 618 try 619 { 620 if(file.indexOf("_")>0) 621 number = right(file.substring(file.indexOf("_")+1, file.indexOf("-")),2); 622 } 623 catch(Exception ex) 624 { 625 number = "00"; 626 } 627 String discNum = "00"; 628 try 629 { 630 if(file.indexOf("_")>0 && 631 file.substring(file.indexOf("_")+1, file.indexOf("-")).length()>2 ) 632 discNum = left(file.substring(file.indexOf("_")+1, file.indexOf("-")),2); 633 } 634 catch(Exception ex) 635 { 636 discNum = "00"; 637 } 638 639 String url = tunesSubPath_+"/"+artistDir()+"/"+albumName()+"/"+file.replace("?","%3F").replace("&","%26").replace("!","%21").replace("'","%27"); 640 url = Util.tokenReplace(url,"%2f","%252f"); 641 url = Util.tokenReplace(url,"%2F","%252F"); 642 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 643 644 if (spacedOut) retVal.append(" "); 645 retVal.append("url: \""); 646 retVal.append(url); 647 retVal.append("\""); 648 retVal.append(","); 649 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 650 651 if (spacedOut) retVal.append(" "); 652 retVal.append(" file: \""); 653 retVal.append(file); 654 retVal.append("\""); 655 retVal.append(","); 656 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 657 658 if (spacedOut) retVal.append(" "); 659 retVal.append(" title: \""); 660 retVal.append(songTitle()); 661 retVal.append("\""); 662 retVal.append(","); 663 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 664 665 if (spacedOut) retVal.append(" "); 666 retVal.append(" album: \""); 667 retVal.append(albumTitle().trim()); 668 retVal.append("\""); 669 retVal.append(","); 670 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 671 672 if (spacedOut) retVal.append(" "); 673 retVal.append(" art: \""); 674 retVal.append(Util.capsToSpacesInString(artistName()).trim()); 675 retVal.append("\""); 676 retVal.append(","); 677 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 678 679 if (spacedOut) retVal.append(" "); 680 retVal.append(" artDir: \""); 681 retVal.append(artistDir()); 682 retVal.append("\""); 683 retVal.append(","); 684 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 685 686 if(!"00".equals(discNum)) 687 { 688 if (spacedOut) retVal.append(" "); 689 retVal.append(" disc: \""); 690 retVal.append(discNum); 691 retVal.append("\""); 692 retVal.append(","); 693 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 694 } 695 696 if (spacedOut) retVal.append(" "); 697 retVal.append(" number: \""); 698 retVal.append(number); 699 retVal.append("\""); 700 retVal.append(","); 701 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 702 703 if (spacedOut) retVal.append(" "); 704 retVal.append(" refKey: \""); 705 retVal.append(getArtistRefKeyString()+"."+getAlbumRefKeyString()+"."+getRefKeyString()); 706 retVal.append("\""); 707 retVal.append(","); 708 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 709 710 if (spacedOut) retVal.append(" "); 711 retVal.append(" index: \""); 712 retVal.append(songIndex); 713 retVal.append("\""); 714 //retVal.append(","); 715 if (spacedOut) retVal.append(SYSTEM_LINE_SEPERATOR); 716 717 retVal.append(" }"); 718 } 719 catch(Exception ex) 720 { 721 System.out.println("Json parsing choked on "+ name(true)); 722 retVal=new StringBuilder("{ file: \""+"choked on "+ name(true)+"\"}"); 723 } 724 return retVal.toString(); 725 } 726 727 728 /** 729 * Gives you the rightmost number of chars in a string. 730 * 731 * @param value is the string to pull result from 732 * @param numChars the number of chars to return from the right side of 'value' 733 * @return a string holding the rightmost number of chars in the passed in String 734 **/ 735 public static String right(String value, int numChars) 736 { 737 String retVal = value; 738 if(value!=null && value.length()>= numChars) retVal = value.substring(value.length() - numChars); 739 return retVal; 740 } 741 742 743 /** 744 * Gives you the leftmost number of chars in a string. 745 * 746 * @param value is the string to pull result from 747 * @param numChars the number of chars to return from the left side of 'value' 748 * @return a string holding the leftmost number of chars in the passed in String 749 **/ 750 public static String left(String value, int numChars) 751 { 752 String retVal = value; 753 if(value!=null && value.length()>= numChars) retVal = value.substring(0,numChars); 754 return retVal; 755 } 756 757 758 /** Compares the Song Titles. **/ 759 public int compareTo(Song o) 760 { 761 return this.toString().compareTo(o.toString()); 762 } 763 764 765 /** The Song Title. **/ 766 public String toString() 767 { 768 return this.name().trim(); 769 } 770 771 772 public String toString(boolean html) 773 { 774 String retVal = ""; 775 String title = name().trim(); 776 String nm = ""; 777 if(title.indexOf("_")>0) 778 try 779 { 780 nm = title.substring(title.indexOf("-",title.indexOf("-",title.indexOf("_")+1)+1),title.lastIndexOf(".")); 781 } 782 catch (java.lang.StringIndexOutOfBoundsException strEx) 783 { 784 nm = title.substring(title.indexOf("-")+1).replace("_"," ").replace(" "," ").trim(); 785 } 786 else 787 nm = title.substring(title.indexOf("-")+1).replace("_"," ").replace(" "," ").trim(); 788 //String ttl = songTitle().trim().substring(songTitle().indexOf("-")+1).replace("_"," ").replace(" "," ").trim(); 789 String ttl = songTitle().trim().replace("_"," ").replace(" "," ").trim(); 790 String url = tunesSubPath_+"/"+artistDir()+"/"+albumName()+"/"; 791 url += Util.tokenReplace(name(true),"?","%3F"); 792 url = Util.tokenReplace(url,"&","%26"); 793 url = Util.tokenReplace(url,"!","%21"); 794 url = Util.tokenReplace(url,"%2f","%252f"); 795 url = Util.tokenReplace(url,"%2F","%252F"); 796 if(html)retVal+= "<li><div class=\"songtip\">"; 797 if(html)retVal+= getHtmlLinkStart().trim(); 798 //retVal+= nm.substring(0,nm.lastIndexOf(".")).trim(); 799 retVal+= ttl; 800 if(html)retVal+= getHtmlLinkEnd().trim(); 801 //retVal += " "+ getLibraryIndex(); 802 if(html)retVal+= "<span class=\"songtiptextTop\">"+url+"</span>"; 803 if(getLastFmLoved()) 804 { 805 if(html) 806 retVal+="<img id=\"jplayer_love\" class=\"love\" name=\"love\" style=\"margin-left: 1px; margin-bottom: -1px\" src=\"images/Heart-Gloss-5.svg\" height=\"12\" width=\"12\">"; 807 else 808 retVal+=" Loved"; 809 } 810 if(html)retVal+= "</div>"; 811 if(html)retVal+= "</li>"; 812 retVal+= SYSTEM_LINE_SEPERATOR; 813 return retVal; 814 } 815 816}