Пример #1
0
TEST_F(TestWebServer, CanNotGetNonExistingFile)
{
  std::string result;
  CCurlFile curl;
  ASSERT_FALSE(curl.Get(GetUrlOfTestFile("file_does_not_exist"), result));
  ASSERT_TRUE(result.empty());
}
Пример #2
0
void N7Xml::list_channels()
{
  CStdString strUrl;
  strUrl.Format("http://%s:%i/n7channel_nt.xml", g_strHostname.c_str(), g_iPort);
  CStdString strXML;

  CCurlFile http;
  if(!http.Get(strUrl, strXML))
  {
    XBMC->Log(LOG_DEBUG, "N7Xml - Could not open connection to N7 backend.");
  }
  else
  {
    TiXmlDocument xml;
    xml.Parse(strXML.c_str());
    TiXmlElement* rootXmlNode = xml.RootElement();
    if (rootXmlNode == NULL)
      return;
    TiXmlElement* channelsNode = rootXmlNode->FirstChildElement("channel");
    if (channelsNode)
    {
      XBMC->Log(LOG_DEBUG, "N7Xml - Connected to N7 backend.");
      m_connected = true;
      int iUniqueChannelId = 0;
      TiXmlNode *pChannelNode = NULL;
      while ((pChannelNode = channelsNode->IterateChildren(pChannelNode)) != NULL)
      {
        CStdString strTmp;
        PVRChannel channel;

        /* unique ID */
        channel.iUniqueId = ++iUniqueChannelId;

        /* channel number */
        if (!XMLUtils::GetInt(pChannelNode, "number", channel.iChannelNumber))
          channel.iChannelNumber = channel.iUniqueId;

        /* channel name */
        if (!XMLUtils::GetString(pChannelNode, "title", strTmp))
          continue;
        channel.strChannelName = strTmp;

        /* icon path */
        const TiXmlElement* pElement = pChannelNode->FirstChildElement("media:thumbnail");
        channel.strIconPath = pElement->Attribute("url");

        /* channel url */
        if (!XMLUtils::GetString(pChannelNode, "guid", strTmp))
          channel.strStreamURL = "";
        else
          channel.strStreamURL = strTmp;

        m_channels.push_back(channel);
      }
    }
  }
}
Пример #3
0
TEST_F(TestWebServer, CanGetFile)
{
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, "");
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_HTML), result));
  ASSERT_STREQ(TEST_FILES_DATA, result.c_str());

  CheckHtmlTestFileResponse(curl);
}
Пример #4
0
void MythXmlCommand::execute(const CStdString& hostname, int port, const MythXmlCommandParameters& params, MythXmlCommandResult& result, int timeout){
	CStdString strUrl = createRequestUrl(hostname, port, params);
	CStdString strXML;
	CCurlFile http;
	http.SetTimeout(timeout);
	if (http.Get(strUrl, strXML))
	{
		CLog::Log(LOGDEBUG, "Got response from mythtv backend: %s", strUrl.c_str());
	}
	http.Cancel();
	result.parseData(strXML);
}
Пример #5
0
TEST_F(TestWebServer, CanGetCachedFileWithOlderIfUnmodifiedSince)
{
  // get the last modified date of the file
  CDateTime lastModified;
  ASSERT_TRUE(GetLastModifiedOfTestFile(TEST_FILES_RANGES, lastModified));
  CDateTime lastModifiedOlder = lastModified - CDateTimeSpan(1, 0, 0, 0);

  // get the file with an older If-Unmodified-Since value
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, "");
  curl.SetRequestHeader(MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE, lastModifiedOlder.GetAsRFC1123DateTime());
  ASSERT_FALSE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
}
Пример #6
0
bool CLastFmManager::RadioHandShake()
{
  if (!m_RadioSession.IsEmpty()) return true; //already signed in

  if (dlgProgress)
  {
    dlgProgress->SetLine(2, 15251);//Connecting to Last.fm..
    dlgProgress->Progress();
  }

  m_RadioSession = "";

  CCurlFile http;
  CStdString html;

  CStdString strPassword = g_guiSettings.GetString("scrobbler.lastfmpass");
  CStdString strUserName = g_guiSettings.GetString("scrobbler.lastfmusername");
  if (strUserName.IsEmpty() || strPassword.IsEmpty())
  {
    CLog::Log(LOGERROR, "Last.fm stream selected but no username or password set.");
    return false;
  }

  CStdString passwordmd5(strPassword);
  passwordmd5.ToLower();

  CStdString url;
  CURL::Encode(strUserName);
  url.Format("http://ws.audioscrobbler.com/radio/handshake.php?version=%s&platform=%s&username=%s&passwordmd5=%s&debug=%i&partner=%s", XBMC_LASTFM_VERSION, XBMC_LASTFM_ID, strUserName, passwordmd5, 0, "");
  if (!http.Get(url, html))
  {
    CLog::Log(LOGERROR, "Connect to Last.fm radio failed.");
    return false;
  }
  //CLog::Log(LOGDEBUG, "Handshake: %s", html.c_str());

  Parameter("session",    html, m_RadioSession);
  Parameter("base_url",   html, m_RadioBaseUrl);
  Parameter("base_path",  html, m_RadioBasePath);
  Parameter("subscriber", html, m_RadioSubscriber);
  Parameter("banned",     html, m_RadioBanned);

  if (m_RadioSession.CompareNoCase("failed") == 0)
  {
    CLog::Log(LOGERROR, "Last.fm return failed response, possible bad username or password?");
    m_RadioSession = "";
  }
  return !m_RadioSession.IsEmpty();
}
Пример #7
0
TEST_F(TestWebServer, CanGetCachedFileWithExactIfModifiedSince)
{
  // get the last modified date of the file
  CDateTime lastModified;
  ASSERT_TRUE(GetLastModifiedOfTestFile(TEST_FILES_RANGES, lastModified));

  // get the file with the exact If-Modified-Since value
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, "");
  curl.SetRequestHeader(MHD_HTTP_HEADER_IF_MODIFIED_SINCE, lastModified.GetAsRFC1123DateTime());
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  ASSERT_TRUE(result.empty());
  CheckRangesTestFileResponse(curl, MHD_HTTP_NOT_MODIFIED, true);
}
Пример #8
0
TEST_F(TestWebServer, CanGetRangedFileRange0_)
{
  const std::string rangedFileContent = TEST_FILES_DATA_RANGES;
  const std::string range = "bytes=0-";

  CHttpRanges ranges;
  ASSERT_TRUE(ranges.Parse(range, rangedFileContent.size()));

  // get the whole file but specify the beginning of the range
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, range);
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  CheckRangesTestFileResponse(curl, result, ranges);
}
Пример #9
0
TEST_F(TestWebServer, CanGetRangedFileRange0_2xEnd)
{
  const std::string rangedFileContent = TEST_FILES_DATA_RANGES;
  const std::string range = GenerateRangeHeaderValue(0, rangedFileContent.size() * 2);

  CHttpRanges ranges;
  ASSERT_TRUE(ranges.Parse(range, rangedFileContent.size()));

  // get the whole file but specify a larger range
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, range);
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  CheckRangesTestFileResponse(curl, result, ranges);
}
Пример #10
0
TEST_F(TestWebServer, CanGetCachedFileWithExactIfUnmodifiedSince)
{
  // get the last modified date of the file
  CDateTime lastModified;
  ASSERT_TRUE(GetLastModifiedOfTestFile(TEST_FILES_RANGES, lastModified));

  // get the file with an older If-Unmodified-Since value
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, "");
  curl.SetRequestHeader(MHD_HTTP_HEADER_IF_UNMODIFIED_SINCE, lastModified.GetAsRFC1123DateTime());
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  EXPECT_STREQ(TEST_FILES_DATA_RANGES, result.c_str());
  CheckRangesTestFileResponse(curl);
}
Пример #11
0
TEST_F(TestWebServer, CanGetRangedFileRange_Last)
{
  const std::string rangedFileContent = TEST_FILES_DATA_RANGES;
  std::vector<std::string> rangedContent = StringUtils::Split(TEST_FILES_DATA_RANGES, ";");
  const std::string range = StringUtils::Format("bytes=-%u", static_cast<unsigned int>(rangedContent.back().size()));

  CHttpRanges ranges;
  ASSERT_TRUE(ranges.Parse(range, rangedFileContent.size()));

  // get the whole file but specify a larger range
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, range);
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  CheckRangesTestFileResponse(curl, result, ranges);
}
Пример #12
0
TEST_F(TestWebServer, CanGetRangedFileRangeFirst_Second)
{
  const std::string rangedFileContent = TEST_FILES_DATA_RANGES;
  std::vector<std::string> rangedContent = StringUtils::Split(TEST_FILES_DATA_RANGES, ";");
  const std::string range = GenerateRangeHeaderValue(rangedContent.front().size() + 1, rangedContent.front().size() + 1 + rangedContent.at(2).size() - 1);

  CHttpRanges ranges;
  ASSERT_TRUE(ranges.Parse(range, rangedFileContent.size()));

  // get the whole file but specify a larger range
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, range);
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  CheckRangesTestFileResponse(curl, result, ranges);
}
Пример #13
0
TEST_F(TestWebServer, CanGetCachedFileWithNewerIfModifiedSinceForcingNoCache)
{
  // get the last modified date of the file
  CDateTime lastModified;
  ASSERT_TRUE(GetLastModifiedOfTestFile(TEST_FILES_RANGES, lastModified));
  CDateTime lastModifiedNewer = lastModified + CDateTimeSpan(1, 0, 0, 0);

  // get the file with a newer If-Modified-Since value but forcing no caching
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, "");
  curl.SetRequestHeader(MHD_HTTP_HEADER_IF_MODIFIED_SINCE, lastModifiedNewer.GetAsRFC1123DateTime());
  curl.SetRequestHeader(MHD_HTTP_HEADER_CACHE_CONTROL, "no-cache");
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  EXPECT_STREQ(TEST_FILES_DATA_RANGES, result.c_str());
  CheckRangesTestFileResponse(curl);
}
Пример #14
0
TEST_F(TestWebServer, CanGetCachedRangedFileWithExactIfRange)
{
  const std::string rangedFileContent = TEST_FILES_DATA_RANGES;
  const std::string range = "bytes=0-";

  CHttpRanges ranges;
  ASSERT_TRUE(ranges.Parse(range, rangedFileContent.size()));

  // get the last modified date of the file
  CDateTime lastModified;
  ASSERT_TRUE(GetLastModifiedOfTestFile(TEST_FILES_RANGES, lastModified));

  // get the whole file (but ranged) with an older If-Range value
  std::string result;
  CCurlFile curl;
  curl.SetRequestHeader(MHD_HTTP_HEADER_RANGE, range);
  curl.SetRequestHeader(MHD_HTTP_HEADER_IF_RANGE, lastModified.GetAsRFC1123DateTime());
  ASSERT_TRUE(curl.Get(GetUrlOfTestFile(TEST_FILES_RANGES), result));
  CheckRangesTestFileResponse(curl, result, ranges);
}
Пример #15
0
TEST_F(TestWebServer, CanGetJsonRpcApiDescription)
{
  std::string result;
  CCurlFile curl;
  ASSERT_TRUE(curl.Get(GetUrl(TEST_URL_JSONRPC), result));
  ASSERT_FALSE(result.empty());

  // get the HTTP header details
  const CHttpHeader& httpHeader = curl.GetHttpHeader();

  // Content-Type must be "application/json"
  EXPECT_STREQ("application/json", httpHeader.GetMimeType().c_str());
  // Accept-Ranges must be "none"
  EXPECT_STREQ("none", httpHeader.GetValue(MHD_HTTP_HEADER_ACCEPT_RANGES).c_str());

  // Cache-Control must contain "mag-age=0" and "no-cache"
  std::string cacheControl = httpHeader.GetValue(MHD_HTTP_HEADER_CACHE_CONTROL);
  EXPECT_TRUE(cacheControl.find("max-age=0") != std::string::npos);
  EXPECT_TRUE(cacheControl.find("no-cache") != std::string::npos);
}
Пример #16
0
bool CPicture::CacheImage(const CStdString& sourceUrl, const CStdString& destFile, int width, int height)
{
  if (width > 0 && height > 0)
  {
    CLog::Log(LOGINFO, "Caching image from: %s to %s with width %i and height %i", sourceUrl.c_str(), destFile.c_str(), width, height);
    
    DllImageLib dll;
    if (!dll.Load()) return false;

    if (URIUtils::IsInternetStream(sourceUrl, true))
    {
      CCurlFile http;
      CStdString data;
      if (http.Get(sourceUrl, data))
      {
        if (!dll.CreateThumbnailFromMemory((BYTE *)data.c_str(), data.GetLength(), URIUtils::GetExtension(sourceUrl).c_str(), destFile.c_str(), width, height))
        {
          CLog::Log(LOGERROR, "%s Unable to create new image %s from image %s", __FUNCTION__, destFile.c_str(), sourceUrl.c_str());
          return false;
        }
        return true;
      }
      return false;
    }

    if (!dll.CreateThumbnail(sourceUrl.c_str(), destFile.c_str(), width, height, g_guiSettings.GetBool("pictures.useexifrotation")))
    {
      CLog::Log(LOGERROR, "%s Unable to create new image %s from image %s", __FUNCTION__, destFile.c_str(), sourceUrl.c_str());
      return false;
    }
    return true;
  }
  else
  {
    CLog::Log(LOGINFO, "Caching image from: %s to %s", sourceUrl.c_str(), destFile.c_str());
    return CFile::Cache(sourceUrl, destFile);
  }
}
Пример #17
0
bool CLastFmManager::ChangeStation(const CURL& stationUrl)
{
  unsigned int start = XbmcThreads::SystemClockMillis();

  InitProgressDialog(stationUrl.Get());

  StopRadio(false);
  if (!RadioHandShake())
  {
    CloseProgressDialog();
    CGUIDialogOK::ShowAndGetInput(15200, 15206, 0, 0);
    return false;
  }

  UpdateProgressDialog(15252); // Selecting station...

  CCurlFile http;
  CStdString url;
  CStdString html;

  url.Format("http://" + m_RadioBaseUrl + m_RadioBasePath + "/adjust.php?session=%s&url=%s&debug=%i", m_RadioSession, stationUrl.Get().c_str(), 0);
  if (!http.Get(url, html))
  {
    CLog::Log(LOGERROR, "Connect to Last.fm to change station failed.");
    CloseProgressDialog();
    return false;
  }
  //CLog::Log(LOGDEBUG, "ChangeStation: %s", html.c_str());

  CStdString strErrorCode;
  Parameter("error", html,  strErrorCode);
  if (strErrorCode != "")
  {
    CLog::Log(LOGERROR, "Last.fm returned an error (%s) response for change station request.", strErrorCode.c_str());
    CloseProgressDialog();
    return false;
  }

  UpdateProgressDialog(261); //Waiting for start....

  g_playlistPlayer.ClearPlaylist(PLAYLIST_MUSIC);
  RequestRadioTracks();
  CacheTrackThumb(XBMC_LASTFM_MINTRACKS);
  AddToPlaylist(XBMC_LASTFM_MINTRACKS);
  Create(); //start thread
  m_hWorkerEvent.Set(); //kickstart the thread

  CSingleLock lock(m_lockPlaylist);
  CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC);
  if ((int)playlist.size())
  {
    g_application.m_strPlayListFile = stationUrl.Get(); //needed to highlight the playing item
    g_playlistPlayer.SetCurrentPlaylist(PLAYLIST_MUSIC);
    g_playlistPlayer.Play(0);
    CLog::Log(LOGDEBUG, "%s: Done (time: %i ms)", __FUNCTION__, (int)(XbmcThreads::SystemClockMillis() - start));
    CloseProgressDialog();
    return true;
  }
  CloseProgressDialog();
  return false;
}
Пример #18
0
void CDownloadQueue::Process()
{
  CLog::Log(LOGNOTICE, "DownloadQueue ready.");

  CCurlFile http;
  bool bSuccess;

  while ( !m_bStop )
  {
    while ( CDownloadQueue::Size() > 0 )
    {
      CSingleLock lock(m_critical);

      // get the first item, but don't pop it from our queue
      // so that the download can be interrupted
      Command request = m_queue.front();
      lock.Leave();

      bool bFileRequest = request.content.length() > 0;
      DWORD dwSize = 0;

      if (bFileRequest)
      {
        CFile::Delete(request.content);
        bSuccess = http.Download(request.location, request.content, &dwSize);
      }
      else
      {
        bSuccess = http.Get(request.location, request.content);
      }

      // now re-grab the item as we may have cancelled our download
      // while we were working
      { CSingleLock lock2(m_critical); // open lock2 scope

      request = m_queue.front();
      m_queue.pop();

      // if the request has been cancelled our observer will be NULL
      if (NULL != request.observer)
      {
        try
        {
          if (bFileRequest)
          {
            request.observer->OnFileComplete(request.ticket, request.content, dwSize,
                                             bSuccess ? IDownloadQueueObserver::Succeeded : IDownloadQueueObserver::Failed );
          }
          else
          {
            request.observer->OnContentComplete(request.ticket, request.content,
                                                bSuccess ? IDownloadQueueObserver::Succeeded : IDownloadQueueObserver::Failed );
          }
        }
        catch (...)
        {
          CLog::Log(LOGERROR, "exception while updating download observer.");

          if (bFileRequest)
          {
            CFile::Delete(request.content);
          }
        }
      }
      } // close lock2 scope
    }

    Sleep(500);
  }

  CLog::Log(LOGNOTICE, "DownloadQueue terminated.");
}
Пример #19
0
void CRssReader::Process()
{
  while (GetQueueSize())
  {
    CSingleLock lock(*this);

    int iFeed = m_vecQueue.front();
    m_vecQueue.erase(m_vecQueue.begin());

    m_strFeed[iFeed] = "";
    m_strColors[iFeed] = "";

    CCurlFile http;
    http.SetUserAgent(g_settings.m_userAgent);
    http.SetTimeout(2);
    CStdString strXML;
    CStdString strUrl = m_vecUrls[iFeed];
    lock.Leave();

    int nRetries = 3;
    CURL url(strUrl);

    // we wait for the network to come up
    if ((url.GetProtocol() == "http" || url.GetProtocol() == "https") && !g_application.getNetwork().IsAvailable(true))
      strXML = "<rss><item><title>"+g_localizeStrings.Get(15301)+"</title></item></rss>";
    else
    {
      unsigned int starttime = XbmcThreads::SystemClockMillis();
      while ( (!m_bStop) && (nRetries > 0) )
      {
        unsigned int currenttimer = XbmcThreads::SystemClockMillis() - starttime;
        if (currenttimer > 15000)
        {
          CLog::Log(LOGERROR,"Timeout whilst retrieving %s", strUrl.c_str());
          http.Cancel();
          break;
        }
        nRetries--;

        if (url.GetProtocol() != "http" && url.GetProtocol() != "https")
        {
          CFile file;
          if (file.Open(strUrl))
          {
            char *yo = new char[(int)file.GetLength()+1];
            file.Read(yo,file.GetLength());
            yo[file.GetLength()] = '\0';
            strXML = yo;
            delete[] yo;
            break;
          }
        }
        else
          if (http.Get(strUrl, strXML))
          {
            CLog::Log(LOGDEBUG, "Got rss feed: %s", strUrl.c_str());
            break;
          }
      }
      http.Cancel();
    }
    if ((!strXML.IsEmpty()) && m_pObserver)
    {
      // erase any <content:encoded> tags (also unsupported by tinyxml)
      int iStart = strXML.Find("<content:encoded>");
      int iEnd = 0;
      while (iStart > 0)
      {
        // get <content:encoded> end position
        iEnd = strXML.Find("</content:encoded>", iStart) + 18;

        // erase the section
        strXML = strXML.erase(iStart, iEnd - iStart);

        iStart = strXML.Find("<content:encoded>");
      }

      if (Parse((LPSTR)strXML.c_str(),iFeed))
      {
        CLog::Log(LOGDEBUG, "Parsed rss feed: %s", strUrl.c_str());
      }
    }
  }
  UpdateObserver();
}
Пример #20
0
bool CLastFmManager::RequestRadioTracks()
{
  unsigned int start = XbmcThreads::SystemClockMillis();
  CStdString url;
  CStdString html;
  url.Format("http://" + m_RadioBaseUrl + m_RadioBasePath + "/xspf.php?sk=%s&discovery=0&desktop=", m_RadioSession);
  {
    CCurlFile http;
    if (!http.Get(url, html))
    {
      m_RadioSession.empty();
      CLog::Log(LOGERROR, "LastFmManager: Connect to Last.fm to request tracks failed.");
      return false;
    }
  }
  //CLog::Log(LOGDEBUG, "RequestRadioTracks: %s", html.c_str());

  //parse playlist
  CXBMCTinyXML xmlDoc;

  xmlDoc.Parse(html);
  if (xmlDoc.Error())
  {
    m_RadioSession.empty();
    CLog::Log(LOGERROR, "LastFmManager: Unable to parse tracklist Error: %s", xmlDoc.ErrorDesc());
    return false;
  }

  TiXmlElement* pRootElement = xmlDoc.RootElement();
  if (!pRootElement )
  {
    CLog::Log(LOGWARNING, "LastFmManager: No more tracks received");
    m_RadioSession.empty();
    return false;
  }

  TiXmlElement* pBodyElement = pRootElement->FirstChildElement("trackList");
  if (!pBodyElement )
  {
    CLog::Log(LOGWARNING, "LastFmManager: No more tracks received, no tracklist");
    m_RadioSession.empty();
    return false;
  }

  TiXmlElement* pTrackElement = pBodyElement->FirstChildElement("track");

  if (!pTrackElement)
  {
    CLog::Log(LOGWARNING, "LastFmManager: No more tracks received, empty tracklist");
    m_RadioSession.empty();
    return false;
  }
  while (pTrackElement)
  {
    CFileItemPtr newItem(new CFileItem);

    TiXmlElement* pElement = pTrackElement->FirstChildElement("location");
    if (pElement)
    {
      TiXmlNode* child = pElement->FirstChild();
      if (child)
      {
        CStdString url = child->Value();
        url.Replace("http:", "lastfm:");
        newItem->SetPath(url);
      }
    }
    pElement = pTrackElement->FirstChildElement("title");
    if (pElement)
    {
      TiXmlNode* child = pElement->FirstChild();
      if (child)
      {
        newItem->SetLabel(child->Value());
        newItem->GetMusicInfoTag()->SetTitle(child->Value());
      }
    }
    pElement = pTrackElement->FirstChildElement("creator");
    if (pElement)
    {
      TiXmlNode* child = pElement->FirstChild();
      if (child)
      {
        newItem->GetMusicInfoTag()->SetArtist(child->Value());
      }
    }
    pElement = pTrackElement->FirstChildElement("album");
    if (pElement)
    {
      TiXmlNode* child = pElement->FirstChild();
      if (child)
      {
        newItem->GetMusicInfoTag()->SetAlbum(child->Value());
      }
    }

    pElement = pTrackElement->FirstChildElement("duration");
    if (pElement)
    {
      TiXmlNode* child = pElement->FirstChild();
      if (child)
      {
        int iDuration = atoi(child->Value())/1000;
        newItem->GetMusicInfoTag()->SetDuration(iDuration);
      }
    }
    newItem->FillInDefaultIcon();
    pElement = pTrackElement->FirstChildElement("image");
    if (pElement)
    {
      TiXmlNode* child = pElement->FirstChild();
      if (child)
      {
        CStdString coverUrl = child->Value();
        if ((coverUrl != "") && (coverUrl.Find("noimage") == -1) && (coverUrl.Right(1) != "/"))
        {
          newItem->SetThumbnailImage(coverUrl);
        }
      }
    }
    //trackauth is needed for validating the track when scrobbling
    pElement = pTrackElement->FirstChildElement("lastfm:trackauth");
    if (pElement)
    {
      TiXmlNode* child = pElement->FirstChild();
      if (child)
      {
        CStdString trackAuth = child->Value();
        //abuse comment field for the track authcode
        newItem->GetMusicInfoTag()->SetComment(trackAuth);
      }
    }

    {
      CSingleLock lock(m_lockCache);
      m_RadioTrackQueue->Add(newItem);
    }
    pTrackElement = pTrackElement->NextSiblingElement();
  }
  //end parse
  CSingleLock lock(m_lockCache);
  int iNrCachedTracks = m_RadioTrackQueue->size();
  CLog::Log(LOGDEBUG, "%s: Done (time: %i ms)", __FUNCTION__, (int)(XbmcThreads::SystemClockMillis() - start));
  return iNrCachedTracks > 0;
}
Пример #21
0
void CRssReader::Process()
{
  while (GetQueueSize())
  {
    CSingleLock lock(m_critical);

    int iFeed = m_vecQueue.front();
    m_vecQueue.erase(m_vecQueue.begin());

    m_strFeed[iFeed].clear();
    m_strColors[iFeed].clear();

    CCurlFile http;
    http.SetUserAgent(g_advancedSettings.m_userAgent);
    http.SetTimeout(2);
    std::string strXML;
    std::string strUrl = m_vecUrls[iFeed];
    lock.Leave();

    int nRetries = 3;
    CURL url(strUrl);
    std::string fileCharset;

    // we wait for the network to come up
    if ((url.IsProtocol("http") || url.IsProtocol("https")) &&
        !g_application.getNetwork().IsAvailable())
    {
      CLog::Log(LOGWARNING, "RSS: No network connection");
      strXML = "<rss><item><title>"+g_localizeStrings.Get(15301)+"</title></item></rss>";
    }
    else
    {
      XbmcThreads::EndTime timeout(15000);
      while (!m_bStop && nRetries > 0)
      {
        if (timeout.IsTimePast())
        {
          CLog::Log(LOGERROR, "Timeout while retrieving rss feed: %s", strUrl.c_str());
          break;
        }
        nRetries--;

        if (!url.IsProtocol("http") && !url.IsProtocol("https"))
        {
          CFile file;
          auto_buffer buffer;
          if (file.LoadFile(strUrl, buffer) > 0)
          {
            strXML.assign(buffer.get(), buffer.length());
            break;
          }
        }
        else
        {
          if (http.Get(strUrl, strXML))
          {
            fileCharset = http.GetServerReportedCharset();
            CLog::Log(LOGDEBUG, "Got rss feed: %s", strUrl.c_str());
            break;
          }
          else if (nRetries > 0)
            Sleep(5000); // Network problems? Retry, but not immediately.
          else
            CLog::Log(LOGERROR, "Unable to obtain rss feed: %s", strUrl.c_str());
        }
      }
      http.Cancel();
    }
    if (!strXML.empty() && m_pObserver)
    {
      // erase any <content:encoded> tags (also unsupported by tinyxml)
      size_t iStart = strXML.find("<content:encoded>");
      size_t iEnd = 0;
      while (iStart != std::string::npos)
      {
        // get <content:encoded> end position
        iEnd = strXML.find("</content:encoded>", iStart) + 18;

        // erase the section
        strXML = strXML.erase(iStart, iEnd - iStart);

        iStart = strXML.find("<content:encoded>");
      }

      if (Parse(strXML, iFeed, fileCharset))
        CLog::Log(LOGDEBUG, "Parsed rss feed: %s", strUrl.c_str());
    }
  }
  UpdateObserver();
}
Пример #22
0
void CRssReader::Process()
{
  while (GetQueueSize())
  {
    CSingleLock lock(m_critical);

    int iFeed = m_vecQueue.front();
    m_vecQueue.erase(m_vecQueue.begin());

    m_strFeed[iFeed] = "";
    m_strColors[iFeed] = "";

    CCurlFile http;
    http.SetUserAgent(g_advancedSettings.m_userAgent);
    http.SetTimeout(2);
    CStdString strXML;
    CStdString strUrl = m_vecUrls[iFeed];
    lock.Leave();

    int nRetries = 3;
    CURL url(strUrl);

    // we wait for the network to come up
    if ((url.GetProtocol() == "http" || url.GetProtocol() == "https") &&
        !g_application.getNetwork().IsAvailable(true))
      strXML = "<rss><item><title>"+g_localizeStrings.Get(15301)+"</title></item></rss>";
    else
    {
      XbmcThreads::EndTime timeout(15000);
      while (!m_bStop && nRetries > 0)
      {
        if (timeout.IsTimePast())
        {
          CLog::Log(LOGERROR, "Timeout whilst retrieving %s", strUrl.c_str());
          http.Cancel();
          break;
        }
        nRetries--;

        if (url.GetProtocol() != "http" && url.GetProtocol() != "https")
        {
          void* bufferPtr;
          const unsigned int fsize = CFileUtils::LoadFile(strUrl, bufferPtr);
          if (fsize != 0)
          {
            strXML.assign((const char*)bufferPtr, fsize);
            free(bufferPtr);
            break;
          }
        }
        else
          if (http.Get(strUrl, strXML))
          {
            CLog::Log(LOGDEBUG, "Got rss feed: %s", strUrl.c_str());
            break;
          }
      }
      http.Cancel();
    }
    if (!strXML.IsEmpty() && m_pObserver)
    {
      // erase any <content:encoded> tags (also unsupported by tinyxml)
      int iStart = strXML.Find("<content:encoded>");
      int iEnd = 0;
      while (iStart > 0)
      {
        // get <content:encoded> end position
        iEnd = strXML.Find("</content:encoded>", iStart) + 18;

        // erase the section
        strXML = strXML.erase(iStart, iEnd - iStart);

        iStart = strXML.Find("<content:encoded>");
      }

      if (Parse((LPSTR)strXML.c_str(), iFeed))
        CLog::Log(LOGDEBUG, "Parsed rss feed: %s", strUrl.c_str());
    }
  }
  UpdateObserver();
}