Ticket #10533: schedopt3.patch
| File schedopt3.patch, 73.7 KB (added by , 14 years ago) |
|---|
-
mythtv/libs/libmyth/programinfo.cpp
diff --git a/mythtv/libs/libmyth/programinfo.cpp b/mythtv/libs/libmyth/programinfo.cpp index 83e0d21..b6c24a1 100644
a b void ProgramInfo::SaveDeletePendingFlag(bool deleteFlag) 2678 2678 MSqlQuery query(MSqlQuery::InitCon()); 2679 2679 2680 2680 query.prepare("UPDATE recorded" 2681 " SET deletepending = :DELETEFLAG" 2681 " SET deletepending = :DELETEFLAG, " 2682 " duplicate = 0 " 2682 2683 " WHERE chanid = :CHANID" 2683 2684 " AND starttime = :STARTTIME ;"); 2684 2685 query.bindValue(":CHANID", chanid); -
mythtv/libs/libmythtv/eitscanner.cpp
diff --git a/mythtv/libs/libmythtv/eitscanner.cpp b/mythtv/libs/libmythtv/eitscanner.cpp index 6135e08..cde2f69 100644
a b void EITScanner::RescheduleRecordings(void) 177 177 QDateTime::currentDateTime().addSecs(kMinRescheduleInterval); 178 178 resched_lock.unlock(); 179 179 180 ScheduledRecording:: signalChange(-1);180 ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(), "EITScanner"); 181 181 } 182 182 183 183 /** \fn EITScanner::StartPassiveScan(ChannelBase*, EITSource*, bool) -
mythtv/libs/libmythtv/recordinginfo.cpp
diff --git a/mythtv/libs/libmythtv/recordinginfo.cpp b/mythtv/libs/libmythtv/recordinginfo.cpp index 73cc9ef..2c42e2d 100644
a b void RecordingInfo::ReactivateRecording(void) 1155 1155 if (!result.exec()) 1156 1156 MythDB::DBError("ReactivateRecording", result); 1157 1157 1158 ScheduledRecording:: signalChange(0);1158 ScheduledRecording::ReschedulePlace("Reactivate"); 1159 1159 } 1160 1160 1161 1161 /** … … void RecordingInfo::AddHistory(bool resched, bool forcedup, bool future) 1223 1223 // The adding of an entry to oldrecorded may affect near-future 1224 1224 // scheduling decisions, so recalculate if told 1225 1225 if (resched) 1226 ScheduledRecording:: signalChange(0);1226 ScheduledRecording::RescheduleCheck(*this, "AddHistory"); 1227 1227 } 1228 1228 1229 1229 /** \fn RecordingInfo::DeleteHistory(void) … … void RecordingInfo::DeleteHistory(void) 1257 1257 1258 1258 // The removal of an entry from oldrecorded may affect near-future 1259 1259 // scheduling decisions, so recalculate 1260 ScheduledRecording:: signalChange(0);1260 ScheduledRecording::RescheduleCheck(*this, "DeleteHistory"); 1261 1261 } 1262 1262 1263 1263 /** \fn RecordingInfo::ForgetHistory(void) … … void RecordingInfo::ForgetHistory(void) 1321 1321 1322 1322 // The removal of an entry from oldrecorded may affect near-future 1323 1323 // scheduling decisions, so recalculate 1324 ScheduledRecording:: signalChange(0);1324 ScheduledRecording::RescheduleCheck(*this, "ForgetHistory"); 1325 1325 } 1326 1326 1327 1327 /** \fn RecordingInfo::SetDupHistory(void) … … void RecordingInfo::SetDupHistory(void) 1347 1347 if (!result.exec()) 1348 1348 MythDB::DBError("setDupHistory", result); 1349 1349 1350 ScheduledRecording:: signalChange(0);1350 ScheduledRecording::RescheduleCheck(*this, "SetHistory"); 1351 1351 } 1352 1352 1353 1353 /** -
mythtv/libs/libmythtv/recordinginfo.h
diff --git a/mythtv/libs/libmythtv/recordinginfo.h b/mythtv/libs/libmythtv/recordinginfo.h index 5ca56bf..4c8378a 100644
a b class MTV_PUBLIC RecordingInfo : public ProgramInfo 228 228 void ApplyTranscoderProfileChange(const QString &profile) const;//pi 229 229 void ApplyTranscoderProfileChangeById(int); 230 230 231 static void signalChange(int recordid);232 233 231 RecStatusType oldrecstatus; 234 232 RecStatusType savedrecstatus; 235 233 bool future; -
mythtv/libs/libmythtv/recordingrule.cpp
diff --git a/mythtv/libs/libmythtv/recordingrule.cpp b/mythtv/libs/libmythtv/recordingrule.cpp index f7a9981..907f92b 100644
a b 8 8 #include "mythcorecontext.h" 9 9 10 10 // libmythtv 11 #include "scheduledrecording.h" // For signalChange()11 #include "scheduledrecording.h" // For RescheduleMatch() 12 12 #include "playgroup.h" // For GetInitialName() 13 13 #include "recordingprofile.h" // For constants 14 14 #include "mythmiscutil.h" … … bool RecordingRule::Save(bool sendSig) 380 380 m_recordID = query.lastInsertId().toInt(); 381 381 382 382 if (sendSig) 383 ScheduledRecording::signalChange(m_recordID); 383 ScheduledRecording::RescheduleMatch(m_recordID, 0, 0, QDateTime(), 384 QString("SaveRule %1").arg(m_title)); 384 385 385 386 return true; 386 387 } … … bool RecordingRule::Delete(bool sendSig) 408 409 } 409 410 410 411 if (sendSig) 411 ScheduledRecording::signalChange(m_recordID); 412 ScheduledRecording::RescheduleMatch(m_recordID, 0, 0, QDateTime(), 413 QString("DeleteRule %1").arg(m_title)); 412 414 413 415 // Set m_recordID to zero, the rule is no longer in the database so it's 414 416 // not valid. Should you want, this allows a rule to be removed from the -
mythtv/libs/libmythtv/scheduledrecording.cpp
diff --git a/mythtv/libs/libmythtv/scheduledrecording.cpp b/mythtv/libs/libmythtv/scheduledrecording.cpp index 4e162b2..0c0fa1c 100644
a b ScheduledRecording::~ScheduledRecording() 9 9 { 10 10 } 11 11 12 void ScheduledRecording:: signalChange(int recordid)12 void ScheduledRecording::SendReschedule(const QStringList &request) 13 13 { 14 14 if (gCoreContext->IsBackend()) 15 15 { 16 MythEvent me(QString("RESCHEDULE_RECORDINGS %1").arg(recordid));16 MythEvent me(QString("RESCHEDULE_RECORDINGS"), request); 17 17 gCoreContext->dispatch(me); 18 18 } 19 19 else 20 20 { 21 21 QStringList slist; 22 slist << QString("RESCHEDULE_RECORDINGS %1").arg(recordid); 22 slist << QString("RESCHEDULE_RECORDINGS"); 23 slist << request; 23 24 if (!gCoreContext->SendReceiveStringList(slist)) 24 25 LOG(VB_GENERAL, LOG_ERR, 25 QString("Error rescheduling id%1 in "26 "ScheduledRecording:: signalChange") .arg(recordid));26 QString("Error rescheduling %1 in " 27 "ScheduledRecording::SendReschedule").arg(request[0])); 27 28 } 28 29 } 29 30 31 QStringList ScheduledRecording::BuildMatchRequest(uint recordid, 32 uint sourceid, uint mplexid, const QDateTime &maxstarttime, 33 const QString &why) 34 { 35 return QStringList(QString("MATCH %1 %2 %3 %4 %5") 36 .arg(recordid).arg(sourceid).arg(mplexid) 37 .arg(maxstarttime.isValid() ? 38 maxstarttime.toString(Qt::ISODate) : 39 "-") 40 .arg(why)); 41 }; 42 43 QStringList ScheduledRecording::BuildCheckRequest(const RecordingInfo &recinfo, 44 const QString &why) 45 { 46 return QStringList(QString("CHECK %1 %2 %3 %4") 47 .arg(recinfo.GetRecordingStatus()) 48 .arg(recinfo.GetParentRecordingRuleID() ? 49 recinfo.GetParentRecordingRuleID() : 50 recinfo.GetRecordingRuleID()) 51 .arg(recinfo.GetFindID()) 52 .arg(why)) 53 << recinfo.GetTitle() 54 << recinfo.GetSubtitle() 55 << recinfo.GetDescription() 56 << recinfo.GetProgramID(); 57 }; 58 59 QStringList ScheduledRecording::BuildPlaceRequest(const QString &why) 60 { 61 return QStringList(QString("PLACE %1").arg(why)); 62 }; 63 30 64 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
mythtv/libs/libmythtv/scheduledrecording.h
diff --git a/mythtv/libs/libmythtv/scheduledrecording.h b/mythtv/libs/libmythtv/scheduledrecording.h index 4a230fb..2f14d2e 100644
a b 2 2 #define SCHEDULEDRECORDING_H 3 3 4 4 #include "mythtvexp.h" 5 #include "qdatetime.h" 6 #include "recordinginfo.h" 5 7 6 8 class MTV_PUBLIC ScheduledRecording 7 9 { 10 friend class Scheduler; 11 8 12 public: 13 // Use when a recording rule or program data changes. Use 0 for 14 // recordid when all recordids are potentially affected, Use 15 // invalid starttime and 0 for chanids when not time nor channel 16 // specific. 17 static void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, 18 const QDateTime &maxstarttime, const QString &why) 19 { SendReschedule(BuildMatchRequest(recordid, sourceid, mplexid, 20 maxstarttime, why)); }; 21 22 // Use when previous or current recorded duplicate status changes. 23 static void RescheduleCheck(const RecordingInfo &recinfo, 24 const QString &why) 25 { SendReschedule(BuildCheckRequest(recinfo, why)); }; 26 27 // Use when none of recording rule, program data or duplicate 28 // status changes. 29 static void ReschedulePlace(const QString &why) 30 { SendReschedule(BuildPlaceRequest(why)); }; 31 32 private: 9 33 ScheduledRecording(); 10 34 ~ScheduledRecording(); 11 35 12 static void signalChange(int recordid); 13 // Use -1 for recordid when all recordids are potentially 14 // affected, such as when the program table is updated. 15 // Use 0 for recordid when a reschdule isn't specific to a single 16 // recordid, such as when a recording type priority is changed. 36 static void SendReschedule(const QStringList &request); 37 static QStringList BuildMatchRequest(uint recordid, uint sourceid, 38 uint mplexid, const QDateTime &maxstarttime, const QString &why); 39 static QStringList BuildCheckRequest(const RecordingInfo &recinfo, 40 const QString &why); 41 static QStringList BuildPlaceRequest(const QString &why); 17 42 }; 18 43 19 44 #endif -
mythtv/libs/libmythtv/tv_rec.cpp
diff --git a/mythtv/libs/libmythtv/tv_rec.cpp b/mythtv/libs/libmythtv/tv_rec.cpp index bf15151..1e88080 100644
a b void TVRec::NotifySchedulerOfRecording(RecordingInfo *rec) 2668 2668 rec->AddHistory(false); 2669 2669 2670 2670 // + save RecordingRule so that we get a recordid 2671 // (don't allow signalChange(), avoiding unneeded reschedule)2671 // (don't allow RescheduleMatch(), avoiding unneeded reschedule) 2672 2672 rec->GetRecordingRule()->Save(false); 2673 2673 2674 2674 // + save recordid to recorded entry -
mythtv/programs/mythbackend/main_helpers.cpp
diff --git a/mythtv/programs/mythbackend/main_helpers.cpp b/mythtv/programs/mythbackend/main_helpers.cpp index 5017af4..1d2740f 100644
a b int handle_command(const MythBackendCommandLineParser &cmdline) 370 370 } 371 371 372 372 verboseMask |= VB_SCHEDULE; 373 LogLevel_t oldLogLevel = logLevel; 374 logLevel = LOG_DEBUG; 373 375 sched->PrintList(true); 376 logLevel = oldLogLevel; 374 377 delete sched; 375 378 return GENERIC_EXIT_OK; 376 379 } … … int handle_command(const MythBackendCommandLineParser &cmdline) 381 384 if (gCoreContext->ConnectToMasterServer()) 382 385 { 383 386 LOG(VB_GENERAL, LOG_INFO, "Connected to master for reschedule"); 384 ScheduledRecording::signalChange(-1); 387 ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(), 388 "MythBackendCommand"); 385 389 ok = true; 386 390 } 387 391 else -
mythtv/programs/mythbackend/mainserver.cpp
diff --git a/mythtv/programs/mythbackend/mainserver.cpp b/mythtv/programs/mythbackend/mainserver.cpp index ff002b4..802232c 100644
a b void MainServer::ProcessRequestWork(MythSocket *sock) 525 525 } 526 526 else if (command == "RESCHEDULE_RECORDINGS") 527 527 { 528 if (tokens.size() != 2) 529 LOG(VB_GENERAL, LOG_ERR, "Bad RESCHEDULE_RECORDINGS request"); 530 else 531 HandleRescheduleRecordings(tokens[1].toInt(), pbs); 528 listline.pop_front(); 529 HandleRescheduleRecordings(listline, pbs); 532 530 } 533 531 else if (command == "FORGET_RECORDING") 534 532 { … … void MainServer::customEvent(QEvent *e) 1007 1005 1008 1006 if (me->Message().left(21) == "RESCHEDULE_RECORDINGS" && m_sched) 1009 1007 { 1010 QStringList tokens = me->Message() 1011 .split(" ", QString::SkipEmptyParts); 1012 1013 if (tokens.size() != 2) 1014 { 1015 LOG(VB_GENERAL, LOG_ERR, "Bad RESCHEDULE_RECORDINGS message"); 1016 return; 1017 } 1018 1019 int recordid = tokens[1].toInt(); 1020 m_sched->Reschedule(recordid); 1008 QStringList request = me->ExtraDataList(); 1009 m_sched->Reschedule(request); 1021 1010 return; 1022 1011 } 1023 1012 … … void MainServer::HandleAnnounce(QStringList &slist, QStringList commands, 1444 1433 } 1445 1434 1446 1435 if (!wasAsleep && m_sched) 1447 m_sched->Reschedule (0);1436 m_sched->ReschedulePlace("SlaveConnected"); 1448 1437 1449 1438 QString message = QString("LOCAL_SLAVE_BACKEND_ONLINE %2") 1450 1439 .arg(commands[2]); … … void MainServer::DoDeleteThread(DeleteStruct *ds) 2001 1990 2002 1991 DoDeleteInDB(ds); 2003 1992 2004 if (pginfo.GetRecordingGroup() != "LiveTV")2005 ScheduledRecording::signalChange(0);2006 2007 1993 deletelock.unlock(); 2008 1994 2009 1995 if (slowDeletes && fd >= 0) … … void MainServer::DoHandleDeleteRecording( 2513 2499 if (forgetHistory) 2514 2500 recinfo.ForgetHistory(); 2515 2501 else if (m_sched) 2516 m_sched->Reschedule (0);2502 m_sched->RescheduleCheck(recinfo, "DoHandleDelete1"); 2517 2503 QStringList outputlist( QString::number(0) ); 2518 2504 SendResponse(pbssock, outputlist); 2519 2505 return; … … void MainServer::DoHandleDeleteRecording( 2534 2520 else if (m_sched && 2535 2521 recinfo.GetRecordingGroup() != "Deleted" && 2536 2522 recinfo.GetRecordingGroup() != "LiveTV") 2537 m_sched->Reschedule (0);2523 m_sched->RescheduleCheck(recinfo, "DoHandleDelete2"); 2538 2524 2539 2525 if (pbssock) 2540 2526 { … … void MainServer::DoHandleDeleteRecording( 2594 2580 else if (m_sched && 2595 2581 recinfo.GetRecordingGroup() != "Deleted" && 2596 2582 recinfo.GetRecordingGroup() != "LiveTV") 2597 m_sched->Reschedule (0);2583 m_sched->RescheduleCheck(recinfo, "DoHandleDelete3"); 2598 2584 2599 2585 // Tell MythTV frontends that the recording list needs to be updated. 2600 2586 if (fileExists || !recinfo.GetFilesize() || forceMetadataDelete) … … void MainServer::DoHandleUndeleteRecording( 2651 2637 SendResponse(pbssock, outputlist); 2652 2638 } 2653 2639 2654 void MainServer::HandleRescheduleRecordings(int recordid, PlaybackSock *pbs) 2640 void MainServer::HandleRescheduleRecordings(const QStringList &request, 2641 PlaybackSock *pbs) 2655 2642 { 2656 2643 QStringList result; 2657 2644 if (m_sched) 2658 2645 { 2659 m_sched->Reschedule(re cordid);2646 m_sched->Reschedule(request); 2660 2647 result = QStringList( QString::number(1) ); 2661 2648 } 2662 2649 else … … void MainServer::HandleGetPendingRecordings(PlaybackSock *pbs, 3151 3138 record->m_recordID = recordid; 3152 3139 if (record->Load() && 3153 3140 record->m_searchType == kManualSearch) 3154 HandleRescheduleRecordings(recordid, NULL); 3141 m_sched->RescheduleMatch(recordid, 0, 0, QDateTime(), 3142 "Speculation"); 3155 3143 delete record; 3156 3144 } 3157 3145 query.prepare("DELETE FROM program WHERE manualid = :RECID;"); … … void MainServer::HandleLockTuner(PlaybackSock *pbs, int cardid) 3413 3401 << query.value(2).toString(); 3414 3402 3415 3403 if (m_sched) 3416 m_sched->Reschedule (0);3404 m_sched->ReschedulePlace("LockTuner"); 3417 3405 3418 3406 SendResponse(pbssock, strlist); 3419 3407 return; … … void MainServer::HandleFreeTuner(int cardid, PlaybackSock *pbs) 3459 3447 LOG(VB_GENERAL, LOG_INFO, msg); 3460 3448 3461 3449 if (m_sched) 3462 m_sched->Reschedule (0);3450 m_sched->ReschedulePlace("FreeTuner"); 3463 3451 3464 3452 strlist << "OK"; 3465 3453 } … … void MainServer::HandleSlaveDisconnectedEvent(const MythEvent &event) 6224 6212 m_sched->SlaveDisconnected(event.ExtraData(i).toUInt()); 6225 6213 6226 6214 if (needsReschedule) 6227 m_sched->Reschedule (0);6215 m_sched->ReschedulePlace("SlaveDisconnected"); 6228 6216 } 6229 6217 } 6230 6218 -
mythtv/programs/mythbackend/mainserver.h
diff --git a/mythtv/programs/mythbackend/mainserver.h b/mythtv/programs/mythbackend/mainserver.h index 0349f8e..e27c9ae 100644
a b class MainServer : public QObject, public MythSocketCBs 163 163 void HandleUndeleteRecording(QStringList &slist, PlaybackSock *pbs); 164 164 void DoHandleUndeleteRecording(RecordingInfo &recinfo, PlaybackSock *pbs); 165 165 void HandleForgetRecording(QStringList &slist, PlaybackSock *pbs); 166 void HandleRescheduleRecordings(int recordid, PlaybackSock *pbs); 166 void HandleRescheduleRecordings(const QStringList &request, 167 PlaybackSock *pbs); 167 168 void HandleGoToSleep(PlaybackSock *pbs); 168 169 void HandleQueryFreeSpace(PlaybackSock *pbs, bool allBackends); 169 170 void HandleQueryFreeSpaceSummary(PlaybackSock *pbs); -
mythtv/programs/mythbackend/scheduler.cpp
diff --git a/mythtv/programs/mythbackend/scheduler.cpp b/mythtv/programs/mythbackend/scheduler.cpp index 23db70c..827aa5a 100644
a b static bool comp_redundant(RecordingInfo *a, RecordingInfo *b) 287 287 Qt::CaseInsensitive); 288 288 if (cmp != 0) 289 289 return cmp < 0; 290 return a->GetRecordingStatus() < b->GetRecordingStatus(); 290 if (a->GetRecordingStatus() != b->GetRecordingStatus()) 291 return a->GetRecordingStatus() < b->GetRecordingStatus(); 292 cmp = a->GetChanNum().compare(b->GetChanNum(), Qt::CaseInsensitive); 293 return cmp < 0; 291 294 } 292 295 293 296 static bool comp_recstart(RecordingInfo *a, RecordingInfo *b) … … bool Scheduler::FillRecordList(void) 400 403 401 404 /** \fn Scheduler::FillRecordListFromDB(int) 402 405 * \param recordid Record ID of recording that has changed, 403 * or -1if anything might have been changed.406 * or 0 if anything might have been changed. 404 407 */ 405 void Scheduler::FillRecordListFromDB( int recordid)408 void Scheduler::FillRecordListFromDB(uint recordid) 406 409 { 407 410 struct timeval fillstart, fillend; 408 float matchTime, placeTime;411 float matchTime, checkTime, placeTime; 409 412 410 413 MSqlQuery query(dbConn); 411 414 QString thequery; 412 415 QString where = ""; 413 416 414 417 // This will cause our temp copy of recordmatch to be empty 415 if (recordid == -1)418 if (recordid == 0) 416 419 where = "WHERE recordid IS NULL "; 417 420 418 421 thequery = QString("CREATE TEMPORARY TABLE recordmatch ") + … … void Scheduler::FillRecordListFromDB(int recordid) 449 452 QMutexLocker locker(&schedLock); 450 453 451 454 gettimeofday(&fillstart, NULL); 452 UpdateMatches(recordid );455 UpdateMatches(recordid, 0, 0, QDateTime()); 453 456 gettimeofday(&fillend, NULL); 454 457 matchTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 455 458 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 456 459 460 LOG(VB_SCHEDULE, LOG_INFO, "CreateTempTables..."); 461 CreateTempTables(); 462 463 gettimeofday(&fillstart, NULL); 464 LOG(VB_SCHEDULE, LOG_INFO, "UpdateDuplicates..."); 465 UpdateDuplicates(); 466 gettimeofday(&fillend, NULL); 467 checkTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 468 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 469 457 470 gettimeofday(&fillstart, NULL); 458 471 FillRecordList(); 459 472 gettimeofday(&fillend, NULL); 460 473 placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 461 474 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 462 475 476 LOG(VB_SCHEDULE, LOG_INFO, "DeleteTempTables..."); 477 DeleteTempTables(); 478 463 479 MSqlQuery queryDrop(dbConn); 464 480 queryDrop.prepare("DROP TABLE recordmatch;"); 465 481 if (!queryDrop.exec()) … … void Scheduler::FillRecordListFromDB(int recordid) 469 485 } 470 486 471 487 QString msg; 472 msg.sprintf("Speculative scheduled %d items in " 473 "%.1f = %.2f match + %.2f place", (int)reclist.size(), 474 matchTime + placeTime, matchTime, placeTime); 488 msg.sprintf("Speculative scheduled %d items in %.1f " 489 "= %.2f match + %.2f check + %.2f place", 490 (int)reclist.size(), 491 matchTime + checkTime + placeTime, 492 matchTime, checkTime, placeTime); 475 493 LOG(VB_GENERAL, LOG_INFO, msg); 476 494 } 477 495 … … void Scheduler::FillRecordListFromMaster(void) 490 508 491 509 void Scheduler::PrintList(RecList &list, bool onlyFutureRecordings) 492 510 { 493 if (!VERBOSE_LEVEL_CHECK(VB_SCHEDULE, LOG_ INFO))511 if (!VERBOSE_LEVEL_CHECK(VB_SCHEDULE, LOG_DEBUG)) 494 512 return; 495 513 496 514 QDateTime now = QDateTime::currentDateTime(); … … void Scheduler::PrintList(RecList &list, bool onlyFutureRecordings) 518 536 519 537 void Scheduler::PrintRec(const RecordingInfo *p, const char *prefix) 520 538 { 521 if (!VERBOSE_LEVEL_CHECK(VB_SCHEDULE, LOG_ INFO))539 if (!VERBOSE_LEVEL_CHECK(VB_SCHEDULE, LOG_DEBUG)) 522 540 return; 523 541 524 542 QString outstr; … … void Scheduler::UpdateRecStatus(RecordingInfo *pginfo) 593 611 p->AddHistory(false); 594 612 if (resched) 595 613 { 596 reschedQueue.enqueue(0);614 EnqueueCheck(*p, "UpdateRecStatus1"); 597 615 reschedWait.wakeOne(); 598 616 } 599 617 else … … void Scheduler::UpdateRecStatus(uint cardid, uint chanid, 643 661 p->AddHistory(false); 644 662 if (resched) 645 663 { 646 reschedQueue.enqueue(0);664 EnqueueCheck(*p, "UpdateRecStatus2"); 647 665 reschedWait.wakeOne(); 648 666 } 649 667 else … … bool Scheduler::ChangeRecordingEnd(RecordingInfo *oldp, RecordingInfo *newp) 665 683 return false; 666 684 667 685 RecordingType oldrectype = oldp->GetRecordingRuleType(); 668 int oldrecordid = oldp->GetRecordingRuleID();686 uint oldrecordid = oldp->GetRecordingRuleID(); 669 687 QDateTime oldrecendts = oldp->GetRecordingEndTime(); 670 688 671 689 oldp->SetRecordingRuleType(newp->GetRecordingRuleType()); … … bool Scheduler::TryAnotherShowing(RecordingInfo *p, bool samePriority, 1225 1243 1226 1244 void Scheduler::SchedNewRecords(void) 1227 1245 { 1228 LOG(VB_SCHEDULE, LOG_INFO, "Scheduling:"); 1229 1230 if (VERBOSE_LEVEL_CHECK(VB_SCHEDULE, LOG_INFO)) 1246 if (VERBOSE_LEVEL_CHECK(VB_SCHEDULE, LOG_DEBUG)) 1231 1247 { 1232 LOG(VB_SCHEDULE, LOG_ INFO,1248 LOG(VB_SCHEDULE, LOG_DEBUG, 1233 1249 "+ = schedule this showing to be recorded"); 1234 LOG(VB_SCHEDULE, LOG_ INFO,1250 LOG(VB_SCHEDULE, LOG_DEBUG, 1235 1251 "# = could not schedule this showing, retry later"); 1236 LOG(VB_SCHEDULE, LOG_ INFO,1252 LOG(VB_SCHEDULE, LOG_DEBUG, 1237 1253 "! = conflict caused by this showing"); 1238 LOG(VB_SCHEDULE, LOG_ INFO,1254 LOG(VB_SCHEDULE, LOG_DEBUG, 1239 1255 "/ = retry this showing, same priority pass"); 1240 LOG(VB_SCHEDULE, LOG_ INFO,1256 LOG(VB_SCHEDULE, LOG_DEBUG, 1241 1257 "? = retry this showing, lower priority pass"); 1242 LOG(VB_SCHEDULE, LOG_ INFO,1258 LOG(VB_SCHEDULE, LOG_DEBUG, 1243 1259 "> = try another showing for this program"); 1244 LOG(VB_SCHEDULE, LOG_ INFO,1260 LOG(VB_SCHEDULE, LOG_DEBUG, 1245 1261 "% = found another showing, same priority required"); 1246 LOG(VB_SCHEDULE, LOG_ INFO,1262 LOG(VB_SCHEDULE, LOG_DEBUG, 1247 1263 "$ = found another showing, lower priority allowed"); 1248 LOG(VB_SCHEDULE, LOG_ INFO,1264 LOG(VB_SCHEDULE, LOG_DEBUG, 1249 1265 "- = unschedule a showing in favor of another one"); 1250 1266 } 1251 1267 … … void Scheduler::GetAllScheduled(QStringList &strList) 1613 1629 } 1614 1630 } 1615 1631 1616 void Scheduler::Reschedule( int recordid)1632 void Scheduler::Reschedule(const QStringList &request) 1617 1633 { 1618 1634 QMutexLocker locker(&schedLock); 1619 1620 if (recordid == -1) 1621 reschedQueue.clear(); 1622 1623 if (recordid != 0 || reschedQueue.empty()) 1624 reschedQueue.enqueue(recordid); 1625 1635 reschedQueue.enqueue(request); 1626 1636 reschedWait.wakeOne(); 1627 1637 } 1628 1638 … … void Scheduler::AddRecording(const RecordingInfo &pi) 1661 1671 new_pi->GetRecordingRule(); 1662 1672 1663 1673 // Trigger reschedule.. 1664 reschedQueue.enqueue(pi.GetRecordingRuleID()); 1674 EnqueueMatch(pi.GetRecordingRuleID(), 0, 0, QDateTime(), 1675 QString("AddRecording %1").arg(pi.GetTitle())); 1665 1676 reschedWait.wakeOne(); 1666 1677 } 1667 1678 … … void Scheduler::OldRecordedFixups(void) 1743 1754 // during normal processing. 1744 1755 query.prepare("UPDATE oldrecorded SET future = 0 " 1745 1756 "WHERE future > 0 AND " 1746 " endtime < (NOW() - INTERVAL 8 HOUR)");1757 " endtime < (NOW() - INTERVAL 475 MINUTE)"); 1747 1758 if (!query.exec()) 1748 1759 MythDB::DBError("UpdateFuture", query); 1749 1760 } … … void Scheduler::run(void) 1768 1779 QMutexLocker lockit(&schedLock); 1769 1780 1770 1781 reschedQueue.clear(); 1771 reschedQueue.enqueue(-1);1782 EnqueueMatch(0, 0, 0, QDateTime(), "SchedulerInit"); 1772 1783 1773 1784 int prerollseconds = 0; 1774 1785 int wakeThreshold = 300; … … int Scheduler::CalcTimeToNextHandleRecordingEvent( 1992 2003 return min(msecs, max_sleep); 1993 2004 } 1994 2005 2006 void Scheduler::ResetDuplicates(uint recordid, uint findid, 2007 const QString &title, const QString &subtitle, 2008 const QString &descrip, 2009 const QString &programid) 2010 { 2011 MSqlQuery query(dbConn); 2012 QString filterClause; 2013 MSqlBindings bindings; 2014 2015 // "**any**" is special value set in ProgLister::DeleteOldSeries() 2016 if (programid != "**any**") 2017 { 2018 filterClause = "AND (0 "; 2019 if (!subtitle.isEmpty()) 2020 { 2021 // Need to check both for kDupCheckSubThenDesc 2022 filterClause += "OR p.subtitle = :SUBTITLE " 2023 "OR p.description = :SUBTITLE "; 2024 bindings[":SUBTITLE"] = subtitle; 2025 } 2026 if (!descrip.isEmpty()) 2027 { 2028 // Need to check both for kDupCheckSubThenDesc 2029 filterClause += "OR p.description = :DESCRIP " 2030 "OR p.subtitle = :DESCRIP "; 2031 bindings[":DESCRIP"] = descrip; 2032 } 2033 if (!programid.isEmpty()) 2034 { 2035 filterClause += "OR p.programid = :PROGRAMID "; 2036 bindings[":PROGRAMID"] = programid; 2037 } 2038 filterClause += ") "; 2039 } 2040 2041 query.prepare(QString("UPDATE recordmatch rm " 2042 "INNER JOIN %1 r " 2043 " ON rm.recordid = r.recordid " 2044 "INNER JOIN program p " 2045 " ON rm.chanid = p.chanid " 2046 " AND rm.starttime = p.starttime " 2047 " AND rm.manualid = p.manualid " 2048 "SET oldrecduplicate = -1 " 2049 "WHERE p.title = :TITLE" 2050 " AND p.generic = 0 " 2051 " AND r.type NOT IN (%2, %3, %4) ") 2052 .arg(recordTable) 2053 .arg(kSingleRecord) 2054 .arg(kOverrideRecord) 2055 .arg(kDontRecord) 2056 + filterClause); 2057 query.bindValue(":TITLE", title); 2058 MSqlBindings::const_iterator it; 2059 for (it = bindings.begin(); it != bindings.end(); ++it) 2060 query.bindValue(it.key(), it.value()); 2061 if (!query.exec()) 2062 MythDB::DBError("ResetDuplicates1", query); 2063 2064 if (findid && programid != "**any**") 2065 { 2066 query.prepare("UPDATE recordmatch rm " 2067 "SET oldrecduplicate = -1 " 2068 "WHERE rm.recordid = :RECORDID " 2069 " AND rm.findid = :FINDID"); 2070 query.bindValue("RECORDID", recordid); 2071 query.bindValue("FINDID", findid); 2072 if (!query.exec()) 2073 MythDB::DBError("ResetDuplicates2", query); 2074 } 2075 } 2076 1995 2077 bool Scheduler::HandleReschedule(void) 1996 2078 { 1997 2079 // We might have been inactive for a long time, so make 1998 2080 // sure our DB connection is fresh before continuing. 1999 2081 dbConn = MSqlQuery::SchedCon(); 2000 2082 2001 struct timeval fillstart; 2083 struct timeval fillstart, fillend; 2084 float matchTime, checkTime, placeTime; 2085 2002 2086 gettimeofday(&fillstart, NULL); 2003 2087 QString msg; 2004 2088 bool deleteFuture = false; 2089 bool runCheck = false; 2005 2090 2006 2091 while (!reschedQueue.empty()) 2007 2092 { 2008 int recordid = reschedQueue.dequeue(); 2093 QStringList request = reschedQueue.dequeue(); 2094 QStringList tokens; 2095 if (request.size() >= 1) 2096 tokens = request[0].split(' ', QString::SkipEmptyParts); 2009 2097 2010 LOG(VB_GENERAL, LOG_INFO, QString("Reschedule requested for id %1.") 2011 .arg(recordid)); 2098 if (request.size() < 1 || tokens.size() < 1) 2099 { 2100 LOG(VB_GENERAL, LOG_ERR, "Empty Reschedule request received"); 2101 return false; 2102 } 2012 2103 2013 if (recordid != 0) 2104 LOG(VB_GENERAL, LOG_INFO, QString("Reschedule requested for %1 %2") 2105 .arg(request[0]).arg((request.size() > 1) ? request[1] : "")); 2106 2107 if (tokens[0] == "MATCH") 2014 2108 { 2015 if (recordid == -1) 2016 reschedQueue.clear(); 2109 if (tokens.size() < 5) 2110 { 2111 LOG(VB_GENERAL, LOG_ERR, 2112 QString("Invalid RescheduleMatch request received (%1)") 2113 .arg(request[0])); 2114 continue; 2115 } 2017 2116 2117 uint recordid = tokens[1].toUInt(); 2118 uint sourceid = tokens[2].toUInt(); 2119 uint mplexid = tokens[3].toUInt(); 2120 QDateTime maxstarttime = 2121 QDateTime::fromString(tokens[4], Qt::ISODate); 2018 2122 deleteFuture = true; 2123 runCheck = true; 2019 2124 schedLock.unlock(); 2020 2125 recordmatchLock.lock(); 2021 UpdateMatches(recordid );2126 UpdateMatches(recordid, sourceid, mplexid, maxstarttime); 2022 2127 recordmatchLock.unlock(); 2023 2128 schedLock.lock(); 2024 2129 } 2130 else if (tokens[0] == "CHECK") 2131 { 2132 if (tokens.size() < 4 || request.size() < 5) 2133 { 2134 LOG(VB_GENERAL, LOG_ERR, 2135 QString("Invalid RescheduleCheck request received (%1)") 2136 .arg(request[0])); 2137 continue; 2138 } 2139 2140 uint recordid = tokens[2].toUInt(); 2141 uint findid = tokens[3].toUInt(); 2142 QString title = request[1]; 2143 QString subtitle = request[2]; 2144 QString descrip = request[3]; 2145 QString programid = request[4]; 2146 runCheck = true; 2147 schedLock.unlock(); 2148 recordmatchLock.lock(); 2149 ResetDuplicates(recordid, findid, title, subtitle, descrip, 2150 programid); 2151 recordmatchLock.unlock(); 2152 schedLock.lock(); 2153 } 2154 else if (tokens[0] != "PLACE") 2155 { 2156 LOG(VB_GENERAL, LOG_ERR, 2157 QString("Unknown Reschedule request received (%1)") 2158 .arg(request[0])); 2159 } 2025 2160 } 2026 2161 2027 2162 // Delete future oldrecorded entries that no longer … … bool Scheduler::HandleReschedule(void) 2039 2174 MythDB::DBError("DeleteFuture", query); 2040 2175 } 2041 2176 2042 struct timeval fillend;2043 2177 gettimeofday(&fillend, NULL); 2178 matchTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 2179 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 2044 2180 2045 float matchTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 2046 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 2181 LOG(VB_SCHEDULE, LOG_INFO, "CreateTempTables..."); 2182 CreateTempTables(); 2183 2184 gettimeofday(&fillstart, NULL); 2185 if (runCheck) 2186 { 2187 LOG(VB_SCHEDULE, LOG_INFO, "UpdateDuplicates..."); 2188 UpdateDuplicates(); 2189 } 2190 gettimeofday(&fillend, NULL); 2191 checkTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 2192 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 2047 2193 2048 2194 gettimeofday(&fillstart, NULL); 2049 2195 bool worklistused = FillRecordList(); 2050 2196 gettimeofday(&fillend, NULL); 2197 placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 2198 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 2199 2200 LOG(VB_SCHEDULE, LOG_INFO, "DeleteTempTables..."); 2201 DeleteTempTables(); 2202 2051 2203 if (worklistused) 2052 2204 { 2053 2205 UpdateNextRecord(); … … bool Scheduler::HandleReschedule(void) 2056 2208 else 2057 2209 { 2058 2210 LOG(VB_GENERAL, LOG_INFO, "Reschedule interrupted, will retry"); 2059 reschedQueue.enqueue(0);2211 EnqueuePlace("Interrupted"); 2060 2212 return false; 2061 2213 } 2062 2214 2063 float placeTime = ((fillend.tv_sec - fillstart.tv_sec ) * 1000000 + 2064 (fillend.tv_usec - fillstart.tv_usec)) / 1000000.0; 2065 2066 msg.sprintf("Scheduled %d items in %.1f = %.2f match + %.2f place", 2067 (int)reclist.size(), matchTime + placeTime, matchTime, 2068 placeTime); 2215 msg.sprintf("Scheduled %d items in %.1f " 2216 "= %.2f match + %.2f check + %.2f place", 2217 (int)reclist.size(), matchTime + checkTime + placeTime, 2218 matchTime, checkTime, placeTime); 2069 2219 LOG(VB_GENERAL, LOG_INFO, msg); 2070 2220 2071 2221 fsInfoCacheFillTime = QDateTime::currentDateTime().addSecs(-1000); … … void Scheduler::HandleWakeSlave(RecordingInfo &ri, int prerollseconds) 2216 2366 .arg(nexttv->GetHostName()).arg(ri.GetTitle())); 2217 2367 2218 2368 if (!WakeUpSlave(nexttv->GetHostName())) 2219 reschedQueue.enqueue(0);2369 EnqueuePlace("HandleWakeSlave1"); 2220 2370 } 2221 2371 else if ((nexttv->IsWaking()) && 2222 2372 ((secsleft - prerollseconds) < 210) && … … void Scheduler::HandleWakeSlave(RecordingInfo &ri, int prerollseconds) 2229 2379 .arg(nexttv->GetHostName())); 2230 2380 2231 2381 if (!WakeUpSlave(nexttv->GetHostName(), false)) 2232 reschedQueue.enqueue(0);2382 EnqueuePlace("HandleWakeSlave2"); 2233 2383 } 2234 2384 else if ((nexttv->IsWaking()) && 2235 2385 ((secsleft - prerollseconds) < 150) && … … void Scheduler::HandleWakeSlave(RecordingInfo &ri, int prerollseconds) 2249 2399 (*it)->SetSleepStatus(sStatus_Undefined); 2250 2400 } 2251 2401 2252 reschedQueue.enqueue(0);2402 EnqueuePlace("HandleWakeSlave3"); 2253 2403 } 2254 2404 } 2255 2405 … … bool Scheduler::HandleRecording( 2287 2437 livetvTime = (livetvTime < nextrectime) ? 2288 2438 nextrectime : livetvTime; 2289 2439 2290 reschedQueue.enqueue(0);2440 EnqueuePlace("PrepareToRecord"); 2291 2441 } 2292 2442 } 2293 2443 … … bool Scheduler::HandleRecording( 2370 2520 enc->SetSleepStatus(sStatus_Undefined); 2371 2521 } 2372 2522 2373 reschedQueue.enqueue(0);2523 EnqueuePlace("SlaveNotAwake"); 2374 2524 } 2375 2525 2376 2526 return false; … … void Scheduler::WakeUpSlaves(void) 3029 3179 } 3030 3180 } 3031 3181 3032 void Scheduler::UpdateManuals( int recordid)3182 void Scheduler::UpdateManuals(uint recordid) 3033 3183 { 3034 3184 MSqlQuery query(dbConn); 3035 3185 … … void Scheduler::UpdateManuals(int recordid) 3108 3258 if (weekday && startdt.date().dayOfWeek() >= 6) 3109 3259 continue; 3110 3260 3111 query.prepare("REPLACE INTO program (chanid, starttime,endtime,"3112 " title, subtitle,manualid) "3113 "VALUES (:CHANID, :STARTTIME,:ENDTIME,:TITLE,"3114 " :SUBTITLE, :RECORDID)");3261 query.prepare("REPLACE INTO program (chanid, starttime, endtime," 3262 " title, subtitle, manualid, generic) " 3263 "VALUES (:CHANID, :STARTTIME, :ENDTIME, :TITLE," 3264 " :SUBTITLE, :RECORDID, 1)"); 3115 3265 query.bindValue(":CHANID", chanidlist[i]); 3116 3266 query.bindValue(":STARTTIME", startdt); 3117 3267 query.bindValue(":ENDTIME", startdt.addSecs(duration * 60)); … … void Scheduler::UpdateManuals(int recordid) 3128 3278 } 3129 3279 } 3130 3280 3131 void Scheduler::BuildNewRecordsQueries( int recordid, QStringList &from,3281 void Scheduler::BuildNewRecordsQueries(uint recordid, QStringList &from, 3132 3282 QStringList &where, 3133 3283 MSqlBindings &bindings) 3134 3284 { … … void Scheduler::BuildNewRecordsQueries(int recordid, QStringList &from, 3138 3288 3139 3289 query = QString("SELECT recordid,search,subtitle,description " 3140 3290 "FROM %1 WHERE search <> %2 AND " 3141 "(recordid = %3 OR %4 = -1) ")3291 "(recordid = %3 OR %4 = 0) ") 3142 3292 .arg(recordTable).arg(kNoSearch).arg(recordid).arg(recordid); 3143 3293 3144 3294 result.prepare(query); … … void Scheduler::BuildNewRecordsQueries(int recordid, QStringList &from, 3231 3381 count++; 3232 3382 } 3233 3383 3234 if (recordid == -1|| from.count() == 0)3384 if (recordid == 0 || from.count() == 0) 3235 3385 { 3236 3386 QString recidmatch = ""; 3237 if (recordid != -1)3387 if (recordid != 0) 3238 3388 recidmatch = "RECTABLE.recordid = :NRRECORDID AND "; 3239 3389 QString s1 = recidmatch + 3240 3390 "RECTABLE.search = :NRST AND " … … void Scheduler::BuildNewRecordsQueries(int recordid, QStringList &from, 3253 3403 from << ""; 3254 3404 where << s2; 3255 3405 bindings[":NRST"] = kNoSearch; 3256 if (recordid != -1)3406 if (recordid != 0) 3257 3407 bindings[":NRRECORDID"] = recordid; 3258 3408 } 3259 3409 } 3260 3410 3261 void Scheduler::UpdateMatches(int recordid) { 3262 struct timeval dbstart, dbend; 3411 static QString progdupinit = QString( 3412 "(CASE " 3413 " WHEN RECTABLE.type IN (%1, %2, %3) THEN 0 " 3414 " WHEN RECTABLE.type IN (%4, %5, %6) THEN -1 " 3415 " ELSE (program.generic - 1) " 3416 " END) ") 3417 .arg(kSingleRecord).arg(kOverrideRecord).arg(kDontRecord) 3418 .arg(kFindOneRecord).arg(kFindDailyRecord).arg(kFindWeeklyRecord); 3263 3419 3264 if (recordid == 0) 3265 return; 3420 static QString progfindid = QString( 3421 "(CASE RECTABLE.type " 3422 " WHEN %1 " 3423 " THEN RECTABLE.findid " 3424 " WHEN %2 " 3425 " THEN to_days(date_sub(program.starttime, interval " 3426 " time_format(RECTABLE.findtime, '%H:%i') hour_minute)) " 3427 " WHEN %3 " 3428 " THEN floor((to_days(date_sub(program.starttime, interval " 3429 " time_format(RECTABLE.findtime, '%H:%i') hour_minute)) - " 3430 " RECTABLE.findday)/7) * 7 + RECTABLE.findday " 3431 " WHEN %4 " 3432 " THEN RECTABLE.findid " 3433 " ELSE 0 " 3434 " END) ") 3435 .arg(kFindOneRecord) 3436 .arg(kFindDailyRecord) 3437 .arg(kFindWeeklyRecord) 3438 .arg(kOverrideRecord); 3439 3440 void Scheduler::UpdateMatches(uint recordid, uint sourceid, uint mplexid, 3441 const QDateTime maxstarttime) 3442 { 3443 struct timeval dbstart, dbend; 3266 3444 3267 3445 MSqlQuery query(dbConn); 3446 MSqlBindings bindings; 3447 QString deleteClause; 3448 QString filterClause = QString(" AND program.endtime > " 3449 "(NOW() - INTERVAL 480 MINUTE)"); 3268 3450 3269 if (recordid == -1) 3270 query.prepare("DELETE FROM recordmatch"); 3271 else 3451 if (recordid) 3272 3452 { 3273 query.prepare("DELETE FROM recordmatch WHERE recordid = :RECORDID");3274 query.bindValue(":RECORDID", recordid);3453 deleteClause += " AND recordmatch.recordid = :RECORDID"; 3454 bindings[":RECORDID"] = recordid; 3275 3455 } 3276 3277 if (!query.exec()) 3456 if (sourceid) 3278 3457 { 3279 MythDB::DBError("UpdateMatches", query); 3280 return; 3458 deleteClause += " AND channel.sourceid = :SOURCEID"; 3459 filterClause += " AND channel.sourceid = :SOURCEID"; 3460 bindings[":SOURCEID"] = sourceid; 3281 3461 } 3282 3283 if (recordid == -1) 3284 query.prepare("DELETE FROM program WHERE manualid <> 0"); 3285 else 3462 if (mplexid) 3463 { 3464 deleteClause += " AND channel.mplexid = :MPLEXID"; 3465 filterClause += " AND channel.mplexid = :MPLEXID"; 3466 bindings[":MPLEXID"] = mplexid; 3467 } 3468 if (maxstarttime.isValid()) 3286 3469 { 3287 query.prepare("DELETE FROM program WHERE manualid = :RECORDID"); 3288 query.bindValue(":RECORDID", recordid); 3470 deleteClause += " AND recordmatch.starttime <= :MAXSTARTTIME"; 3471 filterClause += " AND program.starttime <= :MAXSTARTTIME"; 3472 bindings[":MAXSTARTTIME"] = maxstarttime; 3289 3473 } 3474 3475 query.prepare(QString("DELETE recordmatch FROM recordmatch, channel " 3476 "WHERE recordmatch.chanid = channel.chanid") 3477 + deleteClause); 3478 MSqlBindings::const_iterator it; 3479 for (it = bindings.begin(); it != bindings.end(); ++it) 3480 query.bindValue(it.key(), it.value()); 3290 3481 if (!query.exec()) 3291 3482 { 3292 MythDB::DBError("UpdateMatches ", query);3483 MythDB::DBError("UpdateMatches1", query); 3293 3484 return; 3294 3485 } 3486 if (recordid) 3487 bindings.remove(":RECORDID"); 3295 3488 3296 QString filterClause;3297 3489 query.prepare("SELECT filterid, clause FROM recordfilter " 3298 3490 "WHERE filterid >= 0 AND filterid < :NUMFILTERS AND " 3299 3491 " TRIM(clause) <> ''"); 3300 3492 query.bindValue(":NUMFILTERS", RecordingRule::kNumFilters); 3301 3493 if (!query.exec()) 3302 3494 { 3303 MythDB::DBError("UpdateMatches ", query);3495 MythDB::DBError("UpdateMatches2", query); 3304 3496 return; 3305 3497 } 3306 3498 while (query.next()) … … void Scheduler::UpdateMatches(int recordid) { 3315 3507 query.bindValue(":FINDONE", kFindOneRecord); 3316 3508 if (!query.exec()) 3317 3509 { 3318 MythDB::DBError("UpdateMatches ", query);3510 MythDB::DBError("UpdateMatches3", query); 3319 3511 return; 3320 3512 } 3321 3513 else if (query.size()) … … void Scheduler::UpdateMatches(int recordid) { 3327 3519 query.bindValue(":FINDID", findtoday); 3328 3520 query.bindValue(":FINDONE", kFindOneRecord); 3329 3521 if (!query.exec()) 3330 MythDB::DBError("UpdateMatches ", query);3522 MythDB::DBError("UpdateMatches4", query); 3331 3523 } 3332 3524 3333 3525 int clause; 3334 3526 QStringList fromclauses, whereclauses; 3335 MSqlBindings bindings;3336 3527 3337 3528 BuildNewRecordsQueries(recordid, fromclauses, whereclauses, bindings); 3338 3529 … … void Scheduler::UpdateMatches(int recordid) { 3349 3540 for (clause = 0; clause < fromclauses.count(); ++clause) 3350 3541 { 3351 3542 QString query = QString( 3352 "REPLACE INTO recordmatch (recordid, chanid, starttime, manualid) " 3543 "REPLACE INTO recordmatch (recordid, chanid, starttime, manualid, " 3544 " oldrecduplicate, findid) " 3353 3545 "SELECT RECTABLE.recordid, program.chanid, program.starttime, " 3354 " IF(search = %1, RECTABLE.recordid, 0) ").arg(kManualSearch) + QString( 3546 " IF(search = %1, RECTABLE.recordid, 0), ").arg(kManualSearch) + 3547 progdupinit + ", " + progfindid + QString( 3355 3548 "FROM (RECTABLE, program INNER JOIN channel " 3356 3549 " ON channel.chanid = program.chanid) ") + fromclauses[clause] + QString( 3357 3550 " WHERE ") + whereclauses[clause] + … … void Scheduler::UpdateMatches(int recordid) { 3395 3588 .arg(kWeekslotRecord) 3396 3589 .arg(kNotRecording); 3397 3590 3398 while (1) 3399 { 3400 int i = query.indexOf("RECTABLE"); 3401 if (i == -1) break; 3402 query = query.replace(i, strlen("RECTABLE"), recordTable); 3403 } 3591 query.replace("RECTABLE", recordTable); 3404 3592 3405 3593 LOG(VB_SCHEDULE, LOG_INFO, QString(" |-- Start DB Query %1...") 3406 3594 .arg(clause)); … … void Scheduler::UpdateMatches(int recordid) { 3409 3597 MSqlQuery result(dbConn); 3410 3598 result.prepare(query); 3411 3599 3412 MSqlBindings::const_iterator it;3413 3600 for (it = bindings.begin(); it != bindings.end(); ++it) 3414 3601 { 3415 3602 if (query.contains(it.key())) … … void Scheduler::UpdateMatches(int recordid) { 3435 3622 LOG(VB_SCHEDULE, LOG_INFO, " +-- Done."); 3436 3623 } 3437 3624 3625 void Scheduler::CreateTempTables(void) 3626 { 3627 MSqlQuery result(dbConn); 3628 3629 if (recordTable == "record") 3630 { 3631 result.prepare("DROP TABLE IF EXISTS sched_temp_record;"); 3632 if (!result.exec()) 3633 { 3634 MythDB::DBError("Dropping sched_temp_record table", result); 3635 return; 3636 } 3637 result.prepare("CREATE TEMPORARY TABLE sched_temp_record " 3638 "LIKE record;"); 3639 if (!result.exec()) 3640 { 3641 MythDB::DBError("Creating sched_temp_record table", result); 3642 return; 3643 } 3644 result.prepare("INSERT sched_temp_record SELECT * from record;"); 3645 if (!result.exec()) 3646 { 3647 MythDB::DBError("Populating sched_temp_record table", result); 3648 return; 3649 } 3650 } 3651 3652 result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;"); 3653 if (!result.exec()) 3654 { 3655 MythDB::DBError("Dropping sched_temp_recorded table", result); 3656 return; 3657 } 3658 result.prepare("CREATE TEMPORARY TABLE sched_temp_recorded " 3659 "LIKE recorded;"); 3660 if (!result.exec()) 3661 { 3662 MythDB::DBError("Creating sched_temp_recorded table", result); 3663 return; 3664 } 3665 result.prepare("INSERT sched_temp_recorded SELECT * from recorded;"); 3666 if (!result.exec()) 3667 { 3668 MythDB::DBError("Populating sched_temp_recorded table", result); 3669 return; 3670 } 3671 } 3672 3673 void Scheduler::DeleteTempTables(void) 3674 { 3675 MSqlQuery result(dbConn); 3676 3677 if (recordTable == "record") 3678 { 3679 result.prepare("DROP TABLE IF EXISTS sched_temp_record;"); 3680 if (!result.exec()) 3681 MythDB::DBError("DeleteTempTables sched_temp_record", result); 3682 } 3683 3684 result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;"); 3685 if (!result.exec()) 3686 MythDB::DBError("DeleteTempTables drop table", result); 3687 } 3688 3689 void Scheduler::UpdateDuplicates(void) 3690 { 3691 QString schedTmpRecord = recordTable; 3692 if (schedTmpRecord == "record") 3693 schedTmpRecord = "sched_temp_record"; 3694 3695 QString rmquery = QString( 3696 "UPDATE recordmatch " 3697 " INNER JOIN RECTABLE ON (recordmatch.recordid = RECTABLE.recordid) " 3698 " INNER JOIN program p ON (recordmatch.chanid = p.chanid AND " 3699 " recordmatch.starttime = p.starttime AND " 3700 " recordmatch.manualid = p.manualid) " 3701 " LEFT JOIN oldrecorded ON " 3702 " ( " 3703 " RECTABLE.dupmethod > 1 AND " 3704 " oldrecorded.duplicate <> 0 AND " 3705 " p.title = oldrecorded.title AND " 3706 " p.generic = 0 " 3707 " AND " 3708 " ( " 3709 " (p.programid <> '' " 3710 " AND p.programid = oldrecorded.programid) " 3711 " OR " 3712 " ( ") + 3713 (ProgramInfo::UsingProgramIDAuthority() ? 3714 " (p.programid = '' OR oldrecorded.programid = '' OR " 3715 " LEFT(p.programid, LOCATE('/', p.programid)) <> " 3716 " LEFT(oldrecorded.programid, LOCATE('/', oldrecorded.programid))) " : 3717 " (p.programid = '' OR oldrecorded.programid = '') " ) 3718 + QString( 3719 " AND " 3720 " (((RECTABLE.dupmethod & 0x02) = 0) OR (p.subtitle <> '' " 3721 " AND p.subtitle = oldrecorded.subtitle)) " 3722 " AND " 3723 " (((RECTABLE.dupmethod & 0x04) = 0) OR (p.description <> '' " 3724 " AND p.description = oldrecorded.description)) " 3725 " AND " 3726 " (((RECTABLE.dupmethod & 0x08) = 0) OR " 3727 " (p.subtitle <> '' AND " 3728 " (p.subtitle = oldrecorded.subtitle OR " 3729 " (oldrecorded.subtitle = '' AND " 3730 " p.subtitle = oldrecorded.description))) OR " 3731 " (p.subtitle = '' AND p.description <> '' AND " 3732 " (p.description = oldrecorded.subtitle OR " 3733 " (oldrecorded.subtitle = '' AND " 3734 " p.description = oldrecorded.description)))) " 3735 " ) " 3736 " ) " 3737 " ) " 3738 " LEFT JOIN sched_temp_recorded recorded ON " 3739 " ( " 3740 " RECTABLE.dupmethod > 1 AND " 3741 " recorded.duplicate <> 0 AND " 3742 " p.title = recorded.title AND " 3743 " p.generic = 0 AND " 3744 " recorded.recgroup NOT IN ('LiveTV','Deleted') " 3745 " AND " 3746 " ( " 3747 " (p.programid <> '' " 3748 " AND p.programid = recorded.programid) " 3749 " OR " 3750 " ( ") + 3751 (ProgramInfo::UsingProgramIDAuthority() ? 3752 " (p.programid = '' OR recorded.programid = '' OR " 3753 " LEFT(p.programid, LOCATE('/', p.programid)) <> " 3754 " LEFT(recorded.programid, LOCATE('/', recorded.programid))) " : 3755 " (p.programid = '' OR recorded.programid = '') ") 3756 + QString( 3757 " AND " 3758 " (((RECTABLE.dupmethod & 0x02) = 0) OR (p.subtitle <> '' " 3759 " AND p.subtitle = recorded.subtitle)) " 3760 " AND " 3761 " (((RECTABLE.dupmethod & 0x04) = 0) OR (p.description <> '' " 3762 " AND p.description = recorded.description)) " 3763 " AND " 3764 " (((RECTABLE.dupmethod & 0x08) = 0) OR " 3765 " (p.subtitle <> '' AND " 3766 " (p.subtitle = recorded.subtitle OR " 3767 " (recorded.subtitle = '' AND " 3768 " p.subtitle = recorded.description))) OR " 3769 " (p.subtitle = '' AND p.description <> '' AND " 3770 " (p.description = recorded.subtitle OR " 3771 " (recorded.subtitle = '' AND " 3772 " p.description = recorded.description)))) " 3773 " ) " 3774 " ) " 3775 " ) " 3776 " LEFT JOIN oldfind ON " 3777 " (oldfind.recordid = recordmatch.recordid AND " 3778 " oldfind.findid = recordmatch.findid) " 3779 " SET oldrecduplicate = (oldrecorded.endtime IS NOT NULL), " 3780 " recduplicate = (recorded.endtime IS NOT NULL), " 3781 " findduplicate = (oldfind.findid IS NOT NULL), " 3782 " oldrecstatus = oldrecorded.recstatus " 3783 " WHERE p.endtime >= (NOW() - INTERVAL 480 MINUTE) " 3784 " AND oldrecduplicate = -1 " 3785 ); 3786 rmquery.replace("RECTABLE", schedTmpRecord); 3787 3788 MSqlQuery result(dbConn); 3789 result.prepare(rmquery); 3790 if (!result.exec()) 3791 { 3792 MythDB::DBError("UpdateDuplicates", result); 3793 return; 3794 } 3795 } 3796 3438 3797 void Scheduler::AddNewRecords(void) 3439 3798 { 3799 QString schedTmpRecord = recordTable; 3800 if (schedTmpRecord == "record") 3801 schedTmpRecord = "sched_temp_record"; 3802 3440 3803 struct timeval dbstart, dbend; 3441 3804 3442 3805 QMap<RecordingType, int> recTypeRecPriorityMap; … … void Scheduler::AddNewRecords(void) 3456 3819 schedAfterStartMap.clear(); 3457 3820 3458 3821 MSqlQuery rlist(dbConn); 3459 rlist.prepare(QString("SELECT recordid,title,maxepisodes,maxnewest FROM %1;").arg(recordTable)); 3822 rlist.prepare(QString("SELECT recordid, title, maxepisodes, maxnewest " 3823 "FROM %1").arg(schedTmpRecord)); 3460 3824 3461 3825 if (!rlist.exec()) 3462 3826 { … … void Scheduler::AddNewRecords(void) 3547 3911 pwrpri += QString(" + " 3548 3912 "(FIND_IN_SET('VISUALIMPAIR', program.audioprop) > 0) * %1").arg(adpriority); 3549 3913 3550 QString schedTmpRecord = recordTable;3551 3552 3914 MSqlQuery result(dbConn); 3553 3915 3554 if (schedTmpRecord == "record")3555 {3556 schedTmpRecord = "sched_temp_record";3557 3558 result.prepare("DROP TABLE IF EXISTS sched_temp_record;");3559 3560 if (!result.exec())3561 {3562 MythDB::DBError("Dropping sched_temp_record table", result);3563 return;3564 }3565 3566 result.prepare("CREATE TEMPORARY TABLE sched_temp_record "3567 "LIKE record;");3568 3569 if (!result.exec())3570 {3571 MythDB::DBError("Creating sched_temp_record table",3572 result);3573 return;3574 }3575 3576 result.prepare("INSERT sched_temp_record SELECT * from record;");3577 3578 if (!result.exec())3579 {3580 MythDB::DBError("Populating sched_temp_record table",3581 result);3582 return;3583 }3584 }3585 3586 result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;");3587 3588 if (!result.exec())3589 {3590 MythDB::DBError("Dropping sched_temp_recorded table", result);3591 return;3592 }3593 3594 result.prepare("CREATE TEMPORARY TABLE sched_temp_recorded "3595 "LIKE recorded;");3596 3597 if (!result.exec())3598 {3599 MythDB::DBError("Creating sched_temp_recorded table", result);3600 return;3601 }3602 3603 result.prepare("INSERT sched_temp_recorded SELECT * from recorded;");3604 3605 if (!result.exec())3606 {3607 MythDB::DBError("Populating sched_temp_recorded table", result);3608 return;3609 }3610 3611 3916 result.prepare(QString("SELECT recpriority, selectclause FROM %1;") 3612 3917 .arg(priorityTable)); 3613 3918 … … void Scheduler::AddNewRecords(void) 3630 3935 } 3631 3936 pwrpri += QString(" AS powerpriority "); 3632 3937 3633 QString progfindid = QString(3634 "(CASE RECTABLE.type "3635 " WHEN %1 "3636 " THEN RECTABLE.findid "3637 " WHEN %2 "3638 " THEN to_days(date_sub(program.starttime, interval "3639 " time_format(RECTABLE.findtime, '%H:%i') hour_minute)) "3640 " WHEN %3 "3641 " THEN floor((to_days(date_sub(program.starttime, interval "3642 " time_format(RECTABLE.findtime, '%H:%i') hour_minute)) - "3643 " RECTABLE.findday)/7) * 7 + RECTABLE.findday "3644 " WHEN %4 "3645 " THEN RECTABLE.findid "3646 " ELSE 0 "3647 " END) ")3648 .arg(kFindOneRecord)3649 .arg(kFindDailyRecord)3650 .arg(kFindWeeklyRecord)3651 .arg(kOverrideRecord);3652 3653 QString rmquery = QString(3654 "UPDATE recordmatch "3655 " INNER JOIN RECTABLE ON (recordmatch.recordid = RECTABLE.recordid) "3656 " INNER JOIN program ON (recordmatch.chanid = program.chanid AND "3657 " recordmatch.starttime = program.starttime AND "3658 " recordmatch.manualid = program.manualid) "3659 " LEFT JOIN oldrecorded ON "3660 " ( "3661 " RECTABLE.dupmethod > 1 AND "3662 " oldrecorded.duplicate <> 0 AND "3663 " program.title = oldrecorded.title AND "3664 " program.generic = 0 "3665 " AND "3666 " ( "3667 " (program.programid <> '' "3668 " AND program.programid = oldrecorded.programid) "3669 " OR "3670 " ( ") +3671 (ProgramInfo::UsingProgramIDAuthority() ?3672 " (program.programid = '' OR oldrecorded.programid = '' OR "3673 " LEFT(program.programid, LOCATE('/', program.programid)) <> "3674 " LEFT(oldrecorded.programid, LOCATE('/', oldrecorded.programid))) " :3675 " (program.programid = '' OR oldrecorded.programid = '') " )3676 + QString(3677 " AND "3678 " (((RECTABLE.dupmethod & 0x02) = 0) OR (program.subtitle <> '' "3679 " AND program.subtitle = oldrecorded.subtitle)) "3680 " AND "3681 " (((RECTABLE.dupmethod & 0x04) = 0) OR (program.description <> '' "3682 " AND program.description = oldrecorded.description)) "3683 " AND "3684 " (((RECTABLE.dupmethod & 0x08) = 0) OR "3685 " (program.subtitle <> '' AND "3686 " (program.subtitle = oldrecorded.subtitle OR "3687 " (oldrecorded.subtitle = '' AND "3688 " program.subtitle = oldrecorded.description))) OR "3689 " (program.subtitle = '' AND program.description <> '' AND "3690 " (program.description = oldrecorded.subtitle OR "3691 " (oldrecorded.subtitle = '' AND "3692 " program.description = oldrecorded.description)))) "3693 " ) "3694 " ) "3695 " ) "3696 " LEFT JOIN sched_temp_recorded recorded ON "3697 " ( "3698 " RECTABLE.dupmethod > 1 AND "3699 " recorded.duplicate <> 0 AND "3700 " program.title = recorded.title AND "3701 " program.generic = 0 AND "3702 " recorded.recgroup NOT IN ('LiveTV','Deleted') "3703 " AND "3704 " ( "3705 " (program.programid <> '' "3706 " AND program.programid = recorded.programid) "3707 " OR "3708 " ( ") +3709 (ProgramInfo::UsingProgramIDAuthority() ?3710 " (program.programid = '' OR recorded.programid = '' OR "3711 " LEFT(program.programid, LOCATE('/', program.programid)) <> "3712 " LEFT(recorded.programid, LOCATE('/', recorded.programid))) " :3713 " (program.programid = '' OR recorded.programid = '') ")3714 + QString(3715 " AND "3716 " (((RECTABLE.dupmethod & 0x02) = 0) OR (program.subtitle <> '' "3717 " AND program.subtitle = recorded.subtitle)) "3718 " AND "3719 " (((RECTABLE.dupmethod & 0x04) = 0) OR (program.description <> '' "3720 " AND program.description = recorded.description)) "3721 " AND "3722 " (((RECTABLE.dupmethod & 0x08) = 0) OR "3723 " (program.subtitle <> '' AND "3724 " (program.subtitle = recorded.subtitle OR "3725 " (recorded.subtitle = '' AND "3726 " program.subtitle = recorded.description))) OR "3727 " (program.subtitle = '' AND program.description <> '' AND "3728 " (program.description = recorded.subtitle OR "3729 " (recorded.subtitle = '' AND "3730 " program.description = recorded.description)))) "3731 " ) "3732 " ) "3733 " ) "3734 " LEFT JOIN oldfind ON "3735 " (oldfind.recordid = recordmatch.recordid AND "3736 " oldfind.findid = ") + progfindid + QString(") "3737 " SET oldrecduplicate = (oldrecorded.endtime IS NOT NULL), "3738 " recduplicate = (recorded.endtime IS NOT NULL), "3739 " findduplicate = (oldfind.findid IS NOT NULL), "3740 " oldrecstatus = oldrecorded.recstatus "3741 " WHERE program.endtime >= NOW() - INTERVAL 9 HOUR "3742 );3743 rmquery.replace("RECTABLE", schedTmpRecord);3744 3745 3938 pwrpri.replace("program.","p."); 3746 3939 pwrpri.replace("channel.","c."); 3747 progfindid.replace("program.","p.");3748 progfindid.replace("channel.","c.");3749 3940 QString query = QString( 3750 3941 "SELECT " 3751 3942 " c.chanid, c.sourceid, p.starttime, "// 0-2 … … void Scheduler::AddNewRecords(void) 3763 3954 " capturecard.cardid, cardinput.cardinputid,p.seriesid, "//24-26 3764 3955 " p.programid, RECTABLE.inetref, p.category_type, "//27-29 3765 3956 " p.airdate, p.stars, p.originalairdate, "//30-32 3766 " RECTABLE.inactive, RECTABLE.parentid, ") + progfindid + ","//33-353957 " RECTABLE.inactive, RECTABLE.parentid, recordmatch.findid, "//33-35 3767 3958 " RECTABLE.playgroup, oldrecstatus.recstatus, "//36-37 3768 3959 " oldrecstatus.reactivate, p.videoprop+0, "//38-39 3769 3960 " p.subtitletypes+0, p.audioprop+0, RECTABLE.storagegroup, "//40-42 3770 3961 " capturecard.hostname, recordmatch.oldrecstatus, " 3771 3962 " RECTABLE.avg_delay, "//43-45 3772 " oldrecstatus.future, cardinput.schedorder, " //46-473773 +pwrpri + QString(3963 " oldrecstatus.future, cardinput.schedorder, ") + //46-47 3964 pwrpri + QString( 3774 3965 "FROM recordmatch " 3775 3966 "INNER JOIN RECTABLE ON (recordmatch.recordid = RECTABLE.recordid) " 3776 3967 "INNER JOIN program AS p " … … void Scheduler::AddNewRecords(void) 3785 3976 "ON ( oldrecstatus.station = c.callsign AND " 3786 3977 " oldrecstatus.starttime = p.starttime AND " 3787 3978 " oldrecstatus.title = p.title ) " 3788 "WHERE p.endtime >= NOW() - INTERVAL 1 DAY " 3789 "ORDER BY RECTABLE.recordid DESC "); 3979 "WHERE p.endtime > (NOW() - INTERVAL 480 MINUTE) " 3980 "ORDER BY RECTABLE.recordid DESC, p.starttime, p.title, c.callsign, " 3981 " c.channum "); 3790 3982 query.replace("RECTABLE", schedTmpRecord); 3791 3983 3792 3984 LOG(VB_SCHEDULE, LOG_INFO, QString(" |-- Start DB Query...")); 3793 3985 3794 3986 gettimeofday(&dbstart, NULL); 3795 result.prepare(rmquery);3796 if (!result.exec())3797 {3798 MythDB::DBError("AddNewRecords recordmatch", result);3799 return;3800 }3801 3987 result.prepare(query); 3802 3988 if (!result.exec()) 3803 3989 { … … void Scheduler::AddNewRecords(void) 3812 3998 .arg(((dbend.tv_sec - dbstart.tv_sec) * 1000000 + 3813 3999 (dbend.tv_usec - dbstart.tv_usec)) / 1000000.0)); 3814 4000 4001 RecordingInfo *lastp = NULL; 4002 3815 4003 while (result.next()) 3816 4004 { 4005 // If this is the same program we saw in the last pass and it 4006 // wasn't a viable candidate, then neither is this one so 4007 // don't bother with it. This is essentially an early call to 4008 // PruneRedundants(). 4009 uint recordid = result.value(17).toUInt(); 4010 QDateTime startts = result.value(2).toDateTime(); 4011 QString title = result.value(4).toString(); 4012 QString callsign = result.value(8).toString(); 4013 if (lastp && lastp->GetRecordingStatus() != rsUnknown 4014 && recordid == lastp->GetRecordingRuleID() 4015 && startts == lastp->GetScheduledStartTime() 4016 && title == lastp->GetTitle() 4017 && callsign == lastp->GetChannelSchedulingID()) 4018 continue; 4019 3817 4020 RecordingInfo *p = new RecordingInfo( 3818 result.value(4).toString(),//title4021 title, 3819 4022 result.value(5).toString(),//subtitle 3820 4023 result.value(6).toString(),//description 3821 4024 0, // season … … void Scheduler::AddNewRecords(void) 3824 4027 3825 4028 result.value(0).toUInt(),//chanid 3826 4029 result.value(7).toString(),//channum 3827 result.value(8).toString(),//chansign4030 callsign, 3828 4031 result.value(9).toString(),//channame 3829 4032 3830 4033 result.value(21).toString(),//recgroup … … void Scheduler::AddNewRecords(void) 3842 4045 3843 4046 result.value(12).toInt(),//recpriority 3844 4047 3845 result.value(2).toDateTime(),//startts4048 startts, 3846 4049 result.value(3).toDateTime(),//endts 3847 4050 result.value(18).toDateTime(),//recstartts 3848 4051 result.value(19).toDateTime(),//recendts … … void Scheduler::AddNewRecords(void) 3857 4060 RecStatusType(result.value(37).toInt()),//oldrecstatus 3858 4061 result.value(38).toInt(),//reactivate 3859 4062 3860 re sult.value(17).toUInt(),//recordid4063 recordid, 3861 4064 result.value(34).toUInt(),//parentid 3862 4065 RecordingType(result.value(16).toInt()),//rectype 3863 4066 RecordingDupInType(result.value(13).toInt()),//dupin … … void Scheduler::AddNewRecords(void) 3919 4122 if (p == NULL) 3920 4123 continue; 3921 4124 4125 lastp = p; 4126 3922 4127 if (p->GetRecordingStatus() != rsUnknown) 3923 4128 { 3924 4129 tmpList.push_back(p); … … void Scheduler::AddNewRecords(void) 3989 4194 RecIter tmp = tmpList.begin(); 3990 4195 for ( ; tmp != tmpList.end(); ++tmp) 3991 4196 worklist.push_back(*tmp); 3992 3993 if (schedTmpRecord == "sched_temp_record")3994 {3995 result.prepare("DROP TABLE IF EXISTS sched_temp_record;");3996 if (!result.exec())3997 MythDB::DBError("AddNewRecords sched_temp_record", result);3998 }3999 4000 result.prepare("DROP TABLE IF EXISTS sched_temp_recorded;");4001 if (!result.exec())4002 MythDB::DBError("AddNewRecords drop table", result);4003 4197 } 4004 4198 4005 4199 void Scheduler::AddNotListed(void) { -
mythtv/programs/mythbackend/scheduler.h
diff --git a/mythtv/programs/mythbackend/scheduler.h b/mythtv/programs/mythbackend/scheduler.h index 8203c9f..2df7b68 100644
a b using namespace std; 22 22 #include "mythdeque.h" 23 23 #include "mythscheduler.h" 24 24 #include "mthread.h" 25 #include "scheduledrecording.h" 25 26 26 27 class EncoderLink; 27 28 class MainServer; … … class Scheduler : public MThread, public MythScheduler 41 42 42 43 void SetExpirer(AutoExpire *autoExpirer) { m_expirer = autoExpirer; } 43 44 44 void Reschedule(int recordid); 45 void Reschedule(const QStringList &request); 46 void RescheduleMatch(uint recordid, uint sourceid, uint mplexid, 47 const QDateTime &maxstarttime, const QString &why) 48 { Reschedule(ScheduledRecording::BuildMatchRequest(recordid, sourceid, 49 mplexid, maxstarttime, why)); }; 50 void RescheduleCheck(const RecordingInfo &recinfo, const QString &why) 51 { Reschedule(ScheduledRecording::BuildCheckRequest(recinfo, why)); }; 52 void ReschedulePlace(const QString &why) 53 { Reschedule(ScheduledRecording::BuildPlaceRequest(why)); }; 54 45 55 void AddRecording(const RecordingInfo&); 46 void FillRecordListFromDB( int recordid = -1);56 void FillRecordListFromDB(uint recordid = 0); 47 57 void FillRecordListFromMaster(void); 48 58 49 59 void UpdateRecStatus(RecordingInfo *pginfo); … … class Scheduler : public MThread, public MythScheduler 92 102 93 103 bool VerifyCards(void); 94 104 105 void CreateTempTables(void); 106 void DeleteTempTables(void); 107 void UpdateDuplicates(void); 95 108 bool FillRecordList(void); 96 void UpdateMatches(int recordid); 97 void UpdateManuals(int recordid); 109 void UpdateMatches(uint recordid, uint sourceid, uint mplexid, 110 const QDateTime maxstarttime); 111 void UpdateManuals(uint recordid); 98 112 void BuildWorkList(void); 99 113 bool ClearWorkList(void); 100 114 void AddNewRecords(void); 101 115 void AddNotListed(void); 102 void BuildNewRecordsQueries( int recordid, QStringList &from, QStringList &where,103 MSqlBindings &bindings);116 void BuildNewRecordsQueries(uint recordid, QStringList &from, 117 QStringList &where, MSqlBindings &bindings); 104 118 void PruneOverlaps(void); 105 119 void BuildListMaps(void); 106 120 void ClearListMaps(void); … … class Scheduler : public MThread, public MythScheduler 150 164 RecConstIter startIter, const RecList &reclist, 151 165 int prerollseconds, int max_sleep /*ms*/); 152 166 void OldRecordedFixups(void); 167 void ResetDuplicates(uint recordid, uint findid, const QString &title, 168 const QString &subtitle, const QString &descrip, 169 const QString &programid); 153 170 bool HandleReschedule(void); 154 171 bool HandleRunSchedulerStartup( 155 172 int prerollseconds, int idleWaitForRecordingTime); … … class Scheduler : public MThread, public MythScheduler 166 183 int idleTimeoutSecs, int idleWaitForRecordingTime, 167 184 bool &statuschanged); 168 185 169 170 MythDeque<int> reschedQueue; 186 void EnqueueMatch(uint recordid, uint sourceid, uint mplexid, 187 const QDateTime maxstarttime, const QString &why) 188 { reschedQueue.enqueue(ScheduledRecording::BuildMatchRequest(recordid, 189 sourceid, mplexid, maxstarttime, why)); }; 190 void EnqueueCheck(const RecordingInfo &recinfo, const QString &why) 191 { reschedQueue.enqueue(ScheduledRecording::BuildCheckRequest(recinfo, 192 why)); }; 193 void EnqueuePlace(const QString &why) 194 { reschedQueue.enqueue(ScheduledRecording::BuildPlaceRequest(why)); }; 195 196 MythDeque<QStringList> reschedQueue; 171 197 mutable QMutex schedLock; 172 198 QMutex recordmatchLock; 173 199 QWaitCondition reschedWait; … … class Scheduler : public MThread, public MythScheduler 175 201 RecList worklist; 176 202 RecList retrylist; 177 203 RecList conflictlist; 178 QMap< int, RecList> recordidlistmap;204 QMap<uint, RecList> recordidlistmap; 179 205 QMap<QString, RecList> titlelistmap; 180 206 InputGroupMap igrp; 181 207 -
mythtv/programs/mythfilldatabase/main.cpp
diff --git a/mythtv/programs/mythfilldatabase/main.cpp b/mythtv/programs/mythfilldatabase/main.cpp index 57d4709..1552a1a 100644
a b int main(int argc, char *argv[]) 760 760 "==============================================================="); 761 761 762 762 if (grab_data || mark_repeats) 763 ScheduledRecording::signalChange(-1); 763 ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(), 764 "MythFillDatabase"); 764 765 765 766 gCoreContext->SendMessage("CLEAR_SETTINGS_CACHE"); 766 767 -
mythtv/programs/mythfrontend/channelrecpriority.cpp
diff --git a/mythtv/programs/mythfrontend/channelrecpriority.cpp b/mythtv/programs/mythfrontend/channelrecpriority.cpp index 180bd7e..085ed0f 100644
a b void ChannelRecPriority::saveRecPriority(void) 238 238 applyChannelRecPriorityChange(QString::number(chanInfo->chanid), 239 239 chanInfo->recpriority); 240 240 } 241 ScheduledRecording:: signalChange(0);241 ScheduledRecording::ReschedulePlace("SaveChannelPriority"); 242 242 } 243 243 244 244 void ChannelRecPriority::FillList(void) -
mythtv/programs/mythfrontend/custompriority.cpp
diff --git a/mythtv/programs/mythfrontend/custompriority.cpp b/mythtv/programs/mythfrontend/custompriority.cpp index e595090..4c5c2b0 100644
a b void CustomPriority::installClicked(void) 306 306 if (!query.exec()) 307 307 MythDB::DBError("Install power search insert", query); 308 308 else 309 ScheduledRecording:: signalChange(0);309 ScheduledRecording::ReschedulePlace("InstallCustomPriority"); 310 310 311 311 Close(); 312 312 } … … void CustomPriority::deleteClicked(void) 324 324 if (!query.exec()) 325 325 MythDB::DBError("Delete power search query", query); 326 326 else 327 ScheduledRecording:: signalChange(0);327 ScheduledRecording::ReschedulePlace("DeleteCustomPriority"); 328 328 329 329 Close(); 330 330 } -
mythtv/programs/mythfrontend/main.cpp
diff --git a/mythtv/programs/mythfrontend/main.cpp b/mythtv/programs/mythfrontend/main.cpp index 019bb3a..d9042d6 100644
a b static void TVMenuCallback(void *data, QString &selection) 1044 1044 1045 1045 if (sel == "settings general" || 1046 1046 sel == "settings generalrecpriorities") 1047 ScheduledRecording:: signalChange(0);1047 ScheduledRecording::ReschedulePlace("TVMenuCallback"); 1048 1048 GetMythMainWindow()->ShowPainterWindow(); 1049 1049 } 1050 1050 } -
mythtv/programs/mythfrontend/proglist.cpp
diff --git a/mythtv/programs/mythfrontend/proglist.cpp b/mythtv/programs/mythfrontend/proglist.cpp index ddda2af..f2e10c1 100644
a b void ProgLister::DeleteOldEpisode(bool ok) 675 675 if (!query.exec()) 676 676 MythDB::DBError("ProgLister::DeleteOldEpisode", query); 677 677 678 ScheduledRecording:: signalChange(0);678 ScheduledRecording::RescheduleCheck(*pi, "DeleteOldEpisode"); 679 679 FillItemList(true); 680 680 } 681 681 … … void ProgLister::DeleteOldSeries(bool ok) 704 704 if (!query.exec()) 705 705 MythDB::DBError("ProgLister::DeleteOldSeries -- delete", query); 706 706 707 ScheduledRecording::signalChange(0); 707 // Set the programid to the special value of "**any**" which the 708 // scheduler recognizes to mean the entire series was deleted. 709 RecordingInfo tempri(*pi); 710 tempri.SetProgramID("**any**"); 711 ScheduledRecording::RescheduleCheck(tempri, "DeleteOldSeries"); 708 712 FillItemList(true); 709 713 } 710 714 -
mythtv/programs/mythfrontend/programrecpriority.cpp
diff --git a/mythtv/programs/mythfrontend/programrecpriority.cpp b/mythtv/programs/mythfrontend/programrecpriority.cpp index 1ea874c..a33acf8 100644
a b void ProgramRecPriority::deactivate(void) 1027 1027 } 1028 1028 else 1029 1029 { 1030 ScheduledRecording::signalChange(0); 1030 ScheduledRecording::ReschedulePlace( 1031 QString("DeactivateRule %1 %2") 1032 .arg(pgRecInfo->GetRecordingRuleID()) 1033 .arg(pgRecInfo->GetTitle())); 1031 1034 pgRecInfo->recstatus = inactive ? rsInactive : rsUnknown; 1032 1035 item->DisplayState("disabled", "status"); 1033 1036 } -
mythtv/programs/mythutil/backendutils.cpp
diff --git a/mythtv/programs/mythutil/backendutils.cpp b/mythtv/programs/mythutil/backendutils.cpp index 151fa7d..f4f43ea 100644
a b 3 3 #include "mythcorecontext.h" 4 4 #include "mythlogging.h" 5 5 #include "remoteutil.h" 6 #include "scheduledrecording.h" 6 7 7 8 // local headers 8 9 #include "backendutils.h" 9 10 10 static int RawSendEvent(const QString &eventString)11 static int RawSendEvent(const QStringList &eventStringList) 11 12 { 12 if (eventString .isEmpty())13 if (eventStringList.isEmpty() || eventStringList[0].isEmpty()) 13 14 return GENERIC_EXIT_INVALID_CMDLINE; 14 15 15 16 if (gCoreContext->ConnectToMasterServer(false, false)) 16 17 { 17 gCoreContext->SendMessage(eventString); 18 QStringList message("MESSAGE"); 19 message << eventStringList; 20 gCoreContext->SendReceiveStringList(message); 18 21 return GENERIC_EXIT_OK; 19 22 } 20 23 return GENERIC_EXIT_CONNECT_ERROR; … … static int ClearSettingsCache(const MythUtilCommandLineParser &cmdline) 36 39 37 40 static int SendEvent(const MythUtilCommandLineParser &cmdline) 38 41 { 39 return RawSendEvent(cmdline.toString ("event"));42 return RawSendEvent(cmdline.toStringList("event")); 40 43 } 41 44 42 45 static int SendSystemEvent(const MythUtilCommandLineParser &cmdline) 43 46 { 44 return RawSendEvent(QString ("SYSTEM_EVENT %1 SENDER %2")45 .arg(cmdline.toString("systemevent"))46 .arg(gCoreContext->GetHostName()));47 return RawSendEvent(QStringList(QString("SYSTEM_EVENT %1 SENDER %2") 48 .arg(cmdline.toString("systemevent")) 49 .arg(gCoreContext->GetHostName()))); 47 50 } 48 51 49 52 static int Reschedule(const MythUtilCommandLineParser &cmdline) 50 53 { 51 54 if (gCoreContext->ConnectToMasterServer(false, false)) 52 55 { 53 QStringList slist("RESCHEDULE_RECORDINGS -1"); 54 if (gCoreContext->SendReceiveStringList(slist)) 55 { 56 LOG(VB_GENERAL, LOG_ERR, 57 "Error sending reschedule command to master backend"); 58 return GENERIC_EXIT_CONNECT_ERROR; 59 } 60 56 ScheduledRecording::RescheduleMatch(0, 0, 0, QDateTime(), 57 "MythUtilCommand"); 61 58 LOG(VB_GENERAL, LOG_INFO, "Reschedule command sent to master"); 62 59 return GENERIC_EXIT_OK; 63 60 } -
mythtv/programs/mythutil/commandlineparser.cpp
diff --git a/mythtv/programs/mythutil/commandlineparser.cpp b/mythtv/programs/mythutil/commandlineparser.cpp index 7f00e50..897be65 100644
a b void MythUtilCommandLineParser::LoadArguments(void) 83 83 "access those files to do so. If enabled, this will also " 84 84 "trigger the bulk metadata scanner upon completion.") 85 85 ->SetGroup("Backend") 86 << add("--event", "event", "", "Send a backend event test message.", "") 86 << add("--event", "event", QVariant::StringList, 87 "Send a backend event test message.", "") 87 88 ->SetGroup("Backend") 88 89 << add("--systemevent", "systemevent", "", 89 90 "Send a backend SYSTEM_EVENT test message.", "")
