00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
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
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
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
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