8 #include "libmythbase/mythversion.h"
31 qRegisterMetaType<V2VideoMetadataInfo*>(
"V2VideoMetadataInfo");
32 qRegisterMetaType<V2VideoMetadataInfoList*>(
"V2VideoMetadataInfoList");
33 qRegisterMetaType<V2VideoLookupList*>(
"V2VideoLookupList");
34 qRegisterMetaType<V2BlurayInfo*>(
"V2BlurayInfo");
35 qRegisterMetaType<V2VideoStreamInfoList*>(
"V2VideoStreamInfoList");
36 qRegisterMetaType<V2VideoStreamInfo*>(
"V2VideoStreamInfo");
37 qRegisterMetaType<V2ArtworkInfoList*>(
"V2ArtworkInfoList");
38 qRegisterMetaType<V2ArtworkInfo*>(
"V2ArtworkInfo");
39 qRegisterMetaType<V2CastMemberList*>(
"V2CastMemberList");
40 qRegisterMetaType<V2CastMember*>(
"V2CastMember");
41 qRegisterMetaType<V2GenreList*>(
"V2GenreList");
42 qRegisterMetaType<V2Genre*>(
"V2Genre");
43 qRegisterMetaType<V2VideoLookupList*>(
"V2VideoLookupList");
44 qRegisterMetaType<V2VideoLookup*>(
"V2VideoLookup");
45 qRegisterMetaType<V2ArtworkItem*>(
"V2ArtworkItem");
46 qRegisterMetaType<V2CutList*>(
"V2CutList");
47 qRegisterMetaType<V2Cutting*>(
"V2Cutting");
61 throw( QString(
"No metadata found for selected ID!." ));
67 return pVideoMetadataInfo;
75 mlm->setList(videolist);
79 throw( QString(
"No metadata found for selected filename!." ));
85 return pVideoMetadataInfo;
97 query.
prepare(
"SELECT filename "
99 "WHERE intid = :ID ");
111 fileName = query.
value(0).toString();
114 LOG(VB_GENERAL, LOG_ERR, QString(
"V2Video/GetSavedBookmark Video id %1 Not found.").arg(Id));
144 query.
prepare(
"SELECT filename "
145 "FROM videometadata "
146 "WHERE intid = :ID ");
158 fileName = query.
value(0).toString();
161 LOG(VB_GENERAL, LOG_ERR, QString(
"V2Video/GetLastPlayPos Video id %1 Not found.").arg(Id));
207 bool CollapseSubDirs )
209 QString fields =
"title,director,studio,plot,rating,year,releasedate,"
210 "userrating,length,playcount,filename,hash,showlevel,"
211 "coverfile,inetref,collectionref,homepage,childid,browse,watched,"
212 "playcommand,category,intid,trailer,screenshot,banner,fanart,"
213 "subtitle,tagline,season,episode,host,insertdate,processed,contenttype";
215 QStringList sortFields = fields.split(
',');
222 if (!Folder.isEmpty())
224 if (Folder.endsWith(
'/'))
227 folder = Folder +
"/";
228 bindValue = folder +
"%";
229 sql.append(
" WHERE filename LIKE :BINDVALUE ");
231 sql.append(
" ORDER BY ");
232 QString defSeq =
" ASC";
236 QStringList sortList = Sort.toLower().split(
',',Qt::SkipEmptyParts);
238 for (
const auto & item : std::as_const(sortList))
240 QStringList partList = item.split(
' ',Qt::SkipEmptyParts);
241 if (partList.empty())
243 QString sort = partList[0];
246 else if (sort ==
"released")
247 sort =
"releasedate";
248 if (sortFields.contains(sort))
253 if (partList.length() > 1 && partList[1].compare(
"DESC",Qt::CaseInsensitive) == 0)
255 else if (partList.length() > 1 && partList[1].compare(
"ASC",Qt::CaseInsensitive) == 0)
269 std::vector<VideoMetadataListManager::VideoMetadataPtr> videos(videolist.begin(), videolist.end());
276 QMap<QString, QString> map;
277 int folderlen = folder.length();
279 nStartIndex = (nStartIndex > 0) ? std::min( nStartIndex, (
int)videos.size() ) : 0;
280 int selectedCount = 0;
287 for(
const auto& metadata : videos )
291 QString fnPart = metadata->GetFilename().mid(folderlen);
292 int slashPos = fnPart.indexOf(
'/',1);
295 dir = fnPart.mid(0, slashPos);
296 if (!map.contains(dir))
300 map.insert(dir.toLower(), dir);
306 QMapIterator<QString, QString> it(map);
310 while (bDescending? it.hasPrevious() : it.hasNext())
316 if (totalCount >= nStartIndex && (nCount == 0 || selectedCount < nCount)) {
318 pVideoMetadataInfos->AddNewVideoMetadataInfo();
319 pVideoMetadataInfo->setContentType(
"DIRECTORY");
320 pVideoMetadataInfo->setFileName(folder + it.value());
321 pVideoMetadataInfo->setTitle(it.value());
328 for(
const auto& metadata : videos )
335 QString fnPart = metadata->GetFilename().mid(folderlen);
336 int slashPos = fnPart.indexOf(
'/',1);
341 if (totalCount >= nStartIndex && (nCount == 0 || selectedCount < nCount)) {
354 totalPages = (int)ceil((
float)totalCount / nCount);
360 curPage = (int)ceil((
float)nStartIndex / nCount) + 1;
363 pVideoMetadataInfos->setStartIndex ( nStartIndex );
364 pVideoMetadataInfos->setCount ( selectedCount );
365 pVideoMetadataInfos->setCurrentPage ( curPage );
366 pVideoMetadataInfos->setTotalPages ( totalPages );
367 pVideoMetadataInfos->setTotalAvailable( totalCount );
369 pVideoMetadataInfos->setVersion ( MYTH_BINARY_VERSION );
370 pVideoMetadataInfos->setProtoVer ( MYTH_PROTO_VERSION );
372 return pVideoMetadataInfos;
377 const QString &Subtitle,
378 const QString &Inetref,
392 list = factory->SynchronousLookup(Title, Subtitle,
393 Inetref, Season, Episode,
398 return pVideoLookups;
402 for(
const auto & lookup : std::as_const(list))
404 V2VideoLookup *pVideoLookup = pVideoLookups->AddNewVideoLookup();
408 pVideoLookup->setTitle(lookup->GetTitle());
409 pVideoLookup->setSubTitle(lookup->GetSubtitle());
410 pVideoLookup->setSeason(lookup->GetSeason());
411 pVideoLookup->setEpisode(lookup->GetEpisode());
412 pVideoLookup->setYear(lookup->GetYear());
413 pVideoLookup->setTagline(lookup->GetTagline());
414 pVideoLookup->setDescription(lookup->GetDescription());
415 pVideoLookup->setCertification(lookup->GetCertification());
416 pVideoLookup->setInetref(lookup->GetInetref());
417 pVideoLookup->setCollectionref(lookup->GetCollectionref());
418 pVideoLookup->setHomePage(lookup->GetHomepage());
419 #if QT_VERSION < QT_VERSION_CHECK(6,5,0)
420 pVideoLookup->setReleaseDate(
421 QDateTime(lookup->GetReleaseDate(),
422 QTime(0,0),Qt::LocalTime).toUTC());
424 pVideoLookup->setReleaseDate(
425 QDateTime(lookup->GetReleaseDate(),
427 QTimeZone(QTimeZone::LocalTime)).toUTC());
429 pVideoLookup->setUserRating(lookup->GetUserRating());
430 pVideoLookup->setLength(lookup->GetRuntime().count());
431 pVideoLookup->setLanguage(lookup->GetLanguage());
432 pVideoLookup->setCountries(lookup->GetCountries());
433 pVideoLookup->setPopularity(lookup->GetPopularity());
434 pVideoLookup->setBudget(lookup->GetBudget());
435 pVideoLookup->setRevenue(lookup->GetRevenue());
436 pVideoLookup->setIMDB(lookup->GetIMDB());
437 pVideoLookup->setTMSRef(lookup->GetTMSref());
440 ArtworkList::iterator c;
441 for (c = coverartlist.begin(); c != coverartlist.end(); ++c)
444 art->setType(
"coverart");
445 art->setUrl((*c).url);
446 art->setThumbnail((*c).thumbnail);
447 art->setWidth((*c).width);
448 art->setHeight((*c).height);
451 ArtworkList::iterator f;
452 for (f = fanartlist.begin(); f != fanartlist.end(); ++f)
455 art->setType(
"fanart");
456 art->setUrl((*f).url);
457 art->setThumbnail((*f).thumbnail);
458 art->setWidth((*f).width);
459 art->setHeight((*f).height);
462 ArtworkList::iterator b;
463 for (b = bannerlist.begin(); b != bannerlist.end(); ++b)
466 art->setType(
"banner");
467 art->setUrl((*b).url);
468 art->setThumbnail((*b).thumbnail);
469 art->setWidth((*b).width);
470 art->setHeight((*b).height);
473 ArtworkList::iterator s;
474 for (s = screenshotlist.begin(); s != screenshotlist.end(); ++s)
477 art->setType(
"screenshot");
478 art->setUrl((*s).url);
479 art->setThumbnail((*s).thumbnail);
480 art->setWidth((*s).width);
481 art->setHeight((*s).height);
486 pVideoLookups->setCount ( list.count() );
488 pVideoLookups->setVersion ( MYTH_BINARY_VERSION );
489 pVideoLookups->setProtoVer ( MYTH_PROTO_VERSION );
493 return pVideoLookups;
499 bool bResult =
false;
504 mlm->setList(videolist);
508 bResult = metadata->DeleteFromDatabase();
514 const QString &sHostName )
516 if ( sHostName.isEmpty() )
517 throw( QString(
"Host not provided! Local storage is deprecated and "
518 "is not supported by the API." ));
520 if ( sFileName.isEmpty() ||
521 (sFileName.contains(
"/../")) ||
522 (sFileName.startsWith(
"../")) )
524 throw( QString(
"Filename not provided, or fails sanity checks!" ));
529 QString fullname = sgroup.
FindFile(sFileName);
532 throw( QString(
"Provided filename does not exist!" ));
538 LOG(VB_GENERAL, LOG_ERR,
"Video Hash Failed. Unless this is a DVD or "
539 "Blu-ray, something has probably gone wrong.");
549 QString(), QString(), QString(), QString(),
575 mlm->setList(videolist);
581 metadata->SetWatched(bWatched);
582 metadata->UpdateDatabase();
588 const QString &sTitle,
589 const QString &sSubTitle,
590 const QString &sTagLine,
591 const QString &sDirector,
592 const QString &sStudio,
593 const QString &sPlot,
594 const QString &sRating,
595 const QString &sInetref,
597 const QString &sHomePage,
606 const QString &sFileName,
607 const QString &sHash,
608 const QString &sCoverFile,
613 const QString &sPlayCommand,
615 const QString &sTrailer,
616 const QString &sHost,
617 const QString &sScreenshot,
618 const QString &sBanner,
619 const QString &sFanart,
621 const QString &sContentType,
622 const QString &sGenres,
623 const QString &sCast,
624 const QString &sCountries)
626 bool update_required =
false;
630 mlm->setList(videolist);
635 LOG(VB_GENERAL, LOG_ERR, QString(
"UpdateVideoMetadata: Id=%1 not found")
642 metadata->SetTitle(sTitle);
643 update_required =
true;
648 metadata->SetSubtitle(sSubTitle);
649 update_required =
true;
654 metadata->SetTagline(sTagLine);
655 update_required =
true;
660 metadata->SetDirector(sDirector);
661 update_required =
true;
666 metadata->SetStudio(sStudio);
667 update_required =
true;
672 metadata->SetPlot(sPlot);
673 update_required =
true;
678 metadata->SetUserRating(fUserRating);
679 update_required =
true;
684 metadata->SetInetRef(sInetref);
685 update_required =
true;
690 metadata->SetCollectionRef(nCollectionRef);
691 update_required =
true;
696 metadata->SetHomepage(sHomePage);
697 update_required =
true;
702 metadata->SetYear(nYear);
703 update_required =
true;
708 metadata->SetReleaseDate(sReleasedate);
709 update_required =
true;
714 metadata->SetRating(sRating);
715 update_required =
true;
720 metadata->SetLength(std::chrono::minutes(nLength));
721 update_required =
true;
726 metadata->SetPlayCount(nPlayCount);
727 update_required =
true;
732 metadata->SetSeason(nSeason);
733 update_required =
true;
738 metadata->SetEpisode(nEpisode);
739 update_required =
true;
745 update_required =
true;
750 metadata->SetFilename(sFileName);
751 update_required =
true;
756 metadata->SetHash(sHash);
757 update_required =
true;
762 metadata->SetCoverFile(sCoverFile);
763 update_required =
true;
768 metadata->SetChildID(nChildID);
769 update_required =
true;
774 metadata->SetBrowse(bBrowse);
775 update_required =
true;
780 metadata->SetWatched(bWatched);
781 update_required =
true;
786 metadata->SetProcessed(bProcessed);
787 update_required =
true;
792 metadata->SetPlayCommand(sPlayCommand);
793 update_required =
true;
798 metadata->SetCategoryID(nCategory);
799 update_required =
true;
804 metadata->SetTrailer(sTrailer);
805 update_required =
true;
810 metadata->SetHost(sHost);
811 update_required =
true;
816 metadata->SetScreenshot(sScreenshot);
817 update_required =
true;
822 metadata->SetBanner(sBanner);
823 update_required =
true;
828 metadata->SetFanart(sFanart);
829 update_required =
true;
834 metadata->SetInsertdate(sInsertDate);
835 update_required =
true;
842 if (sContentType ==
"MOVIE")
845 if (sContentType ==
"TELEVISION")
848 if (sContentType ==
"ADULT")
851 if (sContentType ==
"MUSICVIDEO")
854 if (sContentType ==
"HOMEVIDEO")
859 metadata->SetContentType(contentType);
860 update_required =
true;
864 LOG(VB_GENERAL, LOG_ERR, QString(
"UpdateVideoMetadata: Ignoring unknown ContentType: %1").arg(sContentType));
871 QStringList genresList = sGenres.split(
',', Qt::SkipEmptyParts);
872 std::transform(genresList.cbegin(), genresList.cend(), std::back_inserter(genres),
873 [](
const QString& name)
874 {return VideoMetadata::genre_list::value_type(-1, name.simplified());} );
876 metadata->SetGenres(genres);
877 update_required =
true;
883 QStringList castList = sCast.split(
',', Qt::SkipEmptyParts);
884 std::transform(castList.cbegin(), castList.cend(), std::back_inserter(cast),
885 [](
const QString& name)
886 {return VideoMetadata::cast_list::value_type(-1, name.simplified());} );
888 metadata->SetCast(cast);
889 update_required =
true;
895 QStringList countryList = sCountries.split(
',', Qt::SkipEmptyParts);
896 std::transform(countryList.cbegin(), countryList.cend(), std::back_inserter(countries),
897 [](
const QString& name)
898 {return VideoMetadata::country_list::value_type(-1, name.simplified());} );
900 metadata->SetCountries(countries);
901 update_required =
true;
905 metadata->UpdateDatabase();
918 query.
prepare(
"SELECT filename "
919 "FROM videometadata "
920 "WHERE intid = :ID ");
932 fileName = query.
value(0).toString();
935 LOG(VB_GENERAL, LOG_ERR, QString(
"Video/SetSavedBookmark Video id %1 Not found.").arg(Id));
965 query.
prepare(
"SELECT filename "
966 "FROM videometadata "
967 "WHERE intid = :ID ");
979 fileName = query.
value(0).toString();
982 LOG(VB_GENERAL, LOG_ERR, QString(
"Video/SetLastPlayPos Video id %1 Not found.").arg(Id));
1007 QString path = sPath;
1009 if (sPath.isEmpty())
1012 LOG(VB_GENERAL, LOG_NOTICE,
1013 QString(
"Parsing Blu-ray at path: %1 ").arg(path));
1018 throw( QString(
"Unable to open Blu-ray Metadata Parser!" ));
1020 if ( !bdmeta->OpenDisc() )
1021 throw( QString(
"Unable to open Blu-ray Disc/Path!" ));
1023 if ( !bdmeta->ParseDisc() )
1024 throw( QString(
"Unable to parse metadata from Blu-ray Disc/Path!" ));
1028 pBlurayInfo->setPath(path);
1029 pBlurayInfo->setTitle(bdmeta->GetTitle());
1030 pBlurayInfo->setAltTitle(bdmeta->GetAlternateTitle());
1031 pBlurayInfo->setDiscLang(bdmeta->GetDiscLanguage());
1032 pBlurayInfo->setDiscNum(bdmeta->GetCurrentDiscNumber());
1033 pBlurayInfo->setTotalDiscNum(bdmeta->GetTotalDiscNumber());
1034 pBlurayInfo->setTitleCount(bdmeta->GetTitleCount());
1035 pBlurayInfo->setThumbCount(bdmeta->GetThumbnailCount());
1036 pBlurayInfo->setTopMenuSupported(bdmeta->GetTopMenuSupported());
1037 pBlurayInfo->setFirstPlaySupported(bdmeta->GetFirstPlaySupported());
1038 pBlurayInfo->setNumHDMVTitles(bdmeta->GetNumHDMVTitles());
1039 pBlurayInfo->setNumBDJTitles(bdmeta->GetNumBDJTitles());
1040 pBlurayInfo->setNumUnsupportedTitles(bdmeta->GetNumUnsupportedTitles());
1041 pBlurayInfo->setAACSDetected(bdmeta->GetAACSDetected());
1042 pBlurayInfo->setLibAACSDetected(bdmeta->GetLibAACSDetected());
1043 pBlurayInfo->setAACSHandled(bdmeta->GetAACSHandled());
1044 pBlurayInfo->setBDPlusDetected(bdmeta->GetBDPlusDetected());
1045 pBlurayInfo->setLibBDPlusDetected(bdmeta->GetLibBDPlusDetected());
1046 pBlurayInfo->setBDPlusHandled(bdmeta->GetBDPlusHandled());
1048 QStringList thumbs = bdmeta->GetThumbnails();
1049 if (!thumbs.empty())
1050 pBlurayInfo->setThumbPath(thumbs.at(0));
1068 (
const QString &storageGroup,
1069 const QString &FileName )
1075 QString sFullFileName = storage.
FindFile( FileName );
1084 pVideoStreamInfos->setVersion ( MYTH_BINARY_VERSION );
1085 pVideoStreamInfos->setProtoVer ( MYTH_PROTO_VERSION );
1086 pVideoStreamInfos->setErrorCode ( infos.
m_errorCode );
1087 pVideoStreamInfos->setErrorMsg ( infos.
m_errorMsg );
1091 V2VideoStreamInfo *pVideoStreamInfo = pVideoStreamInfos->AddNewVideoStreamInfo();
1092 pVideoStreamInfo->setCodecType ( QString(QChar(
info.m_codecType)) );
1093 pVideoStreamInfo->setCodecName (
info.m_codecName );
1094 pVideoStreamInfo->setWidth (
info.m_width );
1095 pVideoStreamInfo->setHeight (
info.m_height );
1096 pVideoStreamInfo->setAspectRatio (
info.m_SampleAspectRatio );
1097 pVideoStreamInfo->setFieldOrder (
info.m_fieldOrder );
1098 pVideoStreamInfo->setFrameRate (
info.m_frameRate );
1099 pVideoStreamInfo->setAvgFrameRate (
info.m_avgFrameRate );
1100 pVideoStreamInfo->setChannels (
info.m_channels );
1101 pVideoStreamInfo->setDuration (
info.m_duration );
1104 return pVideoStreamInfos;
1113 const QString &offsettype,
1118 query.
prepare(
"SELECT filename "
1119 "FROM videometadata "
1120 "WHERE intid = :ID ");
1126 throw QString(
"Database Error.");
1132 fileName = query.
value(0).toString();
1135 LOG(VB_GENERAL, LOG_ERR, QString(
"V2Video/GetVideoCommBreak Video id %1 Not found.").arg(Id));
1136 throw QString(
"Video Not Found.");
1157 if (offsettype.toLower() ==
"position")
1159 else if (offsettype.toLower() ==
"duration")
1175 const QString &offsettype,
1180 query.
prepare(
"SELECT filename "
1181 "FROM videometadata "
1182 "WHERE intid = :ID ");
1188 throw QString(
"Database Error.");
1194 fileName = query.
value(0).toString();
1197 LOG(VB_GENERAL, LOG_ERR, QString(
"V2Video/GetVideoCommBreak Video id %1 Not found.").arg(Id));
1198 throw QString(
"Video Not Found.");
1219 if (offsettype.toLower() ==
"position")
1221 else if (offsettype.toLower() ==
"duration")