예제 #1
0
/**
 * \brief Gets a list of folders for recorded TV shows
 */
bool CMythDirectory::GetTvShowFolders(const CStdString& base, CFileItemList &items)
{
  cmyth_proglist_t list = m_session->GetAllRecordedPrograms();
  if (!list)
  {
    CLog::Log(LOGERROR, "%s - unable to get list of recordings", __FUNCTION__);
    return false;
  }

  int count = m_dll->proglist_get_count(list);
  for (int i = 0; i < count; i++)
  {
    cmyth_proginfo_t program = m_dll->proglist_get_item(list, i);
    if (program)
    {
      if (!IsVisible(program))
      {
        m_dll->ref_release(program);
        continue;
      }

      if (!IsTvShow(program))
      {
        m_dll->ref_release(program);
        continue;
      }

      CStdString title = GetValue(m_dll->proginfo_title(program));
      CStdString path = base + "/" + title + "/";

      /*
       * Only add each TV show once. If the TV show is already in the list, update the date for the
       * folder to be the date of the last recorded TV show as the programs are returned in the
       * order they were recorded.
       */
      if (items.Contains(path))
      {
        CFileItemPtr item = items.Get(path);
        item->m_dateTime = GetValue(m_dll->proginfo_rec_start(program));
      }
      else
      {
        CFileItemPtr item(new CFileItem(path, true));
        item->m_dateTime = GetValue(m_dll->proginfo_rec_start(program));
        item->SetLabel(title);
        items.Add(item);
      }
      m_dll->ref_release(program);
    }

  }

  if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
    items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_THE, 551 /* Name */, LABEL_MASKS("", "", "%L", "%J"));
  else
    items.AddSortMethod(SORT_METHOD_LABEL, 551 /* Name */, LABEL_MASKS("", "", "%L", "%J"));
  items.AddSortMethod(SORT_METHOD_DATE, 552 /* Date */, LABEL_MASKS("", "", "%L", "%J"));

  return true;
}
예제 #2
0
bool CBlurayDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  Dispose();
  m_url = url;
  std::string root = m_url.GetHostName();
  std::string file = m_url.GetFileName();
  URIUtils::RemoveSlashAtEnd(file);
  URIUtils::RemoveSlashAtEnd(root);

  if (!InitializeBluray(root))
    return false;

  if(file == "root")
    GetRoot(items);
  else if(file == "root/titles")
    GetTitles(false, items);
  else
  {
    CURL url2 = GetUnderlyingCURL(url);
    CDirectory::CHints hints;
    hints.flags = m_flags;
    if (!CDirectory::GetDirectory(url2, items, hints))
      return false;
  }

  items.AddSortMethod(SortByTrackNumber,  554, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SortBySize,         553, LABEL_MASKS("%L", "%I", "%L", "%I"));  // FileName, Size | Foldername, Size

  return true;
}
예제 #3
0
bool CHTSPDirectory::GetChannels( const CURL &base
                                , CFileItemList &items
                                , SChannels channels
                                , int tag)
{
  CURL url(base);

  SEvent event;

  for(SChannels::iterator it = channels.begin(); it != channels.end(); it++)
  {
    if(!m_session->GetEvent(event, it->second.event))
      event.Clear();

    CFileItemPtr item(new CFileItem("", true));

    url.SetFileName("");
    item->SetPath(url.Get());
    CHTSPSession::ParseItem(it->second, tag, event, *item);
    item->m_bIsFolder = false;
    item->SetLabel(item->m_strTitle);
    item->m_strTitle = StringUtils::Format("%d", it->second.num);

    items.Add(item);
  }

  items.AddSortMethod(SortByTrackNumber,   554, LABEL_MASKS("%K[ - %B]", "%Z", "%L", ""));
  items.AddSortMethod(SortByAlbum,         558, LABEL_MASKS("%B", "%Z", "%L", ""), CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);
  items.AddSortMethod(SortByLabel,         551, LABEL_MASKS("%Z", "%B", "%L", ""), CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);

  items.SetContent("livetv");

  return !channels.empty();

}
예제 #4
0
/**
 * \brief Gets a list of folders for recorded TV shows
 */
