Skip to content

Commit

Permalink
Metadata Lookup: Many, many bugfixes and improvements.
Browse files Browse the repository at this point in the history
Move all the logic that was all over the place to try to determine if a programinfo/recrule was a movie, television show, or other, and centralize it.

There are now two simple functions that can be run on these classes to guess, fairly accurately, which are Television, and which are Movies.

This method uses the presence of subtitle, season, episode, inetref, category_type, as well as the same information for the associated recording's rule to decide which grabber is most likely the correct one to run first.  We still fall back to the other grabber when we get no result, but this should markedly improve accuracy.  the lookup code can now fairly accurately decide when a recording is generic (moreso when that recording's rule has been properly set up with inetref, season, and episode data-- remember, when you set season and episode on a recording rule, even if it's not accurate for the specific recording that the rule is built on, it becomes an indicator to further recordings that they should be looked up as Television.  Set up your rules!)

I've tested and retested the video edit metadata and automatic grab functionality, as well as the schedule editor and the various permutations of mythmetadatalookup, and not found any regressions-- in fact, I've fixed a number of issues with all of them as part of this fix.

Adds a new "subtype" to metadata lookups-- while the MetadataType indicator starts us down the right path, the LookupType subtype helps us to fine tune which grabbers to take, in which orders, once we're there.  The good news is that even if this guessing logic were to totally fail, it would still probably produce the right result because of the grabber fallthrough logic.

Generic recordings which are determined to be such masquerade as Season 1, Episode 1 for purposes of assigning inetref and artwork.
  • Loading branch information
Robert McNamara committed Jul 13, 2011
1 parent fd1d6ea commit 6379242
Show file tree
Hide file tree
Showing 11 changed files with 213 additions and 123 deletions.
2 changes: 1 addition & 1 deletion mythtv/libs/libmythbase/mythversion.h
Expand Up @@ -12,7 +12,7 @@
/// Update this whenever the plug-in API changes.
/// Including changes in the libmythbase, libmyth, libmythtv, libmythav* and
/// libmythui class methods used by plug-ins.
#define MYTH_BINARY_VERSION "0.25.20110713-2"
#define MYTH_BINARY_VERSION "0.25.20110713-3"

