From 202bb59ee137c2e4d2be4deb7688a710ae1ac838 Mon Sep 17 00:00:00 2001 From: Scott Theisen Date: Sat, 24 Sep 2022 22:04:59 -0400 Subject: [PATCH 1/4] Manual Recordings: restore date time subtitle Apparently removed in 5f6697ecfaf9bd7175aaf99b3ef07f884d5af65c --- mythtv/programs/mythbackend/scheduler.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mythtv/programs/mythbackend/scheduler.cpp b/mythtv/programs/mythbackend/scheduler.cpp index b78e643b754..c926ac148b9 100644 --- a/mythtv/programs/mythbackend/scheduler.cpp +++ b/mythtv/programs/mythbackend/scheduler.cpp @@ -3848,7 +3848,9 @@ void Scheduler::UpdateManuals(uint recordid) query.bindValue(":STARTTIME", startdt); query.bindValue(":ENDTIME", startdt.addSecs(duration)); query.bindValue(":TITLE", title); - query.bindValue(":SUBTITLE", subtitle); + query.bindValue(":SUBTITLE", + !subtitle.isEmpty() ? subtitle : + MythDate::toString(startdt, MythDate::kDatabase | MythDate::kOverrideLocal)); query.bindValue(":DESCRIPTION", description); query.bindValue(":SEASON", season); query.bindValue(":EPISODE", episode); From 1dda5cb2a6550636008a00cd727e4fa3eedb5797 Mon Sep 17 00:00:00 2001 From: Scott Theisen Date: Mon, 3 Jun 2024 19:34:16 -0400 Subject: [PATCH 2/4] Scheduler::UpdateManuals(): only test if subtitle was empty once if updating for multiple channels. --- mythtv/programs/mythbackend/scheduler.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mythtv/programs/mythbackend/scheduler.cpp b/mythtv/programs/mythbackend/scheduler.cpp index c926ac148b9..74c978b83e1 100644 --- a/mythtv/programs/mythbackend/scheduler.cpp +++ b/mythtv/programs/mythbackend/scheduler.cpp @@ -3763,6 +3763,8 @@ void Scheduler::UpdateManuals(uint recordid) if (description.isEmpty()) description = startdt.toLocalTime().toString(); + bool subtitleWasEmpty = subtitle.isEmpty(); + query.prepare("SELECT chanid from channel " "WHERE deleted IS NULL AND callsign = :STATION"); query.bindValue(":STATION", station); @@ -3833,11 +3835,17 @@ void Scheduler::UpdateManuals(uint recordid) while (progcount--) { + if (subtitleWasEmpty) + { + subtitle = MythDate::toString(startdt, MythDate::kDatabase | MythDate::kOverrideLocal); + } + for (uint id : chanidlist) { if (weekday && startdt.toLocalTime().date().dayOfWeek() >= 6) continue; + query.prepare("REPLACE INTO program (chanid, starttime, endtime," " title, subtitle, description, manualid," " season, episode, inetref, originalairdate, generic) " @@ -3848,9 +3856,7 @@ void Scheduler::UpdateManuals(uint recordid) query.bindValue(":STARTTIME", startdt); query.bindValue(":ENDTIME", startdt.addSecs(duration)); query.bindValue(":TITLE", title); - query.bindValue(":SUBTITLE", - !subtitle.isEmpty() ? subtitle : - MythDate::toString(startdt, MythDate::kDatabase | MythDate::kOverrideLocal)); + query.bindValue(":SUBTITLE", subtitle); query.bindValue(":DESCRIPTION", description); query.bindValue(":SEASON", season); query.bindValue(":EPISODE", episode); From 90aa0e9479180bb06516345cb98701f8f890e9c0 Mon Sep 17 00:00:00 2001 From: Scott Theisen Date: Mon, 3 Jun 2024 19:40:13 -0400 Subject: [PATCH 3/4] Scheduler::UpdateManuals(): update empty description for each recording Previously, the description listed the first date for each daily or weekly recording. --- mythtv/programs/mythbackend/scheduler.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mythtv/programs/mythbackend/scheduler.cpp b/mythtv/programs/mythbackend/scheduler.cpp index 74c978b83e1..05f9404edc1 100644 --- a/mythtv/programs/mythbackend/scheduler.cpp +++ b/mythtv/programs/mythbackend/scheduler.cpp @@ -3760,10 +3760,8 @@ void Scheduler::UpdateManuals(uint recordid) // the services API to propegate originalairdate information. QDate originalairdate = QDate(query.value(12).toDate()); - if (description.isEmpty()) - description = startdt.toLocalTime().toString(); - bool subtitleWasEmpty = subtitle.isEmpty(); + bool descriptionWasEmpty = description.isEmpty(); query.prepare("SELECT chanid from channel " "WHERE deleted IS NULL AND callsign = :STATION"); @@ -3840,6 +3838,11 @@ void Scheduler::UpdateManuals(uint recordid) subtitle = MythDate::toString(startdt, MythDate::kDatabase | MythDate::kOverrideLocal); } + if (descriptionWasEmpty) + { + description = startdt.toLocalTime().toString(); + } + for (uint id : chanidlist) { if (weekday && startdt.toLocalTime().date().dayOfWeek() >= 6) From f0c019e5c92d2c452ce4a343792fae44d7349eef Mon Sep 17 00:00:00 2001 From: Scott Theisen Date: Tue, 4 Jun 2024 02:04:23 -0400 Subject: [PATCH 4/4] Scheduler::UpdateManuals(): prevent scheduling recordings before the given start date MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit and rewrite the confusing code that calculated the start times. I thought about adding something to prevent scheduling recordings in the past, but this function doesn’t have enough information to determine that. ` if (MythDate::current().toLocalTime().time() > starttime) { offset++; } ` The above code would prevent scheduling recordings that should have already started. However, the end time may still be in the future, so it should be scheduled in that case. Unfortunately, the startdate, starttime, enddate, and endtime values do not account for starting/ending the recording early/late (8 hours in either direction from the start and end), so this cannot be determined from the information the function has. Therefore, this function will continue to schedule recordings that may be entirely in the past. --- mythtv/programs/mythbackend/scheduler.cpp | 93 ++++++++++------------- 1 file changed, 41 insertions(+), 52 deletions(-) diff --git a/mythtv/programs/mythbackend/scheduler.cpp b/mythtv/programs/mythbackend/scheduler.cpp index 05f9404edc1..0d7ff88ade4 100644 --- a/mythtv/programs/mythbackend/scheduler.cpp +++ b/mythtv/programs/mythbackend/scheduler.cpp @@ -3776,54 +3776,58 @@ void Scheduler::UpdateManuals(uint recordid) while (query.next()) chanidlist.push_back(query.value(0).toUInt()); - int progcount = 0; - int skipdays = 1; - bool weekday = false; - int daysoff = 0; - QDateTime lstartdt = startdt.toLocalTime(); + std::vector startList; + constexpr int weeksToSchedule = 2; + constexpr int daysInWeek = 7; + // use local date/time so the local time of the recording stays constant + // across daylight savings time changes and weekday/weekend detection works + // correctly + const QDate startDate = startdt.toLocalTime().date(); + const QTime startTime = startdt.toLocalTime().time(); + // don't schedule recordings before startDate + qint64 offset = + std::max(qint64{0}, startDate.daysTo(MythDate::current().toLocalTime().date())); switch (rectype) { case kSingleRecord: case kOverrideRecord: case kDontRecord: - progcount = 1; - skipdays = 1; - weekday = false; - daysoff = 0; + startList.push_back(startdt); break; case kDailyRecord: - progcount = 13; - skipdays = 1; - weekday = (lstartdt.date().dayOfWeek() < 6); - daysoff = lstartdt.date().daysTo( - MythDate::current().toLocalTime().date()); + for (int i = 0; i < daysInWeek * weeksToSchedule; i++) + { + if (startDate.dayOfWeek() < 6 && startDate.addDays(offset + i).dayOfWeek() >= 6) + { + continue; + } #if QT_VERSION < QT_VERSION_CHECK(6,5,0) - startdt = QDateTime(lstartdt.date().addDays(daysoff), - lstartdt.time(), Qt::LocalTime).toUTC(); + startList.push_back(QDateTime(startDate.addDays(offset + i), + startTime, Qt::LocalTime).toUTC()); #else - startdt = QDateTime(lstartdt.date().addDays(daysoff), - lstartdt.time(), - QTimeZone(QTimeZone::LocalTime) - ).toUTC(); + startList.push_back(QDateTime(startDate.addDays(offset + i), + startTime, QTimeZone(QTimeZone::LocalTime) + ).toUTC() + ); #endif + } break; case kWeeklyRecord: - progcount = 2; - skipdays = 7; - weekday = false; - daysoff = lstartdt.date().daysTo( - MythDate::current().toLocalTime().date()); - daysoff = (daysoff + 6) / 7 * 7; + // round offset up to a whole number of weeks + offset = (offset + daysInWeek - 1) / daysInWeek * daysInWeek; + for (int i = 0; i < daysInWeek * weeksToSchedule; i += daysInWeek) + { #if QT_VERSION < QT_VERSION_CHECK(6,5,0) - startdt = QDateTime(lstartdt.date().addDays(daysoff), - lstartdt.time(), Qt::LocalTime).toUTC(); + startList.push_back(QDateTime(startDate.addDays(offset + i), + startTime, Qt::LocalTime).toUTC()); #else - startdt = QDateTime(lstartdt.date().addDays(daysoff), - lstartdt.time(), - QTimeZone(QTimeZone::LocalTime) - ).toUTC(); + startList.push_back(QDateTime(startDate.addDays(offset + i), + startTime, QTimeZone(QTimeZone::LocalTime) + ).toUTC() + ); #endif + } break; default: LOG(VB_GENERAL, LOG_ERR, @@ -3831,24 +3835,20 @@ void Scheduler::UpdateManuals(uint recordid) return; } - while (progcount--) + for (const QDateTime& start : startList) { if (subtitleWasEmpty) { - subtitle = MythDate::toString(startdt, MythDate::kDatabase | MythDate::kOverrideLocal); + subtitle = MythDate::toString(start, MythDate::kDatabase | MythDate::kOverrideLocal); } if (descriptionWasEmpty) { - description = startdt.toLocalTime().toString(); + description = start.toLocalTime().toString(); } for (uint id : chanidlist) { - if (weekday && startdt.toLocalTime().date().dayOfWeek() >= 6) - continue; - - query.prepare("REPLACE INTO program (chanid, starttime, endtime," " title, subtitle, description, manualid," " season, episode, inetref, originalairdate, generic) " @@ -3856,8 +3856,8 @@ void Scheduler::UpdateManuals(uint recordid) " :SUBTITLE, :DESCRIPTION, :RECORDID, " " :SEASON, :EPISODE, :INETREF, :ORIGINALAIRDATE, 1)"); query.bindValue(":CHANID", id); - query.bindValue(":STARTTIME", startdt); - query.bindValue(":ENDTIME", startdt.addSecs(duration)); + query.bindValue(":STARTTIME", start); + query.bindValue(":ENDTIME", start.addSecs(duration)); query.bindValue(":TITLE", title); query.bindValue(":SUBTITLE", subtitle); query.bindValue(":DESCRIPTION", description); @@ -3872,17 +3872,6 @@ void Scheduler::UpdateManuals(uint recordid) return; } } - - daysoff += skipdays; -#if QT_VERSION < QT_VERSION_CHECK(6,5,0) - startdt = QDateTime(lstartdt.date().addDays(daysoff), - lstartdt.time(), Qt::LocalTime).toUTC(); -#else - startdt = QDateTime(lstartdt.date().addDays(daysoff), - lstartdt.time(), - QTimeZone(QTimeZone::LocalTime) - ).toUTC(); -#endif } }