Beispiel #1
0
SongLoader::Result SongLoader::LoadLocal(const QString& filename) {
  qLog(Debug) << "Loading local file" << filename;

  // Search in the database.
  QUrl url = QUrl::fromLocalFile(filename);

  LibraryQuery query;
  query.SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
  query.AddWhere("filename", url.toEncoded());

  if (library_->ExecQuery(&query) && query.Next()) {
    // we may have many results when the file has many sections
    do {
      Song song;
      song.InitFromQuery(query, true);

      if (song.is_valid()) {
        songs_ << song;
      }
    } while (query.Next());

    return Success;
  }

  // It's not in the database, load it asynchronously.
  preload_func_ = std::bind(&SongLoader::LoadLocalAsync, this, filename);
  return BlockingLoadRequired;
}
SongList AlbumCoverManager::GetSongsInAlbum(const QModelIndex& index) const {
  SongList ret;

  LibraryQuery q;
  q.SetColumnSpec("ROWID," + Song::kColumnSpec);
  q.AddWhere("album", index.data(Role_AlbumName).toString());
  q.SetOrderBy("disc, track, title");

  QString artist = index.data(Role_ArtistName).toString();
  q.AddCompilationRequirement(artist.isEmpty());
  if (!artist.isEmpty()) q.AddWhere("artist", artist);

  if (!library_backend_->ExecQuery(&q)) return ret;

  while (q.Next()) {
    Song song;
    song.InitFromQuery(q, true);
    ret << song;
  }
  return ret;
}
SongLoader::Result SongLoader::LoadLocal(const QString& filename) {
  qLog(Debug) << "Loading local file" << filename;

  // First check to see if it's a directory - if so we can load all the songs
  // inside right away.
  if (QFileInfo(filename).isDir()) {
    ConcurrentRun::Run<void>(
        &thread_pool_,
        std::bind(&SongLoader::LoadLocalDirectoryAndEmit, this, filename));
    return WillLoadAsync;
  }

  // It's a local file, so check if it looks like a playlist.
  // Read the first few bytes.
  QFile file(filename);
  if (!file.open(QIODevice::ReadOnly)) return Error;
  QByteArray data(file.read(PlaylistParser::kMagicSize));

  ParserBase* parser = playlist_parser_->ParserForMagic(data);
  if (!parser) {
    // Check the file extension as well, maybe the magic failed, or it was a
    // basic M3U file which is just a plain list of filenames.
    parser = playlist_parser_->ParserForExtension(QFileInfo(filename).suffix());
  }

  if (parser) {
    qLog(Debug) << "Parsing using" << parser->name();

    // It's a playlist!
    ConcurrentRun::Run<void>(
        &thread_pool_,
        std::bind(&SongLoader::LoadPlaylistAndEmit, this, parser, filename));
    return WillLoadAsync;
  }

  // Not a playlist, so just assume it's a song
  QUrl url = QUrl::fromLocalFile(filename);

  LibraryQuery query;
  query.SetColumnSpec("%songs_table.ROWID, " + Song::kColumnSpec);
  query.AddWhere("filename", url.toEncoded());

  SongList song_list;

  if (library_->ExecQuery(&query) && query.Next()) {
    // we may have many results when the file has many sections
    do {
      Song song;
      song.InitFromQuery(query, true);

      song_list << song;
    } while (query.Next());
  } else {
    QString matching_cue = filename.section('.', 0, -2) + ".cue";

    if (QFile::exists(matching_cue)) {
      // it's a cue - create virtual tracks
      QFile cue(matching_cue);
      cue.open(QIODevice::ReadOnly);

      song_list = cue_parser_->Load(&cue, matching_cue,
                                    QDir(filename.section('/', 0, -2)));
    } else {
      // it's a normal media file, load it asynchronously.
      TagReaderReply* reply = TagReaderClient::Instance()->ReadFile(filename);
      NewClosure(reply, SIGNAL(Finished(bool)), this,
                 SLOT(LocalFileLoaded(TagReaderReply*)), reply);

      return WillLoadAsync;
    }
  }

  for (const Song& song : song_list) {
    if (song.is_valid()) {
      songs_ << song;
    }
  }

  return Success;
}