コード例 #1
0
ファイル: CacheDao.java プロジェクト: endthestart/supersonic
  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);
    }
  }
コード例 #2
0
 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);
   }
 }
コード例 #3
0
 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);
   }
 }
コード例 #4
0
  /**
   * 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;
  }
コード例 #5
0
 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);
   }
 }
コード例 #6
0
  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;
  }
コード例 #7
0
 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);
   }
 }
コード例 #8
0
 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);
   }
 }
コード例 #9
0
ファイル: CacheDao.java プロジェクト: endthestart/supersonic
  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();
    }
  }
コード例 #10
0
  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;
  }
コード例 #11
0
  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;
    }
  }
コード例 #12
0
  /**
   * 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;
  }
コード例 #13
0
  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;
  }