Exemple #1
0
  std::string CPVRGUIActions::GetResumeLabel(const CFileItem &item) const
  {
    std::string resumeString;

    const CPVRRecordingPtr recording(CPVRItem(CFileItemPtr(new CFileItem(item))).GetRecording());
    if (recording && !recording->IsDeleted())
    {
      // First try to find the resume position on the back-end, if that fails use video database
      int positionInSeconds = recording->GetLastPlayedPosition();
      // If the back-end does report a saved position it will be picked up by FileItem
      if (positionInSeconds < 0)
      {
        CVideoDatabase db;
        if (db.Open())
        {
          CBookmark bookmark;
          std::string itemPath(recording->m_strFileNameAndPath);
          if (db.GetResumeBookMark(itemPath, bookmark) )
            positionInSeconds = lrint(bookmark.timeInSeconds);
          db.Close();
        }
      }

      // Suppress resume from 0
      if (positionInSeconds > 0)
        resumeString = StringUtils::Format(g_localizeStrings.Get(12022).c_str(),
                                           StringUtils::SecondsToTimeString(positionInSeconds, TIME_FORMAT_HH_MM_SS).c_str());
    }
    return resumeString;
  }
Exemple #2
0
bool CPVRClients::OpenStream(const CPVRRecordingPtr &channel)
{
  assert(channel.get());

  bool bReturn(false);
  CloseStream();

  /* try to open the recording stream on the client */
  PVR_CLIENT client;
  if (GetConnectedClient(channel->m_iClientId, client) &&
      client->OpenStream(channel))
  {
    CSingleLock lock(m_critSection);

    CDateTime endTime = channel->RecordingTimeAsLocalTime() +
        CDateTimeSpan(0, 0, channel->GetDuration() / 60, channel->GetDuration() % 60);

    m_bIsRecordingInProgress = (endTime > CDateTime::GetCurrentDateTime());

    if (m_bIsRecordingInProgress)
      CLog::Log(LOGNOTICE, "PVRClients - %s - recording is still in progress, end time = %s", __FUNCTION__, endTime.GetAsDBDateTime().c_str());

    m_playingClientId = channel->m_iClientId;
    m_bIsPlayingRecording = true;
    m_strPlayingClientName = client->GetFriendlyName();
    bReturn = true;
  }

  return bReturn;
}
Exemple #3
0
CFileItemPtr CPVRRecordings::GetByPath(const std::string &path)
{
  CURL url(path);
  std::string fileName = url.GetFileName();
  URIUtils::RemoveSlashAtEnd(fileName);

  CSingleLock lock(m_critSection);

  if (StringUtils::StartsWith(fileName, PVR_RECORDING_BASE_PATH "/"))
  {
    // Check directory name is for deleted recordings
    fileName.erase(0, sizeof(PVR_RECORDING_BASE_PATH));
    bool bDeleted = StringUtils::StartsWith(fileName, PVR_RECORDING_DELETED_PATH "/");

    for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++)
    {
      CPVRRecordingPtr current = it->second;
      if (!URIUtils::PathEquals(path, current->m_strFileNameAndPath) || bDeleted != current->IsDeleted())
        continue;

      CFileItemPtr fileItem(new CFileItem(current));
      return fileItem;
    }
  }

  CFileItemPtr fileItem(new CFileItem);
  return fileItem;
}
Exemple #4
0
CFileItemPtr CPVRRecordings::GetByPath(const std::string &path)
{
  CSingleLock lock(m_critSection);

  CPVRRecordingsPath recPath(path);
  if (recPath.IsValid())
  {
    bool bDeleted = recPath.IsDeleted();
    bool bRadio   = recPath.IsRadio();

    for (const auto recording : m_recordings)
    {
      CPVRRecordingPtr current = recording.second;
      // Omit recordings not matching criteria
      if (!URIUtils::PathEquals(path, current->m_strFileNameAndPath) ||
          bDeleted != current->IsDeleted() || bRadio != current->IsRadio())
        continue;

      CFileItemPtr fileItem(new CFileItem(current));
      return fileItem;
    }
  }

  CFileItemPtr fileItem(new CFileItem);
  return fileItem;
}
Exemple #5
0
bool CPVRRecordings::SetRecordingsPlayCount(const CFileItemPtr &item, int count)
{
  bool bResult = false;

  if (m_database.IsOpen())
  {
    bResult = true;

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str());
    CFileItemList items;
    if (item->m_bIsFolder)
    {
      XFILE::CDirectory::GetDirectory(item->GetPath(), items);
    }
    else
      items.Add(item);

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size());
    for (int i=0;i<items.Size();++i)
    {
      CLog::Log(LOGDEBUG, "CPVRRecordings - %s - setting watched for item %d", __FUNCTION__, i);

      CFileItemPtr pItem=items[i];
      if (pItem->m_bIsFolder)
      {
        CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str());
        if (pItem->GetLabel() != "..")
        {
          SetRecordingsPlayCount(pItem, count);
        }
        continue;
      }

      if (!pItem->HasPVRRecordingInfoTag())
        continue;

      const CPVRRecordingPtr recording = pItem->GetPVRRecordingInfoTag();
      if (recording)
      {
        recording->SetPlayCount(count);

        // Clear resume bookmark
        if (count > 0)
        {
          m_database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME);
          recording->SetLastPlayedPosition(0);
        }

        m_database.SetPlayCount(*pItem, count);
      }
    }
  }

  return bResult;
}
Exemple #6
0
bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &items)
{
  CSingleLock lock(m_critSection);

  CPVRRecordingsPath recPath(strPath);
  if (recPath.IsValid())
  {
    // Get the directory structure if in non-flatten mode
    // Deleted view is always flatten. So only for an active view
    std::string strDirectory(recPath.GetDirectoryPath());
    if (!recPath.IsDeleted() && m_bGroupItems)
      GetSubDirectories(recPath, &items);

    // get all files of the currrent directory or recursively all files starting at the current directory if in flatten mode
    for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++)
    {
      CPVRRecordingPtr current = it->second;

      // skip items that are not members of the target directory
      if (!IsDirectoryMember(strDirectory, current->m_strDirectory) || current->IsDeleted() != recPath.IsDeleted())
        continue;

      if (m_database.IsOpen())
        current->UpdateMetadata(m_database);
      CFileItemPtr pFileItem(new CFileItem(current));
      pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false));
      pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
      pFileItem->SetPath(current->m_strFileNameAndPath);

      // Set art
      if (!current->m_strIconPath.empty())
      {
        pFileItem->SetIconImage(current->m_strIconPath);
        pFileItem->SetArt("icon", current->m_strIconPath);
      }

      if (!current->m_strThumbnailPath.empty())
        pFileItem->SetArt("thumb", current->m_strThumbnailPath);

      if (!current->m_strFanartPath.empty())
        pFileItem->SetArt("fanart", current->m_strFanartPath);

      // Use the channel icon as a fallback when a thumbnail is not available
      pFileItem->SetArtFallback("thumb", "icon");

      pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pFileItem->GetPVRRecordingInfoTag()->m_playCount > 0);

      items.Add(pFileItem);
    }

    return true;
  }

  return false;
}
Exemple #7
0
bool CPVRRecordings::Undelete(const CFileItem &item)
{
  if (!item.IsDeletedPVRRecording())
  {
    CLog::Log(LOGERROR, "CPVRRecordings - %s - cannot undelete file: no valid recording tag", __FUNCTION__);
    return false;
  }

  CPVRRecordingPtr tag = item.GetPVRRecordingInfoTag();
  return tag->Undelete();
}
Exemple #8
0
bool CPVRRecordings::RenameRecording(CFileItem &item, std::string &strNewName)
{
  if (!item.IsUsablePVRRecording())
  {
    CLog::Log(LOGERROR, "CPVRRecordings - %s - cannot rename file: no valid recording tag", __FUNCTION__);
    return false;
  }

  CPVRRecordingPtr tag = item.GetPVRRecordingInfoTag();
  return tag->Rename(strNewName);
}
Exemple #9
0
void CPVRRecordings::GetAll(CFileItemList &items, bool bDeleted)
{
  CSingleLock lock(m_critSection);
  for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++)
  {
    CPVRRecordingPtr current = it->second;
    if (current->IsDeleted() != bDeleted)
      continue;

    if (m_database.IsOpen())
      current->UpdateMetadata(m_database);

    CFileItemPtr pFileItem(new CFileItem(current));
    pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false));
    pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
    pFileItem->SetPath(current->m_strFileNameAndPath);
    pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pFileItem->GetPVRRecordingInfoTag()->m_playCount > 0);

    items.Add(pFileItem);
  }
}
Exemple #10
0
void CPVRRecordings::GetSubDirectories(const CPVRRecordingsPath &recParentPath, CFileItemList *results)
{
  // Only active recordings are fetched to provide sub directories.
  // Not applicable for deleted view which is supposed to be flattened.
  std::set<CFileItemPtr> unwatchedFolders;
  bool bRadio = recParentPath.IsRadio();

  for (const auto recording : m_recordings)
  {
    CPVRRecordingPtr current = recording.second;
    if (current->IsDeleted())
      continue;

    if (current->IsRadio() != bRadio)
      continue;

    const std::string strCurrent(recParentPath.GetUnescapedSubDirectoryPath(current->m_strDirectory));
    if (strCurrent.empty())
      continue;

    CPVRRecordingsPath recChildPath(recParentPath);
    recChildPath.AppendSegment(strCurrent);
    std::string strFilePath(recChildPath);

    CFileItemPtr pFileItem;
    if (m_database.IsOpen())
      current->UpdateMetadata(m_database);

    if (!results->Contains(strFilePath))
    {
      pFileItem.reset(new CFileItem(strCurrent, true));
      pFileItem->SetPath(strFilePath);
      pFileItem->SetLabel(strCurrent);
      pFileItem->SetLabelPreformatted(true);
      pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();

      // Assume all folders are watched, we'll change the overlay later
      pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, false);
      results->Add(pFileItem);
    }
    else
    {
      pFileItem = results->Get(strFilePath);
      if (pFileItem->m_dateTime<current->RecordingTimeAsLocalTime())
        pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
    }

    if (current->GetPlayCount() == 0)
      unwatchedFolders.insert(pFileItem);
  }

  // Change the watched overlay to unwatched for folders containing unwatched entries
  for (auto item : unwatchedFolders)
    item->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, false);
}
Exemple #11
0
void CPVRRecordings::UpdateFromClient(const CPVRRecordingPtr &tag)
{
  CSingleLock lock(m_critSection);

  if (tag->IsDeleted())
    m_bHasDeleted = true;

  CPVRRecordingPtr newTag = GetById(tag->m_iClientId, tag->m_strRecordingId);
  if (newTag)
  {
    newTag->Update(*tag);
  }
  else
  {
    newTag = CPVRRecordingPtr(new CPVRRecording);
    newTag->Update(*tag);
    if (newTag->BroadcastUid() != EPG_TAG_INVALID_UID)
    {
      const CPVRChannelPtr channel(newTag->Channel());
      if (channel)
      {
        const EPG::CEpgInfoTagPtr epgTag = EPG::CEpgContainer::GetInstance().GetTagById(channel, newTag->BroadcastUid());
        if (epgTag)
          epgTag->SetRecording(newTag);
      }
    }
    newTag->m_iRecordingId = ++m_iLastId;
    m_recordings.insert(std::make_pair(CPVRRecordingUid(newTag->m_iClientId, newTag->m_strRecordingId), newTag));
  }
}
Exemple #12
0
void CPVRRecordings::UpdateFromClient(const CPVRRecordingPtr &tag)
{
  CSingleLock lock(m_critSection);

  if (tag->IsDeleted())
  {
    if (tag->IsRadio())
      m_bDeletedRadioRecordings = true;
    else
      m_bDeletedTVRecordings = true;
  }

  CPVRRecordingPtr newTag = GetById(tag->m_iClientId, tag->m_strRecordingId);
  if (newTag)
  {
    newTag->Update(*tag);
  }
  else
  {
    newTag = CPVRRecordingPtr(new CPVRRecording);
    newTag->Update(*tag);
    newTag->m_iRecordingId = ++m_iLastId;
    m_recordings.insert(std::make_pair(CPVRRecordingUid(newTag->m_iClientId, newTag->m_strRecordingId), newTag));
    if (newTag->IsRadio())
      ++m_iRadioRecordings;
    else
      ++m_iTVRecordings;
  }
}
Exemple #13
0
void CPVRRecordings::UpdateFromClient(const CPVRRecordingPtr &tag)
{
  CSingleLock lock(m_critSection);

  if (tag->IsDeleted())
    m_bHasDeleted = true;

  CPVRRecordingPtr newTag = GetById(tag->m_iClientId, tag->m_strRecordingId);
  if (newTag)
  {
    newTag->Update(*tag);
  }
  else
  {
    newTag = CPVRRecordingPtr(new CPVRRecording);
    newTag->Update(*tag);
    if (newTag->EpgEvent() > 0)
    {
      EPG::CEpgInfoTagPtr epgTag = EPG::CEpgContainer::GetInstance().GetTagById(newTag->EpgEvent());
      if (epgTag)
        epgTag->SetRecording(newTag);
    }
    newTag->m_iRecordingId = ++m_iLastId;
    m_recordings.insert(std::make_pair(CPVRRecordingUid(newTag->m_iClientId, newTag->m_strRecordingId), newTag));
  }
}
Exemple #14
0
CFileItemPtr CPVRRecordings::GetByPath(const std::string &path)
{
  CSingleLock lock(m_critSection);

  CPVRRecordingsPath recPath(path);
  if (recPath.IsValid())
  {
    // Check directory name is for deleted recordings
    bool bDeleted = recPath.IsDeleted();

    for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++)
    {
      CPVRRecordingPtr current = it->second;
      if (!URIUtils::PathEquals(path, current->m_strFileNameAndPath) || bDeleted != current->IsDeleted())
        continue;

      CFileItemPtr fileItem(new CFileItem(current));
      return fileItem;
    }
  }

  CFileItemPtr fileItem(new CFileItem);
  return fileItem;
}
Exemple #15
0
void CPVRRecordings::GetSubDirectories(const std::string &strBase, CFileItemList *results)
{
  // Only active recordings are fetched to provide sub directories.
  // Not applicable for deleted view which is supposed to be flattened.
  std::string strUseBase = TrimSlashes(strBase);
  std::set<CFileItemPtr> unwatchedFolders;

  for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++)
  {
    CPVRRecordingPtr current = it->second;
    if (current->IsDeleted())
      continue;
    const std::string strCurrent = GetDirectoryFromPath(current->m_strDirectory, strUseBase);
    if (strCurrent.empty())
      continue;

    std::string strFilePath;
    if(strUseBase.empty())
      strFilePath = StringUtils::Format("pvr://" PVR_RECORDING_BASE_PATH "/" PVR_RECORDING_ACTIVE_PATH "/%s/", strCurrent.c_str());
    else
      strFilePath = StringUtils::Format("pvr://" PVR_RECORDING_BASE_PATH "/" PVR_RECORDING_ACTIVE_PATH "/%s/%s/", strUseBase.c_str(), strCurrent.c_str());

    CFileItemPtr pFileItem;
    if (m_database.IsOpen())
      current->UpdateMetadata(m_database);

    if (!results->Contains(strFilePath))
    {
      pFileItem.reset(new CFileItem(strCurrent, true));
      pFileItem->SetPath(strFilePath);
      pFileItem->SetLabel(strCurrent);
      pFileItem->SetLabelPreformated(true);
      pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();

      // Assume all folders are watched, we'll change the overlay later
      pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, false);
      results->Add(pFileItem);
    }
    else
    {
      pFileItem=results->Get(strFilePath);
      if (pFileItem->m_dateTime<current->RecordingTimeAsLocalTime())
        pFileItem->m_dateTime  = current->RecordingTimeAsLocalTime();
    }

    if (current->m_playCount == 0)
      unwatchedFolders.insert(pFileItem);
  }

  // Remove the watched overlay from folders containing unwatched entries
  for (std::set<CFileItemPtr>::iterator it = unwatchedFolders.begin(); it != unwatchedFolders.end(); ++it)
    (*it)->SetOverlayImage(CGUIListItem::ICON_OVERLAY_WATCHED, true);
}
Exemple #16
0
void CPVRRecordings::UpdateFromClient(const CPVRRecordingPtr &tag)
{
  CSingleLock lock(m_critSection);

  if (tag->IsDeleted())
  {
    if (tag->IsRadio())
      m_bDeletedRadioRecordings = true;
    else
      m_bDeletedTVRecordings = true;
  }

  CPVRRecordingPtr newTag = GetById(tag->m_iClientId, tag->m_strRecordingId);
  if (newTag)
  {
    newTag->Update(*tag);
  }
  else
  {
    newTag = CPVRRecordingPtr(new CPVRRecording);
    newTag->Update(*tag);
    if (newTag->BroadcastUid() != EPG_TAG_INVALID_UID)
    {
      const CPVRChannelPtr channel(newTag->Channel());
      if (channel)
      {
        const CPVREpgInfoTagPtr epgTag = CServiceBroker::GetPVRManager().EpgContainer().GetTagById(channel, newTag->BroadcastUid());
        if (epgTag)
          epgTag->SetRecording(newTag);
      }
    }
    newTag->m_iRecordingId = ++m_iLastId;
    m_recordings.insert(std::make_pair(CPVRRecordingUid(newTag->m_iClientId, newTag->m_strRecordingId), newTag));
    if (newTag->IsRadio())
      ++m_iRadioRecordings;
    else
      ++m_iTVRecordings;
  }
}
Exemple #17
0
bool CPVRClients::OpenStream(const CPVRRecordingPtr &channel)
{
  assert(channel.get());

  bool bReturn(false);
  CloseStream();

  /* try to open the recording stream on the client */
  PVR_CLIENT client;
  if (GetConnectedClient(channel->m_iClientId, client) &&
      client->OpenStream(channel))
  {
    CSingleLock lock(m_critSection);
    m_playingClientId = channel->m_iClientId;
    m_bIsPlayingRecording = true;
    m_strPlayingClientName = client->GetFriendlyName();
    bReturn = true;
  }

  return bReturn;
}
Exemple #18
0
bool CPVRGUIInfo::GetListItemAndPlayerBool(const CFileItem *item, const CGUIInfo &info, bool &bValue) const
{
  switch (info.m_info)
  {
    case LISTITEM_ISRECORDING:
      if (item->IsPVRChannel())
      {
        bValue = item->GetPVRChannelInfoTag()->IsRecording();
        return true;
      }
      else if (item->IsEPG() || item->IsPVRTimer())
      {
        const CPVRTimerInfoTagPtr timer = CPVRItem(item).GetTimerInfoTag();
        if (timer)
          bValue = timer->IsRecording();
        return true;
      }
      else if (item->IsPVRRecording())
      {
        bValue = item->GetPVRRecordingInfoTag()->IsInProgress();
        return true;
      }
      break;
    case LISTITEM_INPROGRESS:
      if (item->IsPVRChannel() || item->IsEPG())
      {
        const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag();
        if (epgTag)
          bValue = epgTag->IsActive();
        return true;
      }
      break;
    case LISTITEM_HASTIMER:
      if (item->IsPVRChannel() || item->IsEPG())
      {
        const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag();
        if (epgTag)
          bValue = epgTag->HasTimer();
        return true;
      }
      break;
    case LISTITEM_HASTIMERSCHEDULE:
      if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
      {
        const CPVRTimerInfoTagPtr timer = CPVRItem(item).GetTimerInfoTag();
        if (timer)
          bValue = timer->GetTimerRuleId() != PVR_TIMER_NO_PARENT;
        return true;
      }
      break;
    case LISTITEM_TIMERISACTIVE:
      if (item->IsPVRChannel() || item->IsEPG())
      {
        const CPVRTimerInfoTagPtr timer = CPVRItem(item).GetTimerInfoTag();
        if (timer)
          bValue = timer->IsActive();
        break;
      }
      break;
    case LISTITEM_TIMERHASCONFLICT:
      if (item->IsPVRChannel() || item->IsEPG())
      {
        const CPVRTimerInfoTagPtr timer = CPVRItem(item).GetTimerInfoTag();
        if (timer)
          bValue = timer->HasConflict();
        return true;
      }
      break;
    case LISTITEM_TIMERHASERROR:
      if (item->IsPVRChannel() || item->IsEPG())
      {
        const CPVRTimerInfoTagPtr timer = CPVRItem(item).GetTimerInfoTag();
        if (timer)
          bValue = (timer->IsBroken() && !timer->HasConflict());
        return true;
      }
      break;
    case LISTITEM_HASRECORDING:
      if (item->IsPVRChannel() || item->IsEPG())
      {
        const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag();
        if (epgTag)
          bValue = epgTag->HasRecording();
        return true;
      }
      break;
    case LISTITEM_HAS_EPG:
      if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
      {
        const CPVREpgInfoTagPtr epgTag = CPVRItem(item).GetEpgInfoTag();
        bValue = (epgTag != nullptr);
        return true;
      }
      break;
    case LISTITEM_ISENCRYPTED:
      if (item->IsPVRChannel() || item->IsEPG())
      {
        const CPVRChannelPtr channel = CPVRItem(item).GetChannel();
        if (channel)
          bValue = channel->IsEncrypted();
        return true;
      }
      break;
    case MUSICPLAYER_CONTENT:
    case VIDEOPLAYER_CONTENT:
      if (item->IsPVRChannel())
      {
        bValue = StringUtils::EqualsNoCase(info.GetData3(), "livetv");
        return bValue; // if no match for this provider, other providers shall be asked.
      }
      break;
    case VIDEOPLAYER_HAS_INFO:
      if (item->IsPVRChannel())
      {
        bValue = !item->GetPVRChannelInfoTag()->IsEmpty();
        return true;
      }
      break;
    case VIDEOPLAYER_HAS_EPG:
      if (item->IsPVRChannel())
      {
        bValue = (item->GetPVRChannelInfoTag()->GetEPGNow() != nullptr);
        return true;
      }
      break;
    case VIDEOPLAYER_CAN_RESUME_LIVE_TV:
      if (item->IsPVRRecording())
      {
        const CPVRRecordingPtr recording = item->GetPVRRecordingInfoTag();
        const CPVREpgInfoTagPtr epgTag = CServiceBroker::GetPVRManager().EpgContainer().GetTagById(recording->Channel(), recording->BroadcastUid());
        bValue = (epgTag && epgTag->IsActive() && epgTag->Channel());
        return true;
      }
      break;
    case PLAYER_IS_CHANNEL_PREVIEW_ACTIVE:
      if (item->IsPVRChannel())
      {
        if (CServiceBroker::GetPVRManager().GUIActions()->GetChannelNavigator().IsPreviewAndShowInfo())
        {
          bValue = true;
        }
        else
        {
          bValue = !m_videoInfo.valid;
          if (bValue && item->GetPVRChannelInfoTag()->IsRadio())
            bValue = !m_audioInfo.valid;
        }
        return true;
      }
      break;
  }
  return false;
}
Exemple #19
0
bool CPVRGUIInfo::GetListItemAndPlayerLabel(const CFileItem *item, const CGUIInfo &info, std::string &strValue) const
{
  const CPVRTimerInfoTagPtr timer = item->GetPVRTimerInfoTag();
  if (timer)
  {
    switch (info.m_info)
    {
      case LISTITEM_DATE:
        strValue = timer->Summary();
        return true;
      case LISTITEM_STARTDATE:
        strValue = timer->StartAsLocalTime().GetAsLocalizedDate(true);
        return true;
      case LISTITEM_STARTTIME:
        strValue = timer->StartAsLocalTime().GetAsLocalizedTime("", false);
        return true;
      case LISTITEM_ENDDATE:
        strValue = timer->EndAsLocalTime().GetAsLocalizedDate(true);
        return true;
      case LISTITEM_ENDTIME:
        strValue = timer->EndAsLocalTime().GetAsLocalizedTime("", false);
        return true;
      case LISTITEM_TITLE:
        strValue = timer->Title();
        return true;
      case LISTITEM_COMMENT:
        strValue = timer->GetStatus();
        return true;
      case LISTITEM_TIMERTYPE:
        strValue = timer->GetTypeAsString();
        return true;
      case LISTITEM_CHANNEL_NAME:
        strValue = timer->ChannelName();
        return true;
      case LISTITEM_EPG_EVENT_TITLE:
      case LISTITEM_EPG_EVENT_ICON:
      case LISTITEM_GENRE:
      case LISTITEM_PLOT:
      case LISTITEM_PLOT_OUTLINE:
      case LISTITEM_DURATION:
      case LISTITEM_ORIGINALTITLE:
      case LISTITEM_YEAR:
      case LISTITEM_SEASON:
      case LISTITEM_EPISODE:
      case LISTITEM_EPISODENAME:
      case LISTITEM_DIRECTOR:
      case LISTITEM_CHANNEL_NUMBER:
      case LISTITEM_PREMIERED:
        break; // obtain value from channel/epg
      default:
        return false;
    }
  }

  const CPVRRecordingPtr recording(item->GetPVRRecordingInfoTag());
  if (recording)
  {
    // Note: CPVRRecoding is derived from CVideoInfoTag. All base class properties will be handled
    //       by CVideoGUIInfoProvider. Only properties introduced by CPVRRecording need to be handled here.
    switch (info.m_info)
    {
      case LISTITEM_DATE:
        strValue = recording->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(false, false);
        return true;
      case LISTITEM_STARTDATE:
        strValue = recording->RecordingTimeAsLocalTime().GetAsLocalizedDate(true);
        return true;
      case VIDEOPLAYER_STARTTIME:
      case LISTITEM_STARTTIME:
        strValue = recording->RecordingTimeAsLocalTime().GetAsLocalizedTime("", false);
        return true;
      case LISTITEM_ENDDATE:
        strValue = recording->EndTimeAsLocalTime().GetAsLocalizedDate(true);
        return true;
      case VIDEOPLAYER_ENDTIME:
      case LISTITEM_ENDTIME:
        strValue = recording->EndTimeAsLocalTime().GetAsLocalizedTime("", false);
        return true;
      case LISTITEM_EXPIRATION_DATE:
        if (recording->HasExpirationTime())
        {
          strValue = recording->ExpirationTimeAsLocalTime().GetAsLocalizedDate(false);
          return true;
        }
        break;
      case LISTITEM_EXPIRATION_TIME:
        if (recording->HasExpirationTime())
        {
          strValue = recording->ExpirationTimeAsLocalTime().GetAsLocalizedTime("", false);;
          return true;
        }
        break;
      case VIDEOPLAYER_EPISODENAME:
      case LISTITEM_EPISODENAME:
        strValue = recording->EpisodeName();
        return true;
      case VIDEOPLAYER_CHANNEL_NAME:
      case LISTITEM_CHANNEL_NAME:
        strValue = recording->m_strChannelName;
        return true;
      case VIDEOPLAYER_CHANNEL_NUMBER:
      case LISTITEM_CHANNEL_NUMBER:
      {
        const CPVRChannelPtr channel = recording->Channel();
        if (channel)
        {
          strValue = channel->ChannelNumber().FormattedChannelNumber();
          return true;
        }
        break;
      }
      case VIDEOPLAYER_CHANNEL_GROUP:
      {
        CSingleLock lock(m_critSection);
        strValue = recording->IsRadio() ? m_strPlayingRadioGroup : m_strPlayingTVGroup;
        return true;
      }
    }
    return false;
  }

  CPVREpgInfoTagPtr epgTag;
  CPVRChannelPtr channel;
  if (item->IsPVRChannel() || item->IsEPG() || item->IsPVRTimer())
  {
    CPVRItem pvrItem(item);
    channel = pvrItem.GetChannel();

    switch (info.m_info)
    {
      case VIDEOPLAYER_NEXT_TITLE:
      case VIDEOPLAYER_NEXT_GENRE:
      case VIDEOPLAYER_NEXT_PLOT:
      case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
      case VIDEOPLAYER_NEXT_STARTTIME:
      case VIDEOPLAYER_NEXT_ENDTIME:
      case VIDEOPLAYER_NEXT_DURATION:
      case LISTITEM_NEXT_TITLE:
      case LISTITEM_NEXT_GENRE:
      case LISTITEM_NEXT_PLOT:
      case LISTITEM_NEXT_PLOT_OUTLINE:
      case LISTITEM_NEXT_STARTDATE:
      case LISTITEM_NEXT_STARTTIME:
      case LISTITEM_NEXT_ENDDATE:
      case LISTITEM_NEXT_ENDTIME:
      case LISTITEM_NEXT_DURATION:
        // next playing event
        epgTag = pvrItem.GetNextEpgInfoTag();
        break;
      default:
        // now playing event
        epgTag = pvrItem.GetEpgInfoTag();
        break;
    }

    switch (info.m_info)
    {
      // special handling for channels without epg or with radio rds data
      case PLAYER_TITLE:
      case VIDEOPLAYER_TITLE:
      case LISTITEM_TITLE:
      case VIDEOPLAYER_NEXT_TITLE:
      case LISTITEM_NEXT_TITLE:
      case LISTITEM_EPG_EVENT_TITLE:
        // Note: in difference to LISTITEM_TITLE, LISTITEM_EPG_EVENT_TITLE returns the title
        // associated with the epg event of a timer, if any, and not the title of the timer.
        if (epgTag)
          strValue = epgTag->Title();
        if (strValue.empty() && !CServiceBroker::GetSettingsComponent()->GetSettings()->GetBool(CSettings::SETTING_EPG_HIDENOINFOAVAILABLE))
          strValue = g_localizeStrings.Get(19055); // no information available
        return true;
    }
  }

  if (epgTag)
  {
    switch (info.m_info)
    {
      case VIDEOPLAYER_GENRE:
      case LISTITEM_GENRE:
      case VIDEOPLAYER_NEXT_GENRE:
      case LISTITEM_NEXT_GENRE:
        strValue = epgTag->GetGenresLabel();
        return true;
      case VIDEOPLAYER_PLOT:
      case LISTITEM_PLOT:
      case VIDEOPLAYER_NEXT_PLOT:
      case LISTITEM_NEXT_PLOT:
        strValue = epgTag->Plot();
        return true;
      case VIDEOPLAYER_PLOT_OUTLINE:
      case LISTITEM_PLOT_OUTLINE:
      case VIDEOPLAYER_NEXT_PLOT_OUTLINE:
      case LISTITEM_NEXT_PLOT_OUTLINE:
        strValue = epgTag->PlotOutline();
        return true;
      case LISTITEM_DATE:
        strValue = epgTag->StartAsLocalTime().GetAsLocalizedDateTime(false, false);
        return true;
      case LISTITEM_STARTDATE:
      case LISTITEM_NEXT_STARTDATE:
        strValue = epgTag->StartAsLocalTime().GetAsLocalizedDate(true);
        return true;
      case VIDEOPLAYER_STARTTIME:
      case VIDEOPLAYER_NEXT_STARTTIME:
      case LISTITEM_STARTTIME:
      case LISTITEM_NEXT_STARTTIME:
        strValue = epgTag->StartAsLocalTime().GetAsLocalizedTime("", false);
        return true;
      case LISTITEM_ENDDATE:
      case LISTITEM_NEXT_ENDDATE:
        strValue = epgTag->EndAsLocalTime().GetAsLocalizedDate(true);
        return true;
      case VIDEOPLAYER_ENDTIME:
      case VIDEOPLAYER_NEXT_ENDTIME:
      case LISTITEM_ENDTIME:
      case LISTITEM_NEXT_ENDTIME:
        strValue = epgTag->EndAsLocalTime().GetAsLocalizedTime("", false);
        return true;
      // note: for some reason, there is no VIDEOPLAYER_DURATION
      case LISTITEM_DURATION:
      case VIDEOPLAYER_NEXT_DURATION:
      case LISTITEM_NEXT_DURATION:
        if (epgTag->GetDuration() > 0)
        {
          strValue = StringUtils::SecondsToTimeString(epgTag->GetDuration(), static_cast<TIME_FORMAT>(info.GetData4()));
          return true;
        }
        return false;
      case VIDEOPLAYER_IMDBNUMBER:
      case LISTITEM_IMDBNUMBER:
        strValue = epgTag->IMDBNumber();
        return true;
      case VIDEOPLAYER_ORIGINALTITLE:
      case LISTITEM_ORIGINALTITLE:
        strValue = epgTag->OriginalTitle();
        return true;
      case VIDEOPLAYER_YEAR:
      case LISTITEM_YEAR:
        if (epgTag->Year() > 0)
        {
          strValue = StringUtils::Format("%i", epgTag->Year());
          return true;
        }
        return false;
      case VIDEOPLAYER_SEASON:
      case LISTITEM_SEASON:
        if (epgTag->SeriesNumber() > 0)
        {
          strValue = StringUtils::Format("%i", epgTag->SeriesNumber());
          return true;
        }
        return false;
      case VIDEOPLAYER_EPISODE:
      case LISTITEM_EPISODE:
        if (epgTag->EpisodeNumber() > 0)
        {
          if (epgTag->SeriesNumber() == 0) // prefix episode with 'S'
            strValue = StringUtils::Format("S%i", epgTag->EpisodeNumber());
          else
            strValue = StringUtils::Format("%i", epgTag->EpisodeNumber());
          return true;
        }
        return false;
      case VIDEOPLAYER_EPISODENAME:
      case LISTITEM_EPISODENAME:
        strValue = epgTag->EpisodeName();
        return true;
      case VIDEOPLAYER_CAST:
      case LISTITEM_CAST:
        strValue = epgTag->GetCastLabel();
        return true;
      case VIDEOPLAYER_DIRECTOR:
      case LISTITEM_DIRECTOR:
        strValue = epgTag->GetDirectorsLabel();
        return true;
      case VIDEOPLAYER_WRITER:
      case LISTITEM_WRITER:
        strValue = epgTag->GetWritersLabel();
        return true;
      case LISTITEM_EPG_EVENT_ICON:
        strValue = epgTag->Icon();
        return true;
      case VIDEOPLAYER_PARENTAL_RATING:
      case LISTITEM_PARENTALRATING:
        if (epgTag->ParentalRating() > 0)
        {
          strValue = StringUtils::Format("%i", epgTag->ParentalRating());
          return true;
        }
        return false;
      case LISTITEM_PREMIERED:
        if (epgTag->FirstAiredAsLocalTime().IsValid())
        {
          strValue = epgTag->FirstAiredAsLocalTime().GetAsLocalizedDate(true);
          return true;
        }
        return false;
    }
  }

  if (channel)
  {
    switch (info.m_info)
    {
      case MUSICPLAYER_CHANNEL_NAME:
      {
        const std::shared_ptr<CPVRRadioRDSInfoTag> rdsTag = channel->GetRadioRDSInfoTag();
        if (rdsTag)
        {
          strValue = rdsTag->GetProgStation();
          if (!strValue.empty())
            return true;
        }
        // fall-thru is intended
      }
      case VIDEOPLAYER_CHANNEL_NAME:
      case LISTITEM_CHANNEL_NAME:
        strValue = channel->ChannelName();
        return true;
      case MUSICPLAYER_CHANNEL_NUMBER:
      case VIDEOPLAYER_CHANNEL_NUMBER:
      case LISTITEM_CHANNEL_NUMBER:
        strValue = channel->ChannelNumber().FormattedChannelNumber();
        return true;
      case MUSICPLAYER_CHANNEL_GROUP:
      case VIDEOPLAYER_CHANNEL_GROUP:
      {
        CSingleLock lock(m_critSection);
        strValue = channel->IsRadio() ? m_strPlayingRadioGroup : m_strPlayingTVGroup;
        return true;
      }
    }
  }

  return false;
}
Exemple #20
0
bool CPVRRecordings::ChangeRecordingsPlayCount(const CFileItemPtr &item, int count)
{
  bool bResult = false;

  if (m_database.IsOpen())
  {
    bResult = true;

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - item path %s", __FUNCTION__, item->GetPath().c_str());
    CFileItemList items;
    if (item->m_bIsFolder)
    {
      XFILE::CDirectory::GetDirectory(item->GetPath(), items);
    }
    else
      items.Add(item);

    CLog::Log(LOGDEBUG, "CPVRRecordings - %s - will set watched for %d items", __FUNCTION__, items.Size());
    for (int i=0;i<items.Size();++i)
    {
      CLog::Log(LOGDEBUG, "CPVRRecordings - %s - setting watched for item %d", __FUNCTION__, i);

      CFileItemPtr pItem=items[i];
      if (pItem->m_bIsFolder)
      {
        CLog::Log(LOGDEBUG, "CPVRRecordings - %s - path %s is a folder, will call recursively", __FUNCTION__, pItem->GetPath().c_str());
        if (pItem->GetLabel() != "..")
        {
          ChangeRecordingsPlayCount(pItem, count);
        }
        continue;
      }

      if (!pItem->HasPVRRecordingInfoTag())
        continue;

      const CPVRRecordingPtr recording = pItem->GetPVRRecordingInfoTag();
      if (recording)
      {
        if (count == INCREMENT_PLAY_COUNT)
          recording->IncrementPlayCount();
        else
          recording->SetPlayCount(count);

        // Clear resume bookmark
        if (recording->GetPlayCount() > 0)
        {
          m_database.ClearBookMarksOfFile(pItem->GetPath(), CBookmark::RESUME);
          recording->SetResumePoint(CBookmark());
        }

        if (count == INCREMENT_PLAY_COUNT)
          m_database.IncrementPlayCount(*pItem);
        else
          m_database.SetPlayCount(*pItem, count);
      }
    }

    CServiceBroker::GetPVRManager().PublishEvent(RecordingsInvalidated);
  }

  return bResult;
}
Exemple #21
0
bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &items)
{
  CSingleLock lock(m_critSection);

  bool bGrouped = false;
  const CURL url(strPath);
  if (url.HasOption("view"))
  {
    const std::string view(url.GetOption("view"));
    if (view == "grouped")
      bGrouped = true;
    else if (view == "flat")
      bGrouped = false;
    else
    {
      CLog::Log(LOGERROR, "CPVRRecordings - %s - unsupported value '%s' for url parameter 'view'", __FUNCTION__, view.c_str());
      return false;
    }
  }
  else
  {
    bGrouped = CSettings::GetInstance().GetBool(CSettings::SETTING_PVRRECORD_GROUPRECORDINGS);
  }

  CPVRRecordingsPath recPath(url.GetWithoutOptions());
  if (recPath.IsValid())
  {
    // Get the directory structure if in non-flatten mode
    // Deleted view is always flatten. So only for an active view
    std::string strDirectory(recPath.GetUnescapedDirectoryPath());
    if (!recPath.IsDeleted() && bGrouped)
      GetSubDirectories(recPath, &items);

    // get all files of the currrent directory or recursively all files starting at the current directory if in flatten mode
    for (const auto recording : m_recordings)
    {
      CPVRRecordingPtr current = recording.second;

      // Omit recordings not matching criteria
      if (!IsDirectoryMember(strDirectory, current->m_strDirectory, bGrouped) ||
          current->IsDeleted() != recPath.IsDeleted() ||
          current->IsRadio() != recPath.IsRadio())
        continue;

      if (m_database.IsOpen())
        current->UpdateMetadata(m_database);
      CFileItemPtr pFileItem(new CFileItem(current));
      pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false));
      pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
      pFileItem->SetPath(current->m_strFileNameAndPath);

      // Set art
      if (!current->m_strIconPath.empty())
      {
        pFileItem->SetIconImage(current->m_strIconPath);
        pFileItem->SetArt("icon", current->m_strIconPath);
      }

      if (!current->m_strThumbnailPath.empty())
        pFileItem->SetArt("thumb", current->m_strThumbnailPath);

      if (!current->m_strFanartPath.empty())
        pFileItem->SetArt("fanart", current->m_strFanartPath);

      // Use the channel icon as a fallback when a thumbnail is not available
      pFileItem->SetArtFallback("thumb", "icon");

      pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pFileItem->GetPVRRecordingInfoTag()->m_playCount > 0);

      items.Add(pFileItem);
    }
  }

  return recPath.IsValid();
}
Exemple #22
0
bool CPVRRecordings::GetDirectory(const std::string& strPath, CFileItemList &items)
{
  CSingleLock lock(m_critSection);

  CURL url(strPath);
  std::string strDirectoryPath = url.GetFileName();
  URIUtils::RemoveSlashAtEnd(strDirectoryPath);

  if (StringUtils::StartsWith(strDirectoryPath, PVR_RECORDING_BASE_PATH))
  {
    strDirectoryPath.erase(0, sizeof(PVR_RECORDING_BASE_PATH) - 1);

    // Check directory name is for deleted recordings
    bool bDeleted = StringUtils::StartsWith(strDirectoryPath, "/" PVR_RECORDING_DELETED_PATH);
    strDirectoryPath.erase(0, bDeleted ? sizeof(PVR_RECORDING_DELETED_PATH) : sizeof(PVR_RECORDING_ACTIVE_PATH));

    // Get the directory structure if in non-flatten mode
    // Deleted view is always flatten. So only for an active view
    if (!bDeleted && m_bGroupItems)
      GetSubDirectories(strDirectoryPath, &items);

    // get all files of the currrent directory or recursively all files starting at the current directory if in flatten mode
    for (PVR_RECORDINGMAP_CITR it = m_recordings.begin(); it != m_recordings.end(); it++)
    {
      CPVRRecordingPtr current = it->second;

      // skip items that are not members of the target directory
      if (!IsDirectoryMember(strDirectoryPath, current->m_strDirectory) || current->IsDeleted() != bDeleted)
        continue;

      if (m_database.IsOpen())
        current->UpdateMetadata(m_database);
      CFileItemPtr pFileItem(new CFileItem(current));
      pFileItem->SetLabel2(current->RecordingTimeAsLocalTime().GetAsLocalizedDateTime(true, false));
      pFileItem->m_dateTime = current->RecordingTimeAsLocalTime();
      pFileItem->SetPath(current->m_strFileNameAndPath);

      // Set art
      if (!current->m_strIconPath.empty())
      {
        pFileItem->SetIconImage(current->m_strIconPath);
        pFileItem->SetArt("icon", current->m_strIconPath);
      }

      if (!current->m_strThumbnailPath.empty())
        pFileItem->SetArt("thumb", current->m_strThumbnailPath);

      if (!current->m_strFanartPath.empty())
        pFileItem->SetArt("fanart", current->m_strFanartPath);

      // Use the channel icon as a fallback when a thumbnail is not available
      pFileItem->SetArtFallback("thumb", "icon");

      pFileItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pFileItem->GetPVRRecordingInfoTag()->m_playCount > 0);

      items.Add(pFileItem);
    }

    return true;
  }

  return false;
}