/** * \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; }
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; }
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(); }
/** * \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; }
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; }
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; }
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(); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/*---------------------------------------------------------------------- | 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; }
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; }