DTC::ChannelInfoList* Channel::GetChannelInfoList( uint nSourceID, uint nStartIndex, uint nCount, bool bOnlyVisible, bool bDetails ) { ChannelInfoList chanList; uint nTotalAvailable = 0; chanList = ChannelUtil::LoadChannels( 0, 0, nTotalAvailable, bOnlyVisible, ChannelUtil::kChanOrderByChanNum, ChannelUtil::kChanGroupByChanid, nSourceID ); //, nChanGroupID // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ChannelInfoList *pChannelInfos = new DTC::ChannelInfoList(); //uint nTotalAvailable = static_cast<uint>(chanList.size()); nStartIndex = (nStartIndex > 0) ? min( nStartIndex, nTotalAvailable ) : 0; nCount = (nCount > 0) ? min( nCount, nTotalAvailable ) : nTotalAvailable; int nEndIndex = min((nStartIndex + nCount), nTotalAvailable ); ChannelInfoList::iterator chanIt; for( chanIt = chanList.begin(); chanIt != chanList.end(); ++chanIt) { DTC::ChannelInfo *pChannelInfo = pChannelInfos->AddNewChannelInfo(); ChannelInfo channelInfo = (*chanIt); if (!FillChannelInfo(pChannelInfo, channelInfo, bDetails)) throw( QString("Channel ID appears invalid.")); } int nCurPage = 0, nTotalPages = 0; if (nCount == 0) nTotalPages = 1; else nTotalPages = (int)ceil((float)nTotalAvailable / nCount); if (nTotalPages == 1) nCurPage = 1; else { nCurPage = (int)ceil((float)nStartIndex / nCount) + 1; } pChannelInfos->setStartIndex ( nStartIndex ); pChannelInfos->setCount ( nCount ); pChannelInfos->setCurrentPage ( nCurPage ); pChannelInfos->setTotalPages ( nTotalPages ); pChannelInfos->setTotalAvailable( nTotalAvailable ); pChannelInfos->setAsOf ( MythDate::current() ); pChannelInfos->setVersion ( MYTH_BINARY_VERSION ); pChannelInfos->setProtoVer ( MYTH_PROTO_VERSION ); return pChannelInfos; }
DTC::ChannelInfo* Channel::GetChannelInfo( uint nChanID ) { if (nChanID <= 0) throw( QString("Channel ID appears invalid.")); DTC::ChannelInfo *pChannelInfo = new DTC::ChannelInfo(); if (!FillChannelInfo(pChannelInfo, nChanID, true)) throw( QString("Channel ID appears invalid.")); return pChannelInfo; }
bool FillChannelInfo( DTC::ChannelInfo *pChannel, uint nChanID, bool bDetails /* = true */ ) { ChannelInfo channel; if (channel.Load(nChanID)) { return FillChannelInfo(pChannel, channel, bDetails); } return false; }
DTC::ChannelInfoList* Channel::GetChannelInfoList( uint nSourceID, uint nStartIndex, uint nCount ) { vector<uint> chanList; chanList = ChannelUtil::GetChanIDs(nSourceID); // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ChannelInfoList *pChannelInfos = new DTC::ChannelInfoList(); nStartIndex = min( nStartIndex, (uint)chanList.size() ); nCount = (nCount > 0) ? min( nCount, (uint)chanList.size() ) : chanList.size(); int nEndIndex = min((nStartIndex + nCount), (uint)chanList.size() ); for( int n = nStartIndex; n < nEndIndex; n++) { DTC::ChannelInfo *pChannelInfo = pChannelInfos->AddNewChannelInfo(); uint chanid = chanList.at(n); if (!FillChannelInfo(pChannelInfo, chanid, true)) throw( QString("Channel ID appears invalid.")); } int curPage = 0, totalPages = 0; if (nCount == 0) totalPages = 1; else totalPages = (int)ceil((float)chanList.size() / nCount); if (totalPages == 1) curPage = 1; else { curPage = (int)ceil((float)nStartIndex / nCount) + 1; } pChannelInfos->setStartIndex ( nStartIndex ); pChannelInfos->setCount ( nCount ); pChannelInfos->setCurrentPage ( curPage ); pChannelInfos->setTotalPages ( totalPages ); pChannelInfos->setTotalAvailable( chanList.size() ); pChannelInfos->setAsOf ( MythDate::current() ); pChannelInfos->setVersion ( MYTH_BINARY_VERSION ); pChannelInfos->setProtoVer ( MYTH_PROTO_VERSION ); return pChannelInfos; }
DTC::ChannelInfo* Channel::GetChannelInfo( uint nChanID ) { if (nChanID <= 0) throw( QString("Channel ID appears invalid.")); DTC::ChannelInfo *pChannelInfo = new DTC::ChannelInfo(); if (!FillChannelInfo(pChannelInfo, nChanID, true)) { // throw causes a crash on linux and we can't know in advance // that a channel id from an old recording rule is invalid //throw( QString("Channel ID appears invalid.")); } return pChannelInfo; }
DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &dtStartTime , const QDateTime &dtEndTime , int nStartChanId, int nNumChannels, bool bDetails ) { if (!dtStartTime.isValid()) throw( "StartTime is invalid" ); if (!dtEndTime.isValid()) throw( "EndTime is invalid" ); if (dtEndTime < dtStartTime) throw( "EndTime is before StartTime"); if (nNumChannels == 0) nNumChannels = 1; if (nNumChannels == -1) nNumChannels = SHRT_MAX; // ---------------------------------------------------------------------- // Find the ending channel Id // ---------------------------------------------------------------------- int nEndChanId = nStartChanId; MSqlQuery query(MSqlQuery::InitCon()); query.prepare( "SELECT chanid FROM channel WHERE (chanid >= :STARTCHANID )" " ORDER BY chanid LIMIT :NUMCHAN" ); query.bindValue(":STARTCHANID", nStartChanId ); query.bindValue(":NUMCHAN" , nNumChannels ); if (!query.exec()) MythDB::DBError("Select ChanId", query); query.first(); nStartChanId = query.value(0).toInt(); query.last(); nEndChanId = query.value(0).toInt(); // ---------------------------------------------------------------------- // Build SQL statement for Program Listing // ---------------------------------------------------------------------- ProgramList progList; ProgramList schedList; MSqlBindings bindings; QString sSQL = "WHERE program.chanid >= :StartChanId " "AND program.chanid <= :EndChanId " "AND program.endtime >= :StartDate " "AND program.starttime <= :EndDate " "GROUP BY program.starttime, channel.channum, " "channel.callsign, program.title " "ORDER BY program.chanid "; bindings[":StartChanId"] = nStartChanId; bindings[":EndChanId" ] = nEndChanId; bindings[":StartDate" ] = dtStartTime; bindings[":EndDate" ] = dtEndTime; // ---------------------------------------------------------------------- // Get all Pending Scheduled Programs // ---------------------------------------------------------------------- bool hasConflicts; LoadFromScheduler(schedList, hasConflicts); // ---------------------------------------------------------------------- LoadFromProgram( progList, sSQL, bindings, schedList, false ); // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ProgramGuide *pGuide = new DTC::ProgramGuide(); int nChanCount = 0; uint nCurChanId = 0; DTC::ChannelInfo *pChannel = NULL; for( uint n = 0; n < progList.size(); n++) { ProgramInfo *pInfo = progList[ n ]; if ( nCurChanId != pInfo->GetChanID() ) { nChanCount++; nCurChanId = pInfo->GetChanID(); pChannel = pGuide->AddNewChannel(); FillChannelInfo( pChannel, pInfo, bDetails ); } DTC::Program *pProgram = pChannel->AddNewProgram(); FillProgramInfo( pProgram, pInfo, false, bDetails ); } // ---------------------------------------------------------------------- pGuide->setStartTime ( dtStartTime ); pGuide->setEndTime ( dtEndTime ); pGuide->setStartChanId ( nStartChanId ); pGuide->setEndChanId ( nEndChanId ); pGuide->setNumOfChannels( nChanCount ); pGuide->setDetails ( bDetails ); pGuide->setCount ( progList.size()); pGuide->setAsOf ( QDateTime::currentDateTime() ); pGuide->setVersion ( MYTH_BINARY_VERSION ); pGuide->setProtoVer ( MYTH_PROTO_VERSION ); return pGuide; }
DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &rawStartTime , const QDateTime &rawEndTime , int nStartChanId, int nNumChannels, bool bDetails, int nChannelGroupId ) { if (!rawStartTime.isValid()) throw( "StartTime is invalid" ); if (!rawEndTime.isValid()) throw( "EndTime is invalid" ); QDateTime dtStartTime = rawStartTime.toUTC(); QDateTime dtEndTime = rawEndTime.toUTC(); if (dtEndTime < dtStartTime) throw( "EndTime is before StartTime"); if (nNumChannels == 0) nNumChannels = SHRT_MAX; // ---------------------------------------------------------------------- // Find the ending channel Id // ---------------------------------------------------------------------- int nEndChanId = nStartChanId; MSqlQuery query(MSqlQuery::InitCon()); query.prepare( "SELECT chanid FROM channel WHERE (chanid >= :STARTCHANID )" " ORDER BY chanid LIMIT :NUMCHAN" ); query.bindValue(":STARTCHANID", nStartChanId ); query.bindValue(":NUMCHAN" , nNumChannels ); if (!query.exec()) MythDB::DBError("Select ChanId", query); query.first(); nStartChanId = query.value(0).toInt(); query.last(); nEndChanId = query.value(0).toInt(); // ---------------------------------------------------------------------- // Build SQL statement for Program Listing // ---------------------------------------------------------------------- ProgramList progList; ProgramList schedList; MSqlBindings bindings; // lpad is to allow natural sorting of numbers QString sSQL; if (nChannelGroupId > 0) { sSQL = "LEFT JOIN channelgroup ON program.chanid = channelgroup.chanid " "WHERE channelgroup.grpid = :CHANGRPID AND "; bindings[":CHANGRPID" ] = nChannelGroupId; } else sSQL = "WHERE "; sSQL += "visible != 0 " "AND program.chanid >= :StartChanId " "AND program.chanid <= :EndChanId " "AND program.endtime >= :StartDate " "AND program.starttime <= :EndDate " "AND program.manualid = 0 " // Exclude programmes created purely for 'manual' recording schedules "ORDER BY LPAD(CAST(channum AS UNSIGNED), 10, 0), " " LPAD(channum, 10, 0), " " callsign, " " LPAD(program.chanid, 10, 0), " " program.starttime "; bindings[":StartChanId"] = nStartChanId; bindings[":EndChanId" ] = nEndChanId; bindings[":StartDate" ] = dtStartTime; bindings[":EndDate" ] = dtEndTime; // ---------------------------------------------------------------------- // Get all Pending Scheduled Programs // ---------------------------------------------------------------------- bool hasConflicts; LoadFromScheduler(schedList, hasConflicts); // ---------------------------------------------------------------------- LoadFromProgram( progList, sSQL, bindings, schedList ); // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ProgramGuide *pGuide = new DTC::ProgramGuide(); int nChanCount = 0; uint nCurChanId = 0; DTC::ChannelInfo *pChannel = NULL; QString sCurCallsign; uint nSkipChanId = 0; for( uint n = 0; n < progList.size(); n++) { ProgramInfo *pInfo = progList[ n ]; if ( nSkipChanId == pInfo->GetChanID()) continue; if ( nCurChanId != pInfo->GetChanID() ) { nChanCount++; nCurChanId = pInfo->GetChanID(); // Filter out channels with the same callsign, keeping just the // first seen if (sCurCallsign == pInfo->GetChannelSchedulingID()) { nSkipChanId = pInfo->GetChanID(); continue; } pChannel = pGuide->AddNewChannel(); FillChannelInfo( pChannel, pInfo->GetChanID(), bDetails ); sCurCallsign = pChannel->CallSign(); } DTC::Program *pProgram = pChannel->AddNewProgram(); FillProgramInfo( pProgram, pInfo, false, bDetails, false ); // No cast info } // ---------------------------------------------------------------------- pGuide->setStartTime ( dtStartTime ); pGuide->setEndTime ( dtEndTime ); pGuide->setStartChanId ( nStartChanId ); pGuide->setEndChanId ( nEndChanId ); pGuide->setNumOfChannels( nChanCount ); pGuide->setDetails ( bDetails ); pGuide->setCount ( progList.size()); pGuide->setAsOf ( MythDate::current() ); pGuide->setVersion ( MYTH_BINARY_VERSION ); pGuide->setProtoVer ( MYTH_PROTO_VERSION ); return pGuide; }
DTC::ProgramGuide *Guide::GetProgramGuide( const QDateTime &rawStartTime , const QDateTime &rawEndTime , bool bDetails, int nChannelGroupId, int nStartIndex, int nCount) { if (!rawStartTime.isValid()) throw( "StartTime is invalid" ); if (!rawEndTime.isValid()) throw( "EndTime is invalid" ); QDateTime dtStartTime = rawStartTime.toUTC(); QDateTime dtEndTime = rawEndTime.toUTC(); if (dtEndTime < dtStartTime) throw( "EndTime is before StartTime"); if (nStartIndex <= 0) nStartIndex = 0; if (nCount <= 0) nCount = 20000; // ---------------------------------------------------------------------- // Load the channel list // ---------------------------------------------------------------------- uint nTotalAvailable = 0; ChannelInfoList chanList = ChannelUtil::LoadChannels(nStartIndex, nCount, nTotalAvailable, true, ChannelUtil::kChanOrderByChanNum, ChannelUtil::kChanGroupByCallsign, 0, nChannelGroupId); // ---------------------------------------------------------------------- // Build SQL statement for Program Listing // ---------------------------------------------------------------------- ProgramList schedList; MSqlBindings bindings; QString sWhere = "program.chanid = :CHANID " "AND program.endtime >= :STARTDATE " "AND program.starttime < :ENDDATE " "AND program.starttime >= :STARTDATELIMIT " "AND program.manualid = 0"; // Omit 'manual' recordings scheds QString sGroupBy = "program.starttime, channel.channum," "channel.callsign, program.title"; QString sOrderBy = "program.starttime"; bindings[":STARTDATE" ] = dtStartTime; bindings[":STARTDATELIMIT"] = dtStartTime.addDays(-1); bindings[":ENDDATE" ] = dtEndTime; // ---------------------------------------------------------------------- // Get all Pending Scheduled Programs // ---------------------------------------------------------------------- // NOTE: Fetching this information directly from the schedule is // significantly faster than using ProgramInfo::LoadFromScheduler() Scheduler *scheduler = dynamic_cast<Scheduler*>(gCoreContext->GetScheduler()); if (scheduler) scheduler->GetAllPending(schedList); // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ProgramGuide *pGuide = new DTC::ProgramGuide(); ChannelInfoList::iterator chan_it; for (chan_it = chanList.begin(); chan_it != chanList.end(); ++chan_it) { // Create ChannelInfo Object DTC::ChannelInfo *pChannel = NULL; pChannel = pGuide->AddNewChannel(); FillChannelInfo( pChannel, (*chan_it), bDetails ); // Load the list of programmes for this channel ProgramList progList; bindings[":CHANID"] = (*chan_it).chanid; LoadFromProgram( progList, sWhere, sOrderBy, sOrderBy, bindings, schedList ); // Create Program objects and add them to the channel object ProgramList::iterator progIt; for( progIt = progList.begin(); progIt != progList.end(); ++progIt) { DTC::Program *pProgram = pChannel->AddNewProgram(); FillProgramInfo( pProgram, *progIt, false, bDetails, false ); // No cast info } } // ---------------------------------------------------------------------- pGuide->setStartTime ( dtStartTime ); pGuide->setEndTime ( dtEndTime ); pGuide->setDetails ( bDetails ); pGuide->setStartIndex ( nStartIndex ); pGuide->setCount ( chanList.size() ); pGuide->setTotalAvailable( nTotalAvailable ); pGuide->setAsOf ( MythDate::current() ); pGuide->setVersion ( MYTH_BINARY_VERSION ); pGuide->setProtoVer ( MYTH_PROTO_VERSION ); return pGuide; }
void FillProgramInfo( DTC::Program *pProgram, ProgramInfo *pInfo, bool bIncChannel /* = true */, bool bDetails /* = true */) { if ((pProgram == NULL) || (pInfo == NULL)) return; pProgram->setStartTime ( pInfo->GetScheduledStartTime()); pProgram->setEndTime ( pInfo->GetScheduledEndTime ()); pProgram->setTitle ( pInfo->GetTitle() ); pProgram->setSubTitle ( pInfo->GetSubtitle() ); pProgram->setCategory ( pInfo->GetCategory() ); pProgram->setCatType ( pInfo->GetCategoryType() ); pProgram->setRepeat ( pInfo->IsRepeat() ); pProgram->setVideoProps( pInfo->GetVideoProperties() ); pProgram->setAudioProps( pInfo->GetAudioProperties() ); pProgram->setSubProps ( pInfo->GetSubtitleType() ); pProgram->setSerializeDetails( bDetails ); if (bDetails) { pProgram->setSeriesId ( pInfo->GetSeriesID() ); pProgram->setProgramId ( pInfo->GetProgramID() ); pProgram->setStars ( pInfo->GetStars() ); pProgram->setFileSize ( pInfo->GetFilesize() ); pProgram->setLastModified( pInfo->GetLastModifiedTime() ); pProgram->setProgramFlags( pInfo->GetProgramFlags() ); pProgram->setHostname ( pInfo->GetHostname() ); if (pInfo->GetOriginalAirDate().isValid()) pProgram->setAirdate( pInfo->GetOriginalAirDate() ); pProgram->setDescription( pInfo->GetDescription() ); pProgram->setInetref ( pInfo->GetInetRef() ); pProgram->setSeason ( pInfo->GetSeason() ); pProgram->setEpisode ( pInfo->GetEpisode() ); } pProgram->setSerializeChannel( bIncChannel ); if ( bIncChannel ) { // Build Channel Child Element FillChannelInfo( pProgram->Channel(), pInfo, bDetails ); } // Build Recording Child Element if ( pInfo->GetRecordingStatus() != rsUnknown ) { pProgram->setSerializeRecording( true ); DTC::RecordingInfo *pRecording = pProgram->Recording(); pRecording->setStatus ( pInfo->GetRecordingStatus() ); pRecording->setPriority( pInfo->GetRecordingPriority() ); pRecording->setStartTs ( pInfo->GetRecordingStartTime() ); pRecording->setEndTs ( pInfo->GetRecordingEndTime() ); pRecording->setSerializeDetails( bDetails ); if (bDetails) { pRecording->setRecordId ( pInfo->GetRecordingRuleID() ); pRecording->setRecGroup ( pInfo->GetRecordingGroup() ); pRecording->setPlayGroup( pInfo->GetPlaybackGroup() ); pRecording->setRecType ( pInfo->GetRecordingRuleType() ); pRecording->setDupInType( pInfo->GetDuplicateCheckSource() ); pRecording->setDupMethod( pInfo->GetDuplicateCheckMethod() ); pRecording->setEncoderId( pInfo->GetCardID() ); const RecordingInfo ri(*pInfo); pRecording->setProfile( ri.GetProgramRecordingProfile() ); } } }
void FillProgramInfo( DTC::Program *pProgram, ProgramInfo *pInfo, bool bIncChannel /* = true */, bool bDetails /* = true */, bool bIncCast /* = true */) { if ((pProgram == NULL) || (pInfo == NULL)) return; pProgram->setStartTime ( pInfo->GetScheduledStartTime()); pProgram->setEndTime ( pInfo->GetScheduledEndTime ()); pProgram->setTitle ( pInfo->GetTitle() ); pProgram->setSubTitle ( pInfo->GetSubtitle() ); pProgram->setCategory ( pInfo->GetCategory() ); pProgram->setCatType ( pInfo->GetCategoryTypeString()); pProgram->setRepeat ( pInfo->IsRepeat() ); pProgram->setVideoProps( pInfo->GetVideoProperties() ); pProgram->setAudioProps( pInfo->GetAudioProperties() ); pProgram->setSubProps ( pInfo->GetSubtitleType() ); pProgram->setSerializeDetails( bDetails ); if (bDetails) { pProgram->setSeriesId ( pInfo->GetSeriesID() ); pProgram->setProgramId ( pInfo->GetProgramID() ); pProgram->setStars ( pInfo->GetStars() ); pProgram->setLastModified( pInfo->GetLastModifiedTime() ); pProgram->setProgramFlags( pInfo->GetProgramFlags() ); // ---- // DEPRECATED - See RecordingInfo instead pProgram->setFileName ( pInfo->GetPathname() ); pProgram->setFileSize ( pInfo->GetFilesize() ); pProgram->setHostName ( pInfo->GetHostname() ); // ---- if (pInfo->GetOriginalAirDate().isValid()) pProgram->setAirdate( pInfo->GetOriginalAirDate() ); else if (pInfo->GetYearOfInitialRelease() > 0) { QDate year; year.setDate(pInfo->GetYearOfInitialRelease(), 1, 1); pProgram->setAirdate( year ); } pProgram->setDescription( pInfo->GetDescription() ); pProgram->setInetref ( pInfo->GetInetRef() ); pProgram->setSeason ( pInfo->GetSeason() ); pProgram->setEpisode ( pInfo->GetEpisode() ); pProgram->setTotalEpisodes( pInfo->GetEpisodeTotal() ); } pProgram->setSerializeCast(bIncCast); if (bIncCast) { FillCastMemberList( pProgram->Cast(), pInfo ); } pProgram->setSerializeChannel( bIncChannel ); if ( bIncChannel ) { // Build Channel Child Element if (!FillChannelInfo( pProgram->Channel(), pInfo->GetChanID(), bDetails )) { // The channel associated with a given recording may no longer exist // however the ChanID is one half of the unique identifier for the // recording and therefore MUST be included in the return data pProgram->Channel()->setChanId(pInfo->GetChanID()); } } // Build Recording Child Element if ( pInfo->GetRecordingStatus() != RecStatus::Unknown ) { pProgram->setSerializeRecording( true ); DTC::RecordingInfo *pRecording = pProgram->Recording(); const RecordingInfo pRecInfo(*pInfo); pRecording->setRecordedId ( pRecInfo.GetRecordingID() ); pRecording->setStatus ( pRecInfo.GetRecordingStatus() ); pRecording->setPriority( pRecInfo.GetRecordingPriority() ); pRecording->setStartTs ( pRecInfo.GetRecordingStartTime() ); pRecording->setEndTs ( pRecInfo.GetRecordingEndTime() ); pRecording->setSerializeDetails( bDetails ); if (bDetails) { pRecording->setFileName ( pRecInfo.GetPathname() ); pRecording->setFileSize ( pRecInfo.GetFilesize() ); pRecording->setHostName ( pRecInfo.GetHostname() ); pRecording->setLastModified( pRecInfo.GetLastModifiedTime() ); pRecording->setRecordId ( pRecInfo.GetRecordingRuleID() ); pRecording->setRecGroup ( pRecInfo.GetRecordingGroup() ); pRecording->setPlayGroup ( pRecInfo.GetPlaybackGroup() ); pRecording->setStorageGroup( pRecInfo.GetStorageGroup() ); pRecording->setRecType ( pRecInfo.GetRecordingRuleType() ); pRecording->setDupInType ( pRecInfo.GetDuplicateCheckSource() ); pRecording->setDupMethod ( pRecInfo.GetDuplicateCheckMethod() ); pRecording->setEncoderId ( pRecInfo.GetInputID() ); if (pProgram->Channel()) { QString encoderName = CardUtil::GetDisplayName(pRecInfo.GetInputID()); pRecording->setEncoderName( encoderName ); } pRecording->setProfile( pRecInfo.GetProgramRecordingProfile() ); } } if (!pInfo->GetInetRef().isEmpty() ) { pProgram->setSerializeArtwork( true ); FillArtworkInfoList( pProgram->Artwork(), pInfo->GetInetRef(), pInfo->GetSeason()); } }