19#define LOC QString("ProgramData: ")
21static const std::array<const std::string,DBPerson::kGuest+1>
roles
24 "actor",
"director",
"producer",
"executive_producer",
25 "writer",
"guest_star",
"host",
"adapter",
26 "presenter",
"commentator",
"guest",
31 return str.isNull() ?
"" : str;
36 return dt.isNull() ? QVariant(
"0000-00-00 00:00:00") : QVariant(dt);
40 uint chanid,
const QDateTime &starttime)
42 QString relevance = QString(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ");
43 for (
auto it = genres.constBegin(); (it != genres.constEnd()) &&
44 ((it - genres.constBegin()) < relevance.size()); ++it)
47 "INSERT INTO programgenres "
48 " ( chanid, starttime, genre, relevance) "
49 "VALUES (:CHANID, :START, :genre, :relevance)");
53 query.
bindValue(
":relevance", relevance.at(it - genres.constBegin()));
61 : m_role(other.m_role)
62 , m_name(other.m_name)
63 , m_priority(other.m_priority)
64 , m_character(other.m_character)
86 , m_name(std::move(name))
87 , m_priority(priority)
88 , m_character(std::move(character))
95 int priority, QString character)
97 , m_name(std::move(name))
98 , m_priority(priority)
99 , m_character(std::move(character))
103 std::string rolestr = role.toLower().toStdString();
104 for (
size_t i = 0; i <
roles.size(); ++i)
106 if (rolestr ==
roles[i])
127 const QDateTime &starttime,
128 bool recording)
const
143 starttime, recording);
151 "WHERE name = :NAME");
156 else if (query.
next())
157 return query.
value(0).toUInt();
165 "INSERT IGNORE INTO people (name) "
181 "WHERE name = :NAME");
185 return query.
value(0).toUInt();
193 "INSERT IGNORE INTO roles (name) "
205 uint chanid,
const QDateTime &starttime,
206 bool recording)
const
211 QString table = recording ?
"recordedcredits" :
"credits";
213 query.
prepare(QString(
"REPLACE INTO %1 "
214 " ( person, roleid, chanid, starttime, role, priority) "
215 "VALUES (:PERSON, :ROLEID, :CHANID, :STARTTIME, :ROLE, :PRIORITY);")
220 query.
bindValue(
":STARTTIME", starttime);
299 int priority,
const QString &character)
304 m_credits->emplace_back(role, name.simplified(),
305 priority, character.simplified());
309 int priority,
const QString &character)
314 m_credits->emplace_back(role, name.simplified(),
315 priority, character.simplified());
329 LOG(VB_EIT, LOG_DEBUG,
330 QString(
"EIT: new program: %1 %2 '%3' chanid %4")
334 QString::number(chanid)));
337 QDateTime now = QDateTime::currentDateTimeUtc();
340 LOG(VB_EIT, LOG_DEBUG,
341 QString(
"EIT: skip '%1' endtime is in the past")
348 std::vector<DBEvent> programs;
359 for (
uint j=0; j<count; ++j)
361 LOG(VB_EIT, LOG_DEBUG,
362 QString(
"EIT: overlap[%1] : %2 %3 '%4'")
363 .arg(QString::number(j),
366 programs[j].m_title.left(35)));
376 if (match >= match_threshold)
381 LOG(VB_EIT, LOG_DEBUG,
382 QString(
"EIT: accept match[%1]: %2 '%3' vs. '%4'")
385 programs[i].m_title.left(35)));
386 return UpdateDB(query, chanid, programs, i);
394 LOG(VB_EIT, LOG_DEBUG,
395 QString(
"EIT: reject match[%1]: %2 '%3' vs. '%4'")
398 programs[i].m_title.left(35)));
403 return UpdateDB(query, chanid, programs, -1);
430 MSqlQuery &query,
uint chanid, std::vector<DBEvent> &programs)
const
434 "SELECT title, subtitle, description, "
435 " category, category_type, "
436 " starttime, endtime, "
437 " subtitletypes+0,audioprop+0, videoprop+0, "
438 " seriesid, programid, "
439 " partnumber, parttotal, "
440 " syndicatedepisodenumber, "
441 " airdate, originalairdate, "
442 " previouslyshown,listingsource, "
444 " season, episode, totalepisodes, "
447 "WHERE chanid = :CHANID AND "
449 " ( ( starttime >= :STIME1 AND starttime < :ETIME1 ) OR "
450 " ( endtime > :STIME2 AND endtime <= :ETIME2 ) OR "
451 " ( starttime < :STIME3 AND endtime > :ETIME3 ) )");
472 query.
value(0).toString(),
473 query.
value(1).toString(),
474 query.
value(2).toString(),
475 query.
value(3).toString(),
479 query.
value(7).toUInt(),
480 query.
value(8).toUInt(),
481 query.
value(9).toUInt(),
482 query.
value(19).toFloat(),
483 query.
value(10).toString(),
484 query.
value(11).toString(),
485 query.
value(18).toUInt(),
486 query.
value(20).toUInt(),
487 query.
value(21).toUInt(),
488 query.
value(22).toUInt());
498 programs.push_back(prog);
506static int score_words(
const QStringList &al,
const QStringList &bl)
508 QStringList::const_iterator ait = al.begin();
509 QStringList::const_iterator bit = bl.begin();
511 for (; (ait != al.end()) && (bit != bl.end()); ++ait)
513 QStringList::const_iterator bit2 = bit;
516 for (; bit2 != bl.end(); ++bit2)
520 bscore = std::max(1000, 2000 - (dist * 500));
522 if (ait->length() < 5)
523 bscore /= 5 - ait->length();
528 if (bscore && dist < 3)
530 for (
int i = 0; (i < dist) && bit != bl.end(); ++i)
536 return score / al.size();
541 if (a.isEmpty() || b.isEmpty())
546 QString A = a.simplified().toUpper();
547 QString B = b.simplified().toUpper();
551 QStringList al = A.split(
" ", Qt::SkipEmptyParts);
555 QStringList bl = B.split(
" ", Qt::SkipEmptyParts);
562 return std::min(900, score);
568 int match_val = INT_MIN;
571 for (
size_t i = 0; i < programs.size(); ++i)
574 int duration_loop = programs[i].m_starttime.secsTo(programs[i].
m_endtime);
576 mv -= qAbs(
m_starttime.secsTo(programs[i].m_starttime));
577 mv -= qAbs(
m_endtime.secsTo(programs[i].m_endtime));
578 mv -= qAbs(duration - duration_loop);
588 overlap = programs[i].m_starttime.secsTo(
m_endtime);
610 int min_dur = std::max(2, std::min(duration, duration_loop));
611 overlap = std::min(overlap, min_dur/2);
617 LOG(VB_GENERAL, LOG_ERR,
618 QString(
"Unexpected result: shows don't "
619 "overlap\n\t%1: %2 - %3\n\t%4: %5 - %6")
623 .arg(programs[i].m_title.left(35), 35)
624 .arg(programs[i].m_starttime.toString(
Qt::ISODate),
631 LOG(VB_EIT, LOG_DEBUG,
632 QString(
"GM : '%1' new best match '%2' with score %3")
634 programs[i].m_title.left(35),
635 QString::number(mv)));
645 MSqlQuery &q,
uint chanid,
const std::vector<DBEvent> &
p,
int match)
const
649 for (
size_t i = 0; i <
p.size(); ++i)
651 if (i != (
uint)match)
658 LOG(VB_EIT, LOG_DEBUG,
659 QString(
"EIT: cannot insert '%1' MoveOutOfTheWayDB failed")
665 if ((match < 0) || ((
uint)match >=
p.size()))
667 LOG(VB_EIT, LOG_DEBUG,
668 QString(
"EIT: insert '%1'")
679 QDateTime now = QDateTime::currentDateTimeUtc();
682 LOG(VB_EIT, LOG_DEBUG,
683 QString(
"EIT: skip '%1' starttime is in the past")
690 LOG(VB_EIT, LOG_DEBUG,
691 QString(
"EIT: update '%1' with '%2'")
705 const QDateTime &old_starttime,
706 const QDateTime &new_starttime)
709 "SET starttime = :NEWSTARTTIME, "
710 " startdate = :NEWSTARTDATE "
711 "WHERE chanid = :CHANID "
713 "AND search = :SEARCH "
714 "AND starttime = :OLDSTARTTIME "
715 "AND startdate = :OLDSTARTDATE ");
719 query.
bindValue(
":OLDSTARTTIME", old_starttime.time());
720 query.
bindValue(
":OLDSTARTDATE", old_starttime.date());
721 query.
bindValue(
":NEWSTARTTIME", new_starttime.time());
722 query.
bindValue(
":NEWSTARTDATE", new_starttime.date());
735 LOG(VB_EIT, LOG_DEBUG,
736 QString(
"EIT: Updated record: chanid:%1 old:%3 new:%4 rows:%5")
737 .arg(QString::number(chanid),
740 QString::number(rows)));
764 QDateTime
const &old_starttime = match.
m_starttime;
768 LOG(VB_EIT, LOG_DEBUG,
769 QString(
"EIT: (U) change starttime from %1 to %2 for chanid:%3 program '%4' ")
772 QString::number(chanid),
776 if (ltitle.isEmpty() && !match.
m_title.isEmpty())
779 if (lsubtitle.isEmpty() && !match.
m_subtitle.isEmpty())
785 if (lcategory.isEmpty() && !match.
m_category.isEmpty())
794 if (lprogramId.isEmpty() && !match.
m_programId.isEmpty())
797 if (lseriesId.isEmpty() && !match.
m_seriesId.isEmpty())
800 if (linetref.isEmpty() && !match.
m_inetref.isEmpty())
838 if (lsyndicatedepisodenumber.isEmpty() &&
844 "SET title = :TITLE, subtitle = :SUBTITLE, "
845 " description = :DESC, "
846 " category = :CATEGORY, category_type = :CATTYPE, "
847 " starttime = :STARTTIME, endtime = :ENDTIME, "
848 " closecaptioned = :CC, subtitled = :HASSUBTITLES, "
849 " stereo = :STEREO, hdtv = :HDTV, "
850 " subtitletypes = :SUBTYPE, "
851 " audioprop = :AUDIOPROP, videoprop = :VIDEOPROP, "
852 " season = :SEASON, "
853 " episode = :EPISODE, totalepisodes = :TOTALEPS, "
854 " partnumber = :PARTNO, parttotal = :PARTTOTAL, "
855 " syndicatedepisodenumber = :SYNDICATENO, "
856 " airdate = :AIRDATE, originalairdate=:ORIGAIRDATE, "
857 " listingsource = :LSOURCE, "
858 " seriesid = :SERIESID, programid = :PROGRAMID, "
859 " previouslyshown = :PREVSHOWN, inetref = :INETREF "
860 "WHERE chanid = :CHANID AND "
861 " starttime = :OLDSTART ");
872 query.
bindValue(
":CC", (lsubtype & SUB_HARDHEAR) != 0);
873 query.
bindValue(
":HASSUBTITLES",(lsubtype & SUB_NORMAL) != 0);
874 query.
bindValue(
":STEREO", (laudio & AUD_STEREO) != 0);
875 query.
bindValue(
":HDTV", (lvideo & VID_HDTV) != 0);
881 query.
bindValue(
":TOTALEPS", lepisodeTotal);
883 query.
bindValue(
":PARTTOTAL", lparttotal);
885 query.
bindValue(
":AIRDATE", lairdate ? QString::number(lairdate) :
"0000");
886 query.
bindValue(
":ORIGAIRDATE", loriginalairdate);
887 query.
bindValue(
":LSOURCE", llistingsource);
890 query.
bindValue(
":PREVSHOWN", lpreviouslyshown);
908 "INSERT IGNORE INTO programrating "
909 " ( chanid, starttime, `system`, rating) "
910 "VALUES (:CHANID, :START, :SYS, :RATING)");
928 "DELETE from program "
929 "WHERE chanid = :CHANID AND "
930 " starttime = :STARTTIME");
942 "DELETE from credits "
943 "WHERE chanid = :CHANID AND "
944 " starttime = :STARTTIME");
956 "DELETE from programrating "
957 "WHERE chanid = :CHANID AND "
958 " starttime = :STARTTIME");
970 "DELETE from programgenres "
971 "WHERE chanid = :CHANID AND "
972 " starttime = :STARTTIME");
989 "SELECT title FROM program "
990 "WHERE chanid = :CHANID AND "
991 " starttime = :OLDSTART");
1002 const QDateTime &new_st,
const QDateTime &new_end)
1006 "SET starttime = :NEWSTART, "
1007 " endtime = :NEWEND "
1008 "WHERE chanid = :CHANID AND "
1009 " starttime = :OLDSTART");
1024 "SET starttime = :NEWSTART "
1025 "WHERE chanid = :CHANID AND "
1026 " starttime = :OLDSTART");
1039 "UPDATE programrating "
1040 "SET starttime = :NEWSTART "
1041 "WHERE chanid = :CHANID AND "
1042 " starttime = :OLDSTART");
1055 "UPDATE programgenres "
1056 "SET starttime = :NEWSTART "
1057 "WHERE chanid = :CHANID AND "
1058 " starttime = :OLDSTART");
1082 LOG(VB_EIT, LOG_DEBUG,
1083 QString(
"EIT: delete '%1' %2 - %3")
1096 LOG(VB_EIT, LOG_DEBUG,
1097 QString(
"EIT: change '%1' endtime to %2")
1114 LOG(VB_EIT, LOG_DEBUG,
1115 QString(
"EIT: delete '%1' %2 - %3")
1121 LOG(VB_EIT, LOG_DEBUG,
1122 QString(
"EIT: (M) change starttime from %1 to %2 for chanid:%3 program '%4' ")
1125 QString::number(chanid),
1142 bool recording)
const
1144 QString table = recording ?
"recordedprogram" :
"program";
1148 " chanid, title, subtitle, description, "
1149 " category, category_type, "
1150 " starttime, endtime, "
1151 " closecaptioned, stereo, hdtv, subtitled, "
1152 " subtitletypes, audioprop, videoprop, "
1153 " stars, partnumber, parttotal, "
1154 " syndicatedepisodenumber, "
1155 " airdate, originalairdate,listingsource, "
1156 " seriesid, programid, previouslyshown, "
1157 " season, episode, totalepisodes, "
1160 " :CHANID, :TITLE, :SUBTITLE, :DESCRIPTION, "
1161 " :CATEGORY, :CATTYPE, "
1162 " :STARTTIME, :ENDTIME, "
1163 " :CC, :STEREO, :HDTV, :HASSUBTITLES, "
1164 " :SUBTYPES, :AUDIOPROP, :VIDEOPROP, "
1165 " :STARS, :PARTNUMBER, :PARTTOTAL, "
1167 " :AIRDATE, :ORIGAIRDATE, :LSOURCE, "
1168 " :SERIESID, :PROGRAMID, :PREVSHOWN, "
1169 " :SEASON, :EPISODE, :TOTALEPISODES, "
1170 " :INETREF ) ").arg(table));
1209 table = recording ?
"recordedrating" :
"programrating";
1213 "INSERT IGNORE INTO %1 "
1214 " ( chanid, starttime, `system`, rating) "
1215 "VALUES (:CHANID, :START, :SYS, :RATING)").arg(table));
1228 credit.InsertDB(query, chanid,
m_starttime, recording);
1237 DBEvent(other.m_listingsource)
1297 bool recording)
const
1299 QString table = recording ?
"recordedprogram" :
"program";
1301 LOG(VB_XMLTV, LOG_DEBUG,
1302 QString(
"Inserting new %1 : %2 - %3 %4 %5")
1310 " chanid, title, subtitle, description, "
1311 " category, category_type, "
1312 " starttime, endtime, "
1313 " closecaptioned, stereo, hdtv, subtitled, "
1314 " subtitletypes, audioprop, videoprop, "
1315 " partnumber, parttotal, "
1316 " syndicatedepisodenumber, "
1317 " airdate, originalairdate,listingsource, "
1318 " seriesid, programid, previouslyshown, "
1319 " stars, showtype, title_pronounce, colorcode, "
1320 " season, episode, totalepisodes, "
1323 " :CHANID, :TITLE, :SUBTITLE, :DESCRIPTION, "
1324 " :CATEGORY, :CATTYPE, "
1325 " :STARTTIME, :ENDTIME, "
1326 " :CC, :STEREO, :HDTV, :HASSUBTITLES, "
1327 " :SUBTYPES, :AUDIOPROP, :VIDEOPROP, "
1328 " :PARTNUMBER, :PARTTOTAL, "
1330 " :AIRDATE, :ORIGAIRDATE, :LSOURCE, "
1331 " :SERIESID, :PROGRAMID, :PREVSHOWN, "
1332 " :STARS, :SHOWTYPE, :TITLEPRON, :COLORCODE, "
1333 " :SEASON, :EPISODE, :TOTALEPISODES, "
1334 " :INETREF )").arg(table));
1381 table = recording ?
"recordedrating" :
"programrating";
1384 query.
prepare(QString(
"INSERT IGNORE INTO %1 "
1385 " ( chanid, starttime, `system`, rating) "
1386 "VALUES (:CHANID, :START, :SYS, :RATING)")
1400 credit.InsertDB(query, chanid,
m_starttime, recording);
1409 uint chanid,
const QDateTime &from,
const QDateTime &to,
1410 bool use_channel_time_offset)
1412 std::chrono::seconds secs = 0s;
1413 if (use_channel_time_offset)
1416 QDateTime newFrom = from.addSecs(secs.count());
1417 QDateTime newTo = to.addSecs(secs.count());
1420 query.
prepare(
"DELETE FROM program "
1421 "WHERE starttime >= :FROM AND starttime < :TO "
1422 "AND chanid = :CHANID ;");
1426 bool ok = query.
exec();
1428 query.
prepare(
"DELETE FROM programrating "
1429 "WHERE starttime >= :FROM AND starttime < :TO "
1430 "AND chanid = :CHANID ;");
1436 query.
prepare(
"DELETE FROM credits "
1437 "WHERE starttime >= :FROM AND starttime < :TO "
1438 "AND chanid = :CHANID ;");
1444 query.
prepare(
"DELETE FROM programgenres "
1445 "WHERE starttime >= :FROM AND starttime < :TO "
1446 "AND chanid = :CHANID ;");
1456 uint sourceid,
const QDateTime &from,
const QDateTime &to,
1457 bool use_channel_time_offset)
1462 auto cleardata = [&](
uint chanid)
1464 std::ranges::for_each(chanids, cleardata);
1479 QList<ProgInfo*>::iterator it = fixlist.begin();
1482 QList<ProgInfo*>::iterator cur = it;
1486 if ((*cur)->m_endts.isEmpty() || (*cur)->m_startts > (*cur)->m_endts)
1488 if (it != fixlist.end())
1490 (*cur)->m_endts = (*it)->m_startts;
1491 (*cur)->m_endtime = (*it)->m_starttime;
1498 if (it == fixlist.end())
1502 if ((*cur)->HasTimeConflict(**it))
1504 QList<ProgInfo*>::iterator tokeep;
1505 QList<ProgInfo*>::iterator todelete;
1507 if ((*cur)->m_endtime <= (*cur)->m_starttime)
1508 tokeep = it, todelete = cur;
1509 else if ((*it)->m_endtime <= (*it)->m_starttime)
1510 tokeep = cur, todelete = it;
1511 else if (!(*cur)->m_subtitle.isEmpty() &&
1512 (*it)->m_subtitle.isEmpty())
1513 tokeep = cur, todelete = it;
1514 else if (!(*it)->m_subtitle.isEmpty() &&
1515 (*cur)->m_subtitle.isEmpty())
1516 tokeep = it, todelete = cur;
1517 else if (!(*cur)->m_description.isEmpty() &&
1518 (*it)->m_description.isEmpty())
1519 tokeep = cur, todelete = it;
1521 tokeep = it, todelete = cur;
1524 LOG(VB_XMLTV, LOG_DEBUG,
1525 QString(
"Removing conflicting program: %1 - %2 %3 %4")
1526 .arg((*todelete)->m_starttime.toString(
Qt::ISODate),
1528 (*todelete)->m_channel,
1529 (*todelete)->m_title));
1531 LOG(VB_XMLTV, LOG_DEBUG,
1532 QString(
"Conflicted with : %1 - %2 %3 %4")
1533 .arg((*tokeep)->m_starttime.toString(
Qt::ISODate),
1535 (*tokeep)->m_channel,
1536 (*tokeep)->m_title));
1538 bool step_back = todelete == it;
1539 it = fixlist.erase(todelete);
1555 uint sourceid, QMap<QString, QList<ProgInfo> > &proglist)
1562 QMap<QString, QList<ProgInfo> >::const_iterator mapiter;
1563 for (mapiter = proglist.cbegin(); mapiter != proglist.cend(); ++mapiter)
1565 if (mapiter.key().isEmpty())
1571 "WHERE deleted IS NULL AND "
1572 " sourceid = :ID AND "
1573 " xmltvid = :XMLTVID");
1575 query.
bindValue(
":XMLTVID", mapiter.key());
1583 std::vector<uint> chanids;
1584 while (query.
next())
1585 chanids.push_back(query.
value(0).toUInt());
1587 if (chanids.empty())
1589 LOG(VB_GENERAL, LOG_NOTICE,
1590 QString(
"Unknown xmltv channel identifier: %1"
1591 " - Skipping channel.").arg(mapiter.key()));
1595 QList<ProgInfo> &list = proglist[mapiter.key()];
1596 QList<ProgInfo*> sortlist;
1598 for (
auto it = list.begin(); it != list.end(); ++it)
1599 sortlist.push_back(&(*it));
1603 for (
uint chanid : chanids)
1607 LOG(VB_GENERAL, LOG_INFO,
1608 QString(
"Updated programs: %1 Unchanged programs: %2")
1609 .arg(updated) .arg(unchanged));
1625 const QList<ProgInfo*> &sortlist,
1629 for (
auto *pinfo : std::as_const(sortlist))
1640 updated += pinfo->InsertDB(query, chanid);
1654 querystr =
"SELECT chanid, starttime, endtime FROM program "
1655 "WHERE endtime = '0000-00-00 00:00:00' "
1656 "ORDER BY chanid, starttime;";
1658 if (!query1.
exec(querystr))
1660 LOG(VB_GENERAL, LOG_ERR,
1661 QString(
"fix_end_times query failed: %1").arg(querystr));
1665 while (query1.
next())
1667 starttime = query1.
value(1).toString();
1668 chanid = query1.
value(0).toString();
1669 endtime = query1.
value(2).toString();
1671 querystr = QString(
"SELECT chanid, starttime, endtime FROM program "
1672 "WHERE starttime > '%1' "
1673 "AND chanid = '%2' "
1674 "ORDER BY starttime LIMIT 1;")
1675 .arg(starttime, chanid);
1677 if (!query2.
exec(querystr))
1679 LOG(VB_GENERAL, LOG_ERR,
1680 QString(
"fix_end_times query failed: %1").arg(querystr));
1684 if (query2.
next() && (endtime != query2.
value(1).toString()))
1687 endtime = query2.
value(1).toString();
1688 querystr = QString(
"UPDATE program SET "
1689 "endtime = '%2' WHERE (chanid = '%3' AND "
1690 "starttime = '%4');")
1691 .arg(endtime, chanid, starttime);
1693 if (!query2.
exec(querystr))
1695 LOG(VB_GENERAL, LOG_ERR,
1696 QString(
"fix_end_times query failed: %1").arg(querystr));
1711 "WHERE chanid = :CHANID AND "
1712 " starttime = :START AND "
1713 " endtime = :END AND "
1714 " title = :TITLE AND "
1715 " subtitle = :SUBTITLE AND "
1716 " description = :DESC AND "
1717 " category = :CATEGORY AND "
1718 " category_type = :CATEGORY_TYPE AND "
1719 " airdate = :AIRDATE AND "
1720 " stars >= (:STARS1 - 0.001) AND "
1721 " stars <= (:STARS2 + 0.001) AND "
1722 " previouslyshown = :PREVIOUSLYSHOWN AND "
1723 " title_pronounce = :TITLE_PRONOUNCE AND "
1724 " audioprop = :AUDIOPROP AND "
1725 " videoprop = :VIDEOPROP AND "
1726 " subtitletypes = :SUBTYPES AND "
1727 " partnumber = :PARTNUMBER AND "
1728 " parttotal = :PARTTOTAL AND "
1729 " seriesid = :SERIESID AND "
1730 " showtype = :SHOWTYPE AND "
1731 " colorcode = :COLORCODE AND "
1732 " syndicatedepisodenumber = :SYNDICATEDEPISODENUMBER AND "
1733 " programid = :PROGRAMID AND "
1734 " season = :SEASON AND "
1735 " episode = :EPISODE AND "
1736 " totalepisodes = :TOTALEPISODES AND "
1737 " inetref = :INETREF");
1748 query.
bindValue(
":CATEGORY_TYPE", cattype);
1762 query.
bindValue(
":SYNDICATEDEPISODENUMBER",
1771 return query.
value(0).toUInt() > 0;
1783 "SELECT title,starttime,endtime "
1785 "WHERE chanid = :CHANID AND "
1786 " starttime >= :START AND "
1787 " starttime < :END;");
1795 while (query.
next())
1797 LOG(VB_XMLTV, LOG_DEBUG,
1798 QString(
"Removing existing program: %1 - %2 %3 %4")
1802 query.
value(0).toString()));
1805 if (query.
at() == QSql::BeforeFirstRow)
1814 LOG(VB_XMLTV, LOG_ERR,
1815 QString(
"Program delete failed : %1 - %2 %3 %4")
static std::vector< uint > GetChanIDs(int sourceid=-1, bool onlyVisible=false)
static std::chrono::minutes GetTimeOffset(int chan_id)
Returns the listings time offset in minutes for given channel.
virtual void Squeeze(void)
bool HasTimeConflict(const DBEvent &other) const
int GetMatch(const std::vector< DBEvent > &programs, int &bestmatch) const
unsigned char m_subtitleType
ProgramInfo::CategoryType m_categoryType
uint UpdateDB(MSqlQuery &query, uint chanid, int match_threshold) const
QDate m_originalairdate
origial broadcast date
unsigned char m_audioProps
QList< EventRating > m_ratings
uint16_t m_airdate
movie year / production year
void AddPerson(DBPerson::Role role, const QString &name, int priority=0, const QString &character="")
virtual uint InsertDB(MSqlQuery &query, uint chanid, bool recording=false) const
Insert Callback function when Allow Re-record is pressed in Watch Recordings.
DBEvent & operator=(const DBEvent &other)
uint GetOverlappingPrograms(MSqlQuery &query, uint chanid, std::vector< DBEvent > &programs) const
bool MoveOutOfTheWayDB(MSqlQuery &query, uint chanid, const DBEvent &prog) const
QString m_syndicatedepisodenumber
uint InsertPersonDB(MSqlQuery &query) const
uint InsertCreditsDB(MSqlQuery &query, uint personid, uint roleid, uint chanid, const QDateTime &starttime, bool recording=false) const
DBPerson(const DBPerson &other)
uint GetRoleDB(MSqlQuery &query) const
uint GetPersonDB(MSqlQuery &query) const
DBPerson & operator=(const DBPerson &rhs)
QString GetRole(void) const
QString toString(void) const
uint InsertDB(MSqlQuery &query, uint chanid, const QDateTime &starttime, bool recording=false) const
bool InsertRoleDB(MSqlQuery &query) const
QSqlQuery wrapper that fetches a DB connection from the connection pool.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QVariant value(int i) const
int numRowsAffected() const
bool isActive(void) const
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
static void DBError(const QString &where, const MSqlQuery &query)
ProgInfo & operator=(const ProgInfo &other)
void Squeeze(void) override
uint InsertDB(MSqlQuery &query, uint chanid, bool recording=false) const override
Insert a single entry into the "program" database.
QString m_title_pronounce
static void HandlePrograms(uint sourceid, QMap< QString, QList< ProgInfo > > &proglist)
Called from mythfilldatabase to bulk insert data into the program database.
static int fix_end_times(void)
static bool ClearDataBySource(uint sourceid, const QDateTime &from, const QDateTime &to, bool use_channel_time_offset)
static bool DeleteOverlaps(MSqlQuery &query, uint chanid, const ProgInfo &pi)
static void FixProgramList(QList< ProgInfo * > &fixlist)
static bool ClearDataByChannel(uint chanid, const QDateTime &from, const QDateTime &to, bool use_channel_time_offset)
static bool IsUnchanged(MSqlQuery &query, uint chanid, const ProgInfo &pi)
@ kUnknown
Unprocessable file type.
static bool VERBOSE_LEVEL_CHECK(uint64_t mask, LogLevel_t level)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
QDateTime as_utc(const QDateTime &old_dt)
Returns copy of QDateTime with TimeSpec set to UTC.
def rating(profile, smoonURL, gate)
static bool program_exists(MSqlQuery &query, uint chanid, const QDateTime &st)
static void add_genres(MSqlQuery &query, const QStringList &genres, uint chanid, const QDateTime &starttime)
static bool delete_program(MSqlQuery &query, uint chanid, const QDateTime &st)
static bool start_time_less_than(const DBEvent *a, const DBEvent *b)
static const std::array< const std::string, DBPerson::kGuest+1 > roles
static QString denullify(const QString &str)
static int score_match(const QString &a, const QString &b)
static bool change_program(MSqlQuery &query, uint chanid, const QDateTime &st, const QDateTime &new_st, const QDateTime &new_end)
static int score_words(const QStringList &al, const QStringList &bl)
static int change_record(MSqlQuery &query, uint chanid, const QDateTime &old_starttime, const QDateTime &new_starttime)
std::vector< DBPerson > DBCredits
QString myth_category_type_to_string(ProgramInfo::CategoryType category_type)
ProgramInfo::CategoryType string_to_myth_category_type(const QString &category_type)