예제 #1
0
void JamendoService::ParseDirectory(QIODevice* device) const {
  int total_count = 0;

  // Bit of a hack: don't update the model while we're parsing the xml
  disconnect(library_backend_, SIGNAL(SongsDiscovered(SongList)),
             library_model_, SLOT(SongsDiscovered(SongList)));
  disconnect(library_backend_, SIGNAL(TotalSongCountUpdated(int)), this,
             SLOT(UpdateTotalSongCount(int)));

  // Delete the database and recreate it.  This is faster than dropping tables
  // or removing rows.
  library_backend_->db()->RecreateAttachedDb("jamendo");

  TrackIdList track_ids;
  SongList songs;
  QXmlStreamReader reader(device);
  while (!reader.atEnd()) {
    reader.readNext();
    if (reader.tokenType() == QXmlStreamReader::StartElement &&
        reader.name() == "artist") {
      songs << ReadArtist(&reader, &track_ids);
    }

    if (songs.count() >= kBatchSize) {
      // Add the songs to the database in batches
      library_backend_->AddOrUpdateSongs(songs);
      InsertTrackIds(track_ids);

      total_count += songs.count();
      songs.clear();
      track_ids.clear();

      // Update progress info
      app_->task_manager()->SetTaskProgress(load_database_task_id_, total_count,
                                            kApproxDatabaseSize);
    }
  }

  library_backend_->AddOrUpdateSongs(songs);
  InsertTrackIds(track_ids);

  connect(library_backend_, SIGNAL(SongsDiscovered(SongList)), library_model_,
          SLOT(SongsDiscovered(SongList)));
  connect(library_backend_, SIGNAL(TotalSongCountUpdated(int)),
          SLOT(UpdateTotalSongCount(int)));

  library_backend_->UpdateTotalSongCount();
}
예제 #2
0
Organise::Organise(TaskManager* task_manager,
                   boost::shared_ptr<MusicStorage> destination,
                   const OrganiseFormat &format, bool copy, bool overwrite,
                   const SongList& songs, bool eject_after)
                     : thread_(NULL),
                       task_manager_(task_manager),
                       transcoder_(new Transcoder(this)),
                       destination_(destination),
                       format_(format),
                       copy_(copy),
                       overwrite_(overwrite),
                       eject_after_(eject_after),
                       task_count_(songs.count()),
                       transcode_suffix_(1),
                       tasks_complete_(0),
                       started_(false),
                       task_id_(0),
                       current_copy_progress_(0)
{
  original_thread_ = thread();

  for (const Song& song : songs) {
    tasks_pending_ << Task(song);
  }
}
예제 #3
0
void WplParser::Save(const SongList& songs, QIODevice* device, const QDir& dir,
                     Playlist::Path path_type) const {
  QXmlStreamWriter writer(device);
  writer.setAutoFormatting(true);
  writer.setAutoFormattingIndent(2);
  writer.writeProcessingInstruction("wpl", "version=\"1.0\"");

  StreamElement smil("smil", &writer);

  {
    StreamElement head("head", &writer);
    WriteMeta("Generator", "Clementine -- " CLEMENTINE_VERSION_DISPLAY,
              &writer);
    WriteMeta("ItemCount", QString::number(songs.count()), &writer);
  }

  {
    StreamElement body("body", &writer);
    {
      StreamElement seq("seq", &writer);
      for (const Song& song : songs) {
        writer.writeStartElement("media");
        writer.writeAttribute("src", URLOrFilename(song.url(), dir, path_type));
        writer.writeEndElement();
      }
    }
  }
}
void SongLoaderInserter::AsyncLoad() {

  // First, quick load raw songs.
  int async_progress = 0;
  int async_load_id = task_manager_->StartTask(tr("Loading tracks"));
  task_manager_->SetTaskProgress(async_load_id, async_progress,
                                 pending_.count());
  for (SongLoader* loader : pending_) {
    loader->LoadFilenamesBlocking();
    task_manager_->SetTaskProgress(async_load_id, ++async_progress);
    songs_ << loader->songs();
  }
  task_manager_->SetTaskFinished(async_load_id);
  emit PreloadFinished();

  // Songs are inserted in playlist, now load them completely.
  async_progress = 0;
  async_load_id = task_manager_->StartTask(tr("Loading tracks info"));
  task_manager_->SetTaskProgress(async_load_id, async_progress, songs_.count());
  SongList songs;
  for (SongLoader* loader : pending_) {
    loader->LoadMetadataBlocking();
    songs << loader->songs();
    task_manager_->SetTaskProgress(async_load_id, songs.count());
  }
  task_manager_->SetTaskFinished(async_load_id);

  // Replace the partially-loaded items by the new ones, fully loaded.
  emit EffectiveLoadFinished(songs);

  deleteLater();
}
TEST_F(ASXParserTest, ParsesSomaFM) {
  QFile somafm(":/testdata/secretagent.asx");
  somafm.open(QIODevice::ReadOnly);

  ASXParser parser(NULL);
  SongList songs = parser.Load(&somafm);

  ASSERT_EQ(4, songs.count());
  EXPECT_EQ("SomaFM: Secret Agent", songs[0].title());
  EXPECT_EQ("Keep us on the air! Click Support SomaFM above!", songs[0].artist());
  EXPECT_EQ(QUrl("http://streamer-ntc-aa03.somafm.com:80/stream/1021"), songs[0].url());
}
예제 #6
0
void PLSParser::Save(const SongList &songs, QIODevice *device, const QDir &dir) const {
    QTextStream s(device);
    s << "[playlist]" << endl;
    s << "Version=2" << endl;
    s << "NumberOfEntries=" << songs.count() << endl;

    int n = 1;
    foreach (const Song& song, songs) {
        s << "File" << n << "=" << URLOrRelativeFilename(song.url(), dir) << endl;
        s << "Title" << n << "=" << song.title() << endl;
        s << "Length" << n << "=" << song.length_nanosec() / kNsecPerSec << endl;
        ++n;
    }
예제 #7
0
void Playlist::removeAllCDTracks(void)
{
    // find the cd tracks
    SongList cdTracks;
    for (int x = 0; x < m_songs.count(); x++)
    {
        if (m_songs.at(x)->isCDTrack())
            cdTracks.append(m_songs.at(x));
    }

    // remove the tracks from our lists
    for (int x = 0; x < cdTracks.count(); x++)
    {
        m_songs.removeAll(cdTracks.at(x));
        m_songMap.remove(cdTracks.at(x)->ID());
        m_shuffledSongs.removeAll(cdTracks.at(x));;
    }

    changed();
}
예제 #8
0
void SpotifyService::SearchResults(
    const pb::spotify::SearchResponse& response) {
  if (QStringFromStdString(response.request().query()) != pending_search_) {
    qLog(Debug) << "Old search result for"
                << QStringFromStdString(response.request().query())
                << "expecting" << pending_search_;
    return;
  }
  pending_search_.clear();

  SongList songs;
  for (int i = 0; i < response.result_size(); ++i) {
    Song song;
    SongFromProtobuf(response.result(i), &song);
    songs << song;
  }

  qLog(Debug) << "Got" << songs.count() << "results";

  ClearSearchResults();

  // Fill results list
  for (const Song& song : songs) {
    QStandardItem* child = CreateSongItem(song);
    search_->appendRow(child);
  }

  const QString did_you_mean_suggestion =
      QStringFromStdString(response.did_you_mean());
  qLog(Debug) << "Did you mean suggestion: " << did_you_mean_suggestion;
  if (!did_you_mean_suggestion.isEmpty()) {
    search_box_->did_you_mean()->Show(did_you_mean_suggestion);
  } else {
    // In case something else was previously displayed
    search_box_->did_you_mean()->hide();
  }

  QModelIndex index = model()->merged_model()->mapFromSource(search_->index());
  ScrollToIndex(index);
}
예제 #9
0
void TrackSelectionDialog::Init(const SongList& songs) {
  ui_->song_list->clear();
  ui_->stack->setCurrentWidget(ui_->loading_page);
  data_.clear();

  for (const Song& song : songs) {
    Data data;
    data.original_song_ = song;
    data_ << data;

    QListWidgetItem* item = new QListWidgetItem(ui_->song_list);
    item->setText(QFileInfo(song.url().toLocalFile()).fileName());
    item->setForeground(palette().color(QPalette::Disabled, QPalette::Text));
  }

  const bool multiple = songs.count() > 1;
  ui_->song_list->setVisible(multiple);
  next_button_->setEnabled(multiple);
  previous_button_->setEnabled(multiple);

  ui_->song_list->setCurrentRow(0);
}