diff --git a/mythplugins/mytharchive/mytharchive/archivesettings.cpp b/mythplugins/mytharchive/mytharchive/archivesettings.cpp index 4e70e9f7b8f..18e5e55e0a9 100644 --- a/mythplugins/mytharchive/mytharchive/archivesettings.cpp +++ b/mythplugins/mytharchive/mytharchive/archivesettings.cpp @@ -78,7 +78,7 @@ static HostFileBrowserSetting *MythArchiveDVDLocation() gc->setHelpText(ArchiveSettings::tr("Which DVD drive to use when burning " "discs.")); - gc->SetTypeFilter(QDir::AllDirs | QDir::Hidden); + gc->SetTypeFilter(QDir::AllDirs | QDir::Files | QDir::System | QDir::Hidden); return gc; }; diff --git a/mythplugins/mythmusic/mythmusic/pls.cpp b/mythplugins/mythmusic/mythmusic/pls.cpp index 9c353afce98..b6fab8953b4 100644 --- a/mythplugins/mythmusic/mythmusic/pls.cpp +++ b/mythplugins/mythmusic/mythmusic/pls.cpp @@ -131,7 +131,7 @@ int PlayListFile::parseASX(PlayListFile *pls, const QString &filename) } file.close(); - QDomElement docElem = doc.documentElement(); + //QDomElement docElem = doc.documentElement(); QDomNodeList entryList = doc.elementsByTagName("Entry"); QString url; diff --git a/mythtv/libs/libmyth/output.h b/mythtv/libs/libmyth/output.h index 2e15c6b36df..7c38cebc188 100644 --- a/mythtv/libs/libmyth/output.h +++ b/mythtv/libs/libmyth/output.h @@ -114,6 +114,8 @@ class MPUBLIC OutputListeners : public MythObservable void prepareVisuals(); private: + Q_DISABLE_COPY(OutputListeners) + QMutex m_mtx; Visuals m_visuals; diff --git a/mythtv/libs/libmythbase/codecutil.cpp b/mythtv/libs/libmythbase/codecutil.cpp index 168d7dced54..c6ab134608d 100644 --- a/mythtv/libs/libmythbase/codecutil.cpp +++ b/mythtv/libs/libmythbase/codecutil.cpp @@ -14,5 +14,6 @@ bool CodecUtil::isValidUTF8(const QByteArray& data) if (state.invalidChars > 0) return false; + Q_UNUSED(text); return true; } diff --git a/mythtv/libs/libmythbase/hardwareprofile.cpp b/mythtv/libs/libmythbase/hardwareprofile.cpp index e7c3fb2a925..db60a8d16ca 100644 --- a/mythtv/libs/libmythbase/hardwareprofile.cpp +++ b/mythtv/libs/libmythbase/hardwareprofile.cpp @@ -157,7 +157,7 @@ QString HardwareProfile::GetAdminPasswordFromFile() const return ret; } -bool HardwareProfile::WritePrivateUUIDToFile(QString uuid) +bool HardwareProfile::WritePrivateUUIDToFile(const QString &uuid) { QString hwuuid_file = GetConfDir() + "/HardwareProfile/hw-uuid"; QFile file(hwuuid_file); diff --git a/mythtv/libs/libmythbase/hardwareprofile.h b/mythtv/libs/libmythbase/hardwareprofile.h index 21dae6be8ae..cd5e08556fc 100644 --- a/mythtv/libs/libmythbase/hardwareprofile.h +++ b/mythtv/libs/libmythbase/hardwareprofile.h @@ -27,7 +27,7 @@ class MBASE_PUBLIC HardwareProfile : public QObject void GenerateUUIDs(void); QString GetPrivateUUIDFromFile(void) const; - bool WritePrivateUUIDToFile(QString uuid); + bool WritePrivateUUIDToFile(const QString &uuid); QString GetPublicUUIDFromFile(void) const; QString GetAdminPasswordFromFile(void) const; diff --git a/mythtv/libs/libmythbase/iso639.cpp b/mythtv/libs/libmythbase/iso639.cpp index 1761de7f1ff..1940fc71adf 100644 --- a/mythtv/libs/libmythbase/iso639.cpp +++ b/mythtv/libs/libmythbase/iso639.cpp @@ -957,7 +957,7 @@ static ISO639ToNameMap createLanguageMap(void) static ISO639ToNameMap gLanguageMap; -QString GetISO639LanguageName(QString iso639_1) +QString GetISO639LanguageName(const QString &iso639_1) { if (gLanguageMap.isEmpty()) gLanguageMap = createLanguageMap(); @@ -965,7 +965,7 @@ QString GetISO639LanguageName(QString iso639_1) return gLanguageMap[iso639_1]; } -QString GetISO639EnglishLanguageName(QString iso639_1) +QString GetISO639EnglishLanguageName(const QString &iso639_1) { QString iso639_2 = iso639_str2_to_str3(iso639_1); int key2 = iso639_str3_to_key(iso639_2); diff --git a/mythtv/libs/libmythbase/iso639.h b/mythtv/libs/libmythbase/iso639.h index 0a3f07df561..3939ef58fe9 100644 --- a/mythtv/libs/libmythbase/iso639.h +++ b/mythtv/libs/libmythbase/iso639.h @@ -102,7 +102,7 @@ static inline QString iso639_str_to_canonoical_str(const QString &str3) return iso639_key_to_str3(can); } -MBASE_PUBLIC QString GetISO639LanguageName(QString iso639Code); -MBASE_PUBLIC QString GetISO639EnglishLanguageName(QString iso639Code); +MBASE_PUBLIC QString GetISO639LanguageName(const QString &iso639Code); +MBASE_PUBLIC QString GetISO639EnglishLanguageName(const QString &iso639Code); #endif // _ISO_639_2_H_ diff --git a/mythtv/libs/libmythbase/mythcommandlineparser.h b/mythtv/libs/libmythbase/mythcommandlineparser.h index b7b4c5ced23..3d199dbb48e 100644 --- a/mythtv/libs/libmythbase/mythcommandlineparser.h +++ b/mythtv/libs/libmythbase/mythcommandlineparser.h @@ -24,9 +24,9 @@ class MBASE_PUBLIC CommandLineArg : public ReferenceCounter explicit CommandLineArg(QString name); ~CommandLineArg() = default; - CommandLineArg* SetGroup(QString group) { m_group = group; + CommandLineArg* SetGroup(const QString &group) { m_group = group; return this; } - void AddKeyword(QString keyword) { m_keywords << keyword; } + void AddKeyword(const QString &keyword) { m_keywords << keyword; } QString GetName(void) const { return m_name; } QString GetUsedKeyword(void) const { return m_usedKeyword; } diff --git a/mythtv/libs/libmythbase/mythcorecontext.h b/mythtv/libs/libmythbase/mythcorecontext.h index 45bde001cbf..21080bc3c50 100644 --- a/mythtv/libs/libmythbase/mythcorecontext.h +++ b/mythtv/libs/libmythbase/mythcorecontext.h @@ -263,6 +263,7 @@ class MBASE_PUBLIC MythCoreContext : public QObject, public MythObservable, publ void TVPlaybackPlaying(void); private: + Q_DISABLE_COPY(MythCoreContext) MythCoreContextPrivate *d {nullptr}; void connected(MythSocket *sock) override { (void)sock; } //MythSocketCBs diff --git a/mythtv/libs/libmythbase/mythdbcon.cpp b/mythtv/libs/libmythbase/mythdbcon.cpp index 23e9084c09d..d428da8c018 100644 --- a/mythtv/libs/libmythbase/mythdbcon.cpp +++ b/mythtv/libs/libmythbase/mythdbcon.cpp @@ -282,7 +282,7 @@ MDBManager::~MDBManager() { CloseDatabases(); - if (m_connCount != 0 || m_schedCon || m_DDCon) + if (m_connCount != 0 || m_schedCon || m_channelCon) { LOG(VB_GENERAL, LOG_CRIT, "MDBManager exiting with connections still open"); @@ -290,7 +290,7 @@ MDBManager::~MDBManager() #if 0 /* some post logStop() debugging... */ cout<<"m_connCount: "<GetDBManager()->getDDCon(); + MSqlDatabase *db = GetMythDB()->GetDBManager()->getChannelCon(); MSqlQueryInfo qi; InitMSqlQueryInfo(qi); diff --git a/mythtv/libs/libmythbase/mythdbcon.h b/mythtv/libs/libmythbase/mythdbcon.h index cfe34ec5a5d..0bd7976728d 100644 --- a/mythtv/libs/libmythbase/mythdbcon.h +++ b/mythtv/libs/libmythbase/mythdbcon.h @@ -65,7 +65,7 @@ class MBASE_PUBLIC MDBManager void pushConnection(MSqlDatabase *db); MSqlDatabase *getSchedCon(void); - MSqlDatabase *getDDCon(void); + MSqlDatabase *getChannelCon(void); private: MSqlDatabase *getStaticCon(MSqlDatabase **dbcon, QString name); @@ -82,7 +82,7 @@ class MBASE_PUBLIC MDBManager int m_connCount {0}; MSqlDatabase *m_schedCon {nullptr}; - MSqlDatabase *m_DDCon {nullptr}; + MSqlDatabase *m_channelCon {nullptr}; QHash m_static_pool; }; @@ -208,7 +208,7 @@ class MBASE_PUBLIC MSqlQuery : private QSqlQuery static MSqlQueryInfo SchedCon(); /// \brief Returns dedicated connection. (Required for using temporary SQL tables.) - static MSqlQueryInfo DDCon(); + static MSqlQueryInfo ChannelCon(); private: // Only QSql::In is supported as a param type and only named params... diff --git a/mythtv/libs/libmythbase/mythlocale.cpp b/mythtv/libs/libmythbase/mythlocale.cpp index 82232661d8b..6d63f3e5899 100644 --- a/mythtv/libs/libmythbase/mythlocale.cpp +++ b/mythtv/libs/libmythbase/mythlocale.cpp @@ -13,7 +13,7 @@ #include "iso3166.h" #include "iso639.h" -MythLocale::MythLocale(QString localeName) +MythLocale::MythLocale(const QString &localeName) { Init(localeName); } diff --git a/mythtv/libs/libmythbase/mythlocale.h b/mythtv/libs/libmythbase/mythlocale.h index 506b915f700..6834571431a 100644 --- a/mythtv/libs/libmythbase/mythlocale.h +++ b/mythtv/libs/libmythbase/mythlocale.h @@ -12,7 +12,7 @@ class MBASE_PUBLIC MythLocale { public: - explicit MythLocale(QString localeName = QString()); + explicit MythLocale(const QString &localeName = QString()); ~MythLocale() = default; void ReInit(); diff --git a/mythtv/libs/libmythbase/mythobservable.h b/mythtv/libs/libmythbase/mythobservable.h index 04d326ed674..60cb7e081f0 100644 --- a/mythtv/libs/libmythbase/mythobservable.h +++ b/mythtv/libs/libmythbase/mythobservable.h @@ -22,6 +22,9 @@ class MBASE_PUBLIC MythObservable bool hasListeners(void) { return !m_listeners.isEmpty(); } + private: + Q_DISABLE_COPY(MythObservable) + protected: QMutex *m_lock {nullptr}; QSet m_listeners; diff --git a/mythtv/libs/libmythbase/mythsorthelper.cpp b/mythtv/libs/libmythbase/mythsorthelper.cpp index 642c42d8f45..e36edb9649b 100644 --- a/mythtv/libs/libmythbase/mythsorthelper.cpp +++ b/mythtv/libs/libmythbase/mythsorthelper.cpp @@ -79,7 +79,7 @@ MythSortHelper::MythSortHelper() MythSortHelper::MythSortHelper( Qt::CaseSensitivity case_sensitive, SortPrefixMode prefix_mode, - QString exclusions) : + const QString &exclusions) : m_case_sensitive(case_sensitive), m_prefix_mode(prefix_mode), m_exclusions(exclusions) diff --git a/mythtv/libs/libmythbase/mythsorthelper.h b/mythtv/libs/libmythbase/mythsorthelper.h index 97a5af77c1d..d481d905635 100644 --- a/mythtv/libs/libmythbase/mythsorthelper.h +++ b/mythtv/libs/libmythbase/mythsorthelper.h @@ -31,8 +31,9 @@ class MBASE_PUBLIC MythSortHelper public: MythSortHelper(); - MythSortHelper(MythSortHelper *other); - MythSortHelper(Qt::CaseSensitivity case_sensitve, SortPrefixMode prefix_mode, QString exclusions); + explicit MythSortHelper(MythSortHelper *other); + MythSortHelper(Qt::CaseSensitivity case_sensitve, SortPrefixMode prefix_mode, + const QString &exclusions); QString doTitle(const QString& title) const; QString doPathname(const QString& filename) const; diff --git a/mythtv/libs/libmythbase/mythstorage.cpp b/mythtv/libs/libmythbase/mythstorage.cpp index bb46464ee50..f4c58b99578 100644 --- a/mythtv/libs/libmythbase/mythstorage.cpp +++ b/mythtv/libs/libmythbase/mythstorage.cpp @@ -31,13 +31,13 @@ void SimpleDBStorage::Load(void) } } -void SimpleDBStorage::Save(QString _table) +void SimpleDBStorage::Save(const QString &table) { if (!IsSaveRequired()) return; MSqlBindings bindings; - QString querystr = "SELECT * FROM " + _table + " WHERE " + QString querystr = "SELECT * FROM " + table + " WHERE " + GetWhereClause(bindings) + ';'; MSqlQuery query(MSqlQuery::InitCon()); @@ -54,7 +54,7 @@ void SimpleDBStorage::Save(QString _table) { // Row already exists // Don"t change this QString. See the CVS logs rev 1.91. - querystr = "UPDATE " + _table + " SET " + GetSetClause(bindings) + + querystr = "UPDATE " + table + " SET " + GetSetClause(bindings) + " WHERE " + GetWhereClause(bindings) + ';'; query.prepare(querystr); @@ -66,7 +66,7 @@ void SimpleDBStorage::Save(QString _table) else { // Row does not exist yet - querystr = "INSERT INTO " + _table + " SET " + querystr = "INSERT INTO " + table + " SET " + GetSetClause(bindings) + ';'; query.prepare(querystr); diff --git a/mythtv/libs/libmythbase/mythstorage.h b/mythtv/libs/libmythbase/mythstorage.h index a055830e58c..799dacab9dc 100644 --- a/mythtv/libs/libmythbase/mythstorage.h +++ b/mythtv/libs/libmythbase/mythstorage.h @@ -26,7 +26,7 @@ class MBASE_PUBLIC Storage virtual void Load(void) = 0; virtual void Save(void) = 0; - virtual void Save(QString /*destination*/) { } + virtual void Save(const QString &/*destination*/) { } virtual bool IsSaveRequired(void) const { return true; }; virtual void SetSaveRequired(void) { }; }; @@ -34,8 +34,8 @@ class MBASE_PUBLIC Storage class MBASE_PUBLIC DBStorage : public Storage { public: - DBStorage(StorageUser *_user, QString _table, QString _column) : - m_user(_user), m_tablename(_table), m_columnname(_column) { } + DBStorage(StorageUser *user, const QString &table, const QString &column) : + m_user(user), m_tablename(table), m_columnname(column) { } virtual ~DBStorage() = default; @@ -51,14 +51,14 @@ class MBASE_PUBLIC DBStorage : public Storage class MBASE_PUBLIC SimpleDBStorage : public DBStorage { public: - SimpleDBStorage(StorageUser *_user, - QString _table, QString _column) : - DBStorage(_user, _table, _column) { m_initval.clear(); } + SimpleDBStorage(StorageUser *user, + const QString &table, const QString &column) : + DBStorage(user, table, column) { m_initval.clear(); } virtual ~SimpleDBStorage() = default; void Load(void) override; // Storage void Save(void) override; // Storage - void Save(QString destination) override; // Storage + void Save(const QString &destination) override; // Storage bool IsSaveRequired(void) const override; // Storage void SetSaveRequired(void) override; // Storage @@ -73,11 +73,11 @@ class MBASE_PUBLIC SimpleDBStorage : public DBStorage class MBASE_PUBLIC GenericDBStorage : public SimpleDBStorage { public: - GenericDBStorage(StorageUser *_user, - QString _table, QString _column, - QString _keycolumn, QString _keyvalue = QString()) : - SimpleDBStorage(_user, _table, _column), - m_keycolumn(_keycolumn), m_keyvalue(_keyvalue) {} + GenericDBStorage(StorageUser *user, + const QString &table, const QString &column, + const QString &keycolumn, const QString &keyvalue = QString()) : + SimpleDBStorage(user, table, column), + m_keycolumn(keycolumn), m_keyvalue(keyvalue) {} virtual ~GenericDBStorage() = default; void SetKeyValue(const QString &val) { m_keyvalue = val; } @@ -100,7 +100,7 @@ class MBASE_PUBLIC TransientStorage : public Storage void Load(void) override { } // Storage void Save(void) override { } // Storage - void Save(QString /*destination*/) override { } // Storage + void Save(const QString &/*destination*/) override { } // Storage }; class MBASE_PUBLIC HostDBStorage : public SimpleDBStorage diff --git a/mythtv/libs/libmythbase/mythsystem.cpp b/mythtv/libs/libmythbase/mythsystem.cpp index cbdccd7f3bb..19212aedf3a 100644 --- a/mythtv/libs/libmythbase/mythsystem.cpp +++ b/mythtv/libs/libmythbase/mythsystem.cpp @@ -50,9 +50,6 @@ class MythSystemLegacyWrapper : public MythSystem if (args.empty()) return nullptr; - QString program = args[0]; - QStringList other_args = args.mid(1); - MythSystemLegacy *legacy = new MythSystemLegacy(args.join(" "), flags); diff --git a/mythtv/libs/libmythbase/portchecker.cpp b/mythtv/libs/libmythbase/portchecker.cpp index c337bdd457b..ff9a8393e5e 100644 --- a/mythtv/libs/libmythbase/portchecker.cpp +++ b/mythtv/libs/libmythbase/portchecker.cpp @@ -101,7 +101,9 @@ bool PortChecker::checkPort(QString &host, int port, int timeLimit, bool linkLoc return false; } QList cards = QNetworkInterface::allInterfaces(); +#ifndef _WIN32 QListIterator iCard = cards; +#endif MythTimer timer(MythTimer::kStartRunning); QTcpSocket socket(this); QAbstractSocket::SocketState state = QAbstractSocket::UnconnectedState; diff --git a/mythtv/libs/libmythservicecontracts/service.h b/mythtv/libs/libmythservicecontracts/service.h index b87995d94aa..fed7eb30476 100644 --- a/mythtv/libs/libmythservicecontracts/service.h +++ b/mythtv/libs/libmythservicecontracts/service.h @@ -71,7 +71,10 @@ class SERVICE_PUBLIC Service : public QObject // ////////////////////////////////////////////////////////////////////////////// -inline Service::Service(QObject *parent) : QObject(parent) {} +inline Service::Service(QObject *parent) : QObject(parent) +{ + qRegisterMetaType< QFileInfo >(); +} ////////////////////////////////////////////////////////////////////////////// // diff --git a/mythtv/libs/libmythtv/avfringbuffer.h b/mythtv/libs/libmythtv/avfringbuffer.h index a5a6f2d77c6..b375991eb0c 100644 --- a/mythtv/libs/libmythtv/avfringbuffer.h +++ b/mythtv/libs/libmythtv/avfringbuffer.h @@ -37,7 +37,7 @@ class AVFRingBuffer private: RingBuffer *m_rbuffer {nullptr}; - bool m_initState; + bool m_initState {true}; static bool s_avrprotocol_initialised; static URLProtocol s_avfrURL; }; diff --git a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp index 2bf5b011d8b..d688667723b 100644 --- a/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp +++ b/mythtv/libs/libmythtv/channelscan/channelscan_sm.cpp @@ -275,7 +275,7 @@ void ChannelScanSM::HandleAllGood(void) } else { - // nothing to do here, XMLTV & DataDirect have better info + // nothing to do here, XMLTV has better info } m_scanMonitor->ScanAppendTextToLog(msg); diff --git a/mythtv/libs/libmythtv/channelscan/externrecscanner.h b/mythtv/libs/libmythtv/channelscan/externrecscanner.h index da92b162403..b8e679da98d 100644 --- a/mythtv/libs/libmythtv/channelscan/externrecscanner.h +++ b/mythtv/libs/libmythtv/channelscan/externrecscanner.h @@ -44,7 +44,7 @@ class ExternRecChannelScanner : public QRunnable uint m_cardid; QString m_inputname; uint m_sourceid; - uint m_channel_total; + uint m_channel_total {0}; uint m_channel_cnt {1}; bool m_thread_running {false}; bool m_stop_now {false}; diff --git a/mythtv/libs/libmythtv/channelsettings.cpp b/mythtv/libs/libmythtv/channelsettings.cpp index 15ca718386a..8b6d41c56bb 100644 --- a/mythtv/libs/libmythtv/channelsettings.cpp +++ b/mythtv/libs/libmythtv/channelsettings.cpp @@ -177,8 +177,7 @@ class TimeOffset : public MythUISpinBoxSetting setHelpText(QCoreApplication::translate("(ChannelSettings)", "Offset (in minutes) to apply to the program guide data during " "import. This can be used when the listings for a particular " - "channel are in a different time zone. (Works for DataDirect " - "listings only.)")); + "channel are in a different time zone.")); } }; diff --git a/mythtv/libs/libmythtv/channelutil.cpp b/mythtv/libs/libmythtv/channelutil.cpp index cdf63486369..f61a542faf4 100644 --- a/mythtv/libs/libmythtv/channelutil.cpp +++ b/mythtv/libs/libmythtv/channelutil.cpp @@ -1392,7 +1392,7 @@ static uint get_max_chanid(uint sourceid) QString qstr = "SELECT MAX(chanid) FROM channel "; qstr += (sourceid) ? "WHERE sourceid = :SOURCEID" : ""; - MSqlQuery query(MSqlQuery::DDCon()); + MSqlQuery query(MSqlQuery::ChannelCon()); query.prepare(qstr); if (sourceid) @@ -1410,7 +1410,7 @@ static uint get_max_chanid(uint sourceid) static bool chanid_available(uint chanid) { - MSqlQuery query(MSqlQuery::DDCon()); + MSqlQuery query(MSqlQuery::ChannelCon()); query.prepare( "SELECT chanid " "FROM channel " diff --git a/mythtv/libs/libmythtv/datadirect.cpp b/mythtv/libs/libmythtv/datadirect.cpp deleted file mode 100644 index a4f7fe29d3e..00000000000 --- a/mythtv/libs/libmythtv/datadirect.cpp +++ /dev/null @@ -1,2369 +0,0 @@ -#include -#include -#undef Z_NULL -#define Z_NULL nullptr - -// Qt headers -#include -#include -#include -#include -#include - -// MythTV headers -#include "datadirect.h" -#include "sourceutil.h" -#include "channelutil.h" -#include "frequencytables.h" -#include "listingsources.h" -#include "mythmiscutil.h" -#include "mythcontext.h" -#include "mythdb.h" -#include "mythlogging.h" -#include "mythversion.h" -#include "mythdate.h" -#include "dbutil.h" -#include "mythsystemlegacy.h" -#include "exitcodes.h" -#include "mythdownloadmanager.h" -#include "mythtvexp.h" -#include "mythdate.h" - -#define LOC QString("DataDirect: ") - -static QMutex user_agent_lock; -static QString user_agent; - -static QMutex lineup_type_lock; -static QMap lineupid_to_srcid; -static QMap srcid_to_type; - -static void set_lineup_type(const QString &lineupid, const QString &type); -static QString get_lineup_type(uint sourceid); -static QString get_setting(QString line, QString key); -static bool has_setting(QString line, QString key); -static QString html_escape(QString str); -static void get_atsc_stuff(QString channum, int freqid, - int &major, int &minor, long long &freq); -static QString process_dd_station(uint sourceid, - QString chan_major, QString chan_minor, - QString &tvformat, uint &freqid); -static uint update_channel_basic(uint sourceid, bool insert, - QString xmltvid, QString callsign, - QString name, uint freqid, - QString chan_major, QString chan_minor); -void authenticationCallback(QNetworkReply *reply, QAuthenticator *auth, - void *arg); -QByteArray gUncompress(const QByteArray &data); - -// XXX Program duration should be stored as seconds, not as a QTime. -// limited to 24 hours this way. - -bool DDStructureParser::startElement(const QString &pnamespaceuri, - const QString &plocalname, - const QString &pqname, - const QXmlAttributes &pxmlatts) -{ - (void)pnamespaceuri; - (void)plocalname; - - m_currtagname = pqname; - if (m_currtagname == "xtvd") - { - QString beg = pxmlatts.value("from"); - QDateTime begts = MythDate::fromString(beg); - m_parent.SetDDProgramsStartAt(begts); - - QString end = pxmlatts.value("to"); - QDateTime endts = MythDate::fromString(end); - m_parent.SetDDProgramsEndAt(endts); - } - else if (m_currtagname == "station") - { - m_curr_station.Reset(); - m_curr_station.m_stationid = pxmlatts.value("id"); - } - else if (m_currtagname == "lineup") - { - m_curr_lineup.Reset(); - m_curr_lineup.m_name = pxmlatts.value("name"); - m_curr_lineup.m_type = pxmlatts.value("type"); - m_curr_lineup.m_device = pxmlatts.value("device"); - m_curr_lineup.m_postal = pxmlatts.value("postalCode"); - m_curr_lineup.m_lineupid = pxmlatts.value("id"); - m_curr_lineup.m_displayname = m_curr_lineup.m_name + "-" + m_curr_lineup.m_type + - "-" + m_curr_lineup.m_device + "-" + - m_curr_lineup.m_postal + "-" + - m_curr_lineup.m_lineupid; - - if (m_curr_lineup.m_lineupid.isEmpty()) - { - m_curr_lineup.m_lineupid = m_curr_lineup.m_name + m_curr_lineup.m_postal + - m_curr_lineup.m_device + m_curr_lineup.m_type; - } - } - else if (m_currtagname == "map") - { - int tmpindex; - m_curr_lineupmap.Reset(); - m_curr_lineupmap.m_lineupid = m_curr_lineup.m_lineupid; - m_curr_lineupmap.m_stationid = pxmlatts.value("station"); - m_curr_lineupmap.m_channel = pxmlatts.value("channel"); - tmpindex = pxmlatts.index("channelMinor"); // for ATSC - if (tmpindex != -1) - m_curr_lineupmap.m_channelMinor = pxmlatts.value(tmpindex); - } - else if (m_currtagname == "schedule") - { - m_curr_schedule.Reset(); - m_curr_schedule.m_programid = pxmlatts.value("program"); - m_curr_schedule.m_stationid = pxmlatts.value("station"); - - m_curr_schedule.m_time = MythDate::fromString(pxmlatts.value("time")); - QString durstr = pxmlatts.value("duration"); - m_curr_schedule.m_duration = QTime(durstr.mid(2, 2).toInt(), - durstr.mid(5, 2).toInt(), 0, 0); - - m_curr_schedule.m_repeat = (pxmlatts.value("repeat") == "true"); - m_curr_schedule.m_isnew = (pxmlatts.value("new") == "true"); - m_curr_schedule.m_stereo = (pxmlatts.value("stereo") == "true"); - m_curr_schedule.m_dolby = (pxmlatts.value("dolby") == "Dolby" || - pxmlatts.value("dolby") == "Dolby Digital"); - m_curr_schedule.m_subtitled = (pxmlatts.value("subtitled") == "true"); - m_curr_schedule.m_hdtv = (pxmlatts.value("hdtv") == "true"); - m_curr_schedule.m_closecaptioned = (pxmlatts.value("closeCaptioned") == - "true"); - m_curr_schedule.m_tvrating = pxmlatts.value("tvRating"); - } - else if (m_currtagname == "part") - { - m_curr_schedule.m_partnumber = pxmlatts.value("number").toInt(); - m_curr_schedule.m_parttotal = pxmlatts.value("total").toInt(); - } - else if (m_currtagname == "program") - { - m_curr_program.Reset(); - m_curr_program.m_programid = pxmlatts.value("id"); - } - else if (m_currtagname == "crew") - { - m_curr_program.Reset(); - m_lastprogramid = pxmlatts.value("program"); - } - else if (m_currtagname == "programGenre") - { - m_curr_genre.Reset(); - m_lastprogramid = pxmlatts.value("program"); - } - - return true; -} - -bool DDStructureParser::endElement(const QString &pnamespaceuri, - const QString &plocalname, - const QString &pqname) -{ - (void)pnamespaceuri; - (void)plocalname; - - MSqlQuery query(MSqlQuery::DDCon()); - - if (pqname == "station") - { - m_parent.m_stations[m_curr_station.m_stationid] = m_curr_station; - - query.prepare( - "INSERT INTO dd_station " - " ( stationid, callsign, stationname, " - " affiliate, fccchannelnumber) " - "VALUES " - " (:STATIONID, :CALLSIGN, :STATIONNAME, " - " :AFFILIATE, :FCCCHANNUM)"); - - query.bindValue(":STATIONID", m_curr_station.m_stationid); - query.bindValue(":CALLSIGN", m_curr_station.m_callsign); - query.bindValue(":STATIONNAME", m_curr_station.m_stationname); - query.bindValue(":AFFILIATE", m_curr_station.m_affiliate); - query.bindValue(":FCCCHANNUM", m_curr_station.m_fccchannelnumber); - - if (!query.exec()) - MythDB::DBError("Inserting into dd_station", query); - } - else if (pqname == "lineup") - { - set_lineup_type(m_curr_lineup.m_lineupid, m_curr_lineup.m_type); - - m_parent.m_lineups.push_back(m_curr_lineup); - - query.prepare( - "INSERT INTO dd_lineup " - " ( lineupid, name, type, device, postal) " - "VALUES " - " (:LINEUPID, :NAME, :TYPE, :DEVICE, :POSTAL)"); - - query.bindValue(":LINEUPID", m_curr_lineup.m_lineupid); - query.bindValue(":NAME", m_curr_lineup.m_name); - query.bindValue(":TYPE", m_curr_lineup.m_type); - query.bindValue(":DEVICE", m_curr_lineup.m_device); - query.bindValue(":POSTAL", m_curr_lineup.m_postal); - - if (!query.exec()) - MythDB::DBError("Inserting into dd_lineup", query); - } - else if (pqname == "map") - { - m_parent.m_lineupmaps[m_curr_lineupmap.m_lineupid].push_back(m_curr_lineupmap); - - query.prepare( - "INSERT INTO dd_lineupmap " - " ( lineupid, stationid, channel, channelMinor) " - "VALUES " - " (:LINEUPID, :STATIONID, :CHANNEL, :CHANNELMINOR)"); - - query.bindValue(":LINEUPID", m_curr_lineupmap.m_lineupid); - query.bindValue(":STATIONID", m_curr_lineupmap.m_stationid); - query.bindValue(":CHANNEL", m_curr_lineupmap.m_channel); - query.bindValue(":CHANNELMINOR",m_curr_lineupmap.m_channelMinor); - if (!query.exec()) - MythDB::DBError("Inserting into dd_lineupmap", query); - } - else if (pqname == "schedule") - { - QDateTime endtime = m_curr_schedule.m_time.addSecs( - MythDate::toSeconds( m_curr_schedule.m_duration )); - - query.prepare( - "INSERT INTO dd_schedule " - " ( programid, stationid, scheduletime, " - " duration, isrepeat, stereo, " - " dolby, subtitled, hdtv, " - " closecaptioned, tvrating, partnumber, " - " parttotal, endtime, isnew) " - "VALUES " - " (:PROGRAMID, :STATIONID, :TIME, " - " :DURATION, :ISREPEAT, :STEREO, " - " :DOLBY, :SUBTITLED, :HDTV, " - " :CAPTIONED, :TVRATING, :PARTNUMBER, " - " :PARTTOTAL, :ENDTIME, :ISNEW)"); - - query.bindValue(":PROGRAMID", m_curr_schedule.m_programid); - query.bindValue(":STATIONID", m_curr_schedule.m_stationid); - query.bindValue(":TIME", m_curr_schedule.m_time); - query.bindValue(":DURATION", m_curr_schedule.m_duration); - query.bindValue(":ISREPEAT", m_curr_schedule.m_repeat); - query.bindValue(":STEREO", m_curr_schedule.m_stereo); - query.bindValue(":DOLBY", m_curr_schedule.m_dolby); - query.bindValue(":SUBTITLED", m_curr_schedule.m_subtitled); - query.bindValue(":HDTV", m_curr_schedule.m_hdtv); - query.bindValue(":CAPTIONED", m_curr_schedule.m_closecaptioned); - query.bindValue(":TVRATING", m_curr_schedule.m_tvrating); - query.bindValue(":PARTNUMBER", m_curr_schedule.m_partnumber); - query.bindValue(":PARTTOTAL", m_curr_schedule.m_parttotal); - query.bindValue(":ENDTIME", endtime); - query.bindValue(":ISNEW", m_curr_schedule.m_isnew); - - if (!query.exec()) - MythDB::DBError("Inserting into dd_schedule", query); - } - else if (pqname == "program") - { - float staravg = 0.0; - if (!m_curr_program.m_starRating.isEmpty()) - { - int fullstarcount = m_curr_program.m_starRating.count("*"); - int halfstarcount = m_curr_program.m_starRating.count("+"); - staravg = (fullstarcount + (halfstarcount * .5)) / 4; - } - - QString cat_type = ""; - QString prefix = m_curr_program.m_programid.left(2); - - if (prefix == "MV") - cat_type = "movie"; - else if (prefix == "SP") - cat_type = "sports"; - else if (prefix == "EP" || - m_curr_program.m_showtype.contains("series", Qt::CaseInsensitive)) - cat_type = "series"; - else - cat_type = "tvshow"; - - query.prepare( - "INSERT INTO dd_program " - " ( programid, title, subtitle, " - " description, showtype, category_type, " - " mpaarating, starrating, stars, " - " runtime, year, seriesid, " - " colorcode, syndicatedepisodenumber, originalairdate) " - "VALUES " - " (:PROGRAMID, :TITLE, :SUBTITLE, " - " :DESCRIPTION, :SHOWTYPE, :CATTYPE, " - " :MPAARATING, :STARRATING, :STARS, " - " :RUNTIME, :YEAR, :SERIESID, " - " :COLORCODE, :SYNDNUM, :ORIGAIRDATE) "); - - query.bindValue(":PROGRAMID", m_curr_program.m_programid); - query.bindValue(":TITLE", m_curr_program.m_title); - query.bindValue(":SUBTITLE", m_curr_program.m_subtitle); - query.bindValue(":DESCRIPTION", m_curr_program.m_description); - query.bindValue(":SHOWTYPE", m_curr_program.m_showtype); - query.bindValue(":CATTYPE", cat_type); - query.bindValue(":MPAARATING", m_curr_program.m_mpaaRating); - query.bindValue(":STARRATING", m_curr_program.m_starRating); - query.bindValue(":STARS", staravg); - query.bindValue(":RUNTIME", m_curr_program.m_duration); - query.bindValue(":YEAR", m_curr_program.m_year); - query.bindValue(":SERIESID", m_curr_program.m_seriesid); - query.bindValue(":COLORCODE", m_curr_program.m_colorcode); - query.bindValue(":SYNDNUM", m_curr_program.m_syndicatedEpisodeNumber); - query.bindValue(":ORIGAIRDATE", m_curr_program.m_originalAirDate); - - if (!query.exec()) - MythDB::DBError("Inserting into dd_program", query); - } - else if (pqname == "member") - { - QString roleunderlines = m_curr_productioncrew.m_role.replace(" ", "_"); - - QString fullname = m_curr_productioncrew.m_givenname; - if (!fullname.isEmpty()) - fullname += " "; - fullname += m_curr_productioncrew.m_surname; - - query.prepare( - "INSERT INTO dd_productioncrew " - " ( programid, role, givenname, surname, fullname) " - "VALUES (:PROGRAMID, :ROLE, :GIVENNAME, :SURNAME, :FULLNAME)"); - - query.bindValue(":PROGRAMID", m_lastprogramid); - query.bindValue(":ROLE", roleunderlines); - query.bindValue(":GIVENNAME", m_curr_productioncrew.m_givenname); - query.bindValue(":SURNAME", m_curr_productioncrew.m_surname); - query.bindValue(":FULLNAME", fullname); - - if (!query.exec()) - MythDB::DBError("Inserting into dd_productioncrew", query); - - m_curr_productioncrew.m_givenname = ""; - m_curr_productioncrew.m_surname = ""; - } - else if (pqname == "genre") - { - query.prepare( - "INSERT INTO dd_genre " - " ( programid, class, relevance) " - "VALUES (:PROGRAMID, :CLASS, :RELEVANCE)"); - - query.bindValue(":PROGRAMID", m_lastprogramid); - query.bindValue(":CLASS", m_curr_genre.m_gclass); - query.bindValue(":RELEVANCE", m_curr_genre.m_relevance); - - if (!query.exec()) - MythDB::DBError("Inserting into dd_genre", query); - } - - return true; -} - -bool DDStructureParser::startDocument() -{ - m_parent.CreateTempTables(); - return true; -} - -bool DDStructureParser::endDocument() -{ - return true; -} - -bool DDStructureParser::characters(const QString& pchars) -{ -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + "Characters : " + pchars); -#endif - if (pchars.trimmed().isEmpty()) - return true; - - if (m_currtagname == "message") - { - if (pchars.contains("expire")) - { - QString ExtractDateFromMessage = pchars.right(20); - QDateTime EDFM = MythDate::fromString(ExtractDateFromMessage); - QString SDDateFormat = GetMythDB()->GetSetting("DateFormat", - "ddd d MMMM"); - // Ensure we show the year when it's important, regardless of - // specified DateFormat - if ((!SDDateFormat.contains('y')) && - (EDFM.date().year() != MythDate::current().date().year())) - { - SDDateFormat.append(" (yyyy)"); - } - QString dateFormat = QString("%1 %2") - .arg(SDDateFormat) - .arg(GetMythDB()->GetSetting("TimeFormat", "hh:mm")); - QString ExpirationDate = EDFM.toString(dateFormat); - - QString ExpirationDateMessage = "Your subscription expires on " + - ExpirationDate; - - QDateTime curTime = MythDate::current(); - if (curTime.daysTo(EDFM) <= 5) - { - LOG(VB_GENERAL, LOG_WARNING, LOC + QString("WARNING: ") + - ExpirationDateMessage); - } - else - { - LOG(VB_GENERAL, LOG_INFO, LOC + ExpirationDateMessage); - } - - gCoreContext->SaveSettingOnHost("DataDirectMessage", - ExpirationDateMessage, - nullptr); - } - } - if (m_currtagname == "callSign") - m_curr_station.m_callsign = pchars; - else if (m_currtagname == "name") - m_curr_station.m_stationname = pchars; - else if (m_currtagname == "affiliate") - m_curr_station.m_affiliate = pchars; - else if (m_currtagname == "fccChannelNumber") - m_curr_station.m_fccchannelnumber = pchars; - else if (m_currtagname == "title") - m_curr_program.m_title = pchars; - else if (m_currtagname == "subtitle") - m_curr_program.m_subtitle = pchars; - else if (m_currtagname == "description") - m_curr_program.m_description = pchars; - else if (m_currtagname == "showType") - m_curr_program.m_showtype = pchars; - else if (m_currtagname == "series") - m_curr_program.m_seriesid = pchars; - else if (m_currtagname == "colorCode") - m_curr_program.m_colorcode = pchars; - else if (m_currtagname == "mpaaRating") - m_curr_program.m_mpaaRating = pchars; - else if (m_currtagname == "starRating") - m_curr_program.m_starRating = pchars; - else if (m_currtagname == "year") - m_curr_program.m_year = pchars; - else if (m_currtagname == "syndicatedEpisodeNumber") - m_curr_program.m_syndicatedEpisodeNumber = pchars; - else if (m_currtagname == "runTime") - { - QString runtimestr = pchars; - QTime runtime = QTime(runtimestr.mid(2,2).toInt(), - runtimestr.mid(5,2).toInt(), 0, 0); - m_curr_program.m_duration = runtime; - } - else if (m_currtagname == "originalAirDate") - { - QDate airdate = QDate::fromString(pchars, Qt::ISODate); - m_curr_program.m_originalAirDate = airdate; - } - else if (m_currtagname == "role") - m_curr_productioncrew.m_role = pchars; - else if (m_currtagname == "givenname") - m_curr_productioncrew.m_givenname = pchars; - else if (m_currtagname == "surname") - m_curr_productioncrew.m_surname = pchars; - else if (m_currtagname == "class") - m_curr_genre.m_gclass = pchars; - else if (m_currtagname == "relevance") - m_curr_genre.m_relevance = pchars; - - return true; -} - -DataDirectProcessor::DataDirectProcessor(uint lp, QString user, QString pass) : - m_listingsProvider(lp % DD_PROVIDER_COUNT), - m_userid(user), m_password(pass) -{ - { - QMutexLocker locker(&user_agent_lock); - QString mythVersion = MYTH_SOURCE_VERSION; - if (mythVersion.startsWith("v")) - mythVersion = mythVersion.right(mythVersion.length() - 1); // Trim off the leading 'v' - user_agent = QString("MythTV/%1") - .arg(mythVersion); - } - - DataDirectURLs urls0( - "Tribune Media Zap2It", - "http://datadirect.webservices.zap2it.com/tvlistings/xtvdService", - "http://labs.zap2it.com", - "/ztvws/ztvws_login/1,1059,TMS01-1,00.html"); - DataDirectURLs urls1( - "Schedules Direct", - "http://dd.schedulesdirect.org" - "/schedulesdirect/tvlistings/xtvdService", - "http://schedulesdirect.org", - "/login/index.php"); - m_providers.push_back(urls0); - m_providers.push_back(urls1); -} - -DataDirectProcessor::~DataDirectProcessor() -{ - LOG(VB_GENERAL, LOG_INFO, LOC + "Deleting temporary files"); - - if (!m_tmpPostFile.isEmpty()) - { - QByteArray tmp = m_tmpPostFile.toLatin1(); - unlink(tmp.constData()); - } - - if (!m_tmpResultFile.isEmpty()) - { - QByteArray tmp = m_tmpResultFile.toLatin1(); - unlink(tmp.constData()); - } - - if (!m_tmpDDPFile.isEmpty()) - { - QByteArray tmp = m_tmpDDPFile.toLatin1(); - unlink(tmp.constData()); - } - - if (!m_cookieFile.isEmpty()) - { - QByteArray tmp = m_cookieFile.toLatin1(); - unlink(tmp.constData()); - } - - QDir d(m_tmpDir, "mythtv_dd_cache_*", QDir::Name, - QDir::Files | QDir::NoSymLinks); - - for (uint i = 0; i < d.count(); i++) - { - QString tmps = m_tmpDir + "/" + d[i]; - QByteArray tmpa = tmps.toLatin1(); - unlink(tmpa.constData()); - } - - if (m_tmpDir != "/tmp") - { - QByteArray tmp = m_tmpDir.toLatin1(); - rmdir(tmp.constData()); - } -} - -void DataDirectProcessor::UpdateStationViewTable(QString lineupid) -{ - MSqlQuery query(MSqlQuery::DDCon()); - - if (!query.exec("TRUNCATE TABLE dd_v_station;")) - MythDB::DBError("Truncating temporary table dd_v_station", query); - - query.prepare( - "INSERT INTO dd_v_station " - " ( stationid, callsign, stationname, " - " affiliate, fccchannelnumber, channel, " - " channelMinor) " - "SELECT dd_station.stationid, callsign, stationname, " - " affiliate, fccchannelnumber, channel, " - " channelMinor " - "FROM dd_station, dd_lineupmap " - "WHERE ((dd_station.stationid = dd_lineupmap.stationid) AND " - " (dd_lineupmap.lineupid = :LINEUP))"); - - query.bindValue(":LINEUP", lineupid); - - if (!query.exec()) - MythDB::DBError("Populating temporary table dd_v_station", query); -} - -void DataDirectProcessor::UpdateProgramViewTable(uint sourceid) -{ - MSqlQuery query(MSqlQuery::DDCon()); - - if (!query.exec("TRUNCATE TABLE dd_v_program;")) - MythDB::DBError("Truncating temporary table dd_v_program", query); - - QString qstr = - "INSERT INTO dd_v_program " - " ( chanid, starttime, endtime, " - " title, subtitle, description, " - " airdate, stars, previouslyshown, " - " stereo, dolby, subtitled, " - " hdtv, closecaptioned, partnumber, " - " parttotal, seriesid, originalairdate, " - " showtype, category_type, colorcode, " - " syndicatedepisodenumber, tvrating, mpaarating, " - " programid ) " - "SELECT chanid, scheduletime, endtime, " - " title, subtitle, description, " - " year, stars, isrepeat, " - " stereo, dolby, subtitled, " - " hdtv, closecaptioned, partnumber, " - " parttotal, seriesid, originalairdate, " - " showtype, category_type, colorcode, " - " syndicatedepisodenumber, tvrating, mpaarating, " - " dd_program.programid " - "FROM channel, dd_schedule, dd_program " - "WHERE ((dd_schedule.programid = dd_program.programid) AND " - " (channel.xmltvid = dd_schedule.stationid) AND " - " (channel.sourceid = :SOURCEID))"; - - query.prepare(qstr); - - query.bindValue(":SOURCEID", sourceid); - - if (!query.exec()) - MythDB::DBError("Populating temporary table dd_v_program", query); - - if (!query.exec("ANALYZE TABLE dd_v_program;")) - MythDB::DBError("Analyzing table dd_v_program", query); - - if (!query.exec("ANALYZE TABLE dd_productioncrew;")) - MythDB::DBError("Analyzing table dd_productioncrew", query); -} - -int DataDirectProcessor::UpdateChannelsSafe( - uint sourceid, - bool insert_channels, - bool filter_new_channels) -{ - int new_channels = 0; - - if (!SourceUtil::GetConnectionCount(sourceid)) - { - LOG(VB_GENERAL, LOG_WARNING, LOC + - QString("Not inserting channels into disconnected source %1.") - .arg(sourceid)); - return -1; - } - - if (!SourceUtil::IsProperlyConnected(sourceid, true)) - return -1; - - // Find all the channels in the dd_v_station temp table - // where there is no channel with the same xmltvid in the - // DB using the same source. - MSqlQuery query(MSqlQuery::DDCon()); - query.prepare( - "SELECT dd_v_station.stationid, dd_v_station.callsign, " - " dd_v_station.stationname, dd_v_station.fccchannelnumber, " - " dd_v_station.channel, dd_v_station.channelMinor " - "FROM dd_v_station LEFT JOIN channel ON " - " dd_v_station.stationid = channel.xmltvid AND " - " channel.sourceid = :SOURCEID " - "WHERE channel.chanid IS NULL"); - query.bindValue(":SOURCEID", sourceid); - - if (!query.exec()) - { - MythDB::DBError("Selecting new channels", query); - return -1; - } - - bool is_encoder = (SourceUtil::IsCableCardPresent(sourceid) || - SourceUtil::IsEncoder(sourceid, true) || - SourceUtil::IsUnscanable(sourceid)); - - while (query.next()) - { - QString xmltvid = query.value(0).toString(); - QString callsign = query.value(1).toString(); - QString name = query.value(2).toString(); - uint freqid = query.value(3).toUInt(); - QString chan_major = query.value(4).toString(); - QString chan_minor = query.value(5).toString(); - - if (filter_new_channels && is_encoder && - (query.value(5).toUInt() > 0)) - { -#if 0 - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("Not adding channel %1-%2 '%3' (%4),\n\t\t\t" - "looks like a digital channel on an analog source.") - .arg(chan_major).arg(chan_minor).arg(name).arg(callsign)); -#endif - continue; - } - - uint mods = - update_channel_basic(sourceid, insert_channels && is_encoder, - xmltvid, callsign, name, freqid, - chan_major, chan_minor); - - (void) mods; -#if 0 - if (!insert_channels && !mods) - { - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("Not adding channel '%1' (%2).") - .arg(name).arg(callsign)); - } -#endif - new_channels++; - } - - teardown_frequency_tables(); - - return new_channels; -} - -bool DataDirectProcessor::UpdateChannelsUnsafe( - uint sourceid, bool filter_new_channels) -{ - if (filter_new_channels && - !SourceUtil::IsProperlyConnected(sourceid, false)) - { - return false; - } - - MSqlQuery dd_station_info(MSqlQuery::DDCon()); - dd_station_info.prepare( - "SELECT callsign, stationname, stationid," - " fccchannelnumber, channel, channelMinor " - "FROM dd_v_station"); - if (!dd_station_info.exec()) - return false; - - if (dd_station_info.size() == 0) - return true; - - MSqlQuery chan_update_q(MSqlQuery::DDCon()); - chan_update_q.prepare( - "UPDATE channel " - "SET callsign = :CALLSIGN, name = :NAME, " - " channum = :CHANNUM, freqid = :FREQID, " - " atsc_major_chan = :MAJORCHAN, " - " atsc_minor_chan = :MINORCHAN " - "WHERE xmltvid = :STATIONID AND sourceid = :SOURCEID"); - - bool is_encoder = (SourceUtil::IsCableCardPresent(sourceid) || - SourceUtil::IsEncoder(sourceid, true) || - SourceUtil::IsUnscanable(sourceid)); - - while (dd_station_info.next()) - { - uint freqid = dd_station_info.value(3).toUInt(); - QString chan_major = dd_station_info.value(4).toString(); - QString chan_minor = dd_station_info.value(5).toString(); - QString tvformat; - QString channum = process_dd_station( - sourceid, chan_major, chan_minor, tvformat, freqid); - - if (filter_new_channels && is_encoder && - (dd_station_info.value(5).toUInt() > 0)) - { -#if 0 - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("Not adding channel %1-%2 '%3' (%4),\n\t\t\t" - "looks like a digital channel on an analog source.") - .arg(chan_major).arg(chan_minor) - .arg(dd_station_info.value(1).toString()) - .arg(dd_station_info.value(0).toString())); -#endif - continue; - } - - chan_update_q.bindValue(":CALLSIGN", dd_station_info.value(0)); - chan_update_q.bindValue(":NAME", dd_station_info.value(1)); - chan_update_q.bindValue(":STATIONID", dd_station_info.value(2)); - chan_update_q.bindValue(":CHANNUM", channum); - chan_update_q.bindValue(":SOURCEID", sourceid); - chan_update_q.bindValue(":FREQID", freqid); - chan_update_q.bindValue(":MAJORCHAN", chan_major.toUInt()); - chan_update_q.bindValue(":MINORCHAN", chan_minor.toUInt()); - - if (!chan_update_q.exec()) - { - MythDB::DBError("Updating channel table", chan_update_q); - } - } - - return true; -} - -void DataDirectProcessor::DataDirectProgramUpdate(void) -{ - MSqlQuery query(MSqlQuery::DDCon()); - -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + - "Adding rows to main program table from view table"); -#endif - query.prepare( - "INSERT IGNORE INTO program " - " ( chanid, starttime, endtime, title, " - " subtitle, description, showtype, category, " - " category_type, airdate, stars, previouslyshown, " - " stereo, subtitled, subtitletypes, videoprop, " - " audioprop, hdtv, closecaptioned, partnumber, " - " parttotal, seriesid, originalairdate, colorcode, " - " syndicatedepisodenumber, " - " programid, listingsource) " - " SELECT " - " dd_v_program.chanid, " - " DATE_ADD(starttime, INTERVAL channel.tmoffset MINUTE), " - " DATE_ADD(endtime, INTERVAL channel.tmoffset MINUTE), " - " title, " - " subtitle, description, showtype, dd_genre.class, " - " category_type, airdate, stars, previouslyshown, " - " stereo, subtitled, " - " (subtitled << 1 ) | closecaptioned, hdtv, " - " (dolby << 3) | stereo, " - " hdtv, closecaptioned, partnumber, " - " parttotal, seriesid, originalairdate, colorcode, " - " syndicatedepisodenumber, " - " dd_v_program.programid, " - " :LSOURCE " - "FROM (dd_v_program, channel) " - "LEFT JOIN dd_genre ON " - " ( dd_v_program.programid = dd_genre.programid AND " - " dd_genre.relevance = '0' ) " - "WHERE dd_v_program.chanid = channel.chanid"); - - query.bindValue(":LSOURCE", kListingSourceDDSchedulesDirect); - - if (!query.exec()) - MythDB::DBError("Inserting into program table", query); - -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + - "Finished adding rows to main program table"); - LOG(VB_GENERAL, LOG_DEBUG, LOC + "Adding program ratings"); -#endif - - if (!query.exec("INSERT IGNORE INTO programrating (chanid, starttime, " - "system, rating) SELECT dd_v_program.chanid, " - "DATE_ADD(starttime, INTERVAL channel.tmoffset MINUTE), " - " 'MPAA', " - "mpaarating FROM dd_v_program, channel WHERE " - "mpaarating != '' AND dd_v_program.chanid = " - "channel.chanid")) - MythDB::DBError("Inserting into programrating table", query); - - if (!query.exec("INSERT IGNORE INTO programrating (chanid, starttime, " - "system, rating) SELECT dd_v_program.chanid, " - "DATE_ADD(starttime, INTERVAL channel.tmoffset MINUTE), " - "'VCHIP', " - "tvrating FROM dd_v_program, channel WHERE tvrating != ''" - " AND dd_v_program.chanid = channel.chanid")) - MythDB::DBError("Inserting into programrating table", query); - -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + "Finished adding program ratings"); - LOG(VB_GENERAL, LOG_DEBUG, LOC + - "Populating people table from production crew list"); -#endif - - if (!query.exec("INSERT IGNORE INTO people (name) " - "SELECT fullname " - "FROM dd_productioncrew " - "LEFT OUTER JOIN people " - "ON people.name = dd_productioncrew.fullname " - "WHERE people.name IS NULL;")) - MythDB::DBError("Inserting into people table", query); - -#if 0 - LOG(VB_GENERAL, LOG_INFO, LOC + "Finished adding people"); - LOG(VB_GENERAL, LOG_INFO, LOC + - "Adding credits entries from production crew list"); -#endif - - if (!query.exec("INSERT IGNORE INTO credits (chanid, starttime, person, role)" - "SELECT dd_v_program.chanid, " - "DATE_ADD(dd_v_program.starttime, INTERVAL channel.tmoffset MINUTE), " - "people.person, " - "dd_productioncrew.role " - "FROM dd_v_program " - "JOIN channel " - "ON dd_v_program.chanid = channel.chanid " - "JOIN dd_productioncrew " - "ON dd_productioncrew.programid = dd_v_program.programid " - "JOIN people " - "ON people.name = dd_productioncrew.fullname " - "LEFT OUTER JOIN credits " - "ON credits.chanid = dd_v_program.chanid " - "AND credits.starttime = DATE_ADD(dd_v_program.starttime, INTERVAL channel.tmoffset MINUTE) " - "AND credits.person = people.person " - "AND credits.role = dd_productioncrew.role " - "WHERE credits.role IS NULL;")) - MythDB::DBError("Inserting into credits table", query); - -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + "Finished inserting credits"); - LOG(VB_GENERAL, LOG_DEBUG, LOC + "Adding genres"); -#endif - - if (!query.exec("INSERT IGNORE INTO programgenres (chanid, starttime, " - "relevance, genre) SELECT dd_v_program.chanid, " - "DATE_ADD(starttime, INTERVAL channel.tmoffset MINUTE), " - "relevance, class FROM dd_v_program, dd_genre, channel " - "WHERE (dd_v_program.programid = dd_genre.programid) " - "AND dd_v_program.chanid = channel.chanid")) - MythDB::DBError("Inserting into programgenres table",query); - -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + "Done"); -#endif -} - -void authenticationCallback(QNetworkReply *reply, QAuthenticator *auth, - void *arg) -{ - if (!arg) - return; - - DataDirectProcessor *dd = reinterpret_cast(arg); - dd->authenticationCallback(reply, auth); -} - -void DataDirectProcessor::authenticationCallback(QNetworkReply *reply, - QAuthenticator *auth) -{ - LOG(VB_FILE, LOG_DEBUG, "DataDirect auth callback"); - (void)reply; - auth->setUser(GetUserID()); - auth->setPassword(GetPassword()); -} - -bool DataDirectProcessor::DDPost(QString ddurl, QString &inputFile, - QDateTime pstartDate, QDateTime pendDate, - QString &err_txt) -{ - if (!inputFile.isEmpty() && QFile(inputFile).exists()) - { - return true; - } - - QString startdatestr = pstartDate.toString(Qt::ISODate) + "Z"; - QString enddatestr = pendDate.toString(Qt::ISODate) + "Z"; - QByteArray postdata; - postdata = "\n"; - postdata += " headers; - headers.insert("Accept-Encoding", "gzip"); - headers.insert("Content-Type", "application/soap+xml; charset=utf-8"); - - LOG(VB_GENERAL, LOG_INFO, "Downloading DataDirect feed"); - - MythDownloadManager *manager = GetMythDownloadManager(); - - if (!manager->postAuth(ddurl, &postdata, &::authenticationCallback, this, - &headers)) - { - err_txt = QString("Download error"); - return false; - } - - LOG(VB_GENERAL, LOG_INFO, QString("Downloaded %1 bytes") - .arg(postdata.size())); - - LOG(VB_GENERAL, LOG_INFO, "Uncompressing DataDirect feed"); - - QByteArray uncompressed = gUncompress(postdata); - - LOG(VB_GENERAL, LOG_INFO, QString("Uncompressed to %1 bytes") - .arg(uncompressed.size())); - - if (uncompressed.size() == 0) - uncompressed = postdata; - - LOG(VB_GENERAL, LOG_INFO, QString("Writing to temporary file: [%1]") - .arg( inputFile )); - - QFile file(inputFile); - if (!file.open(QIODevice::WriteOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open temporary file: %1").arg(inputFile)); - return false; - } - file.write(uncompressed); - file.close(); - - if (uncompressed.size() == 0) - { - err_txt = QString("Error uncompressing data"); - return false; - } - - return true; -} - -bool DataDirectProcessor::GrabNextSuggestedTime(void) -{ - LOG(VB_GENERAL, LOG_INFO, LOC + "Grabbing next suggested grabbing time"); - - QString ddurl = m_providers[m_listingsProvider].m_webServiceURL; - - bool ok; - QString resultFilename = GetResultFilename(ok); - if (!ok) - { - LOG(VB_GENERAL, LOG_ERR, LOC + - "GrabNextSuggestedTime: Creating temp result file"); - return false; - } - - QByteArray postdata; - postdata = "\n"; - postdata += " headers; - headers.insert("Content-Type", "application/soap+xml; charset=utf-8"); - - MythDownloadManager *manager = GetMythDownloadManager(); - - if (!manager->postAuth(ddurl, &postdata, &::authenticationCallback, this, - &headers)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + - "GrabNextSuggestedTime: Could not download"); - return false; - } - - QDateTime nextSuggestedTime; - QDateTime blockedTime; - - LOG(VB_GENERAL, LOG_INFO, QString("Suggested Time data: %1 bytes") - .arg(postdata.size())); - - QFile file(resultFilename); - if (!file.open(QIODevice::WriteOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open result file: %1").arg(resultFilename)); - return false; - } - file.write(postdata); - file.close(); - - if (file.open(QIODevice::ReadOnly)) - { - QTextStream stream(&file); - QString line; - while (!stream.atEnd()) - { - line = stream.readLine(); - if (line.contains("", Qt::CaseInsensitive)) - { - QString tmpStr = line; - tmpStr.replace( - QRegExp(".*([^<]*).*"), - "\\1"); - - nextSuggestedTime = MythDate::fromString(tmpStr); - - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("nextSuggestedTime is: ") + - nextSuggestedTime.toString(Qt::ISODate)); - } - - if (line.contains("", Qt::CaseInsensitive)) - { - QString tmpStr = line; - tmpStr.replace( - QRegExp(".*([^<]*).*"), "\\1"); - - blockedTime = MythDate::fromString(tmpStr); - LOG(VB_GENERAL, LOG_INFO, LOC + QString("BlockedTime is: ") + - blockedTime.toString(Qt::ISODate)); - } - } - file.close(); - } - - if (nextSuggestedTime.isValid()) - { - gCoreContext->SaveSettingOnHost( - "MythFillSuggestedRunTime", - nextSuggestedTime.toString(Qt::ISODate), nullptr); - } - - return nextSuggestedTime.isValid(); -} - -bool DataDirectProcessor::GrabData(const QDateTime &pstartDate, - const QDateTime &pendDate) -{ - QString msg = (pstartDate.addSecs(1) == pendDate) ? "channel" : "listing"; - LOG(VB_GENERAL, LOG_INFO, LOC + "Grabbing " + msg + " data"); - - QString err = ""; - QString ddurl = m_providers[m_listingsProvider].m_webServiceURL; - QString inputfile = m_inputFilename; - QString cache_dd_data; - - if (m_cacheData) - { - cache_dd_data = m_tmpDir + - QString("/mythtv_dd_cache_%1_UTC_%2_to_%3") - .arg(GetListingsProvider()) - .arg(MythDate::toString(pstartDate, MythDate::kFilename)) - .arg(MythDate::toString(pendDate, MythDate::kFilename)); - - if (QFile(cache_dd_data).exists() && m_inputFilename.isEmpty()) - { - LOG(VB_GENERAL, LOG_INFO, LOC + "Using DD cache"); - } - - if (m_inputFilename.isEmpty()) - inputfile = cache_dd_data; - } - - if (!DDPost(ddurl, inputfile, pstartDate, pendDate, err)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to get data: %1") - .arg(err)); - return false; - } - - QFile file(inputfile); - - if (!file.open(QIODevice::ReadOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open file: %1").arg(inputfile)); - return false; - } - - QByteArray data = file.readAll(); - file.close(); - - if (data.isEmpty()) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "Data is empty"); - return false; - } - - bool ok = true; - - DDStructureParser ddhandler(*this); - QXmlInputSource xmlsource; - QXmlSimpleReader xmlsimplereader; - - xmlsource.setData(data); - xmlsimplereader.setContentHandler(&ddhandler); - if (!xmlsimplereader.parse(xmlsource)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + - "DataDirect XML failed to properly parse, downloaded listings " - "were probably corrupt."); - ok = false; - } - - return ok; -} - -bool DataDirectProcessor::GrabLineupsOnly(void) -{ - const QDateTime start = QDateTime(MythDate::current().date().addDays(2), - QTime(23, 59, 0), Qt::UTC); - const QDateTime end = start.addSecs(1); - - return GrabData(start, end); -} - -bool DataDirectProcessor::GrabAllData(void) -{ - return GrabData(MythDate::current().addDays(-2), - MythDate::current().addDays(15)); -} - -void DataDirectProcessor::CreateATempTable(const QString &ptablename, - const QString &ptablestruct) -{ - MSqlQuery query(MSqlQuery::DDCon()); - QString querystr; - querystr = "CREATE TEMPORARY TABLE IF NOT EXISTS " + ptablename + " " + - ptablestruct + " ENGINE=MyISAM;"; - - if (!query.exec(querystr)) - MythDB::DBError("Creating temporary table", query); - - querystr = "TRUNCATE TABLE " + ptablename + ";"; - - if (!query.exec(querystr)) - MythDB::DBError("Truncating temporary table", query); -} - -void DataDirectProcessor::CreateTempTables() -{ - QMap dd_tables; - - dd_tables["dd_station"] = - "( stationid char(12), callsign char(10), " - " stationname varchar(40), affiliate varchar(25), " - " fccchannelnumber char(15) )"; - - dd_tables["dd_lineup"] = - "( lineupid char(100), name char(42), " - " type char(20), postal char(6), " - " device char(30) )"; - - dd_tables["dd_lineupmap"] = - "( lineupid char(100), stationid char(12), " - " channel char(5), channelMinor char(3) )"; - - - dd_tables["dd_v_station"] = - "( stationid char(12), callsign char(10), " - " stationname varchar(40), affiliate varchar(25), " - " fccchannelnumber char(15), channel char(5), " - " channelMinor char(3) )"; - - dd_tables["dd_schedule"] = - "( programid char(40), stationid char(12), " - " scheduletime datetime, duration time, " - " isrepeat bool, stereo bool, " - " dolby bool, " - " subtitled bool, hdtv bool, " - " closecaptioned bool, tvrating char(5), " - " partnumber int, parttotal int, " - " endtime datetime, isnew bool, " - "INDEX progidx (programid) )"; - - dd_tables["dd_program"] = - "( programid char(40) NOT NULL, seriesid char(12), " - " title varchar(120), subtitle varchar(150), " - " description text, mpaarating char(5), " - " starrating char(5), runtime time, " - " year char(4), showtype char(30), " - " category_type char(64), colorcode char(20), " - " originalairdate date, syndicatedepisodenumber char(20), " - " stars float unsigned, " - "PRIMARY KEY (programid))"; - - dd_tables["dd_v_program"] = - "( chanid int unsigned NOT NULL, starttime datetime NOT NULL, " - " endtime datetime, title varchar(128), " - " subtitle varchar(128), description text, " - " category varchar(64), category_type varchar(64), " - " airdate year, stars float unsigned, " - " previouslyshown tinyint, isrepeat bool, " - " stereo bool, dolby bool, " - " subtitled bool, " - " hdtv bool, closecaptioned bool, " - " partnumber int, parttotal int, " - " seriesid char(12), originalairdate date, " - " showtype varchar(30), colorcode varchar(20), " - " syndicatedepisodenumber varchar(20), programid char(40), " - " tvrating char(5), mpaarating char(5), " - "INDEX progidx (programid))"; - - dd_tables["dd_productioncrew"] = - "( programid char(40), role char(30), " - " givenname char(20), surname char(20), " - " fullname char(41), " - "INDEX progidx (programid), " - "INDEX nameidx (fullname))"; - - dd_tables["dd_genre"] = - "( programid char(40) NOT NULL, class char(30), " - " relevance char(1), " - "INDEX progidx (programid))"; - - QMap::const_iterator it; - for (it = dd_tables.begin(); it != dd_tables.end(); ++it) - CreateATempTable(it.key(), *it); -} - -bool DataDirectProcessor::GrabLoginCookiesAndLineups(bool parse_lineups) -{ - LOG(VB_GENERAL, LOG_INFO, LOC + "Grabbing login cookies and lineups"); - - PostList list; - list.push_back(PostItem("username", GetUserID())); - list.push_back(PostItem("password", GetPassword())); - list.push_back(PostItem("action", "Login")); - - QString labsURL = m_providers[m_listingsProvider].m_webURL; - QString loginPage = m_providers[m_listingsProvider].m_loginPage; - - bool ok; - QString resultFilename = GetResultFilename(ok); - if (!ok) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLoginCookiesAndLineups: " - "Creating temp result file"); - return false; - } - QString cookieFilename = GetCookieFilename(ok); - if (!ok) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLoginCookiesAndLineups: " - "Creating temp cookie file"); - return false; - } - - ok = Post(labsURL + loginPage, list, resultFilename, "", - cookieFilename); - - bool got_cookie = QFileInfo(cookieFilename).size() > 100; - - ok &= got_cookie && (!parse_lineups || ParseLineups(resultFilename)); - if (ok) - m_cookieFileDT = MythDate::current(); - - return ok; -} - -bool DataDirectProcessor::GrabLineupForModify(const QString &lineupid) -{ - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("Grabbing lineup %1 for modification").arg(lineupid)); - - RawLineupMap::const_iterator it = m_rawLineups.find(lineupid); - if (it == m_rawLineups.end()) - return false; - - PostList list; - list.push_back(PostItem("udl_id", GetRawUDLID(lineupid))); - list.push_back(PostItem("zipcode", GetRawZipCode(lineupid))); - list.push_back(PostItem("lineup_id", lineupid)); - list.push_back(PostItem("submit", "Modify")); - - bool ok; - QString resultFilename = GetResultFilename(ok); - if (!ok) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLoginCookiesAndLineups: " - "Creating temp result file"); - return false; - } - QString cookieFilename = GetCookieFilename(ok); - if (!ok) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLoginCookiesAndLineups: " - "Creating temp cookie file"); - return false; - } - - QString labsURL = m_providers[m_listingsProvider].m_webURL; - ok = Post(labsURL + (*it).m_get_action, list, resultFilename, - cookieFilename, ""); - - return ok && ParseLineup(lineupid, resultFilename); -} - -void DataDirectProcessor::SetAll(const QString &lineupid, bool val) -{ - LOG(VB_GENERAL, LOG_INFO, LOC + QString("%1 all channels in lineup %2") - .arg((val) ? "Selecting" : "Deselecting").arg(lineupid)); - - RawLineupMap::iterator lit = m_rawLineups.find(lineupid); - if (lit == m_rawLineups.end()) - return; - - RawLineupChannels &ch = (*lit).m_channels; - for (RawLineupChannels::iterator it = ch.begin(); it != ch.end(); ++it) - (*it).m_chk_checked = val; -} - -static QString get_cache_filename(const QString &lineupid) -{ - return QString("/tmp/.mythtv_cached_lineup_") + lineupid; -} - -QDateTime DataDirectProcessor::GetLineupCacheAge(const QString &lineupid) const -{ - QDateTime cache_dt(QDate(1971, 1, 1), QTime(0,0,0), Qt::UTC); - QFile lfile(get_cache_filename(lineupid)); - if (!lfile.exists()) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLineupCacheAge("+lineupid+ - ") failed -- " + - QString("file '%1' doesn't exist") - .arg(get_cache_filename(lineupid))); - return cache_dt; - } - if (lfile.size() < 8) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLineupCacheAge("+lineupid+ - ") failed -- " + - QString("file '%1' size %2 too small") - .arg(get_cache_filename(lineupid)).arg(lfile.size())); - return cache_dt; - } - if (!lfile.open(QIODevice::ReadOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLineupCacheAge("+lineupid+ - ") failed -- " + - QString("cannot open file '%1'") - .arg(get_cache_filename(lineupid))); - return cache_dt; - } - - QString tmp; - QTextStream io(&lfile); - io >> tmp; - cache_dt = MythDate::fromString(tmp); - - LOG(VB_GENERAL, LOG_INFO, LOC + "GrabLineupCacheAge("+lineupid+") -> " + - cache_dt.toString(Qt::ISODate)); - - return cache_dt; -} - -bool DataDirectProcessor::GrabLineupsFromCache(const QString &lineupid) -{ - QFile lfile(get_cache_filename(lineupid)); - if (!lfile.exists() || (lfile.size() < 8) || - !lfile.open(QIODevice::ReadOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLineupFromCache("+lineupid+ - ") -- failed"); - return false; - } - - QString tmp; - uint size; - QTextStream io(&lfile); - io >> tmp; // read in date - io >> size; // read in number of channels mapped - - for (uint i = 0; i < 14; i++) - io.readLine(); // read extra lines - - DDLineupChannels &channels = m_lineupmaps[lineupid]; - channels.clear(); - - for (uint i = 0; i < size; i++) - { - io.readLine(); // read "start record" string - - DataDirectLineupMap chan; - chan.m_lineupid = lineupid; - chan.m_stationid = io.readLine(); - chan.m_channel = io.readLine(); - chan.m_channelMinor = io.readLine(); - - chan.m_mapFrom = QDate(); - tmp = io.readLine(); - if (!tmp.isEmpty()) - chan.m_mapFrom.fromString(tmp, Qt::ISODate); - - chan.m_mapTo = QDate(); - tmp = io.readLine(); - if (!tmp.isEmpty()) - chan.m_mapTo.fromString(tmp, Qt::ISODate); - - channels.push_back(chan); - - DDStation station; - station.m_stationid = chan.m_stationid; - station.m_callsign = io.readLine(); - station.m_stationname = io.readLine(); - station.m_affiliate = io.readLine(); - station.m_fccchannelnumber = io.readLine(); - tmp = io.readLine(); // read "end record" string - - m_stations[station.m_stationid] = station; - } - - LOG(VB_GENERAL, LOG_INFO, LOC + "GrabLineupFromCache("+lineupid+ - ") -- success"); - - return true; -} - -bool DataDirectProcessor::SaveLineupToCache(const QString &lineupid) const -{ - QString fn = get_cache_filename(lineupid); - QByteArray fna = fn.toLatin1(); - QFile lfile(fna.constData()); - if (!lfile.open(QIODevice::WriteOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "SaveLineupToCache("+lineupid+ - ") -- failed"); - return false; - } - - QTextStream io(&lfile); - io << MythDate::current_iso_string() << endl; - - const DDLineupChannels channels = GetDDLineup(lineupid); - io << channels.size() << endl; - - io << endl; - io << "# start record" << endl; - io << "# stationid" << endl; - io << "# channel" << endl; - io << "# channelMinor" << endl; - io << "# mapped from date" << endl; - io << "# mapped to date" << endl; - io << "# callsign" << endl; - io << "# stationname" << endl; - io << "# affiliate" << endl; - io << "# fccchannelnumber" << endl; - io << "# end record" << endl; - io << endl; - - DDLineupChannels::const_iterator it; - for (it = channels.begin(); it != channels.end(); ++it) - { - io << "# start record" << endl; - io << (*it).m_stationid << endl; - io << (*it).m_channel << endl; - io << (*it).m_channelMinor << endl; - io << (*it).m_mapFrom.toString(Qt::ISODate) << endl; - io << (*it).m_mapTo.toString(Qt::ISODate) << endl; - - DDStation station = GetDDStation((*it).m_stationid); - io << station.m_callsign << endl; - io << station.m_stationname << endl; - io << station.m_affiliate << endl; - io << station.m_fccchannelnumber << endl; - io << "# end record" << endl; - } - io << flush; - - LOG(VB_GENERAL, LOG_INFO, LOC + "SaveLineupToCache("+lineupid+ - ") -- success"); - - bool ret = makeFileAccessible(fna.constData()); // Let anybody update it - if (!ret) - { - // Nothing, makeFileAccessible will print an error - } - - return true; -} - -bool DataDirectProcessor::GrabFullLineup(const QString &lineupid, - bool restore, bool onlyGrabSelected, - uint cache_age_allowed_in_seconds) -{ - if (cache_age_allowed_in_seconds) - { - QDateTime exp_time = GetLineupCacheAge(lineupid) - .addSecs(cache_age_allowed_in_seconds); - bool valid = exp_time > MythDate::current(); - if (valid && GrabLineupsFromCache(lineupid)) - return true; - } - - bool ok = GrabLoginCookiesAndLineups(); - if (!ok) - return false; - - ok = GrabLineupForModify(lineupid); - if (!ok) - return false; - - RawLineupMap::iterator lit = m_rawLineups.find(lineupid); - if (lit == m_rawLineups.end()) - return false; - - const RawLineupChannels orig_channels = (*lit).m_channels; - - if (!onlyGrabSelected) - { - SetAll(lineupid, true); - if (!SaveLineupChanges(lineupid)) - return false; - } - - ok = GrabLineupsOnly(); - - if (ok) - SaveLineupToCache(lineupid); - - (*lit).m_channels = orig_channels; - if (restore && !onlyGrabSelected) - ok &= SaveLineupChanges(lineupid); - - return ok; -} - -bool DataDirectProcessor::SaveLineup(const QString &lineupid, - const QMap &xmltvids) -{ - QMap callsigns; - RawLineupMap::iterator lit = m_rawLineups.find(lineupid); - if (lit == m_rawLineups.end()) - return false; - - // Grab login cookies if they are more than 5 minutes old - if ((!m_cookieFileDT.isValid() || - m_cookieFileDT.addSecs(5*60) < MythDate::current()) && - !GrabLoginCookiesAndLineups(false)) - { - return false; - } - - // Get callsigns based on xmltv ids (aka stationid) - DDLineupMap::const_iterator ddit = m_lineupmaps.find(lineupid); - DDLineupChannels::const_iterator it; - for (it = (*ddit).begin(); it != (*ddit).end(); ++it) - { - if (xmltvids.find((*it).m_stationid) != xmltvids.end()) - callsigns[GetDDStation((*it).m_stationid).m_callsign] = true; - } - - // Set checked mark based on whether the channel is mapped - RawLineupChannels &ch = (*lit).m_channels; - RawLineupChannels::iterator cit; - for (cit = ch.begin(); cit != ch.end(); ++cit) - { - bool chk = callsigns.find((*cit).m_lbl_callsign) != callsigns.end(); - (*cit).m_chk_checked = chk; - } - - // Save these changes - return SaveLineupChanges(lineupid); -} - -bool DataDirectProcessor::SaveLineupChanges(const QString &lineupid) -{ - RawLineupMap::const_iterator lit = m_rawLineups.find(lineupid); - if (lit == m_rawLineups.end()) - return false; - - const RawLineup &lineup = *lit; - const RawLineupChannels &ch = lineup.m_channels; - RawLineupChannels::const_iterator it; - - PostList list; - for (it = ch.begin(); it != ch.end(); ++it) - { - if ((*it).m_chk_checked) - list.push_back(PostItem((*it).m_chk_name, (*it).m_chk_value)); - } - list.push_back(PostItem("action", "Update")); - - LOG(VB_GENERAL, LOG_INFO, LOC + QString("Saving lineup %1 with %2 channels") - .arg(lineupid).arg(list.size() - 1)); - - bool ok; - QString cookieFilename = GetCookieFilename(ok); - if (!ok) - { - LOG(VB_GENERAL, LOG_ERR, LOC + "GrabLoginCookiesAndLineups: " - "Creating temp cookie file"); - return false; - } - - QString labsURL = m_providers[m_listingsProvider].m_webURL; - return Post(labsURL + lineup.m_set_action, list, "", - cookieFilename, ""); -} - -bool DataDirectProcessor::UpdateListings(uint sourceid) -{ - MSqlQuery query(MSqlQuery::DDCon()); - query.prepare( - "SELECT xmltvid " - "FROM channel " - "WHERE sourceid = :SOURCEID"); - query.bindValue(":SOURCEID", sourceid); - - if (!query.exec() || !query.isActive()) - { - MythDB::DBError("Selecting existing channels", query); - return false; - } - - QString a, b, c, lineupid; - if (!SourceUtil::GetListingsLoginData(sourceid, a, b, c, lineupid)) - return false; - - QMap xmltvids; - while (query.next()) - { - if (!query.value(0).toString().isEmpty()) - xmltvids[query.value(0).toString()] = true; - } - - LOG(VB_GENERAL, LOG_INFO, LOC + "Saving updated DataDirect listing"); - bool ok = SaveLineup(lineupid, xmltvids); - - if (!ok) - LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to update DataDirect listings."); - - return ok; -} - -QString DataDirectProcessor::GetRawUDLID(const QString &lineupid) const -{ - RawLineupMap::const_iterator it = m_rawLineups.find(lineupid); - if (it == m_rawLineups.end()) - return QString(); - return (*it).m_udl_id; -} - -QString DataDirectProcessor::GetRawZipCode(const QString &lineupid) const -{ - RawLineupMap::const_iterator it = m_rawLineups.find(lineupid); - if (it == m_rawLineups.end()) - return QString(); - return (*it).m_zipcode; -} - -RawLineup DataDirectProcessor::GetRawLineup(const QString &lineupid) const -{ - RawLineup tmp; - RawLineupMap::const_iterator it = m_rawLineups.find(lineupid); - if (it == m_rawLineups.end()) - return tmp; - return (*it); -} - -void DataDirectProcessor::CreateTemp( - const QString &templatefilename, - const QString &errmsg, - bool directory, - QString &filename, - bool &ok) const -{ - QString tmp = createTempFile(templatefilename, directory); - if (templatefilename == tmp) - { - m_fatalErrors.push_back(errmsg); - ok = false; - } - else - { - filename = tmp; - ok = true; - } -} - -QString DataDirectProcessor::CreateTempDirectory(bool *pok) const -{ - bool ok; - pok = (pok) ? pok : &ok; - if (m_tmpDir == "/tmp") - { - CreateTemp("/tmp/mythtv_ddp_XXXXXX", - "Failed to create temp directory", - true, m_tmpDir, *pok); - } - return m_tmpDir; -} - - -QString DataDirectProcessor::GetResultFilename(bool &ok) const -{ - ok = true; - if (m_tmpResultFile.isEmpty()) - { - CreateTemp(m_tmpDir + "/mythtv_result_XXXXXX", - "Failed to create temp result file", - false, m_tmpResultFile, ok); - } - return m_tmpResultFile; -} - -QString DataDirectProcessor::GetCookieFilename(bool &ok) const -{ - ok = true; - if (m_cookieFile.isEmpty()) - { - CreateTemp(m_tmpDir + "/mythtv_cookies_XXXXXX", - "Failed to create temp cookie file", - false, m_cookieFile, ok); - } - return m_cookieFile; -} - -QString DataDirectProcessor::GetDDPFilename(bool &ok) const -{ - ok = true; - if (m_tmpDDPFile.isEmpty()) - { - CreateTemp(m_tmpDir + "/mythtv_ddp_XXXXXX", - "Failed to create temp ddp file", - false, m_tmpDDPFile, ok); - } - return m_tmpDDPFile; -} - -bool DataDirectProcessor::Post(QString url, const PostList &list, - QString documentFile, - QString inCookieFile, QString outCookieFile) -{ - MythDownloadManager *manager = GetMythDownloadManager(); - - if (!inCookieFile.isEmpty()) - manager->loadCookieJar(inCookieFile); - - QByteArray postdata; - for (uint i = 0; i < list.size(); i++) - { - postdata += ((i) ? "&" : "") + list[i].key + "="; - postdata += html_escape(list[i].value); - } - - if (!manager->post(url, &postdata)) - return false; - - if (!outCookieFile.isEmpty()) - manager->saveCookieJar(outCookieFile); - - if (documentFile.isEmpty()) - return true; - - QFile file(documentFile); - if (!file.open(QIODevice::WriteOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open document file: %1").arg(documentFile)); - return false; - } - file.write(postdata); - file.close(); - - QFileInfo fi(documentFile); - return fi.size(); -} - -bool DataDirectProcessor::ParseLineups(const QString &documentFile) -{ - QFile file(documentFile); - if (!file.open(QIODevice::ReadOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open '%1'") - .arg(documentFile)); - return false; - } - - QTextStream stream(&file); - bool in_form = false; - QString get_action; - QMap name_value; - - m_rawLineups.clear(); - - while (!stream.atEnd()) - { - QString line = stream.readLine(); - QString llow = line.toLower(); - int frm = llow.indexOf("= 0) - { - in_form = true; - get_action = get_setting(line.mid(frm + 5), "action"); - name_value.clear(); -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("action: %1").arg(action)); -#endif - } - - if (!in_form) - continue; - - int inp = llow.indexOf("= 0) - { - QString input_line = line.mid(inp + 6); -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + - QString("input: %1").arg(input_line)); -#endif - QString name = get_setting(input_line, "name"); - QString value = get_setting(input_line, "value"); -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("name: %1").arg(name)); - LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("value: %1").arg(value)); -#endif - if (!name.isEmpty() && !value.isEmpty()) - name_value[name] = value; - } - - if (llow.contains("")) - { - in_form = false; - if (!get_action.isEmpty() && - !name_value["udl_id"].isEmpty() && - !name_value["zipcode"].isEmpty() && - !name_value["lineup_id"].isEmpty()) - { - RawLineup item(get_action, name_value["udl_id"], - name_value["zipcode"]); - - m_rawLineups[name_value["lineup_id"]] = item; -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + - QString("<%1> \t--> <%2,%3,%4>") - .arg(name_value["lineup_id"]) - .arg(item.udl_id).arg(item.zipcode) - .arg(item.get_action)); -#endif - } - } - } - return true; -} - -bool DataDirectProcessor::ParseLineup(const QString &lineupid, - const QString &documentFile) -{ - QFile file(documentFile); - if (!file.open(QIODevice::ReadOnly)) - { - LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to open '%1'") - .arg(documentFile)); - - return false; - } - - QTextStream stream(&file); - bool in_form = false; - int in_label = 0; - QMap settings; - - RawLineup &lineup = m_rawLineups[lineupid]; - RawLineupChannels &ch = lineup.m_channels; - - while (!stream.atEnd()) - { - QString line = stream.readLine(); - QString llow = line.toLower(); - int frm = llow.indexOf("= 0) - { - in_form = true; - lineup.m_set_action = get_setting(line.mid(frm + 5), "action"); -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + "set_action: " + - lineup.sm_et_action); -#endif - } - - if (!in_form) - continue; - - int inp = llow.indexOf("= 0) - { - QString in_line = line.mid(inp + 6); - settings.clear(); - settings["chk_name"] = get_setting(in_line, "name"); - settings["chk_id"] = get_setting(in_line, "id"); - settings["chk_value"] = get_setting(in_line, "value"); - settings["chk_checked"] = has_setting(in_line, "checked")?"1":"0"; - } - - int lbl = llow.indexOf("= 0) - { - QString lbl_line = line.mid(inp + 6); - QString name = get_setting(lbl_line, "for"); - in_label = (name == settings["chk_name"]) ? 1 : 0; - } - - if (in_label) - { - int start = (lbl >= 0) ? lbl + 6 : 0; - int beg = llow.indexOf("", start), end = -1; - if (beg) - end = llow.indexOf("", beg + 4); - - if (end >= 0) - { - QString key = (in_label == 1) ? "lbl_ch" : "lbl_callsign"; - QString val = line.mid(beg + 4, end - beg - 4); - settings[key] = val.replace(" ", "", Qt::CaseInsensitive); - in_label++; - } - } - - in_label = (llow.indexOf("= 0) ? 0 : in_label; - - if (!in_label && - !settings["chk_name"].isEmpty() && - !settings["chk_id"].isEmpty() && - !settings["chk_value"].isEmpty() && - !settings["chk_checked"].isEmpty() && - !settings["lbl_ch"].isEmpty() && - !settings["lbl_callsign"].isEmpty()) - { - RawLineupChannel chan( - settings["chk_name"], settings["chk_id"], - settings["chk_value"], settings["chk_checked"] == "1", - settings["lbl_ch"], settings["lbl_callsign"]); - -#if 0 - LOG(VB_GENERAL, LOG_DEBUG, LOC + - QString("name: %1 id: %2 value: %3 " - "checked: %4 ch: %5 call: %6") - .arg(settings["chk_name"]).arg(settings["chk_id"]) - .arg(settings["chk_value"]).arg(settings["chk_checked"]) - .arg(settings["lbl_ch"],4).arg(settings["lbl_callsign"])); -#endif - - ch.push_back(chan); - settings.clear(); - } - - if (llow.contains("")) - { - in_form = false; - } - } - return true; -} - -static QString html_escape(QString str) -{ - QString new_str = ""; - for (int i = 0; i < str.length(); i++) - { - if (str[i].isLetterOrNumber()) - new_str += str[i]; - else - { - new_str += QString("%%1").arg((int)str[1].toLatin1(), 0, 16); - } - } - - return new_str; -} - -static QString get_setting(QString line, QString key) -{ - QString llow = line.toLower(); - QString kfind = key + "=\""; - int beg = llow.indexOf(kfind); - - if (beg >= 0) - { - int end = llow.indexOf("\"", beg + kfind.length()); - return line.mid(beg + kfind.length(), end - beg - kfind.length()); - } - - kfind = key + "="; - beg = llow.indexOf(kfind); - if (beg < 0) - return QString(); - - int i = beg + kfind.length(); - while (i < line.length() && !line[i].isSpace() && line[i] != '>') - i++; - - if (i < line.length() && (line[i].isSpace() || line[i] == '>')) - return line.mid(beg + kfind.length(), i - beg - kfind.length()); - - return QString(); -} - -static bool has_setting(QString line, QString key) -{ - return (line.toLower().indexOf(key) >= 0); -} - -static void get_atsc_stuff(QString channum, int freqid, - int &major, int &minor, long long &freq) -{ - major = freqid; - minor = 0; - - int chansep = channum.indexOf(QRegExp("\\D")); - if (chansep < 0) - return; - - major = channum.left(chansep).toInt(); - minor = channum.right(channum.length() - (chansep + 1)).toInt(); - - freq = get_center_frequency("atsc", "vsb8", "us", freqid); -} - -static QString process_dd_station( - uint sourceid, QString chan_major, QString chan_minor, - QString &tvformat, uint &freqid) -{ - QString channum = chan_major; - bool ok; - uint minor = chan_minor.toUInt(&ok); - - tvformat = "Default"; - - if (minor && ok) - { - tvformat = "atsc"; - channum += SourceUtil::GetChannelSeparator(sourceid) + chan_minor; - } - else if (!freqid && (get_lineup_type(sourceid) == "LocalBroadcast")) - freqid = chan_major.toInt(); - else - freqid = channum.toInt(); - - return channum; -} - -static uint update_channel_basic(uint sourceid, bool insert, - QString xmltvid, QString callsign, - QString name, uint freqid, - QString chan_major, QString chan_minor) -{ - callsign = (callsign.isEmpty()) ? name : callsign; - - QString tvformat; - QString channum = process_dd_station( - sourceid, chan_major, chan_minor, tvformat, freqid); - - // First check if channel already in DB, but without xmltvid - MSqlQuery query(MSqlQuery::DDCon()); - query.prepare("SELECT chanid, callsign, name " - "FROM channel " - "WHERE sourceid = :SOURCEID AND " - " ( xmltvid = '0' OR xmltvid = '') AND " - " ( channum = :CHANNUM OR " - " ( freqid = :FREQID AND " - " freqid != '0' AND " - " freqid != '' AND " - " atsc_minor_chan = '0') OR " - " ( atsc_major_chan = :MAJORCHAN AND " - " atsc_minor_chan = :MINORCHAN ) )"); - query.bindValue(":SOURCEID", sourceid); - query.bindValue(":CHANNUM", channum); - query.bindValue(":FREQID", freqid); - query.bindValue(":MAJORCHAN", chan_major.toUInt()); - query.bindValue(":MINORCHAN", chan_minor.toUInt()); - - if (!query.exec() || !query.isActive()) - { - MythDB::DBError("Getting chanid of existing channel", query); - return 0; // go on to next channel without xmltv - } - - if (query.next()) - { - // The channel already exists in DB, at least once, - // so set the xmltvid.. - MSqlQuery chan_update_q(MSqlQuery::DDCon()); - chan_update_q.prepare( - "UPDATE channel " - "SET xmltvid = :XMLTVID, name = :NAME, callsign = :CALLSIGN " - "WHERE chanid = :CHANID AND sourceid = :SOURCEID"); - - uint i = 0; - do - { - uint chanid = query.value(0).toInt(); - - QString new_callsign = query.value(1).toString(); - new_callsign = - (new_callsign.indexOf(ChannelUtil::GetUnknownCallsign()) == 0) ? - callsign : new_callsign; - - QString new_name = query.value(2).toString(); - new_name = (new_name.isEmpty()) ? name : new_name; - new_name = (new_name.isEmpty()) ? new_callsign : new_name; - - chan_update_q.bindValue(":CHANID", chanid); - chan_update_q.bindValue(":NAME", new_name); - chan_update_q.bindValue(":CALLSIGN", new_callsign); - chan_update_q.bindValue(":XMLTVID", xmltvid); - chan_update_q.bindValue(":SOURCEID", sourceid); - -#if 0 - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("Updating channel %1: '%2' (%3).") - .arg(chanid).arg(name).arg(callsign)); -#endif - - if (!chan_update_q.exec() || !chan_update_q.isActive()) - { - MythDB::DBError( - "Updating XMLTVID of existing channel", chan_update_q); - continue; // go on to next instance of this channel - } - i++; - } - while (query.next()); - - return i; // go on to next channel without xmltv - } - - if (!insert) - return 0; // go on to next channel without xmltv - - // The channel doesn't exist in the DB, insert it... - int mplexid = -1, majorC, minorC, chanid = 0; - long long freq = -1; - get_atsc_stuff(channum, freqid, majorC, minorC, freq); - - if (minorC > 0 && freq >= 0) - mplexid = ChannelUtil::CreateMultiplex(sourceid, "atsc", freq, "8vsb"); - - if ((mplexid > 0) || (minorC == 0)) - chanid = ChannelUtil::CreateChanID(sourceid, channum); - - LOG(VB_GENERAL, LOG_INFO, LOC + QString("Adding channel %1 '%2' (%3).") - .arg(channum).arg(name).arg(callsign)); - - if (chanid > 0) - { - QString icon = ""; - int serviceid = 0; - bool oag = false; // use on air guide - bool hidden = false; - bool hidden_in_guide = false; - QString freq_id= QString::number(freqid); - - ChannelUtil::CreateChannel( - mplexid, sourceid, chanid, - callsign, name, channum, - serviceid, majorC, minorC, - oag, hidden, hidden_in_guide, - freq_id, icon, tvformat, - xmltvid); - } - - return 1; -} - -static void set_lineup_type(const QString &lineupid, const QString &type) -{ - QMutexLocker locker(&lineup_type_lock); - if (lineupid_to_srcid[lineupid]) - return; - - // get lineup to source mapping - uint srcid = 0; - MSqlQuery query(MSqlQuery::InitCon()); - query.prepare( - "SELECT sourceid " - "FROM videosource " - "WHERE lineupid = :LINEUPID"); - query.bindValue(":LINEUPID", lineupid); - - if (!query.exec() || !query.isActive()) - MythDB::DBError("end_element", query); - else if (query.next()) - srcid = query.value(0).toUInt(); - - if (srcid) - { - lineupid_to_srcid[lineupid] = srcid; - - // set type for source - srcid_to_type[srcid] = type; - - LOG(VB_GENERAL, LOG_INFO, LOC + - QString("sourceid %1 has lineup type: %2").arg(srcid).arg(type)); - } -} - -static QString get_lineup_type(uint sourceid) -{ - QMutexLocker locker(&lineup_type_lock); - return srcid_to_type[sourceid]; -} - -/* - * This function taken from: - * http://stackoverflow.com/questions/2690328/qt-quncompress-gzip-data - * - * Based on zlib example code. - * - * Copyright (c) 2011 Ralf Engels - * Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler - * - * Licensed under the terms of the ZLib license which is found at - * http://zlib.net/zlib_license.html and is as follows: - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * NOTE: The Zlib license is listed as being GPL-compatible - * http://www.gnu.org/licenses/license-list.html#ZLib - */ - -QByteArray gUncompress(const QByteArray &data) -{ - if (data.size() <= 4) { - LOG(VB_GENERAL, LOG_WARNING, "gUncompress: Input data is truncated"); - return QByteArray(); - } - - QByteArray result; - - int ret; - z_stream strm; - static const int CHUNK_SIZE = 1024; - char out[CHUNK_SIZE]; - - /* allocate inflate state */ - strm.zalloc = Z_NULL; - strm.zfree = Z_NULL; - strm.opaque = Z_NULL; - strm.avail_in = data.size(); - strm.next_in = (Bytef*)(data.data()); - - ret = inflateInit2(&strm, 15 + 32); // gzip decoding - if (ret != Z_OK) - return QByteArray(); - - // run inflate() - do { - strm.avail_out = CHUNK_SIZE; - strm.next_out = (Bytef*)(out); - - ret = inflate(&strm, Z_NO_FLUSH); - Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered - - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - [[clang::fallthrough]]; - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void)inflateEnd(&strm); - return QByteArray(); - } - - result.append(out, CHUNK_SIZE - strm.avail_out); - } while (strm.avail_out == 0); - - // clean up and return - inflateEnd(&strm); - return result; -} - -/* vim: set expandtab tabstop=4 shiftwidth=4: */ diff --git a/mythtv/libs/libmythtv/datadirect.h b/mythtv/libs/libmythtv/datadirect.h deleted file mode 100644 index 7dea9db4daa..00000000000 --- a/mythtv/libs/libmythtv/datadirect.h +++ /dev/null @@ -1,447 +0,0 @@ -#ifndef DATADIRECT_H_ -#define DATADIRECT_H_ - -#include -#include -#include -#include -#include -#include - -#include "mythtvexp.h" - -#include - -using namespace std; - -enum DD_PROVIDERS -{ - DD_ZAP2IT = 0, - DD_SCHEDULES_DIRECT = 1, - DD_PROVIDER_COUNT = 2, -}; - -class DataDirectURLs -{ - -public: - DataDirectURLs(QString a, QString b, QString c, QString d) : - m_name(a), m_webServiceURL(b), m_webURL(c), m_loginPage(d) {} - - QString m_name; - QString m_webServiceURL; - QString m_webURL; - QString m_loginPage; -}; - -typedef vector DDProviders; - -class DataDirectProcessor; - -class DataDirectStation -{ - -public: - DataDirectStation() = default; - - void Reset(void) - { - DataDirectStation tmp; - *this = tmp; - } - -public: - // field length req/opt - QString m_stationid; // 12 required - QString m_callsign; // 10 required - QString m_stationname; // 40 required - QString m_affiliate; // 25 optional - QString m_fccchannelnumber;// 8 optional -}; - -typedef DataDirectStation DDStation; - -class DataDirectLineup -{ - -public: - DataDirectLineup() = default; - - void Reset(void) - { - DataDirectLineup tmp; - *this = tmp; - } - -public: - // field length req/opt - QString m_lineupid; // 12 required - QString m_name; // 100 required - QString m_displayname; // 50 ???????? - QString m_type; // 20 required - QString m_postal; // 6 optional - QString m_device; // 30 optional - QString m_location; // 28 required unused -}; - -class DataDirectLineupMap -{ - -public: - DataDirectLineupMap() = default; - - void Reset(void) - { - DataDirectLineupMap tmp; - *this = tmp; - } - -public: - // field length req/opt - QString m_lineupid; // 12 required - QString m_stationid; // 12 required - QString m_channel; // 5 optional (major channel num) - QString m_channelMinor; // 3 optional - QDate m_mapFrom; // 8 optional unused (date broadcasting begins) - QDate m_mapTo; // 8 optional unused (date broadcasting ends) -}; - -class DataDirectSchedule -{ - -public: - DataDirectSchedule() = default; - - void Reset(void) - { - DataDirectSchedule tmp; - *this = tmp; - } - -public: - QString m_programid; // 12 - QString m_stationid; // 12 - QDateTime m_time; - QTime m_duration; - bool m_repeat {false}; - bool m_isnew {false}; - bool m_stereo {false}; - bool m_dolby {false}; - bool m_subtitled {false}; - bool m_hdtv {false}; - bool m_closecaptioned {false}; - QString m_tvrating; - int m_partnumber {0}; - int m_parttotal {0}; -}; - -class DataDirectProgram -{ - -public: - DataDirectProgram() = default; - - void Reset(void) - { - DataDirectProgram tmp; - *this = tmp; - } - -public: - QString m_programid; // 12 - QString m_seriesid; // 12 - QString m_title; // 120 - QString m_subtitle; // 150 - QString m_description; // 255 - QString m_mpaaRating; // 5 - QString m_starRating; // 5 - QTime m_duration; - QString m_year; // 4 - QString m_showtype; // 30 - QString m_colorcode; // 20 - QDate m_originalAirDate; // 20 - QString m_syndicatedEpisodeNumber; // 20 - // advisories ? -}; - -class DataDirectProductionCrew -{ - -public: - DataDirectProductionCrew() = default; - - void Reset(void) - { - DataDirectProductionCrew tmp; - *this = tmp; - } - -public: - QString m_programid; // 12 - QString m_role; // 30 - QString m_givenname; // 20 - QString m_surname; // 20 - QString m_fullname; // 41 -}; - -class DataDirectGenre -{ - -public: - DataDirectGenre() = default; - - void Reset(void) - { - DataDirectGenre tmp; - *this = tmp; - } - -public: - QString m_programid; // 12 - QString m_gclass; // 30 - QString m_relevance; // 1 -}; - -class RawLineupChannel -{ - -public: - RawLineupChannel() = default; - RawLineupChannel(QString name, QString id, - QString value, bool checked, - QString ch, QString callsign) : - m_chk_name(name), m_chk_id(id), m_chk_value(value), - m_chk_checked(checked), m_lbl_ch(ch), m_lbl_callsign(callsign) {} - -public: - QString m_chk_name; - QString m_chk_id; - QString m_chk_value; - bool m_chk_checked {false}; - QString m_lbl_ch; - QString m_lbl_callsign; -}; - -typedef vector RawLineupChannels; - -class RawLineup -{ - -public: - RawLineup() = default; - - RawLineup(QString a, QString b, QString c) : - m_get_action(a), m_udl_id(b), m_zipcode(c) {} - -public: - QString m_get_action; - QString m_set_action; - QString m_udl_id; - QString m_zipcode; - - RawLineupChannels m_channels; -}; - -typedef QMap RawLineupMap; - -class PostItem -{ - -public: - PostItem(QString k, QString v) : key(k), value(v) {} - - QString key; - QString value; -}; - -typedef vector PostList; - -class DDStructureParser: public QXmlDefaultHandler -{ - -public: - explicit DDStructureParser(DataDirectProcessor& _ddparent) : - m_parent(_ddparent) {} - - bool startElement(const QString &pnamespaceuri, const QString &plocalname, - const QString &pqname, const QXmlAttributes &pxmlatts) override; // QXmlDefaultHandler - - bool endElement(const QString &pnamespaceuri, const QString &plocalname, - const QString &pqname) override; // QXmlDefaultHandler - - bool characters(const QString &pchars) override; // QXmlDefaultHandler - - bool startDocument(void) override; // QXmlDefaultHandler - bool endDocument(void) override; // QXmlDefaultHandler - -private: - DataDirectProcessor &m_parent; - - QString m_currtagname; - DataDirectStation m_curr_station; - DataDirectLineup m_curr_lineup; - DataDirectLineupMap m_curr_lineupmap; - DataDirectSchedule m_curr_schedule; - DataDirectProgram m_curr_program; - DataDirectProductionCrew m_curr_productioncrew; - DataDirectGenre m_curr_genre; - QString m_lastprogramid; -}; - - -typedef QMap DDStationList; // stationid -> -typedef vector DDLineupList; -typedef vector DDLineupChannels; -typedef QMap DDLineupMap; // lineupid -> - -class MTV_PUBLIC DataDirectProcessor -{ - - friend class DDStructureParser; - friend void authenticationCallback(QNetworkReply*, QAuthenticator*, void*); - - public: - DataDirectProcessor(uint listings_provider = DD_ZAP2IT, - QString userid = "", QString password = ""); - ~DataDirectProcessor(); - - QString CreateTempDirectory(bool *ok = nullptr) const; - - // web service commands - bool GrabData(const QDateTime &startdate, const QDateTime &enddate); - bool GrabNextSuggestedTime(void); - - // utility wrappers - bool GrabLineupsOnly(void); - bool GrabAllData(void); - - // screen scraper commands - bool GrabLoginCookiesAndLineups(bool parse_lineups = true); - bool GrabLineupForModify(const QString &lineupid); - bool SaveLineupChanges(const QString &lineupid); - - // combined commands - bool GrabFullLineup(const QString &lineupid, bool restore = true, - bool onlyGrabSelected = false, - uint cache_age_allowed_in_seconds = 0); - bool SaveLineup(const QString &lineupid, - const QMap &xmltvids); - bool UpdateListings(uint sourceid); - - // cache commands - bool GrabLineupsFromCache(const QString &lineupid); - bool SaveLineupToCache(const QString &lineupid) const; - - // gets - DDStationList GetStations(void) const { return m_stations; } - DDLineupList GetLineups(void) const { return m_lineups; } - DDLineupMap GetLineupMap(void) const { return m_lineupmaps; } - QDateTime GetLineupCacheAge(const QString &lineupid) const; - - QString GetUserID(void) const { return m_userid.toLower(); } - QString GetPassword(void) const { return m_password; } - uint GetListingsProvider(void) const { return m_listingsProvider; } - - QString GetListingsProviderName(void) const - { - return m_providers[m_listingsProvider % DD_PROVIDER_COUNT].m_name; - } - - QDateTime GetDDProgramsStartAt(void) const { return m_actualListingsFrom; } - QDateTime GetDDProgramsEndAt(void) const { return m_actualListingsTo; } - DDLineupChannels GetDDLineup(const QString &lineupid) const - { - return m_lineupmaps[lineupid]; - } - - DDStation GetDDStation(const QString &xmltvid) const - { - return m_stations[xmltvid]; - } - - QString GetRawUDLID(const QString &lineupid) const; - QString GetRawZipCode(const QString &lineupid) const; - RawLineup GetRawLineup(const QString &lineupid) const; - - // sets - void SetUserID(const QString &uid) { m_userid = uid; } - void SetPassword(const QString &pwd) { m_password = pwd; } - void SetListingsProvider(uint i) - { - m_listingsProvider = i % DD_PROVIDER_COUNT; - } - - void SetInputFile(const QString &file) { m_inputFilename = file; } - void SetCacheData(bool cd) { m_cacheData = cd; } - - // static commands (these update temp DB tables) - static void UpdateStationViewTable(QString lineupid); - static void UpdateProgramViewTable(uint sourceid); - - // static commands (these update regular DB tables from temp DB tables) - static int UpdateChannelsSafe( - uint sourceid, bool insert_channels, bool filter_new_channels); - static bool UpdateChannelsUnsafe( - uint sourceid, bool filter_new_channels); - static void DataDirectProgramUpdate(void); - - QStringList GetFatalErrors(void) const { return m_fatalErrors; } - - private: - void CreateTempTables(void); - void CreateATempTable(const QString &ptablename, - const QString &ptablestruct); - - bool ParseLineups(const QString &documentFile); - bool ParseLineup(const QString &lineupid, const QString &documentFile); - - void CreateTemp(const QString &templatefilename, const QString &errmsg, - bool directory, QString &filename, bool &ok) const; - - QString GetResultFilename(bool &ok) const; - QString GetDDPFilename(bool &ok) const; - QString GetCookieFilename(bool &ok) const; - - void SetAll(const QString &lineupid, bool val); - void SetDDProgramsStartAt(QDateTime begts) { m_actualListingsFrom = begts; } - void SetDDProgramsEndAt(QDateTime endts) { m_actualListingsTo = endts; } - - static bool Post(QString url, const PostList &list, QString documentFile, - QString inCookieFile, QString outCookieFile); - - bool DDPost(QString url, QString &inputFilename, - QDateTime pstartDate, QDateTime pendDate, - QString &err_txt); - - - private: - void authenticationCallback(QNetworkReply *reply, QAuthenticator *auth); - - uint m_listingsProvider; - DDProviders m_providers; - - QString m_userid; - QString m_password; - mutable QString m_tmpDir {"/tmp"}; - bool m_cacheData {false}; - - QDateTime m_actualListingsFrom; - QDateTime m_actualListingsTo; - - QString m_inputFilename; - - DDStationList m_stations; - DDLineupList m_lineups; - DDLineupMap m_lineupmaps; - - RawLineupMap m_rawLineups; - mutable QString m_tmpPostFile; - mutable QString m_tmpResultFile; - mutable QString m_tmpDDPFile; - mutable QString m_cookieFile; - QDateTime m_cookieFileDT; - - mutable QStringList m_fatalErrors; -}; - -#endif diff --git a/mythtv/libs/libmythtv/dbcheck.cpp b/mythtv/libs/libmythtv/dbcheck.cpp index f3485aca9ad..d15e1484210 100644 --- a/mythtv/libs/libmythtv/dbcheck.cpp +++ b/mythtv/libs/libmythtv/dbcheck.cpp @@ -312,8 +312,6 @@ For most, the last four digits are "0000" except EP where the last four digits are the episode number in the series. Note that these are generated by TMS and not the show's producers but they are usually in the same order as the original air dates for the episodes. -Detailed information can be found in the Data Direct documentation -at http://labs.zap2it.com/ . \section oldrecorded_table Old Recorded Table (oldrecorded) diff --git a/mythtv/libs/libmythtv/libmythtv.pro b/mythtv/libs/libmythtv/libmythtv.pro index 3d4a37ab209..5ad22959190 100644 --- a/mythtv/libs/libmythtv/libmythtv.pro +++ b/mythtv/libs/libmythtv/libmythtv.pro @@ -175,10 +175,6 @@ SOURCES += recordingfile.cpp HEADERS += diseqc.h diseqcsettings.h SOURCES += diseqc.cpp diseqcsettings.cpp -# Listings downloading classes -HEADERS += datadirect.h -SOURCES += datadirect.cpp - # File/FIFO Writer classes HEADERS += filewriterbase.h avformatwriter.h HEADERS += fifowriter.h diff --git a/mythtv/libs/libmythtv/mpeg/mpegtables.h b/mythtv/libs/libmythtv/mpeg/mpegtables.h index e6636a682d5..aebcbf3233d 100644 --- a/mythtv/libs/libmythtv/mpeg/mpegtables.h +++ b/mythtv/libs/libmythtv/mpeg/mpegtables.h @@ -1164,7 +1164,7 @@ class MTV_PUBLIC SpliceInformationTable : public PSIPTable vector _ptrs0; vector _ptrs1; const unsigned char *_epilog; - int scte_pid; + int scte_pid {0}; }; /** \class AdaptationFieldControl diff --git a/mythtv/libs/libmythtv/mythplayer.cpp b/mythtv/libs/libmythtv/mythplayer.cpp index 589fde0b617..db421c7225b 100644 --- a/mythtv/libs/libmythtv/mythplayer.cpp +++ b/mythtv/libs/libmythtv/mythplayer.cpp @@ -223,6 +223,8 @@ MythPlayer::MythPlayer(PlayerFlags flags) rtcbase(0), maxtcval(0), maxtcframes(0), numdroppedframes(0), + prior_audiotimecode(0), + prior_videotimecode(0), // LiveTVChain stuff m_tv(nullptr), isDummy(false), // Counter for buffering messages @@ -415,6 +417,8 @@ bool MythPlayer::Play(float speed, bool normal, bool unpauseaudio) return false; } rtcbase = 0; + prior_audiotimecode = 0; + prior_videotimecode = 0; SetEof(kEofStateNone); UnpauseBuffer(); UnpauseDecoder(); @@ -1806,6 +1810,8 @@ void MythPlayer::ResetAVSync(void) prevtc = 0; avsync_next = avsync_interval; // Frames till next sync check rtcbase = 0; + prior_audiotimecode = 0; + prior_videotimecode = 0; LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + "A/V sync reset"); } @@ -1822,6 +1828,8 @@ void MythPlayer::InitAVSync(void) // Number of frames over which to average time divergence avsync_averaging=4; rtcbase = 0; + prior_audiotimecode = 0; + prior_videotimecode = 0; // Special averaging default of 60 for OpenMAX passthru QString device = gCoreContext->GetSetting("AudioOutputDevice",""); @@ -2170,7 +2178,7 @@ void wait_for_time(int64_t framedue) QThread::usleep(delay); } -#define AVSYNC_MAX_LATE 1000000 +#define AVSYNC_MAX_LATE 10000000 void MythPlayer::AVSync2(VideoFrame *buffer) { if (videoOutput->IsErrored()) @@ -2180,7 +2188,6 @@ void MythPlayer::AVSync2(VideoFrame *buffer) SetErrored(tr("Failed to initialize A/V Sync")); return; } - int64_t audiotimecode = audio.GetAudioTime(); int64_t videotimecode = 0; bool dropframe = false; @@ -2191,10 +2198,10 @@ void MythPlayer::AVSync2(VideoFrame *buffer) int64_t unow = 0; int64_t lateness = 0; int64_t playspeed1000 = (float)1000 / play_speed; + bool reset = false; while (framedue == 0) { - bool reset = false; if (buffer) { videotimecode = buffer->timecode & 0x0000ffffffffffff; @@ -2205,12 +2212,18 @@ void MythPlayer::AVSync2(VideoFrame *buffer) now = QDateTime::currentDateTimeUtc(); unow = now.toMSecsSinceEpoch() * 1000; + + if (!normal_speed || FlagIsSet(kMusicChoice)) + { + framedue = unow + frame_interval; + break; + } // first time or after a seek - setup of rtcbase if (rtcbase == 0) { // cater for DVB radio if (videotimecode == 0) - videotimecode = audiotimecode; + videotimecode = audio.GetAudioTime();; // On first frame we get nothing, so exit out. if (videotimecode == 0) return; @@ -2242,26 +2255,37 @@ void MythPlayer::AVSync2(VideoFrame *buffer) lateness = unow - framedue; dropframe = false; if (lateness > 30000) - dropframe = !FlagIsSet(kMusicChoice) && numdroppedframes < 10; + dropframe = numdroppedframes < 10; - if (lateness <= 30000 && audiotimecode > 0 && normal_speed && !FlagIsSet(kMusicChoice)) + if (lateness <= 30000 && prior_audiotimecode > 0 + && prior_videotimecode > 0) { // Get video in sync with audio - audio_adjustment = audiotimecode - videotimecode; - int sign = audio_adjustment < 0 ? -1 : 1; - if (audio_adjustment * sign > 40) + audio_adjustment = prior_audiotimecode - prior_videotimecode; + // If there is excess audio - throw it away. + if (audio_adjustment < -200) { - // adjust by AVSyncIncrementMS milliseconds at a time (range 1-40) - rtcbase -= (int64_t)1000000 * avsync2adjustms * sign / playspeed1000; + audio.Reset(); + audio_adjustment = 0; + } + int sign = audio_adjustment < 0 ? -1 : 1; + int64_t fix_amount = audio_adjustment * sign; + if (fix_amount > avsync2adjustms) + fix_amount = avsync2adjustms; + // Faster catch-up when off by more than 200 ms + if (audio_adjustment * sign > 200) + // fix the sync within 15 - 20 frames + fix_amount = audio_adjustment * sign / 15; + int64_t speedup1000 = (float)1000 * play_speed; + rtcbase -= (int64_t)1000000 * fix_amount * sign / speedup1000; + if (audio_adjustment * sign > 20 || (framesPlayed % 400 == 0)) LOG(VB_PLAYBACK, LOG_INFO, LOC + QString("AV Sync, audio ahead by %1 ms").arg(audio_adjustment)); - } - if (audio_adjustment > 1000) + if (audio_adjustment > 200) pause_audio = true; } // sanity check - reset rtcbase if time codes have gone crazy. - if ((lateness > AVSYNC_MAX_LATE || lateness < - AVSYNC_MAX_LATE) - && !FlagIsSet(kMusicChoice)) + if ((lateness > AVSYNC_MAX_LATE || lateness < - AVSYNC_MAX_LATE)) { framedue = 0; rtcbase = 0; @@ -2277,7 +2301,7 @@ void MythPlayer::AVSync2(VideoFrame *buffer) reset = true; } } - + prior_videotimecode = videotimecode; disp_timecode = videotimecode; output_jmeter && output_jmeter->RecordCycleTime(); @@ -2307,17 +2331,6 @@ void MythPlayer::AVSync2(VideoFrame *buffer) audio.Pause(true); } - LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + - QString("A/V timecodes audio=%1 video=%2 frameinterval=%3 " - "audioadj=%4 tcoffset=%5 unow=%6 udue=%7") - .arg(audiotimecode) - .arg(videotimecode) - .arg(frame_interval) - .arg(audio_adjustment) - .arg(tc_wrap[TC_AUDIO]) - .arg(unow) - .arg(framedue) - ); if (dropframe) numdroppedframes++; @@ -2338,6 +2351,8 @@ void MythPlayer::AVSync2(VideoFrame *buffer) // the primary PBP will become out of sync if (!player_ctx->IsPBP() || player_ctx->IsPrimaryPBP()) wait_for_time(framedue); + // get time codes for calculating difference next time + prior_audiotimecode = audio.GetAudioTime(); videoOutput->Show(ps); if (videoOutput->IsErrored()) { @@ -2373,6 +2388,19 @@ void MythPlayer::AVSync2(VideoFrame *buffer) } else wait_for_time(framedue); + + LOG(VB_PLAYBACK | VB_TIMESTAMP, LOG_INFO, LOC + + QString("A/V timecodes audio=%1 video=%2 frameinterval=%3 " + "audioadj=%4 tcoffset=%5 unow=%6 udue=%7") + .arg(prior_audiotimecode) + .arg(prior_videotimecode) + .arg(frame_interval) + .arg(audio_adjustment) + .arg(tc_wrap[TC_AUDIO]) + .arg(unow) + .arg(framedue) + ); + } void MythPlayer::RefreshPauseFrame(void) @@ -2451,7 +2479,6 @@ bool MythPlayer::PrebufferEnoughFrames(int min_buffers) if (!videoOutput) return false; - bool paused_now = false; if (!(min_buffers ? (videoOutput->ValidVideoFrames() >= min_buffers) : (GetEof() != kEofStateNone) || (videoOutput->hasHWAcceleration() ? @@ -2467,19 +2494,20 @@ bool MythPlayer::PrebufferEnoughFrames(int min_buffers) // for the jerking is detected. bool watchingTV = IsWatchingInprogress(); - if (!paused_now && (livetv || watchingTV) && !FlagIsSet(kMusicChoice)) + if ( (livetv || watchingTV) && !FlagIsSet(kMusicChoice)) { uint64_t frameCount = GetCurrentFrameCount(); uint64_t framesLeft = frameCount - framesPlayed; uint64_t margin = (uint64_t) (video_frame_rate * 3); if (framesLeft < margin) { - LOG(VB_PLAYBACK, LOG_NOTICE, LOC + - QString("Pause to allow live tv catch up. Position in sec. Current: %2, Total: %3") - .arg(framesPlayed).arg(frameCount)); + if (rtcbase) + LOG(VB_PLAYBACK, LOG_NOTICE, LOC + + QString("Pause to allow live tv catch up. Position in sec. Current: %2, Total: %3") + .arg(framesPlayed).arg(frameCount)); audio.Pause(true); avsync_audiopaused = true; - paused_now = true; + rtcbase = 0; } } usleep(frame_interval >> 3); diff --git a/mythtv/libs/libmythtv/mythplayer.h b/mythtv/libs/libmythtv/mythplayer.h index 7358d617a9d..4b295af28fe 100644 --- a/mythtv/libs/libmythtv/mythplayer.h +++ b/mythtv/libs/libmythtv/mythplayer.h @@ -856,6 +856,8 @@ class MTV_PUBLIC MythPlayer int maxtcframes; // number of frames seen since max to date tc int64_t avsync2adjustms; // number of milliseconds to adjust for av sync errors int numdroppedframes; // number of consecutive dropped frames. + int64_t prior_audiotimecode; // time code from prior frame + int64_t prior_videotimecode; // time code from prior frame // LiveTV TV *m_tv; diff --git a/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp b/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp index 01172048c5c..c6040d6c85d 100644 --- a/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp +++ b/mythtv/libs/libmythtv/recorders/ExternalStreamHandler.cpp @@ -1129,7 +1129,7 @@ bool ExternalStreamHandler::StartStreaming(void) if (StreamingCount() == 0) { - if (!ProcessCommand("StartStreaming", result, 10000)) + if (!ProcessCommand("StartStreaming", result, 15000)) { LogLevel_t level = LOG_ERR; if (result.toLower().startsWith("warn")) @@ -1196,7 +1196,7 @@ bool ExternalStreamHandler::StopStreaming(void) } QString result; - if (!ProcessCommand("StopStreaming", result, 6000)) + if (!ProcessCommand("StopStreaming", result, 10000)) { LogLevel_t level = LOG_ERR; if (result.toLower().startsWith("warn")) diff --git a/mythtv/libs/libmythtv/recorders/RTjpegN.cpp b/mythtv/libs/libmythtv/recorders/RTjpegN.cpp index e924a436bce..a9283af7ecf 100644 --- a/mythtv/libs/libmythtv/recorders/RTjpegN.cpp +++ b/mythtv/libs/libmythtv/recorders/RTjpegN.cpp @@ -525,6 +525,7 @@ void RTjpeg::QuantInit(void) for (i = 0; i < 64; i++) qtbl.int16[i] = static_cast(lqt[i]); + // cppcheck-suppress unreadVariable qtbl.int32 = cqt; for (i = 0; i < 64; i++) qtbl.int16[i] = static_cast(cqt[i]); diff --git a/mythtv/libs/libmythtv/recorders/cetonrtsp.cpp b/mythtv/libs/libmythtv/recorders/cetonrtsp.cpp index bad8435db6d..900244724ae 100644 --- a/mythtv/libs/libmythtv/recorders/cetonrtsp.cpp +++ b/mythtv/libs/libmythtv/recorders/cetonrtsp.cpp @@ -428,6 +428,7 @@ bool CetonRTSP::Setup(ushort clientPort1, ushort clientPort2, } QString transport = readParameters("Transport", params); + Q_UNUSED(transport); if (params.contains("ssrc")) { bool ok; diff --git a/mythtv/libs/libmythtv/recordingrule.cpp b/mythtv/libs/libmythtv/recordingrule.cpp index 6092b0b2fd2..cfd53a09b7b 100644 --- a/mythtv/libs/libmythtv/recordingrule.cpp +++ b/mythtv/libs/libmythtv/recordingrule.cpp @@ -256,7 +256,7 @@ bool RecordingRule::LoadByProgram(const ProgramInfo* proginfo) * search. It is inserted into a query after the * FROM clause and before the WHERE clause. For an * example, see the text inserted when matching on a - * datadirect genre. + * genre. * \param pginfo A pointer to an existing ProgramInfo structure. * \return True if search data was successfully loaded. */ diff --git a/mythtv/libs/libmythtv/tv_play.cpp b/mythtv/libs/libmythtv/tv_play.cpp index 698bff19e5f..2df36506e51 100644 --- a/mythtv/libs/libmythtv/tv_play.cpp +++ b/mythtv/libs/libmythtv/tv_play.cpp @@ -63,7 +63,6 @@ using namespace std; #include "jobqueue.h" #include "livetvchain.h" #include "playgroup.h" -#include "datadirect.h" #include "sourceutil.h" #include "cardutil.h" #include "channelutil.h" @@ -173,44 +172,6 @@ EMBEDRETURNVOIDEPG TV::RunProgramGuidePtr = nullptr; */ EMBEDRETURNVOIDFINDER TV::RunProgramFinderPtr = nullptr; -/// Helper class to load channel info for channel editor -class DDLoader : public QRunnable -{ - public: - explicit DDLoader(TV *parent) : m_parent(parent), m_sourceid(0) - { - setAutoDelete(false); - } - - void SetParent(TV *parent) { m_parent = parent; } - void SetSourceID(uint sourceid) { m_sourceid = sourceid; } - - void run(void) override // QRunnable - { - if (m_parent) - m_parent->RunLoadDDMap(m_sourceid); - else - SourceUtil::UpdateChannelsFromListings(m_sourceid); - - QMutexLocker locker(&m_lock); - m_sourceid = 0; - m_wait.wakeAll(); - } - - void wait(void) - { - QMutexLocker locker(&m_lock); - while (m_sourceid) - m_wait.wait(locker.mutex()); - } - - private: - TV *m_parent; - uint m_sourceid; - QMutex m_lock; - QWaitCondition m_wait; -}; - static const MenuBase dummy_menubase; class MenuNodeTuple @@ -1061,7 +1022,6 @@ TV::TV(void) askAllowLock(QMutex::Recursive), // Channel Editing chanEditMapLock(QMutex::Recursive), - ddMapSourceId(0), ddMapLoader(new DDLoader(this)), // Sleep Timer sleep_index(0), sleepTimerId(0), sleepDialogTimerId(0), // Idle Timer @@ -1423,26 +1383,6 @@ TV::~TV(void) lcd->switchToTime(); } - if (ddMapLoader) - { - ddMapLoader->wait(); - - if (ddMapSourceId) - { - ddMapLoader->SetParent(nullptr); - ddMapLoader->SetSourceID(ddMapSourceId); - ddMapLoader->setAutoDelete(true); - MThreadPool::globalInstance()->start(ddMapLoader, "DDLoadMapPost"); - } - else - { - delete ddMapLoader; - } - - ddMapSourceId = 0; - ddMapLoader = nullptr; - } - if (browsehelper) { delete browsehelper; @@ -10479,16 +10419,12 @@ void TV::StartChannelEditMode(PlayerContext *ctx) ReturnOSDLock(ctx, osd); QMutexLocker locker(&chanEditMapLock); - ddMapLoader->wait(); // Get the info available from the backend chanEditMap.clear(); ctx->recorder->GetChannelInfo(chanEditMap); - // Assuming the data is valid, try to load DataDirect listings. - uint sourceid = chanEditMap["sourceid"].toUInt(); - - // Update with XDS and DataDirect Info + // Update with XDS Info ChannelEditAutoFill(ctx, chanEditMap); // Set proper initial values for channel editor, and make it visible.. @@ -10500,12 +10436,6 @@ void TV::StartChannelEditMode(PlayerContext *ctx) osd->SetText(OSD_DLG_EDITOR, chanEditMap, kOSDTimeout_None); } ReturnOSDLock(ctx, osd); - - if (sourceid && (sourceid != ddMapSourceId)) - { - ddMapLoader->SetSourceID(sourceid); - MThreadPool::globalInstance()->start(ddMapLoader, "DDMapLoader"); - } } void TV::StartOsdNavigation(PlayerContext *ctx) @@ -10562,50 +10492,11 @@ bool TV::HandleOSDChannelEdit(PlayerContext *ctx, QString action) * \brief Automatically fills in as much information as possible. */ void TV::ChannelEditAutoFill(const PlayerContext *ctx, InfoMap &infoMap) const -{ - QMap dummy; - ChannelEditAutoFill(ctx, infoMap, dummy); -} - -/** \fn TV::ChannelEditAutoFill(const PlayerContext*,InfoMap&,const QMap&) const - * \brief Automatically fills in as much information as possible. - */ -void TV::ChannelEditAutoFill(const PlayerContext *ctx, InfoMap &infoMap, - const QMap &changed) const { const QString keys[4] = { "XMLTV", "callsign", "channame", "channum", }; // fill in uninitialized and unchanged fields from XDS ChannelEditXDSFill(ctx, infoMap); - - // if no data direct info we're done.. - if (!ddMapSourceId) - return; - - if (changed.size()) - { - ChannelEditDDFill(infoMap, changed, false); - } - else - { - QMutexLocker locker(&chanEditMapLock); - QMap chg; - // check if anything changed - for (uint i = 0; i < 4; i++) - chg[keys[i]] = infoMap[keys[i]] != chanEditMap[keys[i]]; - - // clean up case and extra spaces - infoMap["callsign"] = infoMap["callsign"].toUpper().trimmed(); - infoMap["channum"] = infoMap["channum"].trimmed(); - infoMap["channame"] = infoMap["channame"].trimmed(); - infoMap["XMLTV"] = infoMap["XMLTV"].trimmed(); - - // make sure changes weren't just chaff - for (uint i = 0; i < 4; i++) - chg[keys[i]] &= infoMap[keys[i]] != chanEditMap[keys[i]]; - - ChannelEditDDFill(infoMap, chg, true); - } } void TV::ChannelEditXDSFill(const PlayerContext *ctx, InfoMap &infoMap) const @@ -10644,204 +10535,6 @@ void TV::ChannelEditXDSFill(const PlayerContext *ctx, InfoMap &infoMap) const } } -void TV::ChannelEditDDFill(InfoMap &infoMap, - const QMap &changed, - bool check_unchanged) const -{ - if (!ddMapSourceId) - return; - - QMutexLocker locker(&chanEditMapLock); - const QString keys[4] = { "XMLTV", "callsign", "channame", "channum", }; - - // First check changed keys for availability in our listings source. - // Then, if check_unchanged is set, check unchanged fields. - QString key = "", dd_xmltv = ""; - uint endj = (check_unchanged) ? 2 : 1; - for (uint j = 0; (j < endj) && dd_xmltv.isEmpty(); j++) - { - for (uint i = 0; (i < 4) && dd_xmltv.isEmpty(); i++) - { - key = keys[i]; - if (((j == 1) ^ changed[key]) && !infoMap[key].isEmpty()) - dd_xmltv = GetDataDirect(key, infoMap[key], "XMLTV"); - } - } - - // If we found the channel in the listings, fill in all the data we have - if (!dd_xmltv.isEmpty()) - { - infoMap[keys[0]] = dd_xmltv; - for (uint i = 1; i < 4; i++) - { - QString tmp = GetDataDirect(key, infoMap[key], keys[i]); - if (!tmp.isEmpty()) - infoMap[keys[i]] = tmp; - } - return; - } - - // If we failed to find an exact match, try partial matches. - // But only fill the current field since this data is dodgy. - key = "callsign"; - if (!infoMap[key].isEmpty()) - { - dd_xmltv = GetDataDirect(key, infoMap[key], "XMLTV", true); - LOG(VB_GENERAL, LOG_INFO, QString("xmltv: %1 for key %2") - .arg(dd_xmltv).arg(key)); - if (!dd_xmltv.isEmpty()) - infoMap[key] = GetDataDirect("XMLTV", dd_xmltv, key); - } - - key = "channame"; - if (!infoMap[key].isEmpty()) - { - dd_xmltv = GetDataDirect(key, infoMap[key], "XMLTV", true); - LOG(VB_GENERAL, LOG_INFO, QString("xmltv: %1 for key %2") - .arg(dd_xmltv).arg(key)); - if (!dd_xmltv.isEmpty()) - infoMap[key] = GetDataDirect("XMLTV", dd_xmltv, key); - } -} - -QString TV::GetDataDirect(QString key, QString value, QString field, - bool allow_partial_match) const -{ - QMutexLocker locker(&chanEditMapLock); - - uint sourceid = chanEditMap["sourceid"].toUInt(); - if (!sourceid) - return QString(); - - if (sourceid != ddMapSourceId) - return QString(); - - DDKeyMap::const_iterator it_key = ddMap.find(key); - if (it_key == ddMap.end()) - return QString(); - - DDValueMap::const_iterator it_val = (*it_key).find(value); - if (it_val != (*it_key).end()) - { - InfoMap::const_iterator it_field = (*it_val).find(field); - if (it_field != (*it_val).end()) - { - return *it_field; - } - } - - if (!allow_partial_match || value.isEmpty()) - return QString(); - - // Check for partial matches.. prefer early match, then short string - DDValueMap::const_iterator best_match = (*it_key).end(); - int best_match_idx = INT_MAX, best_match_len = INT_MAX; - for (it_val = (*it_key).begin(); it_val != (*it_key).end(); ++it_val) - { - int match_idx = it_val.key().indexOf(value); - if (match_idx < 0) - continue; - - int match_len = it_val.key().length(); - if ((match_idx < best_match_idx) && (match_len < best_match_len)) - { - best_match = it_val; - best_match_idx = match_idx; - best_match_len = match_len; - } - } - - if (best_match != (*it_key).end()) - { - InfoMap::const_iterator it_field = (*best_match).find(field); - if (it_field != (*best_match).end()) - { - return *it_field; - } - } - - return QString(); -} - -void TV::RunLoadDDMap(uint sourceid) -{ - QMutexLocker locker(&chanEditMapLock); - - const PlayerContext *actx = GetPlayerReadLock(-1, __FILE__, __LINE__); - - // Load DataDirect info - LoadDDMap(sourceid); - - // Update with XDS and DataDirect Info - ChannelEditAutoFill(actx, chanEditMap); - - OSD *osd = GetOSDLock(actx); - if (osd) - { - if (osd->DialogVisible(OSD_DLG_EDITOR)) - osd->SetText(OSD_DLG_EDITOR, chanEditMap, kOSDTimeout_None); - else - LOG(VB_GENERAL, LOG_ERR, LOC + "No channel editor visible. Failed " - "to update data direct channel info."); - } - ReturnOSDLock(actx, osd); - ReturnPlayerLock(actx); -} - -bool TV::LoadDDMap(uint sourceid) -{ - QMutexLocker locker(&chanEditMapLock); - const QString keys[4] = { "XMLTV", "callsign", "channame", "channum", }; - - ddMap.clear(); - ddMapSourceId = 0; - - QString grabber, userid, passwd, lineupid; - bool ok = SourceUtil::GetListingsLoginData(sourceid, grabber, userid, - passwd, lineupid); - if (!ok || (grabber != "datadirect")) - { - LOG(VB_PLAYBACK, LOG_ERR, LOC + QString("g(%1)").arg(grabber)); - return false; - } - - DataDirectProcessor ddp(DD_ZAP2IT, userid, passwd); - ddp.GrabFullLineup(lineupid, true, false, 36*60*60); - const DDLineupChannels channels = ddp.GetDDLineup(lineupid); - - InfoMap tmp; - DDLineupChannels::const_iterator it; - for (it = channels.begin(); it != channels.end(); ++it) - { - DDStation station = ddp.GetDDStation((*it).m_stationid); - tmp["XMLTV"] = (*it).m_stationid; - tmp["callsign"] = station.m_callsign; - tmp["channame"] = station.m_stationname; - tmp["channum"] = (*it).m_channel; - if (!(*it).m_channelMinor.isEmpty()) - { - tmp["channum"] += SourceUtil::GetChannelSeparator(sourceid); - tmp["channum"] += (*it).m_channelMinor; - } - -#if 0 - LOG(VB_CHANNEL, LOG_INFO, - QString("Adding channel: %1 -- %2 -- %3 -- %4") - .arg(tmp["channum"],4).arg(tmp["callsign"],7) - .arg(tmp["XMLTV"]).arg(tmp["channame"])); -#endif - - for (uint j = 0; j < 4; j++) - for (uint i = 0; i < 4; i++) - ddMap[keys[j]][tmp[keys[j]]][keys[i]] = tmp[keys[i]]; - } - - if (!ddMap.empty()) - ddMapSourceId = sourceid; - - return !ddMap.empty(); -} - void TV::OSDDialogEvent(int result, QString text, QString action) { PlayerContext *actx = GetPlayerReadLock(-1, __FILE__, __LINE__); diff --git a/mythtv/libs/libmythtv/tv_play.h b/mythtv/libs/libmythtv/tv_play.h index 891132b72d5..5f483fddb9d 100644 --- a/mythtv/libs/libmythtv/tv_play.h +++ b/mythtv/libs/libmythtv/tv_play.h @@ -49,11 +49,8 @@ class PlayerContext; class TvPlayWindow; class TV; class TVBrowseHelper; -class DDLoader; struct osdInfo; -typedef QMap DDValueMap; -typedef QMap DDKeyMap; typedef void (*EMBEDRETURNVOID) (void *, bool); typedef void (*EMBEDRETURNVOIDEPG) (uint, const QString &, const QDateTime, TV *, bool, bool, int); typedef void (*EMBEDRETURNVOIDFINDER) (TV *, bool, bool); @@ -293,7 +290,6 @@ class MTV_PUBLIC TV : public QObject, public MenuItemDisplayer friend class ScheduleEditor; friend class TvPlayWindow; friend class TVBrowseHelper; - friend class DDLoader; Q_OBJECT public: @@ -696,14 +692,7 @@ class MTV_PUBLIC TV : public QObject, public MenuItemDisplayer void StartChannelEditMode(PlayerContext*); bool HandleOSDChannelEdit(PlayerContext*, QString action); void ChannelEditAutoFill(const PlayerContext*, InfoMap&) const; - void ChannelEditAutoFill(const PlayerContext*, InfoMap&, - const QMap&) const; void ChannelEditXDSFill(const PlayerContext*, InfoMap&) const; - void ChannelEditDDFill(InfoMap&, const QMap&, bool) const; - QString GetDataDirect(QString key, QString value, - QString field, bool allow_partial = false) const; - bool LoadDDMap(uint sourceid); - void RunLoadDDMap(uint sourceid); // General dialog handling bool DialogIsVisible(PlayerContext *ctx, const QString &dialog); @@ -853,10 +842,6 @@ class MTV_PUBLIC TV : public QObject, public MenuItemDisplayer mutable QMutex chanEditMapLock; ///< Lock for chanEditMap and ddMap InfoMap chanEditMap; ///< Channel Editing initial map - DDKeyMap ddMap; ///< DataDirect channel map - uint ddMapSourceId; ///< DataDirect channel map sourceid - DDLoader *ddMapLoader; ///< DataDirect map loader runnable - /// Vector or sleep timer sleep times in seconds, /// with the appropriate UI message. vector sleep_times; diff --git a/mythtv/libs/libmythtv/tv_rec.cpp b/mythtv/libs/libmythtv/tv_rec.cpp index ed25a5e11a2..e02c8038848 100644 --- a/mythtv/libs/libmythtv/tv_rec.cpp +++ b/mythtv/libs/libmythtv/tv_rec.cpp @@ -1197,7 +1197,9 @@ void TVRec::CloseChannel(void) { if (channel && ((genOpt.inputtype == "DVB" && dvbOpt.dvb_on_demand) || - genOpt.inputtype == "FREEBOX" || genOpt.inputtype == "VBOX" || + genOpt.inputtype == "FREEBOX" || + genOpt.inputtype == "VBOX" || + genOpt.inputtype == "HDHOMERUN" || CardUtil::IsV4L(genOpt.inputtype))) { channel->Close(); diff --git a/mythtv/libs/libmythtv/videosource.cpp b/mythtv/libs/libmythtv/videosource.cpp index c99de3b6294..2a3831285c1 100644 --- a/mythtv/libs/libmythtv/videosource.cpp +++ b/mythtv/libs/libmythtv/videosource.cpp @@ -29,7 +29,6 @@ using namespace std; #include "mythconfig.h" #include "mythcorecontext.h" #include "videosource.h" -#include "datadirect.h" #include "scanwizard.h" #include "cardutil.h" #include "sourceutil.h" @@ -228,16 +227,9 @@ class XMLTVGrabber : public MythUIComboBoxSetting void Load(void) override // StandardSetting { - addTargetedChild("schedulesdirect1", - new DataDirect_config(m_parent, DD_SCHEDULES_DIRECT, - this)); addTargetedChild("eitonly", new EITOnly_config(m_parent, this)); addTargetedChild("/bin/true", new NoGrabber_config(m_parent)); - addSelection( - QObject::tr("North America (SchedulesDirect.org) (Internal)"), - "schedulesdirect1"); - addSelection( QObject::tr("Transmitted guide only (EIT)"), "eitonly"); @@ -301,8 +293,7 @@ class XMLTVGrabber : public MythUIComboBoxSetting query.prepare( "UPDATE videosource " "SET userid=NULL, password=NULL " - "WHERE xmltvgrabber NOT IN ( 'datadirect', 'technovera', " - " 'schedulesdirect1' )"); + "WHERE xmltvgrabber NOT IN ( 'technovera' )"); if (!query.exec()) MythDB::DBError("XMLTVGrabber::Save", query); } @@ -479,116 +470,6 @@ class UseEIT : public MythUICheckBoxSetting } }; -class DataDirectUserID : public MythUITextEditSetting -{ - public: - explicit DataDirectUserID(const VideoSource &parent) : - MythUITextEditSetting(new VideoSourceDBStorage(this, parent, "userid")) - { - setLabel(QObject::tr("User ID")); - } -}; - -class DataDirectPassword : public MythUITextEditSetting -{ - public: - explicit DataDirectPassword(const VideoSource &parent) : - MythUITextEditSetting(new VideoSourceDBStorage(this, parent, "password")) - { - SetPasswordEcho(true); - setLabel(QObject::tr("Password")); - } -}; - -void DataDirectLineupSelector::fillSelections(const QString &uid, - const QString &pwd, - int _source) -{ - (void) uid; - (void) pwd; -#ifdef USING_BACKEND - if (uid.isEmpty() || pwd.isEmpty()) - return; - - qApp->processEvents(); - - DataDirectProcessor ddp(_source, uid, pwd); - QString waitMsg = tr("Fetching lineups from %1...") - .arg(ddp.GetListingsProviderName()); - - LOG(VB_GENERAL, LOG_INFO, waitMsg); - - GetNotificationCenter()->Queue(MythBusyNotification(waitMsg, - tr("DataDirect"))); - clearSelections(); - - if (!ddp.GrabLineupsOnly()) - { - MythErrorNotification en(tr("Fetching of lineups failed"), - tr("DataDirect")); - GetNotificationCenter()->Queue(en); - - LOG(VB_GENERAL, LOG_ERR, - "DDLS: fillSelections did not successfully load selections"); - return; - } - const DDLineupList lineups = ddp.GetLineups(); - - DDLineupList::const_iterator it; - for (it = lineups.begin(); it != lineups.end(); ++it) - addSelection((*it).m_displayname, (*it).m_lineupid); - - MythCheckNotification n(tr("Fetching of lineups complete"), - tr("DataDirect")); - GetNotificationCenter()->Queue(n); -#else // USING_BACKEND - LOG(VB_GENERAL, LOG_ERR, - "You must compile the backend to set up a DataDirect line-up"); -#endif // USING_BACKEND -} - -void DataDirect_config::Load() -{ - GroupSetting::Load(); - bool is_sd_userid = userid->getValue().contains('@') > 0; - bool match = ((is_sd_userid && (source == DD_SCHEDULES_DIRECT)) || - (!is_sd_userid && (source == DD_ZAP2IT))); - if (((userid->getValue() != lastloadeduserid) || - (password->getValue() != lastloadedpassword)) && match) - { - lineupselector->fillSelections(userid->getValue(), - password->getValue(), - source); - lastloadeduserid = userid->getValue(); - lastloadedpassword = password->getValue(); - } -} - -DataDirect_config::DataDirect_config(const VideoSource& _parent, int _source, StandardSetting *_setting) : - parent(_parent) -{ - setVisible(false); - - source = _source; - - _setting->addTargetedChild("schedulesdirect1", userid = new DataDirectUserID(parent)); - - _setting->addTargetedChild("schedulesdirect1", password = new DataDirectPassword(parent)); - _setting->addTargetedChild("schedulesdirect1", button = new DataDirectButton()); - - _setting->addTargetedChild("schedulesdirect1", lineupselector = new DataDirectLineupSelector(parent)); - _setting->addTargetedChild("schedulesdirect1", new UseEIT(parent)); - - connect(button, SIGNAL(clicked()), - this, SLOT(fillDataDirectLineupSelector())); -} - -void DataDirect_config::fillDataDirectLineupSelector(void) -{ - lineupselector->fillSelections( - userid->getValue(), password->getValue(), source); -} - XMLTV_generic_config::XMLTV_generic_config(const VideoSource& _parent, QString _grabber, StandardSetting *_setting) : diff --git a/mythtv/libs/libmythtv/videosource.h b/mythtv/libs/libmythtv/videosource.h index 51e15e1decf..707505820ac 100644 --- a/mythtv/libs/libmythtv/videosource.h +++ b/mythtv/libs/libmythtv/videosource.h @@ -6,8 +6,8 @@ using namespace std; #include "mthread.h" #include "standardsettings.h" -#include "datadirect.h" #include "mythcontext.h" +#include "mythtvexp.h" class SignalTimeout; class ChannelTimeout; @@ -26,30 +26,14 @@ class InputGroup; static inline bool is_grabber_external(const QString &grabber) { - return !(grabber == "datadirect" || - grabber == "eitonly" || - grabber == "schedulesdirect1" || + return !(grabber == "eitonly" || grabber == "/bin/true"); } -static inline bool is_grabber_datadirect(const QString &grabber) -{ - return (grabber == "datadirect") || (grabber == "schedulesdirect1"); -} - -static inline int get_datadirect_provider(const QString &grabber) -{ - if (grabber == "datadirect") - return DD_ZAP2IT; - else if (grabber == "schedulesdirect1") - return DD_SCHEDULES_DIRECT; - else - return -1; -} - static inline bool is_grabber_labs(const QString &grabber) { - return grabber == "datadirect"; + Q_UNUSED(grabber); + return false; } class VideoSourceDBStorage : public SimpleDBStorage @@ -115,56 +99,6 @@ class TransFreqTableSelector : public TransMythUIComboBoxSetting QString loaded_freq_table; }; -class DataDirectLineupSelector : - public MythUIComboBoxSetting -{ - Q_OBJECT -public: - explicit DataDirectLineupSelector(const VideoSource& parent) : - MythUIComboBoxSetting(new VideoSourceDBStorage(this, parent, "lineupid")) - { - setLabel(QObject::tr("Data Direct lineup")); - }; - - public slots: - void fillSelections(const QString& uid, const QString& pwd, int source); -}; - -class DataDirectButton : public ButtonStandardSetting -{ - public: - DataDirectButton() : ButtonStandardSetting(QObject::tr("Retrieve Lineups")) - { - } -}; - -class DataDirectUserID; -class DataDirectPassword; - -class DataDirect_config: public GroupSetting -{ - Q_OBJECT - public: - DataDirect_config(const VideoSource& _parent, int _ddsource, StandardSetting *_setting); - - void Load(void) override; // StandardSetting - - QString getLineupID(void) const { return lineupselector->getValue(); }; - - protected slots: - void fillDataDirectLineupSelector(void); - - protected: - const VideoSource &parent; - DataDirectUserID *userid; - DataDirectPassword *password; - DataDirectButton *button; - DataDirectLineupSelector *lineupselector; - QString lastloadeduserid; - QString lastloadedpassword; - int source; -}; - class XMLTV_generic_config: public GroupSetting { Q_OBJECT diff --git a/mythtv/libs/libmythui/AppleRemote.h b/mythtv/libs/libmythui/AppleRemote.h index 82560056108..620f364e878 100644 --- a/mythtv/libs/libmythui/AppleRemote.h +++ b/mythtv/libs/libmythui/AppleRemote.h @@ -55,7 +55,7 @@ class AppleRemote : public QObject, public MThread bool isOpenInExclusiveMode() { return openInExclusiveMode; }; void startListening(); void stopListening(); - void run(); + void run() override; // MThread protected: AppleRemote(); // will be a singleton class diff --git a/mythtv/libs/libmythui/mythuiguidegrid.cpp b/mythtv/libs/libmythui/mythuiguidegrid.cpp index bc7849c9e96..867459d0674 100644 --- a/mythtv/libs/libmythui/mythuiguidegrid.cpp +++ b/mythtv/libs/libmythui/mythuiguidegrid.cpp @@ -312,6 +312,8 @@ void MythUIGuideGrid::DrawSelf(MythPainter *p, int xoffset, int yoffset, } drawCurrent(p, xoffset, yoffset, &m_selectedItem, alphaMod); + // Redraw the current selection's text in case it was clobbered by the above call. + drawText(p, xoffset, yoffset, &m_selectedItem, alphaMod); for (int i = 0; i < m_rowCount; i++) { diff --git a/mythtv/libs/libmythui/screensaver-android.h b/mythtv/libs/libmythui/screensaver-android.h index 2666199baed..8e7ae647ab6 100644 --- a/mythtv/libs/libmythui/screensaver-android.h +++ b/mythtv/libs/libmythui/screensaver-android.h @@ -13,11 +13,11 @@ class ScreenSaverAndroid : public QObject, public ScreenSaver ScreenSaverAndroid(); ~ScreenSaverAndroid(); - void Disable(void); - void Restore(void); - void Reset(void); + void Disable(void) override; // ScreenSaver + void Restore(void) override; // ScreenSaver + void Reset(void) override; // ScreenSaver - bool Asleep(void); + bool Asleep(void) override; // ScreenSaver }; diff --git a/mythtv/libs/libmythui/screensaver-dbus.cpp b/mythtv/libs/libmythui/screensaver-dbus.cpp index 383b3452ae7..1c04b0e8db4 100644 --- a/mythtv/libs/libmythui/screensaver-dbus.cpp +++ b/mythtv/libs/libmythui/screensaver-dbus.cpp @@ -45,7 +45,8 @@ class ScreenSaverDBusPrivate friend class ScreenSaverDBus; public: - ScreenSaverDBusPrivate(QString dbusService, QString dbusPath, QString dbusInterface, QDBusConnection *bus) : + ScreenSaverDBusPrivate(const QString &dbusService, const QString &dbusPath, + const QString &dbusInterface, QDBusConnection *bus) : m_bus(bus), m_interface(new QDBusInterface(dbusService, dbusPath , dbusInterface, *m_bus)), m_serviceUsed(dbusService) @@ -102,7 +103,7 @@ class ScreenSaverDBusPrivate } } } - void SetUnInhibit(QString method) { m_unInhibit = method; } + void SetUnInhibit(const QString &method) { m_unInhibit = method; } protected: bool m_inhibited {false}; diff --git a/mythtv/libs/libmythui/screensaver-osx.h b/mythtv/libs/libmythui/screensaver-osx.h index 6403ebdfcb3..56b35200a9d 100644 --- a/mythtv/libs/libmythui/screensaver-osx.h +++ b/mythtv/libs/libmythui/screensaver-osx.h @@ -9,11 +9,11 @@ class ScreenSaverOSX : public ScreenSaver ScreenSaverOSX(); ~ScreenSaverOSX(); - void Disable(void); - void Restore(void); - void Reset(void); + void Disable(void) override; // ScreenSaver + void Restore(void) override; // ScreenSaver + void Reset(void) override; // ScreenSaver - bool Asleep(void); + bool Asleep(void) override; // ScreenSaver protected: class ScreenSaverOSXPrivate *d {nullptr}; diff --git a/mythtv/libs/libmythupnp/ssdpcache.h b/mythtv/libs/libmythupnp/ssdpcache.h index c6e250ecb48..3e32627adce 100644 --- a/mythtv/libs/libmythupnp/ssdpcache.h +++ b/mythtv/libs/libmythupnp/ssdpcache.h @@ -105,6 +105,7 @@ class UPNP_PUBLIC SSDPCache : public QObject, // ------------------------------------------------------------------ SSDPCache(); + Q_DISABLE_COPY(SSDPCache) public: diff --git a/mythtv/libs/libmythupnp/upnpsubscription.h b/mythtv/libs/libmythupnp/upnpsubscription.h index 2985b1f2900..530d37471ce 100644 --- a/mythtv/libs/libmythupnp/upnpsubscription.h +++ b/mythtv/libs/libmythupnp/upnpsubscription.h @@ -22,6 +22,7 @@ class UPNP_PUBLIC UPNPSubscription : public HttpServerExtension, public MythObse void Remove(const QString &usn); private: + Q_DISABLE_COPY(UPNPSubscription) static bool SendUnsubscribeRequest(const QString &usn, const QUrl &url, const QString &path, const QString &uuid); static int SendSubscribeRequest(const QString &callback, diff --git a/mythtv/programs/mythbackend/backendhousekeeper.cpp b/mythtv/programs/mythbackend/backendhousekeeper.cpp index 56065d5736c..6ccd067be05 100644 --- a/mythtv/programs/mythbackend/backendhousekeeper.cpp +++ b/mythtv/programs/mythbackend/backendhousekeeper.cpp @@ -651,9 +651,7 @@ bool MythFillDatabaseTask::UseSuggestedTime(void) // // TODO: this is really cludgy. there has to be a better way to test // result.prepare("SELECT COUNT(*) FROM videosource" // " WHERE xmltvgrabber IN" -// " ( 'datadirect'," -// " 'technovera'," -// " 'schedulesdirect1' );"); +// " ( 'technovera' );"); // if ((result.exec()) && // (result.next()) && // (result.value(0).toInt() > 0)) diff --git a/mythtv/programs/mythbackend/httpstatus.cpp b/mythtv/programs/mythbackend/httpstatus.cpp index 690e3e618e7..790d9b944aa 100644 --- a/mythtv/programs/mythbackend/httpstatus.cpp +++ b/mythtv/programs/mythbackend/httpstatus.cpp @@ -560,10 +560,6 @@ void HttpStatus::FillStatusXML( QDomDocument *pDoc ) guide.setAttribute("guideDays", qdtNow.daysTo(GuideDataThrough)); } - QDomText dataDirectMessage = - pDoc->createTextNode(gCoreContext->GetSetting("DataDirectMessage")); - guide.appendChild(dataDirectMessage); - // Add Miscellaneous information QString info_script = gCoreContext->GetSetting("MiscStatusScript"); @@ -1437,9 +1433,6 @@ int HttpStatus::PrintMachineInfo( QTextStream &os, QDomElement info ) else os << " There's no guide data available! " << "Have you run mythfilldatabase?"; - - if (!sMsg.isEmpty()) - os << "
\r\n DataDirect Status: " << sMsg; } } os << "\r\n \r\n"; diff --git a/mythtv/programs/mythbackend/scheduler.cpp b/mythtv/programs/mythbackend/scheduler.cpp index 9a91e030297..6aff4bd585a 100644 --- a/mythtv/programs/mythbackend/scheduler.cpp +++ b/mythtv/programs/mythbackend/scheduler.cpp @@ -75,7 +75,7 @@ Scheduler::Scheduler(bool runthread, QMap *tvList, master_sched->GetAllPending(m_reclist); if (!m_doRun) - m_dbConn = MSqlQuery::DDCon(); + m_dbConn = MSqlQuery::ChannelCon(); if (tmptable == "powerpriority_tmp") { diff --git a/mythtv/programs/mythbackend/services/channel.cpp b/mythtv/programs/mythbackend/services/channel.cpp index 1a87c437f25..a8f2e99583f 100644 --- a/mythtv/programs/mythbackend/services/channel.cpp +++ b/mythtv/programs/mythbackend/services/channel.cpp @@ -38,7 +38,6 @@ #include "channelutil.h" #include "sourceutil.h" #include "cardutil.h" -#include "datadirect.h" #include "mythdate.h" #include "serviceUtil.h" @@ -358,39 +357,11 @@ bool Channel::RemoveVideoSource( uint nSourceID ) // ///////////////////////////////////////////////////////////////////////////// -DTC::LineupList* Channel::GetDDLineupList( const QString &sSource, - const QString &sUserId, - const QString &sPassword ) +DTC::LineupList* Channel::GetDDLineupList( const QString &/*sSource*/, + const QString &/*sUserId*/, + const QString &/*sPassword*/ ) { DTC::LineupList *pLineups = new DTC::LineupList(); - - if (sSource.toLower() == "schedulesdirect1" || - sSource.toLower() == "schedulesdirect" || - sSource.isEmpty()) - { - int source = 1; - DataDirectProcessor ddp(source, sUserId, sPassword); - if (!ddp.GrabLineupsOnly()) - { - delete pLineups; - throw( QString("Unable to grab lineups. Check info.")); - } - const DDLineupList lineups = ddp.GetLineups(); - - DDLineupList::const_iterator it; - for (it = lineups.begin(); it != lineups.end(); ++it) - { - DTC::Lineup *pLineup = pLineups->AddNewLineup(); - - pLineup->setLineupId((*it).m_lineupid); - pLineup->setName((*it).m_name); - pLineup->setDisplayName((*it).m_displayname); - pLineup->setType((*it).m_type); - pLineup->setPostal((*it).m_postal); - pLineup->setDevice((*it).m_device); - } - } - return pLineups; } diff --git a/mythtv/programs/mythbackend/services/channel.h b/mythtv/programs/mythbackend/services/channel.h index 1cf82d08113..d52798189d3 100644 --- a/mythtv/programs/mythbackend/services/channel.h +++ b/mythtv/programs/mythbackend/services/channel.h @@ -118,9 +118,9 @@ class Channel : public ChannelServices bool RemoveVideoSource ( uint SourceID ) override; // ChannelServices - DTC::LineupList* GetDDLineupList ( const QString &Source, - const QString &UserId, - const QString &Password ) override; // ChannelServices + DTC::LineupList* GetDDLineupList ( const QString &/*Source*/, + const QString &/*UserId*/, + const QString &/*Password*/ ) override; // ChannelServices int FetchChannelsFromSource( const uint SourceId, const uint CardId, diff --git a/mythtv/programs/mythexternrecorder/MythExternRecApp.cpp b/mythtv/programs/mythexternrecorder/MythExternRecApp.cpp index bc7a67cbb9f..f4970d62baf 100644 --- a/mythtv/programs/mythexternrecorder/MythExternRecApp.cpp +++ b/mythtv/programs/mythexternrecorder/MythExternRecApp.cpp @@ -31,7 +31,8 @@ MythExternRecApp::MythExternRecApp(const QString & command, const QString & conf_file, - const QString & log_file) + const QString & log_file, + const QString & logging) : QObject() , m_fatal(false) , m_run(true) @@ -43,6 +44,7 @@ MythExternRecApp::MythExternRecApp(const QString & command, , m_lock_timeout(0) , m_scan_timeout(120000) , m_log_file(log_file) + , m_logging(logging) , m_config_ini(conf_file) , m_tuned(false) , m_chan_settings(nullptr) @@ -146,7 +148,8 @@ bool MythExternRecApp::Open(void) qRegisterMetaType("QProcess::ExitStatus"); QObject::connect(&m_proc, - static_cast + static_cast (&QProcess::finished), this, &MythExternRecApp::ProcFinished); @@ -391,7 +394,24 @@ Q_SLOT void MythExternRecApp::TuneChannel(const QString & serial, { m_command.replace("%URL%", url); LOG(VB_CHANNEL, LOG_DEBUG, LOC + - QString(": '%URL%' replaced in cmd: '%1'").arg(m_command)); + QString(": '%URL%' replaced with '%1' in cmd: '%2'") + .arg(url).arg(m_command)); + } + + if (!m_log_file.isEmpty() && m_command.indexOf("%LOGFILE%") >= 0) + { + m_command.replace("%LOGFILE%", m_log_file); + LOG(VB_RECORD, LOG_DEBUG, LOC + + QString(": '%LOGFILE%' replaced with '%1' in cmd: '%2'") + .arg(m_log_file).arg(m_command)); + } + + if (!m_logging.isEmpty() && m_command.indexOf("%LOGGING%") >= 0) + { + m_command.replace("%LOGGING%", m_logging); + LOG(VB_RECORD, LOG_DEBUG, LOC + + QString(": '%LOGGING%' replaced with '%1' in cmd: '%2'") + .arg(m_logging).arg(m_command)); } m_desc = m_rec_desc; @@ -498,7 +518,7 @@ Q_SLOT void MythExternRecApp::StopStreaming(const QString & serial, bool silent) if (m_proc.state() == QProcess::Running) { m_proc.terminate(); - m_proc.waitForFinished(); + m_proc.waitForFinished(3000); m_proc.kill(); LOG(VB_RECORD, LOG_INFO, LOC + ": External application terminated."); diff --git a/mythtv/programs/mythexternrecorder/MythExternRecApp.h b/mythtv/programs/mythexternrecorder/MythExternRecApp.h index 175a30b933a..e1115122fd3 100644 --- a/mythtv/programs/mythexternrecorder/MythExternRecApp.h +++ b/mythtv/programs/mythexternrecorder/MythExternRecApp.h @@ -35,7 +35,7 @@ class MythExternRecApp : public QObject public: MythExternRecApp(const QString & command, const QString & conf_file, - const QString & log_file); + const QString & log_file, const QString & logging); ~MythExternRecApp(void); bool Open(void); @@ -108,6 +108,7 @@ class MythExternRecApp : public QObject uint m_scan_timeout; QString m_log_file; + QString m_logging; QString m_config_ini; QString m_desc; diff --git a/mythtv/programs/mythexternrecorder/external-ffmpeg.conf b/mythtv/programs/mythexternrecorder/external-ffmpeg.conf index 934cc4459aa..3804c1301bd 100644 --- a/mythtv/programs/mythexternrecorder/external-ffmpeg.conf +++ b/mythtv/programs/mythexternrecorder/external-ffmpeg.conf @@ -2,6 +2,9 @@ # The recorder command to execute. %URL% is optional, and # will be replaced with the channel's "URL" as defined in the # [TUNER/channels] (channel conf) configuration file +# +# %LOGGING% will be replaced with mythtv logging params. For example: +# --verbose general,channel,record --logpath /var/log/mythtv --loglevel info --quiet command=/opt/ffmpeg/bin/ffmpeg -hide_banner -nostats -loglevel panic -re -i \"%URL%\" -c:v copy -c:a copy -f mpegts - # Used in logging events diff --git a/mythtv/programs/mythexternrecorder/external-twitch.conf b/mythtv/programs/mythexternrecorder/external-twitch.conf index ed251fa6f95..d35bd188c06 100644 --- a/mythtv/programs/mythexternrecorder/external-twitch.conf +++ b/mythtv/programs/mythexternrecorder/external-twitch.conf @@ -2,6 +2,9 @@ # The recorder command to execute. %URL% is optional, and # will be replaced with the channel's "URL" as defined in the # [TUNER/channels] (channel conf) configuration file +# +# %LOGGING% will be replaced with mythtv logging params. For example: +# --verbose general,channel,record --logpath /var/log/mythtv --loglevel info --quiet command="/usr/bin/youtube-dl --hls-use-mpegts --ffmpeg-location /opt/ffmpeg/bin --external-downloader-args \"-hide_banner -nostats -loglevel panic -re\" -o - \"%URL%\"" diff --git a/mythtv/programs/mythexternrecorder/external-vlc.conf b/mythtv/programs/mythexternrecorder/external-vlc.conf index 843f8485852..73ad30db024 100644 --- a/mythtv/programs/mythexternrecorder/external-vlc.conf +++ b/mythtv/programs/mythexternrecorder/external-vlc.conf @@ -2,6 +2,9 @@ # The recorder command to execute. %URL% is optional, and # will be replaced with the channel's "URL" as defined in the # [TUNER/channels] (channel conf) configuration file +# +# %LOGGING% will be replaced with mythtv logging params. For example: +# --verbose general,channel,record --logpath /var/log/mythtv --loglevel info --quiet command="cvlc \"%URL%\" --sout \"#std{mux=ts,access=file,dst=-}\"" # Used in logging events, %ARG% are replaced from the channel info diff --git a/mythtv/programs/mythexternrecorder/main.cpp b/mythtv/programs/mythexternrecorder/main.cpp index 77ba6fc16e4..11a97d1ddad 100644 --- a/mythtv/programs/mythexternrecorder/main.cpp +++ b/mythtv/programs/mythexternrecorder/main.cpp @@ -63,6 +63,7 @@ int main(int argc, char *argv[]) if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK) return retval; QString logfile = cmdline.GetLogFilePath(); + QString logging = logPropagateArgs; MythExternControl *control = new MythExternControl(); MythExternRecApp *process = nullptr; @@ -70,12 +71,12 @@ int main(int argc, char *argv[]) QString conf_file = cmdline.toString("conf"); if (!conf_file.isEmpty()) { - process = new MythExternRecApp("", conf_file, logfile); + process = new MythExternRecApp("", conf_file, logfile, logging); } else if (!cmdline.toString("exec").isEmpty()) { QString command = cmdline.toString("exec"); - process = new MythExternRecApp(command, "", logfile); + process = new MythExternRecApp(command, "", logfile, logging); } else if (!cmdline.toString("infile").isEmpty()) { @@ -83,7 +84,7 @@ int main(int argc, char *argv[]) QString command = QString("ffmpeg -re -i \"%1\" " "-c:v copy -c:a copy -f mpegts -") .arg(filename); - process = new MythExternRecApp(command, "", logfile); + process = new MythExternRecApp(command, "", logfile, logging); } QObject::connect(process, &MythExternRecApp::Opened, diff --git a/mythtv/programs/mythfilldatabase/channeldata.cpp b/mythtv/programs/mythfilldatabase/channeldata.cpp index d155e74d7b2..b09c67b9631 100644 --- a/mythtv/programs/mythfilldatabase/channeldata.cpp +++ b/mythtv/programs/mythfilldatabase/channeldata.cpp @@ -41,7 +41,7 @@ static void get_atsc_stuff(QString channum, int sourceid, int freqid, freq = get_center_frequency("atsc", "vsb8", "us", freqid); // Check if this is connected to an HDTV card. - MSqlQuery query(MSqlQuery::DDCon()); + MSqlQuery query(MSqlQuery::ChannelCon()); query.prepare( "SELECT cardtype " "FROM capturecard " @@ -72,8 +72,7 @@ bool ChannelData::insert_chan(uint sourceid) isEncoder = CardUtil::IsEncoder(m_cardType); isUnscanable = CardUtil::IsUnscanable(m_cardType); } - insert_channels = (isCableCard || isEncoder || isUnscanable) && - !m_removeNewChannels; + insert_channels = (isCableCard || isEncoder || isUnscanable); } return insert_channels; diff --git a/mythtv/programs/mythfilldatabase/channeldata.h b/mythtv/programs/mythfilldatabase/channeldata.h index d3c3284a955..7710df6e0cc 100644 --- a/mythtv/programs/mythfilldatabase/channeldata.h +++ b/mythtv/programs/mythfilldatabase/channeldata.h @@ -29,7 +29,6 @@ class ChannelData bool m_guideDataOnly {false}; bool m_channelPreset {false}; bool m_channelUpdates {false}; - bool m_removeNewChannels {false}; bool m_filterNewChannels {false}; QString m_cardType; }; diff --git a/mythtv/programs/mythfilldatabase/commandlineparser.cpp b/mythtv/programs/mythfilldatabase/commandlineparser.cpp index d1ad7f1f3ab..e677169b407 100644 --- a/mythtv/programs/mythfilldatabase/commandlineparser.cpp +++ b/mythtv/programs/mythfilldatabase/commandlineparser.cpp @@ -29,12 +29,6 @@ void MythFillDatabaseCommandLineParser::LoadArguments(void) "Bypass grabbers and define sourceid and file", "Directly define the sourceid and XMLTV file to " "import.") - ->SetBlocks("ddfile") - ->SetRequires("sourceid"); - add("--dd-file", "ddfile", false, - "Bypass grabber, and read SD data from file", - "Directly define the data needed to import a local " - "DataDirect download.") ->SetRequires("sourceid"); add("--sourceid", "sourceid", 0, "Operate on single source", @@ -43,18 +37,11 @@ void MythFillDatabaseCommandLineParser::LoadArguments(void) add("--offset", "offset", 0, "Day offset of input xml file", "Specify how many days offset from today is the " - "information in the given XML file.") - ->SetRequiredChildOf("ddfile"); - - add("--lineupid", "lineupid", 0, "DataDirect lineup of input xml file", - "Specify the DataDirect lineup that corresponds to " - "the information in the given XML file.") - ->SetRequiredChildOf("ddfile"); + "information in the given XML file."); add("--xmlfile", "xmlfile", "", "XML file to import manually", "Specify an XML guide data file to import directly " "rather than pull data through the specified grabber.") - ->SetRequiredChildOf("ddfile") ->SetRequiredChildOf("file"); @@ -73,24 +60,13 @@ void MythFillDatabaseCommandLineParser::LoadArguments(void) add("--do-channel-updates", "dochannelupdates", false, - "update channels using datadirect", - "When using DataDirect, ask mythfilldatabase to " + "update channels", + "Ask mythfilldatabase to " "overwrite channel names, frequencies, etc. with " "values available from the data source. This will " "override custom channel names, which is why it " "is disabled by default.") ->SetGroup("Channel List Handling"); - add("--remove-new-channels", "removechannels", false, - "disable new channels on datadirect web interface", - "When using DataDirect, ask mythfilldatabase to " - "mark any new channels as disabled on the remote " - "lineup. Channels can be manually enabled on the " - "website at a later time, and incorporated into " - "MythTV by running mythfilldatabase without this " - "option. New digital channels cannot be directly " - "imported and thus are disabled automatically.") - ->SetBlocks("file") - ->SetGroup("Channel List Handling"); add("--do-not-filter-new-channels", "nofilterchannels", false, "don't filter ATSC channels for addition", "Normally, MythTV tries to avoid adding ATSC " @@ -126,51 +102,39 @@ void MythFillDatabaseCommandLineParser::LoadArguments(void) add("--refresh-today", "refreshtoday", false, "", "This option is only valid for selected grabbers.\n" "Force a refresh for today's guide data.\nThis can be used " - "in combination with other --refresh- options.\n" - "If being used with datadirect, this option should not be " - "used, rather use --dd-grab-all to pull all listings each time.") + "in combination with other --refresh- options.") ->SetDeprecated("use --refresh instead") ->SetGroup("Filtering"); add("--dont-refresh-tomorrow", "dontrefreshtomorrow", false, "", "This option is only valid for selected grabbers.\n" "Prevent mythfilldatabase from pulling information for " "tomorrow's listings. Data for tomorrow is always pulled " - "unless specifically specified otherwise.\n" - "If being used with datadirect, this option should not be " - "used, rather use --dd-grab-all to pull all listings each time.") + "unless specifically specified otherwise.") ->SetDeprecated("use --refresh instead") ->SetGroup("Filtering"); add("--refresh-second", "refreshsecond", false, "", "This option is only valid for selected grabbers.\n" "Force a refresh for guide data two days from now. This can " - "be used in combination with other --refresh- options.\n" - "If being used with datadirect, this option should not be " - "used, rather use --dd-grab-all to pull all listings each time.") + "be used in combination with other --refresh- options.") ->SetDeprecated("use --refresh instead") ->SetGroup("Filtering"); add("--refresh-day", "refreshday", QVariant::StringList, "", "This option is only valid for selected grabbers.\n" "Force a refresh for guide data on a specific day. This can " - "be used in combination with other --refresh- options.\n" - "If being used with datadirect, this option should not be " - "used, rather use --dd-grab-all to pull all listings each time.") + "be used in combination with other --refresh- options.") ->SetDeprecated("use --refresh instead") ->SetGroup("Filtering"); add("--dont-refresh-tba", "dontrefreshtba", false, "don't refresh \"To be announced\" programs", "This option is only valid for selected grabbers.\n" "Prevent mythfilldatabase from automatically refreshing any " - "programs marked as \"To be announced\".\n" - "If being used with datadirect, this option should not be " - "used, rather use --dd-grab-all to pull all listings each time.") + "programs marked as \"To be announced\".") ->SetGroup("Filtering"); add("--refresh-all", "refreshall", false, "", "This option is only valid for selected grabbers.\n" "This option forces a refresh of all guide data, but does so " - "with fourteen downloads of one day each.\n" - "If being used with datadirect, this option should not be " - "used, rather use --dd-grab-all to pull all listings each time.") + "with fourteen downloads of one day each.") ->SetDeprecated("use --refresh instead") ->SetBlocks("dontrefreshtomorrow") ->SetBlocks("refreshsecond") @@ -186,19 +150,6 @@ void MythFillDatabaseCommandLineParser::LoadArguments(void) "amount of data") ->SetGroup("Filtering"); - add("--dd-grab-all", "ddgraball", false, - "refresh full data using DataDirect", - "This option is only valid for selected grabbers (DataDirect).\n" - "This option is the preferred way of updating guide data from " - "DataDirect, and pulls all fourteen days of guide data at once.") - ->SetBlocks("refreshtoday") - ->SetBlocks("dontrefreshtomorrow") - ->SetBlocks("refreshsecond") - ->SetBlocks("refreshall") - ->SetBlocks("refreshday") - ->SetBlocks("dontrefreshtba") - ->SetBlocks("maxdays"); - add("--only-update-channels", "onlychannels", false, "only update channel lineup", "Download as little listings data as possible to update the " diff --git a/mythtv/programs/mythfilldatabase/filldata.cpp b/mythtv/programs/mythfilldatabase/filldata.cpp index 775cb0f81ae..73044138ad5 100644 --- a/mythtv/programs/mythfilldatabase/filldata.cpp +++ b/mythtv/programs/mythfilldatabase/filldata.cpp @@ -86,225 +86,6 @@ void FillData::SetRefresh(int day, bool set) } } -// DataDirect stuff -void FillData::DataDirectStationUpdate(Source source) -{ - DataDirectProcessor::UpdateStationViewTable(source.lineupid); - - bool insert_channels = m_chan_data.insert_chan(source.id); - int new_channels = DataDirectProcessor::UpdateChannelsSafe( - source.id, insert_channels, m_chan_data.m_filterNewChannels); - - // User must pass "--do-channel-updates" for these updates - if (m_chan_data.m_channelUpdates) - { - DataDirectProcessor::UpdateChannelsUnsafe( - source.id, m_chan_data.m_filterNewChannels); - } - // TODO delete any channels which no longer exist in listings source - - // Unselect channels not in users lineup for DVB, HDTV - if (!insert_channels && (new_channels > 0) && - is_grabber_labs(source.xmltvgrabber)) - { - bool ok0 = (m_logged_in == source.userid); - bool ok1 = (m_raw_lineup == source.id); - if (!ok0) - { - LOG(VB_GENERAL, LOG_INFO, - "Grabbing login cookies for listing update"); - ok0 = m_ddprocessor.GrabLoginCookiesAndLineups(); - } - if (ok0 && !ok1) - { - LOG(VB_GENERAL, LOG_INFO, "Grabbing listing for listing update"); - ok1 = m_ddprocessor.GrabLineupForModify(source.lineupid); - } - if (ok1) - { - m_ddprocessor.UpdateListings(source.id); - LOG(VB_GENERAL, LOG_INFO, - QString("Removed %1 channel(s) from lineup.") - .arg(new_channels)); - } - } -} - -bool FillData::DataDirectUpdateChannels(Source source) -{ - if (get_datadirect_provider(source.xmltvgrabber) >= 0) - { - m_ddprocessor.SetListingsProvider( - get_datadirect_provider(source.xmltvgrabber)); - } - else - { - LOG(VB_GENERAL, LOG_ERR, LOC + - "We only support DataDirectUpdateChannels with " - "TMS Labs and Schedules Direct."); - return false; - } - - m_ddprocessor.SetUserID(source.userid); - m_ddprocessor.SetPassword(source.password); - - bool ok = true; - if (!is_grabber_labs(source.xmltvgrabber)) - { - ok = m_ddprocessor.GrabLineupsOnly(); - } - else - { - ok = m_ddprocessor.GrabFullLineup( - source.lineupid, true, m_chan_data.insert_chan(source.id)/*only sel*/); - m_logged_in = source.userid; - m_raw_lineup = source.id; - } - - if (ok) - DataDirectStationUpdate(source); - - return ok; -} - -bool FillData::GrabDDData(Source source, int poffset, - QDate pdate, int ddSource) -{ - if (source.dd_dups.empty()) - m_ddprocessor.SetCacheData(false); - else - { - LOG(VB_GENERAL, LOG_INFO, - QString("This DataDirect listings source is " - "shared by %1 MythTV lineups") - .arg(source.dd_dups.size()+1)); - if (source.id > source.dd_dups[0]) - { - LOG(VB_GENERAL, LOG_NOTICE, - "We should use cached data for this one"); - } - else if (source.id < source.dd_dups[0]) - { - LOG(VB_GENERAL, LOG_NOTICE, - "We should keep data around after this one"); - } - m_ddprocessor.SetCacheData(true); - } - - m_ddprocessor.SetListingsProvider(ddSource); - m_ddprocessor.SetUserID(source.userid); - m_ddprocessor.SetPassword(source.password); - - bool needtoretrieve = true; - - if (source.userid != m_lastdduserid) - m_dddataretrieved = false; - - if (m_dd_grab_all && m_dddataretrieved) - needtoretrieve = false; - - QString status = QObject::tr("currently running."); - - updateLastRunStart(); - - if (needtoretrieve) - { - LOG(VB_GENERAL, LOG_INFO, "Retrieving datadirect data."); - if (m_dd_grab_all) - { - LOG(VB_GENERAL, LOG_INFO, "Grabbing ALL available data."); - if (!m_ddprocessor.GrabAllData()) - { - LOG(VB_GENERAL, LOG_ERR, "Encountered error in grabbing data."); - return false; - } - } - else - { - QDateTime fromdatetime = - QDateTime(pdate, QTime(0,0), Qt::UTC).addDays(poffset); - QDateTime todatetime = fromdatetime.addDays(1); - - LOG(VB_GENERAL, LOG_INFO, QString("Grabbing data for %1 offset %2") - .arg(pdate.toString()) - .arg(poffset)); - LOG(VB_GENERAL, LOG_INFO, QString("From %1 to %2 (UTC)") - .arg(fromdatetime.toString(Qt::ISODate)) - .arg(todatetime.toString(Qt::ISODate))); - - if (!m_ddprocessor.GrabData(fromdatetime, todatetime)) - { - LOG(VB_GENERAL, LOG_ERR, "Encountered error in grabbing data."); - return false; - } - } - - m_dddataretrieved = true; - m_lastdduserid = source.userid; - } - else - { - LOG(VB_GENERAL, LOG_INFO, - "Using existing grabbed data in temp tables."); - } - - LOG(VB_GENERAL, LOG_INFO, - QString("Grab complete. Actual data from %1 to %2 (UTC)") - .arg(m_ddprocessor.GetDDProgramsStartAt().toString(Qt::ISODate)) - .arg(m_ddprocessor.GetDDProgramsEndAt().toString(Qt::ISODate))); - - updateLastRunEnd(); - - LOG(VB_GENERAL, LOG_INFO, "Main temp tables populated."); - if (!m_channel_update_run) - { - LOG(VB_GENERAL, LOG_INFO, "Updating MythTV channels."); - DataDirectStationUpdate(source); - LOG(VB_GENERAL, LOG_INFO, "Channels updated."); - m_channel_update_run = true; - } - -#if 0 - LOG(VB_GENERAL, LOG_INFO, "Creating program view table..."); -#endif - DataDirectProcessor::UpdateProgramViewTable(source.id); -#if 0 - LOG(VB_GENERAL, LOG_INFO, "Finished creating program view table..."); -#endif - - MSqlQuery query(MSqlQuery::DDCon()); - query.prepare("SELECT count(*) from dd_v_program;"); - if (query.exec() && query.next()) - { - if (query.value(0).toInt() < 1) - { - LOG(VB_GENERAL, LOG_INFO, "Did not find any new program data."); - return false; - } - } - else - { - LOG(VB_GENERAL, LOG_ERR, "Failed testing program view table."); - return false; - } - - LOG(VB_GENERAL, LOG_INFO, "Clearing data for source."); - QDateTime from = m_ddprocessor.GetDDProgramsStartAt(); - QDateTime to = m_ddprocessor.GetDDProgramsEndAt(); - - LOG(VB_GENERAL, LOG_INFO, QString("Clearing from %1 to %2 (localtime)") - .arg(from.toLocalTime().toString(Qt::ISODate)) - .arg(to.toLocalTime().toString(Qt::ISODate))); - ProgramData::ClearDataBySource(source.id, from, to, true); - LOG(VB_GENERAL, LOG_INFO, "Data for source cleared."); - - LOG(VB_GENERAL, LOG_INFO, "Updating programs."); - DataDirectProcessor::DataDirectProgramUpdate(); - LOG(VB_GENERAL, LOG_INFO, "Program table update complete."); - - return true; -} - // XMLTV stuff bool FillData::GrabDataFromFile(int id, QString &filename) { @@ -328,23 +109,10 @@ bool FillData::GrabDataFromFile(int id, QString &filename) return true; } -bool FillData::GrabData(Source source, int offset, QDate *qCurrentDate) +bool FillData::GrabData(Source source, int offset) { QString xmltv_grabber = source.xmltvgrabber; - int dd_provider = get_datadirect_provider(xmltv_grabber); - if (dd_provider >= 0) - { - if (!GrabDDData(source, offset, *qCurrentDate, dd_provider)) - { - QStringList errors = m_ddprocessor.GetFatalErrors(); - for (int i = 0; i < errors.size(); i++) - m_fatalErrors.push_back(errors[i]); - return false; - } - return true; - } - const QString templatename = "/tmp/mythXXXXXX"; const QString tempfilename = createTempFile(templatename); if (templatename == tempfilename) @@ -452,27 +220,6 @@ bool FillData::GrabData(Source source, int offset, QDate *qCurrentDate) return succeeded; } -bool FillData::GrabDataFromDDFile( - int id, int offset, const QString &filename, - const QString &lineupid, QDate *qCurrentDate) -{ - QDate *currentd = qCurrentDate; - QDate qcd = MythDate::current().date(); - if (!currentd) - currentd = &qcd; - - m_ddprocessor.SetInputFile(filename); - Source s; - s.id = id; - s.xmltvgrabber = "datadirect"; - s.userid = "fromfile"; - s.password = "fromfile"; - s.lineupid = lineupid; - - return GrabData(s, offset, currentd); -} - - /** \fn FillData::Run(SourceList &sourcelist) * \brief Goes through the sourcelist and updates its channels with * program info grabbed with the associated grabber. @@ -495,33 +242,26 @@ bool FillData::Run(SourceList &sourcelist) m_need_post_grab_proc = false; int nonewdata = 0; - bool has_dd_source = false; - // find all DataDirect duplicates, so we only data download once. for (it = sourcelist.begin(); it != sourcelist.end(); ++it) { - if (!is_grabber_datadirect((*it).xmltvgrabber)) - continue; + if (!m_fatalErrors.empty()) + break; + + QString xmltv_grabber = (*it).xmltvgrabber; - has_dd_source = true; - for (it2 = sourcelist.begin(); it2 != sourcelist.end(); ++it2) + if (xmltv_grabber == "datadirect" || + xmltv_grabber == "schedulesdirect1") { - if (((*it).id != (*it2).id) && - ((*it).xmltvgrabber == (*it2).xmltvgrabber) && - ((*it).userid == (*it2).userid) && - ((*it).password == (*it2).password)) - { - (*it).dd_dups.push_back((*it2).id); - } + LOG(VB_GENERAL, LOG_ERR, + QString("Source %1 is configured to use the DataDirect guide" + "service from Schedules Direct. That service is no " + "longer supported by MythTV. Update to use one of " + "the XMLTV grabbers that use the JSON-based guide " + "service from Schedules Direct.") + .arg((*it).id)); + continue; } - } - if (has_dd_source) - m_ddprocessor.CreateTempDirectory(); - - for (it = sourcelist.begin(); it != sourcelist.end(); ++it) - { - if (!m_fatalErrors.empty()) - break; query.prepare("SELECT MAX(endtime) FROM program p LEFT JOIN channel c " "ON p.chanid=c.chanid WHERE c.sourceid= :SRCID " @@ -538,8 +278,6 @@ bool FillData::Run(SourceList &sourcelist) m_channel_update_run = false; m_endofdata = false; - QString xmltv_grabber = (*it).xmltvgrabber; - if (xmltv_grabber == "eitonly") { LOG(VB_GENERAL, LOG_INFO, @@ -666,34 +404,21 @@ bool FillData::Run(SourceList &sourcelist) } } - m_need_post_grab_proc |= !is_grabber_datadirect(xmltv_grabber); + m_need_post_grab_proc |= true; - if (is_grabber_datadirect(xmltv_grabber) && m_dd_grab_all) - { - if (m_only_update_channels) - DataDirectUpdateChannels(*it); - else - { - QDate qCurrentDate = MythDate::current().date(); - if (!GrabData(*it, 0, &qCurrentDate)) - ++failures; - } - } - else if ((*it).xmltvgrabber_prefmethod == "allatonce" && !m_no_allatonce) + if ((*it).xmltvgrabber_prefmethod == "allatonce" && !m_no_allatonce) { if (!GrabData(*it, 0)) ++failures; } - else if ((*it).xmltvgrabber_baseline || - is_grabber_datadirect(xmltv_grabber)) + else if ((*it).xmltvgrabber_baseline) { QDate qCurrentDate = MythDate::current().date(); // We'll keep grabbing until it returns nothing // Max days currently supported is 21 - int grabdays = (is_grabber_datadirect(xmltv_grabber)) ? - 14 : REFRESH_MAX; + int grabdays = REFRESH_MAX; grabdays = (m_maxDays > 0) ? m_maxDays : grabdays; grabdays = (m_only_update_channels) ? 1 : grabdays; @@ -707,12 +432,6 @@ bool FillData::Run(SourceList &sourcelist) for (int i = 0; i < grabdays; i++) refresh_request[i] = m_refresh_day[i]; - if (is_grabber_datadirect(xmltv_grabber) && m_only_update_channels) - { - DataDirectUpdateChannels(*it); - grabdays = 0; - } - for (int i = 0; i < grabdays; i++) { if (!m_fatalErrors.empty()) @@ -894,7 +613,7 @@ bool FillData::Run(SourceList &sourcelist) { LOG(VB_GENERAL, LOG_NOTICE, QString("Refreshing data for ") + currDate); - if (!GrabData(*it, i, &qCurrentDate)) + if (!GrabData(*it, i)) { ++failures; if (!m_fatalErrors.empty() || m_interrupted) diff --git a/mythtv/programs/mythfilldatabase/filldata.h b/mythtv/programs/mythfilldatabase/filldata.h index c1aa722c447..2df3f494772 100644 --- a/mythtv/programs/mythfilldatabase/filldata.h +++ b/mythtv/programs/mythfilldatabase/filldata.h @@ -9,7 +9,6 @@ using namespace std; #include // libmythtv headers -#include "datadirect.h" #include "programdata.h" // filldata headers @@ -50,14 +49,8 @@ class FillData void SetRefresh(int day, bool set); - void DataDirectStationUpdate(Source source); - bool DataDirectUpdateChannels(Source source); - bool GrabDDData(Source source, int poffset, - QDate pdate, int ddSource); bool GrabDataFromFile(int id, QString &filename); - bool GrabData(Source source, int offset, QDate *qCurrentDate = nullptr); - bool GrabDataFromDDFile(int id, int offset, const QString &filename, - const QString &lineupid, QDate *qCurrentDate = nullptr); + bool GrabData(Source source, int offset); bool Run(SourceList &sourcelist); enum @@ -70,7 +63,6 @@ class FillData ProgramData m_prog_data; ChannelData m_chan_data; XMLTVParser m_xmltv_parser; - DataDirectProcessor m_ddprocessor; QString m_logged_in; QString m_lastdduserid; diff --git a/mythtv/programs/mythfilldatabase/main.cpp b/mythtv/programs/mythfilldatabase/main.cpp index f0c77743d6c..fccb257754e 100644 --- a/mythtv/programs/mythfilldatabase/main.cpp +++ b/mythtv/programs/mythfilldatabase/main.cpp @@ -48,16 +48,11 @@ int main(int argc, char *argv[]) { FillData fill_data; int fromfile_id = 1; - int fromfile_offset = 0; QString fromfile_name; bool from_file = false; bool mark_repeats = true; - bool usingDataDirect = false; - - bool from_dd_file = false; int sourceid = -1; - QString fromddfile_lineupid; MythFillDatabaseCommandLineParser cmdline; if (!cmdline.Parse(argc, argv)) @@ -132,34 +127,8 @@ int main(int argc, char *argv[]) from_file = true; } - if (cmdline.toBool("ddfile")) - { - // datadirect file mode - if (!cmdline.toBool("sourceid") || - !cmdline.toBool("offset") || - !cmdline.toBool("lineupid") || - !cmdline.toBool("xmlfile")) - { - cerr << "The --dd-file option must be used in combination" << endl - << "with each of --sourceid, --offset, --lineupid," << endl - << "and --xmlfile." << endl; - return GENERIC_EXIT_INVALID_CMDLINE; - } - - fromfile_id = cmdline.toInt("sourceid"); - fromfile_offset = cmdline.toInt("offset"); - fromddfile_lineupid = cmdline.toString("lineupid"); - fromfile_name = cmdline.toString("xmlfile"); - - LOG(VB_GENERAL, LOG_INFO, - "Bypassing grabbers, reading directly from file"); - from_dd_file = true; - } - if (cmdline.toBool("dochannelupdates")) fill_data.m_chan_data.m_channelUpdates = true; - if (cmdline.toBool("removechannels")) - fill_data.m_chan_data.m_removeNewChannels = true; if (cmdline.toBool("nofilterchannels")) fill_data.m_chan_data.m_filterNewChannels = false; if (!cmdline.GetPassthrough().isEmpty()) @@ -266,11 +235,6 @@ int main(int argc, char *argv[]) if (cmdline.toBool("dontrefreshtba")) fill_data.m_refresh_tba = false; - if (cmdline.toBool("ddgraball")) - { - fill_data.SetRefresh(FillData::kRefreshClear, false); - fill_data.m_dd_grab_all = true; - } if (cmdline.toBool("onlychannels")) fill_data.m_only_update_channels = true; if (cmdline.toBool("noallatonce")) @@ -366,11 +330,6 @@ int main(int argc, char *argv[]) updateLastRunStatus(status); } - else if (from_dd_file) - { - fill_data.GrabDataFromDDFile( - fromfile_id, fromfile_offset, fromfile_name, fromddfile_lineupid); - } else { SourceList sourcelist; @@ -412,8 +371,6 @@ int main(int argc, char *argv[]) newsource.xmltvgrabber_prefmethod = ""; sourcelist.push_back(newsource); - usingDataDirect |= - is_grabber_datadirect(newsource.xmltvgrabber); } } else @@ -677,12 +634,6 @@ int main(int argc, char *argv[]) } } - if ((usingDataDirect) && - (gCoreContext->GetBoolSetting("MythFillGrabberSuggestsTime", true))) - { - fill_data.m_ddprocessor.GrabNextSuggestedTime(); - } - LOG(VB_GENERAL, LOG_INFO, "\n" "===============================================================\n" "| Attempting to contact the master backend for rescheduling. |\n" diff --git a/mythtv/programs/mythfrontend/customedit.cpp b/mythtv/programs/mythfrontend/customedit.cpp index e04e3d1f724..24625e3bc21 100644 --- a/mythtv/programs/mythfrontend/customedit.cpp +++ b/mythtv/programs/mythfrontend/customedit.cpp @@ -428,7 +428,7 @@ void CustomEdit::loadClauses() new MythUIButtonListItem(m_clauseList, rule.title, qVariantFromValue(rule)); - rule.title = tr("All matches for a genre (Data Direct)"); + rule.title = tr("All matches for a genre (Schedules Direct)"); rule.subtitle = "LEFT JOIN programgenres ON " "program.chanid = programgenres.chanid AND " "program.starttime = programgenres.starttime "; @@ -439,7 +439,7 @@ void CustomEdit::loadClauses() new MythUIButtonListItem(m_clauseList, rule.title, qVariantFromValue(rule)); - rule.title = tr("Limit by MPAA or VCHIP rating (Data Direct)"); + rule.title = tr("Limit by MPAA or VCHIP rating (Schedules Direct)"); rule.subtitle = "LEFT JOIN programrating ON " "program.chanid = programrating.chanid AND " "program.starttime = programrating.starttime "; @@ -468,7 +468,7 @@ void CustomEdit::loadClauses() new MythUIButtonListItem(m_clauseList, rule.title, qVariantFromValue(rule)); - rule.title = tr("Person named in the credits (Data Direct)"); + rule.title = tr("Person named in the credits (Schedules Direct)"); rule.subtitle = ", people, credits"; rule.description = "people.name = 'Tom Hanks' \n" "AND credits.person = people.person \n" @@ -535,7 +535,7 @@ void CustomEdit::loadClauses() new MythUIButtonListItem(m_clauseList, rule.title, qVariantFromValue(rule)); - rule.title = tr("First Episodes (complete example for Data Direct)"); + rule.title = tr("First Episodes (complete example for Schedules Direct)"); rule.subtitle.clear(); rule.description = "program.first > 0 \n" "AND program.programid LIKE 'EP%0001' \n" diff --git a/mythtv/programs/mythfrontend/statusbox.cpp b/mythtv/programs/mythfrontend/statusbox.cpp index 876534b6f76..9cba58b0efb 100644 --- a/mythtv/programs/mythfrontend/statusbox.cpp +++ b/mythtv/programs/mythfrontend/statusbox.cpp @@ -515,7 +515,7 @@ void StatusBox::doListingsStatus() QDateTime mfdLastRunStart, mfdLastRunEnd, mfdNextRunStart; QString mfdLastRunStatus; - QString querytext, DataDirectMessage; + QString querytext; int DaysOfData; QDateTime qdtNow, GuideDataThrough; @@ -535,7 +535,6 @@ void StatusBox::doListingsStatus() mfdNextRunStart = MythDate::fromString(tmp); mfdLastRunStatus = gCoreContext->GetSetting("mythfilldatabaseLastRunStatus"); - DataDirectMessage = gCoreContext->GetSetting("DataDirectMessage"); AddLogLine(tr("Mythfrontend version: %1 (%2)").arg(MYTH_SOURCE_PATH) .arg(MYTH_SOURCE_VERSION), helpmsg); @@ -590,13 +589,6 @@ void StatusBox::doListingsStatus() if (DaysOfData <= 3) AddLogLine(tr("WARNING: is mythfilldatabase running?"), helpmsg, "", "", "warning"); - - if (!DataDirectMessage.isEmpty()) - { - AddLogLine(tr("DataDirect Status: "), helpmsg); - AddLogLine(DataDirectMessage, helpmsg); - } - } void StatusBox::doScheduleStatus() diff --git a/mythtv/programs/mythtv-setup/backendsettings.cpp b/mythtv/programs/mythtv-setup/backendsettings.cpp index ef32f9579f5..b9c71acc5f0 100644 --- a/mythtv/programs/mythtv-setup/backendsettings.cpp +++ b/mythtv/programs/mythtv-setup/backendsettings.cpp @@ -826,7 +826,7 @@ static GlobalCheckBoxSetting *MythFillGrabberSuggestsTime() bc->setLabel(QObject::tr("Run guide data program at time suggested by the " "grabber.")); bc->setValue(true); - bc->setHelpText(QObject::tr("If enabled, allow a DataDirect guide data " + bc->setHelpText(QObject::tr("If enabled, allow a guide data " "provider to specify the next download time in order " "to distribute load on their servers. Guide data program " "execution start/end times are also ignored.")); diff --git a/mythtv/programs/mythtv-setup/checksetup.cpp b/mythtv/programs/mythtv-setup/checksetup.cpp index cf50479e132..0365eaec510 100644 --- a/mythtv/programs/mythtv-setup/checksetup.cpp +++ b/mythtv/programs/mythtv-setup/checksetup.cpp @@ -44,9 +44,6 @@ bool checkStoragePaths(QStringList &probs) { bool problemFound = false; - QString recordFilePrefix = - gCoreContext->GetSetting("RecordFilePrefix", "EMPTY"); - MSqlQuery query(MSqlQuery::InitCon()); query.prepare("SELECT count(groupname) FROM storagegroup;"); @@ -241,9 +238,7 @@ bool needsMFDBReminder() query.prepare("SELECT sourceid " "FROM videosource " - "WHERE xmltvgrabber = 'schedulesdirect1' " - "OR xmltvgrabber = 'datadirect' " - "OR xmltvgrabber LIKE 'tv_grab_%';"); + "WHERE xmltvgrabber LIKE 'tv_grab_%';"); if (!query.exec() || !query.isActive()) { MythDB::DBError("needsMFDBReminder", query); diff --git a/mythtv/programs/scripts/unittests.sh b/mythtv/programs/scripts/unittests.sh index 5615934f596..03da3c814de 100755 --- a/mythtv/programs/scripts/unittests.sh +++ b/mythtv/programs/scripts/unittests.sh @@ -21,7 +21,7 @@ do RUNNABLE=$FPATH/$EXEC if test -x $RUNNABLE -a -f $RUNNABLE ; then if ./$RUNNABLE ; then - if test -x $GCOV -a -f $FPATH/$COVGCNO ; then + if test -x "$GCOV" -a -f $FPATH/$COVGCNO ; then P=`pwd` ; cd $FPATH # pushd== LINES=`$GCOV $COV | $GREP Lines | $SED -e 's/Lines//'` echo Coverage: $COV $LINES. See $FPATH/$COV.gcov for details