bool CCMythDirectory::GetTvShowFolders(const CStdString& base, CFileItemList &items)
{
  cmyth_conn_t control = m_session->GetControl();
  if(!control)
    return false;

  cmyth_proglist_t list = m_dll->proglist_get_all_recorded(control);
  if(!list)
  {
    CLog::Log(LOGERROR, "%s - unable to get list of recordings", __FUNCTION__);
    return false;
  }

  int count = m_dll->proglist_get_count(list);
  for(int i=0; i<count; i++)
  {
    cmyth_proginfo_t program = m_dll->proglist_get_item(list, i);
    if(program)
    {
      if(GetValue(m_dll->proginfo_recgroup(program)).Equals("LiveTV"))
      {
        m_dll->ref_release(program);
        continue;
      }

      if (!IsTvShow(program))
      {
        m_dll->ref_release(program);
        continue;
      }

      CStdString title = GetValue(m_dll->proginfo_title(program));

      // Only add each TV show once
      if (items.Contains(base + "/" + title + "/"))
      {
        m_dll->ref_release(program);
        continue;
      }

      CFileItemPtr item(new CFileItem(base + "/" + title + "/", true));
      item->SetLabel(title);
      item->SetLabelPreformated(true);

      items.Add(item);
      m_dll->ref_release(program);
    }

  }

    // Sort by name only. Labels are preformated.
    if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
      items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_THE, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));
    else
      items.AddSortMethod(SORT_METHOD_LABEL, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));

  m_dll->ref_release(list);
  return true;
}
예제 #5
0
bool CPVRDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  CStdString base(url.Get());
  URIUtils::RemoveSlashAtEnd(base);

  CStdString fileName = url.GetFileName();
  URIUtils::RemoveSlashAtEnd(fileName);
  CLog::Log(LOGDEBUG, "CPVRDirectory::GetDirectory(%s)", base.c_str());
  items.SetCacheToDisc(CFileItemList::CACHE_NEVER);

  if (!g_PVRManager.IsStarted())
    return false;

  if (fileName == "")
  {
    CFileItemPtr item;

    item.reset(new CFileItem(base + "/channels/", true));
    item->SetLabel(g_localizeStrings.Get(19019));
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/recordings/", true));
    item->SetLabel(g_localizeStrings.Get(19017));
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/timers/", true));
    item->SetLabel(g_localizeStrings.Get(19040));
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/guide/", true));
    item->SetLabel(g_localizeStrings.Get(19029));
    item->SetLabelPreformated(true);
    items.Add(item);

    // Sort by name only. Labels are preformated.
    items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));

    return true;
  }
  else if (StringUtils::StartsWith(fileName, "recordings"))
  {
    const CStdString pathToUrl(url.Get());
    return g_PVRRecordings->GetDirectory(pathToUrl, items);
  }
  else if (StringUtils::StartsWith(fileName, "channels"))
  {
    const CStdString pathToUrl(url.Get());
    return g_PVRChannelGroups->GetDirectory(pathToUrl, items);
  }
  else if (StringUtils::StartsWith(fileName, "timers"))
  {
    const CStdString pathToUrl(url.Get());
    return g_PVRTimers->GetDirectory(pathToUrl, items);
  }

  return false;
}
예제 #6
0
bool CBlurayDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  Dispose();
  m_url = url;
  std::string root = m_url.GetHostName();
  std::string file = m_url.GetFileName();
  URIUtils::RemoveSlashAtEnd(file);
  URIUtils::RemoveSlashAtEnd(root);

  m_dll = new DllLibbluray();
  if (!m_dll->Load())
  {
    CLog::Log(LOGERROR, "CBlurayDirectory::GetDirectory - failed to load dll");
    return false;
  }

  m_dll->bd_register_dir(DllLibbluray::dir_open);
  m_dll->bd_register_file(DllLibbluray::file_open);
  m_dll->bd_set_debug_handler(DllLibbluray::bluray_logger);
  m_dll->bd_set_debug_mask(DBG_CRIT | DBG_BLURAY | DBG_NAV);

  m_bd = m_dll->bd_open(root.c_str(), NULL);

  if(!m_bd)
  {
    CLog::Log(LOGERROR, "CBlurayDirectory::GetDirectory - failed to open %s", root.c_str());
    return false;
  }

  if(file == "root")
    GetRoot(items);
  else if(file == "root/titles")
    GetTitles(false, items);
  else
  {
    CURL url2 = GetUnderlyingCURL(url);
    CDirectory::CHints hints;
    hints.flags = m_flags;
    if (!CDirectory::GetDirectory(url2, items, hints))
      return false;
  }

  items.AddSortMethod(SortByTrackNumber,  554, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SortBySize,         553, LABEL_MASKS("%L", "%I", "%L", "%I"));  // FileName, Size | Foldername, Size

  return true;
}
예제 #7
0
파일: HTSPDirectory.cpp 프로젝트: Jdad/xbmc
bool CHTSPDirectory::GetChannels( const CURL &base
                                , CFileItemList &items
                                , SChannels channels
                                , int tag)
{
  CURL url(base);

  SEvent event;

  for(SChannels::iterator it = channels.begin(); it != channels.end(); it++)
  {
    if(!m_session->GetEvent(event, it->second.event))
      event.Clear();

    CFileItemPtr item(new CFileItem("", true));

    url.SetFileName("");
    item->SetPath(url.Get());
    CHTSPSession::ParseItem(it->second, tag, event, *item);
    item->m_bIsFolder = false;
    item->SetLabel(item->m_strTitle);
    item->m_strTitle.Format("%d", it->second.num);

    items.Add(item);
  }

  items.AddSortMethod(SORT_METHOD_TRACKNUM, 554, LABEL_MASKS("%K[ - %B]", "%Z", "%L", ""));

  if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
    items.AddSortMethod(SORT_METHOD_ALBUM_IGNORE_THE, 558,   LABEL_MASKS("%B", "%Z", "%L", ""));
  else
    items.AddSortMethod(SORT_METHOD_ALBUM,            558,   LABEL_MASKS("%B", "%Z", "%L", ""));

  if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
    items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_THE, 551, LABEL_MASKS("%Z", "%B", "%L", ""));
  else
    items.AddSortMethod(SORT_METHOD_LABEL,            551, LABEL_MASKS("%Z", "%B", "%L", ""));

  items.SetContent("livetv");

  return !channels.empty();

}
예제 #8
0
bool CPVRDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  CStdString base(strPath);
  CUtil::RemoveSlashAtEnd(base);

  CURL url(strPath);
  CStdString fileName = url.GetFileName();
  CUtil::RemoveSlashAtEnd(fileName);
  CLog::Log(LOGDEBUG, "CPVRDirectory::GetDirectory(%s)", base.c_str());

  if (fileName == "")
  {
    CFileItemPtr item;

    item.reset(new CFileItem(base + "/channels/", true));
    item->SetLabel(g_localizeStrings.Get(19019));
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/recordings/", true));
    item->SetLabel(g_localizeStrings.Get(19017));
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/timers/", true));
    item->SetLabel(g_localizeStrings.Get(19040));
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/guide/", true));
    item->SetLabel(g_localizeStrings.Get(19029));
    item->SetLabelPreformated(true);
    items.Add(item);

    // Sort by name only. Labels are preformated.
    items.AddSortMethod(SORT_METHOD_LABEL, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));

    return true;
  }
  else if (fileName.Left(10) == "recordings")
  {
    return PVRRecordings.GetDirectory(strPath, items) > 0;
  }
  else if (fileName.Left(8) == "channels")
  {
    return CPVRChannels::GetDirectory(strPath, items) > 0;
  }
  else if (fileName.Left(6) == "timers")
  {
    return PVRTimers.GetDirectory(strPath, items) > 0;
  }

  return false;
}
예제 #9
0
bool CBlurayDirectory::GetDirectory(const CStdString& path, CFileItemList &items)
{
  Dispose();
  m_url.Parse(path);
  CStdString root = m_url.GetHostName();
  CStdString file = m_url.GetFileName();
  URIUtils::RemoveSlashAtEnd(file);

  m_dll = new DllLibbluray();
  if (!m_dll->Load())
  {
    CLog::Log(LOGERROR, "CBlurayDirectory::GetDirectory - failed to load dll");
    return false;
  }

  m_dll->bd_register_dir(DllLibbluray::dir_open);
  m_dll->bd_register_file(DllLibbluray::file_open);
  m_dll->bd_set_debug_handler(DllLibbluray::bluray_logger);
  m_dll->bd_set_debug_mask(DBG_CRIT | DBG_BLURAY | DBG_NAV);

  m_bd = m_dll->bd_open(root.c_str(), NULL);

  if(!m_bd)
  {
    CLog::Log(LOGERROR, "CBlurayDirectory::GetDirectory - failed to open %s", root.c_str());
    return false;
  }

  if(file == "")
    GetRoot(items);
  else if(file == "titles")
    GetTitles(false, items);
  else
    return false;

  items.AddSortMethod(SORT_METHOD_TRACKNUM , 554, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SORT_METHOD_SIZE     , 553, LABEL_MASKS("%L", "%I", "%L", "%I"));  // FileName, Size | Foldername, Size

  return true;
}
예제 #10
0
bool CMythDirectory::GetGuide(const CStdString& base, CFileItemList &items)
{
  cmyth_database_t db = m_session->GetDatabase();
  if (!db)
    return false;

  cmyth_chanlist_t list = m_dll->mysql_get_chanlist(db);
  if (!list)
  {
    CLog::Log(LOGERROR, "%s - Unable to get list of channels: %s", __FUNCTION__, base.c_str());
    return false;
  }
  CURL url(base);

  int count = m_dll->chanlist_get_count(list);
  for (int i = 0; i < count; i++)
  {
    cmyth_channel_t channel = m_dll->chanlist_get_item(list, i);
    if (channel)
    {
      if (!m_dll->channel_visible(channel))
      {
        m_dll->ref_release(channel);
        continue;
      }

      int channum = m_dll->channel_channum(channel); // e.g. 3
      CStdString name = GetValue(m_dll->channel_name(channel)); // e.g. TV3
      if (channum <= 0)
      {
        CLog::Log(LOGDEBUG, "%s - Skipping channel number %d as <= 0: %s", __FUNCTION__, channum, name.c_str());
        m_dll->ref_release(channel);
        continue;
      }

      CLog::Log(LOGDEBUG, "%s - Adding channel number %d: %s", __FUNCTION__, channum, name.c_str());

      CStdString number = StringUtils::Format("%d", channum); // CStdString easier for string manipulation than int.
      url.SetFileName("guide/" + number);
      CFileItemPtr item(new CFileItem(url.Get(), true));
      item->m_strTitle = number;
      if (!name.empty())
        item->m_strTitle += " - " + name; // e.g. 3 - TV3

      CStdString icon = GetValue(m_dll->channel_icon(channel));
      if (!icon.empty())
      {
        url.SetFileName("files/channels/" + URIUtils::GetFileName(icon)); // e.g. files/channels/tv3.jpg
        item->SetArt("thumb", url.Get());
      }

      items.Add(item);

      m_dll->ref_release(channel);
    }
  }

  items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("", "", "%K", ""));

  m_dll->ref_release(list);
  return true;
}
예제 #11
0
bool CMythDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  m_session = CMythSession::AquireSession(url);
  if (!m_session)
    return false;

  m_dll = m_session->GetLibrary();
  if (!m_dll)
    return false;

  CStdString base(url.Get());
  URIUtils::RemoveSlashAtEnd(base);

  CStdString fileName = url.GetFileName();
  URIUtils::RemoveSlashAtEnd(fileName);

  if (fileName == "")
  {
    /*
     * If we can't get the control then we can't connect to the backend. Don't even show any of the
     * virtual folders as none of them will work. Without this check the "Browse" functionality
     * when adding a myth:// source is way confusing as it shows folders so it looks like it has
     * connected successfully when it in fact hasn't.
     */
    cmyth_conn_t control = m_session->GetControl();
    if (!control)
      return false;

    CFileItemPtr item;

    item.reset(new CFileItem(base + "/recordings/", true));
    item->SetLabel(g_localizeStrings.Get(22015)); // All recordings
    items.Add(item);

    item.reset(new CFileItem(base + "/tvshows/", true));
    item->SetLabel(g_localizeStrings.Get(20343)); // TV shows
    items.Add(item);

    item.reset(new CFileItem(base + "/movies/", true));
    item->SetLabel(g_localizeStrings.Get(20342)); // Movies
    items.Add(item);

    item.reset(new CFileItem(base + "/channels/", true));
    item->SetLabel(g_localizeStrings.Get(22018)); // Live channels
    items.Add(item);

    item.reset(new CFileItem(base + "/guide/", true));
    item->SetLabel(g_localizeStrings.Get(22020)); // Guide
    items.Add(item);

    items.AddSortMethod(SortByNone, 564 /* Type */, LABEL_MASKS("", "", "%L", "")); // No sorting, as added to list.

    /*
     * Clear the directory cache so the cached sub-folders are guaranteed to be accurate.
     */
    g_directoryCache.ClearSubPaths(base);

    return true;
  }
  else if (fileName == "channels")
    return GetChannels(base, items);
  else if (fileName == "guide")
    return GetGuide(base, items);
  else if (StringUtils::StartsWith(fileName, "guide/"))
    return GetGuideForChannel(base, items, atoi(fileName.substr(6).c_str()));
  else if (fileName == "movies")
    return GetRecordings(base, items, MOVIES);
  else if (fileName == "recordings")
    return GetRecordings(base, items);
  else if (fileName == "tvshows")
    return GetTvShowFolders(base, items);
  else if (StringUtils::StartsWith(fileName, "tvshows/"))
    return GetRecordings(base, items, TV_SHOWS, fileName.substr(8).c_str());
  return false;
}
예제 #12
0
bool CMythDirectory::GetChannels(const CStdString& base, CFileItemList &items)
{
  cmyth_conn_t control = m_session->GetControl();
  if (!control)
    return false;

  vector<cmyth_proginfo_t> channels;
  for (unsigned i = 0; i < 16; i++)
  {
    cmyth_recorder_t recorder = m_dll->conn_get_recorder_from_num(control, i);
    if (!recorder)
      continue;

    cmyth_proginfo_t program;
    program = m_dll->recorder_get_cur_proginfo(recorder);
    program = m_dll->recorder_get_next_proginfo(recorder, program, BROWSE_DIRECTION_UP);
    if (!program)
    {
      m_dll->ref_release(m_recorder);
      continue;
    }

    long startchan = m_dll->proginfo_chan_id(program);
    long currchan  = -1;
    while (startchan != currchan)
    {
      unsigned j;
      for (j = 0; j < channels.size(); j++)
      {
        if (m_dll->proginfo_compare(program, channels[j]) == 0)
          break;
      }

      if (j == channels.size())
        channels.push_back(program);

      program = m_dll->recorder_get_next_proginfo(recorder, program, BROWSE_DIRECTION_UP);
      if (!program)
        break;

      currchan = m_dll->proginfo_chan_id(program);
    }
    m_dll->ref_release(recorder);
  }

  CURL url(base);
  /*
   * The content of the cmyth_proginfo_t struct retrieved and stored in channels[] above does not
   * contain the host so the URL cannot be modified to support both master and slave servers.
   */

  for (unsigned i = 0; i < channels.size(); i++)
  {
    cmyth_proginfo_t program = channels[i];

    url.SetFileName("channels/" + GetValue(m_dll->proginfo_chanstr(program)) + ".ts"); // e.g. 3.ts
    CFileItemPtr item(new CFileItem(url.Get(), false));
    m_session->SetFileItemMetaData(*item, program);

    items.Add(item);
    m_dll->ref_release(program);
  }

  items.AddSortMethod(SortByLabel, 551 /* Name */, LABEL_MASKS("%K", "%B"));

  /*
   * Video sort title is set to the channel number.
   */
  items.AddSortMethod(SortBySortTitle, 556 /* Title */, LABEL_MASKS("%K", "%B"), CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);

  return true;
}
예제 #13
0
bool CMythDirectory::GetRecordings(const CStdString& base, CFileItemList &items, enum FilterType type,
                                    const CStdString& filter)
{
  cmyth_proglist_t list = m_session->GetAllRecordedPrograms();
  if (!list)
  {
    CLog::Log(LOGERROR, "%s - unable to get list of recordings", __FUNCTION__);
    return false;
  }

  int count = m_dll->proglist_get_count(list);
  for (int i = 0; i < count; i++)
  {
    cmyth_proginfo_t program = m_dll->proglist_get_item(list, i);
    if (program)
    {
      if (!IsVisible(program))
      {
        m_dll->ref_release(program);
        continue;
      }

      CURL url(base);
      /*
       * The base is the URL used to connect to the master server. The hostname in this may not
       * appropriate for all items as MythTV supports multiple backends (master + slaves).
       *
       * The appropriate host for playback is contained in the program information sent back from
       * the master. The same username and password are used in the URL as for the master.
       */
      url.SetHostName(GetValue(m_dll->proginfo_host(program)));

      CStdString path = URIUtils::GetFileName(GetValue(m_dll->proginfo_pathname(program)));
      CStdString name = GetValue(m_dll->proginfo_title(program));

      switch (type)
      {
      case MOVIES:
        if (!IsMovie(program))
        {
          m_dll->ref_release(program);
          continue;
        }
        url.SetFileName("movies/" + path);
        break;
      case TV_SHOWS:
        if (!StringUtils::EqualsNoCase(filter, name))
        {
          m_dll->ref_release(program);
          continue;
        }
        url.SetFileName("tvshows/" + name + "/" + path);
        break;
      case ALL:
        url.SetFileName("recordings/" + path);
        break;
      }

      CFileItemPtr item(new CFileItem(url.Get(), false));
      m_session->SetFileItemMetaData(*item, program);

      /*
       * If MOVIES, set the label and specify as pre-formatted so any scraper lookup will use the
       * label rather than the filename. Don't set as pre-formatted for any other types as this
       * prevents the display of the title changing depending on what the list is being sorted by.
       */
      if (type == MOVIES)
      {
        /*
         * Adding the production year, if available, to the label for Movies to aid in scraper
         * lookups.
         */
        CStdString label(item->m_strTitle);
        unsigned short year = m_dll->proginfo_year(program);
        if (year > 0)
          label += StringUtils::Format(" (%d)", year);
        item->SetLabel(label);
        item->SetLabelPreformated(true);
      }

      items.Add(item);
      m_dll->ref_release(program);
    }
  }
  m_dll->ref_release(list);

  /*
   * Don't sort by name for TV_SHOWS as they all have the same name, so only date sort is useful.
   * Since the subtitle has been added to the TV Show name, the video sort title sort is used so
   * the subtitle doesn't influence the sort order and they are sorted by date.
   */
  if (type != TV_SHOWS)
    items.AddSortMethod(SortBySortTitle, 556 /* Name */, LABEL_MASKS("%K", "%J"), CSettings::Get().GetBool("filelists.ignorethewhensorting") ? SortAttributeIgnoreArticle : SortAttributeNone);
  items.AddSortMethod(SortByDate, 552 /* Date */, LABEL_MASKS("%K", "%J"));

  return true;
}
예제 #14
0
bool CMythDirectory::GetGuideForChannel(const CStdString& base, CFileItemList &items, int channelNumber)
{
  cmyth_database_t database = m_session->GetDatabase();
  if (!database)
  {
    CLog::Log(LOGERROR, "%s - Could not get database", __FUNCTION__);
    return false;
  }

  time_t now;
  time(&now);
  time_t end = now + (24 * 60 * 60); // How many seconds of EPG from now we should grab, 24 hours in seconds

  cmyth_program_t *program = NULL;
  // TODO: See if there is a way to just get the entries for the chosen channel rather than ALL
  int count = m_dll->mysql_get_guide(database, &program, now, end);
  CLog::Log(LOGDEBUG, "%s - %i entries in guide data", __FUNCTION__, count);
  if (count <= 0)
    return false;

  for (int i = 0; i < count; i++)
  {
    if (program[i].channum == channelNumber)
    {
      CFileItemPtr item(new CFileItem("", false)); // No path for guide entries

      /*
       * Set the FileItem meta data.
       */
      CStdString title        = program[i].title; // e.g. Mythbusters
      CStdString subtitle     = program[i].subtitle; // e.g. The Pirate Special
      CDateTime localstart;
      if (program[i].starttime)
        localstart = CTimeUtils::GetLocalTime(program[i].starttime);
      item->m_strTitle = StringUtils::Format("%s - %s",
                                             localstart.GetAsLocalizedTime("HH:mm", false).c_str(),
                                             title.c_str()); // e.g. 20:30 - Mythbusters
      if (!subtitle.empty())
        item->m_strTitle     += " - \"" + subtitle + "\""; // e.g. 20:30 - Mythbusters - "The Pirate Special"
      item->m_dateTime        = localstart;

      /*
       * Set the VideoInfoTag meta data so it matches the FileItem meta data where possible.
       */
      CVideoInfoTag* tag      = item->GetVideoInfoTag();
      tag->m_strTitle         = title;
      if (!subtitle.empty())
        tag->m_strTitle      += " - \"" + subtitle + "\""; // e.g. Mythbusters - "The Pirate Special"
      tag->m_strShowTitle     = title;
      tag->m_strOriginalTitle = title;
      tag->m_strPlotOutline   = subtitle;
      tag->m_strPlot          = program[i].description;
      // TODO: Strip out the subtitle from the description if it is present at the start?
      // TODO: Do we need to add the subtitle to the start of the plot if not already as it used to? Seems strange, should be handled by skin?
      tag->m_genre            = StringUtils::Split(program[i].category, g_advancedSettings.m_videoItemSeparator); // e.g. Sports
      tag->m_strAlbum         = program[i].callsign; // e.g. TV3

      CDateTime start(program[i].starttime);
      CDateTime end(program[i].endtime);
      CDateTimeSpan runtime = end - start;
      tag->m_duration         = runtime.GetSeconds() + runtime.GetMinutes() * 60 + runtime.GetHours() * 3600;
      tag->m_iSeason          = 0; // So XBMC treats the content as an episode and displays tag information.
      tag->m_iEpisode         = 0;

      items.Add(item);
    }
  }

  /*
   * Items are sorted as added to the list (in ascending date order). Specifying sorting by date can
   * result in the guide being shown in the wrong order for skins that sort by date in descending
   * order by default with no option to change to ascending, e.g. Confluence.
   */
  items.AddSortMethod(SortByNone, 552 /* Date */, LABEL_MASKS("%K", "%J")); // Still leave the date label

  m_dll->ref_release(program);
  return true;
}
예제 #15
0
bool CCMythDirectory::GetChannels(const CStdString& base, CFileItemList &items)
{
  cmyth_conn_t control = m_session->GetControl();
  if(!control)
    return false;

  std::vector<cmyth_proginfo_t> channels;
  for(unsigned i=0;i<16;i++)
  {
    cmyth_recorder_t recorder = m_dll->conn_get_recorder_from_num(control, i);
    if(!recorder)
      continue;

    cmyth_proginfo_t program;
    program = m_dll->recorder_get_cur_proginfo(recorder);
    program = m_dll->recorder_get_next_proginfo(recorder, program, BROWSE_DIRECTION_UP);
    if(!program) {
      m_dll->ref_release(m_recorder);
      continue;
    }

    long startchan = m_dll->proginfo_chan_id(program);
    long currchan  = -1;
    while(startchan != currchan)
    {
      unsigned j;
      for(j=0;j<channels.size();j++)
      {
        if(m_dll->proginfo_compare(program, channels[j]) == 0)
          break;
      }

      if(j == channels.size())
        channels.push_back(program);

      program = m_dll->recorder_get_next_proginfo(recorder, program, BROWSE_DIRECTION_UP);
      if(!program)
        break;

      currchan = m_dll->proginfo_chan_id(program);
    }
    m_dll->ref_release(recorder);
  }

  CURL url(base);

  for(unsigned i=0;i<channels.size();i++)
  {
    cmyth_proginfo_t program = channels[i];
    CStdString num, progname, channame, icon, sign;

    num      = GetValue(m_dll->proginfo_chanstr (program));
    icon     = GetValue(m_dll->proginfo_chanicon(program));

    CFileItemPtr item(new CFileItem("", false));
    m_session->UpdateItem(*item, program);
    url.SetFileName("channels/" + num + ".ts");
    url.GetURL(item->m_strPath);
    item->SetLabel(GetValue(m_dll->proginfo_chansign(program)));

    if(icon.length() > 0)
    {
      url.SetFileName("files/channels/" + CUtil::GetFileName(icon));
      url.GetURL(icon);
      item->SetThumbnailImage(icon);
    }

    /* hack to get sorting working properly when sorting by show title */
    if(item->GetVideoInfoTag()->m_strShowTitle.IsEmpty())
      item->GetVideoInfoTag()->m_strShowTitle = " ";

    items.Add(item);
    m_dll->ref_release(program);
  }

  if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
    items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_THE, 551, LABEL_MASKS("%K[ - %B]", "%Z", "%L", ""));
  else
    items.AddSortMethod(SORT_METHOD_LABEL, 551, LABEL_MASKS("%K[ - %B]", "%Z", "%L", ""));

  if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
    items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_THE, 20364, LABEL_MASKS("%Z", "%B", "%L", ""));
  else
    items.AddSortMethod(SORT_METHOD_LABEL, 20364, LABEL_MASKS("%Z", "%B", "%L", ""));


  return true;
}
예제 #16
0
bool CCMythDirectory::GetGuideForChannel(const CStdString& base, CFileItemList &items, int channelNumber)
{
  cmyth_database_t database = m_session->GetDatabase();
  if (!database)
  {
    CLog::Log(LOGERROR, "%s - Could not get database", __FUNCTION__);
    return false;
  }

  time_t now;
  time(&now);
  // this sets how many seconds of EPG from now we should grab
  time_t end = now + (1 * 24 * 60 * 60);

  cmyth_program_t *program = NULL;

  int count = m_dll->mysql_get_guide(database, &program, now, end);
  CLog::Log(LOGDEBUG, "%s - %i entries of guide data", __FUNCTION__, count);
  if (count <= 0)
    return false;

  for (int i = 0; i < count; i++)
  {
    if (program[i].channum == channelNumber)
    {
      CStdString path;
      path.Format("%s%s", base.c_str(), program[i].title);

      CDateTime starttime(program[i].starttime);
      CDateTime endtime(program[i].endtime);

      CStdString title;
      title.Format("%s - %s", starttime.GetAsLocalizedTime("HH:mm", false), program[i].title);

      CFileItemPtr item(new CFileItem(title, false));
      item->SetLabel(title);
      item->m_dateTime = starttime;

      CVideoInfoTag* tag = item->GetVideoInfoTag();

      tag->m_strAlbum       = GetValue(program[i].callsign);
      tag->m_strShowTitle   = GetValue(program[i].title);
      tag->m_strPlotOutline = GetValue(program[i].subtitle);
      tag->m_strPlot        = GetValue(program[i].description);
      tag->m_strGenre       = GetValue(program[i].category);

      if(tag->m_strPlot.Left(tag->m_strPlotOutline.length()) != tag->m_strPlotOutline && !tag->m_strPlotOutline.IsEmpty())
          tag->m_strPlot = tag->m_strPlotOutline + '\n' + tag->m_strPlot;
      tag->m_strOriginalTitle = tag->m_strShowTitle;

      tag->m_strTitle = tag->m_strAlbum;
      if(tag->m_strShowTitle.length() > 0)
        tag->m_strTitle += " : " + tag->m_strShowTitle;

      CDateTimeSpan runtime = endtime - starttime;
      StringUtils::SecondsToTimeString( runtime.GetSeconds()
                                      + runtime.GetMinutes() * 60
                                      + runtime.GetHours() * 3600, tag->m_strRuntime);

      tag->m_iSeason  = 0; /* set this so xbmc knows it's a tv show */
      tag->m_iEpisode = 0;
      tag->m_strStatus = program[i].rec_status;
      items.Add(item);
    }
  }

  // Sort by date only.
  items.AddSortMethod(SORT_METHOD_DATE, 552 /* Date */, LABEL_MASKS("%L", "%J", "%L", ""));

  m_dll->ref_release(program);
  return true;
}
예제 #17
0
bool CRSSDirectory::GetDirectory(const CURL& url, CFileItemList &items)
{
  const std::string pathToUrl(url.Get());
  std::string strPath(pathToUrl);
  URIUtils::RemoveSlashAtEnd(strPath);
  std::map<std::string,CDateTime>::iterator it;
  items.SetPath(strPath);
  CSingleLock lock(m_section);
  if ((it=m_cache.find(strPath)) != m_cache.end())
  {
    if (it->second > CDateTime::GetCurrentDateTime() && 
        items.Load())
      return true;
    m_cache.erase(it);
  }
  lock.Leave();

  CXBMCTinyXML xmlDoc;
  if (!xmlDoc.LoadFile(strPath))
  {
    CLog::Log(LOGERROR,"failed to load xml from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId());
    return false;
  }
  if (xmlDoc.Error())
  {
    CLog::Log(LOGERROR,"error parsing xml doc from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId());
    return false;
  }

  TiXmlElement* rssXmlNode = xmlDoc.RootElement();

  if (!rssXmlNode)
    return false;

  TiXmlHandle docHandle( &xmlDoc );
  TiXmlElement* channelXmlNode = docHandle.FirstChild( "rss" ).FirstChild( "channel" ).Element();
  if (channelXmlNode)
    ParseItem(&items, channelXmlNode, pathToUrl);
  else
    return false;

  TiXmlElement* child = NULL;
  for (child = channelXmlNode->FirstChildElement("item"); child; child = child->NextSiblingElement())
  {
    // Create new item,
    CFileItemPtr item(new CFileItem());
    ParseItem(item.get(), child, pathToUrl);

    item->SetProperty("isrss", "1");
    // Use channel image if item doesn't have one
    if (!item->HasArt("thumb") && items.HasArt("thumb"))
      item->SetArt("thumb", items.GetArt("thumb"));

    if (!item->GetPath().empty())
      items.Add(item);
  }

  items.AddSortMethod(SortByNone   , 231, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SortByLabel  , 551, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SortBySize   , 553, LABEL_MASKS("%L", "%I", "%L", "%I"));  // FileName, Size | Foldername, Size
  items.AddSortMethod(SortByDate   , 552, LABEL_MASKS("%L", "%J", "%L", "%J"));  // FileName, Date | Foldername, Date

  CDateTime time = CDateTime::GetCurrentDateTime();
  int mins = 60;
  TiXmlElement* ttl = docHandle.FirstChild("rss").FirstChild("ttl").Element();
  if (ttl)
    mins = strtol(ttl->FirstChild()->Value(),NULL,10);
  time += CDateTimeSpan(0,0,mins,0);
  items.SetPath(strPath);
  items.Save();
  CSingleLock lock2(m_section);
  m_cache.insert(make_pair(strPath,time));

  return true;
}
예제 #18
0
bool CPlexDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  CStdString strRoot = strPath;
  if (CUtil::HasSlashAtEnd(strRoot) && strRoot != "plex://")
    strRoot.Delete(strRoot.size() - 1);
  
  strRoot.Replace(" ", "%20");

  // Start the download thread running.
  printf("PlexDirectory::GetDirectory(%s)\n", strRoot.c_str());
  m_url = strRoot;
  CThread::Create(false, 0);

  // Now display progress, look for cancel.
  CGUIDialogProgress* dlgProgress = 0;
  
  int time = GetTickCount();
  
  while (m_downloadEvent.WaitMSec(100) == false)
  {
    // If enough time has passed, display the dialog.
    if (GetTickCount() - time > 1000 && m_allowPrompting == true)
    {
      dlgProgress = (CGUIDialogProgress*)m_gWindowManager.GetWindow(WINDOW_DIALOG_PROGRESS);
      if (dlgProgress)
      {
        dlgProgress->ShowProgressBar(false);
        dlgProgress->SetHeading(40203);
        dlgProgress->SetLine(0, 40204);
        dlgProgress->SetLine(1, "");
        dlgProgress->SetLine(2, "");
        dlgProgress->StartModal();
      }
    }

    if (dlgProgress)
    {
      dlgProgress->Progress();
      if (dlgProgress->IsCanceled())
      {
        items.m_wasListingCancelled = true;
        m_http.Cancel();
        StopThread();
      }
    }
  }
  
  if (dlgProgress) 
    dlgProgress->Close();
  
  // Wait for the thread to exit.
  WaitForThreadExit(INFINITE);
  
  // See if we suceeded.
  if (m_bSuccess == false)
    return false;
  
  // See if we're supposed to parse the results or not.
  if (m_bParseResults == false)
    return true;
  
  // Parse returned xml.
  TiXmlDocument doc;
  doc.Parse(m_data.c_str());

  TiXmlElement* root = doc.RootElement();
  if (root == 0)
  {
    CLog::Log(LOGERROR, "%s - Unable to parse XML\n%s", __FUNCTION__, m_data.c_str());
    return false;
  }
  
  // Get the fanart.
  const char* fanart = root->Attribute("art");
  string strFanart;
  if (fanart && strlen(fanart) > 0)
    strFanart = ProcessUrl(strPath, fanart, false);

  // Walk the parsed tree.
  string strFileLabel = "%N - %T"; 
  string strDirLabel = "%B";
  string strSecondDirLabel = "%Y";
  
  Parse(m_url, root, items, strFileLabel, strDirLabel, strSecondDirLabel);
  
  // Set the window titles
  const char* title1 = root->Attribute("title1");
  const char* title2 = root->Attribute("title2");

  if (title1 && strlen(title1) > 0)
    items.SetFirstTitle(title1);
  if (title2 && strlen(title2) > 0)
    items.SetSecondTitle(title2);

  // Set fanart on items if they don't have their own.
  for (int i=0; i<items.Size(); i++)
  {
    CFileItemPtr pItem = items[i];
    
    if (strFanart.size() > 0 && pItem->GetQuickFanart().size() == 0)
      pItem->SetQuickFanart(strFanart);
      
    // Make sure sort label is lower case.
    string sortLabel = pItem->GetLabel();
    boost::to_lower(sortLabel);
    pItem->SetSortLabel(sortLabel);
  }
  
  // Set fanart on directory.
  if (strFanart.size() > 0)
    items.SetQuickFanart(strFanart);
    
  // Set the view mode.
  const char* viewmode = root->Attribute("viewmode");
  if (viewmode && strlen(viewmode) > 0)
  {
    CGUIViewState* viewState = CGUIViewState::GetViewState(0, items);
    viewState->SaveViewAsControl(atoi(viewmode));
  }
  
  // Override labels.
  const char* fileLabel = root->Attribute("filelabel");
  if (fileLabel && strlen(fileLabel) > 0)
    strFileLabel = fileLabel;

  const char* dirLabel = root->Attribute("dirlabel");
  if (dirLabel && strlen(dirLabel) > 0)
    strDirLabel = dirLabel;

  // Add the sort method.
  items.AddSortMethod(SORT_METHOD_NONE, 552, LABEL_MASKS(strFileLabel, "%D", strDirLabel, strSecondDirLabel));
  
  // Set the content label.
  const char* content = root->Attribute("content");
  if (content && strlen(content) > 0)
  {
    items.SetContent(content);
  }
  
  // Check for dialog message attributes
  CStdString strMessage = "";
  const char* header = root->Attribute("header");
  if (header && strlen(header) > 0)
  {
    const char* message = root->Attribute("message");
    if (message && strlen(message) > 0) 
      strMessage = message;
    
    items.m_displayMessage = true; 
    items.m_displayMessageTitle = header; 
    items.m_displayMessageContents = root->Attribute("message");
    
    // Don't cache these.
    m_dirCacheType = DIR_CACHE_NEVER;
  }
  
  // See if this directory replaces the parent.
  const char* replace = root->Attribute("replaceParent");
  if (replace && strcmp(replace, "1") == 0)
    items.SetReplaceListing(true);
  
  // See if we're saving this into the history or not.
  const char* noHistory = root->Attribute("noHistory");
    if (noHistory && strcmp(noHistory, "1") == 0)
      items.SetSaveInHistory(false);
  
  // See if we're not supposed to cache this directory.
  const char* noCache = root->Attribute("nocache");
  if (noCache && strcmp(noCache, "1") == 0)
    m_dirCacheType = DIR_CACHE_NEVER;
    
  return true;
}
예제 #19
0
bool CCMythDirectory::GetGuide(const CStdString& base, CFileItemList &items)
{
    cmyth_database_t db = m_session->GetDatabase();
    if(!db)
      return false;

    cmyth_chanlist_t list = m_dll->mysql_get_chanlist(db);
    if(!list)
    {
      CLog::Log(LOGERROR, "%s - unable to get list of channels with url %s", __FUNCTION__, base.c_str());
      return false;
    }
    CURI url(base);

    int count = m_dll->chanlist_get_count(list);
    for(int i = 0; i < count; i++)
    {
      cmyth_channel_t channel = m_dll->chanlist_get_item(list, i);
      if(channel)
      {
        CStdString name, path, icon;

        if(!m_dll->channel_visible(channel))
        {
          m_dll->ref_release(channel);
          continue;
        }
        int num = m_dll->channel_channum(channel);
        char* str;
        if((str = m_dll->channel_name(channel)))
        {
          name.Format("%d - %s", num, str); 
          m_dll->ref_release(str);
        }
        else
          name.Format("%d");

        icon = GetValue(m_dll->channel_icon(channel));

        if(num <= 0)
        {
          CLog::Log(LOGDEBUG, "%s - Channel '%s' Icon '%s' - Skipped", __FUNCTION__, name.c_str(), icon.c_str());
        }
        else
        {
          CLog::Log(LOGDEBUG, "%s - Channel '%s' Icon '%s'", __FUNCTION__, name.c_str(), icon.c_str());
          path.Format("guide/%d/", num);
          url.SetFileName(path);
          path = url.Get();
          CFileItemPtr item(new CFileItem(path, true));
          item->SetLabel(name);
          item->SetLabelPreformated(true);
          if(icon.length() > 0)
          {
            url.SetFileName("files/channels/" + CUtil::GetFileName(icon));
            icon = url.Get();
            item->SetThumbnailImage(icon);
          }
          items.Add(item);
        }
        m_dll->ref_release(channel);
      }
    }

  // Sort by name only. Labels are preformated.
  items.AddSortMethod(SORT_METHOD_LABEL, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));
  
    m_dll->ref_release(list);
    return true;
  }
