public CacheDao() { File subsonicHome = SettingsService.getSubsonicHome(); File dbDir = new File(subsonicHome, "cache"); dbFile = new File(dbDir, "cache.dat"); if (!dbDir.exists()) { dbDir.mkdirs(); } // if (dbFile.exists()) { // try { // Defragment.defrag(dbFile.getPath()); // }catch (IOException e) { // e.printStackTrace(); // } // } try { openDatabase(dbFile); } catch (Throwable x) { LOG.error("Failed to open " + dbFile + ", deleting it: " + x); dbFile.delete(); openDatabase(dbFile); } }
public void index(Album album) { try { albumId3Writer.addDocument(ALBUM_ID3.createDocument(album)); } catch (Exception x) { LOG.error("Failed to create search index for " + album, x); } }
public void index(Artist artist, MusicFolder musicFolder) { try { artistId3Writer.addDocument(ARTIST_ID3.createDocument(artist, musicFolder)); } catch (Exception x) { LOG.error("Failed to create search index for " + artist, x); } }
/** * Returns a number of random songs. * * @param criteria Search criteria. * @return List of random songs. */ public List<MediaFile> getRandomSongs(RandomSearchCriteria criteria) { List<MediaFile> result = new ArrayList<MediaFile>(); IndexReader reader = null; try { reader = createIndexReader(SONG); Searcher searcher = new IndexSearcher(reader); BooleanQuery query = new BooleanQuery(); query.add( new TermQuery(new Term(FIELD_MEDIA_TYPE, MediaFile.MediaType.MUSIC.name().toLowerCase())), BooleanClause.Occur.MUST); if (criteria.getGenre() != null) { String genre = normalizeGenre(criteria.getGenre()); query.add(new TermQuery(new Term(FIELD_GENRE, genre)), BooleanClause.Occur.MUST); } if (criteria.getFromYear() != null || criteria.getToYear() != null) { NumericRangeQuery<Integer> rangeQuery = NumericRangeQuery.newIntRange( FIELD_YEAR, criteria.getFromYear(), criteria.getToYear(), true, true); query.add(rangeQuery, BooleanClause.Occur.MUST); } List<SpanTermQuery> musicFolderQueries = new ArrayList<SpanTermQuery>(); for (MusicFolder musicFolder : criteria.getMusicFolders()) { musicFolderQueries.add( new SpanTermQuery(new Term(FIELD_FOLDER, musicFolder.getPath().getPath()))); } query.add( new SpanOrQuery(musicFolderQueries.toArray(new SpanQuery[musicFolderQueries.size()])), BooleanClause.Occur.MUST); TopDocs topDocs = searcher.search(query, null, Integer.MAX_VALUE); List<ScoreDoc> scoreDocs = Lists.newArrayList(topDocs.scoreDocs); Random random = new Random(System.currentTimeMillis()); while (!scoreDocs.isEmpty() && result.size() < criteria.getCount()) { int index = random.nextInt(scoreDocs.size()); Document doc = searcher.doc(scoreDocs.remove(index).doc); int id = Integer.valueOf(doc.get(FIELD_ID)); try { addIfNotNull(mediaFileService.getMediaFile(id), result); } catch (Exception x) { LOG.warn("Failed to get media file " + id); } } } catch (Throwable x) { LOG.error("Failed to search or random songs.", x); } finally { FileUtil.closeQuietly(reader); } return result; }
public void startIndexing() { try { artistWriter = createIndexWriter(ARTIST); artistId3Writer = createIndexWriter(ARTIST_ID3); albumWriter = createIndexWriter(ALBUM); albumId3Writer = createIndexWriter(ALBUM_ID3); songWriter = createIndexWriter(SONG); } catch (Exception x) { LOG.error("Failed to create search index.", x); } }
private synchronized File getImageCacheDirectory(int size) { File dir = new File(SettingsService.getSubsonicHome(), "thumbs"); dir = new File(dir, String.valueOf(size)); if (!dir.exists()) { if (dir.mkdirs()) { LOG.info("Created thumbnail cache " + dir); } else { LOG.error("Failed to create thumbnail cache " + dir); } } return dir; }
public void index(MediaFile mediaFile) { try { if (mediaFile.isFile()) { songWriter.addDocument(SONG.createDocument(mediaFile)); } else if (mediaFile.isAlbum()) { albumWriter.addDocument(ALBUM.createDocument(mediaFile)); } else { artistWriter.addDocument(ARTIST.createDocument(mediaFile)); } } catch (Exception x) { LOG.error("Failed to create search index for " + mediaFile, x); } }
public void stopIndexing() { try { artistWriter.optimize(); artistId3Writer.optimize(); albumWriter.optimize(); albumId3Writer.optimize(); songWriter.optimize(); } catch (Exception x) { LOG.error("Failed to create search index.", x); } finally { FileUtil.closeQuietly(artistId3Writer); FileUtil.closeQuietly(artistWriter); FileUtil.closeQuietly(albumWriter); FileUtil.closeQuietly(albumId3Writer); FileUtil.closeQuietly(songWriter); } }
public CacheElement getCacheElement(int type, String key) { dbLock.readLock().lock(); try { ObjectSet<CacheElement> result = db.query(new CacheElementPredicate(type, key)); if (result.size() > 1) { LOG.error( "Programming error. Got " + result.size() + " cache elements of type " + type + " and key " + key); } return result.isEmpty() ? null : result.get(0); } finally { dbLock.readLock().unlock(); } }
private long getFileLength(TranscodingService.Parameters parameters) { MediaFile file = parameters.getMediaFile(); if (!parameters.isDownsample() && !parameters.isTranscode()) { return file.getFileSize(); } Integer duration = file.getDurationSeconds(); Integer maxBitRate = parameters.getMaxBitRate(); if (duration == null) { LOG.warn("Unknown duration for " + file + ". Unable to estimate transcoded size."); return file.getFileSize(); } if (maxBitRate == null) { LOG.error("Unknown bit rate for " + file + ". Unable to estimate transcoded size."); return file.getFileSize(); } return duration * maxBitRate * 1000L / 8L; }
private LongRange parseAndConvertOffsetSeconds(String offsetSeconds, MediaFile file) { if (offsetSeconds == null) { return null; } try { Integer duration = file.getDurationSeconds(); Long fileSize = file.getFileSize(); if (duration == null || fileSize == null) { return null; } float offset = Float.parseFloat(offsetSeconds); // Convert from time offset to byte offset. long byteOffset = (long) (fileSize * (offset / duration)); return new LongRange(byteOffset, Long.MAX_VALUE); } catch (Exception x) { LOG.error("Failed to parse and convert time offset: " + offsetSeconds, x); return null; } }
/** * Returns a number of random albums, using ID3 tag. * * @param count Number of albums to return. * @param musicFolders Only return albums from these folders. * @return List of random albums. */ public List<Album> getRandomAlbumsId3(int count, List<MusicFolder> musicFolders) { List<Album> result = new ArrayList<Album>(); IndexReader reader = null; try { reader = createIndexReader(ALBUM_ID3); Searcher searcher = new IndexSearcher(reader); List<SpanTermQuery> musicFolderQueries = new ArrayList<SpanTermQuery>(); for (MusicFolder musicFolder : musicFolders) { musicFolderQueries.add( new SpanTermQuery( new Term(FIELD_FOLDER_ID, NumericUtils.intToPrefixCoded(musicFolder.getId())))); } Query query = new SpanOrQuery(musicFolderQueries.toArray(new SpanQuery[musicFolderQueries.size()])); TopDocs topDocs = searcher.search(query, null, Integer.MAX_VALUE); List<ScoreDoc> scoreDocs = Lists.newArrayList(topDocs.scoreDocs); Random random = new Random(System.currentTimeMillis()); while (!scoreDocs.isEmpty() && result.size() < count) { int index = random.nextInt(scoreDocs.size()); Document doc = searcher.doc(scoreDocs.remove(index).doc); int id = Integer.valueOf(doc.get(FIELD_ID)); try { addIfNotNull(albumDao.getAlbum(id), result); } catch (Exception x) { LOG.warn("Failed to get album file " + id, x); } } } catch (Throwable x) { LOG.error("Failed to search for random albums.", x); } finally { FileUtil.closeQuietly(reader); } return result; }
public SearchResult search( SearchCriteria criteria, List<MusicFolder> musicFolders, IndexType indexType) { SearchResult result = new SearchResult(); int offset = criteria.getOffset(); int count = criteria.getCount(); result.setOffset(offset); IndexReader reader = null; try { reader = createIndexReader(indexType); Searcher searcher = new IndexSearcher(reader); Analyzer analyzer = new SubsonicAnalyzer(); MultiFieldQueryParser queryParser = new MultiFieldQueryParser( LUCENE_VERSION, indexType.getFields(), analyzer, indexType.getBoosts()); BooleanQuery query = new BooleanQuery(); query.add(queryParser.parse(analyzeQuery(criteria.getQuery())), BooleanClause.Occur.MUST); List<SpanTermQuery> musicFolderQueries = new ArrayList<SpanTermQuery>(); for (MusicFolder musicFolder : musicFolders) { if (indexType == ALBUM_ID3 || indexType == ARTIST_ID3) { musicFolderQueries.add( new SpanTermQuery( new Term(FIELD_FOLDER_ID, NumericUtils.intToPrefixCoded(musicFolder.getId())))); } else { musicFolderQueries.add( new SpanTermQuery(new Term(FIELD_FOLDER, musicFolder.getPath().getPath()))); } } query.add( new SpanOrQuery(musicFolderQueries.toArray(new SpanQuery[musicFolderQueries.size()])), BooleanClause.Occur.MUST); TopDocs topDocs = searcher.search(query, null, offset + count); result.setTotalHits(topDocs.totalHits); int start = Math.min(offset, topDocs.totalHits); int end = Math.min(start + count, topDocs.totalHits); for (int i = start; i < end; i++) { Document doc = searcher.doc(topDocs.scoreDocs[i].doc); switch (indexType) { case SONG: case ARTIST: case ALBUM: MediaFile mediaFile = mediaFileService.getMediaFile(Integer.valueOf(doc.get(FIELD_ID))); addIfNotNull(mediaFile, result.getMediaFiles()); break; case ARTIST_ID3: Artist artist = artistDao.getArtist(Integer.valueOf(doc.get(FIELD_ID))); addIfNotNull(artist, result.getArtists()); break; case ALBUM_ID3: Album album = albumDao.getAlbum(Integer.valueOf(doc.get(FIELD_ID))); addIfNotNull(album, result.getAlbums()); break; default: break; } } } catch (Throwable x) { LOG.error("Failed to execute Lucene search.", x); } finally { FileUtil.closeQuietly(reader); } return result; }