Example #1
0
void CFileRar::InitFromUrl(const CURL& url)
{
  url.GetURL(m_strUrl);
  m_strCacheDir = g_advancedSettings.m_cachePath;//url.GetDomain();
  if (!CUtil::HasSlashAtEnd(m_strCacheDir))
    m_strCacheDir += "/"; // should work local and remote..
	m_strRarPath = url.GetHostName();
	m_strPassword = url.GetUserName();
	m_strPathInRar = url.GetFileName();  

  std::vector<CStdString> options;
  CUtil::Tokenize(url.GetOptions().Mid(1), options, "&");
  
	m_bFileOptions = 0;
	m_bRarOptions = 0;

  for( std::vector<CStdString>::iterator it = options.begin();it != options.end(); it++)
  {
    int iEqual = (*it).Find('=');
    if( iEqual >= 0 )
    {
      CStdString strOption = (*it).Left(iEqual);
      CStdString strValue = (*it).Mid(iEqual+1);

      if( strOption.Equals("flags") )
        m_bFileOptions = atoi(strValue.c_str());
      else if( strOption.Equals("cache") )
        m_strCacheDir = strValue;
    }
  }

}
Example #2
0
 CFileItemPtr BuildFileItem(const CURL& url, TiXmlElement& el)
 {
   CFileItemPtr pItem(new CFileItem());
   pItem->m_bIsFolder = true;
   
   const char* key = el.Attribute("key");
   if (key == 0 || strlen(key) == 0)
     return CFileItemPtr();
     
   string src = key;
   CStdString parentPath;
   url.GetURL(parentPath);
   
   // Compute the new path.
   pItem->m_strPath = CPlexDirectory::ProcessUrl(parentPath, src, true);
   
   // Let subclass finish.
   DoBuildFileItem(pItem, string(parentPath), el);
   
   // Date.
   const char* date = el.Attribute("subtitle"); 
   if (date && strlen(date) > 0)
     pItem->SetProperty("subtitle", date);
   
   try
   {
     // Thumb.
     const char* thumb = el.Attribute("thumb"); 
     if (thumb && strlen(thumb) > 0)
     {
       string strThumb = CPlexDirectory::ProcessUrl(parentPath, thumb, false);
       pItem->SetThumbnailImage(strThumb);
     }
     
     // Fanart.
     const char* fanart = el.Attribute("art");
     string strFanart;
     if (fanart && strlen(fanart) > 0)
     {
       strFanart = CPlexDirectory::ProcessUrl(parentPath, fanart, false);
       pItem->SetQuickFanart(strFanart);
     } 
   }
   catch (...)
   {
     printf("ERROR: Exception setting directory thumbnail.\n");
   }
   
   // Make sure we have the trailing slash.
   if (pItem->m_bIsFolder == true && pItem->m_strPath[pItem->m_strPath.size()-1] != '/')
     pItem->m_strPath += "/";
   
   return pItem;
 }
Example #3
0
void CPlexDirectory::Parse(const CURL& url, TiXmlElement* root, CFileItemList &items, string& strFileLabel, string& strDirLabel, string& strSecondDirLabel)
{
  PlexMediaNode* mediaNode = 0;
  
  for (TiXmlElement* element = root->FirstChildElement(); element; element=element->NextSiblingElement())
  {
    mediaNode = PlexMediaNode::Create(element->Value());
    if (mediaNode != 0)
    {
      CFileItemPtr item = mediaNode->BuildFileItem(url, *element);
      if (item)
        items.Add(item);
    }
  }
  
  if (mediaNode != 0)
  {
    CStdString strURL;
    url.GetURL(strURL);
    mediaNode->ComputeLabels(strURL, strFileLabel, strDirLabel, strSecondDirLabel);
  }
}
bool CShoutcastDirectory::ParseGenres(TiXmlElement *root, CFileItemList &items, CURL &url)
{
  TiXmlElement *element = root->FirstChildElement("genre");
  
  if(element == NULL)
  {
    CLog::Log(LOGWARNING, "%s - No genres found", __FUNCTION__);
    return false;
  }
    
  items.m_idepth = 1; /* genre list */

  CStdString genre, path;
  while(element != NULL)
  {
    genre = element->Attribute("name");
    path = genre;

    /* genre must be urlencoded */
    CUtil::URLEncode(path);

    url.SetOptions("?genre=" + path);
    url.GetURL(path);


    CFileItem* pItem = new CFileItem;
    pItem->m_bIsFolder = true;
    pItem->SetLabel(genre);
    pItem->GetMusicInfoTag()->SetGenre(genre);
    pItem->m_strPath = path;  
    
    items.Add(pItem);

    element = element->NextSiblingElement("genre");
  }

  return true;
}
Example #5
0
//*********************************************************************************************
int CFileRar::Stat(const CURL& url, struct __stat64* buffer)
{
  if (Open(url, true))
  {
    buffer->st_size = GetLength();
    buffer->st_mode = _S_IFREG;
    Close();
    errno = 0;
    return 0;
  }

  CStdString strURL;
  url.GetURL(strURL);

  if (CDirectory::Exists(strURL))
  {
    buffer->st_mode = _S_IFDIR;
    return 0;
  }

  errno = ENOENT;
  return -1;
}
Example #6
0
bool CLastFmManager::ChangeStation(const CURL& stationUrl)
{
  DWORD start = timeGetTime();

  CStdString strUrl;
  stationUrl.GetURL(strUrl);

  InitProgressDialog(strUrl);

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

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

  CHTTP http;
  CStdString url;
  CStdString html;
  url.Format("http://" + m_RadioBaseUrl + m_RadioBasePath + "/adjust.php?session=%s&url=%s&debug=%i", m_RadioSession, strUrl, 0);
  if (!http.Get(url, html)) 
  {
    CLog::Log(LOGERROR, "Connect to Last.fm to change station failed.");
    CloseProgressDialog();
    return false;
  }
  //CLog::DebugLog("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);
  g_playlistPlayer.SetShuffle(PLAYLIST_MUSIC, false);
  g_playlistPlayer.SetRepeat(PLAYLIST_MUSIC, PLAYLIST::REPEAT_NONE);
  RequestRadioTracks();
  CacheTrackThumb(XBMC_LASTFM_MINTRACKS);
  AddToPlaylist(XBMC_LASTFM_MINTRACKS);
  Create(); //start thread
  SetEvent(m_hWorkerEvent); //kickstart the thread

  CSingleLock lock(m_lockPlaylist);
  CPlayList& playlist = g_playlistPlayer.GetPlaylist(PLAYLIST_MUSIC);
  if ((int)playlist.size())
  {
    g_application.m_strPlayListFile = strUrl; //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)(timeGetTime() - start));
    CloseProgressDialog();
    return true;
  }
  CloseProgressDialog();
  return false;
}
bool CShoutcastDirectory::ParseStations(TiXmlElement *root, CFileItemList &items, CURL &url)
{
  TiXmlElement *element = NULL;
  CStdString path;

  items.m_idepth = 2; /* station list */

  element = root->FirstChildElement("tunein");
  if(element == NULL) 
  {
    CLog::Log(LOGWARNING, "%s - No tunein base found", __FUNCTION__);
    return false;
  }
  
  path = element->Attribute("base");
  path.TrimLeft("/");

  url.SetFileName(path);

  element = root->FirstChildElement("station");

  if(element == NULL)
  {
    CLog::Log(LOGWARNING, "%s - No stations found", __FUNCTION__);
    return false;
  }
  int stations = 0;
  while(element != NULL && stations < 1000)
  {
    CStdString name = element->Attribute("name");
    CStdString id = element->Attribute("id");
    CStdString bitrate = element->Attribute("br");
    CStdString genre = element->Attribute("genre");
    CStdString listeners = element->Attribute("lc");
    CStdString content = element->Attribute("mt");

    CStdString label = name;

    url.SetOptions("?id=" + id);
    url.GetURL(path);
    //printf("%s: %s\n", name.c_str(), path.c_str());

    CFileItem* pItem = new CFileItem;
    pItem->m_bIsFolder = false;
    
    /* we highjack the music tag for this stuff, they will be used by */
    /* viewstates to sort and display proper information */
    pItem->GetMusicInfoTag()->SetArtist(listeners);
    pItem->GetMusicInfoTag()->SetAlbum(bitrate);
    pItem->GetMusicInfoTag()->SetGenre(genre);

    /* this is what will be sorted upon */
    pItem->GetVideoInfoTag()->m_fRating = (float)atoi(listeners.c_str());
    pItem->m_dwSize = atoi(bitrate.c_str());


    pItem->SetLabel(label);

    /* content type is known before hand, should save later lookup */
    /* wonder if we could combine the contentype of the playlist and of the real stream */
    pItem->SetContentType("audio/x-scpls");

    pItem->m_strPath = path;
    
    items.Add(pItem);

    stations++;
    element = element->NextSiblingElement("station");
  }

  return true;
}
Example #8
0
//*********************************************************************************************
bool CFileRar::Open(const CURL& url, bool bBinary)
{
  CStdString strFile; 
  url.GetURL(strFile);
  
  InitFromUrl(url);
  CFileItemList items;
  g_RarManager.GetFilesInRar(items,m_strRarPath,false);
  int i;
  for (i=0;i<items.Size();++i)
  {
    if (items[i]->GetLabel() == m_strPathInRar)
      break;
  }

  if (i<items.Size())
    if (items[i]->m_idepth == 0x30) // stored
    {
      if (!OpenInArchive())
        return false;

      m_iFileSize = items[i]->m_dwSize;
      m_bOpen = true;
      
      // perform 'noidx' check
      CFileInfo* pFile = g_RarManager.GetFileInRar(m_strRarPath,m_strPathInRar);
      if (pFile)
        if (pFile->m_iIsSeekable == -1)
        {
          if (Seek(-1,SEEK_END) == -1)
          {
            m_bSeekable = false;
            pFile->m_iIsSeekable = 0;
          }
        }
        else
         m_bSeekable = (pFile->m_iIsSeekable == 1);

        return true;
    }
    else 
    {
#ifdef HAS_XBOX_HARDWARE
      if (items[i]->m_dwSize > ((__int64)4)*1024*1024*1024) // 4 gig limit of fat-x
      {
        CGUIDialogOK::ShowAndGetInput(257,21395,-1,-1);
        CLog::Log(LOGERROR,"CFileRar::Open: Can't cache files bigger than 4GB due to fat-x limits.");
        return false;
      }
#endif
      m_bUseFile = true;
      CStdString strPathInCache;
      
      if (!g_RarManager.CacheRarredFile(strPathInCache, m_strRarPath, m_strPathInRar, EXFILE_AUTODELETE | m_bFileOptions, m_strCacheDir, items[i]->m_dwSize))
      {
      	CLog::Log(LOGERROR,"filerar::open failed to cache file %s",m_strPathInRar.c_str());
        return false;
      }
      
      if (!m_File.Open( strPathInCache, bBinary)) 
      {
		CLog::Log(LOGERROR,"filerar::open failed to open file in cache: %s",strPathInCache.c_str());
        return false;
      }
      
      m_bOpen = true;
      return true;
    }

  return false;
}
Example #9
0
bool CFileShoutcast::Open(const CURL& url, bool bBinary)
{
  m_dwLastTime = timeGetTime();
  int ret;

  CGUIDialogProgress* dlgProgress = (CGUIDialogProgress*)m_gWindowManager.GetWindow(WINDOW_DIALOG_PROGRESS);

  set_rip_manager_options_defaults(&m_opt);

  strcpy(m_opt.output_directory, "./");
  m_opt.proxyurl[0] = '\0';

  // Use a proxy, if the GUI was configured as such
  bool bProxyEnabled = g_guiSettings.GetBool("network.usehttpproxy");
  if (bProxyEnabled)
  {
    const CStdString &strProxyServer = g_guiSettings.GetString("network.httpproxyserver");
    const CStdString &strProxyPort = g_guiSettings.GetString("network.httpproxyport");
	  // Should we check for valid strings here
#ifndef _LINUX
	  _snprintf( m_opt.proxyurl, MAX_URL_LEN, "http://%s:%s", strProxyServer.c_str(), strProxyPort.c_str() );
#else
	  snprintf( m_opt.proxyurl, MAX_URL_LEN, "http://%s:%s", strProxyServer.c_str(), strProxyPort.c_str() );
#endif
  }

  CStdString strUrl;
  url.GetURL(strUrl);
  strUrl.Replace("shout://", "http://");
  printf("Opening url: %s\n", strUrl.c_str());
  strncpy(m_opt.url, strUrl.c_str(), MAX_URL_LEN);
  sprintf(m_opt.useragent, "x%s", url.GetFileName().c_str());
  if (dlgProgress)
  {
    dlgProgress->SetHeading(260);
    dlgProgress->SetLine(0, 259);
    dlgProgress->SetLine(1, strUrl);
    dlgProgress->SetLine(2, "");
    if (!dlgProgress->IsDialogRunning())
      dlgProgress->StartModal();
    dlgProgress->Progress();
  }

  if ((ret = rip_manager_start(rip_callback, &m_opt)) != SR_SUCCESS)
  {
    if (dlgProgress) dlgProgress->Close();
    return false;
  }
  int iShoutcastTimeout = 10 * SHOUTCASTTIMEOUT; //i.e: 10 * 10 = 100 * 100ms = 10s
  int iCount = 0;
  while (!m_fileState.bRipDone && !m_fileState.bRipStarted && !m_fileState.bRipError && (!dlgProgress || !dlgProgress->IsCanceled()))
  {
    if (iCount <= iShoutcastTimeout) //Normally, this isn't the problem,
      //because if RIP_MANAGER fails, this would be here
      //with m_fileState.bRipError
    {
      Sleep(100);
    }
    else
    {
      if (dlgProgress)
      {
        dlgProgress->SetLine(1, 257);
        dlgProgress->SetLine(2, "Connection timed out...");
        Sleep(1500);
        dlgProgress->Close();
      }
      return false;
    }
    iCount++;
  }
  
  if (dlgProgress && dlgProgress->IsCanceled())
  {
     Close();
     dlgProgress->Close();
     return false;
  }

  /* store content type of stream */
  m_contenttype = rip_manager_get_content_type();

  //CHANGED CODE: Don't reset timer anymore.

  while (!m_fileState.bRipDone && !m_fileState.bRipError && m_fileState.bBuffering && (!dlgProgress || !dlgProgress->IsCanceled()))
  {
    if (iCount <= iShoutcastTimeout) //Here is the real problem: Sometimes the buffer fills just to
      //slowly, thus the quality of the stream will be bad, and should be
      //aborted...
    {
      Sleep(100);
      char szTmp[1024];
      //g_dialog.SetCaption(0, "Shoutcast" );
      sprintf(szTmp, "Buffering %i bytes", m_ringbuf.GetMaxReadSize());
      if (dlgProgress)
      {
        dlgProgress->SetLine(2, szTmp );
        dlgProgress->Progress();
      }

      sprintf(szTmp, "%s", m_ripInfo.filename);
      for (int i = 0; i < (int)strlen(szTmp); i++)
        szTmp[i] = tolower((unsigned char)szTmp[i]);
      szTmp[50] = 0;
      if (dlgProgress)
      {
        dlgProgress->SetLine(1, szTmp );
        dlgProgress->Progress();
      }
    }
    else //it's not really a connection timeout, but it's here,
      //where things get boring, if connection is slow.
      //trust me, i did a lot of testing... Doesn't happen often,
      //but if it does it sucks to wait here forever.
      //CHANGED: Other message here
    {
      if (dlgProgress)
      {
        dlgProgress->SetLine(1, 257);
        dlgProgress->SetLine(2, "Connection to server too slow...");
        dlgProgress->Close();
      }
      return false;
    }
    iCount++;
  }
  if (dlgProgress && dlgProgress->IsCanceled())
  {
     Close();
     dlgProgress->Close();
     return false;
  }
  if ( m_fileState.bRipError )
  {
    if (dlgProgress)
    {
      dlgProgress->SetLine(1, 257);
      dlgProgress->SetLine(2, m_errorInfo.error_str);
      dlgProgress->Progress();

      Sleep(1500);
      dlgProgress->Close();
    }
    return false;
  }
  if (dlgProgress)
  {
    dlgProgress->SetLine(2, 261);
    dlgProgress->Progress();
    dlgProgress->Close();
  }
  return true;
}