예제 #20
0
bool CCMythDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
  m_session = CCMythSession::AquireSession(strPath);
  if(!m_session)
    return false;

  m_dll = m_session->GetLibrary();
  if(!m_dll)
    return false;

  CStdString base(strPath);
  CUtil::RemoveSlashAtEnd(base);

  CURI url(strPath);
  CStdString fileName = url.GetFileName();
  CUtil::RemoveSlashAtEnd(fileName);

  if (fileName == "")
  {
    CFileItemPtr item;

    item.reset(new CFileItem(base + "/channels/", true));
    item->SetLabel(g_localizeStrings.Get(22018)); // Live channels
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/guide/", true));
    item->SetLabel(g_localizeStrings.Get(22020)); // Guide
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/movies/", true));
    item->SetLabel(g_localizeStrings.Get(20342)); // Movies
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/recordings/", true));
    item->SetLabel(g_localizeStrings.Get(22015)); // All recordings
    item->SetLabelPreformated(true);
    items.Add(item);

    item.reset(new CFileItem(base + "/tvshows/", true));
    item->SetLabel(g_localizeStrings.Get(20343)); // TV shows
    item->SetLabelPreformated(true);
    items.Add(item);

    // Sort by name only. Labels are preformated.
    items.AddSortMethod(SORT_METHOD_LABEL, 551 /* Name */, LABEL_MASKS("%L", "", "%L", ""));

    return true;
  }
  else if (fileName == "channels")
    return GetChannels(base, items);
  else if (fileName == "guide")
    return GetGuide(base, items);
  else if (fileName.Left(6) == "guide/")
    return GetGuideForChannel(base, items, atoi(fileName.Mid(6)));
  else if (fileName == "movies")
    return GetRecordings(base, items, MOVIES);
  else if (fileName == "recordings")
    return GetRecordings(base, items);
  else if (fileName == "tvshows")
    return GetTvShowFolders(base, items);
  else if (fileName.Left(8) == "tvshows/")
    return GetRecordings(base, items, TV_SHOWS, fileName.Mid(8));
  return false;
}
bool CRSSDirectory::GetDirectory(const CStdString& path, CFileItemList &items)
{
  CStdString strPath(path);
  CUtil::RemoveSlashAtEnd(strPath);

  /* check cache */
  if(m_path == strPath)
  {
    items.Copy(m_items);
    return true;
  }

  /* clear cache */
  m_items.Clear();
  m_path == "";

  TiXmlDocument xmlDoc;
  if (!xmlDoc.LoadFile(strPath))
  {
    CLog::Log(LOGERROR,"failed to load xml from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId());
    return false;
  }
  if (xmlDoc.Error())
  {
    CLog::Log(LOGERROR,"error parsing xml doc from <%s>. error: <%d>", strPath.c_str(), xmlDoc.ErrorId());
    return false;
  }

  TiXmlElement* rssXmlNode = xmlDoc.RootElement();

  if (!rssXmlNode)
    return false;

  TiXmlHandle docHandle( &xmlDoc );
  TiXmlElement* channelXmlNode = docHandle.FirstChild( "rss" ).FirstChild( "channel" ).Element();
  if (channelXmlNode)
    ParseItem(&items, channelXmlNode);
  else
    return false;

  TiXmlElement* child = NULL;
  for (child = channelXmlNode->FirstChildElement("item"); child; child = child->NextSiblingElement())
  {
    // Create new item,
    CFileItemPtr item(new CFileItem());
    ParseItem(item.get(), child);

    item->SetProperty("isrss", "1");

    if (!item->m_strPath.IsEmpty())
      items.Add(item);
  }

  items.AddSortMethod(SORT_METHOD_UNSORTED , 231, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SORT_METHOD_LABEL    , 551, LABEL_MASKS("%L", "%D", "%L", ""));    // FileName, Duration | Foldername, empty
  items.AddSortMethod(SORT_METHOD_SIZE     , 553, LABEL_MASKS("%L", "%I", "%L", "%I"));  // FileName, Size | Foldername, Size
  items.AddSortMethod(SORT_METHOD_DATE     , 552, LABEL_MASKS("%L", "%J", "%L", "%J"));  // FileName, Date | Foldername, Date

  m_items.Copy(items);
  m_path  = strPath;

  return true;
}
예제 #22
0
bool CCMythDirectory::GetRecordings(const CStdString& base, CFileItemList &items)
{
  cmyth_conn_t control = m_session->GetControl();
  if(!control)
    return false;

  CURL url(base);

  cmyth_proglist_t list = m_dll->proglist_get_all_recorded(control);
  if(!list)
  {
    CLog::Log(LOGERROR, "%s - unable to get list of recordings", __FUNCTION__);
    return false;
  }
  int count = m_dll->proglist_get_count(list);
  for(int i=0; i<count; i++)
  {
    cmyth_proginfo_t program = m_dll->proglist_get_item(list, i);
    if(program)
    {
      if(GetValue(m_dll->proginfo_recgroup(program)).Equals("LiveTV"))
      {
        m_dll->ref_release(program);
        continue;
      }

      CStdString name, path;

      path = GetValue(m_dll->proginfo_pathname(program));
      path = CUtil::GetFileName(path);
      name = GetValue(m_dll->proginfo_title(program));

      CFileItemPtr item(new CFileItem("", false));
      m_session->UpdateItem(*item, program);

      url.SetFileName("recordings/" + path);
      url.GetURL(item->m_strPath);

      url.SetFileName("files/" + path +  ".png");
      url.GetURL(path);
      item->SetThumbnailImage(path);

      if(m_dll->proginfo_rec_status(program) != RS_RECORDING)
        name += " (" + item->m_dateTime.GetAsLocalizedDateTime() + ")";
      else
      {
        name += " (Recording)";
        item->SetThumbnailImage("");
      }

      item->SetLabel(name);

      items.Add(item);
      m_dll->ref_release(program);
    }

    if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
      items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_THE, 551, LABEL_MASKS("%Z (%J)", "%I", "%L", ""));
    else
      items.AddSortMethod(SORT_METHOD_LABEL, 551, LABEL_MASKS("%Z (%J)", "%I", "%L", ""));
    items.AddSortMethod(SORT_METHOD_SIZE, 553, LABEL_MASKS("%Z (%J)", "%I", "%L", "%I"));
    items.AddSortMethod(SORT_METHOD_DATE, 552, LABEL_MASKS("%Z", "%J %Q", "%L", "%J"));

  }
  m_dll->ref_release(list);
  return true;
}
예제 #23
0
/*----------------------------------------------------------------------
|   CUPnPDirectory::GetDirectory
+---------------------------------------------------------------------*/
bool
CUPnPDirectory::GetDirectory(const CStdString& strPath, CFileItemList &items)
{
    CUPnP* upnp = CUPnP::GetInstance();

    /* upnp should never be cached, it has internal cache */
    items.SetCacheToDisc(CFileItemList::CACHE_NEVER);

    // We accept upnp://devuuid/[item_id/]
    NPT_String path = strPath.c_str();
    if (!path.StartsWith("upnp://", true)) {
        return false;
    }

    if (path.Compare("upnp://", true) == 0) {
        upnp->StartClient();

        // root -> get list of devices
        const NPT_Lock<PLT_DeviceDataReferenceList>& devices = upnp->m_MediaBrowser->GetMediaServers();
        NPT_List<PLT_DeviceDataReference>::Iterator device = devices.GetFirstItem();
        while (device) {
            NPT_String name = (*device)->GetFriendlyName();
            NPT_String uuid = (*device)->GetUUID();

            CFileItemPtr pItem(new CFileItem((const char*)name));
            pItem->SetPath(CStdString((const char*) "upnp://" + uuid + "/"));
            pItem->m_bIsFolder = true;
            pItem->SetArt("thumb", (const char*)(*device)->GetIconUrl("image/png"));

            items.Add(pItem);

            ++device;
        }
    } else {
        if (!path.EndsWith("/")) path += "/";

        // look for nextslash
        int next_slash = path.Find('/', 7);

        NPT_String uuid = (next_slash==-1)?path.SubString(7):path.SubString(7, next_slash-7);
        NPT_String object_id = (next_slash==-1)?"":path.SubString(next_slash+1);
        object_id.TrimRight("/");
        if (object_id.GetLength()) {
            CStdString tmp = (char*) object_id;
            CURL::Decode(tmp);
            object_id = tmp;
        }

        // try to find the device with wait on startup
        PLT_DeviceDataReference device;
        if (!FindDeviceWait(upnp, uuid, device))
            goto failure;

        // issue a browse request with object_id
        // if object_id is empty use "0" for root
        object_id = object_id.IsEmpty()?"0":object_id;

        // remember a count of object classes
        std::map<NPT_String, int> classes;

        // just a guess as to what types of files we want
        bool video = true;
        bool audio = true;
        bool image = true;
        m_strFileMask.TrimLeft("/");
        if (!m_strFileMask.IsEmpty()) {
            video = m_strFileMask.Find(".wmv") >= 0;
            audio = m_strFileMask.Find(".wma") >= 0;
            image = m_strFileMask.Find(".jpg") >= 0;
        }

        // special case for Windows Media Connect and WMP11 when looking for root
        // We can target which root subfolder we want based on directory mask
        if (object_id == "0" && ((device->GetFriendlyName().Find("Windows Media Connect", 0, true) >= 0) ||
                                 (device->m_ModelName == "Windows Media Player Sharing"))) {

            // look for a specific type to differentiate which folder we want
            if (audio && !video && !image) {
                // music
                object_id = "1";
            } else if (!audio && video && !image) {
                // video
                object_id = "2";
            } else if (!audio && !video && image) {
                // pictures
                object_id = "3";
            }
        }

#ifdef DISABLE_SPECIALCASE
        // same thing but special case for XBMC
        if (object_id == "0" && ((device->m_ModelName.Find("XBMC", 0, true) >= 0) ||
                                 (device->m_ModelName.Find("Xbox Media Center", 0, true) >= 0))) {
            // look for a specific type to differentiate which folder we want
            if (audio && !video && !image) {
                // music
                object_id = "virtualpath://upnpmusic";
            } else if (!audio && video && !image) {
                // video
                object_id = "virtualpath://upnpvideo";
            } else if (!audio && !video && image) {
                // pictures
                object_id = "virtualpath://upnppictures";
            }
        }
#endif

        // if error, return now, the device could have gone away
        // this will make us go back to the sources list
        PLT_MediaObjectListReference list;
        NPT_Result res = upnp->m_MediaBrowser->BrowseSync(device, object_id, list);
        if (NPT_FAILED(res)) goto failure;

        // empty list is ok
        if (list.IsNull()) goto cleanup;

        PLT_MediaObjectList::Iterator entry = list->GetFirstItem();
        while (entry) {
            // disregard items with wrong class/type
            if( (!video && (*entry)->m_ObjectClass.type.CompareN("object.item.videoitem", 21,true) == 0)
             || (!audio && (*entry)->m_ObjectClass.type.CompareN("object.item.audioitem", 21,true) == 0)
             || (!image && (*entry)->m_ObjectClass.type.CompareN("object.item.imageitem", 21,true) == 0) )
            {
                ++entry;
                continue;
            }

            // never show empty containers in media views
            if((*entry)->IsContainer()) {
                if( (audio || video || image)
                 && ((PLT_MediaContainer*)(*entry))->m_ChildrenCount == 0) {
                    ++entry;
                    continue;
                }
            }


            // keep count of classes
            classes[(*entry)->m_ObjectClass.type]++;
            CFileItemPtr pItem = BuildObject(*entry);
            if(!pItem) {
                ++entry;
                continue;
            }

            CStdString id = (char*) (*entry)->m_ObjectID;
            CURL::Encode(id);
            URIUtils::AddSlashAtEnd(id);
            pItem->SetPath(CStdString((const char*) "upnp://" + uuid + "/" + id.c_str()));

            items.Add(pItem);

            ++entry;
        }

        NPT_String max_string = "";
        int        max_count  = 0;
        for(std::map<NPT_String, int>::iterator it = classes.begin(); it != classes.end(); it++)
        {
          if(it->second > max_count)
          {
            max_string = it->first;
            max_count  = it->second;
          }
        }
        std::string content = GetContentMapping(max_string);
        items.SetContent(content);
        if (content == "unknown")
        {
          items.AddSortMethod(SORT_METHOD_UNSORTED, 571, LABEL_MASKS("%L", "%I", "%L", ""));
          items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_FOLDERS, 551, LABEL_MASKS("%L", "%I", "%L", ""));
          items.AddSortMethod(SORT_METHOD_SIZE, 553, LABEL_MASKS("%L", "%I", "%L", "%I"));
          items.AddSortMethod(SORT_METHOD_DATE, 552, LABEL_MASKS("%L", "%J", "%L", "%J"));
        }
    }

