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::ChannelInfoList* Channel::GetChannelInfoList( int nSourceID, int nStartIndex, int nCount ) { vector<uint> chanList; chanList = ChannelUtil::GetChanIDs(nSourceID); // ---------------------------------------------------------------------- // Build Response // ---------------------------------------------------------------------- DTC::ChannelInfoList *pChannelInfos = new DTC::ChannelInfoList(); nStartIndex = min( nStartIndex, (int)chanList.size() ); nCount = (nCount > 0) ? min( nCount, (int)chanList.size() ) : chanList.size(); int nEndIndex = min((nStartIndex + nCount), (int)chanList.size() ); for( int n = nStartIndex; n < nEndIndex; n++) { DTC::ChannelInfo *pChannelInfo = pChannelInfos->AddNewChannelInfo(); int chanid = chanList.at(n); QString channum = ChannelUtil::GetChanNum(chanid); QString format, modulation, freqtable, freqid, dtv_si_std, xmltvid, default_authority, icon; int finetune, program_number; uint64_t frequency; uint atscmajor, atscminor, transportid, networkid, mplexid; bool commfree = false; bool eit = false; bool visible = true; if (ChannelUtil::GetExtendedChannelData( nSourceID, channum, format, modulation, freqtable, freqid, finetune, frequency, dtv_si_std, program_number, atscmajor, atscminor, transportid, networkid, mplexid, commfree, eit, visible, xmltvid, default_authority, icon )) { pChannelInfo->setChanId(chanid); pChannelInfo->setChanNum(channum); pChannelInfo->setCallSign(ChannelUtil::GetCallsign(chanid)); pChannelInfo->setIconURL(icon); pChannelInfo->setChannelName(ChannelUtil::GetServiceName(chanid)); pChannelInfo->setMplexId(mplexid); pChannelInfo->setServiceId(program_number); pChannelInfo->setATSCMajorChan(atscmajor); pChannelInfo->setATSCMinorChan(atscminor); pChannelInfo->setFormat(format); pChannelInfo->setModulation(modulation); pChannelInfo->setFrequencyTable(freqtable); pChannelInfo->setFineTune(finetune); pChannelInfo->setFrequency((long)frequency); pChannelInfo->setFrequencyId(freqid); pChannelInfo->setSIStandard(dtv_si_std); pChannelInfo->setTransportId(transportid); pChannelInfo->setNetworkId(networkid); pChannelInfo->setChanFilters(ChannelUtil::GetVideoFilters(nSourceID, channum)); pChannelInfo->setSourceId(nSourceID); pChannelInfo->setCommFree(commfree); pChannelInfo->setUseEIT(eit); pChannelInfo->setVisible(visible); pChannelInfo->setXMLTVID(xmltvid); pChannelInfo->setDefaultAuth(default_authority); } } 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 ( QDateTime::currentDateTime() ); pChannelInfos->setVersion ( MYTH_BINARY_VERSION ); pChannelInfos->setProtoVer ( MYTH_PROTO_VERSION ); return pChannelInfos; }
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; }
DTC::ChannelInfo* Channel::GetChannelInfo( int nChanID ) { if (nChanID == 0) throw( QString("Channel ID appears invalid.")); DTC::ChannelInfo *pChannelInfo = new DTC::ChannelInfo(); QString channum = ChannelUtil::GetChanNum(nChanID); uint sourceid = ChannelUtil::GetSourceIDForChannel(nChanID); QString format, modulation, freqtable, freqid, dtv_si_std, xmltvid, default_authority, icon; int finetune, program_number; uint64_t frequency; uint atscmajor, atscminor, transportid, networkid, mplexid; bool commfree = false; bool eit = false; bool visible = true; if (ChannelUtil::GetExtendedChannelData( sourceid, channum, format, modulation, freqtable, freqid, finetune, frequency, dtv_si_std, program_number, atscmajor, atscminor, transportid, networkid, mplexid, commfree, eit, visible, xmltvid, default_authority, icon )) { pChannelInfo->setChanId(nChanID); pChannelInfo->setChanNum(channum); pChannelInfo->setCallSign(ChannelUtil::GetCallsign(nChanID)); pChannelInfo->setIconURL(icon); pChannelInfo->setChannelName(ChannelUtil::GetServiceName(nChanID)); pChannelInfo->setMplexId(mplexid); pChannelInfo->setServiceId(program_number); pChannelInfo->setATSCMajorChan(atscmajor); pChannelInfo->setATSCMinorChan(atscminor); pChannelInfo->setFormat(format); pChannelInfo->setModulation(modulation); pChannelInfo->setFrequencyTable(freqtable); pChannelInfo->setFineTune(finetune); pChannelInfo->setFrequency((long)frequency); pChannelInfo->setFrequencyId(freqid); pChannelInfo->setSIStandard(dtv_si_std); pChannelInfo->setTransportId(transportid); pChannelInfo->setNetworkId(networkid); pChannelInfo->setChanFilters(ChannelUtil::GetVideoFilters(sourceid, channum)); pChannelInfo->setSourceId(sourceid); pChannelInfo->setCommFree(commfree); pChannelInfo->setUseEIT(eit); pChannelInfo->setVisible(visible); pChannelInfo->setXMLTVID(xmltvid); pChannelInfo->setDefaultAuth(default_authority); } else throw( QString("Channel ID appears invalid.")); return pChannelInfo; }