diff --git a/mythtv/libs/libmythmetadata/metadatacommon.cpp b/mythtv/libs/libmythmetadata/metadatacommon.cpp
index d28d54e..14f1a9e 100644
|
a
|
b
|
MetadataLookup::MetadataLookup(
|
| 219 | 219 | m_artwork(artwork), |
| 220 | 220 | m_downloads(downloads) |
| 221 | 221 | { |
| | 222 | QString manRecSuffix = QString(" (%1)").arg(QObject::tr("Manual Record")); |
| | 223 | m_base_title = title; |
| | 224 | m_base_title.replace(manRecSuffix,""); |
| 222 | 225 | } |
| 223 | 226 | |
| 224 | 227 | // ProgramInfo-style constructor |
| … |
… |
MetadataLookup::MetadataLookup(
|
| 312 | 315 | m_popularity = 0; |
| 313 | 316 | m_budget = 0; |
| 314 | 317 | m_revenue = 0; |
| | 318 | QString manRecSuffix = QString(" (%1)").arg(QObject::tr("Manual Record")); |
| | 319 | m_base_title = title; |
| | 320 | m_base_title.replace(manRecSuffix,""); |
| 315 | 321 | } |
| 316 | 322 | |
| 317 | 323 | // XBMC NFO-style constructor |
| … |
… |
MetadataLookup::MetadataLookup(
|
| 388 | 394 | m_artwork(artwork), |
| 389 | 395 | m_downloads(downloads) |
| 390 | 396 | { |
| | 397 | QString manRecSuffix = QString(" (%1)").arg(QObject::tr("Manual Record")); |
| | 398 | m_base_title = title; |
| | 399 | m_base_title.replace(manRecSuffix,""); |
| 391 | 400 | } |
| 392 | 401 | |
| 393 | 402 | MetadataLookup::~MetadataLookup() |
diff --git a/mythtv/libs/libmythmetadata/metadatadownload.cpp b/mythtv/libs/libmythmetadata/metadatadownload.cpp
index bf5d4fb..b0f1687 100644
|
a
|
b
|
void MetadataDownload::run()
|
| 97 | 97 | lookup->GetType() == kMetadataRecording) |
| 98 | 98 | { |
| 99 | 99 | if (lookup->GetSubtype() == kProbableTelevision) |
| | 100 | { |
| 100 | 101 | list = handleTelevision(lookup); |
| | 102 | if (findExactMatchWithArtCount(list, lookup->GetBaseTitle()) == 0) |
| | 103 | { |
| | 104 | // There are no exact match prospects with artwork from TV search, |
| | 105 | // so add in movies, where we might find a better match. |
| | 106 | list.append(handleMovie(lookup)); |
| | 107 | } |
| | 108 | } |
| 101 | 109 | else if (lookup->GetSubtype() == kProbableMovie) |
| | 110 | { |
| 102 | 111 | list = handleMovie(lookup); |
| | 112 | if (findExactMatchWithArtCount(list, lookup->GetBaseTitle()) == 0) |
| | 113 | { |
| | 114 | // There are no exact match prospects with artwork from Movie search |
| | 115 | // so add in television, where we might find a better match. |
| | 116 | list.append(handleTelevision(lookup)); |
| | 117 | } |
| | 118 | } |
| 103 | 119 | else |
| 104 | 120 | { |
| 105 | 121 | // will try both movie and TV |
| … |
… |
void MetadataDownload::run()
|
| 199 | 215 | RunEpilog(); |
| 200 | 216 | } |
| 201 | 217 | |
| | 218 | unsigned int MetadataDownload::findExactMatchWithArtCount(MetadataLookupList list, |
| | 219 | const QString &originaltitle) const |
| | 220 | { |
| | 221 | unsigned int exactMatchesWithArt = 0; |
| | 222 | |
| | 223 | for (MetadataLookupList::const_iterator i = list.begin(); |
| | 224 | i != list.end(); ++i) |
| | 225 | { |
| | 226 | QString title = (*i)->GetTitle(); |
| | 227 | // Consider exact title matches (ignoring case) |
| | 228 | if ((QString::compare(title, originaltitle, Qt::CaseInsensitive) == 0)) |
| | 229 | { |
| | 230 | // In lookup by name, the television database tends to only include Banner artwork. |
| | 231 | // In lookup by name, the movie database tends to include only Fan and Cover artwork. |
| | 232 | if ((((*i)->GetArtwork(kArtworkFanart)).size() != 0) || |
| | 233 | (((*i)->GetArtwork(kArtworkCoverart)).size() != 0) || |
| | 234 | (((*i)->GetArtwork(kArtworkBanner)).size() != 0)) |
| | 235 | { |
| | 236 | exactMatchesWithArt++; |
| | 237 | } |
| | 238 | } |
| | 239 | } |
| | 240 | return exactMatchesWithArt; |
| | 241 | } |
| | 242 | |
| 202 | 243 | MetadataLookup* MetadataDownload::findBestMatch(MetadataLookupList list, |
| 203 | 244 | const QString &originaltitle) const |
| 204 | 245 | { |
| 205 | 246 | QStringList titles; |
| 206 | 247 | MetadataLookup *ret = NULL; |
| | 248 | QDate exactTitleDate; |
| 207 | 249 | |
| 208 | 250 | // Build a list of all the titles |
| 209 | 251 | int exactMatches = 0; |
| 210 | 252 | for (MetadataLookupList::const_iterator i = list.begin(); |
| 211 | 253 | i != list.end(); ++i) |
| 212 | 254 | { |
| 213 | | QString title = (*i)->GetBaseTitle(); |
| 214 | | if (title == originaltitle) |
| | 255 | QString title = (*i)->GetTitle(); |
| | 256 | LOG(VB_GENERAL, LOG_INFO, QString("Comparing metadata title '%1' [%2] to recording title '%3'") |
| | 257 | .arg(title) |
| | 258 | .arg((*i)->GetReleaseDate().toString()) |
| | 259 | .arg(originaltitle)); |
| | 260 | // Consider exact title matches (ignoring case), which have some artwork available. |
| | 261 | if ((QString::compare(title, originaltitle, Qt::CaseInsensitive) == 0) && |
| | 262 | ((((*i)->GetArtwork(kArtworkFanart)).size() != 0) || |
| | 263 | (((*i)->GetArtwork(kArtworkCoverart)).size() != 0) || |
| | 264 | (((*i)->GetArtwork(kArtworkBanner)).size() != 0))) |
| 215 | 265 | { |
| 216 | | ret = (*i); |
| | 266 | // We have an exact match on the title (ignoring case). After |
| | 267 | // the first exact match, prefer any more recently released one. |
| | 268 | if ((ret == NULL) || ((*i)->GetReleaseDate() > exactTitleDate)) |
| | 269 | { |
| | 270 | exactTitleDate = (*i)->GetReleaseDate(); |
| | 271 | ret = (*i); |
| | 272 | } |
| 217 | 273 | exactMatches++; |
| 218 | 274 | } |
| 219 | 275 | |
| … |
… |
MetadataLookup* MetadataDownload::findBestMatch(MetadataLookupList list,
|
| 226 | 282 | { |
| 227 | 283 | if (exactMatches == 1) |
| 228 | 284 | { |
| 229 | | LOG(VB_GENERAL, LOG_INFO, QString("Single Exact Title Match For %1") |
| | 285 | LOG(VB_GENERAL, LOG_INFO, QString("Single exact title match for '%1'") |
| 230 | 286 | .arg(originaltitle)); |
| 231 | | return ret; |
| 232 | 287 | } |
| 233 | 288 | else |
| 234 | 289 | { |
| 235 | | LOG(VB_GENERAL, LOG_ERR, |
| 236 | | QString("Multiple exact title matches found for %1. " |
| 237 | | "Need to match on other criteria.") |
| 238 | | .arg(originaltitle)); |
| 239 | | return NULL; |
| | 290 | LOG(VB_GENERAL, LOG_INFO, |
| | 291 | QString("Multiple exact title matches found for '%1'. " |
| | 292 | "Selecting most recent [%2]") |
| | 293 | .arg(originaltitle) |
| | 294 | .arg(exactTitleDate.toString())); |
| 240 | 295 | } |
| | 296 | return ret; |
| 241 | 297 | } |
| 242 | 298 | |
| 243 | 299 | // Apply Levenshtein distance algorithm to determine closest match |
| … |
… |
MetadataLookup* MetadataDownload::findBestMatch(MetadataLookupList list,
|
| 260 | 316 | MetadataLookupList::const_iterator i = list.begin(); |
| 261 | 317 | for (; i != list.end(); ++i) |
| 262 | 318 | { |
| 263 | | if ((*i)->GetBaseTitle() == bestTitle) |
| | 319 | if ((*i)->GetTitle() == bestTitle) |
| 264 | 320 | { |
| 265 | 321 | ret = (*i); |
| 266 | 322 | break; |
| … |
… |
MetadataLookupList MetadataDownload::handleMovie(MetadataLookup *lookup)
|
| 534 | 590 | list = grabber.Search(lookup->GetBaseTitle(), lookup); |
| 535 | 591 | } |
| 536 | 592 | |
| | 593 | // remove any list elements which are lacking artwork |
| | 594 | MetadataLookupList::const_iterator itr = list.begin(); |
| | 595 | while (itr != list.end()) |
| | 596 | { |
| | 597 | // In lookup by name, the movie database tends to include only Fan and Cover artwork. |
| | 598 | // However, this tendency may not be universal, so we'll look for any of the three |
| | 599 | // types of artwork. |
| | 600 | if ((((*itr)->GetArtwork(kArtworkFanart)).size() == 0) && |
| | 601 | (((*itr)->GetArtwork(kArtworkCoverart)).size() == 0) && |
| | 602 | (((*itr)->GetArtwork(kArtworkBanner)).size() == 0)) |
| | 603 | { |
| | 604 | LOG(VB_GENERAL, LOG_INFO, QString("Removing '%1' entry with no artwork") |
| | 605 | .arg((*itr)->GetTitle())); |
| | 606 | MetadataLookupList::const_iterator next_itr = itr; |
| | 607 | next_itr++; |
| | 608 | MetadataLookup *mdl = list.takeAt(itr - list.begin()); |
| | 609 | if (mdl != NULL) |
| | 610 | delete(mdl); |
| | 611 | itr = next_itr; |
| | 612 | } |
| | 613 | else |
| | 614 | ++itr; |
| | 615 | } |
| | 616 | |
| 537 | 617 | return list; |
| 538 | 618 | } |
| 539 | 619 | |
| … |
… |
MetadataLookupList MetadataDownload::handleTelevision(MetadataLookup *lookup)
|
| 650 | 730 | } |
| 651 | 731 | } |
| 652 | 732 | |
| | 733 | // remove any list elements which are lacking artwork |
| | 734 | MetadataLookupList::const_iterator itr = list.begin(); |
| | 735 | while (itr != list.end()) |
| | 736 | { |
| | 737 | // In lookup by name, the television database tends to include only Banner artwork. |
| | 738 | // However, this tendency may not be universal, so we'll look for any of the three |
| | 739 | // types of artwork. |
| | 740 | if ((((*itr)->GetArtwork(kArtworkFanart)).size() == 0) && |
| | 741 | (((*itr)->GetArtwork(kArtworkCoverart)).size() == 0) && |
| | 742 | (((*itr)->GetArtwork(kArtworkBanner)).size() == 0)) |
| | 743 | { |
| | 744 | LOG(VB_GENERAL, LOG_INFO, QString("Removing '%1' entry with no artwork") |
| | 745 | .arg((*itr)->GetTitle())); |
| | 746 | MetadataLookupList::const_iterator next_itr = itr; |
| | 747 | next_itr++; |
| | 748 | MetadataLookup *mdl = list.takeAt(itr - list.begin()); |
| | 749 | if (mdl != NULL) |
| | 750 | delete(mdl); |
| | 751 | itr = next_itr; |
| | 752 | } |
| | 753 | else |
| | 754 | ++itr; |
| | 755 | } |
| | 756 | |
| 653 | 757 | return list; |
| 654 | 758 | } |
| 655 | 759 | |
diff --git a/mythtv/libs/libmythmetadata/metadatadownload.h b/mythtv/libs/libmythmetadata/metadatadownload.h
index bc1030b..b585233 100644
|
a
|
b
|
class META_PUBLIC MetadataDownload : public MThread
|
| 67 | 67 | |
| 68 | 68 | MetadataLookupList handleGame(MetadataLookup* lookup); |
| 69 | 69 | |
| | 70 | unsigned int findExactMatchWithArtCount(MetadataLookupList list, |
| | 71 | const QString &originaltitle) const; |
| 70 | 72 | MetadataLookup* findBestMatch(MetadataLookupList list, |
| 71 | 73 | const QString &originaltitle) const; |
| 72 | 74 | MetadataLookupList runGrabber(QString cmd, QStringList args, |
diff --git a/mythtv/programs/mythmetadatalookup/lookup.cpp b/mythtv/programs/mythmetadatalookup/lookup.cpp
index 6de23a1..eb3c2ab 100644
|
a
|
b
|
void LookerUpper::customEvent(QEvent *levent)
|
| 246 | 246 | if (list.count() > 1) |
| 247 | 247 | { |
| 248 | 248 | int yearindex = -1; |
| | 249 | MetadataLookup *exactTitleMeta = NULL; |
| | 250 | QDate exactTitleDate; |
| 249 | 251 | |
| 250 | 252 | for (int p = 0; p != list.size(); ++p) |
| 251 | 253 | { |
| 252 | 254 | ProgramInfo *pginfo = list[p]->GetData().value<ProgramInfo *>(); |
| 253 | 255 | |
| | 256 | if (pginfo && (QString::compare(pginfo->GetTitle(), list[p]->GetBaseTitle(), Qt::CaseInsensitive)) == 0) |
| | 257 | { |
| | 258 | // We have an exact match on the title (ignoring case) |
| | 259 | if ((exactTitleMeta == NULL) || |
| | 260 | (list[p]->GetReleaseDate() > exactTitleDate)) |
| | 261 | { |
| | 262 | // remember the most recently released exact match |
| | 263 | exactTitleDate = list[p]->GetReleaseDate(); |
| | 264 | exactTitleMeta = list[p]; |
| | 265 | } |
| | 266 | } |
| | 267 | |
| 254 | 268 | if (pginfo && !pginfo->GetSeriesID().isEmpty() && |
| 255 | 269 | pginfo->GetSeriesID() == (list[p])->GetTMSref()) |
| 256 | 270 | { |
| … |
… |
void LookerUpper::customEvent(QEvent *levent)
|
| 291 | 305 | return; |
| 292 | 306 | } |
| 293 | 307 | |
| | 308 | if (exactTitleMeta != NULL) |
| | 309 | { |
| | 310 | LOG(VB_GENERAL, LOG_INFO, QString("Most recent exact match released %1").arg(exactTitleDate.toString())); |
| | 311 | MetadataLookup *lookup = exactTitleMeta; |
| | 312 | ProgramInfo *pginfo = exactTitleMeta->GetData().value<ProgramInfo *>(); |
| | 313 | if (lookup->GetSubtype() != kProbableGenericTelevision) |
| | 314 | pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); |
| | 315 | pginfo->SaveInetRef(lookup->GetInetref()); |
| | 316 | m_busyRecList.removeAll(pginfo); |
| | 317 | return; |
| | 318 | } |
| | 319 | |
| 294 | 320 | LOG(VB_GENERAL, LOG_INFO, "Unable to match this title, too many possible matches. " |
| 295 | 321 | "You may wish to manually set the season, episode, and " |
| 296 | 322 | "inetref in the 'Watch Recordings' screen."); |