Ejemplo n.º 1
0
void CMusicInfoTag::SetAlbum(const CAlbum& album)
{
  //Set all artist infomation from album artist credits and artist description
  SetArtistDesc(album.strArtistDesc);
  SetArtist(album.GetAlbumArtist());
  SetMusicBrainzArtistID(album.GetMusicBrainzAlbumArtistID());
  SetAlbumArtistDesc(album.strArtistDesc);
  SetAlbumArtist(album.GetAlbumArtist());
  SetMusicBrainzAlbumArtistID(album.GetMusicBrainzAlbumArtistID());
  SetAlbumId(album.idAlbum);
  SetAlbum(album.strAlbum);
  SetTitle(album.strAlbum);
  SetMusicBrainzAlbumID(album.strMusicBrainzAlbumID);
  SetGenre(album.genre);
  SetMood(StringUtils::Join(album.moods, g_advancedSettings.m_musicItemSeparator));
  SetRating('0' + album.iRating);
  SetCompilation(album.bCompilation);
  SYSTEMTIME stTime;
  stTime.wYear = album.iYear;
  SetReleaseDate(stTime);
  SetAlbumReleaseType(album.releaseType);
  SetDateAdded(album.dateAdded);
  SetPlayCount(album.iTimesPlayed);
  SetDatabaseId(album.idAlbum, MediaTypeAlbum);

  SetLoaded();
}
Ejemplo n.º 2
0
void CAddMusicAlbum::OnCommandCharSelector(SallyAPI::GUI::CGUIBaseObject* reporter)
{
	std::string temp = reporter->GetText();
	if (temp.length() <= 0)
		return;

	char searchForChar = temp[0];

	// go to the top
	if (searchForChar == '*')
	{
		ResetImages();
		UpdateImages();
		return;
	}

	int newPosition = 0;

	std::vector<CAlbum*>::iterator iter = m_vAlbumList.begin();
	while (iter != m_vAlbumList.end())
	{
		CAlbum* item = *iter;

		temp = item->GetArtist();
		if (temp.length() > 0)
		{
			temp = SallyAPI::String::StringHelper::StringToUpper(temp);

			char c = temp[0];
			if (searchForChar == c)
			{
				// found!!!!
				newPosition = newPosition / m_iRows;
				m_iStartPicture = newPosition;
				UpdateImages();
				return;
			}
			if (((c > searchForChar) && ((c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122)))
				|| (((searchForChar == 48 && searchForChar == 57)) && ((c >= 32 && c <= 47) || (c >= 58 && c <= 64) || (c >= 91 && c <= 96) || (c >= 123 && c <= 126))))
			{
				// ok, we already at the next char
				newPosition = newPosition / m_iRows;
				m_iStartPicture = newPosition;
				UpdateImages();
				return;
			}
		}

		++newPosition;
		++iter;
	}
	// not found... go to the last one
	newPosition = newPosition / m_iRows;
	m_iStartPicture = newPosition;
	UpdateImages();
}
Ejemplo n.º 3
0
bool CAudioLibrary::FillFileItem(const std::string &strFilename, CFileItemPtr &item, const CVariant &parameterObject /* = CVariant(CVariant::VariantTypeArray) */)
{
  CMusicDatabase musicdatabase;
  if (strFilename.empty())
    return false;

  bool filled = false;
  if (musicdatabase.Open())
  {
    if (CDirectory::Exists(strFilename))
    {
      CAlbum album;
      int albumid = musicdatabase.GetAlbumIdByPath(strFilename);
      if (musicdatabase.GetAlbum(albumid, album, false))
      {
        item->SetFromAlbum(album);
        FillItemArtistIDs(album.GetArtistIDArray(), item);

        CFileItemList items;
        items.Add(item);

        if (GetAdditionalAlbumDetails(parameterObject, items, musicdatabase) == OK)
          filled = true;
      }
    }
    else
    {
      CSong song;
      if (musicdatabase.GetSongByFileName(strFilename, song))
      {
        item->SetFromSong(song);
        FillItemArtistIDs(song.GetArtistIDArray(), item);

        CFileItemList items;
        items.Add(item);
        if (GetAdditionalSongDetails(parameterObject, items, musicdatabase) == OK)
          filled = true;
      }
    }
  }

  if (item->GetLabel().empty())
  {
    item->SetLabel(CUtil::GetTitleFromPath(strFilename, false));
    if (item->GetLabel().empty())
      item->SetLabel(URIUtils::GetFileName(strFilename));
  }

  return filled;
}
Ejemplo n.º 4
0
CAlbum CPFCManager::GetAlbumInfo(const CStdString& strPath) {
  CAlbum resultAlbum;

  TiXmlDocument xmlDocument;
  if (!GetDefsFile(strPath, xmlDocument)) return resultAlbum;

  TiXmlElement *artistElement = xmlDocument.RootElement()->FirstChildElement("artist");

  if (artistElement)
  {
    resultAlbum.Load(artistElement->FirstChildElement("album"), true, true);
  }

  return resultAlbum;
}
Ejemplo n.º 5
0
void CAudioLibrary::FillAlbumItem(const CAlbum &album, const std::string &path, CFileItemPtr &item)
{
  item = CFileItemPtr(new CFileItem(path, album));
  // Add album artistIds as separate property as not part of CMusicInfoTag
  std::vector<int> artistids = album.GetArtistIDArray();
  FillItemArtistIDs(artistids, item);
}
Ejemplo n.º 6
0
INFO_RET CMusicInfoScanner::UpdateDatabaseAlbumInfo(CAlbum& album, const ADDON::ScraperPtr& scraper, bool bAllowSelection, CGUIDialogProgress* pDialog /* = NULL */)
{
  if (!scraper)
    return INFO_ERROR;

  CMusicAlbumInfo albumInfo;

loop:
  CLog::Log(LOGDEBUG, "%s downloading info for: %s", __FUNCTION__, album.strAlbum.c_str());
  INFO_RET albumDownloadStatus = DownloadAlbumInfo(album, scraper, albumInfo, pDialog);
  if (albumDownloadStatus == INFO_NOT_FOUND)
  {
    if (pDialog && bAllowSelection)
    {
      if (!CGUIKeyboardFactory::ShowAndGetInput(album.strAlbum, CVariant{g_localizeStrings.Get(16011)}, false))
        return INFO_CANCELLED;

      std::string strTempArtist(album.GetAlbumArtistString());
      if (!CGUIKeyboardFactory::ShowAndGetInput(strTempArtist, CVariant{g_localizeStrings.Get(16025)}, false))
        return INFO_CANCELLED;

      album.strArtistDesc = strTempArtist;
      goto loop;
    }
    else
    {
      CEventLog::GetInstance().Add(EventPtr(new CMediaLibraryEvent(
        MediaTypeAlbum, album.strPath, 24146,
        StringUtils::Format(g_localizeStrings.Get(24147).c_str(), MediaTypeAlbum, album.strAlbum.c_str()),
        CScraperUrl::GetThumbURL(album.thumbURL.GetFirstThumb()), CURL::GetRedacted(album.strPath), EventLevel::Warning)));
    }
  }
  else if (albumDownloadStatus == INFO_ADDED)
  {
    bool overridetags = CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_OVERRIDETAGS);
    album.MergeScrapedAlbum(albumInfo.GetAlbum(), overridetags);
    m_musicDatabase.Open();
    m_musicDatabase.UpdateAlbum(album, overridetags);
    GetAlbumArtwork(album.idAlbum, album);
    m_musicDatabase.Close();
    albumInfo.SetLoaded(true);
  }
  return albumDownloadStatus;
}
Ejemplo n.º 7
0
INFO_RET CMusicInfoScanner::UpdateDatabaseAlbumInfo(CAlbum& album, const ADDON::ScraperPtr& scraper, bool bAllowSelection, CGUIDialogProgress* pDialog /* = NULL */)
{
  if (!scraper)
    return INFO_ERROR;

  CMusicAlbumInfo albumInfo;

loop:
  CLog::Log(LOGDEBUG, "%s downloading info for: %s", __FUNCTION__, album.strAlbum.c_str());
  INFO_RET albumDownloadStatus = DownloadAlbumInfo(album, scraper, albumInfo, pDialog);
  if (albumDownloadStatus == INFO_NOT_FOUND)
  {
    if (pDialog && bAllowSelection)
    {
      if (!CGUIKeyboardFactory::ShowAndGetInput(album.strAlbum, g_localizeStrings.Get(16011), false))
        return INFO_CANCELLED;

      std::string strTempArtist(StringUtils::Join(album.artist, g_advancedSettings.m_musicItemSeparator));
      if (!CGUIKeyboardFactory::ShowAndGetInput(strTempArtist, g_localizeStrings.Get(16025), false))
        return INFO_CANCELLED;

      album.artist = StringUtils::Split(strTempArtist, g_advancedSettings.m_musicItemSeparator);
      goto loop;
    }
  }
  else if (albumDownloadStatus == INFO_ADDED)
  {
    album.MergeScrapedAlbum(albumInfo.GetAlbum(), CSettings::Get().GetBool("musiclibrary.overridetags"));
    m_musicDatabase.Open();
    m_musicDatabase.UpdateAlbum(album);
    GetAlbumArtwork(album.idAlbum, album);
    m_musicDatabase.Close();
    albumInfo.SetLoaded(true);
  }
  return albumDownloadStatus;
}
Ejemplo n.º 8
0
void CAddMusicAlbum::OnCommandAddAlbum(int reporterId)
{
	if (reporterId == 0)
		return;

	reporterId = reporterId - 1;

	int col = reporterId / 100;
	int row = reporterId % 100;

	std::vector<SallyAPI::GUI::CImageBox*> imageBoxVector = m_mImage[col];
	std::vector<SallyAPI::GUI::CLabelBox*> imageNameVector = m_mImageName[col];

	int fileID = (m_iStartPicture * m_iRows) + (col * m_iRows) + row - m_iRows;

	if (fileID >= m_vAlbumList.size())
		return;

	CAlbum* album = m_vAlbumList[fileID];

	CMediaDatabase::GetAlbumTitelsFromDatabase(dynamic_cast<SallyAPI::GUI::CAppBase*> (m_pParent), m_pAlbumTitles, album->GetAlbum(), album->GetArtist());

	AddAllToPlaylistFromListView();
}
Ejemplo n.º 9
0
void CGUIWindowMusicBase::UpdateThumb(const CAlbum &album, const std::string &path)
{
  // check user permissions
  bool saveDb = album.idAlbum != -1;
  bool saveDirThumb = true;
  if (!CProfilesManager::GetInstance().GetCurrentProfile().canWriteDatabases() && !g_passwordManager.bMasterUser)
  {
    saveDb = false;
    saveDirThumb = false;
  }

  std::string albumThumb = m_musicdatabase.GetArtForItem(album.idAlbum, MediaTypeAlbum, "thumb");

  // Update the thumb in the music database (songs + albums)
  std::string albumPath(path);
  if (saveDb && CFile::Exists(albumThumb))
    m_musicdatabase.SaveAlbumThumb(album.idAlbum, albumThumb);

  // Update currently playing song if it's from the same album.  This is necessary as when the album
  // first gets it's cover, the info manager's item doesn't have the updated information (so will be
  // sending a blank thumb to the skin.)
  if (g_application.m_pPlayer->IsPlayingAudio())
  {
    const CMusicInfoTag* tag=g_infoManager.GetCurrentSongTag();
    if (tag)
    {
      // really, this may not be enough as it is to reliably update this item.  eg think of various artists albums
      // that aren't tagged as such (and aren't yet scanned).  But we probably can't do anything better than this
      // in that case
      if (album.strAlbum == tag->GetAlbum() && (album.GetAlbumArtist() == tag->GetAlbumArtist() ||
                                                album.GetAlbumArtist() == tag->GetArtist()))
      {
        g_infoManager.SetCurrentAlbumThumb(albumThumb);
      }
    }
  }

  // Save this thumb as the directory thumb if it's the only album in the folder (files view nicety)
  // We do this by grabbing all the songs in the folder, and checking to see whether they come
  // from the same album.
  if (saveDirThumb && CFile::Exists(albumThumb) && !albumPath.empty() && !URIUtils::IsCDDA(albumPath))
  {
    CFileItemList items;
    GetDirectory(albumPath, items);
    OnRetrieveMusicInfo(items);
    VECALBUMS albums;
    CMusicInfoScanner::FileItemsToAlbums(items, albums);
    if (albums.size() == 1)
    { // set as folder thumb as well
      CMusicThumbLoader loader;
      loader.SetCachedImage(items, "thumb", albumPath);
    }
  }

  // update the file listing - we have to update the whole lot, as it's likely that
  // more than just our thumbnails changed
  //! @todo Ideally this would only be done when needed - at the moment we appear to be
  //!       doing this for every lookup, possibly twice (see ShowAlbumInfo)
  Refresh(true);

  //  Do we have to autoswitch to the thumb control?
  m_guiState.reset(CGUIViewState::GetViewState(GetID(), *m_vecItems));
  UpdateButtons();
}
Ejemplo n.º 10
0
JSONRPC_STATUS CAudioLibrary::SetAlbumDetails(const std::string &method, ITransportLayer *transport, IClient *client, const CVariant &parameterObject, CVariant &result)
{
  int id = (int)parameterObject["albumid"].asInteger();

  CMusicDatabase musicdatabase;
  if (!musicdatabase.Open())
    return InternalError;

  CAlbum album;
  // Get current album details, but not songs as we do not want to update them here
  if (!musicdatabase.GetAlbum(id, album, false) || album.idAlbum <= 0)
    return InvalidParams;

  if (ParameterNotNull(parameterObject, "title"))
    album.strAlbum = parameterObject["title"].asString();
  if (ParameterNotNull(parameterObject, "displayartist"))
    album.strArtistDesc = parameterObject["displayartist"].asString();
  // Set album sort string before processing artist credits
  if (ParameterNotNull(parameterObject, "sortartist"))
    album.strArtistSort = parameterObject["sortartist"].asString();

  // Match up artist names and mbids to make new artist credits
  // Mbid values only apply if there are names
  if (ParameterNotNull(parameterObject, "artist"))
  {
    std::vector<std::string> artists;
    std::vector<std::string> mbids;
    CopyStringArray(parameterObject["artist"], artists);
    // Check for Musicbrainz ids
    if (ParameterNotNull(parameterObject, "musicbrainzalbumartistid"))
      CopyStringArray(parameterObject["musicbrainzalbumartistid"], mbids);
    // When display artist is not provided and yet artists is changing make by concatenation
    if (!ParameterNotNull(parameterObject, "displayartist"))
      album.strArtistDesc = StringUtils::Join(artists, g_advancedSettings.m_musicItemSeparator);
    album.SetArtistCredits(artists, std::vector<std::string>(), mbids);
    // On updatealbum artists will be changed
    album.bArtistSongMerge = true;
  }

  if (ParameterNotNull(parameterObject, "description"))
    album.strReview = parameterObject["description"].asString();
  if (ParameterNotNull(parameterObject, "genre"))
    CopyStringArray(parameterObject["genre"], album.genre);
  if (ParameterNotNull(parameterObject, "theme"))
    CopyStringArray(parameterObject["theme"], album.themes);
  if (ParameterNotNull(parameterObject, "mood"))
    CopyStringArray(parameterObject["mood"], album.moods);
  if (ParameterNotNull(parameterObject, "style"))
    CopyStringArray(parameterObject["style"], album.styles);
  if (ParameterNotNull(parameterObject, "type"))
    album.strType = parameterObject["type"].asString();
  if (ParameterNotNull(parameterObject, "albumlabel"))
    album.strLabel = parameterObject["albumlabel"].asString();
  if (ParameterNotNull(parameterObject, "rating"))
    album.fRating = parameterObject["rating"].asFloat();
  if (ParameterNotNull(parameterObject, "userrating"))
    album.iUserrating = parameterObject["userrating"].asInteger();
  if (ParameterNotNull(parameterObject, "votes"))
    album.iVotes = parameterObject["votes"].asInteger();
  if (ParameterNotNull(parameterObject, "year"))
    album.iYear = (int)parameterObject["year"].asInteger();
  if (ParameterNotNull(parameterObject, "musicbrainzalbumid"))
    album.strMusicBrainzAlbumID = parameterObject["musicbrainzalbumid"].asString();
  if (ParameterNotNull(parameterObject, "musicbrainzreleasegroupid"))
    album.strReleaseGroupMBID = parameterObject["musicbrainzreleasegroupid"].asString();

  // Update existing art. Any existing artwork that isn't specified in this request stays as is.
  // If the value is null then the existing art with that type is removed.
  if (ParameterNotNull(parameterObject, "art"))
  {
    // Get current artwork
    musicdatabase.GetArtForItem(album.idAlbum, MediaTypeAlbum, album.art);

    std::set<std::string> removedArtwork;
    CVariant art = parameterObject["art"];
    for (CVariant::const_iterator_map artIt = art.begin_map(); artIt != art.end_map(); artIt++)
    {
      if (artIt->second.isString() && !artIt->second.asString().empty())
        album.art[artIt->first] = CTextureUtils::UnwrapImageURL(artIt->second.asString());
      else if (artIt->second.isNull())
      {
        album.art.erase(artIt->first);
        removedArtwork.insert(artIt->first);
      }
    }
    // Remove null art now, as not done by update
    if (!musicdatabase.RemoveArtForItem(album.idAlbum, MediaTypeAlbum, removedArtwork))
      return InternalError;
  }

  // Update artist including adding or replacing (but not removing) art
  if (!musicdatabase.UpdateAlbum(album))
    return InternalError;

  CJSONRPCUtils::NotifyItemUpdated();
  return ACK;
}
Ejemplo n.º 11
0
void CMusicInfoScanner::Process()
{
  ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::AudioLibrary, "xbmc", "OnScanStarted");
  try
  {
    if (m_showDialog && !CServiceBroker::GetSettings().GetBool(CSettings::SETTING_MUSICLIBRARY_BACKGROUNDUPDATE))
    {
      CGUIDialogExtendedProgressBar* dialog =
        g_windowManager.GetWindow<CGUIDialogExtendedProgressBar>(WINDOW_DIALOG_EXT_PROGRESS);
      if (dialog)
        m_handle = dialog->GetHandle(g_localizeStrings.Get(314));
    }

    // check if we only need to perform a cleaning
    if (m_bClean && m_pathsToScan.empty())
    {
      CleanDatabase(false);
      m_handle = NULL;
      m_bRunning = false;

      return;
    }
    
    unsigned int tick = XbmcThreads::SystemClockMillis();
    m_musicDatabase.Open();
    m_bCanInterrupt = true;

    if (m_scanType == 0) // load info from files
    {
      CLog::Log(LOGDEBUG, "%s - Starting scan", __FUNCTION__);

      if (m_handle)
        m_handle->SetTitle(g_localizeStrings.Get(505));

      // Reset progress vars
      m_currentItem=0;
      m_itemCount=-1;

      // Create the thread to count all files to be scanned
      SetPriority( GetMinPriority() );
      if (m_handle)
        m_fileCountReader.Create();

      // Database operations should not be canceled
      // using Interrupt() while scanning as it could
      // result in unexpected behaviour.
      m_bCanInterrupt = false;
      m_needsCleanup = false;

      bool commit = true;
      for (std::set<std::string>::const_iterator it = m_pathsToScan.begin(); it != m_pathsToScan.end(); ++it)
      {
        if (!CDirectory::Exists(*it) && !m_bClean)
        {
          /*
           * Note that this will skip scanning (if m_bClean is disabled) if the directory really
           * doesn't exist. Since the music scanner is fed with a list of existing paths from the DB
           * and cleans out all songs under that path as its first step before re-adding files, if 
           * the entire source is offline we totally empty the music database in one go.
           */
          CLog::Log(LOGWARNING, "%s directory '%s' does not exist - skipping scan.", __FUNCTION__, it->c_str());
          m_seenPaths.insert(*it);
          continue;
        }
        else if (!DoScan(*it))
        {
          commit = false;
          break;
        }
      }

      if (commit)
      {
        g_infoManager.ResetLibraryBools();

        if (m_needsCleanup)
        {
          if (m_handle)
          {
            m_handle->SetTitle(g_localizeStrings.Get(700));
            m_handle->SetText("");
          }

          m_musicDatabase.CleanupOrphanedItems();

          if (m_handle)
            m_handle->SetTitle(g_localizeStrings.Get(331));

          m_musicDatabase.Compress(false);
        }
      }

      m_fileCountReader.StopThread();

      m_musicDatabase.EmptyCache();
      
      tick = XbmcThreads::SystemClockMillis() - tick;
      CLog::Log(LOGNOTICE, "My Music: Scanning for music info using worker thread, operation took %s", StringUtils::SecondsToTimeString(tick / 1000).c_str());
    }
    if (m_scanType == 1) // load album info
    {
      for (std::set<std::string>::const_iterator it = m_pathsToScan.begin(); it != m_pathsToScan.end(); ++it)
      {
        CQueryParams params;
        CDirectoryNode::GetDatabaseInfo(*it, params);
        if (m_musicDatabase.HasAlbumBeenScraped(params.GetAlbumId())) // should this be here?
          continue;

        CAlbum album;
        m_musicDatabase.GetAlbum(params.GetAlbumId(), album);
        if (m_handle)
        {
          float percentage = (float) std::distance(it, m_pathsToScan.end()) / m_pathsToScan.size();
          m_handle->SetText(album.GetAlbumArtistString() + " - " + album.strAlbum);
          m_handle->SetPercentage(percentage);
        }

        // find album info
        ADDON::ScraperPtr scraper;
        if (!m_musicDatabase.GetScraperForPath(*it, scraper, ADDON::ADDON_SCRAPER_ALBUMS))
          continue;

        UpdateDatabaseAlbumInfo(album, scraper, false);

        if (m_bStop)
          break;
      }
    }
    if (m_scanType == 2) // load artist info
    {
      for (std::set<std::string>::const_iterator it = m_pathsToScan.begin(); it != m_pathsToScan.end(); ++it)
      {
        CQueryParams params;
        CDirectoryNode::GetDatabaseInfo(*it, params);
        if (m_musicDatabase.HasArtistBeenScraped(params.GetArtistId())) // should this be here?
            continue;

        CArtist artist;
        m_musicDatabase.GetArtist(params.GetArtistId(), artist);
        m_musicDatabase.GetArtistPath(params.GetArtistId(), artist.strPath);

        if (m_handle)
        {
          float percentage = (float) (std::distance(m_pathsToScan.begin(), it) / m_pathsToScan.size()) * 100;
          m_handle->SetText(artist.strArtist);
          m_handle->SetPercentage(percentage);
        }

        // find album info
        ADDON::ScraperPtr scraper;
        if (!m_musicDatabase.GetScraperForPath(*it, scraper, ADDON::ADDON_SCRAPER_ARTISTS) || !scraper)
          continue;

        UpdateDatabaseArtistInfo(artist, scraper, false);

        if (m_bStop)
          break;
      }
    }

  }
  catch (...)
  {
    CLog::Log(LOGERROR, "MusicInfoScanner: Exception while scanning.");
  }
  m_musicDatabase.Close();
  CLog::Log(LOGDEBUG, "%s - Finished scan", __FUNCTION__);
  
  m_bRunning = false;
  ANNOUNCEMENT::CAnnouncementManager::GetInstance().Announce(ANNOUNCEMENT::AudioLibrary, "xbmc", "OnScanFinished");
  
  // we need to clear the musicdb cache and update any active lists
  CUtil::DeleteMusicDatabaseDirectoryCache();
  CGUIMessage msg(GUI_MSG_SCAN_FINISHED, 0, 0, 0);
  g_windowManager.SendThreadMessage(msg);
  
  if (m_handle)
    m_handle->MarkFinished();
  m_handle = NULL;
}
Ejemplo n.º 12
0
INFO_RET CMusicInfoScanner::DownloadAlbumInfo(const CAlbum& album, const ADDON::ScraperPtr& info, CMusicAlbumInfo& albumInfo, CGUIDialogProgress* pDialog)
{
  if (m_handle)
  {
    m_handle->SetTitle(StringUtils::Format(g_localizeStrings.Get(20321).c_str(), info->Name().c_str()));
    m_handle->SetText(album.GetAlbumArtistString() + " - " + album.strAlbum);
  }

  // clear our scraper cache
  info->ClearCache();

  CMusicInfoScraper scraper(info);
  bool bMusicBrainz = false;
  if (!album.strMusicBrainzAlbumID.empty())
  {
    CScraperUrl musicBrainzURL;
    if (ResolveMusicBrainz(album.strMusicBrainzAlbumID, info, musicBrainzURL))
    {
      CMusicAlbumInfo albumNfo("nfo", musicBrainzURL);
      scraper.GetAlbums().clear();
      scraper.GetAlbums().push_back(albumNfo);
      bMusicBrainz = true;
    }
  }

  // handle nfo files
  std::string path = album.strPath;
  if (path.empty())
    m_musicDatabase.GetAlbumPath(album.idAlbum, path);

  std::string strNfo = URIUtils::AddFileToFolder(path, "album.nfo");
  CNfoFile::NFOResult result = CNfoFile::NO_NFO;
  CNfoFile nfoReader;
  if (XFILE::CFile::Exists(strNfo))
  {
    CLog::Log(LOGDEBUG,"Found matching nfo file: %s", CURL::GetRedacted(strNfo).c_str());
    result = nfoReader.Create(strNfo, info);
    if (result == CNfoFile::FULL_NFO)
    {
      CLog::Log(LOGDEBUG, "%s Got details from nfo", __FUNCTION__);
      nfoReader.GetDetails(albumInfo.GetAlbum());
      return INFO_ADDED;
    }
    else if (result == CNfoFile::URL_NFO || result == CNfoFile::COMBINED_NFO)
    {
      CScraperUrl scrUrl(nfoReader.ScraperUrl());
      CMusicAlbumInfo albumNfo("nfo",scrUrl);
      ADDON::ScraperPtr nfoReaderScraper = nfoReader.GetScraperInfo();
      CLog::Log(LOGDEBUG,"-- nfo-scraper: %s", nfoReaderScraper->Name().c_str());
      CLog::Log(LOGDEBUG,"-- nfo url: %s", scrUrl.m_url[0].m_url.c_str());
      scraper.SetScraperInfo(nfoReaderScraper);
      scraper.GetAlbums().clear();
      scraper.GetAlbums().push_back(albumNfo);
    }
    else if (result != CNfoFile::PARTIAL_NFO)
      CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str());
  }

  if (!scraper.CheckValidOrFallback(CServiceBroker::GetSettings().GetString(CSettings::SETTING_MUSICLIBRARY_ALBUMSSCRAPER)))
  { // the current scraper is invalid, as is the default - bail
    CLog::Log(LOGERROR, "%s - current and default scrapers are invalid.  Pick another one", __FUNCTION__);
    return INFO_ERROR;
  }

  if (!scraper.GetAlbumCount())
  {
    scraper.FindAlbumInfo(album.strAlbum, album.GetAlbumArtistString());

    while (!scraper.Completed())
    {
      if (m_bStop)
      {
        scraper.Cancel();
        return INFO_CANCELLED;
      }
      Sleep(1);
    }
  }

  CGUIDialogSelect *pDlg = NULL;
  int iSelectedAlbum=0;
  if ((result == CNfoFile::NO_NFO || result == CNfoFile::PARTIAL_NFO)
      && !bMusicBrainz)
  {
    iSelectedAlbum = -1; // set negative so that we can detect a failure
    if (scraper.Succeeded() && scraper.GetAlbumCount() >= 1)
    {
      double bestRelevance = 0;
      double minRelevance = THRESHOLD;
      if (scraper.GetAlbumCount() > 1) // score the matches
      {
        //show dialog with all albums found
        if (pDialog)
        {
          pDlg = g_windowManager.GetWindow<CGUIDialogSelect>(WINDOW_DIALOG_SELECT);
          pDlg->SetHeading(CVariant{g_localizeStrings.Get(181)});
          pDlg->Reset();
          pDlg->EnableButton(true, 413); // manual
        }

        for (int i = 0; i < scraper.GetAlbumCount(); ++i)
        {
          CMusicAlbumInfo& info = scraper.GetAlbum(i);
          double relevance = info.GetRelevance();
          if (relevance < 0)
            relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, album.strAlbum, 
                        info.GetAlbum().GetAlbumArtistString(),
                        album.GetAlbumArtistString());

          // if we're doing auto-selection (ie querying all albums at once, then allow 95->100% for perfect matches)
          // otherwise, perfect matches only
          if (relevance >= std::max(minRelevance, bestRelevance))
          { // we auto-select the best of these
            bestRelevance = relevance;
            iSelectedAlbum = i;
          }
          if (pDialog)
          {
            // set the label to [relevance]  album - artist
            std::string strTemp = StringUtils::Format("[%0.2f]  %s", relevance, info.GetTitle2().c_str());
            CFileItem item(strTemp);
            item.m_idepth = i; // use this to hold the index of the album in the scraper
            pDlg->Add(item);
          }
          if (relevance > .99f) // we're so close, no reason to search further
            break;
        }

        if (pDialog && bestRelevance < THRESHOLD)
        {
          pDlg->Sort(false);
          pDlg->Open();

          // and wait till user selects one
          if (pDlg->GetSelectedItem() < 0)
          { // none chosen
            if (!pDlg->IsButtonPressed())
              return INFO_CANCELLED;

            // manual button pressed
            std::string strNewAlbum = album.strAlbum;
            if (!CGUIKeyboardFactory::ShowAndGetInput(strNewAlbum, CVariant{g_localizeStrings.Get(16011)}, false))
              return INFO_CANCELLED;
            if (strNewAlbum == "")
              return INFO_CANCELLED;

            std::string strNewArtist = album.GetAlbumArtistString();
            if (!CGUIKeyboardFactory::ShowAndGetInput(strNewArtist, CVariant{g_localizeStrings.Get(16025)}, false))
              return INFO_CANCELLED;

            pDialog->SetLine(0, CVariant{strNewAlbum});
            pDialog->SetLine(1, CVariant{strNewArtist});
            pDialog->Progress();

            CAlbum newAlbum = album;
            newAlbum.strAlbum = strNewAlbum;
            newAlbum.strArtistDesc = strNewArtist;

            return DownloadAlbumInfo(newAlbum, info, albumInfo, pDialog);
          }
          iSelectedAlbum = pDlg->GetSelectedFileItem()->m_idepth;
        }
      }
      else
      {
        CMusicAlbumInfo& info = scraper.GetAlbum(0);
        double relevance = info.GetRelevance();
        if (relevance < 0)
          relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum,
                                            album.strAlbum,
                                            info.GetAlbum().GetAlbumArtistString(),
                                            album.GetAlbumArtistString());
        if (relevance < THRESHOLD)
          return INFO_NOT_FOUND;

        iSelectedAlbum = 0;
      }
    }

    if (iSelectedAlbum < 0)
      return INFO_NOT_FOUND;

  }

  scraper.LoadAlbumInfo(iSelectedAlbum);
  while (!scraper.Completed())
  {
    if (m_bStop)
    {
      scraper.Cancel();
      return INFO_CANCELLED;
    }
    Sleep(1);
  }

  if (!scraper.Succeeded())
    return INFO_ERROR;

  albumInfo = scraper.GetAlbum(iSelectedAlbum);
  
  if (result == CNfoFile::COMBINED_NFO || result == CNfoFile::PARTIAL_NFO)
    nfoReader.GetDetails(albumInfo.GetAlbum(), NULL, true);
  
  return INFO_ADDED;
}
Ejemplo n.º 13
0
void CGetCovers::RunEx()
{
	std::vector<CAlbum*> albumList;

	CMediaDatabase::GetAlbumsFromDatabaseNotLoaded(m_pWindow, &albumList);

	// set processbar max
	m_pProcessbar->SetMaxPosition((int) albumList.size());

	std::vector<CAlbum*>::iterator iter = albumList.begin();

	while ((iter != albumList.end()) && (!m_bPleaseStop))
	{
		CAlbum* album = *iter;
		
		std::string outfile = SallyAPI::String::PathHelper::GetDirectoryFromPath(album->GetFilename());
		outfile.append(album->GetCoverName());

		bool exists = SallyAPI::File::FileHelper::FileExists(outfile);
		
		if (exists)
		{
			// Datei exists already
			CMediaDatabase::SetAlbumInDatabase(m_pWindow, album->GetAlbum(), album->GetArtist(), true);
		}
		else
		{
			// Get it from Amazon
			bool result = false;

			result = m_AmazonCover.GetMusicCover(album->GetArtist(), album->GetAlbum(), outfile);

			if (result)
			{
				CMediaDatabase::SetAlbumInDatabase(m_pWindow, album->GetAlbum(), album->GetArtist(), true);
			}
			else
			{
				CMediaDatabase::SetAlbumInDatabase(m_pWindow, album->GetAlbum(), album->GetArtist(), false);
			}
		}
		++iter;

		// update processbar
		m_pProcessbar->SetPosition(m_pProcessbar->GetPosition() + 1);
	}

	// Delete vector
	iter = albumList.begin();
	while (iter != albumList.end())
	{
		SafeDelete(*iter);
		++iter;
	}

	if (!m_bPleaseStop)
		m_pWindow->SendMessageToParent(0, 0, m_iMessageId);
}
Ejemplo n.º 14
0
void CAddMusicAlbum::OnCommandProcessClicked(int reporterId)
{
	if (reporterId == 0)
		return;

	reporterId = reporterId - 1;

	int col = reporterId / 100;
	int row = reporterId % 100;

	std::vector<SallyAPI::GUI::CImageBox*> imageBoxVector = m_mImage[col];
	std::vector<SallyAPI::GUI::CLabelBox*> imageNameVector = m_mImageName[col];

	int fileID = (m_iStartPicture * m_iRows) + (col * m_iRows) + row - m_iRows;
	CAlbum* album = m_vAlbumList[fileID];

	m_tAlbumGetter.SetValues(dynamic_cast<SallyAPI::GUI::CAppBase*> (m_pParent), m_pAlbumTitles, album->GetAlbum(), album->GetArtist());
	m_tAlbumGetter.Start();

	m_pSmoothMoveForm->Enable(false);
	m_pFilterBackground->Enable(false);

	for (int i = 0; i < 28; ++i)
	{
		m_pCharSelector[i]->Enable(false);
	}

	// Set Album und Artist
	std::string temp = album->GetAlbum();
	temp.append("\n");
	temp.append(album->GetArtist());

	m_pAlbumName->SetText(temp);

	// move speed
	int xDistance = imageBoxVector[row]->GetPositionX() - (m_pAlbumBackground->GetPositionX() + 5);
	int yDistance = imageBoxVector[row]->GetPositionY() - (m_pAlbumBackground->GetPositionY() + 5);
	int widthDistance = (510 - 10) - imageBoxVector[row]->GetWidth();
	int heightDistance = (510 - 10) - imageBoxVector[row]->GetHeight();

	if (xDistance < 0)
		xDistance *= -1;

	if (yDistance < 0)
		yDistance *= -1;

	if (widthDistance < 0)
		widthDistance *= -1;

	if (heightDistance < 0)
		heightDistance *= -1;

	int speedX = (int) (600 * (float) ((float) xDistance / (float) widthDistance));
	int speedY = (int) (600 * (float) ((float) yDistance / (float) widthDistance));

	m_pImageBoxBig->Move(imageBoxVector[row]->GetPositionX(), imageBoxVector[row]->GetPositionY());
	m_pImageBoxBig->Resize(imageBoxVector[row]->GetWidth(), imageBoxVector[row]->GetHeight());
	m_pImageBoxBig->MoveAnimated(m_pAlbumBackground->GetPositionX() + 5, m_pAlbumBackground->GetPositionY() + 5, speedX, speedY);
	m_pImageBoxBig->ResizeAnimated(510 - 10, 510 - 10, 600);
	m_pImageBoxBig->SetPicture(imageBoxVector[row]->GetPicture());
	
	m_pImageBoxBig->SetRotationAngleY(0.0f);
	m_pImageBoxBig->SetStopAngelY(180);
	m_pImageBoxBig->RotateAnimatedY(6, false);
	m_pImageBoxBig->Visible(true);

	m_pZoomBackground->Visible(true);
	m_pZoomBackground->SetAlphaBlending(0);
	m_pZoomBackground->BlendAnimated(255, 800);
}
Ejemplo n.º 15
0
void CAddMusicAlbum::UpdateImages()
{
	EnterRenderLock();

	SallyAPI::Config::CConfig* config = SallyAPI::Config::CConfig::GetInstance(); 
	SallyAPI::Config::CTheme* theme = config->GetTheme();

	std::vector<CAlbum*>::iterator iter = m_vAlbumList.begin();

	int k = 0;
	int i = 0;

	if (m_iStartPicture == 0)
	{
		std::vector<SallyAPI::GUI::CImageBox*> imageBoxVector = m_mImage[0];
		std::vector<SallyAPI::GUI::CLabelBox*> imageNameVector = m_mImageName[0];
		std::vector<SallyAPI::GUI::CButton*> imageAddAllVector = m_mImageAddAlbum[0];

		for (int l = 0; l < m_iRows; ++l)
		{
			imageBoxVector[l]->Visible(false);
			imageNameVector[l]->Visible(false);
			imageAddAllVector[l]->Visible(false);
		}
		k = 1;
	}

	for (int l = 0; (l < (m_iStartPicture - 1) * m_iRows) && (iter != m_vAlbumList.end()); ++l)
	{
		++iter;
	}

	SallyAPI::GUI::CPicture* picture;

	while ((k < m_iCols + 2) && (iter != m_vAlbumList.end()))
	{
		std::vector<SallyAPI::GUI::CImageBox*> imageBoxVector = m_mImage[k];
		std::vector<SallyAPI::GUI::CLabelBox*> imageNameVector = m_mImageName[k];
		std::vector<SallyAPI::GUI::CButton*> imageAddAllVector = m_mImageAddAlbum[k];

		for (; (i < m_iRows) && (iter != m_vAlbumList.end()); i++)
		{
			CAlbum* album = *iter;

			std::string covername = album->GetCoverName();
			
			std::string filename = SallyAPI::String::PathHelper::GetDirectoryFromPath(album->GetFilename());
			filename = SallyAPI::String::PathHelper::CorrectPath(filename);

			filename.append(covername);

			std::string description = album->GetArtist();
			description.append("\n");
			description.append(album->GetAlbum());

			imageNameVector[i]->SetText(description);
			imageBoxVector[i]->SetText(filename);

			picture = m_mPictureMap[filename];

			// Not yet loaded... use default pic
			if (picture == NULL)
				picture = theme->GetPicture(GUI_APP_DEFAULT_CD + m_iGraphicId);

			// Now paint
			if (picture != NULL)
			{
				imageBoxVector[i]->SetPicture(picture);
				imageBoxVector[i]->Visible(true);

				/*
				int xImageBox = 0;
				int yImageBox = 0;
				imageBoxVector[i]->GetAbsolutPosition(&xImageBox, &yImageBox);

				float rotationAngleY = xImageBox - ((WINDOW_WIDTH) / 2) + MENU_WIDTH;
				rotationAngleY = rotationAngleY / 1500;

				imageBoxVector[i]->SetRotationAngleY(rotationAngleY);
				*/

				imageNameVector[i]->Visible(true);

				imageAddAllVector[i]->Visible(true);
			}
			else
			{
				imageBoxVector[i]->SetPicture(NULL);
				imageNameVector[i]->SetText("");
				imageNameVector[i]->Visible(false);
				imageAddAllVector[i]->Visible(false);
			}
			++iter;
		}
		if (iter != m_vAlbumList.end())
		{
			i = 0;
			k++;
		}
	}

	for (; k < m_iCols + 2; ++k)
	{
		std::vector<SallyAPI::GUI::CImageBox*> imageBoxVector = m_mImage[k];
		std::vector<SallyAPI::GUI::CLabelBox*> imageNameVector = m_mImageName[k];
		std::vector<SallyAPI::GUI::CButton*> imageAddAllVector = m_mImageAddAlbum[k];

		for (; i < m_iRows; ++i)
		{
			imageBoxVector[i]->Visible(false);
			imageNameVector[i]->Visible(false);
			imageAddAllVector[i]->Visible(false);
			imageNameVector[i]->SetText("");
			imageBoxVector[i]->SetPicture(NULL);
		}
		i = 0;
	}

	LeaveRenderLock();
}
Ejemplo n.º 16
0
bool CMusicThumbLoader::FillLibraryArt(CFileItem &item)
{
  /* Called for any item with MusicInfoTag and no art. 
     Items on Genres, Sources and Roles nodes have ID (although items on Years
     node do not) so check for song/album/artist specifically.
     Non-library songs (file view) can also have MusicInfoTag but no ID or type
  */
  bool artfound(false);
  std::vector<ArtForThumbLoader> art;
  CMusicInfoTag &tag = *item.GetMusicInfoTag();
  if (tag.GetDatabaseId() > -1 && (tag.GetType() == MediaTypeSong || 
      tag.GetType() == MediaTypeAlbum || 
      tag.GetType() == MediaTypeArtist))
  {
    // Item in music library, fetch the art
    m_musicDatabase->Open();
    if (tag.GetType() == MediaTypeSong)
      artfound = m_musicDatabase->GetArtForItem(tag.GetDatabaseId(), tag.GetAlbumId(), -1, false, art);
    else if (tag.GetType() == MediaTypeAlbum)
      artfound = m_musicDatabase->GetArtForItem(-1, tag.GetDatabaseId(), -1, false, art);
    else //Artist
      artfound = m_musicDatabase->GetArtForItem(-1, -1, tag.GetDatabaseId(), true, art);

    m_musicDatabase->Close();
  }
  else if (!tag.GetArtist().empty() && 
    (tag.GetType() == MediaTypeNone || tag.GetType() == MediaTypeSong))
  {
    /* 
    Could be non-library song - has musictag but no ID or type (may have
    thumb already). Try to fetch both song artist(s) and album artist(s) art by
    artist name, e.g. "artist.thumb", "artist.fanart", "artist.clearlogo",
    "artist.banner", "artist1.thumb", "artist1.fanart", "artist1.clearlogo",
    "artist1.banner", "albumartist.thumb", "albumartist.fanart" etc. 
    Set fanart as fallback.
    */
    CSong song;
    // Try to split song artist names (various tags) into artist credits
    song.SetArtistCredits(tag.GetArtist(), tag.GetMusicBrainzArtistHints(), tag.GetMusicBrainzArtistID());
    if (!song.artistCredits.empty())
    {
      tag.SetType(MediaTypeSong);  // Makes "Information" context menu visible
      m_musicDatabase->Open();
      int iOrder = 0;
      // Song artist art
      for (const auto& artistCredit : song.artistCredits)
      {
        int idArtist = m_musicDatabase->GetArtistByName(artistCredit.GetArtist());
        if (idArtist > 0)
        {
          std::vector<ArtForThumbLoader> artistart;
          if (m_musicDatabase->GetArtForItem(-1, -1, idArtist, true, artistart))
          {
            for (auto& artitem : artistart)
            {
              if (iOrder > 0)
                artitem.prefix = StringUtils::Format("artist%i", iOrder);
              else
                artitem.prefix = "artist";
            }
            art.insert(art.end(), artistart.begin(), artistart.end());
          }
        }
        ++iOrder;
      }
      // Album artist art
      if (!tag.GetAlbumArtist().empty() && tag.GetArtistString().compare(tag.GetAlbumArtistString()) != 0)
      {
        // Split song artist names correctly into artist credits from various tag
        // arrays, inc. fallback to song artist names
        CAlbum album;
        album.SetArtistCredits(tag.GetAlbumArtist(), tag.GetMusicBrainzAlbumArtistHints(), tag.GetMusicBrainzAlbumArtistID(),
          tag.GetArtist(), tag.GetMusicBrainzArtistHints(), tag.GetMusicBrainzArtistID());

        iOrder = 0;
        for (const auto& artistCredit : album.artistCredits)
        {
          int idArtist = m_musicDatabase->GetArtistByName(artistCredit.GetArtist());
          if (idArtist > 0)
          {
            std::vector<ArtForThumbLoader> artistart;
            if (m_musicDatabase->GetArtForItem(-1, -1, idArtist, true, artistart))
            {
              for (auto& artitem : artistart)
              {
                if (iOrder > 0)
                  artitem.prefix = StringUtils::Format("albumartist%i", iOrder);
                else
                  artitem.prefix = "albumartist";
              }
              art.insert(art.end(), artistart.begin(), artistart.end());
            }
          }
          ++iOrder;
        }
      }
      else
      {
        // Replicate the artist art as album artist art
        std::vector<ArtForThumbLoader> artistart;
        for (const auto& artitem : art)
        {
          ArtForThumbLoader newart;
          newart.artType = artitem.artType;
          newart.mediaType = artitem.mediaType;
          newart.prefix = "album" + artitem.prefix;
          newart.url = artitem.url;
          artistart.emplace_back(newart);
        }
        art.insert(art.end(), artistart.begin(), artistart.end());
      }
      artfound = !art.empty();
      m_musicDatabase->Close();
    }    
  }

  if (artfound)
  {
    std::string fanartfallback;
    bool bDiscSetThumbSet = false;
    std::map<std::string, std::string> artmap;
    for (auto artitem : art)
    {
      /* Add art to artmap, naming according to media type.
      For example: artists have "thumb", "fanart", "poster" etc.,
      albums have "thumb", "artist.thumb", "artist.fanart",... "artist1.thumb", "artist1.fanart" etc.,
      songs have "thumb", "album.thumb", "artist.thumb", "albumartist.thumb", "albumartist1.thumb" etc.
      */
      std::string artname;
      if (tag.GetType() == artitem.mediaType)
        artname = artitem.artType;
      else if (artitem.prefix.empty())
        artname = artitem.mediaType + "." + artitem.artType;
      else
      {
        if (tag.GetType() == MediaTypeAlbum)
          StringUtils::Replace(artitem.prefix, "albumartist", "artist");
        artname = artitem.prefix + "." + artitem.artType;
      }

      artmap.insert(std::make_pair(artname, artitem.url));

      // Add fallback art for "thumb" and "fanart" art types only
      // Set album thumb as the fallback used when song thumb is missing
      // or use extra album thumb when part of disc set
      if (tag.GetType() == MediaTypeSong && artitem.mediaType == MediaTypeAlbum)
      {
        if (artitem.artType == "thumb" && !bDiscSetThumbSet)
          item.SetArtFallback(artitem.artType, artname);
        else if (StringUtils::StartsWith(artitem.artType, "thumb"))
        {
          int number = atoi(artitem.artType.substr(5).c_str());
          if (number > 0 && tag.GetDiscNumber() == number)
          {
            item.SetArtFallback("thumb", artname);
            bDiscSetThumbSet = true;
          }
        }
      }

      // For albums and songs set fallback fanart from the artist.
      // For songs prefer primary song artist over primary albumartist fanart as fallback fanart
      if (artitem.prefix == "artist" && artitem.artType == "fanart")
        fanartfallback = artname;
      if (artitem.prefix == "albumartist" && artitem.artType == "fanart" && fanartfallback.empty())
        fanartfallback = artname;
    }
    if (!fanartfallback.empty())
      item.SetArtFallback("fanart", fanartfallback);

    item.AppendArt(artmap);
  }

  return artfound;
}