|
MythTV
0.26-pre
|
00001 #include <vector> 00002 00003 #include <QList> 00004 00005 #include "programinfo.h" 00006 #include "recordingrule.h" 00007 #include "mythlogging.h" 00008 #include "jobqueue.h" 00009 #include "remoteutil.h" 00010 00011 #include "metadataimagehelper.h" 00012 00013 #include "lookup.h" 00014 00015 LookerUpper::LookerUpper() : 00016 m_busyRecList(QList<ProgramInfo*>()), 00017 m_updaterules(false), m_updateartwork(false) 00018 { 00019 m_metadataFactory = new MetadataFactory(this); 00020 } 00021 00022 LookerUpper::~LookerUpper() 00023 { 00024 while (!m_busyRecList.isEmpty()) 00025 delete m_busyRecList.takeFirst(); 00026 } 00027 00028 bool LookerUpper::StillWorking() 00029 { 00030 if (m_metadataFactory->IsRunning() || 00031 m_busyRecList.count()) 00032 { 00033 return true; 00034 } 00035 00036 return false; 00037 } 00038 00039 void LookerUpper::HandleSingleRecording(const uint chanid, 00040 const QDateTime starttime, 00041 bool updaterules) 00042 { 00043 ProgramInfo *pginfo = new ProgramInfo(chanid, starttime); 00044 00045 if (!pginfo) 00046 { 00047 LOG(VB_GENERAL, LOG_ERR, 00048 "No valid program info for supplied chanid/starttime"); 00049 return; 00050 } 00051 00052 m_updaterules = updaterules; 00053 00054 m_busyRecList.append(pginfo); 00055 m_metadataFactory->Lookup(pginfo, false, false, false); 00056 } 00057 00058 void LookerUpper::HandleAllRecordings(bool updaterules) 00059 { 00060 QMap< QString, ProgramInfo* > recMap; 00061 QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap(); 00062 QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG); 00063 00064 m_updaterules = updaterules; 00065 00066 ProgramList progList; 00067 00068 LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 ); 00069 00070 for( int n = 0; n < (int)progList.size(); n++) 00071 { 00072 ProgramInfo *pginfo = new ProgramInfo(*(progList[n])); 00073 if ((pginfo->GetRecordingGroup() != "Deleted") && 00074 (pginfo->GetRecordingGroup() != "LiveTV") && 00075 (pginfo->GetInetRef().isEmpty() || 00076 (!pginfo->GetSubtitle().isEmpty() && 00077 (pginfo->GetSeason() == 0) && 00078 (pginfo->GetEpisode() == 0)))) 00079 { 00080 QString msg = QString("Looking up: %1 %2").arg(pginfo->GetTitle()) 00081 .arg(pginfo->GetSubtitle()); 00082 LOG(VB_GENERAL, LOG_INFO, msg); 00083 00084 m_busyRecList.append(pginfo); 00085 m_metadataFactory->Lookup(pginfo, false, false, false); 00086 } 00087 else 00088 delete pginfo; 00089 } 00090 } 00091 00092 void LookerUpper::HandleAllRecordingRules() 00093 { 00094 m_updaterules = true; 00095 00096 vector<ProgramInfo *> recordingList; 00097 00098 RemoteGetAllScheduledRecordings(recordingList); 00099 00100 for( int n = 0; n < (int)recordingList.size(); n++) 00101 { 00102 ProgramInfo *pginfo = new ProgramInfo(*(recordingList[n])); 00103 if (pginfo->GetInetRef().isEmpty()) 00104 { 00105 QString msg = QString("Looking up: %1 %2").arg(pginfo->GetTitle()) 00106 .arg(pginfo->GetSubtitle()); 00107 LOG(VB_GENERAL, LOG_INFO, msg); 00108 00109 m_busyRecList.append(pginfo); 00110 m_metadataFactory->Lookup(pginfo, false, false, true); 00111 } 00112 else 00113 delete pginfo; 00114 } 00115 } 00116 00117 void LookerUpper::HandleAllArtwork(bool aggressive) 00118 { 00119 m_updateartwork = true; 00120 00121 if (aggressive) 00122 m_updaterules = true; 00123 00124 // First, handle all recording rules w/ inetrefs 00125 vector<ProgramInfo *> recordingList; 00126 00127 RemoteGetAllScheduledRecordings(recordingList); 00128 int maxartnum = 3; 00129 00130 for( int n = 0; n < (int)recordingList.size(); n++) 00131 { 00132 ProgramInfo *pginfo = new ProgramInfo(*(recordingList[n])); 00133 bool dolookup = true; 00134 00135 if (pginfo->GetInetRef().isEmpty()) 00136 dolookup = false; 00137 if (dolookup || aggressive) 00138 { 00139 ArtworkMap map = GetArtwork(pginfo->GetInetRef(), pginfo->GetSeason(), true); 00140 if (map.isEmpty() || (aggressive && map.count() < maxartnum)) 00141 { 00142 QString msg = QString("Looking up artwork for recording rule: %1 %2") 00143 .arg(pginfo->GetTitle()) 00144 .arg(pginfo->GetSubtitle()); 00145 LOG(VB_GENERAL, LOG_INFO, msg); 00146 00147 m_busyRecList.append(pginfo); 00148 m_metadataFactory->Lookup(pginfo, false, true, true); 00149 continue; 00150 } 00151 } 00152 delete pginfo; 00153 } 00154 00155 // Now, Attempt to fill in the gaps for recordings 00156 QMap< QString, ProgramInfo* > recMap; 00157 QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap(); 00158 QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG); 00159 00160 ProgramList progList; 00161 00162 LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 ); 00163 00164 for( int n = 0; n < (int)progList.size(); n++) 00165 { 00166 ProgramInfo *pginfo = new ProgramInfo(*(progList[n])); 00167 00168 bool dolookup = true; 00169 00170 LookupType type = GuessLookupType(pginfo); 00171 00172 if (type == kProbableMovie) 00173 maxartnum = 2; 00174 00175 if ((!aggressive && type == kProbableGenericTelevision) || 00176 pginfo->GetRecordingGroup() == "Deleted" || 00177 pginfo->GetRecordingGroup() == "LiveTV") 00178 dolookup = false; 00179 if (dolookup || aggressive) 00180 { 00181 ArtworkMap map = GetArtwork(pginfo->GetInetRef(), pginfo->GetSeason(), true); 00182 if (map.isEmpty() || (aggressive && map.count() < maxartnum)) 00183 { 00184 QString msg = QString("Looking up artwork for recording: %1 %2") 00185 .arg(pginfo->GetTitle()) 00186 .arg(pginfo->GetSubtitle()); 00187 LOG(VB_GENERAL, LOG_INFO, msg); 00188 00189 m_busyRecList.append(pginfo); 00190 m_metadataFactory->Lookup(pginfo, false, true, aggressive); 00191 continue; 00192 } 00193 } 00194 delete pginfo; 00195 } 00196 00197 } 00198 00199 void LookerUpper::CopyRuleInetrefsToRecordings() 00200 { 00201 QMap< QString, ProgramInfo* > recMap; 00202 QMap< QString, uint32_t > inUseMap = ProgramInfo::QueryInUseMap(); 00203 QMap< QString, bool > isJobRunning = ProgramInfo::QueryJobsRunning(JOB_COMMFLAG); 00204 00205 ProgramList progList; 00206 00207 LoadFromRecorded( progList, false, inUseMap, isJobRunning, recMap, -1 ); 00208 00209 for( int n = 0; n < (int)progList.size(); n++) 00210 { 00211 ProgramInfo *pginfo = new ProgramInfo(*(progList[n])); 00212 if (pginfo && pginfo->GetInetRef().isEmpty()) 00213 { 00214 RecordingRule *rule = new RecordingRule(); 00215 rule->m_recordID = pginfo->GetRecordingRuleID(); 00216 rule->Load(); 00217 if (!rule->m_inetref.isEmpty()) 00218 { 00219 QString msg = QString("%1").arg(pginfo->GetTitle()); 00220 if (!pginfo->GetSubtitle().isEmpty()) 00221 msg += QString(": %1").arg(pginfo->GetSubtitle()); 00222 msg += " has no inetref, but its recording rule does. Copying..."; 00223 LOG(VB_GENERAL, LOG_INFO, msg); 00224 pginfo->SaveInetRef(rule->m_inetref); 00225 } 00226 delete rule; 00227 } 00228 delete pginfo; 00229 } 00230 } 00231 00232 void LookerUpper::customEvent(QEvent *levent) 00233 { 00234 if (levent->type() == MetadataFactoryMultiResult::kEventType) 00235 { 00236 MetadataFactoryMultiResult *mfmr = dynamic_cast<MetadataFactoryMultiResult*>(levent); 00237 00238 if (!mfmr) 00239 return; 00240 00241 MetadataLookupList list = mfmr->results; 00242 00243 if (list.count() > 1) 00244 { 00245 int yearindex = -1; 00246 00247 for (int p = 0; p != list.size(); ++p) 00248 { 00249 ProgramInfo *pginfo = qVariantValue<ProgramInfo *>(list[p]->GetData()); 00250 00251 if (pginfo && !pginfo->GetSeriesID().isEmpty() && 00252 pginfo->GetSeriesID() == (list[p])->GetTMSref()) 00253 { 00254 MetadataLookup *lookup = list.takeAt(p); 00255 if (!lookup->GetSubtype() == kProbableGenericTelevision) 00256 pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); 00257 pginfo->SaveInetRef(lookup->GetInetref()); 00258 m_busyRecList.removeAll(pginfo); 00259 qDeleteAll(list); 00260 return; 00261 } 00262 else if (pginfo && pginfo->GetYearOfInitialRelease() != 0 && 00263 (list[p])->GetYear() != 0 && 00264 pginfo->GetYearOfInitialRelease() == (list[p])->GetYear()) 00265 { 00266 if (yearindex != -1) 00267 { 00268 LOG(VB_GENERAL, LOG_INFO, "Multiple results matched on year. No definite " 00269 "match could be found."); 00270 m_busyRecList.removeAll(pginfo); 00271 qDeleteAll(list); 00272 return; 00273 } 00274 else 00275 { 00276 LOG(VB_GENERAL, LOG_INFO, "Matched from multiple results based on year. "); 00277 yearindex = p; 00278 } 00279 } 00280 } 00281 00282 if (yearindex > -1) 00283 { 00284 MetadataLookup *lookup = list.takeAt(yearindex); 00285 ProgramInfo *pginfo = qVariantValue<ProgramInfo *>(lookup->GetData()); 00286 if (!lookup->GetSubtype() == kProbableGenericTelevision) 00287 pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); 00288 pginfo->SaveInetRef(lookup->GetInetref()); 00289 m_busyRecList.removeAll(pginfo); 00290 qDeleteAll(list); 00291 return; 00292 } 00293 00294 LOG(VB_GENERAL, LOG_INFO, "Unable to match this title, too many possible matches. " 00295 "You may wish to manually set the season, episode, and " 00296 "inetref in the 'Watch Recordings' screen."); 00297 00298 ProgramInfo *pginfo = qVariantValue<ProgramInfo *>(list.takeFirst()->GetData()); 00299 00300 qDeleteAll(list); 00301 00302 if (pginfo) 00303 { 00304 m_busyRecList.removeAll(pginfo); 00305 } 00306 } 00307 } 00308 else if (levent->type() == MetadataFactorySingleResult::kEventType) 00309 { 00310 MetadataFactorySingleResult *mfsr = 00311 dynamic_cast<MetadataFactorySingleResult*>(levent); 00312 00313 if (!mfsr) 00314 return; 00315 00316 MetadataLookup *lookup = mfsr->result; 00317 00318 if (!lookup) 00319 return; 00320 00321 ProgramInfo *pginfo = qVariantValue<ProgramInfo *>(lookup->GetData()); 00322 00323 // This null check could hang us as this pginfo would then never be 00324 // removed 00325 if (!pginfo) 00326 return; 00327 00328 LOG(VB_GENERAL, LOG_DEBUG, "I found the following data:"); 00329 LOG(VB_GENERAL, LOG_DEBUG, 00330 QString(" Input Title: %1").arg(pginfo->GetTitle())); 00331 LOG(VB_GENERAL, LOG_DEBUG, 00332 QString(" Input Sub: %1").arg(pginfo->GetSubtitle())); 00333 LOG(VB_GENERAL, LOG_DEBUG, 00334 QString(" Title: %1").arg(lookup->GetTitle())); 00335 LOG(VB_GENERAL, LOG_DEBUG, 00336 QString(" Subtitle: %1").arg(lookup->GetSubtitle())); 00337 LOG(VB_GENERAL, LOG_DEBUG, 00338 QString(" Season: %1").arg(lookup->GetSeason())); 00339 LOG(VB_GENERAL, LOG_DEBUG, 00340 QString(" Episode: %1").arg(lookup->GetEpisode())); 00341 LOG(VB_GENERAL, LOG_DEBUG, 00342 QString(" Inetref: %1").arg(lookup->GetInetref())); 00343 LOG(VB_GENERAL, LOG_DEBUG, 00344 QString(" User Rating: %1").arg(lookup->GetUserRating())); 00345 00346 if (!lookup->GetSubtype() == kProbableGenericTelevision) 00347 pginfo->SaveSeasonEpisode(lookup->GetSeason(), lookup->GetEpisode()); 00348 pginfo->SaveInetRef(lookup->GetInetref()); 00349 00350 if (m_updaterules) 00351 { 00352 RecordingRule *rule = new RecordingRule(); 00353 if (rule) 00354 { 00355 rule->LoadByProgram(pginfo); 00356 if (rule->m_inetref.isEmpty() && 00357 (rule->m_searchType == kNoSearch)) 00358 { 00359 rule->m_inetref = lookup->GetInetref(); 00360 } 00361 rule->m_season = lookup->GetSeason(); 00362 rule->m_episode = lookup->GetEpisode(); 00363 rule->Save(); 00364 00365 delete rule; 00366 } 00367 } 00368 00369 if (m_updateartwork) 00370 { 00371 ArtworkMap map = lookup->GetDownloads(); 00372 SetArtwork(lookup->GetInetref(), lookup->GetSeason(), 00373 gCoreContext->GetMasterHostName(), map); 00374 } 00375 00376 m_busyRecList.removeAll(pginfo); 00377 } 00378 else if (levent->type() == MetadataFactoryNoResult::kEventType) 00379 { 00380 MetadataFactoryNoResult *mfnr = dynamic_cast<MetadataFactoryNoResult*>(levent); 00381 00382 if (!mfnr) 00383 return; 00384 00385 MetadataLookup *lookup = mfnr->result; 00386 00387 if (!lookup) 00388 return; 00389 00390 ProgramInfo *pginfo = qVariantValue<ProgramInfo *>(lookup->GetData()); 00391 00392 // This null check could hang us as this pginfo would then never be removed 00393 if (!pginfo) 00394 return; 00395 00396 m_busyRecList.removeAll(pginfo); 00397 } 00398 }
1.7.6.1