MythTV  0.26-pre
video.cpp
Go to the documentation of this file.
00001 
00002 // Program Name: video.cpp
00003 // Created     : Apr. 21, 2011
00004 //
00005 // Copyright (c) 2011 Robert McNamara <rmcnamara@mythtv.org>
00006 //
00007 // This library is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 2.1 of the License, or at your option any later version of the LGPL.
00011 //
00012 // This library is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 // Lesser General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public
00018 // License along with this library.  If not, see <http://www.gnu.org/licenses/>.
00019 //
00021 
00022 #include <QList>
00023 #include <QFile>
00024 #include <QMutex>
00025 
00026 #include <math.h>
00027 
00028 #include "video.h"
00029 
00030 #include "videometadata.h"
00031 #include "metadatafactory.h"
00032 #include "bluraymetadata.h"
00033 
00034 #include "compat.h"
00035 #include "mythversion.h"
00036 #include "mythcorecontext.h"
00037 #include "storagegroup.h"
00038 #include "remotefile.h"
00039 #include "globals.h"
00040 #include "mythmiscutil.h"
00041 #include "serviceUtil.h"
00042 
00044 //
00046 
00047 DTC::VideoMetadataInfoList* Video::GetVideoList( bool bDescending,
00048                                                  int nStartIndex,
00049                                                  int nCount       )
00050 {
00051     VideoMetadataListManager::metadata_list videolist;
00052     QString sql = "ORDER BY intid";
00053     if (bDescending)
00054         sql += " DESC";
00055     VideoMetadataListManager::loadAllFromDatabase(videolist, sql);
00056 
00057     std::vector<VideoMetadataListManager::VideoMetadataPtr> videos(videolist.begin(), videolist.end());
00058 
00059     // ----------------------------------------------------------------------
00060     // Build Response
00061     // ----------------------------------------------------------------------
00062 
00063     DTC::VideoMetadataInfoList *pVideoMetadataInfos = new DTC::VideoMetadataInfoList();
00064 
00065     nStartIndex   = min( nStartIndex, (int)videos.size() );
00066     nCount        = (nCount > 0) ? min( nCount, (int)videos.size() ) : videos.size();
00067     int nEndIndex = min((nStartIndex + nCount), (int)videos.size() );
00068 
00069     for( int n = nStartIndex; n < nEndIndex; n++ )
00070     {
00071         DTC::VideoMetadataInfo *pVideoMetadataInfo = pVideoMetadataInfos->AddNewVideoMetadataInfo();
00072 
00073         VideoMetadataListManager::VideoMetadataPtr metadata = videos[n];
00074 
00075         if (metadata)
00076             FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
00077     }
00078 
00079     int curPage = 0, totalPages = 0;
00080     if (nCount == 0)
00081         totalPages = 1;
00082     else
00083         totalPages = (int)ceil((float)videos.size() / nCount);
00084 
00085     if (totalPages == 1)
00086         curPage = 1;
00087     else
00088     {
00089         curPage = (int)ceil((float)nStartIndex / nCount) + 1;
00090     }
00091 
00092     pVideoMetadataInfos->setStartIndex    ( nStartIndex     );
00093     pVideoMetadataInfos->setCount         ( nCount          );
00094     pVideoMetadataInfos->setCurrentPage   ( curPage         );
00095     pVideoMetadataInfos->setTotalPages    ( totalPages      );
00096     pVideoMetadataInfos->setTotalAvailable( videos.size()   );
00097     pVideoMetadataInfos->setAsOf          ( QDateTime::currentDateTime() );
00098     pVideoMetadataInfos->setVersion       ( MYTH_BINARY_VERSION );
00099     pVideoMetadataInfos->setProtoVer      ( MYTH_PROTO_VERSION  );
00100 
00101     return pVideoMetadataInfos;
00102 }
00103 
00105 //
00107 
00108 DTC::VideoMetadataInfo* Video::GetVideo( int Id )
00109 {
00110     VideoMetadataListManager::VideoMetadataPtr metadata =
00111                           VideoMetadataListManager::loadOneFromDatabase(Id);
00112 
00113     if ( !metadata )
00114         throw( QString( "No metadata found for selected ID!." ));
00115 
00116     DTC::VideoMetadataInfo *pVideoMetadataInfo = new DTC::VideoMetadataInfo();
00117 
00118     FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
00119 
00120     return pVideoMetadataInfo;
00121 }
00122 
00124 //
00126 
00127 DTC::VideoMetadataInfo* Video::GetVideoByFileName( const QString &FileName )
00128 {
00129     VideoMetadataListManager::metadata_list videolist;
00130     VideoMetadataListManager::loadAllFromDatabase(videolist);
00131     VideoMetadataListManager *mlm = new VideoMetadataListManager();
00132     mlm->setList(videolist);
00133     VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byFilename(FileName);
00134 
00135     if ( !metadata )
00136         throw( QString( "No metadata found for selected filename!." ));
00137 
00138     DTC::VideoMetadataInfo *pVideoMetadataInfo = new DTC::VideoMetadataInfo();
00139 
00140     FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
00141 
00142     delete mlm;
00143 
00144     return pVideoMetadataInfo;
00145 }
00146 
00148 //
00150 
00151 DTC::VideoLookupList* Video::LookupVideo( const QString    &Title,
00152                                               const QString    &Subtitle,
00153                                               const QString    &Inetref,
00154                                               int              Season,
00155                                               int              Episode,
00156                                               const QString    &GrabberType,
00157                                               bool             AllowGeneric )
00158 {
00159     DTC::VideoLookupList *pVideoLookups = new DTC::VideoLookupList();
00160 
00161     MetadataLookupList list;
00162 
00163     MetadataFactory *factory = new MetadataFactory(NULL);
00164 
00165     if (factory)
00166         list = factory->SynchronousLookup(Title, Subtitle,
00167                                          Inetref, Season, Episode,
00168                                          GrabberType, AllowGeneric);
00169 
00170     if ( !list.size() )
00171         return pVideoLookups;
00172 
00173     for( int n = 0; n < list.size(); n++ )
00174     {
00175         DTC::VideoLookup *pVideoLookup = pVideoLookups->AddNewVideoLookup();
00176 
00177         MetadataLookup *lookup = list[n];
00178 
00179         if (lookup)
00180         {
00181             pVideoLookup->setTitle(lookup->GetTitle());
00182             pVideoLookup->setSubTitle(lookup->GetSubtitle());
00183             pVideoLookup->setSeason(lookup->GetSeason());
00184             pVideoLookup->setEpisode(lookup->GetEpisode());
00185             pVideoLookup->setYear(lookup->GetYear());
00186             pVideoLookup->setTagline(lookup->GetTagline());
00187             pVideoLookup->setDescription(lookup->GetDescription());
00188             pVideoLookup->setCertification(lookup->GetCertification());
00189             pVideoLookup->setInetref(lookup->GetInetref());
00190             pVideoLookup->setCollectionref(lookup->GetCollectionref());
00191             pVideoLookup->setHomePage(lookup->GetHomepage());
00192             pVideoLookup->setReleaseDate(QDateTime(lookup->GetReleaseDate()));
00193             pVideoLookup->setUserRating(lookup->GetUserRating());
00194             pVideoLookup->setLength(lookup->GetRuntime());
00195             pVideoLookup->setLanguage(lookup->GetLanguage());
00196             pVideoLookup->setCountries(lookup->GetCountries());
00197             pVideoLookup->setPopularity(lookup->GetPopularity());
00198             pVideoLookup->setBudget(lookup->GetBudget());
00199             pVideoLookup->setRevenue(lookup->GetRevenue());
00200             pVideoLookup->setIMDB(lookup->GetIMDB());
00201             pVideoLookup->setTMSRef(lookup->GetTMSref());
00202 
00203             ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
00204             ArtworkList::iterator c;
00205             for (c = coverartlist.begin(); c != coverartlist.end(); ++c)
00206             {
00207                 DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
00208                 art->setType("coverart");
00209                 art->setUrl((*c).url);
00210                 art->setThumbnail((*c).thumbnail);
00211                 art->setWidth((*c).width);
00212                 art->setHeight((*c).height);
00213             }
00214             ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
00215             ArtworkList::iterator f;
00216             for (f = fanartlist.begin(); f != fanartlist.end(); ++f)
00217             {
00218                 DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
00219                 art->setType("fanart");
00220                 art->setUrl((*f).url);
00221                 art->setThumbnail((*f).thumbnail);
00222                 art->setWidth((*f).width);
00223                 art->setHeight((*f).height);
00224             }
00225             ArtworkList bannerlist = lookup->GetArtwork(kArtworkBanner);
00226             ArtworkList::iterator b;
00227             for (b = bannerlist.begin(); b != bannerlist.end(); ++b)
00228             {
00229                 DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
00230                 art->setType("banner");
00231                 art->setUrl((*b).url);
00232                 art->setThumbnail((*b).thumbnail);
00233                 art->setWidth((*b).width);
00234                 art->setHeight((*b).height);
00235             }
00236             ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
00237             ArtworkList::iterator s;
00238             for (s = screenshotlist.begin(); s != screenshotlist.end(); ++s)
00239             {
00240                 DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
00241                 art->setType("screenshot");
00242                 art->setUrl((*s).url);
00243                 art->setThumbnail((*s).thumbnail);
00244                 art->setWidth((*s).width);
00245                 art->setHeight((*s).height);
00246             }
00247 
00248             delete lookup;
00249         }
00250     }
00251 
00252     pVideoLookups->setCount         ( list.count()                 );
00253     pVideoLookups->setAsOf          ( QDateTime::currentDateTime() );
00254     pVideoLookups->setVersion       ( MYTH_BINARY_VERSION          );
00255     pVideoLookups->setProtoVer      ( MYTH_PROTO_VERSION           );
00256 
00257     delete factory;
00258 
00259     return pVideoLookups;
00260 }
00261 
00263 //
00265 
00266 bool Video::RemoveVideoFromDB( int Id )
00267 {
00268     bool bResult = false;
00269 
00270     VideoMetadataListManager::metadata_list videolist;
00271     VideoMetadataListManager::loadAllFromDatabase(videolist);
00272     VideoMetadataListManager *mlm = new VideoMetadataListManager();
00273     mlm->setList(videolist);
00274     VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byID(Id);
00275 
00276     if (metadata)
00277         bResult = metadata->DeleteFromDatabase();
00278 
00279     delete mlm;
00280 
00281     return bResult;
00282 }
00283 
00285 //
00287 
00288 bool Video::AddVideo( const QString &sFileName,
00289                       const QString &sHostName )
00290 {
00291     if ( sHostName.isEmpty() )
00292         throw( QString( "Host not provided! Local storage is deprecated and "
00293                         "is not supported by the API." ));
00294 
00295     if ( sFileName.isEmpty() ||
00296         (sFileName.contains("/../")) ||
00297         (sFileName.startsWith("../")) )
00298     {
00299         throw( QString( "Filename not provided, or fails sanity checks!" ));
00300     }
00301 
00302     StorageGroup sgroup("Videos", sHostName);
00303 
00304     QString fullname = sgroup.FindFile(sFileName);
00305 
00306     if ( !QFile::exists(fullname) )
00307         throw( QString( "Provided filename does not exist!" ));
00308 
00309     QString hash = FileHash(fullname);
00310 
00311     if (hash == "NULL")
00312     {
00313         LOG(VB_GENERAL, LOG_ERR, "Video Hash Failed. Unless this is a DVD or "
00314                                  "Blu-ray, something has probably gone wrong.");
00315         hash = "";
00316     }
00317 
00318     VideoMetadata newFile(sFileName, hash,
00319                           VIDEO_TRAILER_DEFAULT,
00320                           VIDEO_COVERFILE_DEFAULT,
00321                           VIDEO_SCREENSHOT_DEFAULT,
00322                           VIDEO_BANNER_DEFAULT,
00323                           VIDEO_FANART_DEFAULT,
00324                           VideoMetadata::FilenameToMeta(sFileName, 1),
00325                           VideoMetadata::FilenameToMeta(sFileName, 4),
00326                           QString(), VIDEO_YEAR_DEFAULT,
00327                           QDate::fromString("0000-00-00","YYYY-MM-DD"),
00328                           VIDEO_INETREF_DEFAULT, 0, QString(),
00329                           VIDEO_DIRECTOR_DEFAULT, QString(), VIDEO_PLOT_DEFAULT,
00330                           0.0, VIDEO_RATING_DEFAULT, 0, 0,
00331                           VideoMetadata::FilenameToMeta(sFileName, 2).toInt(),
00332                           VideoMetadata::FilenameToMeta(sFileName, 3).toInt(),
00333                           QDate::currentDate(), 0, ParentalLevel::plLowest);
00334     newFile.SetHost(sHostName);
00335     newFile.SaveToDatabase();
00336 
00337     return true;
00338 }
00339 
00341 //
00343 
00344 DTC::BlurayInfo* Video::GetBluray( const QString &sPath )
00345 {
00346     QString path = sPath;
00347 
00348     if (sPath.isEmpty())
00349         path = gCoreContext->GetSetting( "BluRayMountpoint", "/media/cdrom");
00350 
00351     LOG(VB_GENERAL, LOG_NOTICE,
00352         QString("Parsing Blu-ray at path: %1 ").arg(path));
00353 
00354     BlurayMetadata *bdmeta = new BlurayMetadata(path);
00355 
00356     if ( !bdmeta )
00357         throw( QString( "Unable to open Blu-ray Metadata Parser!" ));
00358 
00359     if ( !bdmeta->OpenDisc() )
00360         throw( QString( "Unable to open Blu-ray Disc/Path!" ));
00361 
00362     if ( !bdmeta->ParseDisc() )
00363         throw( QString( "Unable to parse metadata from Blu-ray Disc/Path!" ));
00364 
00365     DTC::BlurayInfo *pBlurayInfo = new DTC::BlurayInfo();
00366 
00367     pBlurayInfo->setPath(path);
00368     pBlurayInfo->setTitle(bdmeta->GetTitle());
00369     pBlurayInfo->setAltTitle(bdmeta->GetAlternateTitle());
00370     pBlurayInfo->setDiscLang(bdmeta->GetDiscLanguage());
00371     pBlurayInfo->setDiscNum(bdmeta->GetCurrentDiscNumber());
00372     pBlurayInfo->setTotalDiscNum(bdmeta->GetTotalDiscNumber());
00373     pBlurayInfo->setTitleCount(bdmeta->GetTitleCount());
00374     pBlurayInfo->setThumbCount(bdmeta->GetThumbnailCount());
00375     pBlurayInfo->setTopMenuSupported(bdmeta->GetTopMenuSupported());
00376     pBlurayInfo->setFirstPlaySupported(bdmeta->GetFirstPlaySupported());
00377     pBlurayInfo->setNumHDMVTitles((uint)bdmeta->GetNumHDMVTitles());
00378     pBlurayInfo->setNumBDJTitles((uint)bdmeta->GetNumBDJTitles());
00379     pBlurayInfo->setNumUnsupportedTitles((uint)bdmeta->GetNumUnsupportedTitles());
00380     pBlurayInfo->setAACSDetected(bdmeta->GetAACSDetected());
00381     pBlurayInfo->setLibAACSDetected(bdmeta->GetLibAACSDetected());
00382     pBlurayInfo->setAACSHandled(bdmeta->GetAACSHandled());
00383     pBlurayInfo->setBDPlusDetected(bdmeta->GetBDPlusDetected());
00384     pBlurayInfo->setLibBDPlusDetected(bdmeta->GetLibBDPlusDetected());
00385     pBlurayInfo->setBDPlusHandled(bdmeta->GetBDPlusHandled());
00386 
00387     QStringList thumbs = bdmeta->GetThumbnails();
00388     if (thumbs.size())
00389         pBlurayInfo->setThumbPath(thumbs.at(0));
00390 
00391     delete bdmeta;
00392 
00393     return pBlurayInfo;
00394 }
00395 
00397 //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends