MythTV  0.26-pre
metadatacommon.cpp
Go to the documentation of this file.
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 // null constructor
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 // full constructor
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 // ProgramInfo-style constructor
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 // XBMC NFO-style constructor
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     // Language
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     // Title
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     // Subtitle
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     // Network
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     // Status
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     // Season
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     // Episode
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     // Tagline
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     // Plot
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     // Album Name
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     // Inetref
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     // Collectionref
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     // TMSref/SeriesID
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     // IMDB
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     // Home Page
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     // Trailer
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     // Chan ID
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     // Channel Number
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     // Callsign
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     // Channel Name
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     // Playback Filters
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     // Recording Group
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     // Playback Group
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     // SeriesID
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     // ProgramID
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     // Storage Group
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     // Start TS
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     // End TS
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     // Rec Start TS
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     // Rec End TS
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     // Program Flags
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     // Audio Properties
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     // Video Properties
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     // Subtitle Type
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     // Release Date
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     // Last Updated
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     // User Rating
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     // Rating Count
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     // Track Number
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     // Popularity
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     // Budget
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     // Revenue
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     // Runtime
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     // Runtimesecs
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     // Get the easy parses
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     // ProgramInfo specific parsing
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     // TODO: Once TMDB supports certification per-locale, come back and match
01015     // locale of myth to certification locale.
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     // HACK: To go away when someone supports ratings by locale.
01036     if (!ratinglist.isEmpty())
01037         certification = ratinglist.takeFirst().second;
01038 
01039     // Categories
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     // Countries
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     // Studios
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     // People
01088     QDomElement peoplexml = item.firstChildElement("people");
01089     if (!peoplexml.isNull())
01090     {
01091         people = ParsePeople(peoplexml);
01092     }
01093 
01094     // Artwork
01095     QDomElement artworkxml = item.firstChildElement("images");
01096     if (!artworkxml.isNull())
01097     {
01098         artwork = ParseArtwork(artworkxml);
01099     }
01100 
01101     // Have to handle season and episode a little differently.
01102     // If the query object comes in with a season or episode number,
01103     // we want to pass that through.  However, if we are doing a title/subtitle
01104     // lookup, we need to parse for season and episode.
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     // Get the easy parses
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends