/* STATIC FUNCTIONS */ bool CFileCurl::GetHttpHeader(const CURL &url, CHttpHeader &headers) { /* 歌方: 1、 卦指: 1、 傍苧: 1、 */ try { CFileCurl file; if(file.Stat(url, NULL) == 0) { headers = file.GetHttpHeader(); return true; } return false; } catch(...) { CLog::Log(LOGERROR, "%s - Exception thrown while trying to retrieve header url: %s", __FUNCTION__, url.Get().c_str()); return false; } }
bool CFileCurl::GetMimeType(const CURL &url, CStdString &content, CStdString useragent) { /* 歌方: 1、 卦指: 1、 傍苧: 1、 */ CFileCurl file; if (!useragent.IsEmpty()) file.SetUserAgent(useragent); if( file.Stat(url, NULL) == 0 ) { content = file.GetMimeType(); CLog::Log(LOGDEBUG, "CFileCurl::GetMimeType - %s -> %s", url.Get().c_str(), content.c_str()); return true; } CLog::Log(LOGDEBUG, "CFileCurl::GetMimeType - %s -> failed", url.Get().c_str()); content = ""; return false; }
bool CGUIDialogSongInfo::DownloadThumbnail(const CStdString &thumbFile) { // TODO: Obtain the source... CStdString source; CFileCurl http; http.Download(source, thumbFile); return true; }
bool CDVDInputStreamFile::Open(const char* strFile, const std::string& content) { CStdString stdFile = strFile; CURI url(stdFile); if (!CDVDInputStream::Open(strFile, content)) return false; m_pFile = new CFile(); if (!m_pFile) return false; unsigned int flags = READ_TRUNCATED; if( CFileItem(stdFile, false).IsInternetStream() ) flags |= READ_CACHED; bool bOpen = false; // This is a workaround for HTML5 video content. we need to pass a user agent string from // the file item into the resulting file, but can only do this if we open ourselves if( m_item.m_strPath.Left(7).Equals("http://") || m_item.m_strPath.Left(8).Equals("https://")) { CStdString extraInfo = m_item.GetExtraInfo(); if( extraInfo && extraInfo.Left(11).Equals("User-Agent:") ) { CFileCurl* curl = new CFileCurl(); curl->SetUserAgent(extraInfo); if( !curl->Open(stdFile) ) { delete m_pFile; m_pFile = NULL; return false; } // success - atttach to m_pfile m_pFile->Attach( curl, flags ); curl = NULL; bOpen = true; } } // open file in binary mode if( !bOpen && !m_pFile->Open(stdFile, flags)) { delete m_pFile; m_pFile = NULL; return false; } if (m_pFile->GetImplemenation() && (content.empty() || content == "application/octet-stream")) m_content = m_pFile->GetImplemenation()->GetContent(); m_eof = true; return true; }
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 = ""; CFileCurl 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(); }
void CLastFmManager::CacheTrackThumb(const int nrInitialTracksToAdd) { unsigned int start = CTimeUtils::GetTimeMS(); CSingleLock lock(m_lockCache); int iNrCachedTracks = m_RadioTrackQueue->size(); CFileCurl http; for (int i = 0; i < nrInitialTracksToAdd && i < iNrCachedTracks; i++) { CFileItemPtr item = (*m_RadioTrackQueue)[i]; if (!item->GetMusicInfoTag()->Loaded()) { //cache albumthumb, GetThumbnailImage contains the url to cache if (item->HasThumbnail()) { CStdString coverUrl = item->GetThumbnailImage(); CStdString crcFile; CStdString cachedFile; CStdString thumbFile; Crc32 crc; crc.ComputeFromLowerCase(coverUrl); crcFile.Format("%08x.tbn", (__int32)crc); URIUtils::AddFileToFolder(g_advancedSettings.m_cachePath, crcFile, cachedFile); URIUtils::AddFileToFolder(g_settings.GetLastFMThumbFolder(), crcFile, thumbFile); item->SetThumbnailImage(""); try { //download to temp, then make a thumb if (CFile::Exists(thumbFile) || (http.Download(coverUrl, cachedFile) && CPicture::CreateThumbnail(cachedFile, thumbFile))) { if (CFile::Exists(cachedFile)) CFile::Delete(cachedFile); item->SetThumbnailImage(thumbFile); } } catch(...) { CLog::Log(LOGERROR, "LastFmManager: exception while caching %s to %s.", coverUrl.c_str(), thumbFile.c_str()); } } if (!item->HasThumbnail()) { item->SetThumbnailImage("DefaultAlbumCover.png"); } item->GetMusicInfoTag()->SetLoaded(); } } CLog::Log(LOGDEBUG, "%s: Done (time: %i ms)", __FUNCTION__, (int)(CTimeUtils::GetTimeMS() - start)); }
bool CHTTPDirectory::Exists(const char* strPath) { CFileCurl http; CURL url(strPath); struct __stat64 buffer; if( http.Stat(url, &buffer) != 0 ) { return false; } if (buffer.st_mode == _S_IFDIR) return true; return false; }
/* STATIC FUNCTIONS */ bool CFileCurl::GetHttpHeader(const CURI &url, CHttpHeader &headers) { try { CFileCurl file; if(file.Stat(url, NULL) == 0) { headers = file.GetHttpHeader(); return true; } return false; } catch(...) { CStdString path; path = url.Get(); CLog::Log(LOGERROR, "%s - Exception thrown while trying to retrieve header url: %s", __FUNCTION__, path.c_str()); return false; } }
bool MythXml::open(CStdString hostname, int port, CStdString user, CStdString pass, int pin, long timeout) { hostname_ = hostname; port_ = port; timeout_ = timeout; pin_ = pin; CStdString strUrl; strUrl.Format("http://%s:%i/Myth/GetConnectionInfo?Pin=%i", hostname.c_str(), port, pin); CStdString strXML; CFileCurl http; http.SetTimeout(timeout); if(!http.Get(strUrl, strXML)) { CLog::Log(LOGDEBUG, "MythXml - Could not open connection to mythtv backend."); http.Cancel(); return false; } http.Cancel(); return true; }
bool CFileCurl::GetMimeType(const CURL &url, CStdString &content, CStdString useragent) { CFileCurl file; if (!useragent.IsEmpty()) file.SetUserAgent(useragent); struct __stat64 buffer; if( file.Stat(url, &buffer) == 0 ) { if (buffer.st_mode == _S_IFDIR) content = "x-directory/normal"; else content = file.GetMimeType(); CLog::Log(LOGDEBUG, "CFileCurl::GetMimeType - %s -> %s", url.Get().c_str(), content.c_str()); return true; } CLog::Log(LOGDEBUG, "CFileCurl::GetMimeType - %s -> failed", url.Get().c_str()); content = ""; return false; }
bool CFileCurl::GetContent(const CURI &url, CStdString &content, CStdString useragent) { CFileCurl file; if (!useragent.IsEmpty()) file.SetUserAgent(useragent); if( file.Stat(url, NULL) == 0 ) { content = file.GetContent(); return true; } if (file.GetLastRetCode() > 400 ) { content = "text/html"; } else { content = ""; } return false; }
bool CPluginSettings::SaveToPlexMediaServer(const CStdString& path) { // Build up URL parameters with id and value. TiXmlElement* root = m_userXmlDoc.RootElement(); string params = "?"; for (TiXmlElement* setting = root->FirstChildElement("setting"); setting; setting = setting->NextSiblingElement("setting")) { const char* id = setting->Attribute("id"); const char* value = setting->Attribute("value"); if (id) { CStdString strName = id; CStdString strValue = value; CUtil::URLEncode(strName); CUtil::URLEncode(strValue); params += strName + "=" + strValue + "&"; } } // Compute the new path. string strPath = path; strPath += "set" + params.substr(0, params.size()-1); // Send the parameters back to the Plex Media Server. CURL url(strPath); CStdString protocol = url.GetProtocol(); url.SetProtocol("http"); url.SetPort(32400); // Make the request. CFileCurl http; return http.Open(url, false); }
bool CShoutcastDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CStdString strRoot = strPath; if (CUtil::HasSlashAtEnd(strRoot)) strRoot.Delete(strRoot.size() - 1); /* for old users wich doesn't have the full url */ if( strRoot.Equals("shout://www.shoutcast.com") ) strRoot = "shout://www.shoutcast.com/sbin/newxml.phtml"; if (g_directoryCache.GetDirectory(strRoot, items)) return true; CGUIDialogProgress* dlgProgress = (CGUIDialogProgress*)m_gWindowManager.GetWindow(WINDOW_DIALOG_PROGRESS); if (dlgProgress) { dlgProgress->ShowProgressBar(false); dlgProgress->SetHeading(260); dlgProgress->SetLine(0, 14003); dlgProgress->SetLine(1, ""); dlgProgress->SetLine(2, ""); dlgProgress->StartModal(); } CURL url(strRoot); CStdString protocol = url.GetProtocol(); url.SetProtocol("http"); CFileCurl http; //CURL doesn't seem to understand that data is encoded.. odd // opening as text for now //http.SetContentEncoding("deflate"); if( !http.Open(url, false) ) { CLog::Log(LOGERROR, "%s - Unable to get shoutcast dir", __FUNCTION__); if (dlgProgress) dlgProgress->Close(); return false; } /* restore protocol */ url.SetProtocol(protocol); CStdString content = http.GetContent(); if( !(content.Equals("text/html") || content.Equals("text/xml") || content.Equals("text/html;charset=utf-8") || content.Equals("text/xml;charset=utf-8") )) { CLog::Log(LOGERROR, "%s - Invalid content type %s", __FUNCTION__, content.c_str()); if (dlgProgress) dlgProgress->Close(); return false; } int size_read = 0; int size_total = (int)http.GetLength(); int data_size = 0; CStdString data; data.reserve(size_total); /* read response from server into string buffer */ char buffer[16384]; while( (size_read = http.Read(buffer, sizeof(buffer)-1)) > 0 ) { buffer[size_read] = 0; data += buffer; data_size += size_read; dlgProgress->Progress(); if (dlgProgress->IsCanceled()) { dlgProgress->Close(); return false; } } /* parse returned xml */ TiXmlDocument doc; doc.Parse(data.c_str()); TiXmlElement *root = doc.RootElement(); if(root == NULL) { CLog::Log(LOGERROR, "%s - Unable to parse xml", __FUNCTION__); CLog::Log(LOGDEBUG, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str()); dlgProgress->Close(); return false; } /* clear data to keep memusage down, not needed anymore */ data.Empty(); bool result = false; if( strcmp(root->Value(), "genrelist") == 0 ) result = ParseGenres(root, items, url); else if( strcmp(root->Value(), "stationlist") == 0 ) result = ParseStations(root, items, url); else { CLog::Log(LOGERROR, "%s - Invalid root xml element for shoutcast",__FUNCTION__); CLog::Log(LOGDEBUG, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str()); } CFileItemList vecCacheItems; g_directoryCache.ClearDirectory(strRoot); for( int i = 0; i <items.Size(); i++ ) { CFileItem* pItem=items[i]; if (!pItem->IsParentFolder()) vecCacheItems.Add(new CFileItem( *pItem )); } g_directoryCache.SetDirectory(strRoot, vecCacheItems); if (dlgProgress) dlgProgress->Close(); return result; }
/* <?xml version="1.0" encoding="UTF-8"?> <methodCall> <methodName>method</methodName> <params> <param><value><string>user</string></value></param> <param><value><string>challenge</string></value></param> <param><value><string>auth</string></value></param> <param><value><string>artist</string></value></param> <param><value><string>title</string></value></param> </params> </methodCall> */ bool CLastFmManager::CallXmlRpc(const CStdString& action, const CStdString& artist, const CStdString& title) { CStdString strUserName = g_guiSettings.GetString("scrobbler.lastfmusername"); CStdString strPassword = g_guiSettings.GetString("scrobbler.lastfmpass"); if (strUserName.IsEmpty() || strPassword.IsEmpty()) { CLog::Log(LOGERROR, "Last.fm CallXmlRpc no username or password set."); return false; } if (artist.IsEmpty()) { CLog::Log(LOGERROR, "Last.fm CallXmlRpc no artistname provided."); return false; } if (title.IsEmpty()) { CLog::Log(LOGERROR, "Last.fm CallXmlRpc no tracktitle provided."); return false; } char ti[20]; time_t rawtime; time ( &rawtime ); struct tm *now = gmtime(&rawtime); strftime(ti, sizeof(ti), "%Y-%m-%d %H:%M:%S", now); CStdString strChallenge = ti; CStdString strAuth(strPassword); strAuth.ToLower(); strAuth.append(strChallenge); CreateMD5Hash(strAuth, strAuth); //create request xml TiXmlDocument doc; TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "UTF-8", "" ); doc.LinkEndChild( decl ); TiXmlElement * elMethodCall = new TiXmlElement( "methodCall" ); doc.LinkEndChild( elMethodCall ); TiXmlElement * elMethodName = new TiXmlElement( "methodName" ); elMethodCall->LinkEndChild( elMethodName ); TiXmlText * txtAction = new TiXmlText( action ); elMethodName->LinkEndChild( txtAction ); TiXmlElement * elParams = new TiXmlElement( "params" ); elMethodCall->LinkEndChild( elParams ); TiXmlElement * elParam = new TiXmlElement( "param" ); elParams->LinkEndChild( elParam ); TiXmlElement * elValue = new TiXmlElement( "value" ); elParam->LinkEndChild( elValue ); TiXmlElement * elString = new TiXmlElement( "string" ); elValue->LinkEndChild( elString ); TiXmlText * txtParam = new TiXmlText( strUserName ); elString->LinkEndChild( txtParam ); elParam = new TiXmlElement( "param" ); elParams->LinkEndChild( elParam ); elValue = new TiXmlElement( "value" ); elParam->LinkEndChild( elValue ); elString = new TiXmlElement( "string" ); elValue->LinkEndChild( elString ); txtParam = new TiXmlText( strChallenge ); elString->LinkEndChild( txtParam ); elParam = new TiXmlElement( "param" ); elParams->LinkEndChild( elParam ); elValue = new TiXmlElement( "value" ); elParam->LinkEndChild( elValue ); elString = new TiXmlElement( "string" ); elValue->LinkEndChild( elString ); txtParam = new TiXmlText( strAuth ); elString->LinkEndChild( txtParam ); elParam = new TiXmlElement( "param" ); elParams->LinkEndChild( elParam ); elValue = new TiXmlElement( "value" ); elParam->LinkEndChild( elValue ); elString = new TiXmlElement( "string" ); elValue->LinkEndChild( elString ); txtParam = new TiXmlText( artist ); elString->LinkEndChild( txtParam ); elParam = new TiXmlElement( "param" ); elParams->LinkEndChild( elParam ); elValue = new TiXmlElement( "value" ); elParam->LinkEndChild( elValue ); elString = new TiXmlElement( "string" ); elValue->LinkEndChild( elString ); txtParam = new TiXmlText( title ); elString->LinkEndChild( txtParam ); CStdString strBody; strBody << doc; CFileCurl http; CStdString html; CStdString url = "http://ws.audioscrobbler.com/1.0/rw/xmlrpc.php"; http.SetMimeType("text/xml"); if (!http.Post(url, strBody, html)) { CLog::Log(LOGERROR, "Last.fm action %s failed.", action.c_str()); return false; } if (html.Find("fault") >= 0) { CLog::Log(LOGERROR, "Last.fm return failed response: %s", html.c_str()); return false; } return true; }
bool CDAVDirectory::Exists(const char* strPath) { CFileCurl dav; CURL url(strPath); return dav.Exists(url); }
bool CLastFmManager::RequestRadioTracks() { unsigned int start = CTimeUtils::GetTimeMS(); CStdString url; CStdString html; url.Format("http://" + m_RadioBaseUrl + m_RadioBasePath + "/xspf.php?sk=%s&discovery=0&desktop=", m_RadioSession); { CFileCurl 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 TiXmlDocument 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->m_strPath = 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)(CTimeUtils::GetTimeMS() - start)); return iNrCachedTracks > 0; }
bool CLastFmManager::ChangeStation(const CURL& stationUrl) { unsigned int start = CTimeUtils::GetTimeMS(); InitProgressDialog(stationUrl.Get()); StopRadio(false); if (!RadioHandShake()) { CloseProgressDialog(); CGUIDialogOK::ShowAndGetInput(15200, 15206, 0, 0); return false; } UpdateProgressDialog(15252); // Selecting station... CFileCurl 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)(CTimeUtils::GetTimeMS() - start)); CloseProgressDialog(); return true; } CloseProgressDialog(); return false; }
bool CRSSDirectory::Exists(const char* strPath) { CFileCurl rss; CURL url(strPath); return rss.Exists(url); }
bool CDAVDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CFileCurl dav; CURL url(strPath); CStdString strRequest = "PROPFIND"; dav.SetCustomRequest(strRequest); dav.SetMimeType("text/xml; charset=\"utf-8\""); dav.SetRequestHeader("depth", 1); dav.SetPostData( "<?xml version=\"1.0\" encoding=\"utf-8\" ?>" " <D:propfind xmlns:D=\"DAV:\">" " <D:prop>" " <D:resourcetype/>" " <D:getcontentlength/>" " <D:getlastmodified/>" " <D:creationdate/>" " <D:displayname/>" " </D:prop>" " </D:propfind>"); if (!dav.Open(url)) { CLog::Log(LOGERROR, "%s - Unable to get dav directory (%s)", __FUNCTION__, strPath.c_str()); return false; } char buffer[MAX_PATH + 1024]; CStdString strResponse; CStdString strHeader; while (dav.ReadString(buffer, sizeof(buffer))) { if (strstr(buffer, "<D:response") != NULL) { // The header should contain the xml version/utf encoding line // followed by the <multistatus> tag if (strHeader.IsEmpty()) strHeader = strResponse; strResponse = strHeader; } strResponse.append(buffer, strlen(buffer)); if (strstr(buffer, "</D:response") != NULL) { // Close the multistatus tag from the header if (strHeader.Find("<D:multistatus")) strResponse+="</D:multistatus>\n"; TiXmlDocument davResponse; if (!davResponse.Parse(strResponse)) { CLog::Log(LOGERROR, "%s - Unable to process dav directory (%s)", __FUNCTION__, strPath.c_str()); dav.Close(); return false; } TiXmlNode *pChild; // Iterate over all responses for (pChild = davResponse.RootElement()->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) { if (ValueWithoutNamespace(pChild, "response")) { CFileItem item; ParseResponse(pChild->ToElement(), item); CURL url2(strPath); CURL url3(item.m_strPath); URIUtils::AddFileToFolder(url2.GetWithoutFilename(), url3.GetFileName(), item.m_strPath); if (item.GetLabel().IsEmpty()) { CStdString name(item.m_strPath); URIUtils::RemoveSlashAtEnd(name); CURL::Decode(name); item.SetLabel(URIUtils::GetFileName(name)); } if (item.m_bIsFolder) URIUtils::AddSlashAtEnd(item.m_strPath); // Add back protocol options if (!url2.GetProtocolOptions().IsEmpty()) item.m_strPath += "|" + url2.GetProtocolOptions(); if (!item.m_strPath.Equals(strPath)) { CFileItemPtr pItem(new CFileItem(item)); items.Add(pItem); } } } strResponse.clear(); } } dav.Close(); return true; }
bool CFTPDirectory::Exists(const char* strPath) { CFileCurl ftp; CURL url(strPath); return ftp.Exists(url); }
bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CFileCurl http; CURL url(strPath); CStdString strName, strLink; CStdString strBasePath = url.GetFileName(); if(!http.Open(url)) { CLog::Log(LOGERROR, "%s - Unable to get http directory", __FUNCTION__); return false; } CRegExp reItem(true); // HTML is case-insensitive reItem.RegComp("<a href=\"(.*)\">(.*)</a>"); /* read response from server into string buffer */ char buffer[MAX_PATH + 1024]; while(http.ReadString(buffer, sizeof(buffer)-1)) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); if (reItem.RegFind(strBuffer.c_str()) >= 0) { strLink = reItem.GetReplaceString("\\1"); strName = reItem.GetReplaceString("\\2"); if(strLink[0] == '/') strLink = strLink.Mid(1); CStdString strNameTemp = strName.Trim(); CStdString strLinkTemp = strLink; URIUtils::RemoveSlashAtEnd(strLinkTemp); URIUtils::RemoveSlashAtEnd(strNameTemp); CURL::Decode(strLinkTemp); if (strNameTemp == strLinkTemp && strLinkTemp != "..") { CStdStringW wName, wLink, wConverted; g_charsetConverter.unknownToUTF8(strName); g_charsetConverter.utf8ToW(strName, wName, false); HTML::CHTMLUtil::ConvertHTMLToW(wName, wConverted); g_charsetConverter.wToUTF8(wConverted, strName); URIUtils::RemoveSlashAtEnd(strName); g_charsetConverter.unknownToUTF8(strLink); g_charsetConverter.utf8ToW(strLink, wLink, false); HTML::CHTMLUtil::ConvertHTMLToW(wLink, wConverted); g_charsetConverter.wToUTF8(wConverted, strLink); CFileItemPtr pItem(new CFileItem(strName)); pItem->SetProperty("IsHTTPDirectory", true); url.SetFileName(strBasePath + strLink); pItem->SetPath(url.Get()); if(URIUtils::HasSlashAtEnd(pItem->GetPath())) pItem->m_bIsFolder = true; if (!pItem->m_bIsFolder && g_advancedSettings.m_bHTTPDirectoryStatFilesize) { CFileCurl file; file.Open(url); pItem->m_dwSize= file.GetLength(); file.Close(); } if (!pItem->m_bIsFolder && pItem->m_dwSize == 0) { CRegExp reSize(true); reSize.RegComp(">*([0-9.]+)(B|K|M|G| )</td>"); if (reSize.RegFind(strBuffer.c_str()) >= 0) { double Size = atof(reSize.GetReplaceString("\\1")); CStdString strUnit = reSize.GetReplaceString("\\2"); if (strUnit == "K") Size = Size * 1024; else if (strUnit == "M") Size = Size * 1024 * 1024; else if (strUnit == "G") Size = Size * 1000 * 1024 * 1024; pItem->m_dwSize = (int64_t)Size; } } items.Add(pItem); } } } http.Close(); items.SetProperty("IsHTTPDirectory", true); return true; }
void CDownloadQueue::Process() { CLog::Log(LOGNOTICE, "DownloadQueue ready."); CFileCurl 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."); }
bool CFTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CFileCurl reader; CURL url(strPath); CStdString path = url.GetFileName(); if( !path.IsEmpty() && !path.Right(1).Equals("/") ) { path += "/"; url.SetFileName(path); } if (!reader.Open(url)) return false; char buffer[MAX_PATH + 1024]; while( reader.ReadString(buffer, sizeof(buffer)) ) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); struct ftpparse lp = {}; if (ftpparse(&lp, (char*)strBuffer.c_str(), strBuffer.size()) == 1) { if( lp.namelen == 0 ) continue; if( lp.flagtrycwd == 0 && lp.flagtryretr == 0 ) continue; /* buffer name as it's not allways null terminated */ CStdString name; name.assign(lp.name, lp.namelen); if( name.Equals("..") || name.Equals(".") ) continue; /* this should be conditional if we ever add */ /* support for the utf8 extension in ftp client */ g_charsetConverter.stringCharsetToUtf8(name); CFileItemPtr pItem(new CFileItem(name)); pItem->m_strPath = path + name; pItem->m_bIsFolder = (bool)(lp.flagtrycwd != 0); if (pItem->m_bIsFolder) if (!CUtil::HasSlashAtEnd(pItem->m_strPath)) pItem->m_strPath += "/"; /* qualify the url with host and all */ url.SetFileName(pItem->m_strPath); url.GetURL(pItem->m_strPath); pItem->m_dwSize = lp.size; pItem->m_dateTime=lp.mtime; items.Add(pItem); } } return true; }
bool CDirectoryTuxBox::GetDirectory(const CStdString& strPath, CFileItemList &items) { // so we know that we have enigma2 static bool enigma2 = false; // Detect and delete slash at end CStdString strRoot = strPath; if (CUtil::HasSlashAtEnd(strRoot)) strRoot.Delete(strRoot.size() - 1); //Get the request strings CStdString strBQRequest; CStdString strXMLRootString; CStdString strXMLChildString; if(!GetRootAndChildString(strRoot, strBQRequest, strXMLRootString, strXMLChildString)) return false; //Set url Protocol CURL url(strRoot); CStdString strFilter; CStdString protocol = url.GetProtocol(); CStdString strOptions = url.GetOptions(); url.SetProtocol("http"); bool bIsBouquet=false; int ipoint = strOptions.Find("?path="); if (ipoint >=0) { // send Zap! return g_tuxbox.ZapToUrl(url, strOptions, ipoint); } else { ipoint = strOptions.Find("&reference="); if (ipoint >=0 || enigma2) { //List reference strFilter = strOptions.Right((strOptions.size()-(ipoint+11))); bIsBouquet = false; //On Empty is Bouquet if (enigma2) { CStdString strPort; strPort.Format(":%i",url.GetPort()); if (strRoot.Right(strPort.GetLength()) != strPort) // If not root dir, enable Channels strFilter = "e2"; // Disable Bouquets for Enigma2 GetRootAndChildStringEnigma2(strBQRequest, strXMLRootString, strXMLChildString); url.SetOptions(""); url.SetFileName(strBQRequest); } } } if(strFilter.IsEmpty()) { url.SetOptions(strBQRequest); bIsBouquet = true; } //Open CFileCurl http; int iTryConnect = 0; int iWaitTimer = 20; bool result = false; while (iTryConnect < 4) { http.SetTimeout(iWaitTimer); if(http.Open(url)) { //We are connected! iTryConnect = 4; // restore protocol url.SetProtocol(protocol); int size_read = 0; int size_total = (int)http.GetLength(); int data_size = 0; CStdString data; data.reserve(size_total); // read response from server into string buffer char buffer[16384]; while ((size_read = http.Read(buffer, sizeof(buffer)-1)) > 0) { buffer[size_read] = 0; data += buffer; data_size += size_read; } http.Close(); // parse returned xml TiXmlDocument doc; data.Replace("></",">-</"); //FILL EMPTY ELEMENTS WITH "-"! doc.Parse(data.c_str()); TiXmlElement *root = doc.RootElement(); if(root == NULL) { CLog::Log(LOGERROR, "%s - Unable to parse xml", __FUNCTION__); CLog::Log(LOGERROR, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str()); return false; } if( strXMLRootString.Equals(root->Value()) && bIsBouquet) { data.Empty(); if (enigma2) result = g_tuxbox.ParseBouquetsEnigma2(root, items, url, strFilter, strXMLChildString); else result = g_tuxbox.ParseBouquets(root, items, url, strFilter, strXMLChildString); } else if( strXMLRootString.Equals(root->Value()) && !strFilter.IsEmpty() ) { data.Empty(); if (enigma2) result = g_tuxbox.ParseChannelsEnigma2(root, items, url, strFilter, strXMLChildString); else result = g_tuxbox.ParseChannels(root, items, url, strFilter, strXMLChildString); } else { CLog::Log(LOGERROR, "%s - Invalid root xml element for TuxBox", __FUNCTION__); CLog::Log(LOGERROR, "%s - Sample follows...\n%s", __FUNCTION__, data.c_str()); data.Empty(); result = false; } } else { CLog::Log(LOGERROR, "%s - Unable to get XML structure! Try count:%i, Wait Timer:%is",__FUNCTION__, iTryConnect, iWaitTimer); iTryConnect++; if (iTryConnect == 2) //try enigma2 instead of enigma1, best entrypoint here i thought { enigma2 = true; GetRootAndChildStringEnigma2(strBQRequest, strXMLRootString, strXMLChildString); url.SetOptions(""); url.SetFileName(strBQRequest); // iTryConnect = 0; iWaitTimer = 20; } else iWaitTimer = iWaitTimer+10; result = false; http.Close(); // Close old connections } } return result; }
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] = ""; CFileCurl 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 = CTimeUtils::GetTimeMS(); while ( (!m_bStop) && (nRetries > 0) ) { unsigned int currenttimer = CTimeUtils::GetTimeMS() - 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(); }
bool CFTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CFileCurl reader; CURL url(strPath); CStdString path = url.GetFileName(); if( !path.IsEmpty() && !path.Right(1).Equals("/") ) { path += "/"; url.SetFileName(path); } if (!reader.Open(url)) return false; char buffer[MAX_PATH + 1024]; while( reader.ReadString(buffer, sizeof(buffer)) ) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); CFTPParse parse; if (parse.FTPParse(strBuffer)) { if( parse.getName().length() == 0 ) continue; if( parse.getFlagtrycwd() == 0 && parse.getFlagtryretr() == 0 ) continue; /* buffer name */ CStdString name; name.assign(parse.getName()); if( name.Equals("..") || name.Equals(".") ) continue; /* this should be conditional if we ever add */ /* support for the utf8 extension in ftp client */ g_charsetConverter.unknownToUTF8(name); CFileItemPtr pItem(new CFileItem(name)); pItem->m_strPath = path + name; pItem->m_bIsFolder = (bool)(parse.getFlagtrycwd() != 0); if (pItem->m_bIsFolder) CUtil::AddSlashAtEnd(pItem->m_strPath); /* qualify the url with host and all */ url.SetFileName(pItem->m_strPath); pItem->m_strPath = url.Get(); pItem->m_dwSize = parse.getSize(); pItem->m_dateTime=parse.getTime(); items.Add(pItem); } } return true; }
bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items) { CFileCurl http; CURL url(strPath); CStdString strName, strLink; CStdString strBasePath = url.GetFileName(); if(!http.Open(url, false)) { CLog::Log(LOGERROR, "%s - Unable to get http directory", __FUNCTION__); return false; } CRegExp reItem; reItem.RegComp("<a href=\"(.*)\">(.*)</a>"); /* read response from server into string buffer */ char buffer[MAX_PATH + 1024]; while(http.ReadString(buffer, sizeof(buffer)-1)) { CStdString strBuffer = buffer; StringUtils::RemoveCRLF(strBuffer); if (reItem.RegFind(strBuffer.c_str()) >= 0) { strLink = reItem.GetReplaceString("\\1"); strName = reItem.GetReplaceString("\\2"); if(strLink[0] == '/') strLink = strLink.Mid(1); CStdString strNameTemp = strName.Trim(); CStdString strLinkTemp = strLink; CUtil::RemoveSlashAtEnd(strLinkTemp); CUtil::RemoveSlashAtEnd(strNameTemp); CUtil::UrlDecode(strLinkTemp); if (strNameTemp == strLinkTemp) { g_charsetConverter.stringCharsetToUtf8(strName); CUtil::RemoveSlashAtEnd(strName); CFileItemPtr pItem(new CFileItem(strName)); pItem->m_strPath = strBasePath + strLink; if(CUtil::HasSlashAtEnd(pItem->m_strPath)) pItem->m_bIsFolder = true; url.SetFileName(pItem->m_strPath); url.GetURL(pItem->m_strPath); if (!pItem->m_bIsFolder && g_advancedSettings.m_bHTTPDirectoryStatFilesize) { CFileCurl file; file.Open(url, false); pItem->m_dwSize= file.GetLength(); file.Close(); } if (!pItem->m_bIsFolder && pItem->m_dwSize == 0) { CRegExp reSize; reSize.RegComp(">([0-9.]+)(K|M|G)</td>"); if (reSize.RegFind(strBuffer.c_str()) >= 0) { double Size = atof(reSize.GetReplaceString("\\1")); CStdString strUnit = reSize.GetReplaceString("\\2"); if (strUnit == "M") Size = Size * 1024; else if (strUnit == "G") Size = Size * 1000 * 1024; pItem->m_dwSize = (__int64)(Size * 1024); } } items.Add(pItem); } } } http.Close(); return true; }