CSong::CSong(CMusicInfoTag& tag) { SYSTEMTIME stTime; tag.GetReleaseDate(stTime); strTitle = tag.GetTitle(); strGenre = tag.GetGenre(); strFileName = tag.GetURL(); strArtist = tag.GetArtist(); strAlbum = tag.GetAlbum(); strAlbumArtist = tag.GetAlbumArtist(); strComment = tag.GetComment(); strLabel = tag.GetLabel(); // Laureon: Added getLabel strISRC = tag.GetISRC(); // Laureon: Added getISRC iVisible = 1; // Laureon: Added: Song Visibility rating = tag.GetRating(); iYear = stTime.wYear; iTrack = tag.GetTrackAndDiskNumber(); iDuration = tag.GetDuration(); strThumb = ""; iStartOffset = 0; iEndOffset = 0; idSong = -1; iTimesPlayed = 0; iKaraokeNumber = 0; iKaraokeDelay = 0; //! Karaoke song lyrics-music delay in 1/10 seconds. iArtistId = -1; iAlbumId = -1; }
CSong::CSong(CMusicInfoTag& tag) { SYSTEMTIME stTime; tag.GetReleaseDate(stTime); strTitle = tag.GetTitle(); genre = tag.GetGenre(); strFileName = tag.GetURL(); artist = tag.GetArtist(); strAlbum = tag.GetAlbum(); albumArtist = tag.GetAlbumArtist(); strMusicBrainzTrackID = tag.GetMusicBrainzTrackID(); strMusicBrainzArtistID = tag.GetMusicBrainzArtistID(); strMusicBrainzAlbumID = tag.GetMusicBrainzAlbumID(); strMusicBrainzAlbumArtistID = tag.GetMusicBrainzAlbumArtistID(); strMusicBrainzTRMID = tag.GetMusicBrainzTRMID(); strComment = tag.GetComment(); rating = tag.GetRating(); iYear = stTime.wYear; iTrack = tag.GetTrackAndDiskNumber(); iDuration = tag.GetDuration(); bCompilation = tag.GetCompilation(); embeddedArt = tag.GetCoverArtInfo(); strThumb = ""; iStartOffset = 0; iEndOffset = 0; idSong = -1; iTimesPlayed = 0; iKaraokeNumber = 0; iKaraokeDelay = 0; //! Karaoke song lyrics-music delay in 1/10 seconds. iAlbumId = -1; }
bool CLastFmManager::Unban(const CMusicInfoTag& musicinfotag, bool askConfirmation /*= true*/) { if (!IsLastFmEnabled()) { CLog::Log(LOGERROR, "LastFmManager Unban, lasfm is not enabled"); return false; } CStdString strTitle = musicinfotag.GetTitle(); CStdString strArtist = StringUtils::Join(musicinfotag.GetArtist(), g_advancedSettings.m_musicItemSeparator); if (strArtist.IsEmpty()) { CLog::Log(LOGERROR, "Last.fm Unban no artistname provided."); return false; } if (strTitle.IsEmpty()) { CLog::Log(LOGERROR, "Last.fm Unban no tracktitle provided."); return false; } CStdString strInfo; strInfo.Format("%s - %s", strArtist, strTitle); if (!askConfirmation || CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(15200), g_localizeStrings.Get(15298), strInfo, "")) { return CallXmlRpc("unBanTrack", strArtist, strTitle); } return false; }
bool CLastFmManager::Unlove(const CMusicInfoTag& musicinfotag, bool askConfirmation /*= true*/) { if (!IsLastFmEnabled()) { CLog::Log(LOGERROR, "LastFmManager Unlove, lasfm is not enabled"); return false; } CStdString strTitle = musicinfotag.GetTitle(); CStdString strArtist = StringUtils::Join(musicinfotag.GetArtist(), g_advancedSettings.m_musicItemSeparator); if (strArtist.IsEmpty()) { CLog::Log(LOGERROR, "Last.fm Unlove no artistname provided."); return false; } if (strTitle.IsEmpty()) { CLog::Log(LOGERROR, "Last.fm Unlove no tracktitle provided."); return false; } CStdString strInfo; strInfo.Format("%s - %s", strArtist, strTitle); if (!askConfirmation || CGUIDialogYesNo::ShowAndGetInput(g_localizeStrings.Get(15200), g_localizeStrings.Get(15297), strInfo, "")) { if (CallXmlRpc("unLoveTrack", strArtist, strTitle)) { //update our local rating, now this is tricky because we only have an artist and title //and don't know if it was a local or radio song. //So we're going to try to get it from the database and check if the rating is 5, //if it is we can assume this was the song we loved before. CMusicDatabase musicdatabase; if (musicdatabase.Open()) { long songid = musicdatabase.GetSongByArtistAndAlbumAndTitle(strArtist, "%", strTitle); if (songid > 0) { CSong song; musicdatabase.GetSongById(songid, song); if (song.rating == '5') { //reset the rating musicdatabase.SetSongRating(song.strFileName, '0'); } } musicdatabase.Close(); } return true; } } return false; }
TYPED_TEST(TestTagParser, ParsesBasicTag) { // Create a basic tag TypeParam *tg = &this->value_; CMusicInfoTag tag; EXPECT_TRUE(CTagLoaderTagLib::ParseTag<TypeParam>(tg, NULL, tag)); EXPECT_EQ(1985, tag.GetYear()); EXPECT_EQ(2, tag.GetTrackNumber()); EXPECT_EQ(1u, tag.GetArtist().size()); if (tag.GetArtist().size() > 0) EXPECT_EQ("artist", tag.GetArtist().front()); EXPECT_EQ("album", tag.GetAlbum()); EXPECT_EQ("comment", tag.GetComment()); EXPECT_EQ(1u, tag.GetGenre().size()); if (tag.GetGenre().size() > 0) EXPECT_EQ("Jazz", tag.GetGenre().front()); EXPECT_EQ("title", tag.GetTitle()); }
bool CLastFmManager::Ban(const CMusicInfoTag& musicinfotag) { if (!IsRadioEnabled()) { CLog::Log(LOGERROR, "LastFmManager Ban, radio is not active"); return false; } if (CallXmlRpc("banTrack", musicinfotag.GetArtist(), musicinfotag.GetTitle())) { //we banned this track so skip to the next track g_application.getApplicationMessenger().ExecBuiltIn("playercontrol(next)"); m_CurrentSong.IsBanned = true; return true; } return false; }
TYPED_TEST(TestTagParser, FooProperties) { TypeParam *tg = &this->value_; CMusicInfoTag tag; PropertyMap props; int tagcount = end(tags) - tags; for(int i = 0; i < tagcount; i++) { props.insert(tags[i], String("foo")); } tg->setProperties(props); EXPECT_TRUE(CTagLoaderTagLib::ParseTag<TypeParam>(tg, NULL, tag)); EXPECT_EQ(0, tag.GetYear()); EXPECT_EQ(0, tag.GetTrackNumber()); EXPECT_EQ(1u, tag.GetArtist().size()); if (tag.GetArtist().size() > 0) EXPECT_EQ("foo", tag.GetArtist().front()); EXPECT_EQ("foo", tag.GetAlbum()); EXPECT_EQ("foo", tag.GetComment()); if (tag.GetGenre().size() > 0) EXPECT_EQ("foo", tag.GetGenre().front()); EXPECT_EQ("foo", tag.GetTitle()); }
bool CMusicGUIInfo::InitCurrentItem(CFileItem *item) { if (item && (item->IsAudio() || (item->IsInternetStream() && g_application.GetAppPlayer().IsPlayingAudio()))) { CLog::Log(LOGDEBUG,"CMusicGUIInfo::InitCurrentItem(%s)", item->GetPath().c_str()); item->LoadMusicTag(); CMusicInfoTag* tag = item->GetMusicInfoTag(); // creates item if not yet set, so no nullptr checks needed if (tag->GetTitle().empty()) { // No title in tag, show filename only tag->SetTitle(CUtil::GetTitleFromPath(item->GetPath())); } tag->SetLoaded(true); // find a thumb for this file. if (item->IsInternetStream()) { if (!g_application.m_strPlayListFile.empty()) { CLog::Log(LOGDEBUG,"Streaming media detected... using %s to find a thumb", g_application.m_strPlayListFile.c_str()); CFileItem streamingItem(g_application.m_strPlayListFile,false); CMusicThumbLoader loader; loader.FillThumb(streamingItem); if (streamingItem.HasArt("thumb")) item->SetArt("thumb", streamingItem.GetArt("thumb")); } } else { CMusicThumbLoader loader; loader.LoadItem(item); } CMusicInfoLoader::LoadAdditionalTagInfo(item); return true; } return false; }
bool CLastFmManager::Love(const CMusicInfoTag& musicinfotag) { if (!IsLastFmEnabled()) { CLog::Log(LOGERROR, "LastFmManager Love, lastfm is not enabled."); return false; } CStdString strTitle = musicinfotag.GetTitle(); CStdString strArtist = StringUtils::Join(musicinfotag.GetArtist(), g_advancedSettings.m_musicItemSeparator); CStdString strFilePath; if (m_CurrentSong.CurrentSong && !m_CurrentSong.CurrentSong->IsLastFM()) { //path to update the rating for strFilePath = m_CurrentSong.CurrentSong->GetPath(); } if (CallXmlRpc("loveTrack",strArtist, strTitle)) { m_CurrentSong.IsLoved = true; //update the rating to 5, we loved it. CMusicInfoTag newTag(musicinfotag); newTag.SetRating('5'); CApplicationMessenger::Get().SetCurrentSongTag(newTag); //try updating the rating in the database if it's a local file. CMusicDatabase musicdatabase; if (musicdatabase.Open()) { CSong song; //update if the song exists in our database and there is no rating yet. if (musicdatabase.GetSongByFileName(strFilePath, song) && song.rating == '0') { musicdatabase.SetSongRating(strFilePath, '5'); } musicdatabase.Close(); } return true; } return false; }
int CScrobbler::AddSong(const CMusicInfoTag& tag) { if ((!g_guiSettings.GetBool("lastfm.enable") && !g_guiSettings.GetBool("lastfm.recordtoprofile")) || !g_guiSettings.GetBool("network.enableinternet")) return 0; if (tag.GetDuration() <= MINLENGTH || tag.GetDuration() > MAXLENGTH) // made <= to minlength to stop iTMS previews being submitted in iTunes return 0; if (!tag.Loaded() || tag.GetArtist().IsEmpty() || tag.GetTitle().IsEmpty()) return 0; if(m_bSubmitInProgress) { StatusUpdate(S_NOT_SUBMITTING,"Previous submission still in progress"); return 0; } char ti[20]; struct tm *today = gmtime(&m_SongStartTime); strftime(ti, sizeof(ti), "%Y-%m-%d %H:%M:%S", today); CStdString a, b, t; // our tags are stored as UTF-8, so no conversion needed a = tag.GetArtist(); b = tag.GetAlbum(); t = tag.GetTitle(); CStdString i=ti; CStdString m=tag.GetMusicBrainzTrackID(); CUtil::URLEncode(a); CUtil::URLEncode(b); CUtil::URLEncode(t); CUtil::URLEncode(i); CUtil::URLEncode(m); CStdString strSubmitStr; strSubmitStr.Format("a[%i]=%s&t[%i]=%s&b[%i]=%s&m[%i]=%s&l[%i]=%i&i[%i]=%s&", m_iSongNum, a.c_str(), m_iSongNum, t.c_str(), m_iSongNum, b.c_str(), m_iSongNum, m.c_str(), m_iSongNum, tag.GetDuration(), m_iSongNum, i.c_str()); if(m_strPostString.find(ti) != m_strPostString.npos) { // we have already tried to add a song at this time stamp // I have no idea how this could happen but apparently it does so // we stop it now StatusUpdate(S_NOT_SUBMITTING,strSubmitStr); StatusUpdate(S_NOT_SUBMITTING,m_strPostString); StatusUpdate(S_NOT_SUBMITTING,"Submission error, duplicate subbmission time found"); return 3; } m_strPostString += strSubmitStr; m_iSongNum++; SaveCache(m_strPostString.c_str(), m_iSongNum); time_t now; time (&now); if ((m_Interval + m_LastConnect) < now) { DoSubmit(); return 1; } else { CStdString strMsg; strMsg.Format("Not submitting, caching for %i more seconds. Cache is %i entries.", (int)(m_Interval + m_LastConnect - now), m_iSongNum); StatusUpdate(S_NOT_SUBMITTING,strMsg); return 2; } }
bool CLastFmManager::Ban(const CMusicInfoTag& musicinfotag) { if (!IsRadioEnabled()) { CLog::Log(LOGERROR, "LastFmManager Ban, radio is not active"); return false; } if (CallXmlRpc("banTrack", StringUtils::Join(musicinfotag.GetArtist(), g_advancedSettings.m_musicItemSeparator), musicinfotag.GetTitle())) { //we banned this track so skip to the next track CApplicationMessenger::Get().ExecBuiltIn("playercontrol(next)"); m_CurrentSong.IsBanned = true; return true; } return false; }
bool CMusicInfoTagLoaderSid::Load(const CStdString& strFileName, CMusicInfoTag& tag) { CStdString strFileToLoad = strFileName; int iTrack = 0; CStdString strExtension; CUtil::GetExtension(strFileName,strExtension); strExtension.MakeLower(); if (strExtension==".sidstream") { // Extract the track to play CStdString strFile=CUtil::GetFileName(strFileName); int iStart=strFile.ReverseFind("-")+1; iTrack = atoi(strFile.substr(iStart, strFile.size()-iStart-10).c_str()); // The directory we are in, is the file // that contains the bitstream to play, // so extract it CStdString strPath=strFileName; CUtil::GetDirectory(strPath, strFileToLoad); CUtil::RemoveSlashAtEnd(strFileToLoad); // we want the filename } CStdString strFileNameLower(strFileToLoad); strFileNameLower.MakeLower(); int iHVSC = strFileNameLower.find("hvsc"); // need hvsc in path name since our lookupfile is based on hvsc paths if (iHVSC < 0) { iHVSC = strFileNameLower.find("c64music"); if (iHVSC >= 0) iHVSC += 8; } else iHVSC += 4; if( iHVSC < 0 ) { tag.SetLoaded(false); return( false ); } CStdString strHVSCpath = strFileToLoad.substr(iHVSC,strFileToLoad.length()-1); strHVSCpath.Replace('\\','/'); // unix paths strHVSCpath.MakeLower(); char temp[8192]; CRegExp reg; if (!reg.RegComp("TITLE: ([^\r\n]*)\r?\n[^A]*ARTIST: ([^\r\n]*)\r?\n")) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..): failed to compile regular expression"); tag.SetLoaded(false); return( false ); } sprintf(temp,"%s\\%s",g_settings.GetDatabaseFolder().c_str(),"stil.txt"); // changeme? std::ifstream f(temp); if( !f.good() ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..) unable to locate stil.txt"); tag.SetLoaded(false); return( false ); } const char* szStart = NULL; const char* szEnd = NULL; char temp2[8191]; char* temp3 = temp2; while( !f.eof() && !szEnd ) { f.read(temp,8191); CStdString strLower = temp; strLower.MakeLower(); if (!szStart) szStart= (char *)strstr(strLower.c_str(),strHVSCpath.c_str()); if (szStart) { szEnd = strstr(szStart+strHVSCpath.size(),".sid"); if (szEnd) { memcpy(temp3,temp+(szStart-strLower.c_str()),szEnd-szStart); temp3 += szEnd-szStart; } else { memcpy(temp3,temp+(szStart-strLower.c_str()),strlen(szStart)); szStart = NULL; temp3 += strlen(szStart); } } } f.close(); if (!f.eof() && szEnd) { temp2[temp3-temp2] = '\0'; temp3 = strstr(temp2,"TITLE:"); } else temp3 = NULL; if (temp3) { for (int i=0;i<iTrack-1;++i) // skip tracks { int iStart = reg.RegFind(temp3); if (!iStart) { tag.SetLoaded(false); return false; } temp3 += iStart; } if(reg.RegFind(temp3) > -1) { char* szTitle = reg.GetReplaceString("\\1"); char* szArtist = reg.GetReplaceString("\\2"); char* szMins = NULL; char* szSecs = NULL; CRegExp reg2; reg2.RegComp("(.*) \\(([0-9]*):([0-9]*)\\)"); if (reg2.RegFind(szTitle) > -1) { szMins = reg2.GetReplaceString("\\2"); szSecs = reg2.GetReplaceString("\\3"); char* szTemp = reg2.GetReplaceString("\\1"); free(szTitle); szTitle = szTemp; } tag.SetLoaded(true); tag.SetURL(strFileToLoad); tag.SetTrackNumber(iTrack); if (szMins && szSecs) tag.SetDuration(atoi(szMins)*60+atoi(szSecs)); tag.SetTitle(szTitle); tag.SetArtist(szArtist); if( szTitle ) free(szTitle); if( szArtist ) free(szArtist); if( szMins ) free(szMins); if( szSecs ) free(szSecs); } } sprintf(temp,"%s\\%s",g_settings.GetDatabaseFolder().c_str(),"sidlist.csv"); // changeme? std::ifstream f2(temp); if( !f2.good() ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..) unable to locate sidlist.csv"); tag.SetLoaded(false); return( false ); } while( !f2.eof() ) { f2.getline(temp,8191); CStdString strTemp(temp); strTemp.MakeLower(); unsigned int iFind = strTemp.find(strHVSCpath); if (iFind == string::npos) continue; char temp2[1024]; char temp3[1024]; strncpy(temp3,temp+iFind,strlen(strHVSCpath)); temp3[strlen(strHVSCpath)] = '\0'; sprintf(temp2,"\"%s\",\"[^\"]*\",\"[^\"]*\",\"([^\"]*)\",\"([^\"]*)\",\"([0-9]*)[^\"]*\",\"[0-9]*\",\"[0-9]*\",\"",temp3); for (int i=0;i<iTrack-1;++i) strcat(temp2,"[0-9]*:[0-9]* "); strcat(temp2,"([0-9]*):([0-9]*)"); if( !reg.RegComp(temp2) ) { CLog::Log(LOGINFO,"MusicInfoTagLoaderSid::Load(..): failed to compile regular expression"); tag.SetLoaded(false); return( false ); } if( reg.RegFind(temp) >= 0 ) { char* szTitle = reg.GetReplaceString("\\1"); char* szArtist = reg.GetReplaceString("\\2"); char* szYear = reg.GetReplaceString("\\3"); char* szMins = reg.GetReplaceString("\\4"); char* szSecs = reg.GetReplaceString("\\5"); tag.SetLoaded(true); tag.SetTrackNumber(iTrack); if (tag.GetDuration() == 0) tag.SetDuration(atoi(szMins)*60+atoi(szSecs)); if (tag.GetTitle() == "") tag.SetTitle(szTitle); if (tag.GetArtist() == "") tag.SetArtist(szArtist); SYSTEMTIME dateTime; dateTime.wYear = atoi(szYear); tag.SetReleaseDate(dateTime); if( szTitle ) free(szTitle); if( szArtist ) free(szArtist); if( szYear ) free(szYear); if( szMins ) free(szMins); if( szSecs ) free(szSecs); f2.close(); return( true ); } } f2.close(); tag.SetLoaded(false); return( false ); }
bool CTagLoaderTagLib::Load(const string& strFileName, CMusicInfoTag& tag, EmbeddedArt *art /* = NULL */) { CStdString strExtension; URIUtils::GetExtension(strFileName, strExtension); strExtension.ToLower(); strExtension.TrimLeft('.'); if (strExtension.IsEmpty()) return false; TagLibVFSStream* stream = new TagLibVFSStream(strFileName, true); if (!stream) { CLog::Log(LOGERROR, "could not create TagLib VFS stream for: %s", strFileName.c_str()); return false; } TagLib::File* file = NULL; TagLib::APE::File* apeFile = NULL; TagLib::ASF::File* asfFile = NULL; TagLib::FLAC::File* flacFile = NULL; TagLib::IT::File* itFile = NULL; TagLib::Mod::File* modFile = NULL; TagLib::MP4::File* mp4File = NULL; TagLib::MPC::File* mpcFile = NULL; TagLib::MPEG::File* mpegFile = NULL; TagLib::Ogg::Vorbis::File* oggVorbisFile = NULL; TagLib::Ogg::FLAC::File* oggFlacFile = NULL; TagLib::S3M::File* s3mFile = NULL; TagLib::TrueAudio::File* ttaFile = NULL; TagLib::WavPack::File* wvFile = NULL; TagLib::XM::File* xmFile = NULL; if (strExtension == "ape") file = apeFile = new APE::File(stream); else if (strExtension == "asf" || strExtension == "wmv" || strExtension == "wma") file = asfFile = new ASF::File(stream); else if (strExtension == "flac") file = flacFile = new FLAC::File(stream, ID3v2::FrameFactory::instance()); else if (strExtension == "it") file = itFile = new IT::File(stream); else if (strExtension == "mod" || strExtension == "module" || strExtension == "nst" || strExtension == "wow") file = modFile = new Mod::File(stream); else if (strExtension == "mp4" || strExtension == "m4a" || strExtension == "m4r" || strExtension == "m4b" || strExtension == "m4p" || strExtension == "3g2") file = mp4File = new MP4::File(stream); else if (strExtension == "mpc") file = mpcFile = new MPC::File(stream); else if (strExtension == "mp3" || strExtension == "aac") file = mpegFile = new MPEG::File(stream, ID3v2::FrameFactory::instance()); else if (strExtension == "s3m") file = s3mFile = new S3M::File(stream); else if (strExtension == "tta") file = ttaFile = new TrueAudio::File(stream, ID3v2::FrameFactory::instance()); else if (strExtension == "wv") file = wvFile = new WavPack::File(stream); else if (strExtension == "xm") file = xmFile = new XM::File(stream); else if (strExtension == "ogg") file = oggVorbisFile = new Ogg::Vorbis::File(stream); else if (strExtension == "oga") // Leave this madness until last - oga container can have Vorbis or FLAC { file = oggFlacFile = new Ogg::FLAC::File(stream); if (!file || !file->isValid()) { delete file; file = oggVorbisFile = new Ogg::Vorbis::File(stream); } } if (!file || !file->isOpen()) { delete file; delete stream; CLog::Log(LOGDEBUG, "file could not be opened for tag reading"); return false; } APE::Tag *ape = NULL; ASF::Tag *asf = NULL; MP4::Tag *mp4 = NULL; ID3v2::Tag *id3v2 = NULL; Ogg::XiphComment *xiph = NULL; Tag *generic = NULL; if (apeFile) ape = apeFile->APETag(false); else if (asfFile) asf = asfFile->tag(); else if (flacFile) { xiph = flacFile->xiphComment(false); id3v2 = flacFile->ID3v2Tag(false); } else if (mp4File) mp4 = mp4File->tag(); else if (mpegFile) { id3v2 = mpegFile->ID3v2Tag(false); ape = mpegFile->APETag(false); } else if (oggFlacFile) xiph = dynamic_cast<Ogg::XiphComment *>(oggFlacFile->tag()); else if (oggVorbisFile) xiph = dynamic_cast<Ogg::XiphComment *>(oggVorbisFile->tag()); else if (ttaFile) id3v2 = ttaFile->ID3v2Tag(false); else if (wvFile) ape = wvFile->APETag(false); else // This is a catch all to get generic information for other files types (s3m, xm, it, mod, etc) generic = file->tag(); if (file->audioProperties()) tag.SetDuration(file->audioProperties()->length()); if (ape && !g_advancedSettings.m_prioritiseAPEv2tags) ParseAPETag(ape, art, tag); if (asf) ParseASF(asf, art, tag); else if (id3v2) ParseID3v2Tag(id3v2, art, tag); else if (generic) ParseGenericTag(generic, art, tag); else if (mp4) ParseMP4Tag(mp4, art, tag); else if (xiph) ParseXiphComment(xiph, art, tag); // art for flac files is outside the tag if (flacFile) SetFlacArt(flacFile, art, tag); // Add APE tags over the top of ID3 tags if we want to prioritize them if (ape && g_advancedSettings.m_prioritiseAPEv2tags) ParseAPETag(ape, art, tag); if (!tag.GetTitle().IsEmpty() || !tag.GetArtist().empty() || !tag.GetAlbum().IsEmpty()) tag.SetLoaded(); tag.SetURL(strFileName); delete file; delete stream; return true; }