001/* 002 * 003 * $Revision: 1329 $ 004 * $Date: 2020-04-28 18:54:54 -0700 (Tue, 28 Apr 2020) $ 005 * $URL: svn://fred.webarts.bc.ca/open/trunk/projects/WebARTS/ca/bc/webarts/widgets/tunes/MusicMakerTunesHelper.java $ 006 * 007 * Written by Tom Gutwin - WebARTS Design. 008 * http://www.webarts.bc.ca 009 * Copyright (C) 2020 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 ca.bc.webarts.tools.JOrbisComment; 029import ca.bc.webarts.tools.MusicBrainzRestRequester; 030 031import java.io.File; 032import java.text.SimpleDateFormat; 033import java.util.Date; 034import java.util.ArrayList; 035import java.util.Calendar; 036import java.util.Collections; 037import java.util.HashMap; 038import java.util.Iterator; 039import java.util.Locale; 040import java.util.StringTokenizer ; 041import java.util.Vector; 042import java.text.NumberFormat; 043import javax.servlet.http.HttpSession; 044 045import javax.json.*; 046import javax.json.stream.JsonGenerator; 047import javax.json.stream.JsonParser; 048 049import org.apache.commons.codec.DecoderException; 050import org.apache.commons.codec.binary.Hex; 051 052import com.google.gson.Gson; 053import com.google.gson.GsonBuilder; 054import com.google.gson.JsonArray; 055import com.google.gson.JsonObject; 056import com.google.gson.JsonPrimitive; 057 058/** 059 * A helper class for the WebARTS MusicMaker (from AdaFruit) Tunes Web Application. It performs pre-processing 060 * of dirctories and adds {@link DirFileRef metaData JSON files} and html files to 061 * annotate all the directories. It uses the Tunes Package {@link Artist Artist}, {@link Album Album}, {@link Song Song} classes to deserialize the files and directory structures. 062 * 063 * @author TGutwin 064 */ 065public class MusicMakerTunesHelper 066{ 067 /** A holder for this clients System File Separator. */ 068 public final static String SYSTEM_FILE_SEPERATOR = java.io.File.separator; 069 070 /** A holder for this clients System line termination separator. */ 071 public final static String SYSTEM_LINE_SEPERATOR = 072 System.getProperty("line.separator"); 073 public final static String DEFAULT_COLUMN_DELIMITOR = "|"; 074 public final static String DEFAULT_MUSICMAKER_IP = "10.0.0.98"; 075 076 private String columnDelimitor = DEFAULT_COLUMN_DELIMITOR; 077 private String musicMakerIP_ = DEFAULT_MUSICMAKER_IP; 078 private String tunesNasRootPath_ = "/volume1/snd/"; 079 private String tunesFredRootPath_ = "/mnt/nas/snd/"; 080 private String tunesRootPath_ = tunesNasRootPath_; 081 private static String tunesSubPath_ = "ogg"; 082 private static String imagesSubPath_ = "images"; 083 private static String metadataFilename_ = "MetaData.json"; 084 085 /** The users pwd ditrectory. */ 086 public static String USERDIR = System.getProperty("user.dir"); 087 public static boolean testing_ = false; 088 public static boolean toShorts_ = false; 089 public static boolean toLongs_ = false; 090 public static boolean albumHtml_ = false; 091 public static boolean verboseOut = false; 092 public static boolean debug_info_ = false; 093 public static boolean debug_dir_ = true; 094 public static boolean debug_song_ = true; 095 public static boolean debug_all_ = false; 096 097 /** The file extension (type) to load **/ 098 public String FILETYPE = "ogg"; 099 public String fileType = FILETYPE; 100 101 public File tunesRootDirMetaFile_ = null; 102 103 public int numSndDirs_ = 0; 104 public File[] sndDirFiles_ =null; 105 public Vector<File> songDuds = new Vector(); 106 public short numArt_ = 0; 107 public short numAlb_ = 0; 108 public short numSongs_ = 0; 109 110 public Vector <Artist> artists_ = new Vector <Artist>(); 111 112 /** The 1 digit HEX char/byte Reference KEY for this root sub-dir . 113 * Example 1. <br> 114 * Eachsub-dir (ogg, mp3, flac etc.) should have a unique key based on the parsing of the root directory. It is created each time the roor directory is parsed. 115 * It is based on an alpha nemeric sorted list of Full (non hashed) spaceRemoved DirNames. (ie. VelvetRevolver ) 116 **/ 117 private char[] refKEY_ = {'0'}; 118 119 120 /** Constructor for the MusicMakerTunesHelper object. */ 121 public MusicMakerTunesHelper() 122 { 123 System.out.println("[ca.bc.webarts.widgets.tunes > MusicMakerTunesHelper()] " + 124 (new java.util.Date()).toString()); 125 }// -- Constructor 126 127 128 /** Constructor for the TunesHelper object to allow custom root path, but uses the default context = 'tunes'. */ 129 public MusicMakerTunesHelper(String tunesRootPath ) 130 { 131 System.out.println("[ca.bc.webarts.widgets.tunes > MusicMakerTunesHelper("+tunesRootPath+")] " + 132 (new java.util.Date()).toString()); 133 134 tunesRootPath_ = tunesRootPath; 135 tunesRootDirMetaFile_ = new File(tunesRootPath_+SYSTEM_FILE_SEPERATOR+metadataFilename_); 136 }// -- Constructor 137 138 139 /** Main **/ 140 public static void main (String [] args) 141 { 142 boolean topDirIsArtistDir = false; 143 boolean reParseAllDirs = false; 144 int cmdStart = 0; 145 String cmdArgs = ""; 146 String topDirFilename = ""; 147 148 if (args.length >0) 149 { 150 if (args[0].equalsIgnoreCase("-testing")) { testing_ = true; cmdStart++;} 151 if (args[0].equalsIgnoreCase("-toShorts")) {toShorts_ = true; cmdStart++;} 152 if (args[0].equalsIgnoreCase("-toLongs")) {toLongs_ = true; cmdStart++;} 153 if (args[0].equalsIgnoreCase("-albumHtml")) {albumHtml_ = true; cmdStart++;} 154 if (args.length >1 && args[1].equalsIgnoreCase("-testing")) { testing_ = true; cmdStart++;} 155 if (args.length >1 && args[1].equalsIgnoreCase("-toShorts")) {toShorts_ = true; toLongs_ = false;cmdStart++;} 156 if (args.length >1 && args[1].equalsIgnoreCase("-toLongs")) {toLongs_ = true; toShorts_ = false;cmdStart++;} 157 if (args.length >1 && args[1].equalsIgnoreCase("-albumHtml")) {albumHtml_ = true; cmdStart++;} 158 159 if (testing_) System.out.println(" TESTING ONLY "); 160 161 if (toShorts_ || toLongs_) 162 { 163 if (args.length >1) 164 { 165 topDirFilename = args[cmdStart]; // args[args.length-1]; 166 MusicMakerTunesHelper instance = new MusicMakerTunesHelper(topDirFilename); 167 168 System.out.println(" Renaming "+topDirFilename+" to "+(toShorts_?"SHort":"LONG")+" Filenames "); 169 //File topDirMetaFile = new File(topDirFilename+SYSTEM_FILE_SEPERATOR+metadataFilename_); 170 171 if ( reParseAllDirs || instance.tunesRootDirMetaFile_ == null || !instance.tunesRootDirMetaFile_.canRead() ) 172 { 173 // ONLY create when DirState is LONG 174 instance.createMetadataFiles(); 175 } 176 177 if(toShorts_) 178 { 179 instance.renameToShorts(topDirFilename, ""); 180 instance.writeArtistAlbumHtmlFiles(true); 181 } 182 else 183 { 184 instance.renameToLongs(topDirFilename, ""); 185 instance.writeArtistAlbumHtmlFiles(false); 186 } 187 } 188 else 189 System.out.println(" ERROR: You gotta give me a directoryPath to start in."); 190 } 191 else if(args[0].equalsIgnoreCase("-clean")) 192 { 193 if(args.length >1 ) 194 { 195 MusicMakerTunesHelper instance = new MusicMakerTunesHelper(args[1]); 196 instance.cleanDir(args[1]); 197 } 198 else System.out.println(" Error on commandline: You gotta provide a directoryPath to clean."); 199 200 } 201 else if(albumHtml_) 202 { 203 System.out.println(" Create Album HTML Files only"); 204 topDirFilename = args[cmdStart]; // args[args.length-1]; 205 MusicMakerTunesHelper instance = new MusicMakerTunesHelper(topDirFilename); 206 String jsonStr = Util.readFileToString(instance.tunesRootPath_+SYSTEM_FILE_SEPERATOR+metadataFilename_); 207 TopSndDirMetadata metaOBJ = new Gson().fromJson(jsonStr, TopSndDirMetadata.class); 208 //System.out.println(" TopSndDirMetadataJSON="+jsonStr); 209 //System.out.println("\n----------------------------"); 210 //System.out.println(" TopSndDirMetadata="+metaOBJ); 211 if(metaOBJ.getDirState()==DirFileRef.DirState.LONG ) instance.writeArtistAlbumHtmlFiles(false); 212 else instance.writeArtistAlbumHtmlFiles(true); 213 } 214 else 215 { 216 System.out.println(" CreateMetadataFiles only"); 217 // ONLY create when DirState is LONG 218 topDirFilename = args[cmdStart]; // args[args.length-1]; 219 MusicMakerTunesHelper instance = new MusicMakerTunesHelper(topDirFilename); 220 221 if ( reParseAllDirs || instance.tunesRootDirMetaFile_ == null || !instance.tunesRootDirMetaFile_.canRead() ) 222 { 223 System.out.println(" - "+(reParseAllDirs?" ReParsing":"Initial") + " Metadata File Creation"); 224 instance.createMetadataFiles(); 225 System.out.println(" -! DONE "+(reParseAllDirs?" ReParsing":"Initial") + " Metadata File Creation\n\n"); 226 instance.writeArtistAlbumHtmlFiles(false); 227 } 228 else 229 { 230 if ( instance.tunesRootDirMetaFile_ != null && instance.tunesRootDirMetaFile_.canRead() ) 231 { 232 System.out.println(" - RE-CREATING Metadata Files"); 233 // Check the DirState 234 // ONLY create when DirState is LONG 235 String jsonStr = Util.readFileToString(instance.tunesRootPath_+SYSTEM_FILE_SEPERATOR+metadataFilename_); 236 TopSndDirMetadata metaOBJ = new Gson().fromJson(jsonStr, TopSndDirMetadata.class); 237 //System.out.println(" TopSndDirMetadataJSON="+jsonStr); 238 //System.out.println("\n----------------------------"); 239 //System.out.println(" TopSndDirMetadata="+metaOBJ); 240 if(metaOBJ.getDirState()!=DirFileRef.DirState.LONG ) 241 { 242 System.out.println(" - Switching backTo LONGS 1st..."); 243 System.out.println(" metaOBJ.dirState="+metaOBJ.dirState); 244 System.out.println(" DirFileRef.DirState.LONG="+DirFileRef.DirState.LONG); 245 //instance.renameToLongs(topDirFilename, ""); 246 } 247 System.out.println(" - LONG ..."); 248 instance.createMetadataFiles(); 249 if(metaOBJ.getDirState()==DirFileRef.DirState.LONG ) instance.writeArtistAlbumHtmlFiles(false); 250 else instance.writeArtistAlbumHtmlFiles(true); 251 } 252 else 253 System.out.println(" ERROR Processing. Cannot create MetaData Files"); 254 } 255 } 256 } 257 else 258 { 259 System.out.println(" Parse the music/snd subdirectories to collect and save meta-data for each Artist/album directories."); 260 System.out.println("\n You must supply a TOP directory on the commandline that holds parent snd directories "); 261 System.out.println(" The dir should be the the TOP dir holding parenting snd directorie so it can parse the sub-artist dirs."); 262 System.out.println(" a second argument can be specified "); 263 System.out.println(" - if second argument is '-testing' to allow no actual writes"); 264 System.out.println(" - if second argument is '-toShorts' it will renames files to short refKey equivalents"); 265 System.out.println(" - if second argument is '-toLongs' it will renames files to long nospacess equivalents"); 266 System.out.println(" - if second argument is '-albumHtml' it creates the albumHtml files WITHOUT any file renaming"); 267 if (args.length >1) System.out.println(" arg1=" + args[1]); 268 if (args.length >2) System.out.println(" arg2=" + args[2]); 269 if (args.length >3) System.out.println(" arg3=" + args[3]); 270 } 271 } 272 273 274 /** Parses the TOP dir and reads in all the snd subirs creating Metadata files as is recurses. **/ 275 public void createMetadataFiles() {createMetadataFiles(tunesRootPath_);} 276 277 /** Parses the TOP dir and reads in all the snd subirs creating Metadata files as is recurses. **/ 278 private void createMetadataFiles(String topDirFilename) 279 { 280 System.out.println("\n******** MusicMakerTunesHelper ********"); 281 System.out.println(" topDirFilename = "+ topDirFilename); 282 File topDirFile = new File(topDirFilename); 283 284 //String [] topDirSubdirs = topDirFile.list(); 285 //String [] topArtistDirfilenames = topDirFile.list(); 286 if (topDirFile != null && 287 topDirFile.isDirectory() && 288 topDirFile.canRead() ) 289 { 290 cleanDir(topDirFilename); 291 parseTopTunesDir(topDirFilename); 292 } 293 // Now save the JSON RootDir Meta Data file 294 String metaStr = toMetaJsonTopDir(); 295 System.out.println("\n"+metaStr); 296 if (testing_) System.out.println("TESTING: fileWrite "+topDirFilename+SYSTEM_FILE_SEPERATOR+metadataFilename_); 297 else Util.writeStringToFile(metaStr, topDirFilename+SYSTEM_FILE_SEPERATOR+metadataFilename_); 298 299 // Then the snd sub-dirs 300 int sndDirNum = 0; 301 for(File currSnd : sndDirFiles_) 302 { 303 parseTunesDir(currSnd); 304 metaStr = toMetaJsonSndDir(currSnd.getAbsolutePath(), sndDirNum++); 305 System.out.println("\n"+metaStr); 306 if (testing_) System.out.println("TESTING: fileWrite "+currSnd.getAbsolutePath()+SYSTEM_FILE_SEPERATOR+metadataFilename_); 307 else Util.writeStringToFile(metaStr, currSnd.getAbsolutePath()+SYSTEM_FILE_SEPERATOR+metadataFilename_); 308 309 // // Then recurse and save Each Artist dir Meta Data File 310 Artist[] arts = getArtists(true).toArray(new Artist[getArtists(true).size()]); 311 java.util.Arrays.sort(arts); 312 for(Artist currArt : arts) 313 { 314 if (testing_) System.out.println("TESTING: writeMetaJsonFile "+currArt.artistName()); 315 else currArt.writeMetaJsonFile(); 316 317 Album[] artAlbums = currArt.getAlbums(true).toArray(new Album[currArt.getAlbums(true).size()]); 318 java.util.Arrays.sort(artAlbums); 319 for(Album currAlb : artAlbums) 320 { 321 if (testing_) System.out.println("TESTING: writeMetaJsonFile "+currAlb.albumTitle()); 322 else 323 { 324 currAlb.writeMetaJsonFile(); 325 currAlb.writeHtmlDivFile(); 326 } 327 } 328 } 329 } 330 } 331 332 333 public void cleanDir(String dirToClean){cleanDir(dirToClean, true);} 334 335 /** Parses the dir (recursive is optional) and removes non-song files and any useless subdirs (like @eadirs). **/ 336 public void cleanDir(String dirToClean, boolean recurse) 337 { 338 File[] subDirFiles = (new File(dirToClean)).listFiles(); 339 if(subDirFiles!=null) 340 { 341 try 342 { 343 for(File currFile : subDirFiles) 344 { 345 if(currFile.isDirectory() 346 && currFile.canRead() 347 && recurse) 348 { 349 if(currFile.getAbsolutePath().endsWith("@eaDir") 350 || currFile.getAbsolutePath().contains(".trash")) 351 ca.bc.webarts.widgets.Util.removeDir(currFile.getAbsolutePath()); 352 else 353 cleanDir(currFile.getAbsolutePath(), true); 354 } 355 else 356 { 357 // its a file so delete it if not needed 358 if(currFile.getAbsolutePath().endsWith(metadataFilename_)) 359 currFile.delete(); 360 361 } 362 } 363 } 364 catch(Exception ex) { System.out.println("ERROR Cleaning/Reading Dir: "+dirToClean); ex.printStackTrace();} 365 } 366 } 367 368 369 /** Parses the TOP tunes dir and reads in all the snd subirs. **/ 370 public void parseTopTunesDir(String tunesRootDir) 371 { 372 numSndDirs_ = 0; 373 Vector<File> sndDirs = new Vector(); 374 sndDirFiles_ = (new File(tunesRootDir)).listFiles(); 375 if(sndDirFiles_!=null) 376 { 377 try 378 { 379 for(File currFile : sndDirFiles_) 380 if(currFile.isDirectory() 381 && currFile.canRead() ) 382 { 383 numSndDirs_++; 384 sndDirs.add(currFile); 385 //parseTunesDir(currFile); 386 } 387 sndDirFiles_= sndDirs.toArray(new File[sndDirs.size()]); // reset it using only valid dirs 388 System.out.print(" parsing found sndDirs: ["); 389 for(int i=0; i<sndDirFiles_.length;i++) System.out.print(sndDirFiles_[i].getName()+(i<sndDirFiles_.length-1?", ":"]")); 390 } 391 catch(Exception ex) { System.out.println("ERROR Reading tunesRootDir: "+tunesRootDir); ex.printStackTrace();} 392 } 393 } 394 395 396 /** Parses the tunes sub-dirs and reads in all the artists_. **/ 397 public void parseTunesDir(File artistRootDirFile) 398 { 399 parseTunesDir(artistRootDirFile.getAbsolutePath()); 400 } 401 402 403 /** Parses the tunes sub-dirs and reads in all the artists_. **/ 404 public void parseTunesDir(String artistRootDir) 405 { 406 int numValidArtDirs = 0; 407 File[] artistDirFiles = (new File(artistRootDir)).listFiles(); 408 java.util.Arrays.sort(artistDirFiles); 409 boolean useMusicBrainz = true; // now rely on the MB settings for useCacheOnly 410 //java.util.List<Track> pagedLovedTracks = (java.util.List<Track>)lastFmLovedTracks_.getPageResults(); 411 if(artistDirFiles!=null) 412 { 413 //if(artists_==null) 414 artists_ = new Vector <Artist>(); 415 try 416 { 417 for(File currFile : artistDirFiles) 418 { 419 if(currFile.isDirectory() 420 && currFile.canRead() ) 421 { 422 // check if the artist dir has ANY album dirs, then add 423 File[] subFiles = (new File(currFile.getAbsolutePath())).listFiles(); 424 boolean valid = false; 425 try 426 { 427 for(int i=0; !valid&&i<subFiles.length; i++) 428 { 429 if(subFiles[i].isDirectory() 430 && subFiles[i].canRead() 431 && subFiles[i].listFiles().length>0 432 ) valid= true; 433 } 434 if(valid) 435 { 436 numValidArtDirs++; 437 //System.out.print("\n [ca.bc.webarts.widgets > MusicMakerTunesHelper.parseTunesDir() "); 438 //System.out.println("["+numValidArtDirs+"] "+currFile.getAbsolutePath()); 439 Artist art = new Artist(currFile.getAbsolutePath(), useMusicBrainz, artists_.size()); 440 artists_.add(art); 441 } 442 } 443 catch ( Exception ex) 444 { 445 System.out.println(" *!What The Fudge (parseTunesDir()) : "+ex.getMessage()); 446 ex.printStackTrace(); 447 } 448 } 449 } 450 } 451 catch(Exception ex) { /* ignore error dirs */ } 452 artists_.sort(Artist.ArtistComparatorIgnoreCase ); 453 } 454 } 455 456 457 public String getRefKeyString() 458 { 459 String retVal = "0"; 460 461 try 462 { 463 Hex.encodeHexString(Hex.decodeHex(refKEY_)); 464 } 465 catch (DecoderException dEx) 466 { 467 //send back an empty String 468 } 469 return retVal; 470 } 471 472 473 private void renameToShorts(String topDir , String parentRefKey) 474 { 475 renameTo(true, topDir , parentRefKey); 476 } 477 478 479 private void renameToLongs(String topDir , String parentRefKey) 480 { 481 renameTo(false, topDir , parentRefKey); 482 } 483 484 485 private void renameTo(boolean toShorts, String topDir , String parentRefKey) 486 { 487 String jsonStr = Util.readFileToString(topDir+SYSTEM_FILE_SEPERATOR+metadataFilename_); 488 489 File topDirFile = new File(topDir); 490 491 if(debug_info_ && toShorts) System.out.print(" > "+(testing_?"renameToShorts from ":"... ")+topDir+SYSTEM_FILE_SEPERATOR+metadataFilename_+" "); 492 if(debug_info_ && !toShorts) System.out.print(" > "+(testing_?"renameToLongs from ":"... ")+topDir+SYSTEM_FILE_SEPERATOR+metadataFilename_+" "); 493 if (topDirFile != null) 494 { 495 String[] files = topDirFile.list(); 496 File tempFile; 497 DirFileRef metaOBJ = new Gson().fromJson(jsonStr, DirFileRef.class); 498 499 if(debug_info_ && metaOBJ.dirType==SndDirMetadata.DirType.TOPDIR) System.out.println("\nI#I#I#I#\nI#I#I#I#\nI#I#I#I#\nI#I#I#I#\n READ IN:"+jsonStr); 500 if(debug_info_ && metaOBJ.dirType==SndDirMetadata.DirType.TOPDIR) System.out.println(metaOBJ); 501 if(debug_info_) System.out.print("\n DirType = "+metaOBJ.getDirType().typeStr); 502 if(debug_info_) System.out.println(" FULL refKey = "+parentRefKey+metaOBJ.getRefKey()); 503 504 TopSndDirMetadata topDirMetaObj = null; 505 SndDirMetadata sndMetaObj = null; 506 ArtistDirRef artistMetaObj = null; 507 AlbumDirRef albumMetaObj = null; 508 SongRef [] songsMetaObj = null; 509 SongRef currSongMetaObj = null; 510 try 511 { 512 if(metaOBJ.getDirType().typeStr.equals("ARTIST")) 513 { 514 artistMetaObj = new Gson().fromJson(jsonStr, ArtistDirRef.class); 515 } 516 else if(metaOBJ.getDirType().typeStr.equals("SNDROOT")) 517 { 518 sndMetaObj = new Gson().fromJson(jsonStr, SndDirMetadata.class); 519 } 520 else if(metaOBJ.getDirType().typeStr.equals("TOPDIR")) 521 { 522 topDirMetaObj = new Gson().fromJson(jsonStr, TopSndDirMetadata.class); 523 } 524 else if(metaOBJ.getDirType().typeStr.equals("ALBUM")) 525 { 526 albumMetaObj = new Gson().fromJson(jsonStr, AlbumDirRef.class); 527 songsMetaObj = albumMetaObj.getSongs(); 528 if(debug_info_) System.out.println(" ALBUM numSongs= "+albumMetaObj.getNumSongs() + "["+songsMetaObj.length+"]"); 529 } 530 System.out.print("\n "); 531 532 String shortFilename = ""; 533 String shortFilenameNoPeriods = ""; 534 String longFilename = ""; 535 //loop through all the files in the dir RENAMING them 536 // use the Songs Objects 537 for (int i = 0; i < files.length; i++) 538 { 539 currSongMetaObj = null; 540 tempFile = new File(topDir + SYSTEM_FILE_SEPERATOR + files[i]); 541 if (tempFile.isDirectory() && !files[i].startsWith("@")) 542 { 543 // recurse on the subdirectory 1st 544 if(debug_dir_) System.out.println(" >> Recursing"); 545 renameTo(toShorts, topDir + SYSTEM_FILE_SEPERATOR + files[i], parentRefKey+metaOBJ.getRefKey()+"."); 546 547 } 548 else if(files[i].endsWith(".ogg") || files[i].endsWith(".OGG") || 549 files[i].endsWith(".mp3") || files[i].endsWith(".MP3") || 550 files[i].endsWith(".flac") || files[i].endsWith(".FLAC") ) 551 { 552 if(songsMetaObj!=null) 553 { 554 System.out.print("|-> "); 555 for(SongRef currObj : songsMetaObj) 556 { 557 if(toShorts && files[i].equals(currObj.getDirFile())) currSongMetaObj = currObj; 558 if(!toShorts ) 559 { 560 shortFilename = parentRefKey.substring(2,4); 561 shortFilename += Util.right(parentRefKey,4); 562 shortFilename += albumMetaObj.getRefKey()+"."; 563 shortFilename += currObj.getRefKey(); 564 shortFilename = ca.bc.webarts.widgets.Util.tokenReplace(shortFilename,".","") ; 565 shortFilename += Util.right(files[i],4); 566 if(files[i].equals(shortFilename)) currSongMetaObj = currObj; 567 } 568 //System.out.println("chk "+files[i]+" "+currObj.getDirFile()); 569 } 570 if(currSongMetaObj!=null) 571 { 572 // leave the periods in for now 573 shortFilename = parentRefKey.substring(2,4); 574 shortFilename += Util.right(parentRefKey,4); 575 shortFilename += albumMetaObj.getRefKey()+"."; 576 shortFilename += currSongMetaObj.getRefKey(); 577 578 shortFilenameNoPeriods = ca.bc.webarts.widgets.Util.tokenReplace(shortFilename,".","") ; 579 shortFilenameNoPeriods += Util.right(files[i],4); 580 581 shortFilename += Util.right(files[i],4); 582 longFilename = currSongMetaObj.getDirFile(); 583 longFilename.substring(longFilename.lastIndexOf(SYSTEM_FILE_SEPERATOR)+1); 584 } 585 } 586 587 if(!testing_) 588 { 589 if(songsMetaObj!=null) 590 { 591 // process all the files 592 if(debug_song_) System.out.print("."); 593 if(toShorts) 594 { 595 // rename totoShortslongs 596 if(debug_song_) System.out.println(topDir + SYSTEM_FILE_SEPERATOR + files[i] + "\n --> " + 597 shortFilename+" "); 598 ca.bc.webarts.widgets.Util.renameFile(topDir + SYSTEM_FILE_SEPERATOR + files[i], shortFilenameNoPeriods); 599 600 } 601 else 602 { 603 // rename tolongs 604 if(debug_song_) System.out.println(topDir + SYSTEM_FILE_SEPERATOR + files[i] + "\n --> " + 605 longFilename+" "); 606 ca.bc.webarts.widgets.Util.renameFile(topDir + SYSTEM_FILE_SEPERATOR + files[i], longFilename); 607 } 608 } 609 } 610 else 611 { 612 // process all the files 613 if(songsMetaObj!=null) 614 { 615 System.out.print("|-> "); 616 if(toShorts) 617 { 618 System.out.println(topDir + SYSTEM_FILE_SEPERATOR + files[i] + "\n --> " + 619 shortFilename+" "); 620 } 621 else 622 { 623 // rename tolongs 624 System.out.println(topDir + SYSTEM_FILE_SEPERATOR + files[i] + "\n --> " + 625 longFilename+" "); 626 } 627 } 628 } 629 } 630 } // done Songs 631 632 // Finally Rename topDirFile 633 // now Update the MetaData file & RENAME the subdirectory 634 if(metaOBJ.getDirType().typeStr.equals("ALBUM")) 635 { 636 shortFilename = parentRefKey.substring(2,4); 637 shortFilename += Util.right(parentRefKey,4); 638 shortFilename += metaOBJ.getRefKey(); 639 } 640 else if(metaOBJ.getDirType().typeStr.equals("ARTIST")) 641 { 642 System.out.println(" FULL refKey = "+parentRefKey+metaOBJ.getRefKey()); 643 shortFilename = parentRefKey.substring(2,4); 644 shortFilename += Util.right(metaOBJ.getRefKey(),3); 645 //shortFilename += metaOBJ.getRefKey(); 646 } 647 else if(metaOBJ.getDirType().typeStr.equals("SNDROOT")) 648 { 649 System.out.println(" FULL refKey = "+parentRefKey+metaOBJ.getRefKey()); 650 shortFilename = metaOBJ.getRefKey(); 651 //shortFilename += Util.right(metaOBJ.getRefKey(),3); 652 //shortFilename += metaOBJ.getRefKey(); 653 } 654 longFilename = metaOBJ.getDirFile(); 655 longFilename = longFilename.substring(longFilename.lastIndexOf(SYSTEM_FILE_SEPERATOR)+1); 656 657 Gson gson = new Gson(); 658 jsonStr = ""; 659 660 if(!metaOBJ.getDirType().typeStr.equals("TOPDIR")) 661 { 662 if(!testing_) 663 { 664 // UPDATE the MetaFile DirState 665 if(metaOBJ.getDirType().typeStr.equals("SNDROOT")) 666 { 667 sndMetaObj.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 668 for(ArtistDirRef currArtRef : sndMetaObj.getArtists()) currArtRef.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 669 jsonStr = sndMetaObj.toString(); 670 } 671 else if(metaOBJ.getDirType().typeStr.equals("ARTIST")) 672 { 673 artistMetaObj.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 674 for(AlbumDirRef currAlbDirRef : artistMetaObj.getAlbums()) currAlbDirRef.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 675 jsonStr = artistMetaObj.toString(); 676 } 677 else if(metaOBJ.getDirType().typeStr.equals("ALBUM")) 678 { 679 albumMetaObj.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 680 for(SongRef currSongRef : albumMetaObj.getSongs()) currSongRef.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 681 jsonStr = albumMetaObj.toString(); 682 } 683 System.out.println(" Writing "+metaOBJ.getDirType().typeStr+" MetaData file: "+metaOBJ.getDirFile()+SYSTEM_FILE_SEPERATOR+metadataFilename_); 684 ca.bc.webarts.widgets.Util.writeStringToFile(jsonStr, metaOBJ.getDirFile()+SYSTEM_FILE_SEPERATOR+metadataFilename_); 685 if(metaOBJ.getDirType().typeStr.equals("ALBUM")) 686 { 687 //jsonStr = Util.readFileToString(topDir+SYSTEM_FILE_SEPERATOR+metadataFilename_); 688 //artistMetaObj = new Gson().fromJson(jsonStr, ArtistDirRef.class); 689 char[] refChars = {'0','0','0','0'}; 690 if(artistMetaObj!=null) 691 { 692 String ark = artistMetaObj.getRefKey(); 693 if(ark.length()>0) refChars[3] = ark.charAt(ark.length()-1); 694 if(ark.length()>1) refChars[2] = ark.charAt(ark.length()-2); 695 if(ark.length()>2) refChars[1] = ark.charAt(ark.length()-3); 696 if(ark.length()>3) refChars[0] = ark.charAt(ark.length()-4); 697 } 698 else System.out.println(" ERROR: no Artist YET for "+metaOBJ.getDirFile()); 699 700 try { 701 Album al = new Album(metaOBJ.getDirFile(), false, Integer.parseInt(metaOBJ.getRefKey()), refChars ); 702 if(al.isArtistRefKEYEmpty()) al.retrieveArtistRefKey(); 703 al.writeHtmlDivFile(); 704 } 705 catch (Exception ex) {System.out.println(" Error Writing Album html: refKey="+metaOBJ.getRefKey());} 706 } 707 708 shortFilenameNoPeriods = ca.bc.webarts.widgets.Util.tokenReplace(shortFilename,".",""); 709 // do the RENAME 710 if(toShorts) 711 { 712 // rename toShorts 713 if(debug_dir_) System.out.println(" DIR> "+topDir + "\n --> " + 714 shortFilename+" "); 715 ca.bc.webarts.widgets.Util.renameFile(topDir , shortFilenameNoPeriods); 716 } 717 else 718 { 719 // rename tolongs 720 if(debug_dir_) System.out.println(" <DIR> "+topDir+ "\n --> " + 721 longFilename +" "); 722 metaOBJ.setDirState(DirFileRef.DirState.LONG); 723 ca.bc.webarts.widgets.Util.renameFile(topDir , longFilename); 724 } 725 } 726 else 727 { 728 if(toShorts) System.out.println(" DIR: "+topDir + "\n --> " + 729 shortFilename+" "); 730 else System.out.println(" DIR: "+topDir+ "\n --> " + 731 longFilename +" "); 732 } 733 } 734 else 735 { 736 // update the TopDirMeta File 737 topDirMetaObj.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 738 for(DirFileRef currRef : topDirMetaObj.getSndDirs()) currRef.setDirState((toShorts?DirFileRef.DirState.SHORT:DirFileRef.DirState.LONG)); 739 jsonStr = topDirMetaObj.toString(); 740 ca.bc.webarts.widgets.Util.writeStringToFile(jsonStr, topDirMetaObj.getDirFile()+SYSTEM_FILE_SEPERATOR+metadataFilename_); 741 742 } 743 744 if(debug_dir_) System.out.println(" !! " + "done " +"\n"); 745 } 746 catch(NullPointerException npEx) 747 { 748 System.out.println(" Crapped out on "+metaOBJ); 749 System.out.println(" created from: "+jsonStr); 750 npEx.printStackTrace(); 751 } 752 } 753 754 } 755 756 757 /** Using this class object's tunesRootPath_ and existing MetaData Files data, 758 * write the album.html file in each Artist Album directory; overwritingexisitng files if needed. 759 * 760 **/ 761 public void writeArtistAlbumHtmlFiles() 762 { 763 writeArtistAlbumHtmlFiles( true); 764 } 765 766 767 /** Using this class object's tunesRootPath_ and existing MetaData Files data, 768 * write the album.html file in each Artist Album directory; overwritingexisitng files if needed. 769 * 770 **/ 771 public void writeArtistAlbumHtmlFiles(boolean doingRefURLS) 772 { 773 String preUrlStr = "../../../../"; 774 String postUrlStr = "\");"; 775 if( doingRefURLS) preUrlStr = "javascript:MusicMakerWebSocketMessage("+"\"TUNE/"; 776 777 writeArtistAlbumHtmlFiles( tunesRootPath_, preUrlStr, postUrlStr, doingRefURLS); 778 } 779 780 781 /** Using this class object's tunesRootPath_ and existing MetaData Files data, 782 * write the album.html file in each Artist Album directory; overwritingexisitng files if needed. 783 * 784 * @param preUrlStr is a string to pre-pend to all directorys represneting URLs; it can be an empty string to treat them as relative URLs. 785 **/ 786 public void writeArtistAlbumHtmlFiles(String preUrlStr, String postUrlStr, boolean doingRefURLS) 787 { writeArtistAlbumHtmlFiles( tunesRootPath_, preUrlStr, postUrlStr, doingRefURLS);} 788 789 790 /** Using existing MetaData Files data, write the album.html file in 791 * each Artist Album directory; overwritingexisitng files if needed. 792 * 793 * @param tunesRootDir is the top tunesdir holding the snd sub-dirs 794 * @param preUrlStr is a string to pre-pend to all directorys represneting URLs; it can be an empty string to treat them as relative URLs. 795 **/ 796 public void writeArtistAlbumHtmlFiles(String tunesRootDir , String preUrlStr, String postUrlStr, boolean doingRefURLS) 797 { 798 //String htmlLinkStart = "<a class=\"Song"+songCount+"\" id=\"Song"+songCount+"\" name=\"Song"+songCount+"\" href=\"#\" >"; 799 //String htmlLinkEnd ="</a>"; 800 801 String relativeURL = ""; 802 String tuneURL = ""; 803 String urlToUse = ""; 804 String urlRootDir = ""; 805 Vector <ArtistDirRef> artistRefs = new Vector <ArtistDirRef>(); 806 807// if( doingRefURLS) preUrlStr = "/TUNE/"; 808// else preUrlStr = "../../../../" 809 810 System.out.println(" writeArtistAlbumHtmlFiles("+tunesRootDir+", \""+preUrlStr+"\", \""+postUrlStr+"\", "+doingRefURLS+" )"); 811 812 if(tunesRootDir!=null && !"".equals(tunesRootDir)) 813 { 814 File topDirFile = new File(tunesRootDir); 815 if (topDirFile != null && topDirFile.canRead()) 816 { 817 String jsonStr = Util.readFileToString(tunesRootDir+SYSTEM_FILE_SEPERATOR+metadataFilename_); 818 TopSndDirMetadata topDirRef = new Gson().fromJson(jsonStr, TopSndDirMetadata.class); 819 boolean shorts = topDirRef.getDirState().getStateStr()=="SHORT"; 820 821 String tempFileStr = ""; 822 File tempFile = null; 823 String[] files = topDirFile.list(); 824 825 int artistCountTotal = 0; 826 int albumCountTotal = 0; 827 for (int i = 0; i < files.length; i++) // snd dirs 828 { 829 /* files = Root snd dirs */ 830 tempFileStr = tunesRootDir + SYSTEM_FILE_SEPERATOR + files[i]; 831 tempFile = new File(tempFileStr); 832 if (tempFile.isDirectory() && tempFile.canRead() 833 && !files[i].startsWith("@") && !files[i].startsWith(".")) 834 { 835 urlRootDir = tunesRootDir.substring(tunesRootDir.lastIndexOf(SYSTEM_FILE_SEPERATOR)+1) 836 +SYSTEM_FILE_SEPERATOR+files[i]+SYSTEM_FILE_SEPERATOR; 837 838 String tempFileStr2 = ""; 839 File tempFile2 = null; 840 String[] files2 = tempFile.list(); 841 842 // Loop to count Artists 1st 843 int artistCount = 0; 844 for (int i2 = 0; i2 < files2.length; i2++) 845 { 846 /* files2 [i2] = ARTIST dirs */ 847 tempFileStr2 = tempFileStr + SYSTEM_FILE_SEPERATOR + files2[i2]; 848 tempFile2 = new File(tempFileStr2); 849 if (tempFile2.isDirectory() && tempFile2.canRead() 850 && !files2[i2].startsWith("@") && !files2[i2].startsWith(".")) 851 artistCount++; 852 } 853 artistCountTotal +=artistCount; 854 String [] artistNames = new String [artistCount]; 855 String [] artistUrls = new String [artistCount]; 856 String [] artistDivHtml = new String [artistCount]; 857 int currArtistCount = -1; 858 859 for (int i2 = 0; i2 < files2.length; i2++) // Artist dirs 860 { 861 /* files2 [i2] = ARTIST dirs */ 862 String currArtDirName = files2[i2]; 863 ArtistDirRef currArtDirRef = null; 864 String currArtName = ""; 865 tempFileStr2 = tempFileStr + SYSTEM_FILE_SEPERATOR + files2[i2]; 866 tempFile2 = new File(tempFileStr2); 867 if (tempFile2.isDirectory() && tempFile2.canRead() 868 && !files2[i2].startsWith("@") && !files2[i2].startsWith(".")) 869 { 870 currArtistCount++; 871 //System.out.println(" DEBUG: reading Artist MetaData from: "+tempFileStr+SYSTEM_FILE_SEPERATOR+currArtDirName+SYSTEM_FILE_SEPERATOR+metadataFilename_); 872 jsonStr = Util.readFileToString(tempFileStr+SYSTEM_FILE_SEPERATOR+currArtDirName+SYSTEM_FILE_SEPERATOR+metadataFilename_); 873 currArtDirRef = new Gson().fromJson(jsonStr, ArtistDirRef.class); 874 875 currArtName = Util.capsToSpacesInString(currArtDirName); 876 if(currArtDirRef!=null && !"".equals(currArtDirRef.getArtistName())) currArtName = currArtDirRef.getArtistName(); 877 tempFileStr2 = tempFileStr + SYSTEM_FILE_SEPERATOR + files2[i2]; 878 tempFile2 = new File(tempFileStr2); 879 artistNames[currArtistCount] = currArtName; 880 artistUrls[currArtistCount] = tempFileStr2.substring(tunesRootDir.length()+1); 881 if(currArtDirRef!=null && !"".equals(currArtDirRef.getArtistName())) 882 { 883 currArtDirRef.setUrlPath(artistUrls[currArtistCount]); 884 artistRefs.add(currArtDirRef); 885 } 886 887 String tempFileStr3 = ""; 888 File tempFile3 = null; 889 String[] files3 = tempFile2.list(); 890 // count Albums 1st 891 int albumCount = 0; 892 for (int i3 = 0; i3 < files3.length; i3++) 893 { 894 // Loop to count ALBUMS 1st 895 tempFileStr3 = tempFileStr2 + SYSTEM_FILE_SEPERATOR + files3[i3]; 896 tempFile3 = new File(tempFileStr3); 897 if (tempFile3.isDirectory() && tempFile3.canRead() 898 && !files3[i3].startsWith("@") && !files3[i3].startsWith(".")) 899 albumCount++; 900 } 901 albumCountTotal+=albumCount; 902 903 String [] albmumUrls = new String [albumCount]; 904 String [] albmumDivHtml = new String [albumCount]; 905 AlbumDirRef [] albumRefs = new AlbumDirRef[albumCount]; 906 int currAlbumCount = -1; 907 908 for (int i3 = 0; i3 < files3.length; i3++) // Album dirs 909 { 910 /* files3 [i3] = ALBUM dirs */ 911 //System.out.print(" ReadingAlbum Dir="+tempFileStr2 + SYSTEM_FILE_SEPERATOR); 912 //System.out.println(files3[i3]); 913 tempFileStr3 = tempFileStr2 + SYSTEM_FILE_SEPERATOR + files3[i3]; 914 tempFile3 = new File(tempFileStr3); 915 if (tempFile3.isDirectory() && tempFile3.canRead() 916 && !files3[i3].startsWith("@") && !files3[i3].startsWith(".")) 917 { 918 currAlbumCount++; 919 // Read MetaData.json file 920 jsonStr = Util.readFileToString(tempFileStr3+SYSTEM_FILE_SEPERATOR+metadataFilename_); 921 AlbumDirRef currAlbDirRef = new Gson().fromJson(jsonStr, AlbumDirRef.class); 922 923 String albName = Util.capsToSpacesInString(files3[i3]); 924 if(currAlbDirRef!=null && !"".equals(currAlbDirRef.getAlbumName())) 925 { 926 albName = currAlbDirRef.getAlbumName(); 927 albumRefs[currAlbumCount] = currAlbDirRef; 928 SongRef [] songRefs = currAlbDirRef.getSongs(); 929 930 String lastFmAlbumUrl = Album.retrieveLastFmAlbumUrl(currArtName, albName).replace("#","%23"); 931 lastFmAlbumUrl = Util.tokenReplace(lastFmAlbumUrl,"#","%23"); 932 933 // Write album.html 934 String retVal = " <div id=\""+ 935 ca.bc.webarts.widgets.Util.spacesToCapsInString(albName)+ 936 "\" class=\"albumDiv\" >\n"; 937 retVal+= " <ol>\n"; 938 //retVal+= SYSTEM_LINE_SEPERATOR; 939 retVal+= " <img id=\""+Util.spacesToCapsInString(currArtName.trim())+"_" +Util.spacesToCapsInString(albName)+"_cover"+ 940 "\" alt=\""+Util.spacesToCapsInString(albName)+" Album Cover Thumbnail\" src=\""+ 941 "../.." + "/" + files[i] + "/" + files2[i2] + "/" + files3[i3] + "/" + 942 "cover.jpg"+"\" class=\"\" style=\"margin:0px;\" height=\"32px\" width=\"32px\"/>"; 943 retVal+= " <b><u> "; 944 if( !"".equals(lastFmAlbumUrl))retVal+= " <a href=\""+lastFmAlbumUrl+"\" target=\"_blank\"> "; 945 retVal+= albName; 946 if( !"".equals(lastFmAlbumUrl))retVal+= " </a> "; 947 retVal+= "</u></b>"; 948 //retVal+= " <span style=\"font-size: 0.7em;\">"; 949 //retVal+= " ("+ getReleaseYear() + ")"; 950 //retVal+= " [<a href=\""+downloadLink_+"\">zip</a>]</span>"; 951 retVal+= SYSTEM_LINE_SEPERATOR; 952 for (SongRef currSongRef : songRefs) 953 { 954 relativeURL = preUrlStr.trim() + 955 urlRootDir + files2[i2]+"/"+files3[i3]+"/" + 956 postUrlStr.trim(); 957 if(shorts) 958 { 959 relativeURL += files3[i3]+currSongRef.getRefKey() + currSongRef.getDirFile().substring(currSongRef.getDirFile().lastIndexOf(".")); 960 tuneURL = files3[i3]+currSongRef.getRefKey() + currSongRef.getDirFile().substring(currSongRef.getDirFile().lastIndexOf(".")); 961 } 962 else 963 relativeURL += Util.tokenReplace(currSongRef.getDirFile(),"?","%3F"); 964 relativeURL = Util.tokenReplace(relativeURL,"&","%26"); 965 relativeURL = Util.tokenReplace(relativeURL,"!","%21"); 966 relativeURL = Util.tokenReplace(relativeURL,"%2f","%252f"); 967 relativeURL = Util.tokenReplace(relativeURL,"%2F","%252F"); 968 if(doingRefURLS) urlToUse = preUrlStr.trim() + tuneURL +postUrlStr.trim(); 969 else urlToUse = relativeURL; 970 971 retVal+= " <li>\n <div class=\"songtip\">\n "; 972 retVal+= "<a href=\""+urlToUse+"\">"; 973 retVal+= currSongRef.getTitle().trim().replace("_"," ").replace(" "," ").trim(); 974 retVal+= "</a><span class=\"songtiptextTop\">"+urlToUse+"</span>\n"; 975 retVal+= " </div>\n </li>"; 976 retVal+= SYSTEM_LINE_SEPERATOR; 977 } 978 979 retVal += " </ol>\n </div>"; 980 Util.writeStringToFile(retVal, tempFileStr3+SYSTEM_FILE_SEPERATOR+"album.html"); 981 albmumUrls[currAlbumCount] = urlRootDir + files2[i2]+"/"+"album.html"; 982 albmumDivHtml[currAlbumCount] = retVal; 983 984 } 985 else 986 { 987 System.out.println(" Empty/NULL Album Dir Ref: "+currArtName+" / "+albName); 988 System.out.println(" trying from: "+ tempFileStr3+SYSTEM_FILE_SEPERATOR+metadataFilename_); 989 System.out.println(" jsonStr: \n"+jsonStr); 990 } 991 } // valid Album Dir 992 } // Album Dirs loop files3[j3] 993 994 //write the artist.html file 995 String artistHtml = " <script src=\"http://"+musicMakerIP_+"/mmWebSkt.js\"></script>\n"; 996 artistHtml += " <div id=\""+ca.bc.webarts.widgets.Util.spacesToCapsInString(currArtName) + 997 "\" class=\"artistDiv\">\n"; 998 artistHtml += " <span class=\"artistTitle\">"; 999 artistHtml += currArtName; 1000 artistHtml += "</span>\n"; 1001 1002 for(int j=0; j< albmumDivHtml.length; j++) 1003 { 1004 if(albmumDivHtml[j]!=null && !"".equals(albmumDivHtml[j])) 1005 { 1006 artistHtml += ca.bc.webarts.widgets.Util.tokenReplace( 1007 albmumDivHtml[j], 1008 "../../../../","../../../"); 1009 } 1010 else artistHtml += " <!-- empty album dir -->"; 1011 artistHtml += SYSTEM_LINE_SEPERATOR; 1012 } 1013 artistHtml += " </div>\n"; 1014 Util.writeStringToFile(artistHtml, tunesRootDir+SYSTEM_FILE_SEPERATOR + files[i]+SYSTEM_FILE_SEPERATOR + files2[i2]+SYSTEM_FILE_SEPERATOR+"artist.html"); 1015 1016 }// valid Artist dir 1017 }// Artist Dirs loop files2[j2] 1018 } 1019 } // snd dirs 1020 1021 // TOP Music Dir 1022 String artistListJson = "{\n \"artists\": [\n {\n"; 1023 String artistListHtml = " <div id=\"artistList\">\n <ul>\n"; 1024 ArtistDirRef currArtistRef = null; 1025 for(int j=0; j< artistRefs.size(); j++) 1026 { 1027 currArtistRef = artistRefs.get(j); 1028 if(currArtistRef!=null) 1029 { 1030 String metaFileStr = currArtistRef.getDirFile()+SYSTEM_FILE_SEPERATOR+".."+SYSTEM_FILE_SEPERATOR+metadataFilename_; 1031 if(currArtistRef.getDirState()!=DirFileRef.DirState.LONG) 1032 metaFileStr = tunesRootDir+SYSTEM_FILE_SEPERATOR+currArtistRef.getUrlPath()+SYSTEM_FILE_SEPERATOR+".."+SYSTEM_FILE_SEPERATOR+metadataFilename_; 1033 //System.out.println("looking for SNDMetaDatain "+metaFileStr); 1034 jsonStr = Util.readFileToString(metaFileStr); 1035 SndDirMetadata sndDirRef = new Gson().fromJson(jsonStr, SndDirMetadata.class); 1036 artistListJson += " \"name\": \""+currArtistRef.getArtistName()+"\",\n"; 1037 artistListJson += " \"refKey\": \""+sndDirRef.getRefKey() +"."+ currArtistRef.getRefKey()+"\",\n"; 1038 artistListJson += " \"url\": \""+currArtistRef.getUrlPath()+"/artist.html\"\n"; 1039 artistListJson += " }"; 1040 if(j<artistRefs.size()-1) artistListJson += ",\n {\n"; 1041 artistListHtml += " <li><a href=\""+currArtistRef.getUrlPath()+"/artist.html"+"\">"+currArtistRef.getArtistName()+"</a></li>\n"; 1042 } 1043 } 1044 artistListJson += "\n ]\n}"; 1045 artistListHtml += " </ul></div>\n"; 1046 System.out.println("Writing Artist List "+tunesRootDir+SYSTEM_FILE_SEPERATOR+"artists.html"); 1047 Util.writeStringToFile(artistListHtml, tunesRootDir+SYSTEM_FILE_SEPERATOR+"artists.html"); 1048 Util.writeStringToFile(artistListJson, tunesRootDir+SYSTEM_FILE_SEPERATOR+"artists.json"); 1049 createCSSFile(tunesRootDir); 1050 1051 } 1052 else System.out.println(" Error reading tunesRootDir string."); 1053 } 1054 else System.out.println(" Error writing Album html files due to null/empty tunesRootDir string."); 1055 1056 } 1057 1058 1059 /** . **/ 1060 public String createCSSFile(String topDirFilename) 1061 { 1062 String retVal = "header,footer{\n"; 1063 retVal += " color:white;\n"; 1064 retVal += " background-color:#004;\n"; 1065 retVal += " margin-bottom:6px;padding:4px;\n"; 1066 retVal += " font-family:Acme,Tahoma,sans-serif;\n"; 1067 retVal += "}\n"; 1068 retVal += "h1,h2 {\n"; 1069 retVal += " color:white;\n"; 1070 retVal += " background-color:#338;\n"; 1071 retVal += " padding:2px;\n"; 1072 retVal += " margin-bottom:2px;\n"; 1073 retVal += " font-family:Acme,Tahoma,sans-serif;\n"; 1074 retVal += "}\n"; 1075 retVal += "h3,h4,h5,h6 {\n"; 1076 retVal += " color:white;\n"; 1077 retVal += " background-color:#55a;\n"; 1078 retVal += " padding-left:2px;padding-right:4px;padding-top:4px;padding-bottom:4px;\n"; 1079 retVal += " margin-left:1px;\n"; 1080 retVal += " margin-right:1px;\n"; 1081 retVal += " margin-bottom:1px;\n"; 1082 retVal += " font-family:Acme,Tahoma,sans-serif;\n"; 1083 retVal += "}\n"; 1084 retVal += "body {\n"; 1085 retVal += " background-color: #111144; \n"; 1086 retVal += " font-family:'Noto Sans',Tahoma,sans-serif;font-size:0.8em;\n"; 1087 retVal += "}\n"; 1088 retVal += "section {\n"; 1089 retVal += " margin:1px;margin-bottom:6px;padding:1px;\n"; 1090 retVal += " background-color:#005;\n"; 1091 retVal += " font-family:Acme,Tahoma,sans-serif;\n"; 1092 retVal += "}\n"; 1093 retVal += "article {\n"; 1094 retVal += " border:1px solid blue;\n"; 1095 retVal += " margin:1px;margin-bottom:4px;margin-top:0px;padding:1px;\n"; 1096 retVal += " background-color:#eee;\n"; 1097 retVal += " font-family:'Noto Sans',Tahoma,sans-serif;\n"; 1098 retVal += "}\n"; 1099 retVal += "nav ul {\n"; 1100 retVal += " margin:0;padding:0;font-family:Acme,Tahoma,sans-serif;\n"; 1101 retVal += " list-style-type:none;margin:0;padding:0;overflow:hidden;\n"; 1102 retVal += "}\n"; 1103 retVal += "nav ul li a{\n"; 1104 retVal += " display:inline; font-family:'Noto Sans',Tahoma,sans-serif;font-size:0.7em;\n"; 1105 retVal += " color:#ddf!important; padding:3px 5px;float: left;\n"; 1106 retVal += "}\n"; 1107 retVal += "nav ul li a:hover{\n"; 1108 retVal += " color:#fff!important; background-color:#448;text-shadow: 0 0 3px #00F;\n"; 1109 retVal += " box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.2);\n"; 1110 retVal += " transition: all 200ms ease-out;\n"; 1111 retVal += "}\n"; 1112 retVal += "\n"; 1113 retVal += "\n"; 1114 retVal += "a {text-decoration: none;}\n"; 1115 retVal += "a:hover {color:#000!important; background-color:#fafaff;}\n"; 1116 retVal += "a:link {text-decoration: none; color: #337; }\n"; 1117 retVal += "a:visited { text-decoration:none; color: #404; }\n"; 1118 retVal += "a:active { text-decoration:none;color: #228; }\n"; 1119 retVal += "\n"; 1120 retVal += "div.inline { float:left; vertical-align: middle; }\n"; 1121 retVal += ".middle { left:0;width:50%;text-align:center; vertical-align: middle; }\n"; 1122 retVal += ".float-left{ float:left!important}\n"; 1123 retVal += ".float-right{ float:right!important}\n"; 1124 retVal += ".visibleDiv {\n"; 1125 retVal += " position: fixed;\n"; 1126 retVal += " border: solid 1px #046;\n"; 1127 retVal += " vertical-align: middle;\n"; 1128 retVal += " background: #224;\n"; 1129 retVal += " text-align: center;\n"; 1130 retVal += "}\n"; 1131 retVal += ".topLeft { top: 5px; left: 5px; }\n"; 1132 retVal += ".topRight { top: 5px; right: 76px; } /* this needs to be the same as the album size +5 */\n"; 1133 retVal += ".topRightAlbum { top: 5px; right: 5px; margin:0px 0px 0px 0px ;}\n"; 1134 retVal += ".shadowed { top: 5px; right: 5px; margin:0px 0px 0px 0px ; box-shadow: -6px 12px 4px 0px RGBA(24, 0, 255, 0.5);}\n"; 1135 retVal += ".bottomLeft { bottom: 5px; left: 5px; }\n"; 1136 retVal += ".bottomRight { bottom: 5px; right: 5px;}\n"; 1137 retVal += ".playerSpacer{ margin-right: 285px; }\n"; 1138 retVal += ".navSpacer{ margin-top: 85px; }\n"; 1139 retVal += ".navClosed { max-height: 55px;overflow:hidden;}\n"; 1140 retVal += "\n"; 1141 retVal += ".rotate90 {\n"; 1142 retVal += " -webkit-transform: rotate(90deg);\n"; 1143 retVal += " -moz-transform: rotate(90deg);\n"; 1144 retVal += " -o-transform: rotate(90deg);\n"; 1145 retVal += " -ms-transform: rotate(90deg);\n"; 1146 retVal += " transform: rotate(90deg);\n"; 1147 retVal += "}.rotate-90 {\n"; 1148 retVal += " -webkit-transform: rotate(270deg);\n"; 1149 retVal += " -moz-transform: rotate(270deg);\n"; 1150 retVal += " -o-transform: rotate(270deg);\n"; 1151 retVal += " -ms-transform: rotate(270deg);\n"; 1152 retVal += " transform: rotate(270deg);\n"; 1153 retVal += "}\n"; 1154 retVal += "a.coverMetadata:hover {\n"; 1155 retVal += " background:#005;\n"; 1156 retVal += " color:#99f;\n"; 1157 retVal += "}\n"; 1158 retVal += ".songtip {\n"; 1159 retVal += " position: relative;\n"; 1160 retVal += "}\n"; 1161 retVal += ".songtip .songtiptextTop {\n"; 1162 retVal += " visibility: hidden;\n"; 1163 retVal += " width: 240px;\n"; 1164 retVal += " bottom: 100%;\n"; 1165 retVal += " left: 50%;\n"; 1166 retVal += " margin-left: -120px; /* Use half of the width (240/2 = 120), to center the tooltip */\n"; 1167 retVal += " background-color: #9999cc;\n"; 1168 retVal += " color: #005;\n"; 1169 retVal += " text-align: center;\n"; 1170 retVal += " border-radius: 6px;\n"; 1171 retVal += " padding: 3px 0;\n"; 1172 retVal += " font-size: 0.7em;\n"; 1173 retVal += " \n"; 1174 retVal += " /* Position the tooltip */\n"; 1175 retVal += " position: absolute;\n"; 1176 retVal += " z-index: 1;\n"; 1177 retVal += "}\n"; 1178 retVal += ".songtip .songtiptext {\n"; 1179 retVal += " visibility: hidden;\n"; 1180 retVal += " top: -5px;\n"; 1181 retVal += " left: 105%;\n"; 1182 retVal += " background-color: #9999cc;\n"; 1183 retVal += " color: #005;\n"; 1184 retVal += " text-align: center;\n"; 1185 retVal += " border-radius: 6px;\n"; 1186 retVal += " padding: 3px 0;\n"; 1187 retVal += " font-size: 0.6em;\n"; 1188 retVal += " \n"; 1189 retVal += " /* Position the tooltip */\n"; 1190 retVal += " position: absolute;\n"; 1191 retVal += " z-index: 1;\n"; 1192 retVal += "}\n"; 1193 retVal += ".songtip:hover .songtiptextTop {\n"; 1194 retVal += " visibility: visible;\n"; 1195 retVal += "}\n"; 1196 retVal += ".songtip:hover .songtiptext {\n"; 1197 retVal += " visibility: visible;\n"; 1198 retVal += "}\n"; 1199 retVal += ".currentPlayingSong { background: linear-gradient(141deg, #00f6ff00 0%, #1fdba666 60%, #2c98e8 85%); opacity: 0.95; }\n\n"; 1200 retVal += "#coverMetadata {\n"; 1201 retVal += " background-color:#004;\n"; 1202 retVal += " -moz-border-radius:4px;\n"; 1203 retVal += " -webkit-border-radius:4px;\n"; 1204 retVal += " color:#fff;\n"; 1205 retVal += " padding:1px;\n"; 1206 retVal += " font-family:'Noto Sans', tahoma, helvetica, arial, verdana;\n"; 1207 retVal += "}\n"; 1208 retVal += "#coverMetadata a {\n"; 1209 retVal += " background:#004;\n"; 1210 retVal += " color:#bbf;\n"; 1211 retVal += "}\n"; 1212 retVal += "#lastfmRecentPlaysModal {\n"; 1213 retVal += " background-color:#000093;\n"; 1214 retVal += " -moz-border-radius:4px;\n"; 1215 retVal += " -webkit-border-radius:4px;\n"; 1216 retVal += " color:#fff;\n"; 1217 retVal += " padding:1px;\n"; 1218 retVal += " margin-top: 2%;\n"; 1219 retVal += " font-family:'Noto Sans', tahoma, helvetica, arial, verdana;\n"; 1220 retVal += " font-weight:bold;\n"; 1221 retVal += " /*font-size: 80%;*/\n"; 1222 retVal += " /*width:200px;*/\n"; 1223 retVal += " width:60%;\n"; 1224 retVal += " height:90%;\n"; 1225 retVal += " margin-left:20%;\n"; 1226 retVal += "}\n"; 1227 retVal += "#lastfmRecentPlays{\n"; 1228 retVal += " color:#000;\n"; 1229 retVal += " font-family:'Noto Sans', tahoma, helvetica, arial, verdana;\n"; 1230 retVal += "}\n"; 1231 retVal += "#lastfmRecentPlaysModal td{\n"; 1232 retVal += " color:#000;\n"; 1233 retVal += " font-family:'Noto Sans', tahoma, helvetica, arial, verdana;\n"; 1234 retVal += "}\n"; 1235 Util.writeStringToFile(retVal, topDirFilename+SYSTEM_FILE_SEPERATOR+"mMaker.css"); 1236 System.out.println("Writing CSS file "+topDirFilename+SYSTEM_FILE_SEPERATOR+"mMaker.css"); 1237 1238 retVal = "<link rel=\"stylesheet\"\n"; 1239 retVal += " type=\"text/css\"\n"; 1240 retVal += " href=\"/mMaker.css\"\n"; 1241 retVal += " title=\"mMakerStyle\">"; 1242 Util.writeStringToFile(retVal, topDirFilename+SYSTEM_FILE_SEPERATOR+"css.html"); 1243 1244 return retVal; 1245 } 1246 1247 1248 /** Parses the TOP dir and reads in all the snd subirs creating Metadata files as is recurses. **/ 1249 public void createHtmlFiles(String topDirFilename) 1250 { 1251 String retVal = "<div>\n"; 1252 1253 retVal += "</div>"; 1254 Util.writeStringToFile(retVal, topDirFilename+SYSTEM_FILE_SEPERATOR+"album.html"); 1255 1256 } 1257 1258 1259 /** Parses the TOP dir and reads in all the snd subirs creating Metadata files as is recurses. **/ 1260 public String getHtmlDiv(String topDirFilename) 1261 { 1262 String retVal = ""; 1263 return retVal; 1264 } 1265 1266 1267 /** Cobbles together the meta-data information about this Artist Directory in a JSON string. **/ 1268 public String toMetaJsonTopDir(){return toMetaJsonTopDir(false, DirFileRef.DirState.LONG);} 1269 1270 1271 /** Cobbles together the meta-data information about this TOP Directory in a JSON string. 1272 * The JSON this is representing is as Follows:<pre> 1273 * { 1274 * "dirFile": "/home/tgutwin/Music", 1275 * "dirType": "TOPDIR", 1276 * "dirState": "LONG", 1277 * "refKey": "0", 1278 * "numSndDirs": 2, 1279 * "sndDirs": [ 1280 * { 1281 * "refKey": "0", 1282 * "dirFile": "ogg", 1283 * "dirType": "SNDROOT", 1284 * "dirState": "LONG" 1285 * }, 1286 * { 1287 * "refKey": "1", 1288 * "dirFile": "mp3", 1289 * "dirType": "SNDROOT", 1290 * "dirState": "LONG" 1291 * } 1292 * ] 1293 * } 1294 * </pre> 1295 **/ 1296 public String toMetaJsonTopDir(boolean recurseDirs, DirFileRef.DirState dirState) 1297 { 1298 String retVal = ""; 1299 1300 int sndNum = 0; 1301 int albNum = 0; 1302 javax.json.JsonArrayBuilder sndArrayBuilder = javax.json.Json.createArrayBuilder(); 1303 javax.json.JsonArrayBuilder artistArrayBuilder = javax.json.Json.createArrayBuilder(); 1304 1305 for(File currSnd : sndDirFiles_) 1306 { 1307 javax.json.JsonObject jsonSndObject = javax.json.Json.createObjectBuilder() 1308 .add("refKey", ""+sndNum++) 1309 .add("dirFile", currSnd.getName()) 1310 .add("dirType", DirFileRef.DirType.SNDROOT.typeStr) 1311 .add("dirState", dirState.getStateStr()) // this needs to be based on parsing 1312 .build(); 1313 sndArrayBuilder.add( jsonSndObject); 1314 //arrayBuilder.add( currArt.toMetaJsonObject()); 1315 } 1316 javax.json.JsonArray sndArray = sndArrayBuilder.build(); 1317 1318 for(Artist currArt : getArtists(true)) 1319 { 1320 javax.json.JsonObject jsonArtistObject = javax.json.Json.createObjectBuilder() 1321 .add(Util.right(currArt.getRefKeyString(),4), currArt.artistName()) 1322 .add("musicBrainzID", currArt.getMusicBrainzID() ) 1323 .build(); 1324 //jsonArtistObject=currArt.toMetaJsonObject(); // get the FULL details from Artists 1325 artistArrayBuilder.add( jsonArtistObject); 1326 //arrayBuilder.add( currArt.toMetaJsonObject()); 1327 } 1328 1329 javax.json.JsonArray artArray = artistArrayBuilder.build(); 1330 1331 javax.json.JsonObjectBuilder joBuilder = javax.json.Json.createObjectBuilder(); 1332 joBuilder.add("dirFile", getTunesDirPath() ); 1333 joBuilder.add("dirType", DirFileRef.DirType.TOPDIR.typeStr); 1334 joBuilder.add("dirState", dirState.getStateStr()); // this needs to be based on parsing 1335 joBuilder.add("refKey", getRefKeyString() ); 1336 joBuilder.add("numSndDirs", sndNum); 1337 joBuilder.add("sndDirs", sndArray ); 1338 1339 if(recurseDirs) 1340 { 1341 joBuilder.add("numArtists", getNumberOfArtists() ); 1342 joBuilder.add("artists", artArray ); 1343 } 1344 javax.json.JsonObject json = joBuilder.build(); 1345 1346 retVal = prettyPrint(json); 1347 //retVal = json.toString(); 1348 1349 return retVal; 1350 } 1351 1352 1353 /** Cobbles together the meta-data information about this SND sub-Directory in a JSON string. 1354 **/ 1355 public String toMetaJsonSndDir(String currSnd, int refKey) 1356 { 1357 String retVal = ""; 1358 1359 int sndNum = 0; 1360 int albNum = 0; 1361 1362 javax.json.JsonArrayBuilder artistArrayBuilder = javax.json.Json.createArrayBuilder(); 1363 1364 for(Artist currArt : getArtists(true)) 1365 { 1366 javax.json.JsonObject jsonArtistObject = javax.json.Json.createObjectBuilder() 1367 .add("refKey", Util.right(currArt.getRefKeyString(),4)) 1368 .add("dirFile", currArt.getArtistDir().substring(currArt.getArtistDir().lastIndexOf(SYSTEM_FILE_SEPERATOR)+1)) 1369 .add("dirType", DirFileRef.DirType.ARTIST.typeStr) 1370 .add("dirState", DirFileRef.DirState.LONG.stateStr) 1371 .add("name", currArt.artistName()) 1372 .add("shortName", currArt.artistName(true)) 1373 .add("musicBrainzID", currArt.getMusicBrainzID() ) 1374 .build(); 1375 //jsonArtistObject=currArt.toMetaJsonObject(); // get the FULL details from Artists 1376 artistArrayBuilder.add( jsonArtistObject); 1377 //arrayBuilder.add( currArt.toMetaJsonObject()); 1378 } 1379 1380 javax.json.JsonArray artArray = artistArrayBuilder.build(); 1381 1382 javax.json.JsonObject json = javax.json.Json.createObjectBuilder() 1383 .add("dirFile", currSnd ) 1384 .add("dirType", DirFileRef.DirType.SNDROOT.typeStr ) 1385 .add("dirState", DirFileRef.DirState.LONG.stateStr ) // this needs to be based on parsing 1386 .add("refKey", ""+refKey ) 1387 .add("parentRefKey", ""+refKey ) 1388 .add("numArtists", getNumberOfArtists() ) 1389 .add("artists", artArray ) 1390 .build(); 1391 1392 retVal = prettyPrint(json); 1393 //retVal = json.toString(); 1394 1395 return retVal; 1396 } 1397 1398 1399 /** NOT USED - See Artist class . Cobbles together the meta-data information about this Artist Directory in a JSON string. **/ 1400 public String toMetaJsonArtDir() // NOT USED 1401 { 1402 // 1403 // NOT USED 1404 // 1405 String retVal = ""; 1406 1407 int sndNum = 0; 1408 int albNum = 0; 1409 javax.json.JsonArrayBuilder sndArrayBuilder = javax.json.Json.createArrayBuilder(); 1410 javax.json.JsonArrayBuilder artistArrayBuilder = javax.json.Json.createArrayBuilder(); 1411 1412 for(File currSnd : sndDirFiles_) 1413 { 1414 javax.json.JsonObject jsonSndObject = javax.json.Json.createObjectBuilder() 1415 .add(""+sndNum++, currSnd.getAbsolutePath()) 1416 .build(); 1417 sndArrayBuilder.add( jsonSndObject); 1418 //arrayBuilder.add( currArt.toMetaJsonObject()); 1419 } 1420 javax.json.JsonArray sndArray = sndArrayBuilder.build(); 1421 1422 for(Artist currArt : getArtists(true)) 1423 { 1424 javax.json.JsonObject jsonArtistObject = javax.json.Json.createObjectBuilder() 1425 .add(Util.right(currArt.getRefKeyString(),3), currArt.artistName()) 1426 .add("musicBrainzID", currArt.getMusicBrainzID() ) 1427 .build(); 1428 artistArrayBuilder.add( jsonArtistObject); 1429 //arrayBuilder.add( currArt.toMetaJsonObject()); 1430 } 1431 1432 javax.json.JsonArray artArray = artistArrayBuilder.build(); 1433 1434 javax.json.JsonObject json = javax.json.Json.createObjectBuilder() 1435 .add("dirFile", getTunesDirPath() ) 1436 .add("dirType", DirFileRef.DirType.ARTIST.typeStr ) 1437 .add("dirState", DirFileRef.DirState.LONG.stateStr ) // this needs to be based on parsing 1438 .add("refKey", getRefKeyString() ) 1439 .add("numSndDirs", sndNum) 1440 .add("sndDirs", sndArray ) 1441 .add("numArtists", getNumberOfArtists() ) 1442 .add("artists", artArray ) 1443 .build(); 1444 1445 retVal = prettyPrint(json); 1446 1447 return retVal; 1448 } 1449 1450 1451 /** helper to format json string - This is the preferredformatter. **/ 1452 public static String prettyPrint(JsonStructure json) 1453 { 1454 return jsonFormat(json, JsonGenerator.PRETTY_PRINTING); 1455 } 1456 1457 1458 /** helper to format json string **/ 1459 public static String jsonFormat(JsonStructure json, String... options) 1460 { 1461 java.io.StringWriter stringWriter = new java.io.StringWriter(); 1462 java.util.Map<String, Boolean> config = buildConfig(options); 1463 JsonWriterFactory writerFactory = Json.createWriterFactory(config); 1464 JsonWriter jsonWriter = writerFactory.createWriter(stringWriter); 1465 1466 jsonWriter.write(json); 1467 jsonWriter.close(); 1468 1469 return stringWriter.toString(); 1470 } 1471 1472 1473 private static java.util.Map<String, Boolean> buildConfig(String... options) 1474 { 1475 java.util.Map<String, Boolean> config = new HashMap<String, Boolean>(); 1476 1477 if (options != null) { 1478 for (String option : options) { 1479 config.put(option, true); 1480 } 1481 } 1482 1483 return config; 1484 } 1485 1486 1487 public Vector <Artist> getArtists(){ return getArtists(false);} 1488 public Vector <Artist> getArtists(boolean sorted) 1489 { 1490 if(sorted) artists_.sort(Artist.ArtistComparatorIgnoreCase ); 1491 return artists_; 1492 } 1493 1494 1495 public String[] getArtistNames(){return getArtistNames(false);} 1496 1497 1498 public String[] getArtistNames(boolean removeSpaces) 1499 { 1500 String [] retVal = new String[artists_.size()]; 1501 for(int i=0;i<artists_.size();i++){retVal[i]=artists_.get(i).artistName(removeSpaces);} 1502 return retVal; 1503 } 1504 1505 1506 public int getNumberOfArtists() {return artists_.size(); } 1507 1508 1509 public int getNumberOfAlbums() 1510 { 1511 int retVal = 0; 1512 for(int i=0;i<artists_.size();i++){retVal+=artists_.get(i).getNumberOfAlbums();} 1513 return retVal; 1514 } 1515 1516 1517 public int getNumberOfAlbums(String artist) 1518 { 1519 int retVal = 0; 1520 // not implemented 1521 //for(int i=0;i<artists_.size();i++){retVal+=artists_.get(i).getNumberOfAlbums();} 1522 return retVal; 1523 } 1524 1525 1526 public int getNumberOfSongs() 1527 { 1528 int retVal = 0; 1529 for(int i=0;i<artists_.size();i++){retVal+=artists_.get(i).getNumberOfSongs();} 1530 return retVal; 1531 } 1532 1533 1534 /** 1535 * Set Method for class field 'tunesSubPath_'. 1536 * 1537 * @param tunesSubPath is the value to set this class field to. 1538 * 1539 **/ 1540 public static void setTunesSubPath(String tunesSubPath) 1541 { 1542 tunesSubPath_ = tunesSubPath; 1543 } // setTunesSubPath Method 1544 1545 1546 /** 1547 * Get Method for class field 'tunesSubPath_'. 1548 * 1549 * @return String - The value the class field 'tunesSubPath_'. 1550 * 1551 **/ 1552 public static String getTunesSubPath() 1553 { 1554 return tunesSubPath_; 1555 } // getTunesSubPath Method 1556 1557 1558 /** 1559 * Gets the full file path to the tunes dir. 1560 * 1561 * @return String - the full file path to the tunes dir. 1562 * 1563 **/ 1564 public String getTunesDirPath() 1565 { 1566 return tunesRootPath_; 1567 } // getWebappHomePath Method 1568 1569 1570 /** Performs some simple removal of extra line seperators. **/ 1571 private String cleanJSON(StringBuilder sb) 1572 { 1573 String retVal = sb.toString(); 1574 retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+" ,", ","); 1575 retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+" ,", ","); 1576 retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+" ,", ","); 1577 retVal = Util.tokenReplace(retVal, ","+SYSTEM_LINE_SEPERATOR+",", ","); 1578 return retVal; 1579 } 1580 1581 1582 /** Lists all songs in all artists albums in a JSON string. 1583 <pre> 1584 [ 1585 { 1586 url: "http://warp4.webarts.bc.ca/tunes/mythTunes/3DoorsDown/3DoorsDown/3DoorsDown03-It'sNotMyTime.ogg", 1587 file: "3DoorsDown03-It'sNotMyTime.ogg", 1588 title: "It'sNotMyTime", 1589 album: "3DoorsDown", 1590 artist: "3DoorsDown", 1591 number: "03", 1592 index: "26" 1593 }, 1594 { 1595 url: "http://warp4.webarts.bc.ca/tunes/mythTunes/3DoorsDown/3DoorsDown/3DoorsDown04-LetMeBeMyself.ogg", 1596 file: "3DoorsDown04-LetMeBeMyself.ogg", 1597 title: "LetMeBeMyself", 1598 album: "3DoorsDown", 1599 artist: "3DoorsDown", 1600 number: "04", 1601 index: "27" 1602 }, 1603 { 1604 url: "http://warp4.webarts.bc.ca/tunes/mythTunes/3DoorsDown/3DoorsDown/3DoorsDown05-Pages.ogg", 1605 file: "3DoorsDown05-Pages.ogg", 1606 title: "Pages", 1607 album: "3DoorsDown", 1608 artist: "3DoorsDown", 1609 number: "05", 1610 index: "28" 1611 } 1612 ] 1613 </pre> 1614 **/ 1615 public String toJsonString() 1616 { 1617 StringBuilder retVal = new StringBuilder("["); 1618 int songCount = 0; int artistCount = 0; int tot = artists_.size(); 1619 retVal.append(SYSTEM_LINE_SEPERATOR); 1620 1621 for(Artist currArtist : artists_) 1622 { 1623 if(currArtist.getNumberOfSongs()>0) 1624 { 1625 retVal.append(currArtist.toJsonString(songCount)); 1626 if(++artistCount<tot)retVal.append(" ,"); // End Artist "+ currArtist.name(true)); 1627 retVal.append(SYSTEM_LINE_SEPERATOR); 1628 songCount+=currArtist.getNumberOfSongs(); 1629 } 1630 else ++artistCount; 1631 } 1632 retVal.append("]"); 1633 return cleanJSON(retVal); 1634 } 1635 1636} 1637 1638 1639/* *************************************** */ 1640/** 1641 * DirFileRef a Template/super class Deserialized Object for the MusicMaker music directories JSON meta data - (use it to be extended for specific subdirectories) . 1642 * 1643 * This class included 2 enums to represent a {@link DirFileRef.DirType DirType} and a {@link DirFileRef.DirState DirState } for use by this object or {@link DirFileRef.DirType DirType} and a {@link MusicMakerTunesHelper MusicMakerTunesHelper }MusicMaker.<br> 1644 * The JSON this is representing is as Follows:<pre> 1645 * { 1646 * "dirFile": "/home/tgutwin/Music", 1647 * "dirType": "TOPDIR", 1648 * "dirState": "LONG", 1649 * "refKey": "0" 1650 * } 1651 * </pre> 1652 * NOTE: that the dirType and dirState class vars are represented with the {@link DirFileRef.DirType DirType} and a {@link DirFileRef.DirState DirState } enum types within this super class. 1653 **/ 1654class DirFileRef 1655{ 1656 /** An enum TYPE for the allowed Directory Types defining the TYPE for the dirType class var. **/ 1657 public enum DirType 1658 { 1659 UNDEFINED (0), //calls constructor with value 0 step 1660 TOPDIR (1), //calls constructor with value 1 step 1661 SNDROOT (2), //calls constructor with value 2 1662 ARTIST (4), //calls constructor with value 4 1663 ALBUM (8), //calls constructor with value 8 1664 RELEASE (16), //calls constructor with value 16 1665 ; // semicolon needed when fields / methods follow 1666 public final int type ; 1667 public final String typeStr ; 1668 private DirType(int type) { 1669 switch (type) { 1670 case 1: this.type = type;this.typeStr = "TOPDIR"; break; 1671 case 2: this.type = type;this.typeStr = "SNDROOT"; break; 1672 case 4: this.type = type;this.typeStr = "ARTIST"; break; 1673 case 8: this.type = type;this.typeStr = "ALBUM"; break; 1674 case 16: this.type = type;this.typeStr = "RELEASE"; break; 1675 default: this.type = 0; this.typeStr = "UNDEFINED"; 1676 } 1677 } 1678 private DirType(String typeStr) { 1679 switch (typeStr) { 1680 case "TOPDIR": this.type = 1; this.typeStr = typeStr; break; 1681 case "SNDROOT": this.type = 2; this.typeStr = typeStr; break; 1682 case "ARTIST": this.type = 4; this.typeStr = typeStr; break; 1683 case "ALBUM": this.type = 8; this.typeStr = typeStr; break; 1684 case "RELEASE": this.type = 16; this.typeStr = typeStr; break; 1685 default: this.type = 0; this.typeStr = "UNDEFINED"; 1686 } 1687 } 1688 public int getType() { 1689 return this.type; 1690 } 1691 public String getTypeStr() { 1692 return this.typeStr; 1693 } 1694 } 1695 1696 /** An Enum for the allowed states for the directory file - either long or short. It is used to defining the TYPE for the dirState class var. 1697 **/ 1698 public enum DirState 1699 { 1700 UNDEFINED (0), //calls constructor with value 0 step 1701 SHORT (1), //calls constructor with value 1 step 1702 LONG (2), //calls constructor with value 2 1703 ; // semicolon needed when fields / methods follow 1704 public final int state; 1705 public final String stateStr ; 1706 private DirState(int state) { 1707 switch (state) { 1708 case 1: this.state = state;this.stateStr = "SHORT"; break; 1709 case 2: this.state = state;this.stateStr = "LONG"; break; 1710 default: this.state = 0;this.stateStr = "UNDEFINED"; 1711 } 1712 } 1713 /*private DirState(String stateStr) { 1714 switch (stateStr) { 1715 case "SHORT": this.state = SHORT; break; 1716 case "LONG": this.state = LONG; break; 1717 default: this.state = UNDEFINED; 1718 } 1719 }*/ 1720 public int getState() { 1721 return this.state; 1722 } 1723 public String getStateStr() { 1724 return this.stateStr; 1725 } 1726 } 1727 1728 String refKey = ""; 1729 String dirFile = ""; 1730 DirType dirType = DirType.UNDEFINED; 1731 DirState dirState = DirState.UNDEFINED; 1732 1733 1734 /** Constructs with default values - UNDEFINED. **/ 1735 public DirFileRef(){ } 1736 /** Constructs with passed in values . **/ 1737 public DirFileRef(String refKey, String dirFile, DirType dirType, DirState dirState) 1738 { 1739 this.refKey=refKey; 1740 this.dirFile=dirFile; 1741 this.dirType=dirType; 1742 this.dirState=dirState; 1743 } 1744 1745 1746 public void setRefKey(String refKey){this.refKey = refKey;} 1747 public String getRefKey(){return refKey;} 1748 public void setDirFile(String dirFile){this.dirFile = dirFile;} // setDirFile Method 1749 public String getDirFile(){return dirFile;} // getDirFile Method 1750 public void setDirType(DirType dirType){this.dirType = dirType;} 1751 public DirType getDirType(){return dirType;} 1752 public void setDirState(DirState dirState){this.dirState = dirState;} 1753 public DirState getDirState(){return dirState;} 1754 1755 @Override 1756 public String toString() 1757 { 1758 String retVal = ""; 1759 Gson gson = new GsonBuilder() 1760 .setPrettyPrinting() 1761 .create(); 1762 retVal = gson.toJson(this); 1763 return retVal; 1764 } 1765} 1766 1767 1768/** The Deserialized object for the MusicMaker Top directory. It extends the Base/Super DirFileRef class. 1769 * 1770 * The JSON this is representing is as Follows:<pre> 1771 * { 1772 * "dirFile": "/home/tgutwin/Music", 1773 * "dirType": "TOPDIR", 1774 * "dirState": "LONG", 1775 * "refKey": "0", 1776 * "numSndDirs": 2, 1777 * "sndDirs": [ 1778 * { 1779 * "refKey": "0", 1780 * "dirFile": "ogg", 1781 * "dirType": "SNDROOT", 1782 * "dirState": "LONG" 1783 * }, 1784 * { 1785 * "refKey": "1", 1786 * "dirFile": "mp3", 1787 * "dirType": "SNDROOT", 1788 * "dirState": "LONG" 1789 * } 1790 * ] 1791 * } 1792 * </pre> 1793 **/ 1794class TopSndDirMetadata extends DirFileRef 1795{ 1796 public int numSndDirs = 0; 1797 public DirFileRef [] sndDirs = null; 1798 1799 1800 public TopSndDirMetadata(){ } 1801 public TopSndDirMetadata(String refKey, String dirFile, DirFileRef.DirType dirType, DirFileRef.DirState dirState, int numSndDirs, DirFileRef [] sndDirs) 1802 { 1803 super(refKey, dirFile, dirType, dirState); 1804 1805 this.dirType=DirFileRef.DirType.TOPDIR; // overRide the default 1806 this.numSndDirs=numSndDirs; 1807 this.sndDirs=sndDirs; 1808 } 1809 1810 public void setNumSndDirs(int numSndDirs){this.numSndDirs = numSndDirs;} 1811 public int getNumSndDirs(){return numSndDirs;} 1812 public void setSndDirs(DirFileRef [] sndDirs){this.sndDirs = sndDirs;} 1813 public DirFileRef [] getSndDirs(){return sndDirs;} 1814 1815 @Override 1816 public String toString() 1817 { 1818 String retVal = ""; 1819 Gson gson = new GsonBuilder() 1820 .setPrettyPrinting() 1821 .create(); 1822 retVal = gson.toJson(this); 1823 return retVal; 1824 } 1825} 1826 1827 1828/** The Deserialized object for the MusicMaker SND directory (typically ogg, mp3 or flac sub-dir inside the TOP SND DIR. It extends the Base/Super DirFileRef class. */ 1829class SndDirMetadata extends DirFileRef 1830{ 1831 public int numArtist = 0; 1832 public ArtistDirRef [] artists = null; 1833 1834 public SndDirMetadata(){ } 1835 public SndDirMetadata(String refKey, String dirFile, DirFileRef.DirType dirType, DirFileRef.DirState dirState, int numArtist, ArtistDirRef [] artists) 1836 { 1837 super(refKey, dirFile, dirType, dirState); 1838 1839 this.dirType=DirFileRef.DirType.SNDROOT; 1840 this.numArtist=numArtist; 1841 this.artists=artists; 1842 } 1843 1844 public void setNumArtists(int numArtist){this.numArtist = numArtist;} 1845 public int getNumArtists(){return numArtist;} 1846 public void setArtists(ArtistDirRef [] artists){this.artists = artists;} 1847 public ArtistDirRef [] getArtists(){return artists;} 1848 1849 @Override 1850 public String toString() 1851 { 1852 String retVal = ""; 1853 Gson gson = new GsonBuilder() 1854 .setPrettyPrinting() 1855 .create(); 1856 retVal = gson.toJson(this); 1857 return retVal; 1858 } 1859} // SndDirMetadata class 1860 1861 1862class ArtistDirRef extends DirFileRef 1863{ 1864 String artistName = ""; 1865 String shortArtistName = ""; 1866 String urlPath = ""; 1867 String musicBrainzID = ""; 1868 int numAlbums = 0; 1869 public AlbumDirRef [] albums = null; 1870 1871 public ArtistDirRef(){ } 1872 public ArtistDirRef(String refKey, String dirFile, DirFileRef.DirType dirType, DirFileRef.DirState dirState, 1873 String artistName, String shortArtistName, String urlPath, String musicBrainzID , 1874 int numAlbums, AlbumDirRef [] albums) 1875 { 1876 super(refKey, dirFile, dirType, dirState); 1877 1878 this.dirType=DirFileRef.DirType.ARTIST; 1879 this.artistName=artistName; 1880 this.shortArtistName=shortArtistName; 1881 this.urlPath=urlPath; 1882 this.musicBrainzID=musicBrainzID; 1883 this.numAlbums=numAlbums; 1884 this.albums=albums; 1885 } 1886 1887 public void setArtistName(String artistName){this.artistName = artistName;} 1888 public String getArtistName(){return artistName;} 1889 public void setShortArtistName(String shortArtistName){this.shortArtistName = shortArtistName;} 1890 public String getShortArtistName(){return shortArtistName;} 1891 public void setUrlPath(String urlPath){this.urlPath = urlPath;} 1892 public String getUrlPath(){return urlPath;} 1893 public void setNumAlbums(int numAlbums){this.numAlbums = numAlbums;} 1894 public int getNumAlbums(){return numAlbums;} 1895 public void setAlbums(AlbumDirRef [] albums){this.albums = albums;} 1896 public AlbumDirRef [] getAlbums(){return albums;} 1897 1898 @Override 1899 public String toString() 1900 { 1901 String retVal = ""; 1902 Gson gson = new GsonBuilder() 1903 .setPrettyPrinting() 1904 .create(); 1905 retVal = gson.toJson(this); 1906 return retVal; 1907 } 1908} 1909 1910 1911class AlbumDirRef extends DirFileRef 1912{ 1913 String albumName = ""; 1914 String shortAlbumName = ""; 1915 String musicBrainzID = ""; 1916 String artistRefKey = ""; 1917 int numSongs = 0; 1918 public SongRef [] songs = null; 1919 1920 public AlbumDirRef(){ } 1921 public AlbumDirRef(String refKey, String dirFile, DirFileRef.DirType dirType, DirFileRef.DirState dirState, 1922 String albumName, String shortAlbumName, String musicBrainzID , 1923 String artistRefKey, 1924 int numAlbums, SongRef [] songs) 1925 { 1926 super(refKey, dirFile, dirType, dirState); 1927 1928 this.dirType=DirFileRef.DirType.ARTIST; // over-ride to force this to ARTIST 1929 this.dirType=DirFileRef.DirType.ARTIST; // over-ride to force this to ARTIST 1930 this.albumName=albumName; 1931 this.shortAlbumName=shortAlbumName; 1932 this.musicBrainzID=musicBrainzID; 1933 this.artistRefKey=artistRefKey; 1934 this.numSongs=numSongs; 1935 this.songs=songs; 1936 } 1937 1938 public void setAlbumName(String albumName){this.albumName = albumName;} 1939 public String getAlbumName(){return albumName;} 1940 public void setShortAlbumName(String shortAlbumName){this.shortAlbumName = shortAlbumName;} 1941 public String getShortAlbumName(){return shortAlbumName;} 1942 public void setMusicBrainzID(String musicBrainzID){this.musicBrainzID = musicBrainzID;} 1943 public String getMusicBrainzID(){return musicBrainzID;} 1944 public void setArtistRefKey(String artistRefKey){this.artistRefKey = artistRefKey;} 1945 public String getArtistRefKey(){return artistRefKey;} 1946 public void setNumSongs(int numSongs){this.numSongs = numSongs;} 1947 public int getNumSongs(){return numSongs;} 1948 public void setSongs(SongRef [] songs){this.songs = songs;} 1949 public SongRef [] getSongs(){return songs;} 1950 1951 @Override 1952 public String toString() 1953 { 1954 String retVal = ""; 1955 Gson gson = new GsonBuilder() 1956 .setPrettyPrinting() 1957 .create(); 1958 retVal = gson.toJson(this); 1959 return retVal; 1960 } 1961} 1962 1963 1964class SongRef extends DirFileRef 1965{ 1966 String title = ""; 1967 int trackNum = 0; 1968 String musicBrainzID = ""; 1969 1970 public SongRef(){ } 1971 public SongRef(String refKey, String dirFile, DirFileRef.DirType dirType, DirFileRef.DirState dirState, 1972 String title, int trackNum, String musicBrainzID ) 1973 { 1974 super(refKey, dirFile, dirType, dirState); 1975 1976 this.dirType=DirFileRef.DirType.ARTIST; 1977 this.title=title; 1978 this.trackNum=trackNum; 1979 this.musicBrainzID=musicBrainzID; 1980 } 1981 1982 public void setTitle(String title){this.title = title;} 1983 public String getTitle(){return title;} 1984 public void setMusicBrainzID(String musicBrainzID){this.musicBrainzID = musicBrainzID;} 1985 public String getMusicBrainzID(){return musicBrainzID;} 1986 public void setTrackNum(int trackNum){this.trackNum = trackNum;} 1987 public int getTrackNum(){return trackNum;} 1988 1989 @Override 1990 public String toString() 1991 { 1992 String retVal = ""; 1993 Gson gson = new GsonBuilder() 1994 .setPrettyPrinting() 1995 .create(); 1996 retVal = gson.toJson(this); 1997 return retVal; 1998 } 1999} 2000 2001