MythTV  0.28pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
video.cpp
Go to the documentation of this file.
1 // Program Name: video.cpp
3 // Created : Apr. 21, 2011
4 //
5 // Copyright (c) 2011 Robert McNamara <rmcnamara@mythtv.org>
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 //
25 
26 #include <QList>
27 #include <QFile>
28 #include <QMutex>
29 
30 #include <math.h>
31 
32 #include "video.h"
33 
34 #include "videometadata.h"
35 #include "metadatafactory.h"
36 #include "bluraymetadata.h"
37 
38 #include "compat.h"
39 #include "mythversion.h"
40 #include "mythcorecontext.h"
41 #include "storagegroup.h"
42 #include "remotefile.h"
43 #include "globals.h"
44 #include "mythdate.h"
45 #include "serviceUtil.h"
46 #include "mythmiscutil.h"
47 
49 //
51 
53  const QString &Sort,
54  bool bDescending,
55  int nStartIndex,
56  int nCount )
57 {
58  QString fields = "title,director,studio,plot,rating,year,releasedate,"
59  "userrating,length,playcount,filename,hash,showlevel,"
60  "coverfile,inetref,collectionref,homepage,childid,browse,watched,"
61  "playcommand,category,intid,trailer,screenshot,banner,fanart,"
62  "subtitle,tagline,season,episode,host,insertdate,processed,contenttype";
63 
64  QStringList sortFields = fields.split(',');
65 
67 
68  QString sql = "";
69  if (!Folder.isEmpty())
70  sql.append(" WHERE filename LIKE '" + Folder + "%'");
71 
72  sql.append(" ORDER BY ");
73  QString sort = QString(Sort.toLower());
74  if (sort == "added")
75  sql.append("insertdate");
76  else if (sort == "released")
77  sql.append("releasedate");
78  else if (sortFields.contains(sort))
79  sql.append(sort);
80  else
81  sql.append("intid");
82 
83  if (bDescending)
84  sql += " DESC";
86 
87  std::vector<VideoMetadataListManager::VideoMetadataPtr> videos(videolist.begin(), videolist.end());
88 
89  // ----------------------------------------------------------------------
90  // Build Response
91  // ----------------------------------------------------------------------
92 
93  DTC::VideoMetadataInfoList *pVideoMetadataInfos = new DTC::VideoMetadataInfoList();
94 
95  nStartIndex = min( nStartIndex, (int)videos.size() );
96  nCount = (nCount > 0) ? min( nCount, (int)videos.size() ) : videos.size();
97  int nEndIndex = min((nStartIndex + nCount), (int)videos.size() );
98 
99  for( int n = nStartIndex; n < nEndIndex; n++ )
100  {
101  DTC::VideoMetadataInfo *pVideoMetadataInfo = pVideoMetadataInfos->AddNewVideoMetadataInfo();
102 
104 
105  if (metadata)
106  FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
107  }
108 
109  int curPage = 0, totalPages = 0;
110  if (nCount == 0)
111  totalPages = 1;
112  else
113  totalPages = (int)ceil((float)videos.size() / nCount);
114 
115  if (totalPages == 1)
116  curPage = 1;
117  else
118  {
119  curPage = (int)ceil((float)nStartIndex / nCount) + 1;
120  }
121 
122  pVideoMetadataInfos->setStartIndex ( nStartIndex );
123  pVideoMetadataInfos->setCount ( nCount );
124  pVideoMetadataInfos->setCurrentPage ( curPage );
125  pVideoMetadataInfos->setTotalPages ( totalPages );
126  pVideoMetadataInfos->setTotalAvailable( videos.size() );
127  pVideoMetadataInfos->setAsOf ( MythDate::current() );
128  pVideoMetadataInfos->setVersion ( MYTH_BINARY_VERSION );
129  pVideoMetadataInfos->setProtoVer ( MYTH_PROTO_VERSION );
130 
131  return pVideoMetadataInfos;
132 }
133 
135 //
137 
139 {
142 
143  if ( !metadata )
144  throw( QString( "No metadata found for selected ID!." ));
145 
146  DTC::VideoMetadataInfo *pVideoMetadataInfo = new DTC::VideoMetadataInfo();
147 
148  FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
149 
150  return pVideoMetadataInfo;
151 }
152 
154 //
156 
158 {
162  mlm->setList(videolist);
163  VideoMetadataListManager::VideoMetadataPtr metadata = mlm->byFilename(FileName);
164 
165  if ( !metadata )
166  throw( QString( "No metadata found for selected filename!." ));
167 
168  DTC::VideoMetadataInfo *pVideoMetadataInfo = new DTC::VideoMetadataInfo();
169 
170  FillVideoMetadataInfo ( pVideoMetadataInfo, metadata, true );
171 
172  delete mlm;
173 
174  return pVideoMetadataInfo;
175 }
176 
178 //
180 
182  const QString &Subtitle,
183  const QString &Inetref,
184  int Season,
185  int Episode,
186  const QString &GrabberType,
187  bool AllowGeneric )
188 {
189  DTC::VideoLookupList *pVideoLookups = new DTC::VideoLookupList();
190 
191  MetadataLookupList list;
192 
193  MetadataFactory *factory = new MetadataFactory(NULL);
194 
195  if (factory)
196  list = factory->SynchronousLookup(Title, Subtitle,
197  Inetref, Season, Episode,
198  GrabberType, AllowGeneric);
199 
200  if ( !list.size() )
201  return pVideoLookups;
202 
203  //MetadataLookupList is a reference counted list.
204  //it will delete all its content at its end of life
205  for( int n = 0; n < list.size(); n++ )
206  {
207  DTC::VideoLookup *pVideoLookup = pVideoLookups->AddNewVideoLookup();
208 
209  MetadataLookup *lookup = list[n];
210 
211  if (lookup)
212  {
213  pVideoLookup->setTitle(lookup->GetTitle());
214  pVideoLookup->setSubTitle(lookup->GetSubtitle());
215  pVideoLookup->setSeason(lookup->GetSeason());
216  pVideoLookup->setEpisode(lookup->GetEpisode());
217  pVideoLookup->setYear(lookup->GetYear());
218  pVideoLookup->setTagline(lookup->GetTagline());
219  pVideoLookup->setDescription(lookup->GetDescription());
220  pVideoLookup->setCertification(lookup->GetCertification());
221  pVideoLookup->setInetref(lookup->GetInetref());
222  pVideoLookup->setCollectionref(lookup->GetCollectionref());
223  pVideoLookup->setHomePage(lookup->GetHomepage());
224  pVideoLookup->setReleaseDate(
225  QDateTime(lookup->GetReleaseDate(),
226  QTime(0,0),Qt::LocalTime).toUTC());
227  pVideoLookup->setUserRating(lookup->GetUserRating());
228  pVideoLookup->setLength(lookup->GetRuntime());
229  pVideoLookup->setLanguage(lookup->GetLanguage());
230  pVideoLookup->setCountries(lookup->GetCountries());
231  pVideoLookup->setPopularity(lookup->GetPopularity());
232  pVideoLookup->setBudget(lookup->GetBudget());
233  pVideoLookup->setRevenue(lookup->GetRevenue());
234  pVideoLookup->setIMDB(lookup->GetIMDB());
235  pVideoLookup->setTMSRef(lookup->GetTMSref());
236 
237  ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
238  ArtworkList::iterator c;
239  for (c = coverartlist.begin(); c != coverartlist.end(); ++c)
240  {
241  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
242  art->setType("coverart");
243  art->setUrl((*c).url);
244  art->setThumbnail((*c).thumbnail);
245  art->setWidth((*c).width);
246  art->setHeight((*c).height);
247  }
248  ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
249  ArtworkList::iterator f;
250  for (f = fanartlist.begin(); f != fanartlist.end(); ++f)
251  {
252  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
253  art->setType("fanart");
254  art->setUrl((*f).url);
255  art->setThumbnail((*f).thumbnail);
256  art->setWidth((*f).width);
257  art->setHeight((*f).height);
258  }
259  ArtworkList bannerlist = lookup->GetArtwork(kArtworkBanner);
260  ArtworkList::iterator b;
261  for (b = bannerlist.begin(); b != bannerlist.end(); ++b)
262  {
263  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
264  art->setType("banner");
265  art->setUrl((*b).url);
266  art->setThumbnail((*b).thumbnail);
267  art->setWidth((*b).width);
268  art->setHeight((*b).height);
269  }
270  ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
271  ArtworkList::iterator s;
272  for (s = screenshotlist.begin(); s != screenshotlist.end(); ++s)
273  {
274  DTC::ArtworkItem *art = pVideoLookup->AddNewArtwork();
275  art->setType("screenshot");
276  art->setUrl((*s).url);
277  art->setThumbnail((*s).thumbnail);
278  art->setWidth((*s).width);
279  art->setHeight((*s).height);
280  }
281  }
282  }
283 
284  pVideoLookups->setCount ( list.count() );
285  pVideoLookups->setAsOf ( MythDate::current() );
286  pVideoLookups->setVersion ( MYTH_BINARY_VERSION );
287  pVideoLookups->setProtoVer ( MYTH_PROTO_VERSION );
288 
289  delete factory;
290 
291  return pVideoLookups;
292 }
293 
295 //
297 
299 {
300  bool bResult = false;
301 
305  mlm->setList(videolist);
307 
308  if (metadata)
309  bResult = metadata->DeleteFromDatabase();
310 
311  delete mlm;
312 
313  return bResult;
314 }
315 
317 //
319 
320 bool Video::AddVideo( const QString &sFileName,
321  const QString &sHostName )
322 {
323  if ( sHostName.isEmpty() )
324  throw( QString( "Host not provided! Local storage is deprecated and "
325  "is not supported by the API." ));
326 
327  if ( sFileName.isEmpty() ||
328  (sFileName.contains("/../")) ||
329  (sFileName.startsWith("../")) )
330  {
331  throw( QString( "Filename not provided, or fails sanity checks!" ));
332  }
333 
334  StorageGroup sgroup("Videos", sHostName);
335 
336  QString fullname = sgroup.FindFile(sFileName);
337 
338  if ( !QFile::exists(fullname) )
339  throw( QString( "Provided filename does not exist!" ));
340 
341  QString hash = FileHash(fullname);
342 
343  if (hash == "NULL")
344  {
345  LOG(VB_GENERAL, LOG_ERR, "Video Hash Failed. Unless this is a DVD or "
346  "Blu-ray, something has probably gone wrong.");
347  hash = "";
348  }
349 
350  VideoMetadata newFile(sFileName, hash,
356  VideoMetadata::FilenameToMeta(sFileName, 1),
357  VideoMetadata::FilenameToMeta(sFileName, 4),
358  QString(), VIDEO_YEAR_DEFAULT,
359  QDate::fromString("0000-00-00","YYYY-MM-DD"),
360  VIDEO_INETREF_DEFAULT, 0, QString(),
362  0.0, VIDEO_RATING_DEFAULT, 0, 0,
363  VideoMetadata::FilenameToMeta(sFileName, 2).toInt(),
364  VideoMetadata::FilenameToMeta(sFileName, 3).toInt(),
365  MythDate::current().date(), 0,
367 
368  newFile.SetHost(sHostName);
369  newFile.SaveToDatabase();
370 
371  return true;
372 }
373 
375 //
377 
379  bool bWatched )
380 {
381  bool bResut = false;
384 
385  if ( metadata )
386  {
387  metadata->SetWatched(bWatched);
388  metadata->UpdateDatabase();
389  bResut = true;
390  }
391 
392  return bResut;
393 }
394 
396 //
398 
399 DTC::BlurayInfo* Video::GetBluray( const QString &sPath )
400 {
401  QString path = sPath;
402 
403  if (sPath.isEmpty())
404  path = gCoreContext->GetSetting( "BluRayMountpoint", "/media/cdrom");
405 
406  LOG(VB_GENERAL, LOG_NOTICE,
407  QString("Parsing Blu-ray at path: %1 ").arg(path));
408 
409  BlurayMetadata *bdmeta = new BlurayMetadata(path);
410 
411  if ( !bdmeta )
412  throw( QString( "Unable to open Blu-ray Metadata Parser!" ));
413 
414  if ( !bdmeta->OpenDisc() )
415  throw( QString( "Unable to open Blu-ray Disc/Path!" ));
416 
417  if ( !bdmeta->ParseDisc() )
418  throw( QString( "Unable to parse metadata from Blu-ray Disc/Path!" ));
419 
420  DTC::BlurayInfo *pBlurayInfo = new DTC::BlurayInfo();
421 
422  pBlurayInfo->setPath(path);
423  pBlurayInfo->setTitle(bdmeta->GetTitle());
424  pBlurayInfo->setAltTitle(bdmeta->GetAlternateTitle());
425  pBlurayInfo->setDiscLang(bdmeta->GetDiscLanguage());
426  pBlurayInfo->setDiscNum(bdmeta->GetCurrentDiscNumber());
427  pBlurayInfo->setTotalDiscNum(bdmeta->GetTotalDiscNumber());
428  pBlurayInfo->setTitleCount(bdmeta->GetTitleCount());
429  pBlurayInfo->setThumbCount(bdmeta->GetThumbnailCount());
430  pBlurayInfo->setTopMenuSupported(bdmeta->GetTopMenuSupported());
431  pBlurayInfo->setFirstPlaySupported(bdmeta->GetFirstPlaySupported());
432  pBlurayInfo->setNumHDMVTitles((uint)bdmeta->GetNumHDMVTitles());
433  pBlurayInfo->setNumBDJTitles((uint)bdmeta->GetNumBDJTitles());
434  pBlurayInfo->setNumUnsupportedTitles((uint)bdmeta->GetNumUnsupportedTitles());
435  pBlurayInfo->setAACSDetected(bdmeta->GetAACSDetected());
436  pBlurayInfo->setLibAACSDetected(bdmeta->GetLibAACSDetected());
437  pBlurayInfo->setAACSHandled(bdmeta->GetAACSHandled());
438  pBlurayInfo->setBDPlusDetected(bdmeta->GetBDPlusDetected());
439  pBlurayInfo->setLibBDPlusDetected(bdmeta->GetLibBDPlusDetected());
440  pBlurayInfo->setBDPlusHandled(bdmeta->GetBDPlusHandled());
441 
442  QStringList thumbs = bdmeta->GetThumbnails();
443  if (thumbs.size())
444  pBlurayInfo->setThumbPath(thumbs.at(0));
445 
446  delete bdmeta;
447 
448  return pBlurayInfo;
449 }
450 
452 //
QString FileHash(QString filename)
QStringList GetCountries() const
uint GetRevenue() const
QString GetSubtitle() const
uint GetTotalDiscNumber(void)
const QString VIDEO_SCREENSHOT_DEFAULT
Definition: globals.cpp:27
uint32_t GetNumHDMVTitles(void)
static void loadAllFromDatabase(metadata_list &items, const QString &sql="")
QString GetCollectionref() const
QString GetAlternateTitle(void)
DTC::VideoMetadataInfo * GetVideo(int Id)
Definition: video.cpp:138
DTC::VideoLookupList * LookupVideo(const QString &Title, const QString &Subtitle, const QString &Inetref, int Season, int Episode, const QString &GrabberType, bool AllowGeneric)
Definition: video.cpp:181
GrabberType
unsigned int uint
Definition: compat.h:139
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
ArtworkList GetArtwork(VideoArtworkType type) const
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
bool GetTopMenuSupported(void)
VideoLookup * AddNewVideoLookup()
QString GetTitle() const
QString GetCertification() const
bool ParseDisc(void)
uint GetEpisode() const
unsigned char b
Definition: ParseText.cpp:339
VideoMetadataPtr byID(unsigned int db_id) const
void setList(metadata_list &list)
const QString VIDEO_PLOT_DEFAULT
Definition: globals.cpp:32
bool AddVideo(const QString &FileName, const QString &HostName)
Definition: video.cpp:320
float GetUserRating() const
const QString VIDEO_TRAILER_DEFAULT
Definition: globals.cpp:26
bool GetAACSHandled(void)
uint GetSeason() const
bool GetBDPlusDetected(void)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
QString GetSetting(const QString &key, const QString &defaultval="")
uint32_t GetNumBDJTitles(void)
DTC::VideoMetadataInfoList * GetVideoList(const QString &Folder, const QString &Sort, bool Descending, int StartIndex, int Count)
Definition: video.cpp:52
MetadataLookupList SynchronousLookup(QString title, QString subtitle, QString inetref, int season, int episode, QString grabber, bool allowgeneric=false)
bool OpenDisc(void)
QString GetDiscLanguage(void)
static QString FilenameToMeta(const QString &file_name, int position)
QString GetTMSref() const
QString GetIMDB() const
bool GetFirstPlaySupported(void)
bool GetAACSDetected(void)
QString GetTitle(void)
QString GetLanguage() const
QStringList GetThumbnails(void)
QList< ArtworkInfo > ArtworkList
void SetHost(const QString &host)
std::list< VideoMetadataPtr > metadata_list
ArtworkItem * AddNewArtwork()
DTC::BlurayInfo * GetBluray(const QString &Path)
Definition: video.cpp:399
void FillVideoMetadataInfo(DTC::VideoMetadataInfo *pVideoMetadataInfo, VideoMetadataListManager::VideoMetadataPtr pMetadata, bool bDetails)
const QString VIDEO_INETREF_DEFAULT
Definition: globals.cpp:24
QString FindFile(const QString &filename)
DTC::VideoMetadataInfo * GetVideoByFileName(const QString &FileName)
Definition: video.cpp:157
VideoMetadataPtr byFilename(const QString &file_name) const
QString GetDescription() const
uint32_t GetNumUnsupportedTitles(void)
bool RemoveVideoFromDB(int Id)
Definition: video.cpp:298
uint GetYear() const
const QString VIDEO_COVERFILE_DEFAULT
Definition: globals.cpp:25
uint GetTitleCount(void)
uint GetBudget() const
bool UpdateVideoWatchedStatus(int Id, bool Watched)
Definition: video.cpp:378
uint GetCurrentDiscNumber(void)
const QString VIDEO_RATING_DEFAULT
Definition: globals.cpp:30
QString GetInetref() const
uint GetThumbnailCount(void)
QString GetTagline() const
const QString VIDEO_FANART_DEFAULT
Definition: globals.cpp:29
bool GetLibBDPlusDetected(void)
QDate GetReleaseDate() const
const QString VIDEO_DIRECTOR_DEFAULT
Definition: globals.cpp:23
static VideoMetadataPtr loadOneFromDatabase(uint id)
QString GetHomepage() const
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
uint GetPopularity() const
bool GetLibAACSDetected(void)
uint GetRuntime() const
bool GetBDPlusHandled(void)
const QString VIDEO_BANNER_DEFAULT
Definition: globals.cpp:28