Package com.pugh.sockso.web.action.covers

Source Code of com.pugh.sockso.web.action.covers.LocalCoverer

package com.pugh.sockso.web.action.covers;

import com.pugh.sockso.Constants;
import com.pugh.sockso.Properties;
import com.pugh.sockso.Utils;
import com.pugh.sockso.cache.CacheException;
import com.pugh.sockso.db.Database;
import com.pugh.sockso.music.CoverArt;
import com.pugh.sockso.cache.CoverArtCache;

import java.awt.image.BufferedImage;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.ArrayList;
import java.util.HashSet;

import javax.imageio.ImageIO;

import org.apache.log4j.Logger;

public class LocalCoverer extends BaseCoverer {

    private static final Logger log = Logger.getLogger( LocalCoverer.class );
   
    /**
     *  Try to serve a local cover from a well known path
     *
     *  @param itemName
     *
     *  @return
     *
     *  @throws SQLException
     *  @throws IOException
     *
     */

    public boolean serveCover( final String itemName ) throws SQLException, IOException, CacheException {

        final String localPath = getLocalCoverPath( itemName );

        if ( localPath != null ) {
            serveLocalCover( itemName, localPath );
            return true;
        }

        return false;

    }

    /**
     *  serves a local cover that the user has stored with their collection, this
     *  file may be any size so we need to resize it if it's not what we want.
     *
     *  @param itemName
     *  @param localPath
     *
     *  @throws java.io.IOException
     *
     */

    protected void serveLocalCover( final String itemName, final String localPath ) throws IOException, CacheException {

        final Properties p = getProperties();
        final BufferedImage originalImage = ImageIO.read( new File( localPath ) );
        final CoverArt cover = new CoverArt(itemName, originalImage);

        cover.scale(
                (int) p.get(Constants.DEFAULT_ARTWORK_WIDTH, 115),
                (int) p.get(Constants.DEFAULT_ARTWORK_HEIGHT, 115));

        // only cache local cover images if we've been explicitly
        // told to do so (improves performance)

        serveCover(
            cover,
            itemName,
            p.get( Constants.COVERS_CACHE_LOCAL ).equals( Properties.YES )
        );

    }

    /**
     *  returns the filename for local covers.  there are defaults for both
     *  artists ("artist") and albums ("album"), but the user can override this themselves
     *
     *  @param itemName
     *
     *  @return
     *
     */
   
    protected String getLocalCoverFileName( final String itemName ) {

        final Properties p = getProperties();
        final String typeName = isArtist(itemName) ? "artist" : "album";

        return p.get(
            isArtist(itemName) ? Constants.COVERS_ARTIST_FILE : Constants.COVERS_ALBUM_FILE,
            typeName
        );

    }

     /**
     *  looks on the filesystem to see if the user has cover art stored with
     *  their music.  if found it returns the path to the file, otherwise null.
     *  The itemName is the name of the music item, eg. ar123, al456, etc...
     *
     *  @param itemName
     *
     *  @return
     *
     *  @throws SQLException
     *
     */
   
    protected String getLocalCoverPath( final String itemName ) throws SQLException {
      
        final String coverFileName = getLocalCoverFileName( itemName );
        final File[] trackDirs = getLocalCoverDirectories( itemName );
        final File[] possibleCovers = getLocalCoverFiles( trackDirs, coverFileName, isArtist(itemName) );

        for ( final File possibleCover : possibleCovers ) {
            if ( possibleCover.exists() )
                return possibleCover.getAbsolutePath();
        }

        return null;

    }

    /**
     *  determines if an item name (eg. ar123) is an artist
     *
     *  @param itemName
     *
     *  @return
     *
     */
   
    protected boolean isArtist( final String itemName ) {
       
        return itemName != null
            && itemName.length() > 2
            && itemName.substring( 0, 2 ).toLowerCase().equals( "ar" );
       
    }

    /**
     *  returns unique directories associated with an itemName (eg. ar123).  this
     *  is worked out by getting all the tracks for this item, and using the
     *  directory that they're in.
     *
     *  @param itemName (eg. ar123)
     *
     *  @return
     *
     *  @throws java.sql.SQLException
     *
     */
   
    protected File[] getLocalCoverDirectories( final String itemName ) throws SQLException {

        final ArrayList<File> dirs = new ArrayList<File>();

        ResultSet rs = null;
        PreparedStatement st = null;
       
        try {

            final HashSet<String> taken = new HashSet<String>();
            final String type = itemName.substring( 0, 2 );
            final int id = Integer.parseInt( itemName.substring(2) );
            final boolean isArtist = type.equals( "ar" );
            final String typeName = isArtist ? "artist" : "album";
            final String sql = " select t.path as path " +
                               " from tracks t " +
                               " where t." +typeName+ "_id = " +id;
            final Database db = getDatabase();
           
            st = db.prepare( sql );
            rs = st.executeQuery();
       
            while ( rs.next() ) {
                final String path = rs.getString( "path" );
                if ( !taken.contains(path) ) {
                    dirs.add( new File(path) );
                    taken.add( path );
                }
            }
           
        }

        finally {
            Utils.close( rs );
            Utils.close( st );
        }
       
        return dirs.toArray( new File[0] );
       
    }
   
    /**
     *  returns an array of files to test that could possibly be local covers.
     *
     *  @param trackDirs
     *  @param coverFileName
     *
     *  @return
     *
     */

    protected File[] getLocalCoverFiles( final File[] trackDirs, final String coverFileName, final boolean isArtist ) {

        final ArrayList<File> files = new ArrayList<File>();
        final String[] exts = CoverArtCache.CACHE_IMAGE_EXTENSIONS;
        final Properties p = getProperties();

        for ( final File track : trackDirs ) {

            final String[] dirs = {
                track.getParent(),
                isArtist ? track.getParentFile().getParent() : null
            };

            // look for album info in this directory, but artist info in the
            // directory one level up as well (maybe "/My Music/artist/album/"
            // structure)
            for ( final String directory : dirs ) {
                if ( directory == null ) continue; // will be null if album
                for ( final String ext : exts ) {
                    final String path = directory + File.separator + coverFileName + "." + ext;
                    files.add( new File(path) );
                }
            }

            // Should we fallback and search for the first image
            // file in the track folder, regardless of its name ?
            if ( p.get(Constants.COVERS_FILE_FALLBACK).equals(Properties.YES) ) {
                final File fallbackFile = checkForFallbackFile( exts, track );
                if ( fallbackFile != null ) {
                    files.add( fallbackFile );
                }
            }

           
        }

        return files.toArray( new File[0] );
       
    }
   
    /**
     *  Checks for a file in the track directory to use as a fallback
     *
     *  @param files
     *  @param exts
     *  @param track
     *
     */
    protected File checkForFallbackFile( final String[] exts, final File track ) {
       
        final File[] fallbackFiles = track.getParentFile().listFiles(new FileFilter() {
            @Override
            public boolean accept(File f) {
               
                if (f.isFile()) {
                    for (final String ext : exts) {
                        if (f.getName().endsWith(ext)) {
                            return true;
                        }
                    }
                }
               
                return false;
               
            }
        });

        if ( fallbackFiles != null && fallbackFiles.length > 0 ) {
            log.debug("Found " + fallbackFiles.length + " fallback cover files."
                            + " Picking first: " + fallbackFiles[0].getAbsolutePath());
            return fallbackFiles[ 0 ];
        }
       
        return null;

    }

}
TOP

Related Classes of com.pugh.sockso.web.action.covers.LocalCoverer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.