void Playlist::computeSize(double &size_in_MB, double &size_in_sec) { double child_MB; double child_sec; // Clear return values size_in_MB = 0.0; size_in_sec = 0.0; SongList::const_iterator it = songs.begin(); for (; it != songs.end(); ++it) { if ((*it)->getCDFlag()) continue; if ((*it)->getValue() == 0) { VERBOSE(VB_IMPORTANT, kID0err); } else if ((*it)->getValue() > 0) { // Normal track Metadata *tmpdata = all_available_music->getMetadata((*it)->getValue()); if (tmpdata) { if (tmpdata->Length() > 0) size_in_sec += tmpdata->Length(); else VERBOSE(VB_GENERAL, "Computing track lengths. " "One track <=0"); // Check tmpdata->Filename QFileInfo finfo(tmpdata->Filename()); size_in_MB += finfo.size() / 1000000; } } if ((*it)->getValue() < 0) { // it's a playlist, recurse (mildly) // Comment: I can't make this thing work. // Nothing is computed with playlists Playlist *level_down = parent->getPlaylist(((*it)->getValue()) * -1); if (level_down) { level_down->computeSize(child_MB, child_sec); size_in_MB += child_MB; size_in_sec += child_sec; } } } }
/*! * \copydoc MetaIO::read() */ Metadata* MetaIOFLACVorbis::read(QString filename) { TagLib::FLAC::File *flacfile = OpenFile(filename); if (!flacfile) return NULL; TagLib::Ogg::XiphComment *tag = flacfile->xiphComment(); if (!tag) { delete flacfile; return NULL; } Metadata *metadata = new Metadata(filename); ReadGenericMetadata(tag, metadata); bool compilation = false; if (tag->contains("COMPILATION_ARTIST")) { QString compilation_artist = TStringToQString( tag->fieldListMap()["COMPILATION_ARTIST"].toString()).trimmed(); if (compilation_artist != metadata->Artist()) { metadata->setCompilationArtist(compilation_artist); compilation = true; } } if (!compilation && tag->contains("MUSICBRAINZ_ALBUMARTISTID")) { QString musicbrainzcode = TStringToQString( tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString()).trimmed(); if (musicbrainzcode == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID) compilation = true; } metadata->setCompilation(compilation); if (metadata->Length() <= 0) { TagLib::FileRef *fileref = new TagLib::FileRef(flacfile); metadata->setLength(getTrackLength(fileref)); // FileRef takes ownership of flacfile, and is responsible for it's // deletion. Messy. delete fileref; } else delete flacfile; return metadata; }
/*! * \copydoc MetaIO::read() */ Metadata* MetaIOOggVorbis::read(const QString &filename) { TagLib::Ogg::Vorbis::File *oggfile = OpenFile(filename); if (!oggfile) return NULL; TagLib::Ogg::XiphComment *tag = oggfile->tag(); if (!tag) { delete oggfile; return NULL; } Metadata *metadata = new Metadata(filename); ReadGenericMetadata(tag, metadata); bool compilation = false; if (tag->contains("COMPILATION_ARTIST")) { QString compilation_artist = TStringToQString( tag->fieldListMap()["COMPILATION_ARTIST"].toString()).trimmed(); if (compilation_artist != metadata->Artist()) { metadata->setCompilationArtist(compilation_artist); compilation = true; } } if (!compilation && tag->contains("MUSICBRAINZ_ALBUMARTISTID")) { QString musicbrainzcode = TStringToQString( tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString()).trimmed(); if (musicbrainzcode == MYTH_MUSICBRAINZ_ALBUMARTIST_UUID) compilation = true; } metadata->setCompilation(compilation); if (metadata->Length() <= 0) metadata->setLength(getTrackLength(oggfile)); else delete oggfile; return metadata; }
void Playlist::getStats(int *trackCount, int *totalLength, int currenttrack, int *playedLength) const { *trackCount = songs.size(); *totalLength = 0; if (playedLength) *playedLength = 0; if (currenttrack < 0 || currenttrack >= songs.size()) currenttrack = 0; int track = 0; SongList::const_iterator it = songs.begin(); for (; it != songs.end(); ++it, ++track) { int trackID = (*it)->getValue(); Metadata *mdata = gMusicData->all_music->getMetadata(trackID); if (mdata) { *totalLength += mdata->Length(); if (playedLength && track < currenttrack) *playedLength += mdata->Length(); } } }
void DatabaseBox::entered(UIListTreeType *treetype, UIListGenericTree *item) { if (!item || !treetype) return; // Determin if this is a CD entry bool cd = false; if (dynamic_cast<CDCheckItem*>(item)) cd = true; TreeCheckItem *item_ptr = dynamic_cast<TreeCheckItem*>(item); if (item_ptr && item->childCount() == 0 && item_ptr->getLevel() == "title") { int id = item_ptr->getID(); Metadata *mdata; if (!cd) { mdata = gMusicData->all_music->getMetadata(id); if (!mdata) return; } else { // Need to allocate storage for CD Metadata mdata = new Metadata; if (!gMusicData->all_music->getCDMetadata(id, mdata)) { delete mdata; return; } } unsigned int line = 0; QString tmpstr; if (mdata->Compilation()) { tmpstr = tr("Compilation Artist:\t") + mdata->CompilationArtist(); if (m_lines.at(line)) m_lines.at(line++)->SetText(tmpstr); } tmpstr = tr("Artist:\t") + mdata->Artist(); if (m_lines.at(line)) m_lines.at(line++)->SetText(tmpstr); tmpstr = tr("Album:\t") + mdata->Album(); if (m_lines.at(line)) m_lines.at(line++)->SetText(tmpstr); tmpstr = tr("Title:\t") + mdata->Title(); if (m_lines.at(line)) m_lines.at(line++)->SetText(tmpstr); if (m_lines.at(line)) { int maxTime = mdata->Length() / 1000; int maxh = maxTime / 3600; int maxm = (maxTime / 60) % 60; int maxs = maxTime % 60; QString timeStr; if (maxh > 0) timeStr.sprintf("%02d:%02d:%02d", maxh, maxm, maxs); else timeStr.sprintf("%02d:%02d", maxm, maxs); tmpstr = tr("Length:\t") + timeStr; m_lines.at(line++)->SetText(tmpstr); } tmpstr = tr("Genre: ") + mdata->Genre(); if (m_lines.at(line)) { m_lines.at(line)->SetText(tmpstr); } else { QString prevvalue = m_lines.at(line-1)->GetText(); tmpstr = prevvalue + " " + tmpstr; m_lines.at(line-1)->SetText(tmpstr); } // Pre increment as not incremented from previous use. while (++line < (unsigned) m_lines.size()) m_lines.at(line)->SetText(""); // Don't forget to delete the mdata storage if we allocated it. if (cd) delete mdata; return; } QStringList pathto = treetype->getRouteToCurrent(); int linelen = 0; int dispat = 0; QString data; for (QStringList::Iterator it = pathto.begin(); it != pathto.end(); ++it) { if (it == pathto.begin()) continue; if (!data.isEmpty()) data += " / "; data += *it; linelen++; if (linelen == 2) { if (m_lines.at(dispat)) { m_lines.at(dispat)->SetText(data); } data.clear(); linelen = 0; dispat++; } } if (linelen != 0) { if (m_lines.at(dispat)) { m_lines.at(dispat)->SetText(data); } dispat++; } for (unsigned int i = dispat; i < (unsigned) m_lines.size(); i++) m_lines.at(i)->SetText(""); }
void Ripper::ScanFinished() { delete m_scanThread; m_scanThread = NULL; m_tracks->clear(); bool isCompilation = false; bool newTune = true; if (m_decoder) { QString label; Metadata *metadata; m_artistName.clear(); m_albumName.clear(); m_genreName.clear(); m_year.clear(); bool yesToAll = false; bool noToAll = false; for (int trackno = 0; trackno < m_decoder->getNumTracks(); trackno++) { RipTrack *ripTrack = new RipTrack; metadata = m_decoder->getMetadata(trackno + 1); if (metadata) { ripTrack->metadata = metadata; ripTrack->length = metadata->Length(); ripTrack->active = true; if (metadata->Compilation()) { isCompilation = true; m_artistName = metadata->CompilationArtist(); } else if (m_artistName.isEmpty()) { m_artistName = metadata->Artist(); } if (m_albumName.isEmpty()) m_albumName = metadata->Album(); if (m_genreName.isEmpty() && !metadata->Genre().isEmpty()) m_genreName = metadata->Genre(); if (m_year.isEmpty() && metadata->Year() > 0) m_year = QString::number(metadata->Year()); QString title = metadata->Title(); newTune = Ripper::isNewTune(m_artistName, m_albumName, title); if (newTune) { m_tracks->push_back(ripTrack); } else { if (yesToAll) { deleteTrack(m_artistName, m_albumName, title); m_tracks->push_back(ripTrack); } else if (noToAll) { delete ripTrack; delete metadata; continue; } else { DialogBox *dlg = new DialogBox( GetMythMainWindow(), tr("Artist: %1\n" "Album: %2\n" "Track: %3\n\n" "This track is already in the database. \n" "Do you want to remove the existing track?") .arg(m_artistName).arg(m_albumName).arg(title)); dlg->AddButton("No"); dlg->AddButton("No To All"); dlg->AddButton("Yes"); dlg->AddButton("Yes To All"); DialogCode res = dlg->exec(); dlg->deleteLater(); dlg = NULL; if (kDialogCodeButton0 == res) { delete ripTrack; delete metadata; } else if (kDialogCodeButton1 == res) { noToAll = true; delete ripTrack; delete metadata; } else if (kDialogCodeButton2 == res) { deleteTrack(m_artistName, m_albumName, title); m_tracks->push_back(ripTrack); } else if (kDialogCodeButton3 == res) { yesToAll = true; deleteTrack(m_artistName, m_albumName, title); m_tracks->push_back(ripTrack); } else // treat cancel as no { delete ripTrack; delete metadata; } } } } else delete ripTrack; } m_artistEdit->SetText(m_artistName); m_albumEdit->SetText(m_albumName); m_genreEdit->SetText(m_genreName); m_yearEdit->SetText(m_year); m_compilationCheck->SetCheckState(isCompilation); if (!isCompilation) m_switchTitleArtist->SetVisible(false); else m_switchTitleArtist->SetVisible(true); } BuildFocusList(); updateTrackList(); CloseBusyPopup(); }
void Ripper::ScanFinished() { delete m_scanThread; m_scanThread = NULL; m_tracks->clear(); bool isCompilation = false; if (m_decoder) { QString label; Metadata *metadata; m_artistName.clear(); m_albumName.clear(); m_genreName.clear(); m_year.clear(); for (int trackno = 0; trackno < m_decoder->getNumTracks(); trackno++) { RipTrack *ripTrack = new RipTrack; metadata = m_decoder->getMetadata(trackno + 1); if (metadata) { ripTrack->metadata = metadata; ripTrack->length = metadata->Length(); if (metadata->Compilation()) { isCompilation = true; m_artistName = metadata->CompilationArtist(); } else if (m_artistName.isEmpty()) { m_artistName = metadata->Artist(); } if (m_albumName.isEmpty()) m_albumName = metadata->Album(); if (m_genreName.isEmpty() && !metadata->Genre().isEmpty()) m_genreName = metadata->Genre(); if (m_year.isEmpty() && metadata->Year() > 0) m_year = QString::number(metadata->Year()); QString title = metadata->Title(); ripTrack->isNew = isNewTune(m_artistName, m_albumName, title); ripTrack->active = ripTrack->isNew; m_tracks->push_back(ripTrack); } else delete ripTrack; } m_artistEdit->SetText(m_artistName); m_albumEdit->SetText(m_albumName); m_genreEdit->SetText(m_genreName); m_yearEdit->SetText(m_year); m_compilationCheck->SetCheckState(isCompilation); if (!isCompilation) m_switchTitleArtist->SetVisible(false); else m_switchTitleArtist->SetVisible(true); } BuildFocusList(); updateTrackList(); CloseBusyPopup(); }
/*! * \copydoc MetaIO::read() */ Metadata *MetaIOID3::read(const QString &filename) { if (!OpenFile(filename)) return NULL; TagLib::ID3v2::Tag *tag = GetID3v2Tag(true); // Create tag if none are found // if there is no ID3v2 tag, try to read the ID3v1 tag and copy it to // the ID3v2 tag structure if (tag->isEmpty()) { TagLib::ID3v1::Tag *tag_v1 = GetID3v1Tag(); if (!tag_v1) return NULL; if (!tag_v1->isEmpty()) { tag->setTitle(tag_v1->title()); tag->setArtist(tag_v1->artist()); tag->setAlbum(tag_v1->album()); tag->setTrack(tag_v1->track()); tag->setYear(tag_v1->year()); tag->setGenre(tag_v1->genre()); } } Metadata *metadata = new Metadata(filename); ReadGenericMetadata(tag, metadata); bool compilation = false; // Compilation Artist (TPE4 Remix) or fallback to (TPE2 Band) // N.B. The existance of a either frame is NOT an indication that this // is a compilation, but if it is then one of them will probably hold // the compilation artist. TextIdentificationFrame *tpeframe = NULL; TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"]; if (tpelist.isEmpty() || tpelist.front()->toString().isEmpty()) tpelist = tag->frameListMap()["TPE2"]; if (!tpelist.isEmpty()) tpeframe = (TextIdentificationFrame *)tpelist.front(); if (tpeframe && !tpeframe->toString().isEmpty()) { QString compilation_artist = TStringToQString(tpeframe->toString()) .trimmed(); metadata->setCompilationArtist(compilation_artist); } // MythTV rating and playcount, stored in POPM frame PopularimeterFrame *popm = findPOPM(tag, email); if (!popm) { if (!tag->frameListMap()["POPM"].isEmpty()) popm = dynamic_cast<PopularimeterFrame *> (tag->frameListMap()["POPM"].front()); } if (popm) { int rating = popm->rating(); rating = static_cast<int>(((static_cast<float>(rating)/255.0) * 10.0) + 0.5); metadata->setRating(rating); metadata->setPlaycount(popm->counter()); } // Look for MusicBrainz Album+Artist ID in TXXX Frame UserTextIdentificationFrame *musicbrainz = find(tag, "MusicBrainz Album Artist Id"); if (musicbrainz) { // If the MusicBrainz ID is the special "Various Artists" ID // then compilation is TRUE if (!compilation && !musicbrainz->fieldList().isEmpty()) compilation = (MYTH_MUSICBRAINZ_ALBUMARTIST_UUID == TStringToQString(musicbrainz->fieldList().front())); } // TLEN - Ignored intentionally, some encoders write bad values // e.g. Lame under certain circumstances will always write a length of // 27 hours // Length if (!tag->frameListMap()["TLEN"].isEmpty()) { int length = tag->frameListMap()["TLEN"].front()->toString().toInt(); LOG(VB_FILE, LOG_DEBUG, QString("MetaIOID3::read: Length for '%1' from tag is '%2'\n").arg(filename).arg(length)); } metadata->setCompilation(compilation); metadata->setLength(getTrackLength(m_file)); // The number of tracks on the album, if supplied if (!tag->frameListMap()["TRCK"].isEmpty()) { QString trackFrame = TStringToQString( tag->frameListMap()["TRCK"].front()->toString()) .trimmed(); int trackCount = trackFrame.section('/', -1).toInt(); if (trackCount > 0) metadata->setTrackCount(trackCount); } LOG(VB_FILE, LOG_DEBUG, QString("MetaIOID3::read: Length for '%1' from properties is '%2'\n").arg(filename).arg(metadata->Length())); return metadata; }
void Playlist::savePlaylist(QString a_name, QString a_host) { name = a_name.simplified(); if (name.length() < 1) { VERBOSE(VB_GENERAL, LOC_WARN + "Not saving unnamed playlist"); return; } if (a_host.length() < 1) { VERBOSE(VB_GENERAL, LOC_WARN + "Not saving playlist without a host name"); return; } if (name.length() < 1) return; fillSonglistFromSongs(); MSqlQuery query(MSqlQuery::InitCon()); int length = 0, songcount = 0, playtime = 0, an_int; QStringList list = raw_songlist.split(",", QString::SkipEmptyParts); QStringList::iterator it = list.begin(); for (; it != list.end(); it++) { an_int = QString(*it).toInt(); if (an_int != 0) { songcount++; if (an_int > 0) { Metadata *md = all_available_music->getMetadata(an_int); if (md) length = md->Length(); } else { query.prepare("SELECT length FROM music_playlists " "WHERE playlist_id = :ID ;"); an_int *= -1; query.bindValue(":ID", an_int); if (query.exec() && query.next()) { length = query.value(0).toInt(); } } playtime += length; } } bool save_host = ("default_playlist_storage" == a_name || "backup_playlist_storage" == a_name); if (playlistid > 0) { QString str_query = "UPDATE music_playlists SET " "playlist_songs = :LIST, " "playlist_name = :NAME, " "songcount = :SONGCOUNT, " "length = :PLAYTIME"; if (save_host) str_query += ", hostname = :HOSTNAME"; str_query += " WHERE playlist_id = :ID ;"; query.prepare(str_query); query.bindValue(":ID", playlistid); } else { QString str_query = "INSERT INTO music_playlists" " (playlist_name, playlist_songs," " songcount, length"; if (save_host) str_query += ", hostname"; str_query += ") VALUES(:NAME, :LIST, :SONGCOUNT, :PLAYTIME"; if (save_host) str_query += ", :HOSTNAME"; str_query += ");"; query.prepare(str_query); } query.bindValue(":LIST", raw_songlist); query.bindValue(":NAME", a_name); query.bindValue(":SONGCOUNT", songcount); query.bindValue(":PLAYTIME", playtime); if (save_host) query.bindValue(":HOSTNAME", a_host); if (!query.exec() || (playlistid < 1 && query.numRowsAffected() < 1)) { MythDB::DBError("Problem saving playlist", query); } if (playlistid < 1) playlistid = query.lastInsertId().toInt(); }