package com.quiltplayer.core.scanner.impl; import java.io.IOException; import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; import java.util.Stack; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.quiltplayer.core.scanner.CoverScanner; import com.quiltplayer.core.scanner.ScanningEvent; import com.quiltplayer.core.scanner.ScanningEvent.Scanner; import com.quiltplayer.core.scanner.ScanningEvent.Status; import com.quiltplayer.core.storage.ArtistStorage; import com.quiltplayer.core.storage.Storage; import com.quiltplayer.external.covers.DiscogsScanner; import com.quiltplayer.external.covers.exception.RequestOverFlowException; import com.quiltplayer.external.covers.model.LocalImage; import com.quiltplayer.model.Album; import com.quiltplayer.properties.Configuration; import com.quiltplayer.view.swing.listeners.ScanningListener; /** * Default implementation of CollectionScanner. Scans the whole collection. TODO Refactor and split * so the pool is in a other class with ability to know when all threads are done. * * @author Vlado Palczynski */ @Component public class DiscogsCoverScanner implements CoverScanner { private Logger log = Logger.getLogger(DiscogsCoverScanner.class); private static final int THREADS = 10; private List<Thread> threadPool; @Autowired private DiscogsScanner discogsScanner; @Autowired private Storage storage; @Autowired private ArtistStorage artistStorage; @Autowired private ScanningListener scanningListener; protected Stack<Album> albumsToScan; private boolean scanOneAlbum = false; /** * @param scanOneAlbum * the scanOneAlbum to set */ public void setScanOneAlbum(boolean scanOneAlbum) { this.scanOneAlbum = scanOneAlbum; } /* * @see java.lang.Runnable#run() */ @Override public void run() { boolean b = true; Album album = null; while (b) { album = getAlbum(); if (album != null) { // Only scan albums without covers, the other should be scanned // individually if (scanOneAlbum || album.getImages() != null && album.getImages().size() < 2) { System.out.println("!!!!"); scanOneAlbum = false; try { log.debug("Searching for images...."); com.quiltplayer.external.covers.discogs.Album discogsAlbum = discogsScanner.scanForAlbum(album .getArtist().getArtistName().getName(), album.getTitle(), album.getSongCollection() .getSongs().size(), Configuration.getInstance().getFolderProperties().getCovers()); if (discogsAlbum != null) assemble(album, discogsAlbum); } catch (RequestOverFlowException e) { /* Quit */ log.debug("Maximum requests, interrupting thread..."); b = false; } catch (Exception e) { e.printStackTrace(); } } } else b = false; } } /** * */ private void assemble(Album album, com.quiltplayer.external.covers.discogs.Album discogsAlbum) { try { bindImagesToAlbum(album, discogsAlbum); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } album.setYear(discogsAlbum.getYear()); if (discogsAlbum.getLabels() != null && discogsAlbum.getLabels().size() > 0) album.setLabel(discogsAlbum.getLabels().get(0).getName()); } /** * Create images. * * @param album * @param selectedRelease * @throws MalformedURLException * @throws IOException */ private void bindImagesToAlbum(final Album album, final com.quiltplayer.external.covers.discogs.Album discogsAlbum) throws MalformedURLException, IOException { if (discogsAlbum.getImages() != null) { if (discogsAlbum.getImages().size() == 1 && album.getImages() != null && album.getImages().size() == 1) { // Don't replace 1 already set album cover... } else if (discogsAlbum.getImages().size() > 0) { album.deleteImages(); for (LocalImage localImage : discogsAlbum.getImages()) { // Indexing in neo split on some chars. String fileName = localImage.getLargeImage().getName().replace("-", "").replace(".", ""); LocalImage storageImage = storage.getLocalImage(fileName); if (storageImage == null) { storageImage = storage.createLocalImage(album, fileName, localImage); } } } } } /* * @see org.coverrock.CollectionScanner#scanCollection() */ @Override public void scanCovers() { albumsToScan = storage.getAlbumsAsStack(artistStorage.getArtists()); threadPool = new ArrayList<Thread>(); scanningListener.scannerEvent(new ScanningEvent(Status.STARTED, Scanner.COVERS)); for (int i = 0; i < THREADS; i++) { DiscogsCoverScanner das = new DiscogsCoverScanner(); das.artistStorage = artistStorage; das.discogsScanner = discogsScanner; das.storage = storage; das.setAlbumsToScan(albumsToScan); Thread thread = new Thread(das); threadPool.add(thread); thread.start(); log.debug("Thread " + thread.getId() + " is starting..."); } } /* * @see org.coverrock.CollectionScanner#scanCollection() */ @Override public void scanCovers(Album album) { log.debug("Settng album to scan; " + album); albumsToScan = new Stack<Album>(); albumsToScan.push(album); threadPool = new ArrayList<Thread>(); for (int i = 0; i < 1; i++) { DiscogsCoverScanner dcs = new DiscogsCoverScanner(); dcs.setScanOneAlbum(true); dcs.artistStorage = artistStorage; dcs.discogsScanner = discogsScanner; dcs.storage = storage; dcs.setAlbumsToScan(albumsToScan); Thread thread = new Thread(dcs); threadPool.add(thread); thread.start(); log.debug("Thread " + thread.getId() + " is starting..."); } } private synchronized Album getAlbum() { if (!albumsToScan.isEmpty()) return albumsToScan.pop(); return null; } /* * (non-Javadoc) * * @see org.quiltplayer.core.scanner.CoverScanner#cancelScanCovers() */ @Override public void cancelScanCovers() { scanningListener.scannerEvent(new ScanningEvent(Status.DONE, Scanner.COVERS)); for (Thread thread : threadPool) { thread.stop(); System.out.println("Thread " + thread.getId() + " is stopped."); } } /** * @param albumsToScan * the albumsToScan to set */ public final void setAlbumsToScan(Stack<Album> albumsToScan) { this.albumsToScan = albumsToScan; } }