/** \brief Increment this whenever the MythTV network protocol changes.
*
Expand Down
25 changes: 17 additions & 8 deletions mythtv/libs/libmythmetadata/metadatacommon.cpp
Expand Up @@ -8,6 +8,7 @@
// null constructor
MetadataLookup::MetadataLookup(void) :
m_type(VID),
m_subtype(kUnknownVideo),
m_data(),
m_step(SEARCH),
m_automatic(false),
Expand Down Expand Up @@ -71,6 +72,7 @@ MetadataLookup::MetadataLookup(void) :
// full constructor
MetadataLookup::MetadataLookup(
MetadataType type,
LookupType subtype,
QVariant data,
LookupStep step,
bool automatic,
Expand Down Expand Up @@ -130,6 +132,7 @@ MetadataLookup::MetadataLookup(
DownloadMap downloads) :

m_type(type),
m_subtype(subtype),
m_data(data),
m_step(step),
m_automatic(automatic),
Expand Down Expand Up @@ -193,6 +196,7 @@ MetadataLookup::MetadataLookup(
// ProgramInfo-style constructor
MetadataLookup::MetadataLookup(
MetadataType type,
LookupType subtype,
QVariant data,
LookupStep step,
bool automatic,
Expand Down Expand Up @@ -231,6 +235,7 @@ MetadataLookup::MetadataLookup(
const uint runtimesecs) :

m_type(type),
m_subtype(subtype),
m_data(data),
m_step(step),
m_automatic(automatic),
Expand Down Expand Up @@ -273,6 +278,7 @@ MetadataLookup::MetadataLookup(
// XBMC NFO-style constructor
MetadataLookup::MetadataLookup(
MetadataType type,
LookupType subtype,
QVariant data,
LookupStep step,
bool automatic,
Expand Down Expand Up @@ -301,6 +307,7 @@ MetadataLookup::MetadataLookup(
DownloadMap downloads) :

m_type(type),
m_subtype(subtype),
m_data(data),
m_step(step),
m_automatic(automatic),
Expand Down Expand Up @@ -599,12 +606,13 @@ MetadataLookup* ParseMetadataItem(const QDomElement& item,
.arg(season).arg(episode));
}

return new MetadataLookup(lookup->GetType(), lookup->GetData(),
lookup->GetStep(), lookup->GetAutomatic(), lookup->GetHandleImages(),
lookup->GetAllowOverwrites(), lookup->GetPreferDVDOrdering(),
lookup->GetHost(), lookup->GetFilename(), title, categories,
userrating, language, subtitle, tagline, description,
season, episode, chanid, channum, chansign, channame,
return new MetadataLookup(lookup->GetType(), lookup->GetSubtype(),
lookup->GetData(), lookup->GetStep(), lookup->GetAutomatic(),
lookup->GetHandleImages(), lookup->GetAllowOverwrites(),
lookup->GetPreferDVDOrdering(), lookup->GetHost(),
lookup->GetFilename(), title, categories, userrating,
language, subtitle, tagline, description, season,
episode, chanid, channum, chansign, channame,
chanplaybackfilters, recgroup, playgroup, seriesid, programid,
storagegroup, startts, endts, recstartts, recendts, programflags,
audioproperties, videoproperties, subtitletype, certification,
Expand Down Expand Up @@ -679,8 +687,9 @@ MetadataLookup* ParseMetadataMovieNFO(const QDomElement& item,
people.insert(DIRECTOR, info);
}

return new MetadataLookup(lookup->GetType(), lookup->GetData(),
lookup->GetStep(), lookup->GetAutomatic(), lookup->GetHandleImages(),
return new MetadataLookup(lookup->GetType(), lookup->GetSubtype(),
lookup->GetData(), lookup->GetStep(),
lookup->GetAutomatic(), lookup->GetHandleImages(),
lookup->GetAllowOverwrites(), lookup->GetPreferDVDOrdering(),
lookup->GetHost(), lookup->GetFilename(), title, categories,
userrating, subtitle, tagline, description, season, episode,
Expand Down
16 changes: 16 additions & 0 deletions mythtv/libs/libmythmetadata/metadatacommon.h
Expand Up @@ -55,6 +55,15 @@ enum MetadataType {
GAME = 3
};

enum LookupType {
kProbableTelevision = 0,
kProbableGenericTelevision = 1,
kProbableMovie = 2,
kUnknownVideo = 3,
kProbableMusic = 4,
kProbableGame = 5
};

enum PeopleType {
ACTOR = 0,
AUTHOR = 1,
Expand Down Expand Up @@ -88,6 +97,7 @@ class META_PUBLIC MetadataLookup : public QObject

MetadataLookup(
MetadataType type,
LookupType subtype,
QVariant data,
LookupStep step,
bool automatic,
Expand Down Expand Up @@ -149,6 +159,7 @@ class META_PUBLIC MetadataLookup : public QObject
//ProgramInfo Constructor
MetadataLookup(
MetadataType type,
LookupType subtype,
QVariant data,
LookupStep step,
bool automatic,
Expand Down Expand Up @@ -189,6 +200,7 @@ class META_PUBLIC MetadataLookup : public QObject
// XBMC NFO Constructor
MetadataLookup(
MetadataType type,
LookupType subtype,
QVariant data,
LookupStep step,
bool automatic,
Expand Down Expand Up @@ -222,6 +234,8 @@ class META_PUBLIC MetadataLookup : public QObject

// Must set a type, data, and step.
void SetType(MetadataType type) { m_type = type; };
// For some lookup, it helps to know the subtype (TV vs. Movie)
void SetSubtype(LookupType subtype) { m_subtype = subtype; };
// Reference value- when the event comes back, need to associate with an item.
void SetData(QVariant data) { m_data = data; };
// Steps: SEARCH, GETDATA
Expand Down Expand Up @@ -258,6 +272,7 @@ class META_PUBLIC MetadataLookup : public QObject
// GETS

MetadataType GetType() const { return m_type; };
LookupType GetSubtype() const { return m_subtype; };
QVariant GetData() const { return m_data; };
LookupStep GetStep() const { return m_step; };
bool GetAutomatic() const { return m_automatic; };
Expand Down Expand Up @@ -340,6 +355,7 @@ class META_PUBLIC MetadataLookup : public QObject
private:
// General
MetadataType m_type;
LookupType m_subtype;
QVariant m_data;
LookupStep m_step;
bool m_automatic;
Expand Down
149 changes: 54 additions & 95 deletions mythtv/libs/libmythmetadata/metadatadownload.cpp
Expand Up @@ -68,20 +68,42 @@ void MetadataDownload::run()
{
MetadataLookupList list;
// Go go gadget Metadata Lookup
if (lookup->GetType() == VID || lookup->GetType() == RECDNG)
if (lookup->GetType() == VID)
{
if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)
if (lookup->GetSubtype() == kProbableTelevision)
list = handleTelevision(lookup);
else if (!lookup->GetSubtitle().isEmpty() &&
lookup->GetType() == VID)
list = handleVideoUndetermined(lookup);
else if (lookup->GetType() == RECDNG)
list = handleRecordingUndetermined(lookup);
else if (lookup->GetSubtype() == kProbableMovie)
list = handleMovie(lookup);
else
list = handleVideoUndetermined(lookup);

if (!list.size() &&
lookup->GetSubtype() == kUnknownVideo)
{
list = handleMovie(lookup);
}
}
else if (lookup->GetType() == RECDNG)
{
if (lookup->GetSubtype() == kProbableTelevision)
{
if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)
list = handleTelevision(lookup);
else if (!lookup->GetSubtitle().isEmpty())
list = handleVideoUndetermined(lookup);
}
else if (lookup->GetSubtype() == kProbableMovie)
list = handleMovie(lookup);
else
list = handleRecordingGeneric(lookup);

if (!list.size() &&
(lookup->GetSubtype() == kProbableMovie ||
lookup->GetSubtype() == kProbableTelevision))
{
list = handleRecordingGeneric(lookup);
}
}
// else if (lookup->GetType() == MUSIC)
// list = handleMusic(lookup);
else if (lookup->GetType() == GAME)
list = handleGame(lookup);

Expand Down Expand Up @@ -173,16 +195,6 @@ bool MetadataDownload::findBestMatch(MetadataLookupList list,
MetadataLookup *newlookup = (*i);
newlookup->SetStep(GETDATA);

// If searching for TV without a subtitle, but we've found
// a series match, arbitrarily set season/episode to "1" to
// avoid looping forever trying to figure it out.

if (newlookup->GetType() == RECDNG)
{
newlookup->SetSeason(1);
newlookup->SetEpisode(1);
}

prependLookup(newlookup);
return true;
}
Expand Down Expand Up @@ -498,105 +510,52 @@ MetadataLookupList MetadataDownload::handleVideoUndetermined(
// Try to do a title/subtitle lookup
list = runGrabber(cmd, args, lookup, false);

// If there were no results for that, fall back to a movie lookup.
if (!list.size())
list = handleMovie(lookup);

if (list.count() == 1)
list.at(0)->SetStep(GETDATA);

return list;
}

MetadataLookupList MetadataDownload::handleRecordingUndetermined(
MetadataLookupList MetadataDownload::handleRecordingGeneric(
MetadataLookup* lookup)
{
// Ground rules: if we are here, we're operating on a recording.
// If this lookup is trying to handle images, the only place that can
// be in a --refresh-all-artwork run of mythmetadatalookup.

// Thus, TRUST the season and episode if there's an inetref + handleimages!
// We only enter this mode if we are pretty darn sure this is a TV show,
// but we're for some reason looking up a generic, or the title didn't
// exactly match in one of the earlier lookups. This is a total
// hail mary to try to get at least *series* level info and art/inetref.

MetadataLookupList list;

if ((lookup->GetHandleImages() && !lookup->GetInetref().isEmpty() &&
(lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)) ||
!lookup->GetHandleImages())
{
QString def_cmd = QDir::cleanPath(QString("%1/%2")
QString def_cmd = QDir::cleanPath(QString("%1/%2")
.arg(GetShareDir())
.arg("metadata/Television/ttvdb.py"));

QString cmd = gCoreContext->GetSetting("TelevisionGrabber", def_cmd);

QStringList args;
args.append(QString("-l")); // Language Flag
args.append(gCoreContext->GetLanguage()); // UI Language
if (!lookup->GetSubtitle().isEmpty())
args.append(QString("-N"));
else
{
// If the input lookup doesn't have Subtitle, Season or Episode,
// We're going to "artificially" set Seas/Ep to 1 since the input
// isn't enough information to get conclusive metadata anyway.
// This is needed in case of a multi-result, so that on the second
// pass through, we definitely get the TV grabber and at least get
// an inetref.
if (lookup->GetSeason() == 0 && lookup->GetEpisode() == 0)
{
lookup->SetSeason(1);
lookup->SetEpisode(1);
}
args.append(QString("-M"));
}

if (!lookup->GetInetref().isEmpty())
{
QString inetref = lookup->GetInetref();
args.append(inetref);
}
else
{
QString title = lookup->GetTitle();
args.append(title);
}
QString cmd = gCoreContext->GetSetting("TelevisionGrabber", def_cmd);

if (!lookup->GetSubtitle().isEmpty())
{
QString subtitle = lookup->GetSubtitle();
args.append(subtitle);
list = runGrabber(cmd, args, lookup, false);
QStringList args;

if (!list.size() && !lookup->GetHandleImages())
{
// Hail Mary lookup. Drop the subtitle.
// (Because really, this should be a TV show)
args.clear();
args.append(QString("-l")); // Language Flag
args.append(gCoreContext->GetLanguage()); // UI Language
args.append("-M");
QString title = lookup->GetTitle();
args.append(title);
lookup->SetSeason(1);
lookup->SetEpisode(1);
list = runGrabber(cmd, args, lookup, true);
}
}
else
list = runGrabber(cmd, args, lookup, true);
}
args.append(QString("-l")); // Language Flag
args.append(gCoreContext->GetLanguage()); // UI Language
args.append("-M");
QString title = lookup->GetTitle();
args.append(title);
int origseason = lookup->GetSeason();
int origepisode = lookup->GetEpisode();

// If there were no results for that, fall back to a movie lookup.
if (!list.size() && lookup->GetSubtitle().isEmpty())
if (origseason == 0 && origepisode == 0)
{
lookup->SetSeason(0);
lookup->SetEpisode(0);
list = handleMovie(lookup);
lookup->SetSeason(1);
lookup->SetEpisode(1);
}

list = runGrabber(cmd, args, lookup, true);

if (list.count() == 1)
list.at(0)->SetStep(GETDATA);

lookup->SetSeason(origseason);
lookup->SetEpisode(origepisode);

return list;
}

Expand Down
2 changes: 1 addition & 1 deletion mythtv/libs/libmythmetadata/metadatadownload.h
Expand Up @@ -56,7 +56,7 @@ class META_PUBLIC MetadataDownload : public QThread
MetadataLookupList handleMovie(MetadataLookup* lookup);
MetadataLookupList handleTelevision(MetadataLookup* lookup);
MetadataLookupList handleVideoUndetermined(MetadataLookup* lookup);
MetadataLookupList handleRecordingUndetermined(MetadataLookup* lookup);
MetadataLookupList handleRecordingGeneric(MetadataLookup* lookup);

MetadataLookupList handleGame(MetadataLookup* lookup);

Expand Down

0 comments on commit 6379242

Please sign in to comment.