cleanup:
    return true;

failure:
    return false;
}
예제 #24
0
bool CCMythDirectory::GetRecordings(const CStdString& base, CFileItemList &items, enum FilterType type,
                                    const CStdString& filter)
{
  cmyth_conn_t control = m_session->GetControl();
  if(!control)
    return false;

  cmyth_proglist_t list = m_dll->proglist_get_all_recorded(control);
  if(!list)
  {
    CLog::Log(LOGERROR, "%s - unable to get list of recordings", __FUNCTION__);
    return false;
  }

  int count = m_dll->proglist_get_count(list);
  for(int i=0; i<count; i++)
  {
    cmyth_proginfo_t program = m_dll->proglist_get_item(list, i);
    if(program)
    {
      if(GetValue(m_dll->proginfo_recgroup(program)).Equals("LiveTV"))
      {
        m_dll->ref_release(program);
        continue;
      }

      CURI url(base);
      /*
       * The base is the URL used to connect to the master server. The hostname in this may not
       * appropriate for all items as MythTV supports multiple backends (master + slaves).
       *
       * The appropriate host for playback is contained in the program information sent back from
       * the master. The same username and password are used in the URL as for the master.
       */
      url.SetHostName(GetValue(m_dll->proginfo_host(program)));

      CStdString path = CUtil::GetFileName(GetValue(m_dll->proginfo_pathname(program)));
      CStdString name = GetValue(m_dll->proginfo_title(program));
      
      switch (type)
      {
        case MOVIES:
        if (!IsMovie(program))
        {
          m_dll->ref_release(program);
          continue;
        }
        url.SetFileName("movies/" + path);
        break;
        case TV_SHOWS:
        if (filter != name)
      {
          m_dll->ref_release(program);
          continue;
        }
        url.SetFileName("tvshows/" + path);
        break;
        case ALL:
        url.SetFileName("recordings/" + path);
        break;
      }

      CFileItemPtr item(new CFileItem("", false));
      m_session->UpdateItem(*item, program);
      item->m_strPath = url.Get();

      url.SetFileName("files/" + path +  ".png");
      path = url.Get();
      item->SetThumbnailImage(path);

      /*
       * Don't adjust the name for MOVIES as additional information in the name will affect any scraper lookup.
       */
      if (type != MOVIES)
      {
        if (m_dll->proginfo_rec_status(program) == RS_RECORDING)
        {
        name += " (Recording)";
        item->SetThumbnailImage("");
      }
        else
          name += " (" + item->m_dateTime.GetAsLocalizedDateTime() + ")";
      }

      item->SetLabel(name);
      /*
       * Set the label as preformated for MOVIES so any scraper lookup will use
       * the label rather than the filename. Don't set as preformated for other
       * filter types as this prevents the display of the title changing 
       * depending on what the list is being sorted by.
       */
      if (type == MOVIES)
        item->SetLabelPreformated(true);

      items.Add(item);
      m_dll->ref_release(program);
    }
  }

    if (g_guiSettings.GetBool("filelists.ignorethewhensorting"))
      items.AddSortMethod(SORT_METHOD_LABEL_IGNORE_THE, 551 /* Name */, LABEL_MASKS("%Z (%J)", "%Q", "%L", ""));
    else
      items.AddSortMethod(SORT_METHOD_LABEL, 551 /* Name */, LABEL_MASKS("%Z (%J)", "%Q", "%L", ""));
    items.AddSortMethod(SORT_METHOD_DATE, 552 /* Date */, LABEL_MASKS("%Z", "%J", "%L", "%J"));

  m_dll->ref_release(list);
  return true;
}