コード例 #1
0
bool CMusicInfoScanner::DownloadAlbumInfo(const CStdString& strPath, const CStdString& strArtist, const CStdString& strAlbum, bool& bCanceled, CMusicAlbumInfo& albumInfo, CGUIDialogProgress* pDialog)
{
  CAlbum album;
  VECSONGS songs;
  DIRECTORY::MUSICDATABASEDIRECTORY::CQueryParams params;
  DIRECTORY::MUSICDATABASEDIRECTORY::CDirectoryNode::GetDatabaseInfo(strPath, params);
  bCanceled = false;
  m_musicDatabase.Open();
  if (m_musicDatabase.HasAlbumInfo(params.GetAlbumId()) && m_musicDatabase.GetAlbumInfo(params.GetAlbumId(),album,&songs))
    return true;

  // find album info
  SScraperInfo info;
  if (!m_musicDatabase.GetScraperForPath(strPath,info))
  {
    m_musicDatabase.Close();
    return false;
  }

  if (m_pObserver)
  {
    m_pObserver->OnStateChanged(DOWNLOADING_ALBUM_INFO);
    m_pObserver->OnDirectoryChanged(strAlbum);
  }

  CMusicInfoScraper scraper(info);

  // handle nfo files
  CStdString strAlbumPath, strNfo;
  m_musicDatabase.GetAlbumPath(params.GetAlbumId(),strAlbumPath);
  CUtil::AddFileToFolder(strAlbumPath,"album.nfo",strNfo);
  if (XFILE::CFile::Exists(strNfo))
  {
    CLog::Log(LOGDEBUG,"Found matching nfo file: %s", strNfo.c_str());
    CNfoFile nfoReader("albums");
    if (nfoReader.Create(strNfo) == S_OK)
    {
      if (nfoReader.m_strScraper == "NFO")
      {
        CLog::Log(LOGDEBUG, "%s Got details from nfo", __FUNCTION__);
        CAlbum album;
        VECSONGS songs;
        nfoReader.GetDetails(album);
        m_musicDatabase.SetAlbumInfo(params.GetAlbumId(), album, songs);
        m_musicDatabase.Close();
        return true;
      }
      else
      {
        CScraperUrl scrUrl(nfoReader.m_strImDbUrl); 
        CMusicAlbumInfo album("nfo",scrUrl);
        scraper.GetAlbums().push_back(album);
      }
    }
    else
      CLog::Log(LOGERROR,"Unable to find an url in nfo file: %s", strNfo.c_str());
  }

  if (!scraper.GetAlbumCount())
    scraper.FindAlbuminfo(strAlbum, strArtist);

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

  CGUIDialogSelect *pDlg=NULL;
  int iSelectedAlbum=0;
  if (scraper.Successfull() && scraper.GetAlbumCount() >= 1)
  {
    int bestMatch = 0;
    double bestRelevance = 0;
    double minRelevance = THRESHOLD;
    if (scraper.GetAlbumCount() > 1) // score the matches
    {
      //show dialog with all albums found
      if (pDialog)
      {
        pDlg = (CGUIDialogSelect*)m_gWindowManager.GetWindow(WINDOW_DIALOG_SELECT);
        pDlg->SetHeading(g_localizeStrings.Get(181).c_str());
        pDlg->Reset();
        pDlg->EnableButton(true);
        pDlg->SetButtonLabel(413); // manual
      }

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

        // 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 >= max(minRelevance, bestRelevance))
        { // we auto-select the best of these
          secondBestRelevance = bestRelevance;
          bestRelevance = relevance;
          bestMatch = i;
        }
        if (pDialog)
        {
          // set the label to [relevance]  album - artist
          CStdString strTemp;
          strTemp.Format("[%0.2f]  %s", relevance, info.GetTitle2());
          CFileItem item(strTemp);
          item.m_idepth = i; // use this to hold the index of the album in the scraper
          pDlg->Add(&item);
        }
      }
    }
    else
    {
      CMusicAlbumInfo& info = scraper.GetAlbum(0);
      double relevance = CUtil::AlbumRelevance(info.GetAlbum().strAlbum, strAlbum, info.GetAlbum().strArtist, strArtist);
      if (relevance < THRESHOLD)
      {
        m_musicDatabase.Close();
        return false; 
      }
   }

    iSelectedAlbum = bestMatch;
    if (pDialog && bestRelevance < THRESHOLD)
    {
      pDlg->Sort(false);
      pDlg->DoModal();

      // and wait till user selects one
      if (pDlg->GetSelectedLabel() < 0) 
      { // none chosen
        if (!pDlg->IsButtonPressed()) 
        {
          bCanceled = true;
          return false;
        }
        // manual button pressed
        CStdString strNewAlbum = strAlbum;
        if (!CGUIDialogKeyboard::ShowAndGetInput(strNewAlbum, g_localizeStrings.Get(16011), false)) return false;
        if (strNewAlbum == "") return false;

        CStdString strNewArtist = strArtist;
        if (!CGUIDialogKeyboard::ShowAndGetInput(strNewArtist, g_localizeStrings.Get(16025), false)) return false;

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

        m_musicDatabase.Close();
        return DownloadAlbumInfo(strPath,strArtist,strAlbum,bCanceled,albumInfo,pDialog);
      }
      iSelectedAlbum = pDlg->GetSelectedItem().m_idepth;
    }
  }
  else
  {
    m_musicDatabase.Close();
    return false;
  }

  scraper.LoadAlbuminfo(iSelectedAlbum);
  while (!scraper.Completed())
  {
    if (m_bStop)
    {
      scraper.Cancel();
      break;
    }
    Sleep(1);
  }

  if (scraper.Successfull())
  {
    albumInfo = scraper.GetAlbum(iSelectedAlbum);
    album = scraper.GetAlbum(iSelectedAlbum).GetAlbum();
    m_musicDatabase.SetAlbumInfo(params.GetAlbumId(), album, scraper.GetAlbum(iSelectedAlbum).GetSongs(),false);
  }
  else
  {
    m_musicDatabase.Close();
    return false;
  }

  // check thumb stuff
  if (album.thumbURL.m_url.size())
  {
    CStdString thumb;
    if (!m_musicDatabase.GetAlbumThumb(params.GetAlbumId(),thumb) || thumb.IsEmpty() || !XFILE::CFile::Exists(thumb))
    {
      thumb = CUtil::GetCachedAlbumThumb(album.strAlbum,album.strArtist);
      CScraperUrl::DownloadThumbnail(thumb,album.thumbURL.m_url[0]);
      m_musicDatabase.SaveAlbumThumb(params.GetAlbumId(), thumb);
    }
  }

  m_musicDatabase.Close();
  return true;
}
コード例 #2
0
bool CMetadataResolverMusic::GetMetadataFromAMG(const CStdString& _strAlbum, const CStdString& _strArtist,MUSIC_GRABBER::CMusicAlbumInfo& album)
{
  CStdString strAlbum = _strAlbum;
  strAlbum = strAlbum.ToLower();

  CStdString strArtist = _strArtist;
  strArtist = strArtist.ToLower();

  // This function can resolve by album only, so we do not care about the artist at this point
  if (strAlbum.IsEmpty() || strArtist.IsEmpty()) 
    return false;

  SScraperInfo info;
  info.strPath = "allmusic.xml";
  info.strContent = "albums";

  int iRetries = 2;

  while (iRetries-- > 0) 
  {
    MUSIC_GRABBER::CMusicInfoScraper scraper(info);

    scraper.SetAlbum(strAlbum);
    scraper.SetArtist(strArtist);

    scraper.FindAlbuminfo();
    scraper.LoadAlbuminfo();

    int iSelectedAlbum = 0;

        while (!scraper.Completed() && !scraper.IsCanceled())
        {
          if (m_bStopped)
          {
            if (!scraper.IsCanceled())
            {
              //CLog::Log(LOGDEBUG, "LIBRARY: Boxee Metadata Resolver, Canceling scraper");
              scraper.Cancel();
              break;
            }
          }
          Sleep(200);
        }

    if (scraper.Successfull() && scraper.GetAlbumCount() > 0)
    {
      // did we found at least 1 album?
      int iAlbumCount = scraper.GetAlbumCount();
      if (iAlbumCount >= 1)
      {
        if (iAlbumCount > 1)
        {
          int bestMatch = -1;

          double minRelevance;

          minRelevance = 0.7;

          double bestRelevance = 0;
          double secondBestRelevance = 0;

          for (int i = 0; i < iAlbumCount; ++i)
          {
            MUSIC_GRABBER::CMusicAlbumInfo& info = scraper.GetAlbum(i);

            CStdString  strFoundAlbum = info.GetAlbum().strAlbum; 
            strFoundAlbum.MakeLower();
            CStdString  strFoundArtist = info.GetAlbum().strArtist; 
            strFoundArtist.MakeLower();

            bool bFoundSoundtrack = false;


            if ((strFoundAlbum.Find("soundtrack") != -1) || (strFoundArtist.Find("soundtrack") != -1))
            {
              bFoundSoundtrack = true;
              // reset found artist in order to avoid artist comparison
              strFoundArtist = "";

              //strFoundAlbum = CleanAlbumName(strFoundAlbum);

              // check if we can remove the "[original soundtrack]" token
              int pos = strFoundAlbum.Find("[original soundtrack]");
              if (pos != -1) 
              {
                strFoundAlbum.erase(pos, 21);
              }
              else
              {
                // try to remove words separately
                int pos1 = strFoundAlbum.Find("soundtrack");
                if (pos1 != -1)
                {
                  strFoundAlbum.erase(pos1, 10);
                }

                int pos2 = strFoundAlbum.Find("original");
                if (pos2 != -1) 
                {
                  strFoundAlbum.erase(pos2, 8);
                }
              }
            }


            // TODO: Check if originally we were looking for a soundtrack
            // Check if we need a sound track
            //            if (pContext->bIsSoundtrack && !bFoundSoundtrack)
            //            {
            //              continue;
            //            }

            double relevance = CUtil::AlbumRelevance(strFoundAlbum, strAlbum, strFoundArtist, strArtist);

            // 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
              secondBestRelevance = bestRelevance;
              bestRelevance = relevance;
              bestMatch = i;
            }
          }


          if (bestMatch > -1 && bestRelevance != secondBestRelevance)
          { // autochoose the single best matching item
            iSelectedAlbum = bestMatch;
          }
          else
          { //  nothing found, or two equal matches to choose from
            // perform additional checks

            return false;
          }

        }
      }
      else {
        return false;
      }

      MUSIC_GRABBER::CMusicAlbumInfo info = scraper.GetAlbum(iSelectedAlbum);

      // Save album and artist names as they get erased in the process
      CStdString strTempAlbumName = info.GetAlbum().strAlbum;
      CStdString strTempArtistName = info.GetAlbum().strArtist;

      scraper.LoadAlbuminfo(iSelectedAlbum);
      while (!scraper.Completed() && !scraper.IsCanceled())
      {
        //        if (m_bStopped)
        //        {
        //          if (!scraper.IsCanceled()) {
        //            scraper.Cancel();
        //          }
        //        }
        Sleep(200);
      }

      if (!scraper.IsCanceled() && scraper.Successfull()) 
      {
        album = scraper.GetAlbum(iSelectedAlbum);

        // Restore erased fields
        album.GetAlbum().strAlbum = strTempAlbumName;
        album.GetAlbum().strArtist = strTempArtistName;  

        return true;
      }
      else {
        if (scraper.HadNetworkProblems()) {
          Sleep(500);
          continue;
        }
        return false;
      }
    }
    else {
      if (scraper.HadNetworkProblems()) {
        Sleep(500);
        continue;

      }
      return false;
    }
  } // while retries

  return false;
}