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."); |