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 &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 , 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; }