예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}