Permalink
Browse files

Metadata Lookup: Look up extra metadata on recording start.

This adds the metadata lookup to the jobqueue in the same way that commflag and transcode are there.  By default, when a recording begins the first thing the jobqueue will do is look up the extra metadata.

As with the other mentioned jobs, metadata lookup for your recordings can be turned off on a per-rule or per-backend basis. (per-rule UI changes to come, remotefile needs to get fixed for me to be able to commit those).
  • Loading branch information...
1 parent 51f5e67 commit 89b6416b50cdb81a60a1d19dd0fe1b1453824e87 Robert McNamara committed Jul 3, 2011
View
137 mythtv/libs/libmythtv/jobqueue.cpp
@@ -593,13 +593,17 @@ bool JobQueue::QueueJobs(int jobTypes, uint chanid, const QDateTime &recstartts,
{
if (gCoreContext->GetNumSetting("AutoTranscodeBeforeAutoCommflag", 0))
{
+ if (jobTypes & JOB_METADATA)
+ QueueJob(JOB_METADATA, chanid, recstartts, args, comment, host);
if (jobTypes & JOB_TRANSCODE)
QueueJob(JOB_TRANSCODE, chanid, recstartts, args, comment, host);
if (jobTypes & JOB_COMMFLAG)
QueueJob(JOB_COMMFLAG, chanid, recstartts, args, comment, host);
}
else
{
+ if (jobTypes & JOB_METADATA)
+ QueueJob(JOB_METADATA, chanid, recstartts, args, comment, host);
if (jobTypes & JOB_COMMFLAG)
QueueJob(JOB_COMMFLAG, chanid, recstartts, args, comment, host);
if (jobTypes & JOB_TRANSCODE)
@@ -1081,6 +1085,7 @@ QString JobQueue::JobText(int jobType)
{
case JOB_TRANSCODE: return tr("Transcode");
case JOB_COMMFLAG: return tr("Flag Commercials");
+ case JOB_METADATA: return tr("Look up Metadata");
}
if (jobType & JOB_USERJOB)
@@ -1293,7 +1298,8 @@ int JobQueue::GetJobsInQueue(QMap<int, JobQueueEntry> &jobs, int findJobs)
if ((query.value(12).toDateTime() > QDateTime::currentDateTime()) &&
((!commflagWhileRecording) ||
- (thisJob.type != JOB_COMMFLAG)))
+ ((thisJob.type != JOB_COMMFLAG) &&
+ (thisJob.type != JOB_METADATA))))
{
VERBOSE(VB_JOBQUEUE, LOC +
QString("GetJobsInQueue: Ignoring '%1' Job "
@@ -1409,6 +1415,8 @@ bool JobQueue::AllowedToRun(JobQueueEntry job)
break;
case JOB_COMMFLAG: allowSetting = "JobAllowCommFlag";
break;
+ case JOB_METADATA: allowSetting = "JobAllowMetadata";
+ break;
default: return false;
}
}
@@ -1685,6 +1693,11 @@ void JobQueue::ProcessJob(JobQueueEntry job)
{
StartChildJob(FlagCommercialsThread, jobID);
}
+ else if ((job.type == JOB_METADATA) ||
+ (runningJobs[jobID].command == "mythmetadatalookup"))
+ {
+ StartChildJob(MetadataLookupThread, jobID);
+ }
else if (job.type & JOB_USERJOB)
{
StartChildJob(UserJobThread, jobID);
@@ -2059,6 +2072,128 @@ void JobQueue::DoTranscodeThread(int jobID)
RemoveRunningJob(jobID);
}
+void *JobQueue::MetadataLookupThread(void *param)
+{
+ JobThreadStruct *jts = (JobThreadStruct *)param;
+ JobQueue *jq = jts->jq;
+
+ threadRegister(QString("Metadata_%1").arg(jts->jobID));
+ jq->DoMetadataLookupThread(jts->jobID);
+ threadDeregister();
+
+ delete jts;
+
+ return NULL;
+}
+
+void JobQueue::DoMetadataLookupThread(int jobID)
+{
+ // We can't currently lookup non-recording files w/o a ProgramInfo
+ runningJobsLock->lock();
+ if (!runningJobs[jobID].pginfo)
+ {
+ VERBOSE(VB_JOBQUEUE, LOC_ERR +
+ "The JobQueue cannot currently perform lookups for items which do not "
+ "have a chanid/starttime in the recorded table.");
+ ChangeJobStatus(jobID, JOB_ERRORED, "ProgramInfo data not found");
+ RemoveRunningJob(jobID);
+ runningJobsLock->unlock();
+ return;
+ }
+
+ ProgramInfo *program_info = runningJobs[jobID].pginfo;
+ runningJobsLock->unlock();
+
+ QString detailstr = QString("%1 recorded from channel %3")
+ .arg(program_info->toString(ProgramInfo::kTitleSubtitle))
+ .arg(program_info->toString(ProgramInfo::kRecordingKey));
+ QByteArray details = detailstr.toLocal8Bit();
+
+ if (!MSqlQuery::testDBConnection())
+ {
+ QString msg = QString("Metadata Lookup failed. Could not open "
+ "new database connection for %1. "
+ "Program cannot be looked up.")
+ .arg(details.constData());
+ VERBOSE(VB_IMPORTANT, LOC_ERR + msg);
+
+ ChangeJobStatus(jobID, JOB_ERRORED,
+ "Could not open new database connection for "
+ "metadata lookup.");
+
+ delete program_info;
+ return;
+ }
+
+ QString msg = tr("Metadata Lookup Starting");
+ VERBOSE(VB_GENERAL, LOC + "Metadata Lookup Starting for " + detailstr);
+
+ uint retVal = 0;
+ QString path;
+ QString command;
+
+ path = GetInstallPrefix() + "/bin/mythmetadatalookup";
+ command = QString("%1 -j %2")
+ .arg(path).arg(jobID);
+ command += logPropagateArgs;
+
+ VERBOSE(VB_JOBQUEUE, LOC + QString("Running command: '%1'").arg(command));
+
+ retVal = myth_system(command);
+ int priority = LOG_NOTICE;
+ QString comment;
+
+ runningJobsLock->lock();
+
+ if ((retVal == GENERIC_EXIT_DAEMONIZING_ERROR) ||
+ (retVal == GENERIC_EXIT_CMD_NOT_FOUND))
+ {
+ comment = tr("Unable to find mythmetadatalookup");
+ ChangeJobStatus(jobID, JOB_ERRORED, comment);
+ priority = LOG_WARNING;
+ }
+ else if (runningJobs[jobID].flag == JOB_STOP)
+ {
+ comment = tr("Aborted by user");
+ ChangeJobStatus(jobID, JOB_ABORTED, comment);
+ priority = LOG_WARNING;
+ }
+ else if (retVal == GENERIC_EXIT_NO_RECORDING_DATA)
+ {
+ comment = tr("Unable to open file or init decoder");
+ ChangeJobStatus(jobID, JOB_ERRORED, comment);
+ priority = LOG_WARNING;
+ }
+ else if (retVal >= GENERIC_EXIT_NOT_OK) // 256 or above - error
+ {
+ comment = tr("Failed with exit status %1").arg(retVal);
+ ChangeJobStatus(jobID, JOB_ERRORED, comment);
+ priority = LOG_WARNING;
+ }
+ else
+ {
+ comment = tr("Metadata Lookup Complete.");
+ ChangeJobStatus(jobID, JOB_FINISHED, comment);
+
+ program_info->SendUpdateEvent();
+ }
+
+ msg = tr("Metadata Lookup %1", "Job ID")
+ .arg(StatusText(GetJobStatus(jobID)));
+
+ if (!comment.isEmpty())
+ {
+ detailstr += QString(" (%1)").arg(comment);
+ details = detailstr.toLocal8Bit();
+ }
+
+ if (priority <= LOG_WARNING)
+ VERBOSE(VB_IMPORTANT, LOC_ERR + msg + ": " + details.constData());
+
+ RemoveRunningJob(jobID);
+ runningJobsLock->unlock();
+}
+
void *JobQueue::FlagCommercialsThread(void *param)
{
JobThreadStruct *jts = (JobThreadStruct *)param;
View
4 mythtv/libs/libmythtv/jobqueue.h
@@ -75,6 +75,7 @@ enum JobTypes {
JOB_SYSTEMJOB = 0x00ff,
JOB_TRANSCODE = 0x0001,
JOB_COMMFLAG = 0x0002,
+ JOB_METADATA = 0x0004,
JOB_USERJOB = 0xff00,
JOB_USERJOB1 = 0x0100,
@@ -233,6 +234,9 @@ class MTV_PUBLIC JobQueue : public QObject
static void *TranscodeThread(void *param);
void DoTranscodeThread(int jobID);
+ static void *MetadataLookupThread(void *param);
+ void DoMetadataLookupThread(int jobID);
+
static void *FlagCommercialsThread(void *param);
void DoFlagCommercialsThread(int jobID);
View
3 mythtv/libs/libmythtv/recordinginfo.cpp
@@ -470,6 +470,8 @@ int RecordingInfo::GetAutoRunJobs(void) const
result |= JOB_TRANSCODE;
if (record->m_autoCommFlag)
result |= JOB_COMMFLAG;
+ if (record->m_autoMetadataLookup)
+ result |= JOB_METADATA;
if (record->m_autoUserJob1)
result |= JOB_USERJOB1;
if (record->m_autoUserJob2)
@@ -479,6 +481,7 @@ int RecordingInfo::GetAutoRunJobs(void) const
if (record->m_autoUserJob4)
result |= JOB_USERJOB4;
+
return result;
}
View
16 mythtv/libs/libmythtv/tv_rec.cpp
@@ -3833,6 +3833,22 @@ static int init_jobs(const RecordingInfo *rec, RecordingProfile &profile,
if ((!autoTrans) || (autoTrans->getValue().toInt() == 0))
JobQueue::RemoveJobsFromMask(JOB_TRANSCODE, jobs);
+ bool ml = JobQueue::JobIsInMask(JOB_METADATA, jobs);
+ if (ml)
+ {
+ // When allowed, metadata lookup should occur at the
+ // start of a recording to make the additional info
+ // available immediately (and for use in future jobs).
+ QString host = (on_host) ? gCoreContext->GetHostName() : "";
+ JobQueue::QueueJob(JOB_METADATA,
+ rec->GetChanID(),
+ rec->GetRecordingStartTime(), "", "",
+ host, JOB_LIVE_REC);
+
+ // don't do regular metadata lookup, we won't need it.
+ JobQueue::RemoveJobsFromMask(JOB_METADATA, jobs);
+ }
+
// is commercial flagging enabled, and is on-line comm flagging enabled?
bool rt = JobQueue::JobIsInMask(JOB_COMMFLAG, jobs) && on_line_comm;
// also, we either need transcoding to be disabled or
View
8 mythtv/programs/mythbackend/config_backend_general.xml
@@ -492,6 +492,14 @@
<option display="Medium" data="1" />
<option display="High" data="2" />
</setting>
+ <setting data_type="checkbox" value="JobAllowMetadata"
+ label="Allow metadata lookup jobs"
+ default_data="true"
+ setting_type="host"
+ help_text="If enabled, allow metadata lookup jobs to
+ run on this backend. Metadata lookup jobs
+ add information like season and episode to
+ completed recordings." />
<setting data_type="checkbox" value="JobAllowCommFlag"
label="Allow commercial-detection jobs"
default_data="true"
View
29 mythtv/programs/mythfrontend/playbackbox.cpp
@@ -2672,6 +2672,7 @@ void PlaybackBox::showPlaylistJobPopup(void)
ProgramInfo *tmpItem;
bool isTranscoding = true;
bool isFlagging = true;
+ bool isMetadataLookup = true;
bool isRunningUserJob1 = true;
bool isRunningUserJob2 = true;
bool isRunningUserJob3 = true;
@@ -2691,6 +2692,10 @@ void PlaybackBox::showPlaylistJobPopup(void)
tmpItem->GetChanID(), tmpItem->GetRecordingStartTime()))
isFlagging = false;
if (!JobQueue::IsJobQueuedOrRunning(
+ JOB_METADATA,
+ tmpItem->GetChanID(), tmpItem->GetRecordingStartTime()))
+ isMetadataLookup = false;
+ if (!JobQueue::IsJobQueuedOrRunning(
JOB_USERJOB1,
tmpItem->GetChanID(), tmpItem->GetRecordingStartTime()))
isRunningUserJob1 = false;
@@ -2724,6 +2729,13 @@ void PlaybackBox::showPlaylistJobPopup(void)
m_popupMenu->AddButton(tr("Stop Commercial Detection"),
SLOT(stopPlaylistFlagging()));
+ if (!isMetadataLookup)
+ m_popupMenu->AddButton(tr("Begin Metadata Lookup"),
+ SLOT(doPlaylistBeginLookup()));
+ else
+ m_popupMenu->AddButton(tr("Stop Metadata Lookup"),
+ SLOT(stopPlaylistLookup()));
+
command = gCoreContext->GetSetting("UserJob1", "");
if (!command.isEmpty())
{
@@ -2887,38 +2899,42 @@ void PlaybackBox::showJobPopup()
QString jobTitle;
QString command;
- bool add[6] =
+ bool add[7] =
{
true,
true,
+ true,
!gCoreContext->GetSetting("UserJob1", "").isEmpty(),
!gCoreContext->GetSetting("UserJob2", "").isEmpty(),
!gCoreContext->GetSetting("UserJob3", "").isEmpty(),
!gCoreContext->GetSetting("UserJob4", "").isEmpty(),
};
- int jobs[6] =
+ int jobs[7] =
{
JOB_TRANSCODE,
JOB_COMMFLAG,
+ JOB_METADATA,
JOB_USERJOB1,
JOB_USERJOB2,
JOB_USERJOB3,
JOB_USERJOB4,
};
- QString desc[12] =
+ QString desc[14] =
{
// stop start
tr("Stop Transcoding"), tr("Begin Transcoding"),
tr("Stop Commercial Detection"), tr("Begin Commercial Detection"),
+ tr("Stop Metadata Lookup"), tr("Begin Metadata Lookup"),
"1", "1",
"2", "2",
"3", "3",
"4", "4",
};
- const char *myslots[12] =
+ const char *myslots[14] =
{ // stop start
SLOT(doBeginTranscoding()), SLOT(showTranscodingProfiles()),
SLOT(doBeginFlagging()), SLOT(doBeginFlagging()),
+ SLOT(doBeginLookup()), SLOT(doBeginLookup()),
SLOT(doBeginUserJob1()), SLOT(doBeginUserJob1()),
SLOT(doBeginUserJob2()), SLOT(doBeginUserJob2()),
SLOT(doBeginUserJob3()), SLOT(doBeginUserJob3()),
@@ -3244,6 +3260,11 @@ void PlaybackBox::doBeginFlagging()
doJobQueueJob(JOB_COMMFLAG);
}
+void PlaybackBox::doBeginLookup()
+{
+ doJobQueueJob(JOB_METADATA);
+}
+
void PlaybackBox::doPlaylistJobQueueJob(int jobType, int jobFlags)
{
ProgramInfo *tmpItem;
View
3 mythtv/programs/mythfrontend/playbackbox.h
@@ -219,6 +219,7 @@ class PlaybackBox : public ScheduleCommon
void doPlaylistJobQueueJob(int jobType, int jobFlags = 0);
void stopPlaylistJobQueueJob(int jobType);
void doBeginFlagging();
+ void doBeginLookup();
void doBeginTranscoding() { doJobQueueJob(JOB_TRANSCODE,
JOB_USE_CUTLIST); }
void doBeginUserJob1() { doJobQueueJob(JOB_USERJOB1); }
@@ -230,6 +231,8 @@ class PlaybackBox : public ScheduleCommon
void stopPlaylistTranscoding() { stopPlaylistJobQueueJob(JOB_TRANSCODE);}
void doPlaylistBeginFlagging() { doPlaylistJobQueueJob(JOB_COMMFLAG); }
void stopPlaylistFlagging() { stopPlaylistJobQueueJob(JOB_COMMFLAG); }
+ void doPlaylistBeginLookup() { doPlaylistJobQueueJob(JOB_METADATA); }
+ void stopPlaylistLookup() { stopPlaylistJobQueueJob(JOB_METADATA); }
void doPlaylistBeginUserJob1() { doPlaylistJobQueueJob(JOB_USERJOB1); }
void stopPlaylistUserJob1() { stopPlaylistJobQueueJob(JOB_USERJOB1); }
void doPlaylistBeginUserJob2() { doPlaylistJobQueueJob(JOB_USERJOB2); }
View
22 mythtv/programs/mythmetadatalookup/main.cpp
@@ -15,13 +15,16 @@ using namespace std;
#include "mythdb.h"
#include "mythversion.h"
#include "util.h"
+#include "jobqueue.h"
#include "mythtranslation.h"
#include "mythconfig.h"
#include "mythcommandlineparser.h"
#include "mythlogging.h"
#include "lookup.h"
+bool inJobQueue = false;
+
class MPUBLIC MythMetadataLookupCommandLineParser : public MythCommandLineParser
{
public:
@@ -38,6 +41,7 @@ void MythMetadataLookupCommandLineParser::LoadArguments(void)
addHelp();
addVersion();
addRecording();
+ addJob();
addLogging();
add("--refresh-all", "refresh-all", false,
@@ -87,7 +91,9 @@ int main(int argc, char *argv[])
bool refreshall = cmdline.toBool("refresh-all");
bool usedchanid = cmdline.toBool("chanid");
bool usedstarttime = cmdline.toBool("starttime");
+ bool addjob = cmdline.toBool("jobid");
+ int jobid = cmdline.toInt("jobid");
uint chanid = cmdline.toUInt("chanid");
QDateTime starttime = cmdline.toDateTime("starttime");
@@ -98,12 +104,18 @@ int main(int argc, char *argv[])
return GENERIC_EXIT_INVALID_CMDLINE;
}
- if (!refreshall && !usedchanid && !usedstarttime)
+ if (!addjob && !refreshall && !usedchanid && !usedstarttime)
{
refreshall = true;
}
- if (!refreshall && !(usedchanid && usedstarttime))
+ if (addjob && (refreshall || usedchanid || usedstarttime))
+ {
+ VERBOSE(VB_IMPORTANT, "The jobqueue (-j) command cannot be use with other options.");
+ return GENERIC_EXIT_INVALID_CMDLINE;
+ }
+
+ if (!refreshall && !addjob && !(usedchanid && usedstarttime))
{
VERBOSE(VB_IMPORTANT, "--chanid and --starttime must be used together.");
return GENERIC_EXIT_INVALID_CMDLINE;
@@ -115,6 +127,12 @@ int main(int argc, char *argv[])
LookerUpper *lookup = new LookerUpper();
+ if (addjob)
+ {
+ int type = JOB_METADATA;
+ JobQueue::GetJobInfoFromID(jobid, type, chanid, starttime);
+ }
+
if (refreshall)
lookup->HandleAllRecordings();
else
View
11 mythtv/programs/mythtv-setup/backendsettings.cpp
@@ -626,6 +626,16 @@ static GlobalLineEdit *UserJobDesc(uint job_num)
return gc;
};
+static HostCheckBox *JobAllowMetadata()
+{
+ HostCheckBox *gc = new HostCheckBox("JobAllowMetadata");
+ gc->setLabel(QObject::tr("Allow metadata lookup jobs"));
+ gc->setValue(true);
+ gc->setHelpText(QObject::tr("If enabled, allow jobs of this type to "
+ "run on this backend."));
+ return gc;
+};
+
static HostCheckBox *JobAllowCommFlag()
{
HostCheckBox *gc = new HostCheckBox("JobAllowCommFlag");
@@ -945,6 +955,7 @@ BackendSettings::BackendSettings() {
group5a1->addChild(JobQueueWindowStart());
group5a1->addChild(JobQueueWindowEnd());
group5a1->addChild(JobQueueCPU());
+ group5a1->addChild(JobAllowMetadata());
group5a1->addChild(JobAllowCommFlag());
group5a1->addChild(JobAllowTranscode());
group5a->addChild(group5a1);

0 comments on commit 89b6416

Please sign in to comment.