diff --git a/mythtv/programs/mythmetadatalookup/.gitignore b/mythtv/programs/mythmetadatalookup/.gitignore new file mode 100644 index 00000000000..9e8a4045e92 --- /dev/null +++ b/mythtv/programs/mythmetadatalookup/.gitignore @@ -0,0 +1 @@ +mythfillnetvision diff --git a/mythtv/programs/mythmetadatalookup/lookup.cpp b/mythtv/programs/mythmetadatalookup/lookup.cpp new file mode 100644 index 00000000000..37cc9c5730d --- /dev/null +++ b/mythtv/programs/mythmetadatalookup/lookup.cpp @@ -0,0 +1,136 @@ +#include + +#include + +#include "programinfo.h" +#include "mythlogging.h" +#include "jobqueue.h" + +#include "lookup.h" + +LookerUpper::LookerUpper() : + m_busyRecList(QList()) +{ + m_metadataFactory = new MetadataFactory(this); +} + +LookerUpper::~LookerUpper() +{ +} + +bool LookerUpper::StillWorking() +{ + if (m_metadataFactory->IsRunning() || + m_busyRecList.count()) + { + return true; + } + + return false; +} + +void LookerUpper::HandleSingleRecording(const uint chanid, + const QDateTime starttime) +{ + ProgramInfo *pginfo = new ProgramInfo(chanid, starttime); + + if (!pginfo) + { + VERBOSE(VB_IMPORTANT, "No valid program info for supplied chanid/starttime"); + return; + } + + m_busyRecList.append(pginfo); + m_metadataFactory->Lookup(pginfo, false, false); +} + +void LookerUpper::HandleAllRecordings() +{ + QMap< QString, ProgramInfo* > recMap; + QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap(); + QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG); + + ProgramList progList; + + LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 ); + + for( int n = 0; n < (int)progList.size(); n++) + { + ProgramInfo *pginfo = new ProgramInfo(*(progList[n])); + if (pginfo->GetInetRef().isEmpty() || + (!pginfo->GetSubtitle().isEmpty() && + (pginfo->GetSeason() == 0) && + (pginfo->GetEpisode() == 0))) + { + QString msg = QString("Looking up: %1 %2").arg(pginfo->GetTitle()) + .arg(pginfo->GetSubtitle()); + VERBOSE(VB_IMPORTANT, msg); + + m_busyRecList.append(pginfo); + m_metadataFactory->Lookup(pginfo, false, false); + } + } +} + +void LookerUpper::customEvent(QEvent *levent) +{ + if (levent->type() == MetadataFactoryMultiResult::kEventType) + { + VERBOSE(VB_IMPORTANT, "Got a multiresult."); + // We shouldn't get any of these. If we do, metadataFactory->Lookup + // was called with the wrong arguments. + } + else if (levent->type() == MetadataFactorySingleResult::kEventType) + { + MetadataFactorySingleResult *mfsr = dynamic_cast(levent); + + if (!mfsr) + return; + + MetadataLookup *lookup = mfsr->result; + + if (!lookup) + return; + + ProgramInfo *pginfo = qVariantValue(lookup->GetData()); + + // This null check could hang us as this pginfo would then never be removed + if (!pginfo) + return; + + VERBOSE(VB_GENERAL|VB_EXTRA, QString("I found the following data:")); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Input Title: %1").arg(pginfo->GetTitle())); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Input Sub: %1").arg(pginfo->GetSubtitle())); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Title: %1").arg(lookup->GetTitle())); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Subtitle: %1").arg(lookup->GetSubtitle())); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Season: %1").arg(lookup->GetSeason())); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Episode: %1").arg(lookup->GetEpisode())); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" Inetref: %1").arg(lookup->GetInetref())); + VERBOSE(VB_GENERAL|VB_EXTRA, QString(" User Rating: %1").arg(lookup->GetUserRating())); + + pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); + pginfo->SaveInetRef(lookup->GetInetref()); + + m_busyRecList.removeAll(pginfo); + } + else if (levent->type() == MetadataFactoryNoResult::kEventType) + { + MetadataFactoryNoResult *mfnr = dynamic_cast(levent); + + if (!mfnr) + return; + + MetadataLookup *lookup = mfnr->result; + + if (!lookup) + return; + + ProgramInfo *pginfo = qVariantValue(lookup->GetData()); + + // This null check could hang us as this pginfo would then never be removed + if (!pginfo) + return; + + m_busyRecList.removeAll(pginfo); + } +} diff --git a/mythtv/programs/mythmetadatalookup/lookup.h b/mythtv/programs/mythmetadatalookup/lookup.h new file mode 100644 index 00000000000..3687a67654b --- /dev/null +++ b/mythtv/programs/mythmetadatalookup/lookup.h @@ -0,0 +1,30 @@ +#ifndef LOOKUP_H_ +#define LOOKUP_H_ + +#include +#include + +#include "programinfo.h" +#include "metadatafactory.h" + +class LookerUpper : public QObject +{ + public: + LookerUpper(); + ~LookerUpper(); + + bool StillWorking(); + + void HandleSingleRecording(const uint chanid, + const QDateTime starttime); + void HandleAllRecordings(); + + private: + void customEvent(QEvent *event); + + MetadataFactory *m_metadataFactory; + + QList m_busyRecList; +}; + +#endif //LOOKUP_H_ diff --git a/mythtv/programs/mythmetadatalookup/main.cpp b/mythtv/programs/mythmetadatalookup/main.cpp new file mode 100644 index 00000000000..c7d2f3c40a5 --- /dev/null +++ b/mythtv/programs/mythmetadatalookup/main.cpp @@ -0,0 +1,137 @@ +// C headers +#include + +// C++ headers +#include +using namespace std; + +// Qt headers +#include +#include + +// libmyth headers +#include "exitcodes.h" +#include "mythcontext.h" +#include "mythdb.h" +#include "mythversion.h" +#include "util.h" +#include "mythtranslation.h" +#include "mythconfig.h" +#include "mythcommandlineparser.h" +#include "mythlogging.h" + +#include "lookup.h" + +class MPUBLIC MythMetadataLookupCommandLineParser : public MythCommandLineParser +{ + public: + MythMetadataLookupCommandLineParser(); + void LoadArguments(void); +}; + +MythMetadataLookupCommandLineParser::MythMetadataLookupCommandLineParser() : + MythCommandLineParser("mythmetadatalookup") +{ LoadArguments(); } + +void MythMetadataLookupCommandLineParser::LoadArguments(void) +{ + addHelp(); + addVersion(); + addVerbose(); + addRecording(); + addLogging(); + + add("--refresh-all", "refresh-all", false, + "Refresh all recorded programs and recording rules metadata", ""); +} + +int main(int argc, char *argv[]) +{ + MythMetadataLookupCommandLineParser cmdline; + if (!cmdline.Parse(argc, argv)) + { + cmdline.PrintHelp(); + return GENERIC_EXIT_INVALID_CMDLINE; + } + + if (cmdline.toBool("showhelp")) + { + cmdline.PrintHelp(); + return GENERIC_EXIT_OK; + } + + if (cmdline.toBool("showversion")) + { + cmdline.PrintVersion(); + return GENERIC_EXIT_OK; + } + + QCoreApplication a(argc, argv); + QCoreApplication::setApplicationName("mythmetadatalookup"); + + int retval; + if ((retval = cmdline.ConfigureLogging()) != GENERIC_EXIT_OK) + return retval; + + /////////////////////////////////////////////////////////////////////// + // Don't listen to console input + close(0); + + gContext = new MythContext(MYTH_BINARY_VERSION); + if (!gContext->Init(false)) + { + VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); + delete gContext; + return GENERIC_EXIT_NO_MYTHCONTEXT; + } + + bool refreshall = cmdline.toBool("refresh-all"); + bool usedchanid = cmdline.toBool("chanid"); + bool usedstarttime = cmdline.toBool("starttime"); + + uint chanid = cmdline.toUInt("chanid"); + QString startstring = cmdline.toString("starttime"); + QDateTime starttime = myth_dt_from_string(startstring); + + if (refreshall && (usedchanid || usedstarttime)) + { + VERBOSE(VB_IMPORTANT, "--refresh-all must not be accompanied by " + "--chanid or --starttime"); + return GENERIC_EXIT_INVALID_CMDLINE; + } + + if (!refreshall && !(usedchanid && usedstarttime)) + { + VERBOSE(VB_IMPORTANT, "--chanid and --starttime must be used together."); + return GENERIC_EXIT_INVALID_CMDLINE; + } + + if (!refreshall && !usedchanid && !usedstarttime) + { + refreshall = true; + } + + myth_nice(19); + + MythTranslation::load("mythfrontend"); + + LookerUpper *lookup = new LookerUpper(); + + if (refreshall) + lookup->HandleAllRecordings(); + else + lookup->HandleSingleRecording(chanid, starttime); + + while (lookup->StillWorking()) + { + sleep(1); + qApp->processEvents(); + } + + delete lookup; + delete gContext; + + VERBOSE(VB_IMPORTANT, "MythMetadataLookup run complete."); + + return GENERIC_EXIT_OK; +} diff --git a/mythtv/programs/mythmetadatalookup/mythmetadatalookup.pro b/mythtv/programs/mythmetadatalookup/mythmetadatalookup.pro new file mode 100644 index 00000000000..90f01a0e49a --- /dev/null +++ b/mythtv/programs/mythmetadatalookup/mythmetadatalookup.pro @@ -0,0 +1,19 @@ +include ( ../../settings.pro ) +include ( ../../version.pro ) +include ( ../programs-libs.pro ) + +QT += network xml sql + +TEMPLATE = app +CONFIG += thread +CONFIG -= moc +TARGET = mythmetadatalookup +target.path = $${PREFIX}/bin +INSTALLS = target + +QMAKE_CLEAN += $(TARGET) + +# Input +HEADERS += lookup.h +SOURCES += main.cpp lookup.cpp + diff --git a/mythtv/programs/programs.pro b/mythtv/programs/programs.pro index 16df7c21dbd..05fd633a85d 100644 --- a/mythtv/programs/programs.pro +++ b/mythtv/programs/programs.pro @@ -13,6 +13,7 @@ using_frontend { using_backend { SUBDIRS += mythbackend mythfilldatabase mythtv-setup scripts + SUBDIRS += mythmetadatalookup } using_mythtranscode: SUBDIRS += mythtranscode