Example #1
0
bool AutoTimer::UpdateFrom(TiXmlElement* autoTimerNode, Channels &channels)
{
  std::string strTmp;
  int iTmp;

  m_type = Timer::EPG_AUTO_SEARCH;

  //this is an auto timer so the state is always scheduled unless it's disabled
  m_state = PVR_TIMER_STATE_SCHEDULED;

  m_tags.clear();
  if (XMLUtils::GetString(autoTimerNode, "e2tags", strTmp))
    m_tags = strTmp;

  if (autoTimerNode->QueryStringAttribute("name", &strTmp) == TIXML_SUCCESS)
    m_title = strTmp;

  if (autoTimerNode->QueryStringAttribute("match", &strTmp) == TIXML_SUCCESS)
    m_searchPhrase = strTmp;

  if (autoTimerNode->QueryStringAttribute("enabled", &strTmp) == TIXML_SUCCESS)
  {
    if (strTmp == AUTOTIMER_ENABLED_NO)
    {
      m_state = PVR_TIMER_STATE_DISABLED;
    }
  }

  if (autoTimerNode->QueryIntAttribute("id", &iTmp) == TIXML_SUCCESS)
    m_backendId = iTmp;

  std::string from;
  std::string to;
  std::string avoidDuplicateDescription;
  std::string searchForDuplicateDescription;
  autoTimerNode->QueryStringAttribute("from", &from);
  autoTimerNode->QueryStringAttribute("to", &to);
  autoTimerNode->QueryStringAttribute("avoidDuplicateDescription", &avoidDuplicateDescription);
  autoTimerNode->QueryStringAttribute("searchForDuplicateDescription", &searchForDuplicateDescription);

  if (avoidDuplicateDescription != AUTOTIMER_AVOID_DUPLICATE_DISABLED)
  {
    if (searchForDuplicateDescription == AUTOTIMER_CHECK_SEARCH_FOR_DUP_IN_TITLE)
      m_deDup = AutoTimer::DeDup::CHECK_TITLE;
    else if (searchForDuplicateDescription == AUTOTIMER_CHECK_SEARCH_FOR_DUP_IN_TITLE_AND_SHORT_DESC)
      m_deDup = AutoTimer::DeDup::CHECK_TITLE_AND_SHORT_DESC;
    else if (searchForDuplicateDescription.empty() || searchForDuplicateDescription == AUTOTIMER_CHECK_SEARCH_FOR_DUP_IN_TITLE_AND_ALL_DESCS) //Even though this value should be 2 it is sent as ommitted for this attribute, we'll allow 2 anyway incase it changes in the future
      m_deDup = AutoTimer::DeDup::CHECK_TITLE_AND_ALL_DESCS;
  }

  if (autoTimerNode->QueryStringAttribute("encoding", &strTmp) == TIXML_SUCCESS)
    m_encoding = strTmp;

  if (autoTimerNode->QueryStringAttribute("searchType", &strTmp) == TIXML_SUCCESS)
  {
    m_searchType = strTmp;
    if (strTmp == AUTOTIMER_SEARCH_TYPE_DESCRIPTION)
      m_searchFulltext = true;
  }

  if (autoTimerNode->QueryStringAttribute("searchCase", &strTmp) == TIXML_SUCCESS)
    m_searchCase = strTmp;

  TiXmlElement* serviceNode = autoTimerNode->FirstChildElement("e2service");

  if (serviceNode)
  {
    const TiXmlElement *nextServiceNode = serviceNode->NextSiblingElement("e2service");

    if (!nextServiceNode)
    {
      //If we only have one channel
      if (XMLUtils::GetString(serviceNode, "e2servicereference", strTmp))
      {
        m_channelId = channels.GetChannelUniqueId(Channel::NormaliseServiceReference(strTmp.c_str()));

        // For autotimers for channels we don't know about, such as when the addon only uses one bouquet or an old channel referene that doesn't exist
        // we'll default to any channel (as that is what kodi PVR does) and leave in ERROR state
        if (m_channelId == PVR_CHANNEL_INVALID_UID)
        {
          m_state = PVR_TIMER_STATE_ERROR;
          Logger::Log(LEVEL_DEBUG, "%s Overriding AutoTimer state as channel not found, state is: ERROR", __FUNCTION__);
          m_channelName = LocalizedString(30520); // Invalid Channel
          m_channelId = PVR_TIMER_ANY_CHANNEL;
          m_anyChannel = true;
        }
        else
        {
          m_channelName = channels.GetChannel(m_channelId)->GetChannelName();
        }
      }
    }
    else //otherwise set to any channel
    {
      m_channelId = PVR_TIMER_ANY_CHANNEL;
      m_anyChannel = true;
    }
  }
  else //otherwise set to any channel
  {
    m_channelId = PVR_TIMER_ANY_CHANNEL;
    m_anyChannel = true;
  }

  m_weekdays = 0;

  TiXmlElement* includeNode = autoTimerNode->FirstChildElement("include");

  if (includeNode)
  {
    for (; includeNode != nullptr; includeNode = includeNode->NextSiblingElement("include"))
    {
      std::string includeVal = includeNode->GetText();

      std::string where;
      if (includeNode->QueryStringAttribute("where", &where) == TIXML_SUCCESS)
      {
        if (where == "dayofweek")
        {
          m_weekdays = m_weekdays |= (1 << atoi(includeVal.c_str()));
        }
      }
    }
  }

  if (m_weekdays != PVR_WEEKDAY_NONE)
  {
    std::time_t t = std::time(nullptr);
    std::tm timeinfo = *std::localtime(&t);
    timeinfo.tm_sec = 0;
    m_startTime = 0;
    if (!from.empty())
    {
      ParseTime(from, timeinfo);
      m_startTime = std::mktime(&timeinfo);
    }

    timeinfo = *std::localtime(&t);
    timeinfo.tm_sec = 0;
    m_endTime = 0;
    if (!to.empty())
    {
      ParseTime(to, timeinfo);
      m_endTime = std::mktime(&timeinfo);
    }
  }
  else
  {
    for (int i = 0; i < DAYS_IN_WEEK; i++)
    {
      m_weekdays = m_weekdays |= (1 << i);
    }
    m_startAnyTime = true;
    m_endAnyTime = true;
  }

  if (ContainsTag(TAG_FOR_GENRE_ID))
  {
    int genreId = 0;
    if (std::sscanf(ReadTagValue(TAG_FOR_GENRE_ID).c_str(), "0x%02X", &genreId) == 1)
    {
      m_genreType = genreId & 0xF0;
      m_genreSubType = genreId & 0x0F;
    }
    else
    {
      m_genreType = 0;
      m_genreSubType = 0;
    }
  }

  return true;
}