00001 #include <QLocale>
00002
00003 #include "rssparse.h"
00004 #include "programinfo.h"
00005 #include "mythcorecontext.h"
00006 #include "metadatacommon.h"
00007 #include "mythlogging.h"
00008 #include "mythlocale.h"
00009 #include "mythmiscutil.h"
00010
00011
00012 MetadataLookup::MetadataLookup(void) :
00013 m_type(kMetadataVideo),
00014 m_subtype(kUnknownVideo),
00015 m_data(),
00016 m_step(kLookupSearch),
00017 m_automatic(false),
00018 m_handleimages(false),
00019 m_allowoverwrites(false),
00020 m_allowgeneric(false),
00021 m_dvdorder(false),
00022 m_host(),
00023 m_filename(),
00024 m_title(),
00025 m_network(),
00026 m_status(),
00027 m_categories(),
00028 m_userrating(0),
00029 m_ratingcount(0),
00030 m_language(),
00031 m_subtitle(),
00032 m_tagline(),
00033 m_description(),
00034 m_season(0),
00035 m_episode(0),
00036 m_chanid(0),
00037 m_channum(),
00038 m_chansign(),
00039 m_channame(),
00040 m_chanplaybackfilters(),
00041 m_recgroup(),
00042 m_playgroup(),
00043 m_seriesid(),
00044 m_programid(),
00045 m_storagegroup(),
00046 m_startts(),
00047 m_endts(),
00048 m_recstartts(),
00049 m_recendts(),
00050 m_programflags(0),
00051 m_audioproperties(0),
00052 m_videoproperties(0),
00053 m_subtitletype(0),
00054 m_certification(),
00055 m_countries(),
00056 m_popularity(0),
00057 m_budget(0),
00058 m_revenue(0),
00059 m_album(),
00060 m_tracknum(0),
00061 m_system(),
00062 m_year(0),
00063 m_releasedate(),
00064 m_lastupdated(),
00065 m_runtime(0),
00066 m_runtimesecs(0),
00067 m_inetref(),
00068 m_collectionref(),
00069 m_tmsref(),
00070 m_imdb(),
00071 m_people(),
00072 m_studios(),
00073 m_homepage(),
00074 m_trailerURL(),
00075 m_artwork(),
00076 m_downloads()
00077 {
00078 }
00079
00080
00081 MetadataLookup::MetadataLookup(
00082 MetadataType type,
00083 LookupType subtype,
00084 QVariant data,
00085 LookupStep step,
00086 bool automatic,
00087 bool handleimages,
00088 bool allowoverwrites,
00089 bool allowgeneric,
00090 bool preferdvdorder,
00091 const QString &host,
00092 const QString &filename,
00093 const QString &title,
00094 const QString &network,
00095 const QString &status,
00096 const QStringList &categories,
00097 const float userrating,
00098 uint ratingcount,
00099 const QString &language,
00100 const QString &subtitle,
00101 const QString &tagline,
00102 const QString &description,
00103 uint season,
00104 uint episode,
00105 uint chanid,
00106 const QString &channum,
00107 const QString &chansign,
00108 const QString &channame,
00109 const QString &chanplaybackfilters,
00110 const QString &recgroup,
00111 const QString &playgroup,
00112 const QString &seriesid,
00113 const QString &programid,
00114 const QString &storagegroup,
00115 const QDateTime startts,
00116 const QDateTime endts,
00117 const QDateTime recstartts,
00118 const QDateTime recendts,
00119 uint programflags,
00120 uint audioproperties,
00121 uint videoproperties,
00122 uint subtitletype,
00123 const QString &certification,
00124 const QStringList &countries,
00125 const uint popularity,
00126 const uint budget,
00127 const uint revenue,
00128 const QString &album,
00129 uint tracknum,
00130 const QString &system,
00131 const uint year,
00132 const QDate releasedate,
00133 const QDateTime lastupdated,
00134 const uint runtime,
00135 const uint runtimesecs,
00136 const QString &inetref,
00137 const QString &collectionref,
00138 const QString &tmsref,
00139 const QString &imdb,
00140 const PeopleMap people,
00141 const QStringList &studios,
00142 const QString &homepage,
00143 const QString &trailerURL,
00144 const ArtworkMap artwork,
00145 DownloadMap downloads) :
00146
00147 m_type(type),
00148 m_subtype(subtype),
00149 m_data(data),
00150 m_step(step),
00151 m_automatic(automatic),
00152 m_handleimages(handleimages),
00153 m_allowoverwrites(allowoverwrites),
00154 m_allowgeneric(allowgeneric),
00155 m_dvdorder(preferdvdorder),
00156 m_host(host),
00157 m_filename(filename),
00158 m_title(title),
00159 m_network(network),
00160 m_status(status),
00161 m_categories(categories),
00162 m_userrating(userrating),
00163 m_ratingcount(ratingcount),
00164 m_language(language),
00165 m_subtitle(subtitle),
00166 m_tagline(tagline),
00167 m_description(description),
00168 m_season(season),
00169 m_episode(episode),
00170 m_chanid(chanid),
00171 m_channum(channum),
00172 m_chansign(chansign),
00173 m_channame(channame),
00174 m_chanplaybackfilters(chanplaybackfilters),
00175 m_recgroup(recgroup),
00176 m_playgroup(playgroup),
00177 m_seriesid(seriesid),
00178 m_programid(programid),
00179 m_storagegroup(storagegroup),
00180 m_startts(startts),
00181 m_endts(endts),
00182 m_recstartts(recstartts),
00183 m_recendts(recendts),
00184 m_programflags(programflags),
00185 m_audioproperties(audioproperties),
00186 m_videoproperties(videoproperties),
00187 m_subtitletype(subtitletype),
00188 m_certification(certification),
00189 m_countries(countries),
00190 m_popularity(popularity),
00191 m_budget(budget),
00192 m_revenue(revenue),
00193 m_album(album),
00194 m_tracknum(tracknum),
00195 m_system(system),
00196 m_year(year),
00197 m_releasedate(releasedate),
00198 m_lastupdated(lastupdated),
00199 m_runtime(runtime),
00200 m_runtimesecs(runtimesecs),
00201 m_inetref(inetref),
00202 m_collectionref(collectionref),
00203 m_tmsref(tmsref),
00204 m_imdb(imdb),
00205 m_people(people),
00206 m_studios(studios),
00207 m_homepage(homepage),
00208 m_trailerURL(trailerURL),
00209 m_artwork(artwork),
00210 m_downloads(downloads)
00211 {
00212 }
00213
00214
00215 MetadataLookup::MetadataLookup(
00216 MetadataType type,
00217 LookupType subtype,
00218 QVariant data,
00219 LookupStep step,
00220 bool automatic,
00221 bool handleimages,
00222 bool allowoverwrites,
00223 bool allowgeneric,
00224 bool preferdvdorder,
00225 const QString &host,
00226 const QString &filename,
00227 const QString &title,
00228 const QStringList &categories,
00229 const float userrating,
00230 const QString &subtitle,
00231 const QString &description,
00232 uint chanid,
00233 const QString &channum,
00234 const QString &chansign,
00235 const QString &channame,
00236 const QString &chanplaybackfilters,
00237 const QString &recgroup,
00238 const QString &playgroup,
00239 const QString &seriesid,
00240 const QString &programid,
00241 const QString &storagegroup,
00242 const QDateTime startts,
00243 const QDateTime endts,
00244 const QDateTime recstartts,
00245 const QDateTime recendts,
00246 uint programflags,
00247 uint audioproperties,
00248 uint videoproperties,
00249 uint subtitletype,
00250 const uint year,
00251 const QDate releasedate,
00252 const QDateTime lastupdated,
00253 const uint runtime,
00254 const uint runtimesecs) :
00255
00256 m_type(type),
00257 m_subtype(subtype),
00258 m_data(data),
00259 m_step(step),
00260 m_automatic(automatic),
00261 m_handleimages(handleimages),
00262 m_allowoverwrites(allowoverwrites),
00263 m_allowgeneric(allowgeneric),
00264 m_dvdorder(preferdvdorder),
00265 m_host(host),
00266 m_filename(filename),
00267 m_title(title),
00268 m_categories(categories),
00269 m_userrating(userrating),
00270 m_subtitle(subtitle),
00271 m_description(description),
00272 m_chanid(chanid),
00273 m_channum(channum),
00274 m_chansign(chansign),
00275 m_channame(channame),
00276 m_chanplaybackfilters(chanplaybackfilters),
00277 m_recgroup(recgroup),
00278 m_playgroup(playgroup),
00279 m_seriesid(seriesid),
00280 m_programid(programid),
00281 m_storagegroup(storagegroup),
00282 m_startts(startts),
00283 m_endts(endts),
00284 m_recstartts(recstartts),
00285 m_recendts(recendts),
00286 m_programflags(programflags),
00287 m_audioproperties(audioproperties),
00288 m_videoproperties(videoproperties),
00289 m_subtitletype(subtitletype),
00290 m_year(year),
00291 m_releasedate(releasedate),
00292 m_lastupdated(lastupdated),
00293 m_runtime(runtime),
00294 m_runtimesecs(runtimesecs)
00295 {
00296 m_tracknum = 0;
00297 m_popularity = 0;
00298 m_budget = 0;
00299 m_revenue = 0;
00300 }
00301
00302
00303 MetadataLookup::MetadataLookup(
00304 MetadataType type,
00305 LookupType subtype,
00306 QVariant data,
00307 LookupStep step,
00308 bool automatic,
00309 bool handleimages,
00310 bool allowoverwrites,
00311 bool allowgeneric,
00312 bool preferdvdorder,
00313 const QString &host,
00314 const QString &filename,
00315 const QString &title,
00316 const QStringList &categories,
00317 const float userrating,
00318 const QString &subtitle,
00319 const QString &tagline,
00320 const QString &description,
00321 uint season,
00322 uint episode,
00323 const QString &certification,
00324 const uint year,
00325 const QDate releasedate,
00326 const uint runtime,
00327 const uint runtimesecs,
00328 const QString &inetref,
00329 const PeopleMap people,
00330 const QString &trailerURL,
00331 const ArtworkMap artwork,
00332 DownloadMap downloads) :
00333
00334 m_type(type),
00335 m_subtype(subtype),
00336 m_data(data),
00337 m_step(step),
00338 m_automatic(automatic),
00339 m_handleimages(handleimages),
00340 m_allowoverwrites(allowoverwrites),
00341 m_allowgeneric(allowgeneric),
00342 m_dvdorder(preferdvdorder),
00343 m_host(host),
00344 m_filename(filename),
00345 m_title(title),
00346 m_categories(categories),
00347 m_userrating(userrating),
00348 m_subtitle(subtitle),
00349 m_tagline(tagline),
00350 m_description(description),
00351 m_season(season),
00352 m_episode(episode),
00353 m_certification(certification),
00354 m_year(year),
00355 m_releasedate(releasedate),
00356 m_runtime(runtime),
00357 m_runtimesecs(runtimesecs),
00358 m_inetref(inetref),
00359 m_people(people),
00360 m_trailerURL(trailerURL),
00361 m_artwork(artwork),
00362 m_downloads(downloads)
00363 {
00364 }
00365
00366 MetadataLookup::~MetadataLookup()
00367 {
00368 }
00369
00370 QList<PersonInfo> MetadataLookup::GetPeople(PeopleType type) const
00371 {
00372 QList<PersonInfo> ret;
00373 ret = m_people.values(type);
00374 return ret;
00375 }
00376
00377 ArtworkList MetadataLookup::GetArtwork(VideoArtworkType type) const
00378 {
00379 ArtworkList ret;
00380 ret = m_artwork.values(type);
00381 return ret;
00382 }
00383
00384 void MetadataLookup::toMap(MetadataMap &metadataMap)
00385 {
00386 metadataMap["filename"] = m_filename;
00387 metadataMap["title"] = m_title;
00388 metadataMap["network"] = m_network;
00389 metadataMap["status"] = m_status;
00390 metadataMap["category"] = m_categories.join(", ");
00391 metadataMap["userrating"] = QString::number(m_userrating);
00392 metadataMap["ratingcount"] = QString::number(m_ratingcount);
00393 metadataMap["language"] = m_language;
00394 metadataMap["subtitle"] = m_subtitle;
00395 metadataMap["tagline"] = m_tagline;
00396 metadataMap["description"] = m_description;
00397 metadataMap["season"] = QString::number(m_season);
00398 metadataMap["episode"] = QString::number(m_episode);
00399 metadataMap["chanid"] = QString::number(m_chanid);
00400 metadataMap["channum"] = m_channum;
00401 metadataMap["callsign"] = m_chansign;
00402 metadataMap["channame"] = m_channame;
00403 metadataMap["playbackfilters"] = m_chanplaybackfilters;
00404 metadataMap["recgroup"] = m_recgroup;
00405 metadataMap["playgroup"] = m_playgroup;
00406 metadataMap["seriesid"] = m_seriesid;
00407 metadataMap["programid"] = m_programid;
00408 metadataMap["storagegroup"] = m_storagegroup;
00409 metadataMap["startts"] = MythDateTimeToString(m_startts, kDateFull);
00410 metadataMap["endts"] = MythDateTimeToString(m_endts, kDateFull);
00411 metadataMap["recstartts"] = MythDateTimeToString(m_recstartts, kDateFull);
00412 metadataMap["recendts"] = MythDateTimeToString(m_recendts, kDateFull);
00413 metadataMap["certification"] = m_certification;
00414 metadataMap["countries"] = m_countries.join(", ");
00415 metadataMap["popularity"] = QString::number(m_popularity);
00416 metadataMap["budget"] = QString::number(m_budget);
00417 metadataMap["revenue"] = QString::number(m_revenue);
00418 metadataMap["album"] = m_album;
00419 metadataMap["tracknum"] = QString::number(m_tracknum);
00420 metadataMap["system"] = m_system;
00421 metadataMap["year"] = QString::number(m_year);
00422
00423 metadataMap["releasedate"] = MythDateToString(m_releasedate, kDateFull);
00424 metadataMap["lastupdated"] = MythDateTimeToString(m_lastupdated, kDateFull);
00425
00426 metadataMap["runtime"] = QObject::tr("%n minute(s)", "", m_runtime);
00427 metadataMap["runtimesecs"] = QObject::tr("%n second(s)", "", m_runtimesecs);
00428 metadataMap["inetref"] = m_inetref;
00429 metadataMap["collectionref"] = m_collectionref;
00430 metadataMap["tmsref"] = m_tmsref;
00431 metadataMap["imdb"] = m_imdb;
00432 metadataMap["studios"] = m_studios.join(", ");
00433 metadataMap["homepage"] = m_homepage;
00434 metadataMap["trailer"] = m_trailerURL;
00435 }
00436
00437 MetadataLookup* LookupFromProgramInfo(ProgramInfo *pginfo)
00438 {
00439 uint runtimesecs = pginfo->GetRecordingStartTime()
00440 .secsTo(pginfo->GetRecordingEndTime());
00441 uint runtime = (runtimesecs/60);
00442
00443 MetadataLookup *ret = new MetadataLookup(kMetadataRecording, kUnknownVideo,
00444 qVariantFromValue(pginfo), kLookupData, false, false, false, false, false,
00445 pginfo->GetHostname(),pginfo->GetBasename(),pginfo->GetTitle(),
00446 QStringList() << pginfo->GetCategory(), pginfo->GetStars() * 10,
00447 pginfo->GetSubtitle(), pginfo->GetDescription(), pginfo->GetChanID(),
00448 pginfo->GetChanNum(), pginfo->GetChannelSchedulingID(),
00449 pginfo->GetChannelName(), pginfo->GetChannelPlaybackFilters(),
00450 pginfo->GetRecordingGroup(), pginfo->GetPlaybackGroup(),
00451 pginfo->GetSeriesID(), pginfo->GetProgramID(), pginfo->GetStorageGroup(),
00452 pginfo->GetScheduledStartTime(), pginfo->GetScheduledEndTime(),
00453 pginfo->GetRecordingStartTime(), pginfo->GetRecordingEndTime(),
00454 pginfo->GetProgramFlags(), pginfo->GetAudioProperties(),
00455 pginfo->GetVideoProperties(), pginfo->GetSubtitleType(),
00456 pginfo->GetYearOfInitialRelease(), pginfo->GetOriginalAirDate(),
00457 pginfo->GetLastModifiedTime(), runtime, runtimesecs);
00458
00459 ret->SetSeason(pginfo->GetSeason());
00460 ret->SetEpisode(pginfo->GetEpisode());
00461 ret->SetInetref(pginfo->GetInetRef());
00462
00463 return ret;
00464 }
00465
00466 QDomDocument CreateMetadataXML(MetadataLookupList list)
00467 {
00468 QDomDocument doc("MythMetadataXML");
00469
00470 QDomElement root = doc.createElement("metadata");
00471 doc.appendChild(root);
00472
00473 for (MetadataLookupList::const_iterator i = list.begin();
00474 i != list.end(); ++i)
00475 {
00476 CreateMetadataXMLItem(*i, root, doc);
00477 }
00478
00479 return doc;
00480 }
00481
00482 QDomDocument CreateMetadataXML(MetadataLookup *lookup)
00483 {
00484 QDomDocument doc("MythMetadataXML");
00485
00486 QDomElement root = doc.createElement("metadata");
00487 doc.appendChild(root);
00488
00489 CreateMetadataXMLItem(lookup, root, doc);
00490
00491 return doc;
00492 }
00493
00494 QDomDocument CreateMetadataXML(ProgramInfo *pginfo)
00495 {
00496 QDomDocument doc("MythMetadataXML");
00497
00498 MetadataLookup *lookup = LookupFromProgramInfo(pginfo);
00499 if (lookup)
00500 doc = CreateMetadataXML(lookup);
00501
00502 delete lookup;
00503 lookup = NULL;
00504
00505 return doc;
00506 }
00507
00508 void CreateMetadataXMLItem(MetadataLookup *lookup,
00509 QDomElement placetoadd,
00510 QDomDocument docroot)
00511 {
00512 if (!lookup)
00513 return;
00514
00515 QDomElement item = docroot.createElement("item");
00516 placetoadd.appendChild(item);
00517 QString RFC822("ddd, d MMMM yyyy hh:mm:ss");
00518
00519
00520 if (!lookup->GetLanguage().isEmpty())
00521 {
00522 QDomElement language = docroot.createElement("language");
00523 item.appendChild(language);
00524 language.appendChild(docroot.createTextNode(lookup->GetLanguage()));
00525 }
00526
00527 if (!lookup->GetTitle().isEmpty())
00528 {
00529 QDomElement title = docroot.createElement("title");
00530 item.appendChild(title);
00531 title.appendChild(docroot.createTextNode(lookup->GetTitle()));
00532 }
00533
00534 if (!lookup->GetSubtitle().isEmpty())
00535 {
00536 QDomElement subtitle = docroot.createElement("subtitle");
00537 item.appendChild(subtitle);
00538 subtitle.appendChild(docroot.createTextNode(lookup->GetSubtitle()));
00539 }
00540
00541 if (!lookup->GetNetwork().isEmpty())
00542 {
00543 QDomElement network = docroot.createElement("network");
00544 item.appendChild(network);
00545 network.appendChild(docroot.createTextNode(lookup->GetNetwork()));
00546 }
00547
00548 if (!lookup->GetStatus().isEmpty())
00549 {
00550 QDomElement status = docroot.createElement("status");
00551 item.appendChild(status);
00552 status.appendChild(docroot.createTextNode(lookup->GetStatus()));
00553 }
00554
00555 if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)
00556 {
00557 QDomElement season = docroot.createElement("season");
00558 item.appendChild(season);
00559 season.appendChild(docroot.createTextNode(
00560 QString::number(lookup->GetSeason())));
00561 }
00562
00563 if (lookup->GetSeason() > 0 || lookup->GetEpisode() > 0)
00564 {
00565 QDomElement episode = docroot.createElement("episode");
00566 item.appendChild(episode);
00567 episode.appendChild(docroot.createTextNode(
00568 QString::number(lookup->GetEpisode())));
00569 }
00570
00571 if (!lookup->GetTagline().isEmpty())
00572 {
00573 QDomElement tagline = docroot.createElement("tagline");
00574 item.appendChild(tagline);
00575 tagline.appendChild(docroot.createTextNode(lookup->GetTagline()));
00576 }
00577
00578 if (!lookup->GetDescription().isEmpty())
00579 {
00580 QDomElement desc = docroot.createElement("description");
00581 item.appendChild(desc);
00582 desc.appendChild(docroot.createTextNode(lookup->GetDescription()));
00583 }
00584
00585 if (!lookup->GetAlbumTitle().isEmpty())
00586 {
00587 QDomElement albumname = docroot.createElement("albumname");
00588 item.appendChild(albumname);
00589 albumname.appendChild(docroot.createTextNode(lookup->GetAlbumTitle()));
00590 }
00591
00592 if (!lookup->GetInetref().isEmpty())
00593 {
00594 QDomElement inetref = docroot.createElement("inetref");
00595 item.appendChild(inetref);
00596 inetref.appendChild(docroot.createTextNode(lookup->GetInetref()));
00597 }
00598
00599 if (!lookup->GetCollectionref().isEmpty())
00600 {
00601 QDomElement collectionref = docroot.createElement("collectionref");
00602 item.appendChild(collectionref);
00603 collectionref.appendChild(docroot.createTextNode(lookup->GetCollectionref()));
00604 }
00605
00606 if (!lookup->GetTMSref().isEmpty())
00607 {
00608 QDomElement tmsref = docroot.createElement("tmsref");
00609 item.appendChild(tmsref);
00610 tmsref.appendChild(docroot.createTextNode(lookup->GetTMSref()));
00611 }
00612
00613 if (!lookup->GetIMDB().isEmpty())
00614 {
00615 QDomElement imdb = docroot.createElement("imdb");
00616 item.appendChild(imdb);
00617 imdb.appendChild(docroot.createTextNode(lookup->GetIMDB()));
00618 }
00619
00620 if (!lookup->GetHomepage().isEmpty())
00621 {
00622 QDomElement homepage = docroot.createElement("homepage");
00623 item.appendChild(homepage);
00624 homepage.appendChild(docroot.createTextNode(lookup->GetHomepage()));
00625 }
00626
00627 if (!lookup->GetTrailerURL().isEmpty())
00628 {
00629 QDomElement trailer = docroot.createElement("trailer");
00630 item.appendChild(trailer);
00631 trailer.appendChild(docroot.createTextNode(lookup->GetTrailerURL()));
00632 }
00633
00634 if (lookup->GetChanId() > 0)
00635 {
00636 QDomElement chanid = docroot.createElement("chanid");
00637 item.appendChild(chanid);
00638 chanid.appendChild(docroot.createTextNode(
00639 QString::number(lookup->GetChanId())));
00640 }
00641
00642 if (!lookup->GetChanNum().isEmpty())
00643 {
00644 QDomElement channum = docroot.createElement("channum");
00645 item.appendChild(channum);
00646 channum.appendChild(docroot.createTextNode(lookup->GetChanNum()));
00647 }
00648
00649 if (!lookup->GetChanSign().isEmpty())
00650 {
00651 QDomElement callsign = docroot.createElement("chansign");
00652 item.appendChild(callsign);
00653 callsign.appendChild(docroot.createTextNode(lookup->GetChanSign()));
00654 }
00655
00656 if (!lookup->GetChanName().isEmpty())
00657 {
00658 QDomElement channame = docroot.createElement("channame");
00659 item.appendChild(channame);
00660 channame.appendChild(docroot.createTextNode(lookup->GetChanName()));
00661 }
00662
00663 if (!lookup->GetChanPlaybackFilters().isEmpty())
00664 {
00665 QDomElement filters = docroot.createElement("filters");
00666 item.appendChild(filters);
00667 filters.appendChild(docroot.createTextNode(
00668 lookup->GetChanPlaybackFilters()));
00669 }
00670
00671 if (!lookup->GetRecGroup().isEmpty())
00672 {
00673 QDomElement recgroup = docroot.createElement("recgroup");
00674 item.appendChild(recgroup);
00675 recgroup.appendChild(docroot.createTextNode(lookup->GetRecGroup()));
00676 }
00677
00678 if (!lookup->GetPlayGroup().isEmpty())
00679 {
00680 QDomElement playgroup = docroot.createElement("playgroup");
00681 item.appendChild(playgroup);
00682 playgroup.appendChild(docroot.createTextNode(lookup->GetPlayGroup()));
00683 }
00684
00685 if (!lookup->GetSeriesId().isEmpty())
00686 {
00687 QDomElement seriesid = docroot.createElement("seriesid");
00688 item.appendChild(seriesid);
00689 seriesid.appendChild(docroot.createTextNode(lookup->GetSeriesId()));
00690 }
00691
00692 if (!lookup->GetProgramId().isEmpty())
00693 {
00694 QDomElement programid = docroot.createElement("programid");
00695 item.appendChild(programid);
00696 programid.appendChild(docroot.createTextNode(lookup->GetProgramId()));
00697 }
00698
00699 if (!lookup->GetStorageGroup().isEmpty())
00700 {
00701 QDomElement sgroup = docroot.createElement("storagegroup");
00702 item.appendChild(sgroup);
00703 sgroup.appendChild(docroot.createTextNode(lookup->GetStorageGroup()));
00704 }
00705
00706 if (!lookup->GetStartTS().isNull())
00707 {
00708 QDomElement startts = docroot.createElement("startts");
00709 item.appendChild(startts);
00710 startts.appendChild(docroot.createTextNode(
00711 lookup->GetStartTS().toString(RFC822)));
00712 }
00713
00714 if (!lookup->GetEndTS().isNull())
00715 {
00716 QDomElement endts = docroot.createElement("endts");
00717 item.appendChild(endts);
00718 endts.appendChild(docroot.createTextNode(
00719 lookup->GetEndTS().toString(RFC822)));
00720 }
00721
00722 if (!lookup->GetRecStartTS().isNull())
00723 {
00724 QDomElement recstartts = docroot.createElement("recstartts");
00725 item.appendChild(recstartts);
00726 recstartts.appendChild(docroot.createTextNode(
00727 lookup->GetRecStartTS().toString(RFC822)));
00728 }
00729
00730 if (!lookup->GetRecEndTS().isNull())
00731 {
00732 QDomElement recendts = docroot.createElement("recendts");
00733 item.appendChild(recendts);
00734 recendts.appendChild(docroot.createTextNode(
00735 lookup->GetRecEndTS().toString(RFC822)));
00736 }
00737
00738 if (lookup->GetProgramFlags() > 0)
00739 {
00740 QDomElement progflags = docroot.createElement("programflags");
00741 item.appendChild(progflags);
00742 progflags.appendChild(docroot.createTextNode(
00743 QString::number(lookup->GetProgramFlags())));
00744 }
00745
00746 if (lookup->GetAudioProperties() > 0)
00747 {
00748 QDomElement audioprops = docroot.createElement("audioproperties");
00749 item.appendChild(audioprops);
00750 audioprops.appendChild(docroot.createTextNode(
00751 QString::number(lookup->GetAudioProperties())));
00752 }
00753
00754 if (lookup->GetVideoProperties() > 0)
00755 {
00756 QDomElement videoprops = docroot.createElement("videoproperties");
00757 item.appendChild(videoprops);
00758 videoprops.appendChild(docroot.createTextNode(
00759 QString::number(lookup->GetVideoProperties())));
00760 }
00761
00762 if (lookup->GetSubtitleType() > 0)
00763 {
00764 QDomElement subprops = docroot.createElement("subtitletype");
00765 item.appendChild(subprops);
00766 subprops.appendChild(docroot.createTextNode(
00767 QString::number(lookup->GetSubtitleType())));
00768 }
00769
00770 if (!lookup->GetReleaseDate().isNull())
00771 {
00772 QDomElement releasedate = docroot.createElement("releasedate");
00773 item.appendChild(releasedate);
00774 releasedate.appendChild(docroot.createTextNode(
00775 lookup->GetReleaseDate().toString("yyyy-MM-dd")));
00776 }
00777
00778 if (!lookup->GetLastUpdated().isNull())
00779 {
00780 QDomElement lastupdated = docroot.createElement("lastupdated");
00781 item.appendChild(lastupdated);
00782 lastupdated.appendChild(docroot.createTextNode(
00783 lookup->GetLastUpdated().toString(RFC822)));
00784 }
00785
00786 if (lookup->GetUserRating() > 0)
00787 {
00788 QDomElement userrating = docroot.createElement("userrating");
00789 item.appendChild(userrating);
00790 userrating.appendChild(docroot.createTextNode(QString::number(
00791 lookup->GetUserRating())));
00792 }
00793
00794 if (lookup->GetRatingCount() > 0)
00795 {
00796 QDomElement ratingcount = docroot.createElement("ratingcount");
00797 item.appendChild(ratingcount);
00798 ratingcount.appendChild(docroot.createTextNode(QString::number(
00799 lookup->GetRatingCount())));
00800 }
00801
00802 if (lookup->GetTrackNumber() > 0)
00803 {
00804 QDomElement tracknum = docroot.createElement("tracknum");
00805 item.appendChild(tracknum);
00806 tracknum.appendChild(docroot.createTextNode(QString::number(
00807 lookup->GetTrackNumber())));
00808 }
00809
00810 if (lookup->GetPopularity() > 0)
00811 {
00812 QDomElement popularity = docroot.createElement("popularity");
00813 item.appendChild(popularity);
00814 popularity.appendChild(docroot.createTextNode(QString::number(
00815 lookup->GetPopularity())));
00816 }
00817
00818 if (lookup->GetBudget() > 0)
00819 {
00820 QDomElement budget = docroot.createElement("budget");
00821 item.appendChild(budget);
00822 budget.appendChild(docroot.createTextNode(QString::number(
00823 lookup->GetBudget())));
00824 }
00825
00826 if (lookup->GetRevenue() > 0)
00827 {
00828 QDomElement revenue = docroot.createElement("revenue");
00829 item.appendChild(revenue);
00830 revenue.appendChild(docroot.createTextNode(QString::number(
00831 lookup->GetRevenue())));
00832 }
00833
00834 if (lookup->GetRuntime() > 0)
00835 {
00836 QDomElement runtime = docroot.createElement("runtime");
00837 item.appendChild(runtime);
00838 runtime.appendChild(docroot.createTextNode(QString::number(
00839 lookup->GetRuntime())));
00840 }
00841
00842 if (lookup->GetRuntimeSeconds() > 0)
00843 {
00844 QDomElement runtimesecs = docroot.createElement("runtimesecs");
00845 item.appendChild(runtimesecs);
00846 runtimesecs.appendChild(docroot.createTextNode(QString::number(
00847 lookup->GetRuntimeSeconds())));
00848 }
00849
00850 if (lookup->GetCertification().size())
00851 AddCertifications(lookup, item, docroot);
00852 if (lookup->GetCategories().size())
00853 AddCategories(lookup, item, docroot);
00854 if (lookup->GetStudios().size())
00855 AddStudios(lookup, item, docroot);
00856 if (lookup->GetCountries().size())
00857 AddCountries(lookup, item, docroot);
00858 }
00859
00860 void AddCertifications(MetadataLookup *lookup,
00861 QDomElement placetoadd,
00862 QDomDocument docroot)
00863 {
00864 QString certstr = lookup->GetCertification();
00865 QDomElement certifications = docroot.createElement("certifications");
00866 placetoadd.appendChild(certifications);
00867
00868 QDomElement cert = docroot.createElement("certification");
00869 certifications.appendChild(cert);
00870 cert.setAttribute("locale", gCoreContext->GetLocale()->GetCountryCode());
00871 cert.setAttribute("name", certstr);
00872 }
00873
00874 void AddCategories(MetadataLookup *lookup,
00875 QDomElement placetoadd,
00876 QDomDocument docroot)
00877 {
00878 QStringList cats = lookup->GetCategories();
00879 QDomElement categories = docroot.createElement("categories");
00880 placetoadd.appendChild(categories);
00881
00882 for (QStringList::const_iterator i = cats.begin();
00883 i != cats.end(); ++i)
00884 {
00885 QDomElement cat = docroot.createElement("category");
00886 categories.appendChild(cat);
00887 cat.setAttribute("type", "genre");
00888 cat.setAttribute("name", *i);
00889 }
00890 }
00891
00892 void AddStudios(MetadataLookup *lookup,
00893 QDomElement placetoadd,
00894 QDomDocument docroot)
00895 {
00896 QStringList studs = lookup->GetStudios();
00897 QDomElement studios = docroot.createElement("studios");
00898 placetoadd.appendChild(studios);
00899
00900 for (QStringList::const_iterator i = studs.begin();
00901 i != studs.end(); ++i)
00902 {
00903 QDomElement stud = docroot.createElement("studio");
00904 studios.appendChild(stud);
00905 stud.setAttribute("name", *i);
00906 }
00907 }
00908
00909 void AddCountries(MetadataLookup *lookup,
00910 QDomElement placetoadd,
00911 QDomDocument docroot)
00912 {
00913 QStringList counts = lookup->GetCountries();
00914 QDomElement countries = docroot.createElement("countries");
00915 placetoadd.appendChild(countries);
00916
00917 for (QStringList::const_iterator i = counts.begin();
00918 i != counts.end(); ++i)
00919 {
00920 QDomElement count = docroot.createElement("country");
00921 countries.appendChild(count);
00922 count.setAttribute("name", *i);
00923 }
00924 }
00925
00926 MetadataLookup* ParseMetadataItem(const QDomElement& item,
00927 MetadataLookup *lookup,
00928 bool passseas)
00929 {
00930 if (!lookup)
00931 return new MetadataLookup();
00932
00933 uint season = 0, episode = 0, chanid = 0, programflags = 0,
00934 audioproperties = 0, videoproperties = 0, subtitletype = 0,
00935 tracknum = 0, popularity = 0, budget = 0, revenue = 0,
00936 year = 0, runtime = 0, runtimesecs = 0, ratingcount = 0;
00937 QString title, network, status, subtitle, tagline, description, certification,
00938 channum, chansign, channame, chanplaybackfilters, recgroup,
00939 playgroup, seriesid, programid, storagegroup, album, system,
00940 inetref, collectionref, tmsref, imdb, homepage, trailerURL, language;
00941 QStringList categories, countries, studios;
00942 float userrating = 0;
00943 QDate releasedate;
00944 QDateTime lastupdated, startts, endts, recstartts, recendts;
00945 PeopleMap people;
00946 ArtworkMap artwork;
00947
00948
00949 language = item.firstChildElement("language").text();
00950 title = Parse::UnescapeHTML(item.firstChildElement("title").text());
00951 network = Parse::UnescapeHTML(item.firstChildElement("network").text());
00952 status = Parse::UnescapeHTML(item.firstChildElement("status").text());
00953 subtitle = Parse::UnescapeHTML(item.firstChildElement("subtitle").text());
00954 tagline = Parse::UnescapeHTML(item.firstChildElement("tagline").text());
00955 description = Parse::UnescapeHTML(item.firstChildElement("description").text());
00956 album = Parse::UnescapeHTML(item.firstChildElement("albumname").text());
00957 inetref = item.firstChildElement("inetref").text();
00958 collectionref = item.firstChildElement("collectionref").text();
00959 tmsref = item.firstChildElement("tmsref").text();
00960 imdb = item.firstChildElement("imdb").text();
00961 homepage = item.firstChildElement("homepage").text();
00962 trailerURL = item.firstChildElement("trailer").text();
00963
00964
00965 chanid = item.firstChildElement("chanid").text().toUInt();
00966 channum = item.firstChildElement("channum").text();
00967 chansign = item.firstChildElement("chansign").text();
00968 channame = item.firstChildElement("channame").text();
00969 chanplaybackfilters = item.firstChildElement("chanplaybackfilters").text();
00970 recgroup = item.firstChildElement("recgroup").text();
00971 playgroup = item.firstChildElement("playgroup").text();
00972 seriesid = item.firstChildElement("seriesid").text();
00973 programid = item.firstChildElement("programid").text();
00974 storagegroup = item.firstChildElement("storagegroup").text();
00975 startts = RFC822TimeToQDateTime(item.
00976 firstChildElement("startts").text());
00977 endts = RFC822TimeToQDateTime(item.
00978 firstChildElement("endts").text());
00979 recstartts = RFC822TimeToQDateTime(item.
00980 firstChildElement("recstartts").text());
00981 recendts = RFC822TimeToQDateTime(item.
00982 firstChildElement("recendts").text());
00983 programflags = item.firstChildElement("programflags").text().toUInt();
00984 audioproperties = item.firstChildElement("audioproperties").text().toUInt();
00985 videoproperties = item.firstChildElement("videoproperties").text().toUInt();
00986 subtitletype = item.firstChildElement("subtitletype").text().toUInt();
00987
00988 QString tmpDate = item.firstChildElement("releasedate").text();
00989 if (!tmpDate.isEmpty())
00990 releasedate = QDate::fromString(tmpDate, "yyyy-MM-dd");
00991 lastupdated = RFC822TimeToQDateTime(item.
00992 firstChildElement("lastupdated").text());
00993
00994 userrating = item.firstChildElement("userrating").text().toFloat();
00995 ratingcount = item.firstChildElement("ratingcount").text().toUInt();
00996 tracknum = item.firstChildElement("tracknum").text().toUInt();
00997 popularity = item.firstChildElement("popularity").text().toUInt();
00998 budget = item.firstChildElement("budget").text().toUInt();
00999 revenue = item.firstChildElement("revenue").text().toUInt();
01000 year = item.firstChildElement("year").text().toUInt();
01001 if (!year && !releasedate.isNull())
01002 year = releasedate.toString("yyyy").toUInt();
01003 runtime = item.firstChildElement("runtime").text().toUInt();
01004 runtimesecs = item.firstChildElement("runtimesecs").text().toUInt();
01005
01006 QDomElement systems = item.firstChildElement("systems");
01007 if (!systems.isNull())
01008 {
01009 QDomElement firstSystem = systems.firstChildElement("system");
01010 if (!firstSystem.isNull())
01011 system = firstSystem.text();
01012 }
01013
01014
01015
01016 QDomElement certifications = item.firstChildElement("certifications");
01017 QList< QPair<QString,QString> > ratinglist;
01018 if (!certifications.isNull())
01019 {
01020 QDomElement cert = certifications.firstChildElement("certification");
01021 if (!cert.isNull())
01022 {
01023 while (!cert.isNull())
01024 {
01025 if (cert.hasAttribute("locale") && cert.hasAttribute("name"))
01026 {
01027 QPair<QString,QString> newcert(cert.attribute("locale"),
01028 cert.attribute("name"));
01029 ratinglist.append(newcert);
01030 }
01031 cert = cert.nextSiblingElement("certification");
01032 }
01033 }
01034 }
01035
01036 if (!ratinglist.isEmpty())
01037 certification = ratinglist.takeFirst().second;
01038
01039
01040 QDomElement categoriesxml = item.firstChildElement("categories");
01041 if (!categoriesxml.isNull())
01042 {
01043 QDomElement cat = categoriesxml.firstChildElement("category");
01044 if (!cat.isNull())
01045 {
01046 while (!cat.isNull())
01047 {
01048 if (cat.hasAttribute("name"))
01049 categories.append(cat.attribute("name"));
01050 cat = cat.nextSiblingElement("category");
01051 }
01052 }
01053 }
01054
01055
01056 QDomElement countriesxml = item.firstChildElement("countries");
01057 if (!countriesxml.isNull())
01058 {
01059 QDomElement cntry = countriesxml.firstChildElement("country");
01060 if (!cntry.isNull())
01061 {
01062 while (!cntry.isNull())
01063 {
01064 if (cntry.hasAttribute("name"))
01065 countries.append(cntry.attribute("name"));
01066 cntry = cntry.nextSiblingElement("country");
01067 }
01068 }
01069 }
01070
01071
01072 QDomElement studiosxml = item.firstChildElement("studios");
01073 if (!studiosxml.isNull())
01074 {
01075 QDomElement studio = studiosxml.firstChildElement("studio");
01076 if (!studio.isNull())
01077 {
01078 while (!studio.isNull())
01079 {
01080 if (studio.hasAttribute("name"))
01081 studios.append(studio.attribute("name"));
01082 studio = studio.nextSiblingElement("studio");
01083 }
01084 }
01085 }
01086
01087
01088 QDomElement peoplexml = item.firstChildElement("people");
01089 if (!peoplexml.isNull())
01090 {
01091 people = ParsePeople(peoplexml);
01092 }
01093
01094
01095 QDomElement artworkxml = item.firstChildElement("images");
01096 if (!artworkxml.isNull())
01097 {
01098 artwork = ParseArtwork(artworkxml);
01099 }
01100
01101
01102
01103
01104
01105 if (passseas)
01106 {
01107 season = lookup->GetSeason();
01108 episode = lookup->GetEpisode();
01109 }
01110 else
01111 {
01112 if (lookup->GetPreferDVDOrdering())
01113 {
01114 season = item.firstChildElement("dvdseason").text().toUInt();
01115 episode = item.firstChildElement("dvdepisode").text().toUInt();
01116 }
01117
01118 if ((season == 0) && (episode == 0))
01119 {
01120 season = item.firstChildElement("season").text().toUInt();
01121 episode = item.firstChildElement("episode").text().toUInt();
01122 }
01123 LOG(VB_GENERAL, LOG_INFO, QString("Result Found, Season %1 Episode %2")
01124 .arg(season).arg(episode));
01125 }
01126
01127 return new MetadataLookup(lookup->GetType(), lookup->GetSubtype(),
01128 lookup->GetData(), lookup->GetStep(), lookup->GetAutomatic(),
01129 lookup->GetHandleImages(), lookup->GetAllowOverwrites(),
01130 lookup->GetAllowGeneric(), lookup->GetPreferDVDOrdering(), lookup->GetHost(),
01131 lookup->GetFilename(), title, network, status, categories, userrating,
01132 ratingcount, language, subtitle, tagline, description, season,
01133 episode, chanid, channum, chansign, channame,
01134 chanplaybackfilters, recgroup, playgroup, seriesid, programid,
01135 storagegroup, startts, endts, recstartts, recendts, programflags,
01136 audioproperties, videoproperties, subtitletype, certification,
01137 countries, popularity, budget, revenue, album, tracknum, system, year,
01138 releasedate, lastupdated, runtime, runtimesecs, inetref, collectionref,
01139 tmsref, imdb, people, studios, homepage, trailerURL, artwork, DownloadMap());
01140 }
01141
01142 MetadataLookup* ParseMetadataMovieNFO(const QDomElement& item,
01143 MetadataLookup *lookup)
01144 {
01145 if (!lookup)
01146 return new MetadataLookup();
01147
01148 uint year = 0, runtime = 0, runtimesecs = 0,
01149 season = 0, episode = 0;
01150 QString title, subtitle, tagline, description,
01151 inetref, trailer, certification;
01152 float userrating = 0;
01153 QDate releasedate;
01154 QStringList categories;
01155 PeopleMap people;
01156 ArtworkMap artwork;
01157
01158
01159 QString titletmp;
01160 if (item.tagName() == "movie")
01161 title = Parse::UnescapeHTML(item.firstChildElement("title").text());
01162 else if (item.tagName() == "episodedetails")
01163 subtitle = Parse::UnescapeHTML(item.firstChildElement("title").text());
01164 userrating = item.firstChildElement("rating").text().toFloat();
01165 year = item.firstChildElement("year").text().toUInt();
01166 season = item.firstChildElement("season").text().toUInt();
01167 episode = item.firstChildElement("episode").text().toUInt();
01168 description = Parse::UnescapeHTML(item.firstChildElement("plot").text());
01169 tagline = Parse::UnescapeHTML(item.firstChildElement("tagline").text());
01170 inetref = item.firstChildElement("id").text();
01171 trailer = item.firstChildElement("trailer").text();
01172 certification = item.firstChildElement("mpaa").text();
01173 categories.append(item.firstChildElement("genre").text());
01174
01175 QString tmpDate = item.firstChildElement("releasedate").text();
01176 if (!tmpDate.isEmpty())
01177 releasedate = QDate::fromString(tmpDate, "yyyy-MM-dd");
01178 else if (year > 0)
01179 releasedate = QDate::fromString(QString::number(year), "yyyy");
01180
01181 runtime = item.firstChildElement("runtime").text()
01182 .remove(QRegExp("[A-Za-z]"))
01183 .trimmed().toUInt();
01184 runtimesecs = runtime * 60;
01185
01186 QDomElement actor = item.firstChildElement("actor");
01187 if (!actor.isNull())
01188 {
01189 while (!actor.isNull())
01190 {
01191 PersonInfo info;
01192 info.name = actor.firstChildElement("name").text();
01193 info.role = actor.firstChildElement("role").text();
01194 info.thumbnail = actor.firstChildElement("thumb").text();
01195 people.insert(kPersonActor, info);
01196 actor = actor.nextSiblingElement("actor");
01197 }
01198 }
01199
01200 QString director = item.firstChildElement("director").text();
01201 if (!director.isEmpty())
01202 {
01203 PersonInfo info;
01204 info.name = director;
01205 people.insert(kPersonDirector, info);
01206 }
01207
01208 return new MetadataLookup(lookup->GetType(), lookup->GetSubtype(),
01209 lookup->GetData(), lookup->GetStep(),
01210 lookup->GetAutomatic(), lookup->GetHandleImages(),
01211 lookup->GetAllowOverwrites(), lookup->GetAllowGeneric(),
01212 lookup->GetPreferDVDOrdering(), lookup->GetHost(),
01213 lookup->GetFilename(), title, categories,
01214 userrating, subtitle, tagline, description, season, episode,
01215 certification, year, releasedate, runtime, runtimesecs,
01216 inetref, people, trailer, artwork, DownloadMap());
01217 }
01218
01219 PeopleMap ParsePeople(QDomElement people)
01220 {
01221 PeopleMap ret;
01222
01223 QDomElement person = people.firstChildElement("person");
01224 if (!person.isNull())
01225 {
01226 while (!person.isNull())
01227 {
01228 if (person.hasAttribute("job"))
01229 {
01230 QString jobstring = person.attribute("job");
01231 PeopleType type;
01232 if (jobstring.toLower() == "actor")
01233 type = kPersonActor;
01234 else if (jobstring.toLower() == "author")
01235 type = kPersonAuthor;
01236 else if (jobstring.toLower() == "producer")
01237 type = kPersonProducer;
01238 else if (jobstring.toLower() == "executive producer")
01239 type = kPersonExecProducer;
01240 else if (jobstring.toLower() == "director")
01241 type = kPersonDirector;
01242 else if (jobstring.toLower() == "cinematographer")
01243 type = kPersonCinematographer;
01244 else if (jobstring.toLower() == "composer")
01245 type = kPersonComposer;
01246 else if (jobstring.toLower() == "editor")
01247 type = kPersonEditor;
01248 else if (jobstring.toLower() == "casting")
01249 type = kPersonCastingDirector;
01250 else if (jobstring.toLower() == "artist")
01251 type = kPersonArtist;
01252 else if (jobstring.toLower() == "album artist")
01253 type = kPersonAlbumArtist;
01254 else if (jobstring.toLower() == "guest star")
01255 type = kPersonGuestStar;
01256 else
01257 type = kPersonActor;
01258
01259 PersonInfo info;
01260 if (person.hasAttribute("name"))
01261 info.name = person.attribute("name");
01262 if (person.hasAttribute("character"))
01263 info.role = person.attribute("character");
01264 if (person.hasAttribute("thumb"))
01265 info.thumbnail = person.attribute("thumb");
01266 if (person.hasAttribute("url"))
01267 info.url = person.attribute("url");
01268
01269 ret.insert(type,info);
01270 }
01271 person = person.nextSiblingElement("person");
01272 }
01273 }
01274 return ret;
01275 }
01276
01277 ArtworkMap ParseArtwork(QDomElement artwork)
01278 {
01279 ArtworkMap ret;
01280
01281 QDomElement image = artwork.firstChildElement("image");
01282 if (!image.isNull())
01283 {
01284 while (!image.isNull())
01285 {
01286 if (image.hasAttribute("type"))
01287 {
01288 QString typestring = image.attribute("type");
01289 VideoArtworkType type;
01290 if (typestring.toLower() == "coverart")
01291 type = kArtworkCoverart;
01292 else if (typestring.toLower() == "fanart")
01293 type = kArtworkFanart;
01294 else if (typestring.toLower() == "banner")
01295 type = kArtworkBanner;
01296 else if (typestring.toLower() == "screenshot")
01297 type = kArtworkScreenshot;
01298 else if (typestring.toLower() == "poster")
01299 type = kArtworkPoster;
01300 else if (typestring.toLower() == "back cover")
01301 type = kArtworkBackCover;
01302 else if (typestring.toLower() == "inside cover")
01303 type = kArtworkInsideCover;
01304 else if (typestring.toLower() == "cd image")
01305 type = kArtworkCDImage;
01306 else
01307 type = kArtworkCoverart;
01308
01309 ArtworkInfo info;
01310 if (image.hasAttribute("thumb"))
01311 info.thumbnail = image.attribute("thumb");
01312 if (image.hasAttribute("url"))
01313 info.url = image.attribute("url");
01314 if (image.hasAttribute("width"))
01315 info.width = image.attribute("width").toUInt();
01316 else
01317 info.width = 0;
01318 if (image.hasAttribute("height"))
01319 info.height = image.attribute("height").toUInt();
01320 else
01321 info.height = 0;
01322
01323 ret.insert(type,info);
01324 }
01325 image = image.nextSiblingElement("image");
01326 }
01327 }
01328 return ret;
01329 }
01330
01331 int editDistance( const QString& s, const QString& t )
01332 {
01333 #define D( i, j ) d[(i) * n + (j)]
01334 int i;
01335 int j;
01336 int m = s.length() + 1;
01337 int n = t.length() + 1;
01338 int *d = new int[m * n];
01339 int result;
01340
01341 for ( i = 0; i < m; i++ )
01342 D( i, 0 ) = i;
01343 for ( j = 0; j < n; j++ )
01344 D( 0, j ) = j;
01345 for ( i = 1; i < m; i++ )
01346 {
01347 for ( j = 1; j < n; j++ )
01348 {
01349 if ( s[i - 1] == t[j - 1] )
01350 D( i, j ) = D( i - 1, j - 1 );
01351 else
01352 {
01353 int x = D( i - 1, j );
01354 int y = D( i - 1, j - 1 );
01355 int z = D( i, j - 1 );
01356 D( i, j ) = 1 + qMin( qMin(x, y), z );
01357 }
01358 }
01359 }
01360 result = D( m - 1, n - 1 );
01361 delete[] d;
01362 return result;
01363 #undef D
01364 }
01365
01366 QString nearestName(const QString& actual, const QStringList& candidates)
01367 {
01368 int deltaBest = 10000;
01369 int numBest = 0;
01370 int tolerance = gCoreContext->GetNumSetting("MetadataLookupTolerance", 5);
01371 QString best;
01372
01373 QStringList::ConstIterator i = candidates.begin();
01374 while ( i != candidates.end() )
01375 {
01376 if ( (*i)[0] == actual[0] )
01377 {
01378 int delta = editDistance( actual, *i );
01379 if ( delta < deltaBest )
01380 {
01381 deltaBest = delta;
01382 numBest = 1;
01383 best = *i;
01384 }
01385 else if ( delta == deltaBest )
01386 {
01387 numBest++;
01388 }
01389 }
01390 ++i;
01391 }
01392
01393 if ( numBest == 1 && deltaBest <= tolerance &&
01394 actual.length() + best.length() >= 5 )
01395 return best;
01396 else
01397 return QString();
01398 }
01399
01400 QDateTime RFC822TimeToQDateTime(const QString& t)
01401 {
01402 QMap<QString, int> TimezoneOffsets;
01403
01404 if (t.size() < 20)
01405 return QDateTime();
01406
01407 QString time = t.simplified();
01408 short int hoursShift = 0, minutesShift = 0;
01409
01410 QStringList tmp = time.split(' ');
01411 if (tmp.isEmpty())
01412 return QDateTime();
01413 if (tmp. at(0).contains(QRegExp("\\D")))
01414 tmp.removeFirst();
01415 if (tmp.size() != 5)
01416 return QDateTime();
01417 QString timezone = tmp.takeAt(tmp.size() -1);
01418 if (timezone.size() == 5)
01419 {
01420 bool ok;
01421 int tz = timezone.toInt(&ok);
01422 if(ok)
01423 {
01424 hoursShift = tz / 100;
01425 minutesShift = tz % 100;
01426 }
01427 }
01428 else
01429 hoursShift = TimezoneOffsets.value(timezone, 0);
01430
01431 if (tmp.at(0).size() == 1)
01432 tmp[0].prepend("0");
01433 tmp [1].truncate(3);
01434
01435 time = tmp.join(" ");
01436
01437 QDateTime result;
01438 if (tmp.at(2).size() == 4)
01439 result = QLocale::c().toDateTime(time, "dd MMM yyyy hh:mm:ss");
01440 else
01441 result = QLocale::c().toDateTime(time, "dd MMM yy hh:mm:ss");
01442 if (result.isNull() || !result.isValid())
01443 return QDateTime();
01444 result = result.addSecs(hoursShift * 3600 * (-1) + minutesShift *60 * (-1));
01445 result.setTimeSpec(Qt::UTC);
01446 return result.toLocalTime();
01447 }
01448
01449 MetaGrabberScript::MetaGrabberScript(
01450 const QString &name,
01451 const QString &author,
01452 const QString &thumbnail,
01453 const QString &command,
01454 const GrabberType type,
01455 const QString &typestring,
01456 const QString &description,
01457 const float version
01458 ) :
01459 m_name(name),
01460 m_author(author),
01461 m_thumbnail(thumbnail),
01462 m_command(command),
01463 m_type(type),
01464 m_typestring(typestring),
01465 m_description(description),
01466 m_version(version)
01467 {
01468 }
01469
01470 MetaGrabberScript::~MetaGrabberScript()
01471 {
01472 }
01473
01474 MetaGrabberScript* ParseGrabberVersion(const QDomElement& item)
01475 {
01476 QString name, author, thumbnail, command, description, typestring;
01477 float version = 0;
01478 GrabberType type = kGrabberMovie;
01479
01480 name = item.firstChildElement("name").text();
01481 author = item.firstChildElement("author").text();
01482 thumbnail = item.firstChildElement("thumbnail").text();
01483 command = item.firstChildElement("command").text();
01484 description = item.firstChildElement("description").text();
01485 version = item.firstChildElement("version").text().toFloat();
01486 typestring = item.firstChildElement("type").text();
01487
01488 if (!typestring.isEmpty())
01489 {
01490 if (typestring.toLower() == "movie")
01491 type = kGrabberMovie;
01492 else if (typestring.toLower() == "television")
01493 type = kGrabberTelevision;
01494 else if (typestring.toLower() == "game")
01495 type = kGrabberGame;
01496 else if (typestring.toLower() == "music")
01497 type = kGrabberMusic;
01498 }
01499
01500 return new MetaGrabberScript(name, author, thumbnail, command,
01501 type, typestring, description, version);
01502 }
01503
01504 void MetaGrabberScript::toMap(MetadataMap &metadataMap)
01505 {
01506 metadataMap["name"] = m_name;
01507 metadataMap["author"] = m_author;
01508 metadataMap["thumbnailfilename"] = m_thumbnail;
01509 metadataMap["command"] = m_command;
01510 metadataMap["description"] = m_description;
01511 metadataMap["version"] = QString::number(m_version);
01512 metadataMap["type"] = m_typestring;
01513 }