|
MythTV
0.26-pre
|
00001 00002 // Program Name: dvr.cpp 00003 // Created : Mar. 7, 2011 00004 // 00005 // Copyright (c) 2011 David Blain <dblain@mythtv.org> 00006 // 00007 // This library is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 2.1 of the License, or at your option any later version of the LGPL. 00011 // 00012 // This library is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 // Lesser General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public 00018 // License along with this library. If not, see <http://www.gnu.org/licenses/>. 00019 // 00021 00022 #include <QMap> 00023 #include <QRegExp> 00024 00025 #include "dvr.h" 00026 00027 #include "compat.h" 00028 #include "mythversion.h" 00029 #include "mythcorecontext.h" 00030 #include "mythevent.h" 00031 #include "scheduler.h" 00032 #include "autoexpire.h" 00033 #include "jobqueue.h" 00034 #include "encoderlink.h" 00035 #include "remoteutil.h" 00036 00037 #include "serviceUtil.h" 00038 00039 extern QMap<int, EncoderLink *> tvList; 00040 extern AutoExpire *expirer; 00041 00043 // 00045 00046 DTC::ProgramList* Dvr::GetRecordedList( bool bDescending, 00047 int nStartIndex, 00048 int nCount ) 00049 { 00050 return GetFilteredRecordedList( bDescending, nStartIndex, nCount, 00051 QString(), QString(), QString() ); 00052 } 00053 00054 DTC::ProgramList* Dvr::GetFilteredRecordedList( bool bDescending, 00055 int nStartIndex, 00056 int nCount, 00057 const QString &sTitleRegEx, 00058 const QString &sRecGroup, 00059 const QString &sStorageGroup ) 00060 { 00061 QMap< QString, ProgramInfo* > recMap; 00062 00063 if (gCoreContext->GetScheduler()) 00064 recMap = gCoreContext->GetScheduler()->GetRecording(); 00065 00066 QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap(); 00067 QMap< QString, bool > isJobRunning= ProgramInfo::QueryJobsRunning(JOB_COMMFLAG); 00068 00069 ProgramList progList; 00070 00071 int desc = 0; 00072 if (bDescending) 00073 desc = -1; 00074 00075 LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, desc ); 00076 00077 QMap< QString, ProgramInfo* >::iterator mit = recMap.begin(); 00078 00079 for (; mit != recMap.end(); mit = recMap.erase(mit)) 00080 delete *mit; 00081 00082 // ---------------------------------------------------------------------- 00083 // Build Response 00084 // ---------------------------------------------------------------------- 00085 00086 DTC::ProgramList *pPrograms = new DTC::ProgramList(); 00087 int nAvailable = 0; 00088 00089 if ((sTitleRegEx.isEmpty()) && 00090 (sRecGroup.isEmpty()) && 00091 (sStorageGroup.isEmpty())) 00092 { 00093 nStartIndex = min( nStartIndex, (int)progList.size() ); 00094 nCount = (nCount > 0) ? min( nCount, (int)progList.size() ) : progList.size(); 00095 int nEndIndex = min((nStartIndex + nCount), (int)progList.size() ); 00096 nCount = nEndIndex - nStartIndex; 00097 00098 nAvailable = progList.size(); 00099 00100 for( int n = nStartIndex; n < nEndIndex; n++) 00101 { 00102 ProgramInfo *pInfo = progList[ n ]; 00103 if (pInfo->GetRecordingGroup() != "Deleted") 00104 { 00105 DTC::Program *pProgram = pPrograms->AddNewProgram(); 00106 00107 FillProgramInfo( pProgram, pInfo, true ); 00108 } 00109 } 00110 } 00111 else 00112 { 00113 int nMax = nCount; 00114 00115 nAvailable = 0; 00116 nCount = 0; 00117 00118 QRegExp rTitleRegEx = QRegExp(sTitleRegEx, Qt::CaseInsensitive); 00119 00120 for( unsigned int n = 0; n < progList.size(); n++) 00121 { 00122 ProgramInfo *pInfo = progList[ n ]; 00123 00124 if ((!sTitleRegEx.isEmpty() && !pInfo->GetTitle().contains(rTitleRegEx)) || 00125 (!sRecGroup.isEmpty() && sRecGroup != pInfo->GetRecordingGroup()) || 00126 (!sStorageGroup.isEmpty() && sStorageGroup != pInfo->GetStorageGroup())) 00127 continue; 00128 00129 ++nAvailable; 00130 00131 if ((nAvailable < nStartIndex) || 00132 (nCount >= nMax)) 00133 continue; 00134 00135 ++nCount; 00136 00137 DTC::Program *pProgram = pPrograms->AddNewProgram(); 00138 00139 FillProgramInfo( pProgram, pInfo, true ); 00140 } 00141 } 00142 00143 // ---------------------------------------------------------------------- 00144 00145 pPrograms->setStartIndex ( nStartIndex ); 00146 pPrograms->setCount ( nCount ); 00147 pPrograms->setTotalAvailable( nAvailable ); 00148 pPrograms->setAsOf ( QDateTime::currentDateTime() ); 00149 pPrograms->setVersion ( MYTH_BINARY_VERSION ); 00150 pPrograms->setProtoVer ( MYTH_PROTO_VERSION ); 00151 00152 return pPrograms; 00153 } 00154 00156 // 00158 00159 DTC::Program* Dvr::GetRecorded( int nChanId, 00160 const QDateTime &dStartTime ) 00161 { 00162 if (nChanId <= 0 || !dStartTime.isValid()) 00163 throw( QString("Channel ID or StartTime appears invalid.")); 00164 00165 ProgramInfo *pInfo = new ProgramInfo(nChanId, dStartTime); 00166 00167 DTC::Program *pProgram = new DTC::Program(); 00168 FillProgramInfo( pProgram, pInfo, true ); 00169 00170 return pProgram; 00171 } 00172 00174 // 00176 00177 bool Dvr::RemoveRecorded( int nChanId, 00178 const QDateTime &dStartTime ) 00179 { 00180 if (nChanId <= 0 || !dStartTime.isValid()) 00181 throw( QString("Channel ID or StartTime appears invalid.")); 00182 00183 bool bResult = false; 00184 00185 ProgramInfo *pInfo = new ProgramInfo(nChanId, dStartTime); 00186 00187 QString cmd = QString("DELETE_RECORDING %1 %2") 00188 .arg(nChanId) 00189 .arg(dStartTime.toString(Qt::ISODate)); 00190 MythEvent me(cmd); 00191 00192 if (pInfo->HasPathname()) 00193 { 00194 gCoreContext->dispatch(me); 00195 bResult = true; 00196 } 00197 00198 return bResult; 00199 } 00200 00202 // 00204 00205 DTC::ProgramList* Dvr::GetExpiringList( int nStartIndex, 00206 int nCount ) 00207 { 00208 pginfolist_t infoList; 00209 00210 if (expirer) 00211 expirer->GetAllExpiring( infoList ); 00212 00213 // ---------------------------------------------------------------------- 00214 // Build Response 00215 // ---------------------------------------------------------------------- 00216 00217 DTC::ProgramList *pPrograms = new DTC::ProgramList(); 00218 00219 nStartIndex = min( nStartIndex, (int)infoList.size() ); 00220 nCount = (nCount > 0) ? min( nCount, (int)infoList.size() ) : infoList.size(); 00221 int nEndIndex = min((nStartIndex + nCount), (int)infoList.size() ); 00222 00223 for( int n = nStartIndex; n < nEndIndex; n++) 00224 { 00225 ProgramInfo *pInfo = infoList[ n ]; 00226 00227 if (pInfo != NULL) 00228 { 00229 DTC::Program *pProgram = pPrograms->AddNewProgram(); 00230 00231 FillProgramInfo( pProgram, pInfo, true ); 00232 00233 delete pInfo; 00234 } 00235 } 00236 00237 // ---------------------------------------------------------------------- 00238 00239 pPrograms->setStartIndex ( nStartIndex ); 00240 pPrograms->setCount ( nCount ); 00241 pPrograms->setTotalAvailable( infoList.size() ); 00242 pPrograms->setAsOf ( QDateTime::currentDateTime() ); 00243 pPrograms->setVersion ( MYTH_BINARY_VERSION ); 00244 pPrograms->setProtoVer ( MYTH_PROTO_VERSION ); 00245 00246 return pPrograms; 00247 } 00248 00250 // 00252 00253 DTC::EncoderList* Dvr::GetEncoderList() 00254 { 00255 DTC::EncoderList* pList = new DTC::EncoderList(); 00256 00257 QMap<int, EncoderLink *>::Iterator iter = tvList.begin(); 00258 00259 for (; iter != tvList.end(); ++iter) 00260 { 00261 EncoderLink *elink = *iter; 00262 00263 if (elink != NULL) 00264 { 00265 DTC::Encoder *pEncoder = pList->AddNewEncoder(); 00266 00267 pEncoder->setId ( elink->GetCardID() ); 00268 pEncoder->setState ( elink->GetState() ); 00269 pEncoder->setLocal ( elink->IsLocal() ); 00270 pEncoder->setConnected ( elink->IsConnected() ); 00271 pEncoder->setSleepStatus ( elink->GetSleepStatus() ); 00272 // pEncoder->setLowOnFreeSpace( elink->isLowOnFreeSpace()); 00273 00274 if (pEncoder->Local()) 00275 pEncoder->setHostName( gCoreContext->GetHostName() ); 00276 else 00277 pEncoder->setHostName( elink->GetHostName() ); 00278 00279 switch ( pEncoder->State() ) 00280 { 00281 case kState_WatchingLiveTV: 00282 case kState_RecordingOnly: 00283 case kState_WatchingRecording: 00284 { 00285 ProgramInfo *pInfo = elink->GetRecording(); 00286 00287 if (pInfo) 00288 { 00289 DTC::Program *pProgram = pEncoder->Recording(); 00290 00291 FillProgramInfo( pProgram, pInfo, true, true ); 00292 00293 delete pInfo; 00294 } 00295 00296 break; 00297 } 00298 00299 default: 00300 break; 00301 } 00302 } 00303 } 00304 return pList; 00305 } 00306 00308 // 00310 00311 DTC::ProgramList* Dvr::GetUpcomingList( int nStartIndex, 00312 int nCount, 00313 bool bShowAll ) 00314 { 00315 RecordingList recordingList; 00316 RecordingList tmpList; 00317 bool hasConflicts; 00318 LoadFromScheduler(tmpList, hasConflicts); 00319 00320 // Sort the upcoming into only those which will record 00321 RecordingList::iterator it = tmpList.begin(); 00322 for(; it < tmpList.end(); ++it) 00323 { 00324 if (!bShowAll && ((*it)->GetRecordingStatus() <= rsWillRecord) && 00325 ((*it)->GetRecordingStartTime() >= 00326 QDateTime::currentDateTime())) 00327 { 00328 recordingList.push_back(new RecordingInfo(**it)); 00329 } 00330 else if (bShowAll && ((*it)->GetRecordingStartTime() >= 00331 QDateTime::currentDateTime())) 00332 { 00333 recordingList.push_back(new RecordingInfo(**it)); 00334 } 00335 } 00336 00337 // ---------------------------------------------------------------------- 00338 // Build Response 00339 // ---------------------------------------------------------------------- 00340 00341 DTC::ProgramList *pPrograms = new DTC::ProgramList(); 00342 00343 nStartIndex = min( nStartIndex, (int)recordingList.size() ); 00344 nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size(); 00345 int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() ); 00346 00347 for( int n = nStartIndex; n < nEndIndex; n++) 00348 { 00349 ProgramInfo *pInfo = recordingList[ n ]; 00350 00351 DTC::Program *pProgram = pPrograms->AddNewProgram(); 00352 00353 FillProgramInfo( pProgram, pInfo, true ); 00354 } 00355 00356 // ---------------------------------------------------------------------- 00357 00358 pPrograms->setStartIndex ( nStartIndex ); 00359 pPrograms->setCount ( nCount ); 00360 pPrograms->setTotalAvailable( recordingList.size() ); 00361 pPrograms->setAsOf ( QDateTime::currentDateTime() ); 00362 pPrograms->setVersion ( MYTH_BINARY_VERSION ); 00363 pPrograms->setProtoVer ( MYTH_PROTO_VERSION ); 00364 00365 return pPrograms; 00366 } 00367 00369 // 00371 00372 DTC::ProgramList* Dvr::GetConflictList( int nStartIndex, 00373 int nCount ) 00374 { 00375 RecordingList recordingList; 00376 RecordingList tmpList; 00377 bool hasConflicts; 00378 LoadFromScheduler(tmpList, hasConflicts); 00379 00380 // Sort the upcoming into only those which are conflicts 00381 RecordingList::iterator it = tmpList.begin(); 00382 for(; it < tmpList.end(); ++it) 00383 { 00384 if (((*it)->GetRecordingStatus() == rsConflict) && 00385 ((*it)->GetRecordingStartTime() >= 00386 QDateTime::currentDateTime())) 00387 { 00388 recordingList.push_back(new RecordingInfo(**it)); 00389 } 00390 } 00391 00392 // ---------------------------------------------------------------------- 00393 // Build Response 00394 // ---------------------------------------------------------------------- 00395 00396 DTC::ProgramList *pPrograms = new DTC::ProgramList(); 00397 00398 nStartIndex = min( nStartIndex, (int)recordingList.size() ); 00399 nCount = (nCount > 0) ? min( nCount, (int)recordingList.size() ) : recordingList.size(); 00400 int nEndIndex = min((nStartIndex + nCount), (int)recordingList.size() ); 00401 00402 for( int n = nStartIndex; n < nEndIndex; n++) 00403 { 00404 ProgramInfo *pInfo = recordingList[ n ]; 00405 00406 DTC::Program *pProgram = pPrograms->AddNewProgram(); 00407 00408 FillProgramInfo( pProgram, pInfo, true ); 00409 } 00410 00411 // ---------------------------------------------------------------------- 00412 00413 pPrograms->setStartIndex ( nStartIndex ); 00414 pPrograms->setCount ( nCount ); 00415 pPrograms->setTotalAvailable( recordingList.size() ); 00416 pPrograms->setAsOf ( QDateTime::currentDateTime() ); 00417 pPrograms->setVersion ( MYTH_BINARY_VERSION ); 00418 pPrograms->setProtoVer ( MYTH_PROTO_VERSION ); 00419 00420 return pPrograms; 00421 } 00422 00423 int Dvr::AddRecordSchedule ( int nChanId, 00424 QDateTime dStartTime, 00425 int nParentId, 00426 bool bInactive, 00427 uint nSeason, 00428 uint nEpisode, 00429 QString sInetref, 00430 int nFindId, 00431 QString sType, 00432 QString sSearchType, 00433 int nRecPriority, 00434 uint nPreferredInput, 00435 int nStartOffset, 00436 int nEndOffset, 00437 QString sDupMethod, 00438 QString sDupIn, 00439 uint nFilter, 00440 QString sRecProfile, 00441 QString sRecGroup, 00442 QString sStorageGroup, 00443 QString sPlayGroup, 00444 bool bAutoExpire, 00445 int nMaxEpisodes, 00446 bool bMaxNewest, 00447 bool bAutoCommflag, 00448 bool bAutoTranscode, 00449 bool bAutoMetaLookup, 00450 bool bAutoUserJob1, 00451 bool bAutoUserJob2, 00452 bool bAutoUserJob3, 00453 bool bAutoUserJob4, 00454 int nTranscoder) 00455 { 00456 RecordingInfo *info = new RecordingInfo(nChanId, dStartTime, false); 00457 RecordingRule *rule = info->GetRecordingRule(); 00458 00459 if (sType.isEmpty()) 00460 sType = "single"; 00461 00462 if (sSearchType.isEmpty()) 00463 sSearchType = "none"; 00464 00465 if (sDupMethod.isEmpty()) 00466 sDupMethod = "subtitleanddescription"; 00467 00468 if (sDupIn.isEmpty()) 00469 sDupIn = "all"; 00470 00471 rule->m_title = info->GetTitle(); 00472 rule->m_type = recTypeFromString(sType); 00473 rule->m_searchType = searchTypeFromString(sSearchType); 00474 rule->m_dupMethod = dupMethodFromString(sDupMethod); 00475 rule->m_dupIn = dupInFromString(sDupIn); 00476 00477 if (sRecProfile.isEmpty()) 00478 sRecProfile = "Default"; 00479 00480 if (sRecGroup.isEmpty()) 00481 sRecGroup = "Default"; 00482 00483 if (sStorageGroup.isEmpty()) 00484 sStorageGroup = "Default"; 00485 00486 if (sPlayGroup.isEmpty()) 00487 sPlayGroup = "Default"; 00488 00489 rule->m_recProfile = sRecProfile; 00490 rule->m_recGroup = sRecGroup; 00491 rule->m_storageGroup = sStorageGroup; 00492 rule->m_playGroup = sPlayGroup; 00493 00494 rule->m_parentRecID = nParentId; 00495 rule->m_isInactive = bInactive; 00496 00497 rule->m_season = nSeason; 00498 rule->m_episode = nEpisode; 00499 rule->m_inetref = sInetref; 00500 rule->m_findid = nFindId; 00501 00502 rule->m_recPriority = nRecPriority; 00503 rule->m_prefInput = nPreferredInput; 00504 rule->m_startOffset = nStartOffset; 00505 rule->m_endOffset = nEndOffset; 00506 rule->m_filter = nFilter; 00507 00508 rule->m_autoExpire = bAutoExpire; 00509 rule->m_maxEpisodes = nMaxEpisodes; 00510 rule->m_maxNewest = bMaxNewest; 00511 00512 rule->m_autoCommFlag = bAutoCommflag; 00513 rule->m_autoTranscode = bAutoTranscode; 00514 rule->m_autoMetadataLookup = bAutoMetaLookup; 00515 00516 rule->m_autoUserJob1 = bAutoUserJob1; 00517 rule->m_autoUserJob2 = bAutoUserJob2; 00518 rule->m_autoUserJob3 = bAutoUserJob3; 00519 rule->m_autoUserJob4 = bAutoUserJob4; 00520 00521 rule->m_transcoder = nTranscoder; 00522 00523 rule->Save(); 00524 00525 int recid = rule->m_recordID; 00526 00527 delete rule; 00528 rule = NULL; 00529 00530 return recid; 00531 } 00532 00533 bool Dvr::RemoveRecordSchedule ( uint nRecordId ) 00534 { 00535 bool bResult = false; 00536 00537 if (nRecordId <= 0 ) 00538 throw( QString("Record ID appears invalid.")); 00539 00540 RecordingRule pRule; 00541 pRule.m_recordID = nRecordId; 00542 00543 bResult = pRule.Delete(); 00544 00545 return bResult; 00546 } 00547 00548 DTC::RecRuleList* Dvr::GetRecordScheduleList( int nStartIndex, 00549 int nCount ) 00550 { 00551 RecList recList; 00552 Scheduler::GetAllScheduled(recList); 00553 00554 // ---------------------------------------------------------------------- 00555 // Build Response 00556 // ---------------------------------------------------------------------- 00557 00558 DTC::RecRuleList *pRecRules = new DTC::RecRuleList(); 00559 00560 nStartIndex = min( nStartIndex, (int)recList.size() ); 00561 nCount = (nCount > 0) ? min( nCount, (int)recList.size() ) : recList.size(); 00562 int nEndIndex = min((nStartIndex + nCount), (int)recList.size() ); 00563 00564 for( int n = nStartIndex; n < nEndIndex; n++) 00565 { 00566 RecordingInfo *info = recList[n]; 00567 00568 if (info != NULL) 00569 { 00570 DTC::RecRule *pRecRule = pRecRules->AddNewRecRule(); 00571 00572 FillRecRuleInfo( pRecRule, info->GetRecordingRule() ); 00573 00574 delete info; 00575 } 00576 } 00577 00578 // ---------------------------------------------------------------------- 00579 00580 pRecRules->setStartIndex ( nStartIndex ); 00581 pRecRules->setCount ( nCount ); 00582 pRecRules->setTotalAvailable( recList.size() ); 00583 pRecRules->setAsOf ( QDateTime::currentDateTime() ); 00584 pRecRules->setVersion ( MYTH_BINARY_VERSION ); 00585 pRecRules->setProtoVer ( MYTH_PROTO_VERSION ); 00586 00587 return pRecRules; 00588 } 00589 00590 DTC::RecRule* Dvr::GetRecordSchedule( uint nRecordId ) 00591 { 00592 if (nRecordId <= 0 ) 00593 throw( QString("Record ID appears invalid.")); 00594 00595 RecordingRule *pRule = new RecordingRule(); 00596 pRule->m_recordID = nRecordId; 00597 pRule->Load(); 00598 00599 DTC::RecRule *pRecRule = new DTC::RecRule(); 00600 FillRecRuleInfo( pRecRule, pRule ); 00601 delete pRule; 00602 00603 return pRecRule; 00604 } 00605 00606 bool Dvr::EnableRecordSchedule ( uint nRecordId ) 00607 { 00608 bool bResult = false; 00609 00610 if (nRecordId <= 0 ) 00611 throw( QString("Record ID appears invalid.")); 00612 00613 RecordingRule pRule; 00614 pRule.m_recordID = nRecordId; 00615 pRule.Load(); 00616 00617 if (pRule.IsLoaded()) 00618 { 00619 pRule.m_isInactive = false; 00620 pRule.Save(); 00621 bResult = true; 00622 } 00623 00624 return bResult; 00625 } 00626 00627 bool Dvr::DisableRecordSchedule( uint nRecordId ) 00628 { 00629 bool bResult = false; 00630 00631 if (nRecordId <= 0 ) 00632 throw( QString("Record ID appears invalid.")); 00633 00634 RecordingRule pRule; 00635 pRule.m_recordID = nRecordId; 00636 pRule.Load(); 00637 00638 if (pRule.IsLoaded()) 00639 { 00640 pRule.m_isInactive = true; 00641 pRule.Save(); 00642 bResult = true; 00643 } 00644 00645 return bResult; 00646 } 00647
1.7.6.1