Exemple #1
0
bool CTuxBoxDirectory::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;
  URIUtils::RemoveSlashAtEnd(strRoot);

  //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();
  url.SetProtocol("http");
  bool bIsBouquet=false;

  if (url.HasOption("path"))
  {
    // send Zap!
    return g_tuxbox.ZapToUrl(url, url.GetOption("path"));
  }
  else
  {
    if (url.HasOption("reference") || enigma2)
    {
      //List reference
      strFilter = url.GetOption("reference");
      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("");
    url.SetFileName(strBQRequest);
    bIsBouquet = true;
  }
  //Open
  CCurlFile 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
      CXBMCTinyXML 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
    }
  }
  items.SetContent("movies");
  return result;
}
bool CHTTPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
    CCurlFile 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>");

    CRegExp reDateTime(true);
    reDateTime.RegComp("<td align=\"right\">([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) +</td>");

    CRegExp reDateTimeNginx(true);
    reDateTimeNginx.RegComp("</a> +([0-9]{2})-([A-Z]{3})-([0-9]{4}) ([0-9]{2}):([0-9]{2}) ");

    CRegExp reSize(true);
    reSize.RegComp(">*([0-9.]+)(B|K|M|G| )</td>");

    CRegExp reSizeNginx;
    reSizeNginx.RegComp("([0-9]+)$");

    /* 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;

                CStdString day, month, year, hour, minute;

                if (reDateTime.RegFind(strBuffer.c_str()) >= 0)
                {
                    day = reDateTime.GetReplaceString("\\1");
                    month = reDateTime.GetReplaceString("\\2");
                    year = reDateTime.GetReplaceString("\\3");
                    hour = reDateTime.GetReplaceString("\\4");
                    minute = reDateTime.GetReplaceString("\\5");
                }
                else if (reDateTimeNginx.RegFind(strBuffer.c_str()) >= 0)
                {
                    day = reDateTimeNginx.GetReplaceString("\\1");
                    month = reDateTimeNginx.GetReplaceString("\\2");
                    year = reDateTimeNginx.GetReplaceString("\\3");
                    hour = reDateTimeNginx.GetReplaceString("\\4");
                    minute = reDateTimeNginx.GetReplaceString("\\5");
                }

                if (day.length() > 0 && month.length() > 0 && year.length() > 0)
                {
                    pItem->m_dateTime = CDateTime(atoi(year.c_str()), CDateTime::MonthStringToMonthNum(month), atoi(day.c_str()), atoi(hour.c_str()), atoi(minute.c_str()), 0);
                }

                if (!pItem->m_bIsFolder)
                {
                    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;
                    }
                    else if (reSizeNginx.RegFind(strBuffer.c_str()) >= 0)
                    {
                        double Size = atof(reSizeNginx.GetReplaceString("\\1"));
                        pItem->m_dwSize = (int64_t)Size;
                    }
                    else if (g_advancedSettings.m_bHTTPDirectoryStatFilesize) // As a fallback get the size by stat-ing the file (slow)
                    {
                        CCurlFile file;
                        file.Open(url);
                        pItem->m_dwSize=file.GetLength();
                        file.Close();
                    }
                }
                items.Add(pItem);
            }
        }
    }
    http.Close();

    items.SetProperty("IsHTTPDirectory", true);

    return true;
}